agent-starter-pack 0.0.1b0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of agent-starter-pack might be problematic. Click here for more details.

Files changed (162) hide show
  1. agent_starter_pack-0.0.1b0.dist-info/METADATA +143 -0
  2. agent_starter_pack-0.0.1b0.dist-info/RECORD +162 -0
  3. agent_starter_pack-0.0.1b0.dist-info/WHEEL +4 -0
  4. agent_starter_pack-0.0.1b0.dist-info/entry_points.txt +2 -0
  5. agent_starter_pack-0.0.1b0.dist-info/licenses/LICENSE +201 -0
  6. agents/agentic_rag_vertexai_search/README.md +22 -0
  7. agents/agentic_rag_vertexai_search/app/agent.py +145 -0
  8. agents/agentic_rag_vertexai_search/app/retrievers.py +79 -0
  9. agents/agentic_rag_vertexai_search/app/templates.py +53 -0
  10. agents/agentic_rag_vertexai_search/notebooks/evaluating_langgraph_agent.ipynb +1561 -0
  11. agents/agentic_rag_vertexai_search/template/.templateconfig.yaml +14 -0
  12. agents/agentic_rag_vertexai_search/tests/integration/test_agent.py +57 -0
  13. agents/crewai_coding_crew/README.md +34 -0
  14. agents/crewai_coding_crew/app/agent.py +86 -0
  15. agents/crewai_coding_crew/app/crew/config/agents.yaml +39 -0
  16. agents/crewai_coding_crew/app/crew/config/tasks.yaml +37 -0
  17. agents/crewai_coding_crew/app/crew/crew.py +71 -0
  18. agents/crewai_coding_crew/notebooks/evaluating_crewai_agent.ipynb +1571 -0
  19. agents/crewai_coding_crew/notebooks/evaluating_langgraph_agent.ipynb +1561 -0
  20. agents/crewai_coding_crew/template/.templateconfig.yaml +12 -0
  21. agents/crewai_coding_crew/tests/integration/test_agent.py +47 -0
  22. agents/langgraph_base_react/README.md +9 -0
  23. agents/langgraph_base_react/app/agent.py +73 -0
  24. agents/langgraph_base_react/notebooks/evaluating_langgraph_agent.ipynb +1561 -0
  25. agents/langgraph_base_react/template/.templateconfig.yaml +13 -0
  26. agents/langgraph_base_react/tests/integration/test_agent.py +48 -0
  27. agents/multimodal_live_api/README.md +50 -0
  28. agents/multimodal_live_api/app/agent.py +86 -0
  29. agents/multimodal_live_api/app/server.py +193 -0
  30. agents/multimodal_live_api/app/templates.py +51 -0
  31. agents/multimodal_live_api/app/vector_store.py +55 -0
  32. agents/multimodal_live_api/template/.templateconfig.yaml +15 -0
  33. agents/multimodal_live_api/tests/integration/test_server_e2e.py +254 -0
  34. agents/multimodal_live_api/tests/load_test/load_test.py +40 -0
  35. agents/multimodal_live_api/tests/unit/test_server.py +143 -0
  36. src/base_template/.gitignore +197 -0
  37. src/base_template/Makefile +37 -0
  38. src/base_template/README.md +91 -0
  39. src/base_template/app/utils/tracing.py +143 -0
  40. src/base_template/app/utils/typing.py +115 -0
  41. src/base_template/deployment/README.md +123 -0
  42. src/base_template/deployment/cd/deploy-to-prod.yaml +98 -0
  43. src/base_template/deployment/cd/staging.yaml +215 -0
  44. src/base_template/deployment/ci/pr_checks.yaml +51 -0
  45. src/base_template/deployment/terraform/apis.tf +34 -0
  46. src/base_template/deployment/terraform/build_triggers.tf +122 -0
  47. src/base_template/deployment/terraform/dev/apis.tf +42 -0
  48. src/base_template/deployment/terraform/dev/iam.tf +90 -0
  49. src/base_template/deployment/terraform/dev/log_sinks.tf +66 -0
  50. src/base_template/deployment/terraform/dev/providers.tf +29 -0
  51. src/base_template/deployment/terraform/dev/storage.tf +76 -0
  52. src/base_template/deployment/terraform/dev/variables.tf +126 -0
  53. src/base_template/deployment/terraform/dev/vars/env.tfvars +21 -0
  54. src/base_template/deployment/terraform/iam.tf +130 -0
  55. src/base_template/deployment/terraform/locals.tf +50 -0
  56. src/base_template/deployment/terraform/log_sinks.tf +72 -0
  57. src/base_template/deployment/terraform/providers.tf +35 -0
  58. src/base_template/deployment/terraform/service_accounts.tf +42 -0
  59. src/base_template/deployment/terraform/storage.tf +100 -0
  60. src/base_template/deployment/terraform/variables.tf +202 -0
  61. src/base_template/deployment/terraform/vars/env.tfvars +43 -0
  62. src/base_template/pyproject.toml +113 -0
  63. src/base_template/tests/unit/test_utils/test_tracing_exporter.py +140 -0
  64. src/cli/commands/create.py +534 -0
  65. src/cli/commands/setup_cicd.py +730 -0
  66. src/cli/main.py +35 -0
  67. src/cli/utils/__init__.py +35 -0
  68. src/cli/utils/cicd.py +662 -0
  69. src/cli/utils/gcp.py +120 -0
  70. src/cli/utils/logging.py +51 -0
  71. src/cli/utils/template.py +644 -0
  72. src/data_ingestion/README.md +79 -0
  73. src/data_ingestion/data_ingestion_pipeline/components/ingest_data.py +175 -0
  74. src/data_ingestion/data_ingestion_pipeline/components/process_data.py +321 -0
  75. src/data_ingestion/data_ingestion_pipeline/pipeline.py +58 -0
  76. src/data_ingestion/data_ingestion_pipeline/submit_pipeline.py +184 -0
  77. src/data_ingestion/pyproject.toml +17 -0
  78. src/data_ingestion/uv.lock +999 -0
  79. src/deployment_targets/agent_engine/app/agent_engine_app.py +238 -0
  80. src/deployment_targets/agent_engine/app/utils/gcs.py +42 -0
  81. src/deployment_targets/agent_engine/deployment_metadata.json +4 -0
  82. src/deployment_targets/agent_engine/notebooks/intro_reasoning_engine.ipynb +869 -0
  83. src/deployment_targets/agent_engine/tests/integration/test_agent_engine_app.py +120 -0
  84. src/deployment_targets/agent_engine/tests/load_test/.results/.placeholder +0 -0
  85. src/deployment_targets/agent_engine/tests/load_test/.results/report.html +264 -0
  86. src/deployment_targets/agent_engine/tests/load_test/.results/results_exceptions.csv +1 -0
  87. src/deployment_targets/agent_engine/tests/load_test/.results/results_failures.csv +1 -0
  88. src/deployment_targets/agent_engine/tests/load_test/.results/results_stats.csv +3 -0
  89. src/deployment_targets/agent_engine/tests/load_test/.results/results_stats_history.csv +22 -0
  90. src/deployment_targets/agent_engine/tests/load_test/README.md +42 -0
  91. src/deployment_targets/agent_engine/tests/load_test/load_test.py +100 -0
  92. src/deployment_targets/agent_engine/tests/unit/test_dummy.py +22 -0
  93. src/deployment_targets/cloud_run/Dockerfile +29 -0
  94. src/deployment_targets/cloud_run/app/server.py +128 -0
  95. src/deployment_targets/cloud_run/deployment/terraform/artifact_registry.tf +22 -0
  96. src/deployment_targets/cloud_run/deployment/terraform/dev/service_accounts.tf +20 -0
  97. src/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +192 -0
  98. src/deployment_targets/cloud_run/tests/load_test/.results/.placeholder +0 -0
  99. src/deployment_targets/cloud_run/tests/load_test/README.md +79 -0
  100. src/deployment_targets/cloud_run/tests/load_test/load_test.py +85 -0
  101. src/deployment_targets/cloud_run/tests/unit/test_server.py +142 -0
  102. src/deployment_targets/cloud_run/uv.lock +6952 -0
  103. src/frontends/live_api_react/frontend/package-lock.json +19405 -0
  104. src/frontends/live_api_react/frontend/package.json +56 -0
  105. src/frontends/live_api_react/frontend/public/favicon.ico +0 -0
  106. src/frontends/live_api_react/frontend/public/index.html +62 -0
  107. src/frontends/live_api_react/frontend/public/robots.txt +3 -0
  108. src/frontends/live_api_react/frontend/src/App.scss +189 -0
  109. src/frontends/live_api_react/frontend/src/App.test.tsx +25 -0
  110. src/frontends/live_api_react/frontend/src/App.tsx +205 -0
  111. src/frontends/live_api_react/frontend/src/components/audio-pulse/AudioPulse.tsx +64 -0
  112. src/frontends/live_api_react/frontend/src/components/audio-pulse/audio-pulse.scss +68 -0
  113. src/frontends/live_api_react/frontend/src/components/control-tray/ControlTray.tsx +217 -0
  114. src/frontends/live_api_react/frontend/src/components/control-tray/control-tray.scss +201 -0
  115. src/frontends/live_api_react/frontend/src/components/logger/Logger.tsx +241 -0
  116. src/frontends/live_api_react/frontend/src/components/logger/logger.scss +133 -0
  117. src/frontends/live_api_react/frontend/src/components/logger/mock-logs.ts +151 -0
  118. src/frontends/live_api_react/frontend/src/components/side-panel/SidePanel.tsx +161 -0
  119. src/frontends/live_api_react/frontend/src/components/side-panel/side-panel.scss +285 -0
  120. src/frontends/live_api_react/frontend/src/contexts/LiveAPIContext.tsx +48 -0
  121. src/frontends/live_api_react/frontend/src/hooks/use-live-api.ts +115 -0
  122. src/frontends/live_api_react/frontend/src/hooks/use-media-stream-mux.ts +23 -0
  123. src/frontends/live_api_react/frontend/src/hooks/use-screen-capture.ts +72 -0
  124. src/frontends/live_api_react/frontend/src/hooks/use-webcam.ts +69 -0
  125. src/frontends/live_api_react/frontend/src/index.css +28 -0
  126. src/frontends/live_api_react/frontend/src/index.tsx +35 -0
  127. src/frontends/live_api_react/frontend/src/multimodal-live-types.ts +242 -0
  128. src/frontends/live_api_react/frontend/src/react-app-env.d.ts +17 -0
  129. src/frontends/live_api_react/frontend/src/reportWebVitals.ts +31 -0
  130. src/frontends/live_api_react/frontend/src/setupTests.ts +21 -0
  131. src/frontends/live_api_react/frontend/src/utils/audio-recorder.ts +111 -0
  132. src/frontends/live_api_react/frontend/src/utils/audio-streamer.ts +270 -0
  133. src/frontends/live_api_react/frontend/src/utils/audioworklet-registry.ts +43 -0
  134. src/frontends/live_api_react/frontend/src/utils/multimodal-live-client.ts +329 -0
  135. src/frontends/live_api_react/frontend/src/utils/store-logger.ts +64 -0
  136. src/frontends/live_api_react/frontend/src/utils/utils.ts +86 -0
  137. src/frontends/live_api_react/frontend/src/utils/worklets/audio-processing.ts +73 -0
  138. src/frontends/live_api_react/frontend/src/utils/worklets/vol-meter.ts +65 -0
  139. src/frontends/live_api_react/frontend/tsconfig.json +25 -0
  140. src/frontends/streamlit/frontend/side_bar.py +213 -0
  141. src/frontends/streamlit/frontend/streamlit_app.py +263 -0
  142. src/frontends/streamlit/frontend/style/app_markdown.py +37 -0
  143. src/frontends/streamlit/frontend/utils/chat_utils.py +67 -0
  144. src/frontends/streamlit/frontend/utils/local_chat_history.py +125 -0
  145. src/frontends/streamlit/frontend/utils/message_editing.py +59 -0
  146. src/frontends/streamlit/frontend/utils/multimodal_utils.py +217 -0
  147. src/frontends/streamlit/frontend/utils/stream_handler.py +282 -0
  148. src/frontends/streamlit/frontend/utils/title_summary.py +77 -0
  149. src/resources/containers/data_processing/Dockerfile +25 -0
  150. src/resources/locks/uv-agentic_rag_vertexai_search-agent_engine.lock +4684 -0
  151. src/resources/locks/uv-agentic_rag_vertexai_search-cloud_run.lock +5799 -0
  152. src/resources/locks/uv-crewai_coding_crew-agent_engine.lock +5509 -0
  153. src/resources/locks/uv-crewai_coding_crew-cloud_run.lock +6688 -0
  154. src/resources/locks/uv-langgraph_base_react-agent_engine.lock +4595 -0
  155. src/resources/locks/uv-langgraph_base_react-cloud_run.lock +5710 -0
  156. src/resources/locks/uv-multimodal_live_api-cloud_run.lock +5665 -0
  157. src/resources/setup_cicd/cicd_variables.tf +36 -0
  158. src/resources/setup_cicd/github.tf +85 -0
  159. src/resources/setup_cicd/providers.tf +39 -0
  160. src/utils/generate_locks.py +135 -0
  161. src/utils/lock_utils.py +82 -0
  162. src/utils/watch_and_rebuild.py +190 -0
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "multimodal-live-api-web-console",
3
+ "version": "0.1.0",
4
+ "dependencies": {
5
+ "classnames": "^2.5.1",
6
+ "dotenv-flow": "^4.1.0",
7
+ "eventemitter3": "^5.0.1",
8
+ "lodash": "^4.17.21",
9
+ "react": "^18.3.1",
10
+ "react-dom": "^18.3.1",
11
+ "react-icons": "^5.3.0",
12
+ "react-scripts": "5.0.1",
13
+ "react-select": "^5.8.3",
14
+ "sass": "^1.80.6",
15
+ "vega": "^5.30.0",
16
+ "vega-embed": "^6.29.0",
17
+ "vega-lite": "^5.22.0",
18
+ "web-vitals": "^2.1.4",
19
+ "zustand": "^5.0.1"
20
+ },
21
+ "scripts": {
22
+ "start": "react-scripts start",
23
+ "build": "react-scripts build",
24
+ "test": "react-scripts test",
25
+ "eject": "react-scripts eject"
26
+ },
27
+ "eslintConfig": {},
28
+ "browserslist": {
29
+ "production": [
30
+ ">0.2%",
31
+ "not dead",
32
+ "not op_mini all"
33
+ ],
34
+ "development": [
35
+ "last 1 chrome version",
36
+ "last 1 firefox version",
37
+ "last 1 safari version"
38
+ ]
39
+ },
40
+ "devDependencies": {
41
+ "@google/generative-ai": "^0.21.0",
42
+ "@testing-library/jest-dom": "^5.17.0",
43
+ "@testing-library/react": "^13.4.0",
44
+ "@testing-library/user-event": "^13.5.0",
45
+ "@types/jest": "^27.5.2",
46
+ "@types/node": "^16.18.119",
47
+ "@types/react": "^18.3.12",
48
+ "@types/react-dom": "^18.3.1",
49
+ "@types/lodash": "^4.17.13",
50
+ "ts-node": "^10.9.2",
51
+ "typescript": "^5.6.3"
52
+ },
53
+ "overrides": {
54
+ "typescript": "^5.6.3"
55
+ }
56
+ }
@@ -0,0 +1,62 @@
1
+ <!doctype html>
2
+ <!--
3
+ Copyright 2025 Google LLC
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
+ http://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
+
18
+ <html lang="en">
19
+ <head>
20
+ <meta charset="utf-8" />
21
+ <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
22
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
23
+ <meta name="theme-color" content="#000000" />
24
+ <meta
25
+ name="description"
26
+ content="Web site created using create-react-app" />
27
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
28
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
29
+ <link
30
+ href="https://fonts.googleapis.com/css2?family=Space+Mono:ital,wght@0,400;0,700;1,400;1,700&display=swap"
31
+ rel="stylesheet" />
32
+ <link
33
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=block"
34
+ rel="stylesheet" />
35
+ <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
36
+ <!--
37
+ Notice the use of %PUBLIC_URL% in the tags above.
38
+ It will be replaced with the URL of the `public` folder during the build.
39
+ Only files inside the `public` folder can be referenced from the HTML.
40
+
41
+ Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
42
+ work correctly both with client-side routing and a non-root public URL.
43
+ Learn how to configure a non-root public URL by running `npm run build`.
44
+ -->
45
+ <title>Multimodal Live - Console</title>
46
+ </head>
47
+
48
+ <body>
49
+ <noscript>You need to enable JavaScript to run this app.</noscript>
50
+ <div id="root"></div>
51
+ <!--
52
+ This HTML file is a template.
53
+ If you open it directly in the browser, you will see an empty page.
54
+
55
+ You can add webfonts, meta tags, or analytics to this file.
56
+ The build step will place the bundled scripts into the <body> tag.
57
+
58
+ To begin the development, run `npm start` or `yarn start`.
59
+ To create a production bundle, use `npm run build` or `yarn build`.
60
+ -->
61
+ </body>
62
+ </html>
@@ -0,0 +1,3 @@
1
+ # https://www.robotstxt.org/robotstxt.html
2
+ User-agent: *
3
+ Disallow:
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Copyright 2025 Google LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ /* stylelint-disable */
18
+ :root {
19
+ --text: white;
20
+ --gray-200: #b4b8bb;
21
+ --gray-300: #80868b;
22
+ --gray-500: #5f6368;
23
+ --gray-600: #444444;
24
+ --gray-700: #202020;
25
+ --gray-800: #171717;
26
+ --gray-900: #111111;
27
+ --gray-1000: #0a0a0a;
28
+ --border-stroke: #444444;
29
+ --accent-blue: rgb(161, 228, 242);
30
+ --accent-blue-active-bg: #001233;
31
+ --accent-blue-active: #98beff;
32
+ --accent-blue-headers: #448dff;
33
+ --accent-green: rgb(168, 218, 181);
34
+
35
+ --midnight-blue: rgb(0, 18, 51);
36
+ --blue-30: #99beff;
37
+
38
+ --accent-red: #ff4600;
39
+
40
+ --background: var(--gray-900);
41
+ --color: var(--text);
42
+
43
+ scrollbar-color: var(--gray-600) var(--gray-900);
44
+ scrollbar-width: thin;
45
+
46
+ --font-family: "Space Mono", monospace;
47
+
48
+ /* */
49
+ --Neutral-00: #000;
50
+ --Neutral-5: #181a1b;
51
+ --Neutral-10: #1c1f21;
52
+ --Neutral-15: #232729;
53
+ --Neutral-20: #2a2f31;
54
+ --Neutral-30: #404547;
55
+ --Neutral-50: #707577;
56
+ --Neutral-60: #888d8f;
57
+ --Neutral-80: #c3c6c7;
58
+ --Neutral-90: #e1e2e3;
59
+
60
+ --Green-500: #0d9c53;
61
+ --Green-700: #025022;
62
+
63
+ --Blue-500: #1f94ff;
64
+ --Blue-800: #0f3557;
65
+
66
+ --Red-400: #ff9c7a;
67
+ --Red-500: #ff4600;
68
+ --Red-600: #e03c00;
69
+ --Red-700: #bd3000;
70
+ }
71
+
72
+ body {
73
+ font-family: "Space Mono", monospace;
74
+ background: var(--Neutral-30);
75
+ }
76
+
77
+ .material-symbols-outlined {
78
+ &.filled {
79
+ font-variation-settings:
80
+ "FILL" 1,
81
+ "wght" 400,
82
+ "GRAD" 0,
83
+ "opsz" 24;
84
+ }
85
+ }
86
+
87
+ .space-mono-regular {
88
+ font-family: "Space Mono", monospace;
89
+ font-weight: 400;
90
+ font-style: normal;
91
+ }
92
+
93
+ .space-mono-bold {
94
+ font-family: "Space Mono", monospace;
95
+ font-weight: 700;
96
+ font-style: normal;
97
+ }
98
+
99
+ .space-mono-regular-italic {
100
+ font-family: "Space Mono", monospace;
101
+ font-weight: 400;
102
+ font-style: italic;
103
+ }
104
+
105
+ .space-mono-bold-italic {
106
+ font-family: "Space Mono", monospace;
107
+ font-weight: 700;
108
+ font-style: italic;
109
+ }
110
+
111
+ .hidden {
112
+ display: none;
113
+ }
114
+
115
+ .flex {
116
+ display: flex;
117
+ }
118
+
119
+ .h-screen-full {
120
+ height: 100vh;
121
+ }
122
+
123
+ .w-screen-full {
124
+ width: 100vw;
125
+ }
126
+
127
+ .flex-col {
128
+ flex-direction: column;
129
+ }
130
+
131
+ @media (prefers-reduced-motion: no-preference) {
132
+ }
133
+
134
+ .streaming-console {
135
+ background: var(--Neutral-5);
136
+ color: var(--gray-300);
137
+ display: flex;
138
+ height: 100vh;
139
+ width: 100vw;
140
+
141
+ a,
142
+ a:visited,
143
+ a:active {
144
+ color: var(--gray-300);
145
+ }
146
+
147
+ .disabled {
148
+ pointer-events: none;
149
+
150
+ > * {
151
+ pointer-events: none;
152
+ }
153
+ }
154
+
155
+ main {
156
+ position: relative;
157
+ display: flex;
158
+ flex-direction: column;
159
+ align-items: center;
160
+ justify-content: center;
161
+ flex-grow: 1;
162
+ gap: 1rem;
163
+ max-width: 100%;
164
+ overflow: hidden;
165
+ }
166
+
167
+ .main-app-area {
168
+ display: flex;
169
+ flex: 1;
170
+ align-items: center;
171
+ justify-content: center;
172
+ }
173
+
174
+ .function-call {
175
+ position: absolute;
176
+ top: 0;
177
+ width: 100%;
178
+ height: 50%;
179
+ overflow-y: auto;
180
+ }
181
+ }
182
+
183
+ /* video player */
184
+ .stream {
185
+ flex-grow: 1;
186
+ max-width: 90%;
187
+ border-radius: 32px;
188
+ max-height: fit-content;
189
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Copyright 2024 Google LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import React from 'react';
18
+ import { render, screen } from '@testing-library/react';
19
+ import App from './App';
20
+
21
+ test('renders learn react link', () => {
22
+ render(<App />);
23
+ const linkElement = screen.getByText(/learn react/i);
24
+ expect(linkElement).toBeInTheDocument();
25
+ });
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Copyright 2024 Google LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { useRef, useState } from "react";
18
+ import "./App.scss";
19
+ import { LiveAPIProvider } from "./contexts/LiveAPIContext";
20
+ import SidePanel from "./components/side-panel/SidePanel";
21
+ import ControlTray from "./components/control-tray/ControlTray";
22
+ import cn from "classnames";
23
+
24
+ const defaultHost = "localhost:8000";
25
+ const defaultUri = `ws://${defaultHost}/`;
26
+
27
+ function App() {
28
+ const videoRef = useRef<HTMLVideoElement>(null);
29
+ const [videoStream, setVideoStream] = useState<MediaStream | null>(null);
30
+ const [serverUrl, setServerUrl] = useState<string>(defaultUri);
31
+ const [runId] = useState<string>(crypto.randomUUID());
32
+ const [userId, setUserId] = useState<string>("user1");
33
+
34
+ // Feedback state
35
+ const [feedbackScore, setFeedbackScore] = useState<number>(10);
36
+ const [feedbackText, setFeedbackText] = useState<string>("");
37
+ const [sendFeedback, setShowFeedback] = useState(false);
38
+
39
+ const submitFeedback = async () => {
40
+ const feedbackUrl = new URL('feedback', serverUrl.replace('ws', 'http')).href;
41
+
42
+ try {
43
+ const response = await fetch(feedbackUrl, {
44
+ method: 'POST',
45
+ headers: {
46
+ 'Content-Type': 'application/json'
47
+ },
48
+ body: JSON.stringify({
49
+ score: feedbackScore,
50
+ text: feedbackText,
51
+ run_id: runId,
52
+ user_id: userId,
53
+ log_type: "feedback"
54
+ })
55
+ });
56
+ if (!response.ok) {
57
+ throw new Error(`Failed to submit feedback: Server returned status ${response.status} ${response.statusText}`);
58
+ }
59
+
60
+ // Clear feedback after successful submission
61
+ setFeedbackScore(10);
62
+ setFeedbackText("");
63
+ setShowFeedback(false);
64
+ alert("Feedback submitted successfully!");
65
+ } catch (error) {
66
+ console.error('Error submitting feedback:', error);
67
+ alert(`Failed to submit feedback: ${error}`);
68
+ }
69
+ };
70
+
71
+ return (
72
+ <div className="App">
73
+ <LiveAPIProvider url={serverUrl} userId={userId}>
74
+ <div className="streaming-console">
75
+ <SidePanel />
76
+ <main>
77
+ <div className="main-app-area">
78
+ <video
79
+ className={cn("stream", {
80
+ hidden: !videoRef.current || !videoStream,
81
+ })}
82
+ ref={videoRef}
83
+ autoPlay
84
+ playsInline
85
+ />
86
+ </div>
87
+ <ControlTray
88
+ videoRef={videoRef}
89
+ supportsVideo={true}
90
+ onVideoStreamChange={setVideoStream}
91
+ >
92
+ </ControlTray>
93
+ <div className="url-setup" style={{position: 'absolute', top: 0, left: 0, right: 0, pointerEvents: 'auto', zIndex: 1000, padding: '2px', marginBottom: '2px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', background: 'rgba(255, 255, 255, 0.9)'}}>
94
+ <div>
95
+ <label htmlFor="server-url">Server URL:</label>
96
+ <input
97
+ id="server-url"
98
+ type="text"
99
+ value={serverUrl}
100
+ onChange={(e) => setServerUrl(e.target.value)}
101
+ placeholder="Enter server URL"
102
+ style={{
103
+ cursor: 'text',
104
+ padding: '4px',
105
+ margin: '0 4px',
106
+ borderRadius: '2px',
107
+ border: '1px solid #ccc',
108
+ fontSize: '14px',
109
+ fontFamily: 'system-ui, -apple-system, sans-serif',
110
+ width: '200px'
111
+ }}
112
+ />
113
+ <label htmlFor="user-id">User ID:</label>
114
+ <input
115
+ id="user-id"
116
+ type="text"
117
+ value={userId}
118
+ onChange={(e) => setUserId(e.target.value)}
119
+ placeholder="Enter user ID"
120
+ style={{
121
+ cursor: 'text',
122
+ padding: '4px',
123
+ margin: '0 4px',
124
+ borderRadius: '2px',
125
+ border: '1px solid #ccc',
126
+ fontSize: '14px',
127
+ fontFamily: 'system-ui, -apple-system, sans-serif',
128
+ width: '100px'
129
+ }}
130
+ />
131
+ </div>
132
+
133
+ {/* Feedback Button */}
134
+ <button
135
+ onClick={() => setShowFeedback(!sendFeedback)}
136
+ style={{
137
+ padding: '5px 10px',
138
+ margin: '10px',
139
+ cursor: 'pointer'
140
+ }}
141
+ >
142
+ {sendFeedback ? 'Hide Feedback' : 'Send Feedback'}
143
+ </button>
144
+ </div>
145
+
146
+ {/* Feedback Overlay Section */}
147
+ {sendFeedback && (
148
+ <div className="feedback-section" style={{
149
+ position: 'absolute',
150
+ top: '50%',
151
+ left: '50%',
152
+ transform: 'translate(-50%, -50%)',
153
+ padding: '20px',
154
+ background: 'rgba(255, 255, 255, 0.95)',
155
+ boxShadow: '0 0 10px rgba(0,0,0,0.2)',
156
+ borderRadius: '8px',
157
+ zIndex: 1001,
158
+ minWidth: '300px'
159
+ }}>
160
+ <h3>Provide Feedback</h3>
161
+ <div>
162
+ <label htmlFor="feedback-score">Score (0-10): </label>
163
+ <input
164
+ id="feedback-score"
165
+ type="number"
166
+ min="0"
167
+ max="10"
168
+ value={feedbackScore}
169
+ onChange={(e) => setFeedbackScore(Number(e.target.value))}
170
+ style={{margin: '0 10px'}}
171
+ />
172
+ </div>
173
+ <div style={{marginTop: '10px'}}>
174
+ <label htmlFor="feedback-text">Comments: </label>
175
+ <textarea
176
+ id="feedback-text"
177
+ value={feedbackText}
178
+ onChange={(e) => setFeedbackText(e.target.value)}
179
+ style={{
180
+ width: '100%',
181
+ height: '60px',
182
+ margin: '5px 0'
183
+ }}
184
+ />
185
+ </div>
186
+ <button
187
+ onClick={submitFeedback}
188
+ style={{
189
+ padding: '5px 10px',
190
+ marginTop: '5px',
191
+ cursor: 'pointer'
192
+ }}
193
+ >
194
+ Submit Feedback
195
+ </button>
196
+ </div>
197
+ )}
198
+ </main>
199
+ </div>
200
+ </LiveAPIProvider>
201
+ </div>
202
+ );
203
+ }
204
+
205
+ export default App;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Copyright 2024 Google LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import "./audio-pulse.scss";
18
+ import React from "react";
19
+ import { useEffect, useRef } from "react";
20
+ import c from "classnames";
21
+
22
+ const lineCount = 3;
23
+
24
+ export type AudioPulseProps = {
25
+ active: boolean;
26
+ volume: number;
27
+ hover?: boolean;
28
+ };
29
+
30
+ export default function AudioPulse({ active, volume, hover }: AudioPulseProps) {
31
+ const lines = useRef<HTMLDivElement[]>([]);
32
+
33
+ useEffect(() => {
34
+ let timeout: number | null = null;
35
+ const update = () => {
36
+ lines.current.forEach(
37
+ (line, i) =>
38
+ (line.style.height = `${Math.min(
39
+ 24,
40
+ 4 + volume * (i === 1 ? 400 : 60),
41
+ )}px`),
42
+ );
43
+ timeout = window.setTimeout(update, 100);
44
+ };
45
+
46
+ update();
47
+
48
+ return () => clearTimeout((timeout as number)!);
49
+ }, [volume]);
50
+
51
+ return (
52
+ <div className={c("audioPulse", { active, hover })}>
53
+ {Array(lineCount)
54
+ .fill(null)
55
+ .map((_, i) => (
56
+ <div
57
+ key={i}
58
+ ref={(el) => (lines.current[i] = el!)}
59
+ style={{ animationDelay: `${i * 133}ms` }}
60
+ />
61
+ ))}
62
+ </div>
63
+ );
64
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Copyright 2025 Google LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ /* stylelint-disable */
18
+ .audioPulse {
19
+ display: flex;
20
+ width: 24px;
21
+ justify-content: space-evenly;
22
+ align-items: center;
23
+ transition: all 0.5s;
24
+
25
+ & > div {
26
+ background-color: var(--Neutral-30);
27
+ border-radius: 1000px;
28
+ width: 4px;
29
+ min-height: 4px;
30
+ border-radius: 1000px;
31
+ transition: height 0.1s;
32
+ }
33
+
34
+ &.hover > div {
35
+ animation: hover 1.4s infinite alternate ease-in-out;
36
+ }
37
+
38
+ height: 4px;
39
+ transition: opacity 0.333s;
40
+
41
+ &.active {
42
+ opacity: 1;
43
+
44
+ & > div {
45
+ background-color: var(--Neutral-80);
46
+ }
47
+ }
48
+ }
49
+
50
+ @keyframes hover {
51
+ from {
52
+ transform: translateY(0);
53
+ }
54
+
55
+ to {
56
+ transform: translateY(-3.5px);
57
+ }
58
+ }
59
+
60
+ @keyframes pulse {
61
+ from {
62
+ scale: 1 1;
63
+ }
64
+
65
+ to {
66
+ scale: 1.2 1.2;
67
+ }
68
+ }