├── backend ├── .python-version ├── app │ ├── tests │ │ └── __init__.py │ ├── services │ │ ├── image │ │ │ └── __init__.py │ │ ├── text │ │ │ └── __init__.py │ │ ├── video │ │ │ └── __init__.py │ │ ├── __init__.py │ │ ├── agent │ │ │ ├── speech_to_text_service.py │ │ │ ├── scenario_service.py │ │ │ ├── text_service.py │ │ │ └── text_to_speech_service.py │ │ └── story_service.py │ ├── api │ │ ├── __init__.py │ │ ├── endpoints │ │ │ ├── __init__.py │ │ │ └── scenario_router.py │ │ ├── admin │ │ │ └── util.py │ │ └── router.py │ ├── core │ │ └── __init__.py │ ├── models │ │ ├── __init__.py │ │ ├── agent │ │ │ ├── enums.py │ │ │ ├── agent_interface.py │ │ │ ├── user_model.py │ │ │ └── agent_model.py │ │ ├── image │ │ │ └── image_request_models.py │ │ ├── text │ │ │ └── text_gen_models.py │ │ └── video │ │ │ └── video_gen_models.py │ ├── prompts │ │ └── __init__.py │ ├── adk_web_agent │ │ ├── __init__.py │ │ └── agent.py │ ├── dependencies │ │ ├── __init__.py │ │ └── database.py │ ├── tools │ │ ├── get_weather.py │ │ ├── text_gen.py │ │ ├── image_tools.py │ │ └── video_gen.py │ ├── orm │ │ ├── scenario_data.yaml │ │ ├── root_agent.yaml │ │ └── creative_agents.yaml │ └── main.py ├── requirements.txt ├── .dockerignore ├── Dockerfile ├── openapi-run-template.yaml └── README.md ├── frontend ├── dreamboard │ ├── src │ │ ├── app │ │ │ ├── components │ │ │ │ ├── confirm-dialog │ │ │ │ │ ├── confirm-dialog.component.css │ │ │ │ │ ├── confirm-dialog.component.html │ │ │ │ │ ├── confirm-dialog.component.spec.ts │ │ │ │ │ └── confirm-dialog.component.ts │ │ │ │ ├── snackbar │ │ │ │ │ ├── snackbar.component.html │ │ │ │ │ ├── snackbar.component.css │ │ │ │ │ ├── snackbar.component.spec.ts │ │ │ │ │ └── snackbar.component.ts │ │ │ │ ├── sidebar │ │ │ │ │ ├── sidebar.component.html │ │ │ │ │ ├── sidebar.component.css │ │ │ │ │ ├── sidebar.component.spec.ts │ │ │ │ │ └── sidebar.component.ts │ │ │ │ ├── stories-list │ │ │ │ │ ├── stories-list.component.css │ │ │ │ │ └── stories-list.component.spec.ts │ │ │ │ ├── login │ │ │ │ │ ├── login.component.html │ │ │ │ │ ├── login.component.spec.ts │ │ │ │ │ └── login.component.css │ │ │ │ ├── stories │ │ │ │ │ ├── stories.component.spec.ts │ │ │ │ │ ├── stories.component.css │ │ │ │ │ └── stories.component.html │ │ │ │ ├── navbar │ │ │ │ │ ├── navbar.component.html │ │ │ │ │ ├── navbar.component.spec.ts │ │ │ │ │ ├── navbar.component.css │ │ │ │ │ └── navbar.component.ts │ │ │ │ ├── frame-extraction │ │ │ │ │ ├── frame-extraction.component.spec.ts │ │ │ │ │ ├── frame-extraction.component.css │ │ │ │ │ └── frame-extraction.component.html │ │ │ │ ├── new-story-dialog │ │ │ │ │ ├── new-story-dialog.component.spec.ts │ │ │ │ │ ├── new-story-dialog.component.css │ │ │ │ │ └── new-story-dialog.component.html │ │ │ │ ├── transitions-settings-dialog │ │ │ │ │ ├── transitions-settings-dialog.component.html │ │ │ │ │ ├── transitions-settings-dialog.component.css │ │ │ │ │ └── transitions-settings-dialog.component.spec.ts │ │ │ │ ├── storyboard │ │ │ │ │ ├── storyboard.component.css │ │ │ │ │ ├── storyboard.component.html │ │ │ │ │ ├── storyboard.component.spec.ts │ │ │ │ │ └── storyboard.component.ts │ │ │ │ ├── scene-settings-dialog │ │ │ │ │ ├── scene-settings-dialog.component.css │ │ │ │ │ ├── scene-settings-dialog.component.spec.ts │ │ │ │ │ └── scene-settings-dialog.component.html │ │ │ │ ├── post-video-production │ │ │ │ │ ├── post-video-production.component.html │ │ │ │ │ ├── post-video-production.component.spec.ts │ │ │ │ │ └── post-video-production.component.ts │ │ │ │ ├── file-uploader │ │ │ │ │ ├── file-uploader.component.spec.ts │ │ │ │ │ ├── file-uploader.component.html │ │ │ │ │ └── file-uploader.component.scss │ │ │ │ ├── brainstorm │ │ │ │ │ ├── brainstorm.component.spec.ts │ │ │ │ │ └── brainstorm.component.css │ │ │ │ ├── scene-builder │ │ │ │ │ ├── scene-builder.component.spec.ts │ │ │ │ │ └── scene-builder.component.css │ │ │ │ ├── image-scene-settings │ │ │ │ │ └── image-scene-settings.component.spec.ts │ │ │ │ └── video-scene-settings │ │ │ │ │ ├── video-scene-settings.component.spec.ts │ │ │ │ │ └── video-scene-settings.component.css │ │ │ ├── app.component.html │ │ │ ├── services │ │ │ │ ├── auth │ │ │ │ │ ├── auth.service.ts │ │ │ │ │ ├── auth.service.spec.ts │ │ │ │ │ ├── auth-guard-login.service.spec.ts │ │ │ │ │ ├── auth-guard-storyboard.service.spec.ts │ │ │ │ │ ├── auth-guard-login.service.ts │ │ │ │ │ └── auth-guard-storyboard.service.ts │ │ │ │ ├── stories-storage.service.spec.ts │ │ │ │ ├── files-manager.service.spec.ts │ │ │ │ ├── text-generation.service.spec.ts │ │ │ │ ├── image-generation.service.spec.ts │ │ │ │ ├── video-generation.service.spec.ts │ │ │ │ ├── components-communication.service.spec.ts │ │ │ │ ├── video-generation.service.ts │ │ │ │ ├── image-generation.service.ts │ │ │ │ ├── stories-storage.service.ts │ │ │ │ ├── files-manager.service.ts │ │ │ │ └── frame-extraction.service.ts │ │ │ ├── app.component.css │ │ │ ├── app.config.ts │ │ │ ├── story-utils.ts │ │ │ ├── app.routes.ts │ │ │ ├── app.component.ts │ │ │ ├── models │ │ │ │ ├── settings-models.ts │ │ │ │ ├── scene-models.ts │ │ │ │ └── story-models.ts │ │ │ ├── app.component.spec.ts │ │ │ └── utils.ts │ │ ├── index.html │ │ ├── main.ts │ │ ├── environments │ │ │ ├── environment.ts │ │ │ ├── environment.development.ts │ │ │ └── environment-template.ts │ │ └── styles.css │ ├── public │ │ ├── scene.png │ │ └── favicon.ico │ ├── nginx.conf │ ├── .editorconfig │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ ├── .gitignore │ ├── Dockerfile │ ├── tsconfig.json │ └── package.json ├── .dockerignore ├── server │ └── package.json └── Dockerfile ├── images ├── dreamboard_logo.png ├── dreamboard-general-flow.png └── dreamboard_workflow_overview.png ├── gke ├── .gitignore ├── terraform │ ├── backend.tf │ ├── versions.tf │ ├── variables.tf │ ├── outputs.tf │ ├── main.tf │ ├── cluster.tf │ └── iam.tf └── manifests │ └── dreamboard-app.yaml ├── .gitignore └── contributing.md /backend/.python-version: -------------------------------------------------------------------------------- 1 | 3.13 2 | -------------------------------------------------------------------------------- /backend/app/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/app/services/image/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/app/services/text/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/app/services/video/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/confirm-dialog/confirm-dialog.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/snackbar/snackbar.component.html: -------------------------------------------------------------------------------- 1 |

snackbar works!

2 | -------------------------------------------------------------------------------- /images/dreamboard_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google-marketing-solutions/dreamboard/HEAD/images/dreamboard_logo.png -------------------------------------------------------------------------------- /images/dreamboard-general-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google-marketing-solutions/dreamboard/HEAD/images/dreamboard-general-flow.png -------------------------------------------------------------------------------- /frontend/dreamboard/public/scene.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google-marketing-solutions/dreamboard/HEAD/frontend/dreamboard/public/scene.png -------------------------------------------------------------------------------- /frontend/dreamboard/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google-marketing-solutions/dreamboard/HEAD/frontend/dreamboard/public/favicon.ico -------------------------------------------------------------------------------- /gke/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # Terraform 4 | .terraform* 5 | *.tfstate* 6 | *tfvars* -------------------------------------------------------------------------------- /images/dreamboard_workflow_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google-marketing-solutions/dreamboard/HEAD/images/dreamboard_workflow_overview.png -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/auth/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable({ 4 | providedIn: 'root', 5 | }) 6 | export class AuthService { 7 | constructor() {} 8 | 9 | isLoggedIn(): boolean { 10 | return localStorage.getItem('user') !== null; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /frontend/dreamboard/nginx.conf: -------------------------------------------------------------------------------- 1 | events { worker_connections 1024; } 2 | 3 | http { 4 | server { 5 | listen 8080; 6 | include /etc/nginx/mime.types; 7 | location / { 8 | root /usr/share/nginx/html; 9 | index index.html index.htm; 10 | try_files $uri $uri/ /index.html =404; 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/sidebar/sidebar.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |

My Stories

4 |
5 |

Story 1

6 |

Story 2

7 |

Story 3

8 |

Story 4

9 |
10 |
11 |
12 | -------------------------------------------------------------------------------- /backend/requirements.txt: -------------------------------------------------------------------------------- 1 | fastapi==0.115.11 2 | google-cloud-aiplatform==1.95.1 3 | google-cloud-firestore==2.21.0 4 | google-cloud-logging==3.11.4 5 | google-genai>=1.5.0 6 | imageio-ffmpeg==0.6.0 7 | moviepy==1.0.3 8 | opencv-python-headless==4.11.0.86 9 | pydantic_settings==2.8.1 10 | python-multipart==0.0.20 11 | scikit-image==0.25.2 12 | scipy==1.15.2 13 | uvicorn[standard]==0.34.0 14 | -------------------------------------------------------------------------------- /backend/.dockerignore: -------------------------------------------------------------------------------- 1 | # Python 2 | **/venv 3 | **/__pycache__/ 4 | 5 | # Visual Studio Code 6 | **/.vscode/* 7 | !.vscode/settings.json 8 | !.vscode/tasks.json 9 | !.vscode/launch.json 10 | !.vscode/extensions.json 11 | .history/* 12 | 13 | # Git 14 | .git 15 | .gitignore 16 | 17 | # Docker 18 | Dockerfile 19 | .dockerignore 20 | deploy.sh 21 | README.md 22 | 23 | app/dreamboard 24 | TEST.py 25 | .env -------------------------------------------------------------------------------- /frontend/dreamboard/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | ij_typescript_use_double_quotes = false 14 | 15 | [*.md] 16 | max_line_length = off 17 | trim_trailing_whitespace = false 18 | -------------------------------------------------------------------------------- /frontend/.dockerignore: -------------------------------------------------------------------------------- 1 | # Visual Studio Code 2 | **/.vscode/* 3 | !.vscode/settings.json 4 | !.vscode/tasks.json 5 | !.vscode/launch.json 6 | !.vscode/extensions.json 7 | .history/* 8 | 9 | # Git 10 | .git 11 | .gitignore 12 | 13 | # Docker 14 | Dockerfile 15 | dreamboard/Docker 16 | .dockerignore 17 | deploy.sh 18 | README.md 19 | 20 | dreamboard/dist 21 | dreamboard/node_modules 22 | server/node_modules 23 | server/.env 24 | .vscode -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/confirm-dialog/confirm-dialog.component.html: -------------------------------------------------------------------------------- 1 |

{{ data.title }}

2 | 3 | 4 | {{ data.message }} 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/auth/auth.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { AuthService } from './auth.service'; 4 | 5 | describe('AuthService', () => { 6 | let service: AuthService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(AuthService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /frontend/dreamboard/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ 2 | /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ 3 | { 4 | "extends": "./tsconfig.json", 5 | "compilerOptions": { 6 | "outDir": "./out-tsc/app", 7 | "types": [] 8 | }, 9 | "files": [ 10 | "src/main.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/stories-storage.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { StoriesStorageService } from './stories-storage.service'; 4 | 5 | describe('StoriesStorageService', () => { 6 | let service: StoriesStorageService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(StoriesStorageService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /frontend/dreamboard/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ 2 | /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ 3 | { 4 | "extends": "./tsconfig.json", 5 | "compilerOptions": { 6 | "outDir": "./out-tsc/spec", 7 | "types": [ 8 | "jasmine" 9 | ] 10 | }, 11 | "include": [ 12 | "src/**/*.spec.ts", 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/auth/auth-guard-login.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { AuthGuardLogInService } from './auth-guard-login.service'; 4 | 5 | describe('AuthGuardLogInService', () => { 6 | let service: AuthGuardLogInService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(AuthGuardLogInService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /backend/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.12-slim 2 | 3 | # Allow statements and log messages to immediately appear in the logs 4 | ENV PYTHONUNBUFFERED True 5 | 6 | WORKDIR /code 7 | 8 | RUN apt-get update && apt-get install -y ffmpeg && apt-get clean 9 | 10 | COPY requirements.txt /code/requirements.txt 11 | 12 | RUN pip install --upgrade pip 13 | 14 | RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt 15 | 16 | COPY app /code/app 17 | 18 | ENV PYTHONPATH "${PYTHONPATH}:/code/app" 19 | 20 | CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"] -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/auth/auth-guard-storyboard.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { AuthGuardStoryboardService } from './auth-guard-storyboard.service'; 4 | 5 | describe('AuthStoryboardGuardService', () => { 6 | let service: AuthGuardStoryboardService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(AuthGuardStoryboardService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/stories-list/stories-list.component.css: -------------------------------------------------------------------------------- 1 | .stories-container { 2 | margin: 24px; 3 | 4 | .stories-actions { 5 | display: flex; 6 | justify-content: flex-end; 7 | margin-bottom: 16px; 8 | 9 | button { 10 | margin: 3px; 11 | } 12 | } 13 | } 14 | 15 | /* Structure */ 16 | table { 17 | width: 100%; 18 | } 19 | 20 | .mat-mdc-form-field { 21 | font-size: 14px; 22 | width: 30%; 23 | } 24 | 25 | .mat-column-description { 26 | flex: 0 0 40%; 27 | width: 35%; /* Redundant but good for clarity */ 28 | } -------------------------------------------------------------------------------- /frontend/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "type": "commonjs", 14 | "dependencies": { 15 | "@google-cloud/storage": "^7.17.1", 16 | "cors": "^2.8.5", 17 | "dotenv": "^17.2.1", 18 | "express": "^5.1.0", 19 | "google-auth-library": "^10.2.1", 20 | "multer": "^2.0.2" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/api/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/auth/auth-guard-login.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | import { AuthService } from './auth.service'; 4 | 5 | @Injectable({ 6 | providedIn: 'root', 7 | }) 8 | export class AuthGuardLogInService { 9 | constructor(private authService: AuthService, private router: Router) {} 10 | 11 | canActivate(): boolean { 12 | if (!this.authService.isLoggedIn()) { 13 | return true; 14 | } else { 15 | // Redirect to storyboard 16 | this.router.navigate(['/storyboard']); 17 | return false; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /backend/app/core/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /backend/app/models/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /backend/app/prompts/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /backend/app/services/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/auth/auth-guard-storyboard.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | import { AuthService } from './auth.service'; 4 | 5 | @Injectable({ 6 | providedIn: 'root', 7 | }) 8 | export class AuthGuardStoryboardService { 9 | constructor(private authService: AuthService, private router: Router) {} 10 | 11 | canActivate(): boolean { 12 | if (this.authService.isLoggedIn()) { 13 | return true; 14 | } else { 15 | // Redirect to login page 16 | this.router.navigate(['/login']); 17 | return false; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /backend/app/adk_web_agent/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /backend/app/api/endpoints/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /backend/app/dependencies/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/login/login.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
or
5 |
6 | 9 | 15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/login/login.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { LoginComponent } from './login.component'; 4 | 5 | describe('LoginComponent', () => { 6 | let component: LoginComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [LoginComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(LoginComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/stories/stories.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { StoriesComponent } from './stories.component'; 4 | 5 | describe('StoriesComponent', () => { 6 | let component: StoriesComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [StoriesComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(StoriesComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/navbar/navbar.component.html: -------------------------------------------------------------------------------- 1 | 25 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DreamBoard 6 | 7 | 8 | 9 | 13 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /frontend/dreamboard/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. 2 | 3 | # Compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | /bazel-out 8 | 9 | # Node 10 | /node_modules 11 | npm-debug.log 12 | yarn-error.log 13 | 14 | # IDEs and editors 15 | .idea/ 16 | .project 17 | .classpath 18 | .c9/ 19 | *.launch 20 | .settings/ 21 | *.sublime-workspace 22 | 23 | # Visual Studio Code 24 | .vscode/* 25 | !.vscode/settings.json 26 | !.vscode/tasks.json 27 | !.vscode/launch.json 28 | !.vscode/extensions.json 29 | .history/* 30 | 31 | # Miscellaneous 32 | /.angular/cache 33 | .sass-cache/ 34 | /connect.lock 35 | /coverage 36 | /libpeerconnection.log 37 | testem.log 38 | /typings 39 | 40 | # System files 41 | .DS_Store 42 | Thumbs.db 43 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/stories-list/stories-list.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { StoriesListComponent } from './stories-list.component'; 4 | 5 | describe('StoriesListComponent', () => { 6 | let component: StoriesListComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [StoriesListComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(StoriesListComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /gke/terraform/backend.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | terraform { 16 | backend "gcs" { 17 | bucket = "" # replace with your GCS bucket 18 | prefix = "terraform-state" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/confirm-dialog/confirm-dialog.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ConfirmDialogComponent } from './confirm-dialog.component'; 4 | 5 | describe('ConfirmDialogComponent', () => { 6 | let component: ConfirmDialogComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [ConfirmDialogComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(ConfirmDialogComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/frame-extraction/frame-extraction.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { FrameExtractionComponent } from './frame-extraction.component'; 4 | 5 | describe('FrameExtractionComponent', () => { 6 | let component: FrameExtractionComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [FrameExtractionComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(FrameExtractionComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/new-story-dialog/new-story-dialog.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { NewStoryDialogComponent } from './new-story-dialog.component'; 4 | 5 | describe('NewStoryDialogComponent', () => { 6 | let component: NewStoryDialogComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [NewStoryDialogComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(NewStoryDialogComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # Backend 4 | backend/app/venv 5 | backend/app/.env 6 | backend/**/__pycache__/ 7 | backend/app/dreamboard_videos 8 | backend/database.db 9 | 10 | # Frontend 11 | frontend/dreamboard/dist 12 | frontend/server/.env 13 | frontend/server/node_modules 14 | 15 | # IDEs and editors 16 | .idea/ 17 | .project 18 | .classpath 19 | .c9/ 20 | *.launch 21 | .settings/ 22 | *.sublime-workspace 23 | 24 | # Visual Studio Code 25 | **/.vscode/* 26 | !.vscode/settings.json 27 | !.vscode/tasks.json 28 | !.vscode/launch.json 29 | !.vscode/extensions.json 30 | .history/* 31 | 32 | # Miscellaneous 33 | /connect.lock 34 | /coverage 35 | /libpeerconnection.log 36 | testem.log 37 | /typings 38 | 39 | # System files 40 | **/.DS_Store 41 | Thumbs.db 42 | 43 | # Git 44 | .git -------------------------------------------------------------------------------- /gke/terraform/versions.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | terraform { 16 | required_version = ">= 1.0" 17 | required_providers { 18 | google = { 19 | source = "hashicorp/google" 20 | version = ">= 6.0, < 7.0" 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /frontend/dreamboard/Dockerfile: -------------------------------------------------------------------------------- 1 | # Stage 0, "build-stage", based on Node.js, to build and compile the frontend with multi-stage builds 2 | FROM node:22.12 as build-stage 3 | 4 | WORKDIR /app 5 | 6 | COPY package*.json package-lock.json /app/ 7 | 8 | RUN npm install -g npm@latest 9 | 10 | RUN npm install 11 | 12 | COPY ./ /app/ 13 | 14 | ARG configuration=production 15 | 16 | RUN npm run build --configuration=production 17 | 18 | # Stage 1, based on Nginx, to have only the compiled app, ready for production with Nginx 19 | FROM nginx:1.28 20 | 21 | COPY nginx.conf /etc/nginx/nginx.conf 22 | 23 | ## Remove default nginx index page 24 | RUN rm -rf /usr/share/nginx/html/* 25 | 26 | # Copy from the stage 1 27 | COPY --from=build-stage /app/dist/dreamboard/browser /usr/share/nginx/html 28 | 29 | RUN chmod -R 755 /usr/share/nginx/html 30 | 31 | EXPOSE 8080 -------------------------------------------------------------------------------- /gke/terraform/variables.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | variable "project_id" { 16 | description = "GCP Project ID." 17 | type = string 18 | } 19 | 20 | variable "region" { 21 | description = "GCP location for the regional deployment." 22 | type = string 23 | } 24 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/transitions-settings-dialog/transitions-settings-dialog.component.html: -------------------------------------------------------------------------------- 1 |

{{ title }}

2 | 3 | 4 |
5 | 6 | Transitions 7 | 8 | @for (transition of transitions; track transition) { 9 | {{ 10 | transition.displayName 11 | }} 12 | } 13 | 14 | 15 |
16 |
17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/frame-extraction/frame-extraction.component.css: -------------------------------------------------------------------------------- 1 | :host { 2 | display: block; 3 | margin-top: 16px; 4 | } 5 | 6 | .frame-extraction-container { 7 | display: flex; 8 | flex-direction: column; 9 | margin-top: 16px; 10 | } 11 | 12 | .item-container { 13 | display: flex; 14 | align-items: baseline; 15 | } 16 | 17 | .item-container mat-form-field { 18 | width: 82%; 19 | } 20 | 21 | .item-container button { 22 | margin-left: 12px; 23 | } 24 | 25 | .extraction-controls { 26 | display: flex; 27 | align-items: center; 28 | margin-top: 16px; 29 | } 30 | 31 | mat-form-field { 32 | margin-right: 8px; 33 | } 34 | 35 | .video-player-container { 36 | margin-top: 16px; 37 | } 38 | 39 | video { 40 | width: 100%; 41 | max-width: 500px; 42 | height: auto; 43 | } 44 | -------------------------------------------------------------------------------- /backend/app/adk_web_agent/agent.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from services.agent.agent_service import AgentService 16 | from dotenv import load_dotenv 17 | 18 | agent_service = AgentService() 19 | load_dotenv() 20 | root_agent_name = "orchestor_agent" 21 | root_agent = agent_service.lookup_agent(root_agent_name).agent 22 | -------------------------------------------------------------------------------- /backend/app/models/agent/enums.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from enum import Enum 16 | 17 | 18 | class AgentType(Enum): 19 | LLM = "LLM" 20 | Sequential = "Sequential" 21 | Parallel = "Parallel" 22 | Loop = "Loop" 23 | CodeExecutor = "CodeExecutor" 24 | 25 | 26 | class AgentNames(Enum): 27 | ROOT = "root_agent" 28 | -------------------------------------------------------------------------------- /backend/app/tools/get_weather.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | async def get_weather(city: str) -> str: 17 | """Returns the weather for a given city 18 | Args: 19 | city (str): The city to get the weather for 20 | Returns: 21 | The weather for the city 22 | """ 23 | return f"The weather in {city} is lovely" 24 | -------------------------------------------------------------------------------- /backend/app/models/agent/agent_interface.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from typing import Optional 16 | 17 | from pydantic import BaseModel 18 | 19 | 20 | class ConversationTurn(BaseModel): 21 | content: str 22 | role: str 23 | author: str 24 | message_id: str 25 | audio: Optional[str] = None 26 | 27 | 28 | class Conversation(BaseModel): 29 | turns: list[ConversationTurn] 30 | -------------------------------------------------------------------------------- /backend/app/models/agent/user_model.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from sqlmodel import Field, SQLModel 16 | 17 | 18 | class User(SQLModel): 19 | id: int = Field(default=None, primary_key=True, unique=True) 20 | username: str = Field(default=None) 21 | email: str 22 | disabled: bool 23 | admin: bool = Field(default=False) 24 | 25 | 26 | class UserInDB(User, table=True): 27 | hashed_password: str 28 | -------------------------------------------------------------------------------- /frontend/dreamboard/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ 2 | /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ 3 | { 4 | "compileOnSave": false, 5 | "compilerOptions": { 6 | "outDir": "./dist/out-tsc", 7 | "strict": true, 8 | "noImplicitOverride": true, 9 | "noPropertyAccessFromIndexSignature": true, 10 | "noImplicitReturns": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "skipLibCheck": true, 13 | "isolatedModules": true, 14 | "esModuleInterop": true, 15 | "experimentalDecorators": true, 16 | "moduleResolution": "bundler", 17 | "importHelpers": true, 18 | "target": "ES2022", 19 | "module": "ES2022" 20 | }, 21 | "angularCompilerOptions": { 22 | "enableI18nLegacyMessageIdFormat": false, 23 | "strictInjectionParameters": true, 24 | "strictInputAccessModifiers": true, 25 | "strictTemplates": true 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | .mat-drawer-container { 23 | width: 100%; 24 | min-height: 100%; 25 | } 26 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/snackbar/snackbar.component.css: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | :host { 23 | display: flex; 24 | } -------------------------------------------------------------------------------- /frontend/Dockerfile: -------------------------------------------------------------------------------- 1 | # Stage 0, "build-stage", based on Node.js, to build and compile the frontend with multi-stage builds 2 | FROM node:22.20 as angular-build-stage 3 | 4 | WORKDIR /app 5 | 6 | COPY dreamboard/package*.json dreamboard/package-lock.json /app/ 7 | 8 | RUN npm install -g npm@latest 9 | 10 | RUN npm install 11 | 12 | COPY dreamboard /app/ 13 | 14 | ARG configuration=production 15 | 16 | RUN npm run build --configuration=production 17 | 18 | 19 | # Use a lightweight Node.js base image 20 | FROM node:22.12-alpine 21 | 22 | # Set the working directory in the container 23 | WORKDIR /app 24 | 25 | COPY --from=angular-build-stage /app/dist/dreamboard ./dist/dreamboard 26 | 27 | # Copy package.json and package-lock.json (if present) 28 | COPY server/package*.json ./ 29 | 30 | # Install dependencies 31 | RUN npm install --production 32 | 33 | # Copy the rest of your application code 34 | COPY server/ . 35 | 36 | # Expose the port your app listens on (Cloud Run will inject the PORT env var) 37 | EXPOSE 8080 38 | 39 | # Start the application 40 | CMD ["node", "server.js"] -------------------------------------------------------------------------------- /backend/app/api/admin/util.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from fastapi import Depends, HTTPException 16 | 17 | from models.agent.user_model import User 18 | from api.endpoints.login_router import get_current_active_user 19 | 20 | 21 | async def verify_admin(current_user: User = Depends(get_current_active_user)): 22 | if not current_user.admin: 23 | raise HTTPException( 24 | status_code=403, detail="Not enough permissions. Admin access required." 25 | ) 26 | return current_user 27 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/confirm-dialog/confirm-dialog.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject } from '@angular/core'; 2 | import { 3 | MAT_DIALOG_DATA, 4 | MatDialogTitle, 5 | MatDialogContent, 6 | MatDialogModule, 7 | MatDialogRef, 8 | } from '@angular/material/dialog'; 9 | import { MatButtonModule } from '@angular/material/button'; 10 | import { MatIconModule } from '@angular/material/icon'; 11 | 12 | @Component({ 13 | selector: 'app-confirm-dialog', 14 | imports: [ 15 | MatDialogTitle, 16 | MatDialogContent, 17 | MatDialogModule, 18 | MatButtonModule, 19 | MatIconModule, 20 | ], 21 | templateUrl: './confirm-dialog.component.html', 22 | styleUrl: './confirm-dialog.component.css', 23 | }) 24 | export class ConfirmDialogComponent { 25 | constructor( 26 | public dialogRef: MatDialogRef, 27 | @Inject(MAT_DIALOG_DATA) public data: { title: string; message: string } 28 | ) {} 29 | 30 | onCancel(): void { 31 | this.dialogRef.close(false); 32 | } 33 | 34 | onConfirm(): void { 35 | this.dialogRef.close(true); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /backend/app/orm/scenario_data.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | - name: "don_draper" 16 | description: "Scenarios can provide global context to agents" 17 | overview: "Suave, sophisticated" 18 | initial_prompt: "Some prompt" 19 | system_instructions: "Only use styles and words from the 60s era of advertising " 20 | 21 | - name: "reagan_era" 22 | description: "Scenarios can provide global context to agents" 23 | overview: "Bold, loud" 24 | initial_prompt: "Some prompt" 25 | system_instructions: "Do everything over the top!" 26 | -------------------------------------------------------------------------------- /backend/app/orm/root_agent.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | name: "orchestor_agent" 16 | id: 1 17 | instruction: > 18 | You help users brainstorm. Using the 3 agents assigned to you, generate a story. 19 | The 3 sub agents are: 20 | 1. A text_bot that can generate a story 21 | 2. An image_bot that can generate images 22 | 3. A video_bot that can generate short video snippets 23 | description: "Use the X specialized sub-agents to respond to the user" 24 | agent_type: "Sequential" 25 | use_as_root_agent: 1 26 | sub_agent_ids: 2,3,4 27 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/storyboard/storyboard.component.css: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | .storyboard-container { 23 | height: 100%; 24 | align-items: center; 25 | padding: 16px 32px; 26 | } 27 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/transitions-settings-dialog/transitions-settings-dialog.component.css: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | form { 23 | margin: 32px 8px; 24 | } 25 | 26 | mat-form-field { 27 | width: 100%; 28 | } 29 | -------------------------------------------------------------------------------- /backend/openapi-run-template.yaml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | title: DreamBoard Backend Endpoint 4 | description: Dreamboard API on Cloud Endpoints with a Cloud Run backend 5 | version: 1.0.0 6 | host: {CLOUD_RUN_HOST_NAME} 7 | schemes: 8 | - https 9 | produces: 10 | - application/json 11 | x-google-backend: 12 | address: {CLOUD_RUN_SERVICE_URL} 13 | protocol: h2 14 | paths: 15 | /video_health_check: 16 | post: 17 | summary: Health check for video routes 18 | operationId: video_health_check 19 | responses: 20 | '200': 21 | description: A successful response 22 | schema: 23 | type: object 24 | /image_health_check: 25 | get: 26 | summary: Health check for image routes 27 | operationId: image_health_check 28 | responses: 29 | '200': 30 | description: A successful response 31 | schema: 32 | type: object 33 | /text_health_check: 34 | get: 35 | summary: Health check for text routes 36 | operationId: text_health_check 37 | responses: 38 | '200': 39 | description: A successful response 40 | schema: 41 | type: object -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We would love to accept your patches and contributions to this project. 4 | 5 | ## Before you begin 6 | 7 | ### Sign our Contributor License Agreement 8 | 9 | Contributions to this project must be accompanied by a 10 | [Contributor License Agreement](https://cla.developers.google.com/about) (CLA). 11 | You (or your employer) retain the copyright to your contribution; this simply 12 | gives us permission to use and redistribute your contributions as part of the 13 | project. 14 | 15 | If you or your current employer have already signed the Google CLA (even if it 16 | was for a different project), you probably don't need to do it again. 17 | 18 | Visit to see your current agreements or to 19 | sign a new one. 20 | 21 | ### Review our Community Guidelines 22 | 23 | This project follows [Google's Open Source Community 24 | Guidelines](https://opensource.google/conduct/). 25 | 26 | ## Contribution process 27 | 28 | ### Code Reviews 29 | 30 | All submissions, including submissions by project members, require review. We 31 | use [GitHub pull requests](https://docs.github.com/articles/about-pull-requests) 32 | for this purpose. 33 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/storyboard/storyboard.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Storyboard

3 | 9 | 10 | 11 | castle  Stories 12 | 13 | 14 | 15 | 16 | 17 | auto_fix_high  AI Brainstorm 18 | 19 | 20 | 21 | 22 | 23 | build  Scene Builder 24 | 25 | 26 | 27 | 28 | 29 | video_settings  Post Video Production 30 | 31 | 32 | 33 | 34 |
35 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/main.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { bootstrapApplication } from '@angular/platform-browser'; 23 | import { appConfig } from './app/app.config'; 24 | import { AppComponent } from './app/app.component'; 25 | 26 | bootstrapApplication(AppComponent, appConfig).catch((err) => 27 | console.error(err) 28 | ); 29 | -------------------------------------------------------------------------------- /backend/app/dependencies/database.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import os 16 | from typing import Annotated 17 | 18 | from fastapi import Depends 19 | from sqlmodel import Session, SQLModel, create_engine 20 | 21 | sqlite_file_name = os.getenv("DB_PATH") 22 | sqlite_url = f"sqlite:///{sqlite_file_name}" 23 | 24 | engine = create_engine(sqlite_url, connect_args={"check_same_thread": False}) 25 | 26 | 27 | def get_session(): 28 | with Session(engine) as session: 29 | yield session 30 | session.close() 31 | 32 | 33 | def initialize_clean_db(): 34 | SQLModel.metadata.drop_all(engine) 35 | SQLModel.metadata.create_all(engine) 36 | 37 | 38 | SessionDep = Annotated[Session, Depends(get_session)] 39 | -------------------------------------------------------------------------------- /frontend/dreamboard/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dreamboard", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "watch": "ng build --watch --configuration development", 9 | "test": "ng test" 10 | }, 11 | "private": true, 12 | "dependencies": { 13 | "@angular/animations": "^20.3.2", 14 | "@angular/cdk": "^20.2.5", 15 | "@angular/common": "^20.3.2", 16 | "@angular/compiler": "^20.3.2", 17 | "@angular/core": "^20.3.2", 18 | "@angular/forms": "^20.3.2", 19 | "@angular/material": "^20.2.5", 20 | "@angular/platform-browser": "^20.3.2", 21 | "@angular/platform-browser-dynamic": "^20.3.2", 22 | "@angular/router": "^20.3.2", 23 | "rxjs": "~7.8.0", 24 | "tslib": "^2.3.0", 25 | "uuid": "^11.1.0", 26 | "zone.js": "~0.15.0" 27 | }, 28 | "devDependencies": { 29 | "@angular/build": "^20.3.3", 30 | "@angular/cli": "^20.3.3", 31 | "@angular/compiler-cli": "^20.3.2", 32 | "@types/jasmine": "~5.1.0", 33 | "jasmine-core": "~5.4.0", 34 | "karma": "~6.4.0", 35 | "karma-chrome-launcher": "~3.2.0", 36 | "karma-coverage": "~2.2.0", 37 | "karma-jasmine": "~5.1.0", 38 | "karma-jasmine-html-reporter": "~2.1.0", 39 | "typescript": "~5.9.2" 40 | } 41 | } -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/new-story-dialog/new-story-dialog.component.css: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | .item-container { 23 | display: flex; 24 | justify-content: flex-start; 25 | 26 | mat-form-field { 27 | width: 80%; 28 | } 29 | 30 | button { 31 | margin-left: 12px; 32 | } 33 | } 34 | 35 | form { 36 | margin-top: 32px; 37 | } 38 | 39 | .close-button { 40 | margin-top: 10px; 41 | float: right; 42 | } -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/new-story-dialog/new-story-dialog.component.html: -------------------------------------------------------------------------------- 1 |

2 | {{ title }} 3 | 11 |

12 | 13 | 14 |
15 |
16 | 17 | Title 18 | 23 | 24 |
25 |
26 | 27 | Description 28 | 34 | 35 |
36 |
37 |
38 | 39 | 40 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | export const environment = { 23 | production: true, 24 | videoGenerationApiURL: '/api/video_generation', 25 | imageGenerationApiURL: '/api/image_generation', 26 | textGenerationApiURL: '/api/text_generation', 27 | fileUploaderApiURL: '/api/file_uploader', 28 | storiesStorageApiURL: '/api/story_storage', 29 | proxyURL: '', // proxy url is just api/handleRequest for Nodejs server in PROD 30 | clientID: '', 31 | }; 32 | -------------------------------------------------------------------------------- /gke/terraform/outputs.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | output "cluster_name" { 16 | value = google_container_cluster.dreamboard-cluster.name 17 | description = "GKE Cluster" 18 | } 19 | 20 | output "ip_address" { 21 | value = google_compute_address.static_address.address 22 | description = "Static IP Address" 23 | } 24 | 25 | output "bucket_name" { 26 | value = google_storage_bucket.bucket.name 27 | description = "GCS Bucket" 28 | } 29 | 30 | output "repo_address" { 31 | value = "${var.region}-docker.pkg.dev/${var.project_id}/${google_artifact_registry_repository.docker.repository_id}" 32 | description = "Artifact Registry repository address" 33 | } 34 | 35 | output "service_account" { 36 | value = google_service_account.dreamboard-sa.email 37 | description = "Dreamboard GCP Service Account" 38 | } 39 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/login/login.component.css: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | .login-container { 23 | width: 500px; 24 | height: 300px; 25 | margin: 100px auto; 26 | border: 1px dotted rgb(206, 201, 201); 27 | border-radius: 16px; 28 | 29 | .center-div { 30 | width: 200px; 31 | margin: 15% auto; 32 | } 33 | 34 | .or { 35 | text-align: center; 36 | margin: 16px; 37 | } 38 | 39 | .guest-button { 40 | margin-left: 11px; 41 | } 42 | } 43 | 44 | mat-icon { 45 | font-size: 16px; 46 | } 47 | -------------------------------------------------------------------------------- /backend/app/models/image/image_request_models.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """ 16 | Module for the Data models used by the APIRouter to define the request 17 | parameters. 18 | 19 | This file defines Pydantic models specifically for structuring incoming 20 | request payloads related to image generation via the API Router. 21 | """ 22 | 23 | from models import request_models 24 | from pydantic import BaseModel 25 | 26 | 27 | class ImageRequest(BaseModel): 28 | """ 29 | Represents the basic structure for an Imagen API request. 30 | 31 | This model encapsulates a collection of `Scene` objects, where each 32 | scene contains the necessary parameters for image generation or editing. 33 | 34 | Attributes: 35 | scenes: A list of `Scene` objects, each defining a specific 36 | image generation task. 37 | """ 38 | 39 | scenes: list[request_models.Scene] 40 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/app.config.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; 23 | import { provideRouter } from '@angular/router'; 24 | 25 | import { routes } from './app.routes'; 26 | import { provideHttpClient, withFetch } from '@angular/common/http'; 27 | 28 | export const appConfig: ApplicationConfig = { 29 | providers: [ 30 | provideZoneChangeDetection({ eventCoalescing: true }), 31 | provideRouter(routes), 32 | provideHttpClient(withFetch()), 33 | ], 34 | }; 35 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/files-manager.service.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { TestBed } from '@angular/core/testing'; 23 | 24 | import { FilesManagerService } from './files-manager.service'; 25 | 26 | describe('FilesManagerService', () => { 27 | let service: FilesManagerService; 28 | 29 | beforeEach(() => { 30 | TestBed.configureTestingModule({}); 31 | service = TestBed.inject(FilesManagerService); 32 | }); 33 | 34 | it('should be created', () => { 35 | expect(service).toBeTruthy(); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/text-generation.service.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { TestBed } from '@angular/core/testing'; 23 | 24 | import { TextGenerationService } from './text-generation.service'; 25 | 26 | describe('TextGenerationService', () => { 27 | let service: TextGenerationService; 28 | 29 | beforeEach(() => { 30 | TestBed.configureTestingModule({}); 31 | service = TestBed.inject(TextGenerationService); 32 | }); 33 | 34 | it('should be created', () => { 35 | expect(service).toBeTruthy(); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/image-generation.service.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { TestBed } from '@angular/core/testing'; 23 | 24 | import { ImageGenerationService } from './image-generation.service'; 25 | 26 | describe('ImageGenerationService', () => { 27 | let service: ImageGenerationService; 28 | 29 | beforeEach(() => { 30 | TestBed.configureTestingModule({}); 31 | service = TestBed.inject(ImageGenerationService); 32 | }); 33 | 34 | it('should be created', () => { 35 | expect(service).toBeTruthy(); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/video-generation.service.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { TestBed } from '@angular/core/testing'; 23 | 24 | import { VideoGenerationService } from './video-generation.service'; 25 | 26 | describe('VideoGenerationService', () => { 27 | let service: VideoGenerationService; 28 | 29 | beforeEach(() => { 30 | TestBed.configureTestingModule({}); 31 | service = TestBed.inject(VideoGenerationService); 32 | }); 33 | 34 | it('should be created', () => { 35 | expect(service).toBeTruthy(); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/environments/environment.development.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | export const environment = { 23 | production: false, 24 | videoGenerationApiURL: 'http://127.0.0.1:8000/api/video_generation', 25 | imageGenerationApiURL: 'http://127.0.0.1:8000/api/image_generation', 26 | textGenerationApiURL: 'http://127.0.0.1:8000/api/text_generation', 27 | fileUploaderApiURL: 'http://127.0.0.1:8000/api/file_uploader', 28 | storiesStorageApiURL: 'http://127.0.0.1:8000/api/story_storage', 29 | proxyURL: 'http://127.0.0.1:3000', 30 | clientID: '', 31 | }; 32 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/story-utils.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { VideoStory } from './models/story-models'; 23 | import { v4 as uuidv4 } from 'uuid'; 24 | 25 | export function getNewVideoStory() { 26 | const videoStory: VideoStory = { 27 | id: uuidv4(), 28 | title: 'New Story', 29 | description: 'This is a new story', 30 | brandGuidelinesAdherence: '', 31 | abcdAdherence: '', 32 | scenes: [], 33 | generatedVideos: [], 34 | owner: localStorage.getItem('user')!, 35 | shareWith: [], 36 | }; 37 | 38 | return videoStory; 39 | } 40 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/scene-settings-dialog/scene-settings-dialog.component.css: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | .item-container { 23 | display: flex; 24 | justify-content: center; 25 | margin-top: 16px; 26 | 27 | mat-form-field { 28 | width: 82%; 29 | } 30 | } 31 | 32 | .next-actions { 33 | display: flex; 34 | justify-content: flex-end; 35 | margin: 16px 0px; 36 | } 37 | 38 | .back-actions { 39 | display: flex; 40 | justify-content: flex-start; 41 | margin: 16px 0px; 42 | } 43 | 44 | 45 | .close-button { 46 | margin-top: 10px; 47 | float: right; 48 | } -------------------------------------------------------------------------------- /backend/app/api/endpoints/scenario_router.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from fastapi import APIRouter, Request 16 | 17 | from models.agent.agent_model import ( 18 | Scenario, 19 | SetScenarioData, 20 | ) 21 | 22 | router = APIRouter( 23 | prefix="/scenario", 24 | responses={404: {"description": "Not found"}}, 25 | ) 26 | 27 | 28 | @router.get("/get-all") 29 | async def get_all_scenarios(request: Request) -> list[Scenario]: 30 | return request.state.scenario_service.get_all_scenarios() 31 | 32 | 33 | @router.get("/get-current-scenario") 34 | async def get_current_scenario(request: Request) -> Scenario: 35 | return request.state.scenario_service.get_current_scenario() 36 | 37 | 38 | @router.post("/set-scenario-data") 39 | async def set_scenario_data(request: Request, scenario_data: SetScenarioData): 40 | return request.state.scenario_service.set_scenario( 41 | scenario_id=scenario_data.scenario_id 42 | ) 43 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/components-communication.service.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { TestBed } from '@angular/core/testing'; 23 | 24 | import { ComponentsCommunicationService } from './components-communication.service'; 25 | 26 | describe('ComponentsCommunicationService', () => { 27 | let service: ComponentsCommunicationService; 28 | 29 | beforeEach(() => { 30 | TestBed.configureTestingModule({}); 31 | service = TestBed.inject(ComponentsCommunicationService); 32 | }); 33 | 34 | it('should be created', () => { 35 | expect(service).toBeTruthy(); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/post-video-production/post-video-production.component.html: -------------------------------------------------------------------------------- 1 |
2 | @if (story && story.generatedVideos) { 3 |

Story Title: {{ story.title }}

4 |

Story ID: {{ story.id }}

5 |
6 | @for (video of story.generatedVideos; track video.name; let i = $index) { 7 | 8 | 9 |
10 | Video Name: {{ video.name }} 11 | 12 |
13 | 14 | 17 | 18 |
19 | 25 |
26 |
27 | 28 |
29 | } 30 |
31 | 32 | } @else { 33 |
34 |

35 | Your video will show here
36 | videocamera 37 |

38 |
39 | } 40 |
41 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/sidebar/sidebar.component.css: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | .sidenav { 23 | width: 5%; 24 | padding: 20px; 25 | color: white; 26 | } 27 | 28 | mat-drawer { 29 | background-color: white; 30 | background-color: #8d779b; 31 | box-shadow: rgba(0, 0, 0, 0.25) 0px 54px 55px, 32 | rgba(0, 0, 0, 0.12) 0px -12px 30px, rgba(0, 0, 0, 0.12) 0px 4px 6px, 33 | rgba(0, 0, 0, 0.17) 0px 12px 13px, rgba(0, 0, 0, 0.09) 0px -3px 5px; 34 | border-radius: 0px; 35 | } 36 | 37 | .stories-container { 38 | margin-top: 40px; 39 | } 40 | 41 | .stories-list { 42 | margin-left: 16px; 43 | } 44 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/environments/environment-template.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | export const environment = { 23 | production: true, 24 | videoGenerationApiURL: '{BACKEND_CLOUD_RUN_SERVICE_URL}/api/video_generation', 25 | imageGenerationApiURL: '{BACKEND_CLOUD_RUN_SERVICE_URL}/api/image_generation', 26 | textGenerationApiURL: '{BACKEND_CLOUD_RUN_SERVICE_URL}/api/text_generation', 27 | fileUploaderApiURL: '{BACKEND_CLOUD_RUN_SERVICE_URL}/api/file_uploader', 28 | storiesStorageApiURL: '{BACKEND_CLOUD_RUN_SERVICE_URL}/api/story_storage', 29 | clientID: '{CLIENT_ID}', 30 | proxyURL: '', // proxy url is just api/handleRequest for Nodejs server in PROD 31 | }; 32 | -------------------------------------------------------------------------------- /backend/app/tools/text_gen.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from google.adk.tools import ToolContext 16 | from google.genai import types 17 | from services.agent.text_service import TextService 18 | 19 | 20 | async def generate_text(prompt: str, tool_context: "ToolContext") -> dict: 21 | """Generates text based on a prompt 22 | 23 | Args: 24 | prompt: The prompt to generate text from 25 | 26 | Returns: 27 | A dictionary containing the generated text and status. 28 | """ 29 | text_service = TextService() 30 | text_response = text_service.generate_markdown_text(prompt=prompt) 31 | if text_response: 32 | await tool_context.save_artifact( 33 | "text.md", 34 | types.Part.from_text(text=text_response), 35 | ) 36 | return { 37 | "status": "success", 38 | "detail": ( 39 | "Markdown text generated successfully and stored in artifacts." 40 | ), 41 | "filename": "text.md", 42 | } 43 | else: 44 | return {"image": None, "status": "failure"} 45 | -------------------------------------------------------------------------------- /backend/app/orm/creative_agents.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | - name: "text_bot" 16 | id: 2 17 | instruction: "Generate an idea in text using the generate_text tool" 18 | description: "Generates an idea in text" 19 | tools: "generate_text" 20 | modules: "text_gen" 21 | media_type: "text" 22 | use_as_root_agent: 1 23 | 24 | - name: "image_bot" 25 | id: 3 26 | instruction: "Generate an image using the generate_image tool" 27 | description: "Generates an image" 28 | tools: "generate_image" 29 | modules: "image_tools" 30 | media_type: "image" 31 | use_as_root_agent: 1 32 | 33 | - name: "video_bot" 34 | id: 4 35 | instruction: "Generate a video using the generate_video tool" 36 | description: "Generates a video" 37 | tools: "generate_video" 38 | modules: "video_gen" 39 | media_type: "video" 40 | use_as_root_agent: 1 41 | 42 | - name: "weather_bot" 43 | id: 5 44 | instruction: "Using the weather tool, it returns the weather for a given city" 45 | description: "Returns the weather for a given city" 46 | tools: "get_weather" 47 | modules: "get_weather" 48 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/navbar/navbar.component.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 23 | 24 | import { NavbarComponent } from './navbar.component'; 25 | 26 | describe('NavbarComponent', () => { 27 | let component: NavbarComponent; 28 | let fixture: ComponentFixture; 29 | 30 | beforeEach(async () => { 31 | await TestBed.configureTestingModule({ 32 | imports: [NavbarComponent], 33 | }).compileComponents(); 34 | 35 | fixture = TestBed.createComponent(NavbarComponent); 36 | component = fixture.componentInstance; 37 | fixture.detectChanges(); 38 | }); 39 | 40 | it('should create', () => { 41 | expect(component).toBeTruthy(); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/sidebar/sidebar.component.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 23 | 24 | import { SidebarComponent } from './sidebar.component'; 25 | 26 | describe('SidebarComponent', () => { 27 | let component: SidebarComponent; 28 | let fixture: ComponentFixture; 29 | 30 | beforeEach(async () => { 31 | await TestBed.configureTestingModule({ 32 | imports: [SidebarComponent], 33 | }).compileComponents(); 34 | 35 | fixture = TestBed.createComponent(SidebarComponent); 36 | component = fixture.componentInstance; 37 | fixture.detectChanges(); 38 | }); 39 | 40 | it('should create', () => { 41 | expect(component).toBeTruthy(); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/snackbar/snackbar.component.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 23 | 24 | import { SnackbarComponent } from './snackbar.component'; 25 | 26 | describe('SnackbarComponent', () => { 27 | let component: SnackbarComponent; 28 | let fixture: ComponentFixture; 29 | 30 | beforeEach(async () => { 31 | await TestBed.configureTestingModule({ 32 | imports: [SnackbarComponent], 33 | }).compileComponents(); 34 | 35 | fixture = TestBed.createComponent(SnackbarComponent); 36 | component = fixture.componentInstance; 37 | fixture.detectChanges(); 38 | }); 39 | 40 | it('should create', () => { 41 | expect(component).toBeTruthy(); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/snackbar/snackbar.component.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | /** 23 | * @fileoverview This component defines a custom Angular Material snackbar. 24 | * It provides a basic structure for displaying messages to the user, 25 | * typically with an action button to dismiss the snackbar. 26 | */ 27 | 28 | import { Component, inject } from '@angular/core'; 29 | import { MatSnackBarRef } from '@angular/material/snack-bar'; 30 | import { MatButtonModule } from '@angular/material/button'; 31 | 32 | @Component({ 33 | selector: 'app-snackbar', 34 | imports: [MatButtonModule], 35 | templateUrl: './snackbar.component.html', 36 | styleUrl: './snackbar.component.css', 37 | }) 38 | export class SnackbarComponent { 39 | snackBarRef = inject(MatSnackBarRef); 40 | } 41 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/file-uploader/file-uploader.component.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 23 | 24 | import { FileUploaderComponent } from './file-uploader.component'; 25 | 26 | describe('FileUploaderComponent', () => { 27 | let component: FileUploaderComponent; 28 | let fixture: ComponentFixture; 29 | 30 | beforeEach(() => { 31 | TestBed.configureTestingModule({ 32 | declarations: [FileUploaderComponent], 33 | }); 34 | fixture = TestBed.createComponent(FileUploaderComponent); 35 | component = fixture.componentInstance; 36 | fixture.detectChanges(); 37 | }); 38 | 39 | it('should create', () => { 40 | expect(component).toBeTruthy(); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/brainstorm/brainstorm.component.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 23 | 24 | import { BrainstormComponent } from './brainstorm.component'; 25 | 26 | describe('BrainstormComponent', () => { 27 | let component: BrainstormComponent; 28 | let fixture: ComponentFixture; 29 | 30 | beforeEach(async () => { 31 | await TestBed.configureTestingModule({ 32 | imports: [BrainstormComponent], 33 | }).compileComponents(); 34 | 35 | fixture = TestBed.createComponent(BrainstormComponent); 36 | component = fixture.componentInstance; 37 | fixture.detectChanges(); 38 | }); 39 | 40 | it('should create', () => { 41 | expect(component).toBeTruthy(); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/storyboard/storyboard.component.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 23 | 24 | import { StoryboardComponent } from './storyboard.component'; 25 | 26 | describe('StoryboardComponent', () => { 27 | let component: StoryboardComponent; 28 | let fixture: ComponentFixture; 29 | 30 | beforeEach(async () => { 31 | await TestBed.configureTestingModule({ 32 | imports: [StoryboardComponent], 33 | }).compileComponents(); 34 | 35 | fixture = TestBed.createComponent(StoryboardComponent); 36 | component = fixture.componentInstance; 37 | fixture.detectChanges(); 38 | }); 39 | 40 | it('should create', () => { 41 | expect(component).toBeTruthy(); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/app.routes.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { Routes } from '@angular/router'; 23 | import { LoginComponent } from './components/login/login.component'; 24 | import { StoryboardComponent } from './components/storyboard/storyboard.component'; 25 | import { AuthGuardLogInService } from './services/auth/auth-guard-login.service'; 26 | import { AuthGuardStoryboardService } from './services/auth/auth-guard-storyboard.service'; 27 | 28 | export const routes: Routes = [ 29 | { 30 | path: 'login', 31 | component: LoginComponent, 32 | canActivate: [AuthGuardLogInService], 33 | }, 34 | { 35 | path: 'storyboard', 36 | component: StoryboardComponent, 37 | canActivate: [AuthGuardStoryboardService], 38 | }, 39 | { path: '**', redirectTo: '/storyboard', pathMatch: 'full' }, 40 | ]; 41 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/scene-builder/scene-builder.component.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 23 | 24 | import { SceneBuilderComponent } from './scene-builder.component'; 25 | 26 | describe('SceneBuilderComponent', () => { 27 | let component: SceneBuilderComponent; 28 | let fixture: ComponentFixture; 29 | 30 | beforeEach(async () => { 31 | await TestBed.configureTestingModule({ 32 | imports: [SceneBuilderComponent], 33 | }).compileComponents(); 34 | 35 | fixture = TestBed.createComponent(SceneBuilderComponent); 36 | component = fixture.componentInstance; 37 | fixture.detectChanges(); 38 | }); 39 | 40 | it('should create', () => { 41 | expect(component).toBeTruthy(); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/image-scene-settings/image-scene-settings.component.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 23 | 24 | import { ImageSceneSettingsComponent } from './image-scene-settings.component'; 25 | 26 | describe('SceneSettingsComponent', () => { 27 | let component: ImageSceneSettingsComponent; 28 | let fixture: ComponentFixture; 29 | 30 | beforeEach(async () => { 31 | await TestBed.configureTestingModule({ 32 | imports: [ImageSceneSettingsComponent], 33 | }).compileComponents(); 34 | 35 | fixture = TestBed.createComponent(ImageSceneSettingsComponent); 36 | component = fixture.componentInstance; 37 | fixture.detectChanges(); 38 | }); 39 | 40 | it('should create', () => { 41 | expect(component).toBeTruthy(); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/stories/stories.component.css: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | .stories-container { 23 | margin-top: 8px; 24 | 25 | .scenes-container { 26 | margin-top: 16px; 27 | 28 | mat-card { 29 | margin-bottom: 16px; 30 | 31 | mat-card-subtitle { 32 | font-size: 10px; 33 | } 34 | 35 | mat-icon { 36 | margin-left: 90%; 37 | } 38 | } 39 | } 40 | 41 | .selection-buttons { 42 | display: flex; 43 | justify-content: center; 44 | 45 | button { 46 | margin-left: 5px; 47 | } 48 | } 49 | 50 | .no-stories { 51 | text-align: center; 52 | margin: 200px 0px; 53 | } 54 | } 55 | 56 | mat-form-field { 57 | margin-top: 16px; 58 | width: 95%; 59 | } 60 | 61 | h3 { 62 | margin-top: 50px; 63 | } 64 | 65 | .element-id { 66 | margin-top: 8px; 67 | font-size: 10px; 68 | } 69 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/scene-settings-dialog/scene-settings-dialog.component.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 23 | 24 | import { SceneSettingsDialogComponent } from './scene-settings-dialog.component'; 25 | 26 | describe('ConfigDialogComponent', () => { 27 | let component: SceneSettingsDialogComponent; 28 | let fixture: ComponentFixture; 29 | 30 | beforeEach(async () => { 31 | await TestBed.configureTestingModule({ 32 | imports: [SceneSettingsDialogComponent], 33 | }).compileComponents(); 34 | 35 | fixture = TestBed.createComponent(SceneSettingsDialogComponent); 36 | component = fixture.componentInstance; 37 | fixture.detectChanges(); 38 | }); 39 | 40 | it('should create', () => { 41 | expect(component).toBeTruthy(); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/post-video-production/post-video-production.component.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 23 | 24 | import { PostVideoProductionComponent } from './post-video-production.component'; 25 | 26 | describe('PostVideoProductionComponent', () => { 27 | let component: PostVideoProductionComponent; 28 | let fixture: ComponentFixture; 29 | 30 | beforeEach(async () => { 31 | await TestBed.configureTestingModule({ 32 | imports: [PostVideoProductionComponent], 33 | }).compileComponents(); 34 | 35 | fixture = TestBed.createComponent(PostVideoProductionComponent); 36 | component = fixture.componentInstance; 37 | fixture.detectChanges(); 38 | }); 39 | 40 | it('should create', () => { 41 | expect(component).toBeTruthy(); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/video-scene-settings/video-scene-settings.component.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 23 | 24 | import { VideoSceneSettingsComponent } from './video-scene-settings.component'; 25 | 26 | describe('VideoSceneSettingsComponent', () => { 27 | let component: VideoSceneSettingsComponent; 28 | let fixture: ComponentFixture; 29 | 30 | beforeEach(async () => { 31 | await TestBed.configureTestingModule({ 32 | imports: [VideoSceneSettingsComponent] 33 | }) 34 | .compileComponents(); 35 | 36 | fixture = TestBed.createComponent(VideoSceneSettingsComponent); 37 | component = fixture.componentInstance; 38 | fixture.detectChanges(); 39 | }); 40 | 41 | it('should create', () => { 42 | expect(component).toBeTruthy(); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { Component } from '@angular/core'; 23 | import { RouterOutlet } from '@angular/router'; 24 | import { MatSidenavModule } from '@angular/material/sidenav'; 25 | import { NavbarComponent } from './components/navbar/navbar.component'; 26 | import { MatButtonModule } from '@angular/material/button'; 27 | import { SidebarComponent } from './components/sidebar/sidebar.component'; 28 | 29 | declare global { 30 | interface Window { 31 | google: any; 32 | } 33 | } 34 | 35 | @Component({ 36 | selector: 'app-root', 37 | imports: [ 38 | RouterOutlet, 39 | MatSidenavModule, 40 | NavbarComponent, 41 | MatButtonModule, 42 | SidebarComponent, 43 | ], 44 | templateUrl: './app.component.html', 45 | styleUrl: './app.component.css', 46 | }) 47 | export class AppComponent { 48 | title = 'DreamBoard'; 49 | } 50 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/brainstorm/brainstorm.component.css: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | .brainstorming { 23 | display: flex; 24 | justify-content: space-around; 25 | margin-top: 40px; 26 | 27 | .campaign-setup { 28 | width: 30%; 29 | padding: 15px; 30 | margin-right: 10px; 31 | border: 1px dotted rgb(196, 193, 193); 32 | } 33 | 34 | .stories { 35 | width: 70%; 36 | padding: 15px; 37 | } 38 | 39 | mat-form-field { 40 | width: 100%; 41 | } 42 | 43 | .button-actions { 44 | display: flex; 45 | justify-content: flex-end; 46 | 47 | button { 48 | margin-right: 5px; 49 | } 50 | } 51 | 52 | .generate-button { 53 | display: flex; 54 | justify-content: center; 55 | margin-top: 30px; 56 | } 57 | 58 | .generate-images-check { 59 | margin-top: 16px; 60 | } 61 | } 62 | 63 | h2 { 64 | text-align: center; 65 | } -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/navbar/navbar.component.css: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | .navbar { 23 | background-color: #8d779b; 24 | color: #ffff; 25 | font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serifs; 26 | font-size: 40px; 27 | height: 100px; 28 | box-shadow: rgba(0, 0, 0, 0.16) 0px 3px 60px, rgba(0, 0, 0, 0.23) 0px 3px 60px; 29 | } 30 | 31 | .logo-container { 32 | display: flex; 33 | justify-content: flex-start; 34 | padding-top: 8px; 35 | 36 | div { 37 | margin: auto 0px; 38 | } 39 | } 40 | 41 | .header-container { 42 | display: flex; 43 | justify-content: space-between; 44 | 45 | .log-in-container { 46 | margin: 30px 30px 0px 0px; 47 | 48 | .log-out-button { 49 | display: flex; 50 | justify-content: flex-end; 51 | margin-left: 100px; 52 | } 53 | } 54 | .user-id-container { 55 | margin-top: 8px; 56 | font-size: 12px; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/transitions-settings-dialog/transitions-settings-dialog.component.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 23 | 24 | import { TransitionsSettingsDialogComponent } from './transitions-settings-dialog.component'; 25 | 26 | describe('CreativeDirSettingsDialogComponent', () => { 27 | let component: TransitionsSettingsDialogComponent; 28 | let fixture: ComponentFixture; 29 | 30 | beforeEach(async () => { 31 | await TestBed.configureTestingModule({ 32 | imports: [TransitionsSettingsDialogComponent], 33 | }).compileComponents(); 34 | 35 | fixture = TestBed.createComponent(TransitionsSettingsDialogComponent); 36 | component = fixture.componentInstance; 37 | fixture.detectChanges(); 38 | }); 39 | 40 | it('should create', () => { 41 | expect(component).toBeTruthy(); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/models/settings-models.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | export enum UploadedFileType { 23 | UserProvidedImage = 'UserProvidedImage', 24 | ReferenceImage = 'ReferenceImage', 25 | Video = 'Video', 26 | CreativeBrief = 'CreativeBrief', 27 | BrandGuidelines = 'BrandGuidelines', 28 | None = 'None', 29 | } 30 | 31 | export interface UploadedFile { 32 | sceneId: string; 33 | id: string; 34 | name: string; 35 | gcsUri: string; 36 | signedUri: string; 37 | gcsFusePath: string; 38 | mimeType: string; 39 | type: UploadedFileType; 40 | } 41 | 42 | export interface SelectItem { 43 | displayName: string; 44 | value: string; 45 | field1?: any; // represents any additional information for the item 46 | } 47 | 48 | export const enum UploadStatus { 49 | InProgress = 'inProgress', 50 | Cancel = 'cancel', 51 | Error = 'error', 52 | Success = 'success', 53 | } 54 | 55 | export interface APIError { 56 | error: { [id: string] : { detail: string }; } 57 | } -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/file-uploader/file-uploader.component.html: -------------------------------------------------------------------------------- 1 |
2 |
7 | 15 | @if (!uploadInProgress) { 16 |
17 | 26 |
27 | } 28 | 31 | @if (uploadInProgress) { 32 |
33 |
34 |
upload_file
35 | 36 |
37 |
38 |
39 |
40 | } 41 |
42 | @if(fileType === 'ReferenceImage') { 43 |
44 | @for (fileItem of fileItems; track fileItem.id; let i = $index) { 45 |
46 |
47 |
48 | {{ statusIcon }} 49 | 50 |
51 |
52 | @if (uploadError) { 53 |
54 | There was an error uploading the file. Please remove it and try 56 | again. 58 |
59 | } 60 |
61 | } 62 |
63 | } 64 |
65 | -------------------------------------------------------------------------------- /backend/app/tools/image_tools.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from google.adk.tools import ToolContext 16 | from google.genai import types 17 | 18 | from services.image.image_api_service import ImageService 19 | from models.request_models import Scene, CreativeDirection 20 | 21 | 22 | async def generate_image(prompt: str, tool_context: "ToolContext") -> dict: 23 | """Generates images based on a prompt 24 | 25 | Args: 26 | prompt: The prompt to generate images from 27 | 28 | Returns: 29 | A dictionary containing the generated image and status. 30 | """ 31 | image_service = ImageService() 32 | # Note: scene_num is dummy variable to reuse data structure 33 | creative_direction = CreativeDirection() 34 | scene = Scene(scene_num=1, img_prompt=prompt, creative_dir=creative_direction) 35 | image_response = image_service.generate_images_for_agent(scene) 36 | if image_response and image_response.generated_images: 37 | image_bytes = image_response.generated_images[0].image.image_bytes 38 | await tool_context.save_artifact( 39 | "image.png", 40 | types.Part.from_bytes(data=image_bytes, mime_type="image/png"), 41 | ) 42 | return { 43 | "status": "success", 44 | "detail": "Image generated successfully and stored in artifacts.", 45 | "filename": "image.png", 46 | } 47 | else: 48 | return {"image": None, "status": "failure"} 49 | -------------------------------------------------------------------------------- /backend/app/tools/video_gen.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from google.adk.tools import ToolContext 16 | from google.genai import types 17 | 18 | from services.video.veo_api_service import VeoAPIService 19 | from models.video.video_request_models import VideoSegmentRequest 20 | 21 | 22 | async def generate_video(prompt: str, tool_context: "ToolContext") -> dict: 23 | """Generates images based on a prompt 24 | 25 | Args: 26 | prompt: The prompt to generate videos from 27 | 28 | Returns: 29 | A dictionary containing the generated image and status. 30 | """ 31 | # Note: scene_id and segment_number are dummy values to reuse data structure 32 | video_segment_request = VideoSegmentRequest( 33 | prompt=prompt, scene_id="first", segment_number=1 34 | ) 35 | veo_api_service = VeoAPIService() 36 | video_response = veo_api_service.generate_video_for_agent( 37 | video_segment_request 38 | ) 39 | 40 | if video_response: 41 | video_bytes = video_response[0].video.video_bytes 42 | await tool_context.save_artifact( 43 | "video.mp4", 44 | types.Part.from_bytes(data=video_bytes, mime_type="video/mp4"), 45 | ) 46 | return { 47 | "status": "success", 48 | "detail": "Video generated successfully and stored in artifacts.", 49 | "filename": "video.mp4", 50 | } 51 | else: 52 | return {"image": None, "status": "failure"} 53 | -------------------------------------------------------------------------------- /gke/terraform/main.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | provider "google" { 16 | project = var.project_id 17 | region = var.region 18 | } 19 | 20 | provider "google-beta" { 21 | project = var.project_id 22 | region = var.region 23 | } 24 | 25 | locals { 26 | project_number = data.google_project.project.number 27 | services = toset([ 28 | "cloudresourcemanager.googleapis.com", 29 | "artifactregistry.googleapis.com", 30 | "cloudbuild.googleapis.com", 31 | "aiplatform.googleapis.com", 32 | "servicemanagement.googleapis.com", 33 | "servicecontrol.googleapis.com", 34 | "iap.googleapis.com", 35 | "container.googleapis.com", 36 | ]) 37 | } 38 | 39 | resource "google_project_service" "apis" { 40 | for_each = local.services 41 | service = each.key 42 | disable_on_destroy = false 43 | } 44 | 45 | data "google_project" "project" { 46 | project_id = var.project_id 47 | depends_on = [google_project_service.apis] 48 | } 49 | 50 | resource "google_storage_bucket" "bucket" { 51 | name = "${var.project_id}-dreamboard-bucket" 52 | location = var.region 53 | force_destroy = true 54 | 55 | public_access_prevention = "enforced" 56 | uniform_bucket_level_access = true 57 | } 58 | 59 | resource "google_artifact_registry_repository" "docker" { 60 | location = var.region 61 | repository_id = "dreamboard-docker-repo" 62 | format = "DOCKER" 63 | } 64 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { TestBed } from '@angular/core/testing'; 23 | import { AppComponent } from './app.component'; 24 | 25 | describe('AppComponent', () => { 26 | beforeEach(async () => { 27 | await TestBed.configureTestingModule({ 28 | imports: [AppComponent], 29 | }).compileComponents(); 30 | }); 31 | 32 | it('should create the app', () => { 33 | const fixture = TestBed.createComponent(AppComponent); 34 | const app = fixture.componentInstance; 35 | expect(app).toBeTruthy(); 36 | }); 37 | 38 | it(`should have the 'dreamboard' title`, () => { 39 | const fixture = TestBed.createComponent(AppComponent); 40 | const app = fixture.componentInstance; 41 | expect(app.title).toEqual('dreamboard'); 42 | }); 43 | 44 | it('should render title', () => { 45 | const fixture = TestBed.createComponent(AppComponent); 46 | fixture.detectChanges(); 47 | const compiled = fixture.nativeElement as HTMLElement; 48 | expect(compiled.querySelector('h1')?.textContent).toContain( 49 | 'Hello, dreamboard' 50 | ); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/sidebar/sidebar.component.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | /** 23 | * @fileoverview This component provides a sidebar navigation mechanism for the application. 24 | * It leverages Angular Material's MatSidenav to offer a collapsible side panel, 25 | * typically used for navigation links or supplementary content. 26 | */ 27 | 28 | import { Component, ViewChild } from '@angular/core'; 29 | import { MatDrawer, MatSidenavModule } from '@angular/material/sidenav'; 30 | import { MatButtonModule } from '@angular/material/button'; 31 | 32 | @Component({ 33 | selector: 'app-sidebar', 34 | imports: [MatSidenavModule, MatButtonModule], 35 | templateUrl: './sidebar.component.html', 36 | styleUrl: './sidebar.component.css', 37 | }) 38 | export class SidebarComponent { 39 | @ViewChild('sidenav') sidenav!: MatDrawer; 40 | 41 | /** 42 | * Toggles the open or closed state of the Material sidebar (MatDrawer). 43 | * This method is typically invoked by a button or another UI element to 44 | * show or hide the sidebar. 45 | * @returns {void} 46 | */ 47 | toggle(): void { 48 | this.sidenav.toggle(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /backend/app/services/agent/speech_to_text_service.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from typing import Optional 16 | 17 | from google.cloud import speech 18 | 19 | 20 | class SpeechToTextService: 21 | 22 | def __init__(self): 23 | # Initialize the Speech-to-Text client 24 | self.client = speech.SpeechClient() 25 | 26 | async def transcribe_audio(self, audio_content: bytes) -> Optional[str]: 27 | """ 28 | Transcribe audio content using Google Cloud Speech-to-Text. 29 | 30 | Args: 31 | audio_content: The audio content in bytes 32 | 33 | Returns: 34 | The transcribed text or None if transcription fails 35 | """ 36 | try: 37 | # Configure the audio and recognition settings 38 | audio = speech.RecognitionAudio(content=audio_content) 39 | config = speech.RecognitionConfig( 40 | encoding=speech.RecognitionConfig.AudioEncoding.WEBM_OPUS, 41 | sample_rate_hertz=48000, # WebM Opus typically uses 48kHz 42 | language_code="en-US", 43 | enable_automatic_punctuation=True, 44 | ) 45 | 46 | # Perform the transcription 47 | response = self.client.recognize(config=config, audio=audio) 48 | 49 | # Combine all transcribed text 50 | transcript = " ".join( 51 | [result.alternatives[0].transcript for result in response.results] 52 | ) 53 | return transcript 54 | 55 | except Exception as e: 56 | print(f"Error transcribing audio: {str(e)}") 57 | return None 58 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/scene-settings-dialog/scene-settings-dialog.component.html: -------------------------------------------------------------------------------- 1 |

2 | {{ title }} 3 | 12 |

13 | 14 |
15 |
16 | 17 | Scene Description 18 | 25 | 26 |
27 |
28 | 29 | 30 | 35 |
36 | 39 |
40 |
41 | 42 | 46 |
47 | 54 |
55 |
56 |
57 |
58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /backend/app/services/story_service.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Service that loads, saves, and deletes stories from Firestore.""" 16 | 17 | import os 18 | from google.cloud import firestore 19 | from typing import Dict, List, Optional 20 | 21 | class StoryService: 22 | def __init__(self): 23 | self.db = firestore.Client(project=os.getenv("GCP_PROJECT"), database=os.getenv("FIRESTORE_DB")) 24 | 25 | def save_story(self, user_id: str, story: Dict) -> None: 26 | """ 27 | Saves a story under the given user using its provided 'id'. 28 | If the story already exists, it will be overwritten. 29 | """ 30 | story_id = story.get("id") 31 | doc_ref = self.db.collection("users").document(user_id).collection("stories").document(story_id) 32 | doc_ref.set(story) 33 | 34 | def get_story(self, user_id: str, story_id: str) -> Optional[Dict]: 35 | doc_ref = self.db.collection("users").document(user_id).collection("stories").document(story_id) 36 | doc = doc_ref.get() 37 | if not doc.exists: 38 | return None 39 | data = doc.to_dict() 40 | return data 41 | 42 | def list_stories(self, user_id: str) -> List[Dict]: 43 | stories_ref = self.db.collection("users").document(user_id).collection("stories") 44 | docs = stories_ref.stream() 45 | return [{**doc.to_dict(), "id": doc.id} for doc in docs] 46 | 47 | def delete_story(self, user_id: str, story_id: str) -> None: 48 | doc_ref = self.db.collection("users").document(user_id).collection("stories").document(story_id) 49 | doc_ref.delete() -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/models/scene-models.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { ImageGenerationSettings } from './image-gen-models'; 23 | import { VideoGenerationSettings } from './video-gen-models'; 24 | 25 | export interface Scene { 26 | id: string; 27 | number: number; 28 | description: string; 29 | imagePrompt: string; 30 | } 31 | 32 | export interface SceneItem { 33 | id: string; 34 | number: number; 35 | description: string; 36 | image_prompt: string; 37 | } 38 | 39 | export interface VideoScene { 40 | id: string; 41 | number: number; 42 | description: string; 43 | imageGenerationSettings: ImageGenerationSettings; 44 | videoGenerationSettings: VideoGenerationSettings; 45 | } 46 | 47 | export interface ExportScenes { 48 | videoScenes: VideoScene[]; 49 | replaceExistingScenesOnExport: boolean; 50 | generateInitialImageForScenes: boolean; 51 | } 52 | 53 | export interface SceneValidations { 54 | scenesWithNoGeneratedVideo: number[]; 55 | invalidTextToVideoScenes: number[]; 56 | invalidScenesCutVideoParams: number[]; 57 | sceneVideosToGenerate: number[]; 58 | sceneVideosToMerge: number[]; 59 | } 60 | 61 | /* Models for backend interactions */ 62 | 63 | export interface ScenesGenerationRequest { 64 | idea: string; 65 | brand_guidelines?: string; 66 | num_scenes: number; 67 | } 68 | -------------------------------------------------------------------------------- /backend/app/services/agent/scenario_service.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from sqlmodel import Session, select 16 | 17 | from dependencies.database import engine 18 | from models.agent.agent_model import Scenario 19 | 20 | 21 | class ScenarioService: 22 | 23 | def __init__(self, default_scenario_id: int = 1): 24 | self.scenario = self._load_initial_scenario(default_scenario_id) 25 | 26 | def _load_initial_scenario(self, default_scenario_id: int) -> Scenario: 27 | """ 28 | Loads the initial scenario data 29 | 30 | Args: 31 | default_scenario_id: The ID of the default scenario 32 | 33 | Returns: 34 | The scenario data for the default scenario 35 | """ 36 | with Session(engine) as session: 37 | statement = select(Scenario).where(Scenario.id == default_scenario_id) 38 | scenario = session.exec(statement).one() 39 | return scenario 40 | 41 | def get_current_scenario(self) -> Scenario: 42 | """ 43 | Returns the scenario data for the currently set scenario 44 | 45 | Returns: 46 | The scenario data for the current scenario 47 | """ 48 | return self.scenario 49 | 50 | def set_scenario(self, scenario_id: int) -> None: 51 | """ 52 | Sets the scenario data for the currently set scenario 53 | 54 | Args: 55 | scenario: The scenario to set 56 | """ 57 | with Session(engine) as session: 58 | statement = select(Scenario).where(Scenario.id == scenario_id) 59 | scenario = session.exec(statement).one() 60 | self.scenario = scenario 61 | 62 | def get_all_scenarios(self) -> list[Scenario]: 63 | with Session(engine) as session: 64 | statement = select(Scenario) 65 | scenarios = session.exec(statement).all() 66 | return scenarios 67 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/video-generation.service.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { Injectable } from '@angular/core'; 23 | import { HttpClient } from '@angular/common/http'; 24 | import { 25 | VideoGenerationRequest, 26 | VideoGenerationResponse, 27 | } from '../models/video-gen-models'; 28 | import { environment } from '../../environments/environment'; 29 | 30 | @Injectable({ 31 | providedIn: 'root', 32 | }) 33 | export class VideoGenerationService { 34 | PROXY_URL = environment.proxyURL; 35 | BASE_URL = environment.videoGenerationApiURL; 36 | 37 | constructor(private http: HttpClient) {} 38 | 39 | generateVideosFromScenes( 40 | story_id: string, 41 | videoGeneration: VideoGenerationRequest 42 | ): any { 43 | const requestBody = { 44 | url: `${this.BASE_URL}/generate_videos_from_scenes/${story_id}`, 45 | options: { method: 'POST', data: videoGeneration }, 46 | }; 47 | return this.http.post( 48 | `${this.PROXY_URL}/api/handleRequest`, 49 | requestBody 50 | ); 51 | } 52 | 53 | mergeVideos(story_id: string, videoGeneration: VideoGenerationRequest) { 54 | const requestBody = { 55 | url: `${this.BASE_URL}/merge_videos/${story_id}`, 56 | options: { method: 'POST', data: videoGeneration }, 57 | }; 58 | return this.http.post( 59 | `${this.PROXY_URL}/api/handleRequest`, 60 | requestBody 61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/frame-extraction/frame-extraction.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | movie Extract Images from Generated Video 5 | 6 | 7 | Use a frame from a previously generated video to ground the video generation 8 | 9 | 10 | 11 |
12 |
13 | 14 | Selected Video for Image Extraction 15 | 16 | Select a scene's video 17 | @for (scene of scenes; track scene) { 18 | @if(scene.videoGenerationSettings.selectedVideo) { 19 | 20 | Scene {{ scene.number }} - {{ scene.videoGenerationSettings.selectedVideo.name }} 21 | 22 | } 23 | } 24 | 25 | 26 | 30 |
31 | 32 | @if (selectedVideoUrl) { 33 |
34 | 38 |
39 | } 40 | 41 |
42 | 43 | Time in seconds 44 | 45 | 46 | 47 | 48 | Number of frames 49 | 50 | 51 |
52 |
53 |
-------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/image-generation.service.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { Injectable } from '@angular/core'; 23 | import { HttpClient } from '@angular/common/http'; 24 | import { ImageGenerationRequest } from '../models/image-gen-models'; 25 | import { environment } from '../../environments/environment'; 26 | 27 | @Injectable({ 28 | providedIn: 'root', 29 | }) 30 | export class ImageGenerationService { 31 | PROXY_URL = environment.proxyURL; 32 | BASE_URL = environment.imageGenerationApiURL; 33 | 34 | constructor(private http: HttpClient) {} 35 | 36 | generateImage( 37 | story_id: string, 38 | imageGeneration: ImageGenerationRequest 39 | ): any { 40 | const requestBody = { 41 | url: `${this.BASE_URL}/generate_image/${story_id}`, 42 | options: { method: 'POST', data: imageGeneration }, 43 | }; 44 | return this.http.post( 45 | `${this.PROXY_URL}/api/handleRequest`, 46 | requestBody 47 | ); 48 | } 49 | 50 | uploadImage(story_id: string, imageData: FormData): any { 51 | // TODO (ae) check 52 | const requestBody = { 53 | url: `${this.BASE_URL}/upload_file/${story_id}`, 54 | options: { method: 'POST', data: imageData }, 55 | }; 56 | /* { 57 | reportProgress: true, 58 | observe: 'events', 59 | } */ 60 | return this.http.post( 61 | `${this.PROXY_URL}/api/handleFileUploadRequest`, 62 | requestBody 63 | ); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/models/story-models.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { Scene, SceneItem } from './scene-models'; 23 | import { VideoScene } from './scene-models'; 24 | import { Video } from './video-gen-models'; 25 | 26 | export interface Story { 27 | id: string; 28 | title: string; 29 | description: string; 30 | brandGuidelinesAdherence: string; 31 | abcdAdherence: string; 32 | scenes: Scene[]; 33 | } 34 | 35 | export interface VideoStory { 36 | id: string; 37 | title: string; 38 | description: string; 39 | brandGuidelinesAdherence: string; 40 | abcdAdherence: string; 41 | scenes: VideoScene[]; 42 | generatedVideos: Video[]; 43 | owner: string; 44 | shareWith: string[]; 45 | } 46 | 47 | export interface ExportStory { 48 | story: VideoStory; 49 | replaceExistingStoryOnExport: boolean; 50 | generateInitialImageForScenes: boolean; 51 | } 52 | 53 | /* Models for backend interactions */ 54 | 55 | export interface StoriesGenerationRequest { 56 | num_stories: number; 57 | creative_brief_idea: string; 58 | target_audience: string; 59 | brand_guidelines?: string; 60 | video_format: string; 61 | num_scenes: number; 62 | } 63 | 64 | export interface StoryItem { 65 | id: string; 66 | title: string; 67 | description: string; 68 | brand_guidelines_adherence: string; 69 | abcd_adherence: string; 70 | scenes: SceneItem[]; 71 | } 72 | 73 | export interface ExtractTextItem { 74 | file_gcs_uri: string; 75 | file_type: string; 76 | } 77 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/post-video-production/post-video-production.component.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | /** 23 | * @fileoverview This component handles the display and management of the final generated video. 24 | * It subscribes to updates from other components to receive the generated video data and 25 | * dynamically updates the video player in the template. 26 | */ 27 | 28 | import { Component, ViewChild, ElementRef } from '@angular/core'; 29 | import { MatButtonModule } from '@angular/material/button'; 30 | import { MatIconModule } from '@angular/material/icon'; 31 | import { MatCardModule } from '@angular/material/card'; 32 | import { ComponentsCommunicationService } from '../../services/components-communication.service'; 33 | import { VideoStory } from '../../models/story-models'; 34 | 35 | @Component({ 36 | selector: 'app-post-video-production', 37 | imports: [MatButtonModule, MatIconModule, MatCardModule], 38 | templateUrl: './post-video-production.component.html', 39 | styleUrl: './post-video-production.component.css', 40 | }) 41 | export class PostVideoProductionComponent { 42 | story!: VideoStory; 43 | @ViewChild('finalVideo', { static: false }) videoElementRef!: ElementRef; 44 | 45 | constructor( 46 | private componentsCommunicationService: ComponentsCommunicationService 47 | ) { 48 | componentsCommunicationService.videoGenerated$.subscribe( 49 | (story: VideoStory) => { 50 | this.story = story; 51 | } 52 | ); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /backend/app/services/agent/text_service.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from typing import Optional 16 | 17 | import os 18 | from google import genai 19 | import traceback 20 | from google.genai import types 21 | 22 | 23 | class TextService: 24 | 25 | def __init__( 26 | self, project_id: Optional[str] = None, location: Optional[str] = None 27 | ): 28 | try: 29 | self.project_id = project_id or os.getenv("GOOGLE_CLOUD_PROJECT") 30 | self.location = location or os.getenv( 31 | "GOOGLE_CLOUD_LOCATION", "us-central1" 32 | ) 33 | 34 | if not self.project_id: 35 | raise ValueError( 36 | "Google Cloud project ID must be provided either as an argument " 37 | "or through the GOOGLE_CLOUD_PROJECT environment variable." 38 | ) 39 | 40 | self.client = genai.Client( 41 | vertexai=True, project=self.project_id, location=self.location 42 | ) 43 | 44 | except Exception as e: 45 | print(f"Error initializing ImagenService: {str(e)}") 46 | traceback.print_exc() 47 | raise 48 | 49 | def generate_markdown_text( 50 | self, prompt: str, model: str = "gemini-2.5-flash" 51 | ) -> str: 52 | """Generates a text response based on the given prompt using a specified model. 53 | Returns all text in markdown format 54 | 55 | Args: 56 | prompt (str): The input prompt for text generation. 57 | model (str, optional): The model to use for text generation. 58 | Defaults to "gemini-2.5-pro-preview-06-05\t". 59 | """ 60 | 61 | response = self.client.models.generate_content( 62 | model=model, 63 | contents=prompt, 64 | config=types.GenerateContentConfig( 65 | system_instruction="Return all responses in Markdown format" 66 | ), 67 | ) 68 | return response.text 69 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/file-uploader/file-uploader.component.scss: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | .file-uploader-container { 23 | .file-uploader-container-input { 24 | text-align: center; 25 | 26 | margin-top: 14px; 27 | 28 | input { 29 | display: none; 30 | } 31 | 32 | .supported-formats { 33 | margin-top: 3px; 34 | font-size: 10px; 35 | } 36 | } 37 | 38 | .file-hover { 39 | background-color: rgb(218, 213, 213); 40 | } 41 | 42 | .files-container { 43 | margin: 10px 5px 10px 5px; 44 | max-height: 150px; 45 | overflow-y: auto; 46 | 47 | .file { 48 | background-color: #f1eded; 49 | padding: 8px 8px 0px 8px; 50 | border-radius: 20px; 51 | 52 | .file-info { 53 | display: flex; 54 | justify-content: space-between; 55 | 56 | .file-info-details { 57 | width: 70%; 58 | 59 | label { 60 | padding: 5px; 61 | vertical-align: super; 62 | } 63 | } 64 | 65 | .file-progress-details { 66 | width: 16%; 67 | 68 | label { 69 | padding: 5px 0px; 70 | vertical-align: super; 71 | } 72 | } 73 | 74 | .scale-icon { 75 | transform: scale(0.6); 76 | } 77 | 78 | .progress-bar-container { 79 | width: 100%; 80 | } 81 | } 82 | 83 | .upload-error-message { 84 | padding: 5px; 85 | font-size: 10px; 86 | color: red; 87 | } 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/stories-storage.service.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { Injectable } from '@angular/core'; 23 | import { HttpClient } from '@angular/common/http'; 24 | import { environment } from '../../environments/environment.development'; 25 | import { VideoStory } from '../models/story-models'; 26 | 27 | @Injectable({ 28 | providedIn: 'root', 29 | }) 30 | export class StoriesStorageService { 31 | PROXY_URL = environment.proxyURL; 32 | BASE_URL = environment.storiesStorageApiURL; 33 | 34 | constructor(private http: HttpClient) {} 35 | 36 | addNewStory(userId: string, newStory: VideoStory): any { 37 | const requestBody = { 38 | url: `${this.BASE_URL}/save_story/${userId}`, 39 | options: { method: 'POST', data: newStory }, 40 | }; 41 | return this.http.post( 42 | `${this.PROXY_URL}/api/handleRequest`, 43 | requestBody 44 | ); 45 | } 46 | 47 | getStoriesByUserId(userId: string): any { 48 | const requestBody = { 49 | url: `${this.BASE_URL}/list_all_stories/${userId}`, 50 | options: { method: 'GET' }, 51 | }; 52 | return this.http.post( 53 | `${this.PROXY_URL}/api/handleRequest`, 54 | requestBody 55 | ); 56 | } 57 | 58 | deleteStoryById(userId: string, storyId: string): any { 59 | const requestBody = { 60 | url: `${this.BASE_URL}/remove_story/${userId}/${storyId}`, 61 | options: { method: 'DELETE' }, 62 | }; 63 | return this.http.post( 64 | `${this.PROXY_URL}/api/handleRequest`, 65 | requestBody 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /gke/terraform/cluster.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | resource "google_compute_network" "vpc" { 16 | name = "dreamboard-vpc" 17 | auto_create_subnetworks = false 18 | } 19 | 20 | resource "google_compute_subnetwork" "subnet" { 21 | name = "dreamboard-${var.region}" 22 | region = var.region 23 | network = google_compute_network.vpc.id 24 | ip_cidr_range = "10.0.0.0/16" 25 | 26 | secondary_ip_range { 27 | range_name = "services-range" 28 | ip_cidr_range = "192.168.0.0/24" 29 | } 30 | 31 | secondary_ip_range { 32 | range_name = "pods-range" 33 | ip_cidr_range = "192.168.1.0/24" 34 | } 35 | } 36 | 37 | resource "google_compute_address" "static_address" { 38 | name = "regional-static-address" 39 | region = var.region 40 | address_type = "EXTERNAL" 41 | network_tier = "PREMIUM" 42 | } 43 | 44 | resource "google_container_cluster" "dreamboard-cluster" { 45 | name = "dreamboard-cluster" 46 | location = var.region 47 | enable_autopilot = true 48 | deletion_protection = false 49 | 50 | network = google_compute_network.vpc.id 51 | subnetwork = google_compute_subnetwork.subnet.id 52 | 53 | ip_allocation_policy { 54 | services_secondary_range_name = google_compute_subnetwork.subnet.secondary_ip_range[0].range_name 55 | cluster_secondary_range_name = google_compute_subnetwork.subnet.secondary_ip_range[1].range_name 56 | } 57 | 58 | release_channel { 59 | channel = "REGULAR" 60 | } 61 | 62 | control_plane_endpoints_config { 63 | dns_endpoint_config { 64 | allow_external_traffic = true 65 | } 66 | } 67 | 68 | master_authorized_networks_config {} 69 | 70 | workload_identity_config { 71 | workload_pool = "${var.project_id}.svc.id.goog" 72 | } 73 | 74 | addons_config { 75 | gcs_fuse_csi_driver_config { 76 | enabled = true 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/navbar/navbar.component.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | /** 23 | * @fileoverview This component represents the main navigation bar of the application. 24 | * It provides a consistent header across different views and can be extended to include 25 | * navigation links, branding, and user-related elements. 26 | */ 27 | 28 | import { Component } from '@angular/core'; 29 | import { Router } from '@angular/router'; 30 | import { MatButtonModule } from '@angular/material/button'; 31 | import { MatIconModule } from '@angular/material/icon'; 32 | import { ComponentsCommunicationService } from '../../services/components-communication.service'; 33 | 34 | @Component({ 35 | selector: 'app-navbar', 36 | standalone: true, 37 | imports: [MatButtonModule, MatIconModule], 38 | templateUrl: './navbar.component.html', 39 | styleUrl: './navbar.component.css', 40 | }) 41 | export class NavbarComponent { 42 | user: string | null = localStorage.getItem('user'); 43 | 44 | constructor( 45 | private componentsCommunicationService: ComponentsCommunicationService, 46 | private router: Router 47 | ) { 48 | componentsCommunicationService.userLoggedInSource$.subscribe( 49 | (loggedIn: boolean) => { 50 | if (loggedIn) { 51 | this.user = localStorage.getItem('user'); 52 | } else { 53 | this.user = null; 54 | } 55 | } 56 | ); 57 | } 58 | 59 | logOut() { 60 | // TODO (ae) log out with Google button 61 | localStorage.removeItem('user'); 62 | this.user = localStorage.getItem('user'); 63 | this.router.navigate(['/login']); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /gke/manifests/dreamboard-app.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: dreamboard 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: dreamboard 10 | template: 11 | metadata: 12 | labels: 13 | app: dreamboard 14 | annotations: 15 | gke-gcsfuse/volumes: "true" 16 | gke-gcsfuse/cpu-limit: "2" 17 | gke-gcsfuse/memory-limit: "8Gi" 18 | gke-gcsfuse/ephemeral-storage-limit: "0" 19 | spec: 20 | serviceAccount: dreamboard-gke-sa 21 | containers: 22 | - name: frontend 23 | imagePullPolicy: Always 24 | image: {repo_address}/dreamboard-frontend:latest 25 | ports: 26 | - containerPort: 8080 27 | volumeMounts: 28 | - name: gcs-fuse-csi-ephemeral 29 | mountPath: /code/app/mounted_files 30 | - name: backend 31 | imagePullPolicy: Always 32 | image: {repo_address}/dreamboard-backend:latest 33 | ports: 34 | - containerPort: 8000 35 | env: 36 | - name: PROJECT_ID 37 | value: {project_id} 38 | - name: LOCATION 39 | value: {region} 40 | - name: GCS_BUCKET 41 | value: {bucket} 42 | volumeMounts: 43 | - name: gcs-fuse-csi-ephemeral 44 | mountPath: /code/app/mounted_files 45 | volumes: 46 | - name: gke-gcsfuse-cache 47 | emptyDir: 48 | medium: Memory 49 | - name: gcs-fuse-csi-ephemeral 50 | csi: 51 | driver: gcsfuse.csi.storage.gke.io 52 | volumeAttributes: 53 | bucketName: {bucket} 54 | mountOptions: "implicit-dirs,file-cache:enable-parallel-downloads:true,file-cache:parallel-downloads-per-file:100,file-cache:max-parallel-downloads:-1,file-cache:download-chunk-size-mb:10,file-cache:max-size-mb:-1" 55 | --- 56 | apiVersion: v1 57 | kind: Service 58 | metadata: 59 | name: dreamboard-svc 60 | annotations: 61 | networking.gke.io/load-balancer-ip-addresses: {ip_address} 62 | spec: 63 | type: LoadBalancer 64 | loadBalancerIP: {ip_address} 65 | ports: 66 | - name: frontend 67 | protocol: TCP 68 | port: 80 69 | targetPort: 8080 70 | - name: backend 71 | protocol: TCP 72 | port: 8000 73 | targetPort: 8000 74 | selector: 75 | app: dreamboard 76 | --- 77 | apiVersion: v1 78 | kind: ServiceAccount 79 | metadata: 80 | annotations: 81 | iam.gke.io/gcp-service-account: {service_account_email} 82 | name: dreamboard-gke-sa 83 | namespace: default 84 | -------------------------------------------------------------------------------- /gke/terraform/iam.tf: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | locals { 16 | iam_bindings = { 17 | 0 = { 18 | member = "serviceAccount:${google_service_account.dreamboard-sa.email}" 19 | role = "roles/storage.admin" 20 | }, 21 | 1 = { 22 | member = "serviceAccount:${google_service_account.dreamboard-sa.email}" 23 | role = "roles/aiplatform.user" 24 | }, 25 | 2 = { 26 | member = "serviceAccount:${google_service_account.dreamboard-sa.email}" 27 | role = "roles/logging.logWriter" 28 | }, 29 | 3 = { 30 | member = "serviceAccount:${google_service_account.dreamboard-sa.email}" 31 | role = "roles/servicemanagement.serviceController" 32 | }, 33 | 4 = { 34 | member = "serviceAccount:${google_service_account.dreamboard-sa.email}" 35 | role = "roles/artifactregistry.reader" 36 | }, 37 | 5 = { 38 | member = "serviceAccount:${google_service_account.dreamboard-sa.email}" 39 | role = "roles/container.defaultNodeServiceAccount" 40 | } 41 | 6 = { 42 | member = "serviceAccount:${google_service_account.dreamboard-sa.email}" 43 | role = "roles/iam.serviceAccountTokenCreator" 44 | } 45 | } 46 | } 47 | 48 | resource "google_service_account" "dreamboard-sa" { 49 | project = var.project_id 50 | account_id = "dreamboard-account" 51 | display_name = "Dreamboard Cloud Run SA." 52 | } 53 | 54 | resource "google_project_iam_member" "bindings" { 55 | for_each = local.iam_bindings 56 | project = var.project_id 57 | role = each.value.role 58 | member = each.value.member 59 | 60 | depends_on = [ 61 | google_project_service.apis, 62 | ] 63 | } 64 | 65 | # Allow GKE account to use the dreamboard SA via WIF 66 | resource "google_service_account_iam_member" "gke-sa-iam" { 67 | service_account_id = google_service_account.dreamboard-sa.id 68 | role = "roles/iam.workloadIdentityUser" 69 | member = "serviceAccount:${var.project_id}.svc.id.goog[default/dreamboard-gke-sa]" 70 | } 71 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/files-manager.service.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { Injectable } from '@angular/core'; 23 | import { HttpClient } from '@angular/common/http'; 24 | import { environment } from '../../environments/environment'; 25 | import { UploadedFileType } from '../models/settings-models'; 26 | 27 | @Injectable({ 28 | providedIn: 'root', 29 | }) 30 | export class FilesManagerService { 31 | PROXY_URL = environment.proxyURL; 32 | BASE_URL = environment.fileUploaderApiURL; 33 | 34 | constructor(private http: HttpClient) {} 35 | 36 | uploadFile( 37 | story_id: string, 38 | fileType: UploadedFileType, 39 | fileData: FormData 40 | ): any { 41 | let bucketPath = ''; 42 | if ( 43 | fileType === UploadedFileType.ReferenceImage || 44 | fileType === UploadedFileType.UserProvidedImage 45 | ) { 46 | } 47 | switch (fileType) { 48 | case UploadedFileType.ReferenceImage: 49 | case UploadedFileType.UserProvidedImage: 50 | bucketPath = `${story_id}@images`; 51 | break; 52 | case UploadedFileType.CreativeBrief: 53 | case UploadedFileType.BrandGuidelines: 54 | case UploadedFileType.Video: 55 | bucketPath = `${story_id}`; 56 | break; 57 | default: 58 | console.log(`No file type supported ${fileType}.`); 59 | break; 60 | } 61 | // Append bucket where the file will be uploaded to 62 | fileData.append('bucketPath', bucketPath); 63 | return this.http.post( 64 | `${this.PROXY_URL}/api/handleFileUploadRequest`, 65 | fileData, 66 | { 67 | reportProgress: true, 68 | observe: 'events', 69 | } 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /backend/app/models/text/text_gen_models.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """ 16 | Modules to define business logic modules. 17 | 18 | This file contains data models (dataclasses) used across the application 19 | to represent entities related to text generation, such as generated scene 20 | items and the structured responses from text generation APIs. 21 | """ 22 | 23 | from dataclasses import dataclass 24 | 25 | 26 | @dataclass 27 | class SceneItem: 28 | """ 29 | Represents a single generated scene, typically brainstormed by a text 30 | generation model. 31 | 32 | Attributes: 33 | number: The sequential number of the scene. 34 | description: A textual description of the scene's content. 35 | brand_guidelines_alignment: An optional field indicating how well 36 | the scene aligns with specified brand 37 | guidelines. 38 | image_prompt: An optional image prompt derived from the scene 39 | description. 40 | """ 41 | 42 | number: int 43 | description: str 44 | brand_guidelines_alignment: str | None = None 45 | image_prompt: str | None = None 46 | 47 | 48 | @dataclass 49 | class StoryItem: 50 | """Represents a story""" 51 | 52 | id: str 53 | title: str 54 | description: str 55 | brand_guidelines_adherence: str 56 | abcd_adherence: str 57 | scenes: list[SceneItem] 58 | 59 | 60 | @dataclass 61 | class TextGenerationResponse: 62 | """ 63 | Represents the structured response from a text generation API call. 64 | 65 | Attributes: 66 | new_prompt: The newly generated or enhanced text prompt. 67 | done: A boolean flag indicating if the generation operation is 68 | complete. 69 | operation_name: The name of the asynchronous operation, useful for 70 | tracking its status. 71 | execution_message: Any message or status detail about the execution 72 | of the text generation. 73 | """ 74 | 75 | new_prompt: str 76 | done: bool 77 | operation_name: str 78 | execution_message: str 79 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/services/frame-extraction.service.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { Injectable } from '@angular/core'; 23 | import { HttpClient } from '@angular/common/http'; 24 | import { Observable } from 'rxjs'; 25 | import { map } from 'rxjs/operators'; 26 | import { environment } from '../../environments/environment'; 27 | import { Image } from '../models/image-gen-models'; 28 | 29 | @Injectable({ 30 | providedIn: 'root', 31 | }) 32 | export class FrameExtractionService { 33 | private apiUrl = `${environment.videoGenerationApiURL}/extract_frames`; 34 | private handleRequestUrl = `${environment.proxyURL}/api/handleRequest`; 35 | 36 | constructor(private http: HttpClient) {} 37 | 38 | extractFrames( 39 | gcs_uri: string, 40 | story_id: string, 41 | scene_num: string, 42 | time_sec: number, 43 | frame_count: number 44 | ): Observable { 45 | const body = { 46 | gcs_uri, 47 | story_id, 48 | scene_num, 49 | time_sec, 50 | frame_count, 51 | }; 52 | const request = { 53 | url: this.apiUrl, 54 | options: { 55 | method: 'POST', 56 | data: body, 57 | }, 58 | }; 59 | return this.http.post(this.handleRequestUrl, request).pipe( 60 | map((response: any) => { 61 | if (response.data && Array.isArray(response.data)) { 62 | response.data = response.data.map((image: any): Image => ({ 63 | id: image.id, 64 | name: image.name, 65 | gcsUri: image.gcs_uri, 66 | signedUri: image.signed_uri, 67 | gcsFusePath: image.gcs_fuse_path, 68 | mimeType: image.mime_type, 69 | })); 70 | } 71 | return response; 72 | }) 73 | ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /backend/app/services/agent/text_to_speech_service.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from typing import Optional 16 | 17 | from google.cloud import texttospeech 18 | 19 | 20 | class TextToSpeechService: 21 | 22 | def __init__(self): 23 | try: 24 | # Initialize the Text-to-Speech client 25 | self.client = texttospeech.TextToSpeechClient() 26 | print("TextToSpeechService initialized successfully") 27 | except Exception as e: 28 | print(f"Error initializing TextToSpeechService: {str(e)}") 29 | raise 30 | 31 | async def text_to_speech(self, text: str) -> Optional[bytes]: 32 | """ 33 | Convert text to speech using Google Cloud Text-to-Speech. 34 | 35 | Args: 36 | text: The text to convert to speech 37 | 38 | Returns: 39 | The audio content in bytes or None if conversion fails 40 | """ 41 | try: 42 | print(f"Attempting to convert text to speech: {text[:100]}...") 43 | 44 | # Set the text input to be synthesized 45 | synthesis_input = texttospeech.SynthesisInput(text=text) 46 | 47 | # Build the voice request 48 | voice = texttospeech.VoiceSelectionParams( 49 | language_code="en-US", 50 | name="en-US-Chirp3-HD-Zephyr", # Using a neural voice for better quality 51 | ) 52 | 53 | # Select the type of audio file 54 | audio_config = texttospeech.AudioConfig( 55 | audio_encoding=texttospeech.AudioEncoding.MP3, 56 | speaking_rate=1.0, 57 | pitch=0.0, 58 | ) 59 | 60 | print("Sending request to Google Cloud Text-to-Speech API...") 61 | # Perform the text-to-speech request 62 | response = self.client.synthesize_speech( 63 | input=synthesis_input, voice=voice, audio_config=audio_config 64 | ) 65 | 66 | print( 67 | "Received response from API, audio content length:" 68 | f" {len(response.audio_content)} bytes" 69 | ) 70 | return response.audio_content 71 | 72 | except Exception as e: 73 | print(f"Error converting text to speech: {str(e)}") 74 | return None 75 | -------------------------------------------------------------------------------- /backend/app/api/router.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """ 16 | Application Router that registers all the application endpoints. 17 | 18 | This module serves as the main entry point for API routing, consolidating 19 | routers from various functional areas (video, image, and text generation) 20 | into a single, unified API. 21 | """ 22 | from dotenv import load_dotenv 23 | from fastapi import routing 24 | import os 25 | 26 | from api.endpoints import ( 27 | image_gen_routes, 28 | text_gen_routes, 29 | video_gen_routes, 30 | file_uploader_routes, 31 | story_routes, 32 | ) 33 | 34 | load_dotenv() 35 | 36 | # Create the main API router for the application. 37 | api_router = routing.APIRouter() 38 | 39 | # Include specific routers for different functionalities. 40 | # Each router is tagged for better documentation and organization in 41 | # the OpenAPI (Swagger UI) interface. 42 | api_router.include_router( 43 | video_gen_routes.video_gen_router, tags=["video_gen_routes"] 44 | ) 45 | api_router.include_router( 46 | image_gen_routes.image_gen_router, tags=["image_gen_routes"] 47 | ) 48 | api_router.include_router( 49 | text_gen_routes.text_gen_router, tags=["text_gen_routes"] 50 | ) 51 | api_router.include_router( 52 | file_uploader_routes.file_uploader_router, tags=["file_uploader_routes"] 53 | ) 54 | api_router.include_router(story_routes.story_router, tags=["story_routes"]) 55 | 56 | # Agent Routes 57 | if os.getenv("USE_AGENTS"): 58 | 59 | from api.endpoints import login_router, scenario_router, agent_router 60 | from api.admin import agents_crud, scenarios_crud, subagent_links_crud 61 | 62 | api_router.include_router(login_router.router, tags=["user"]) 63 | api_router.include_router(agent_router.router, tags=["agent"]) 64 | api_router.include_router(scenario_router.router, tags=["scenario"]) 65 | api_router.include_router(agents_crud.router, tags=["admin-agents"]) 66 | api_router.include_router(scenarios_crud.router, tags=["admin-scenarios"]) 67 | api_router.include_router( 68 | subagent_links_crud.router, 69 | tags=["admin-subagent-links"], 70 | ) 71 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/styles.css: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | html, 23 | body { 24 | height: 100%; 25 | } 26 | body { 27 | margin: 0; 28 | font-family: Roboto, "Helvetica Neue", sans-serif; 29 | } 30 | 31 | /* Image / Video selector */ 32 | 33 | :host { 34 | flex: 1; 35 | } 36 | 37 | .carousel { 38 | position: relative; 39 | height: 100%; 40 | width: 100%; 41 | overflow: hidden; 42 | border-radius: 0.5em; 43 | } 44 | 45 | .generated-file, 46 | .generated-image { 47 | position: absolute; 48 | top: 0; 49 | left: 0; 50 | width: 100%; 51 | height: 100%; 52 | object-fit: cover; 53 | transition: transform 150ms cubic-bezier(0.25, 0.46, 0.45, 0.84); 54 | border-radius: 0.5em; 55 | } 56 | 57 | .generated-image:hover { 58 | transform: scale(1.025); 59 | } 60 | 61 | /* Next and Prev buttons */ 62 | 63 | .carousel-buttons { 64 | border: none; 65 | background-color: transparent; 66 | outline: 0; 67 | position: absolute; 68 | cursor: pointer; 69 | display: flex; 70 | flex-direction: column; 71 | justify-content: center; 72 | padding: 0.5em; 73 | color: white; 74 | font-weight: bold; 75 | font-size: 3em; 76 | user-select: none; 77 | height: 100%; 78 | opacity: 80%; 79 | transition: opacity 150ms cubic-bezier(0.25, 0.46, 0.45, 0.84); 80 | 81 | &:hover, 82 | &:focus { 83 | opacity: 1; 84 | } 85 | 86 | &.next { 87 | right: 0; 88 | } 89 | &.prev { 90 | left: 0; 91 | } 92 | } 93 | 94 | .arrow { 95 | display: block; 96 | border-left: 0.1em solid white; 97 | border-bottom: 0.1em solid white; 98 | width: 0.5em; 99 | height: 0.5em; 100 | 101 | &.left { 102 | transform: rotate(45deg); 103 | } 104 | &.right { 105 | transform: rotate(225deg); 106 | } 107 | } -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/scene-builder/scene-builder.component.css: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | .scenes-container { 23 | display: flex; 24 | justify-content: center; 25 | flex-wrap: wrap; 26 | 27 | mat-card-subtitle { 28 | font-size: 10px; 29 | } 30 | } 31 | 32 | .scene-card { 33 | max-width: 500px; 34 | margin: 32px 16px; 35 | 36 | mat-card-header { 37 | mat-icon { 38 | margin-left: 85px; 39 | } 40 | } 41 | 42 | .scene-image { 43 | width: 95%; 44 | margin: auto; 45 | border: 1px solid rgb(192, 191, 191); 46 | border-radius: 10px; 47 | 48 | img { 49 | max-width: 100%; 50 | max-height: 100%; 51 | } 52 | 53 | p { 54 | margin: 100px; 55 | text-align: center; 56 | } 57 | } 58 | 59 | .gen-video-container { 60 | video { 61 | width: 100%; 62 | height: 100%; 63 | object-fit: cover; 64 | transition: transform 150ms cubic-bezier(0.25, 0.46, 0.45, 0.84); 65 | border-radius: 0.5em; 66 | } 67 | } 68 | } 69 | 70 | .header-image { 71 | background-image: url("../../../../public/scene.png"); 72 | background-size: cover; 73 | border-radius: 0px; 74 | } 75 | 76 | .actions { 77 | margin-top: 12px; 78 | } 79 | 80 | .header-actions { 81 | display: flex; 82 | justify-content: flex-end; 83 | margin: 20px 100px 0px 0px; 84 | 85 | button { 86 | margin-right: 8px; 87 | } 88 | } 89 | 90 | .initial-add-scene { 91 | width: 30%; 92 | margin: 5% auto; 93 | border: 1px dotted gray; 94 | height: 300px; 95 | 96 | div { 97 | margin: 5% auto; 98 | text-align: center; 99 | 100 | button { 101 | width: 200px; 102 | height: 200px; 103 | } 104 | } 105 | } 106 | 107 | .story-id { 108 | font-size: 10px; 109 | } 110 | 111 | .transition { 112 | margin-top: 250px; 113 | } 114 | -------------------------------------------------------------------------------- /backend/README.md: -------------------------------------------------------------------------------- 1 | # DreamBoard Backend Code 2 | 3 | This directory contains the backend code to run the AI text/image/video generation services of DreamBoard. The code is to be deployed on GCP as a Cloud Run Service and accessed as an API. The backend is FastAPI-based and can run individually as an API server without the frontend. 4 | 5 | # Structure 6 | 7 | The general folder structure is as follows under backend/app: 8 | 9 | - api: Contains backend API routing code. 10 | - endpoints: Endpoints for each type of AI generation (text, image, video). 11 | - core: Contains configuration of the backend server. 12 | - dreamboard: (optional) Folder used for local/development environments. Environment variable must be set to "DEV" to use this folder. 13 | - models: Contains API request and response objects for text/image/video. 14 | - prompts: Prompts used to for text/image/video generation. 15 | - services: Actual code that runs the generation. 16 | - tests: Directory for test cases. 17 | 18 | ## Requirements 19 | 20 | - A Google Cloud Platform project with access to the following: 21 | - Veo3 22 | - Imagen4 23 | - Gemini 24 | - Cloud Storage FUSE 25 | - Cloud Storage Bucket - to store the image and video results 26 | - A service account to invoke Cloud Run Service, start AI generation, and other associated compute access. Please see the deploy_backend.sh script for specific service account permissions 27 | - Deployment individual to have permission to the following: 28 | - Build Cloud Run Service 29 | - Create Cloud Storage Buckets 30 | - Enable APIs 31 | - Create service account and apply IAM permissions (if creating at deployment time) 32 | 33 | # Installation 34 | 35 | DreamBoard can be deployed locally on a laptop for personal use or on Google Cloud as Cloud Run Service. 36 | 37 | ### Deploy on Google Cloud 38 | 39 | Run `deploy_backend.sh` in the backend folder. 40 | 41 | Make note of the following items for use in deploying the frontend: 42 | - GCP Project Id 43 | - Cloud Storage Bucket Name 44 | - Location 45 | - Cloud Run Service Name Deployed 46 | 47 | If you wish to change the name of items such as the service account name, service name, or bucket name you may modify the `deploy_backend.sh`. Follow the prompts to create the service. 48 | 49 | 50 | ### Deploy Locally 51 | 52 | Locally, this code can run with the following commands in a Linux-based CLI (change directory to backend directory first): 53 | 54 | - `cd /backend/app` 55 | - `uv add -r requirements.txt` 56 | - `gcloud auth application-default login` 57 | 58 | Create a `.env` folder in `/backend/app` (next to `main.py`) with the following fields: 59 | 60 | ``` 61 | - PROJECT_ID= 62 | - LOCATION= 63 | - GCS_BUCKET= 64 | - ENV=dev 65 | - FIRESTORE_DB=dreamboard-db 66 | - USE_AUTH_MIDDLEWARE=true 67 | ``` 68 | 69 | - `uv run fastapi dev app/main.py` 70 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/storyboard/storyboard.component.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | /** 23 | * @fileoverview This component serves as the main container for the video storyboard application. 24 | * It manages the different stages of video creation, such as brainstorming, scene building, 25 | * and post-production, using Angular Material tabs. It also handles inter-component communication 26 | * to switch between these tabs. 27 | */ 28 | 29 | import { Component } from '@angular/core'; 30 | import { MatSidenavModule } from '@angular/material/sidenav'; 31 | import { MatButtonModule } from '@angular/material/button'; 32 | import { MatIconModule } from '@angular/material/icon'; 33 | import { MatTabsModule } from '@angular/material/tabs'; 34 | import { StoriesListComponent } from '../stories-list/stories-list.component'; 35 | import { BrainstormComponent } from '../brainstorm/brainstorm.component'; 36 | import { SceneBuilderComponent } from '../scene-builder/scene-builder.component'; 37 | import { PostVideoProductionComponent } from '../post-video-production/post-video-production.component'; 38 | import { ComponentsCommunicationService } from '../../services/components-communication.service'; 39 | 40 | @Component({ 41 | selector: 'app-storyboard', 42 | imports: [ 43 | MatSidenavModule, 44 | MatButtonModule, 45 | MatIconModule, 46 | MatTabsModule, 47 | StoriesListComponent, 48 | BrainstormComponent, 49 | SceneBuilderComponent, 50 | PostVideoProductionComponent, 51 | ], 52 | templateUrl: './storyboard.component.html', 53 | styleUrl: './storyboard.component.css', 54 | }) 55 | export class StoryboardComponent { 56 | selectedTab: number = 0; 57 | 58 | constructor( 59 | private componentsCommunicationService: ComponentsCommunicationService 60 | ) { 61 | componentsCommunicationService.tabChangedSource$.subscribe( 62 | (tabNumber: number) => { 63 | this.selectedTab = tabNumber; 64 | } 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /backend/app/models/agent/agent_model.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google Inc 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from pydantic import BaseModel 16 | from sqlmodel import Field, SQLModel, String 17 | from typing import Literal 18 | from .enums import AgentType 19 | from google.adk.agents import BaseAgent 20 | 21 | 22 | class Scenario(SQLModel, table=True): 23 | id: int = Field(default=None, primary_key=True, unique=True) 24 | name: str = Field(default=None) 25 | description: str = Field(default=None) 26 | overview: str = Field(default=None) 27 | system_instructions: str = Field(default=None) 28 | initial_prompt: str = Field(default=None) 29 | 30 | 31 | class SetScenarioData(BaseModel): 32 | scenario_id: int 33 | 34 | 35 | class AgentPydantic(SQLModel, table=True): 36 | id: int = Field(default=None, primary_key=True, unique=True) 37 | scenario_id: int = Field(default=None, foreign_key="scenario.id") 38 | agent_type: Literal[ 39 | AgentType.LLM.value, 40 | AgentType.Sequential.value, 41 | AgentType.Parallel.value, 42 | AgentType.Loop.value, 43 | AgentType.CodeExecutor.value, 44 | ] = Field(sa_type=String, default=AgentType.LLM.value) 45 | name: str = Field(default=None) 46 | instruction: str = Field(default=None) 47 | description: str = Field(default=None) 48 | model: str = Field(default=None) 49 | media_type: Literal["text", "image", "video", "music"] = Field( 50 | sa_type=String, default="text" 51 | ) 52 | # These are stored as csv 53 | tools: str = Field(default="") 54 | modules: str = Field(default="") 55 | # For cross DB compatibility, using 1 for True and 0 for false 56 | use_as_root_agent: int = Field(default=0) 57 | sub_agent_ids: str = Field(default="") 58 | 59 | 60 | class SubAgentLink(SQLModel, table=True): 61 | root_agent_id: int = Field( 62 | default=None, foreign_key="agentpydantic.id", primary_key=True 63 | ) 64 | sub_agent_id: int = Field( 65 | default=None, foreign_key="agentpydantic.id", primary_key=True 66 | ) 67 | 68 | 69 | class InMemoryAgent(BaseModel): 70 | agent_pydantic: AgentPydantic 71 | agent: BaseAgent 72 | 73 | 74 | class AgentResponse(BaseModel): 75 | text: str | None 76 | code_explanation: str | None = None 77 | text_string: str | None = None 78 | image_byte_string: str | None = None 79 | video_byte_string: str | None = None 80 | 81 | 82 | class UploadDataResponse(BaseModel): 83 | location: str 84 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/video-scene-settings/video-scene-settings.component.css: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | .videos-container { 23 | display: flex; 24 | justify-content: center; 25 | margin: 32px 0px; 26 | 27 | .videos { 28 | width: 500px; 29 | height: 400px; 30 | background-color: white; 31 | border: 1px dotted gray; 32 | margin: auto 8px; 33 | 34 | .image-actions { 35 | display: flex; 36 | justify-content: center; 37 | margin-top: 8px; 38 | 39 | button { 40 | margin-right: 8px; 41 | } 42 | } 43 | 44 | .c-buttons { 45 | width: 200px; 46 | margin: auto; 47 | 48 | button { 49 | margin: 8px 0px 8px 35px; 50 | } 51 | } 52 | } 53 | 54 | .reference-image { 55 | width: 300px; 56 | height: 300px; 57 | margin: auto 8px; 58 | 59 | img { 60 | max-width: 100%; 61 | max-height: 100%; 62 | } 63 | 64 | p { 65 | margin-top: 120px; 66 | } 67 | } 68 | 69 | p { 70 | margin-top: 190px; 71 | text-align: center; 72 | } 73 | } 74 | 75 | .item-container { 76 | display: flex; 77 | justify-content: flex-start; 78 | 79 | mat-form-field { 80 | width: 82%; 81 | } 82 | 83 | button { 84 | margin-left: 12px; 85 | } 86 | } 87 | 88 | mat-form-field { 89 | margin-right: 8px; 90 | } 91 | 92 | .generate-button { 93 | display: flex; 94 | justify-content: center; 95 | margin-top: 16px; 96 | } 97 | 98 | p { 99 | font-size: 16px; 100 | margin-bottom: 32px; 101 | } 102 | 103 | .large-textarea { 104 | width: 40%; 105 | } 106 | 107 | form { 108 | margin-top: 32px; 109 | 110 | .selected-video { 111 | width: 30%; 112 | } 113 | } 114 | 115 | a { 116 | color: #ba005c; 117 | text-decoration: none; 118 | } 119 | 120 | a:hover { 121 | color: #ba005c; 122 | text-decoration: none; 123 | cursor: pointer; 124 | } 125 | 126 | .video-cut-settings { 127 | p { 128 | font-size: 12px; 129 | margin-bottom: 15px; 130 | } 131 | } -------------------------------------------------------------------------------- /backend/app/models/video/video_gen_models.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """ 16 | Modules to define business logic modules. 17 | 18 | This file contains data models (dataclasses) used across the application 19 | to represent entities related to video generation, including individual 20 | video assets and structured responses from video generation APIs. 21 | """ 22 | 23 | from dataclasses import dataclass, field 24 | 25 | from models.video import video_request_models 26 | 27 | 28 | @dataclass 29 | class Video: 30 | """ 31 | Represents a single video asset within a generation response. 32 | 33 | Attributes: 34 | name: The name of the video file. 35 | gcs_uri: The Google Cloud Storage (GCS) URI where the video is stored. 36 | signed_uri: A pre-signed URL for temporary public access to the video. 37 | gcs_fuse_path: The FUSE path if the GCS bucket is mounted locally. 38 | mime_type: The MIME type of the video (e.g., 'video/mp4'). 39 | frames_uris: An optional list of GCS URIs for individual frames 40 | that comprise the video. Defaults to an empty list. 41 | """ 42 | 43 | id: str 44 | name: str 45 | gcs_uri: str 46 | signed_uri: str 47 | gcs_fuse_path: str 48 | mime_type: str 49 | duration: float 50 | frames_uris: list[str] | None = field(default_factory=list) 51 | 52 | 53 | @dataclass 54 | class VideoGenerationResponse: 55 | """ 56 | Represents the structured response from a video generation API call. 57 | 58 | This model provides status, operational details, and references to 59 | the generated video assets. 60 | 61 | Attributes: 62 | done: A boolean flag indicating if the video generation operation is 63 | complete. 64 | operation_name: The name of the asynchronous operation, useful for 65 | tracking its status. 66 | execution_message: Any message or status detail about the execution 67 | of the video generation. 68 | videos: A list of `Video` objects, representing the generated video(s). 69 | video_segment: An optional `VideoSegmentRequest` if this response 70 | pertains to a specific segment of a larger video. 71 | This will be `None` for a final, merged video. 72 | """ 73 | 74 | done: bool 75 | operation_name: str 76 | execution_message: str 77 | videos: list[Video] 78 | video_segment: video_request_models.VideoSegmentRequest | None = None 79 | -------------------------------------------------------------------------------- /backend/app/main.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """API Entry point where the app and routers are set up.""" 16 | import logging 17 | import os 18 | import uvicorn 19 | from api.router import api_router 20 | from core.config import settings 21 | from fastapi import FastAPI 22 | from starlette.middleware import cors 23 | 24 | logger = logging.getLogger(__name__) 25 | logging.basicConfig(filename="myapp.log", level=logging.INFO) 26 | 27 | from dotenv import load_dotenv 28 | 29 | if os.getenv("USE_AGENTS"): 30 | from dependencies.database import initialize_clean_db 31 | from orm.sample_data import initialize_all_sample_data 32 | from services.agent.scenario_service import ScenarioService 33 | from services.agent.agent_service import AgentService 34 | from contextlib import asynccontextmanager 35 | 36 | @asynccontextmanager 37 | async def lifespan(app: FastAPI): 38 | # TODO: need to change this to more persistent storage, right now just starting with clean db every time 39 | 40 | initialize_clean_db() 41 | initialize_all_sample_data() 42 | 43 | scenario_service = ScenarioService() 44 | # We only load the agents from the DB on startup or when manually requested by user 45 | # e.g. if an Admin user modifies an agent in the database 46 | agent_service = AgentService() 47 | 48 | yield { 49 | "scenario_service": scenario_service, 50 | "agent_service": agent_service, 51 | } 52 | 53 | load_dotenv() 54 | 55 | # Initialize FastAPI app 56 | app = FastAPI( 57 | title=settings.PROJECT_NAME, 58 | openapi_url=f"{settings.API_PREFIX}/openapi.json", 59 | lifespan=lifespan, 60 | ) 61 | else: 62 | load_dotenv() 63 | 64 | # Initialize FastAPI app 65 | app = FastAPI( 66 | title=settings.PROJECT_NAME, 67 | openapi_url=f"{settings.API_PREFIX}/openapi.json", 68 | ) 69 | 70 | # Set all CORS enabled origins if specified in settings 71 | if settings.BACKEND_CORS_ORIGINS: 72 | app.add_middleware( 73 | cors.CORSMiddleware, 74 | allow_origins=["*"], # Allows all origins 75 | allow_credentials=True, 76 | allow_methods=["*"], # Allows all methods 77 | allow_headers=["*"], # Allows all headers 78 | ) 79 | 80 | # Include the API router with a defined prefix 81 | app.include_router(api_router, prefix=settings.API_PREFIX) 82 | 83 | # Run the Uvicorn server when the script is executed directly 84 | if __name__ == "__main__": 85 | uvicorn.run(app, host="127.0.0.1", port=8000) 86 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/utils.ts: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright 2025 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Note that these code samples being shared are not official Google 18 | * products and are not formally supported. 19 | * 20 | ***************************************************************************/ 21 | 22 | import { MatSnackBar } from '@angular/material/snack-bar'; 23 | import { MatDialog } from '@angular/material/dialog'; 24 | import { ConfirmDialogComponent } from './components/confirm-dialog/confirm-dialog.component'; 25 | 26 | export function openSnackBar( 27 | snackBar: MatSnackBar, 28 | message: string, 29 | duration?: number 30 | ) { 31 | if (duration) { 32 | snackBar.open(message, 'X', { 33 | duration: 5 * 1000, 34 | }); 35 | } else { 36 | snackBar.open(message, 'X'); 37 | } 38 | } 39 | 40 | export function closeSnackBar(snackBar: MatSnackBar) { 41 | snackBar.dismiss(); 42 | } 43 | 44 | export function confirmAction( 45 | confirmDialog: MatDialog, 46 | width: string, 47 | message: string, 48 | param1: any, 49 | func: any 50 | ) { 51 | const dialogRef = confirmDialog.open(ConfirmDialogComponent, { 52 | width: width, 53 | data: { 54 | title: 'Confirm Action', 55 | message: message, 56 | }, 57 | }); 58 | 59 | dialogRef.afterClosed().subscribe((result) => { 60 | if (result) { 61 | // User clicked OK 62 | func(param1); 63 | } else { 64 | // User clicked Cancel 65 | console.log('Action cancelled.'); 66 | } 67 | }); 68 | } 69 | 70 | export function isValidEmail(email: string): boolean { 71 | const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; 72 | return emailRegex.test(email); 73 | } 74 | 75 | export function getWarningMessage() { 76 | return `WARNING: You are not logged in. Please use the Google Sign In button to 77 | log in. If you don't have a Google account, please create/save your first story 78 | to generate a random User Id.`; 79 | } 80 | 81 | export function decodeJwtResponse(token: string) { 82 | let base64Url = token.split('.')[1]; 83 | let base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); 84 | let jsonPayload = decodeURIComponent( 85 | atob(base64) 86 | .split('') 87 | .map(function (c) { 88 | return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); 89 | }) 90 | .join('') 91 | ); 92 | 93 | return JSON.parse(jsonPayload); 94 | } 95 | -------------------------------------------------------------------------------- /frontend/dreamboard/src/app/components/stories/stories.component.html: -------------------------------------------------------------------------------- 1 |
2 | @if(stories.length === 0) { 3 |
4 | subject Your stories will show here. 5 |
6 | } 7 |
8 | 15 | @for (story of stories; track story.id; let i = $index) { 16 | 17 | 18 | subject  Story {{ i + 1 }} 19 | 20 | 21 |

{{ story.title }}

22 |
23 | Id: {{ story.id }} 24 |
25 |

26 | {{ story.description }} 27 |

28 | 29 |

Scene Breakdown

30 |
31 | @for (scene of selectedStory.scenes; track scene.id; let i = $index) { 32 | 33 | 34 | Scene {{ i + 1 }} 35 | delete 36 | 37 | 38 | 39 |
40 | Id: {{ scene.id }} 41 |
42 | 43 | Description 44 | 50 | 51 | 52 | Image Prompt 53 | 59 | 60 |
61 |
62 | 63 | } 64 |
65 |

Brand Guidelines Alignment

66 |

{{ story.brandGuidelinesAdherence }}

67 |

ABCD Alignment

68 |

{{ story.abcdAdherence }}

69 |
70 | } 71 |
72 | @if (stories.length > 0) { 73 |
74 | 77 | 80 |
81 | } 82 |
83 |
84 | --------------------------------------------------------------------------------