agent-starter-pack 0.15.7__py3-none-any.whl → 0.16.0__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.
- {agent_starter_pack-0.15.7.dist-info → agent_starter_pack-0.16.0.dist-info}/METADATA +2 -2
- {agent_starter_pack-0.15.7.dist-info → agent_starter_pack-0.16.0.dist-info}/RECORD +96 -94
- agents/adk_base/.template/templateconfig.yaml +1 -1
- agents/{live_api → adk_live}/.template/templateconfig.yaml +5 -7
- agents/adk_live/README.md +31 -0
- agents/adk_live/app/agent.py +48 -0
- agents/adk_live/tests/unit/test_dummy.py +38 -0
- agents/agentic_rag/.template/templateconfig.yaml +1 -1
- agents/crewai_coding_crew/app/agent.py +18 -57
- agents/langgraph_base_react/app/agent.py +7 -46
- llm.txt +1 -1
- src/base_template/GEMINI.md +1 -1
- src/base_template/Makefile +130 -61
- src/base_template/README.md +6 -6
- src/base_template/deployment/terraform/dev/apis.tf +1 -1
- src/base_template/deployment/terraform/dev/variables.tf +1 -1
- src/base_template/deployment/terraform/locals.tf +1 -1
- src/base_template/deployment/terraform/variables.tf +1 -1
- src/base_template/pyproject.toml +22 -21
- src/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/deploy-to-prod.yaml +2 -2
- src/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/pr_checks.yaml +1 -1
- src/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/staging.yaml +71 -8
- src/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/deploy-to-prod.yaml +2 -2
- src/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/pr_checks.yaml +1 -1
- src/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/staging.yaml +90 -8
- src/base_template/{{cookiecutter.agent_directory}}/utils/tracing.py +1 -1
- src/base_template/{{cookiecutter.agent_directory}}/utils/typing.py +4 -4
- src/cli/utils/template.py +12 -5
- src/deployment_targets/agent_engine/tests/integration/test_agent_engine_app.py +205 -4
- src/deployment_targets/agent_engine/tests/load_test/README.md +47 -0
- src/deployment_targets/agent_engine/tests/load_test/load_test.py +132 -3
- src/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/agent_engine_app.py +11 -3
- src/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/utils/deployment.py +5 -1
- src/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/utils/{% if cookiecutter.is_adk_live %}expose_app.py{% else %}unused_expose_app.py{% endif %} +461 -0
- src/deployment_targets/cloud_run/Dockerfile +3 -3
- src/deployment_targets/cloud_run/deployment/terraform/dev/service.tf +4 -4
- src/deployment_targets/cloud_run/deployment/terraform/service.tf +7 -7
- src/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +207 -5
- src/deployment_targets/cloud_run/tests/load_test/README.md +82 -0
- src/deployment_targets/cloud_run/tests/load_test/load_test.py +130 -3
- src/deployment_targets/cloud_run/{{cookiecutter.agent_directory}}/server.py +178 -146
- src/frontends/{live_api_react → adk_live_react}/frontend/package-lock.json +39 -1007
- src/frontends/{live_api_react → adk_live_react}/frontend/package.json +1 -9
- src/frontends/{live_api_react → adk_live_react}/frontend/src/App.tsx +1 -1
- src/frontends/{live_api_react → adk_live_react}/frontend/src/components/logger/Logger.tsx +8 -3
- src/frontends/{live_api_react → adk_live_react}/frontend/src/components/logger/logger.scss +26 -0
- src/frontends/{live_api_react → adk_live_react}/frontend/src/components/side-panel/SidePanel.tsx +11 -5
- src/frontends/{live_api_react → adk_live_react}/frontend/src/components/side-panel/side-panel.scss +146 -115
- src/frontends/adk_live_react/frontend/src/components/transcription-preview/TranscriptionPreview.tsx +106 -0
- src/frontends/adk_live_react/frontend/src/components/transcription-preview/transcription-preview.scss +150 -0
- src/frontends/{live_api_react → adk_live_react}/frontend/src/hooks/use-live-api.ts +8 -2
- src/frontends/{live_api_react → adk_live_react}/frontend/src/multimodal-live-types.ts +38 -2
- src/frontends/{live_api_react → adk_live_react}/frontend/src/utils/audio-recorder.ts +1 -1
- src/frontends/{live_api_react → adk_live_react}/frontend/src/utils/audio-streamer.ts +1 -1
- src/frontends/{live_api_react → adk_live_react}/frontend/src/utils/multimodal-live-client.ts +204 -23
- src/frontends/{live_api_react → adk_live_react}/frontend/src/utils/utils.ts +27 -5
- src/frontends/streamlit/frontend/utils/local_chat_history.py +2 -0
- src/resources/idx/.idx/dev.nix +25 -11
- src/resources/idx/idx-template.json +1 -16
- src/resources/idx/idx-template.nix +2 -3
- src/resources/locks/uv-adk_base-agent_engine.lock +434 -349
- src/resources/locks/uv-adk_base-cloud_run.lock +502 -409
- src/resources/locks/uv-adk_live-agent_engine.lock +4189 -0
- src/resources/locks/{uv-live_api-cloud_run.lock → uv-adk_live-cloud_run.lock} +884 -2219
- src/resources/locks/uv-agentic_rag-agent_engine.lock +473 -388
- src/resources/locks/uv-agentic_rag-cloud_run.lock +557 -464
- src/resources/locks/uv-crewai_coding_crew-agent_engine.lock +498 -515
- src/resources/locks/uv-crewai_coding_crew-cloud_run.lock +898 -687
- src/resources/locks/uv-langgraph_base_react-agent_engine.lock +455 -483
- src/resources/locks/uv-langgraph_base_react-cloud_run.lock +910 -645
- src/utils/generate_locks.py +8 -4
- agents/live_api/README.md +0 -37
- agents/live_api/app/agent.py +0 -72
- agents/live_api/tests/integration/test_server_e2e.py +0 -260
- agents/live_api/tests/load_test/load_test.py +0 -40
- agents/live_api/tests/unit/test_server.py +0 -144
- {agent_starter_pack-0.15.7.dist-info → agent_starter_pack-0.16.0.dist-info}/WHEEL +0 -0
- {agent_starter_pack-0.15.7.dist-info → agent_starter_pack-0.16.0.dist-info}/entry_points.txt +0 -0
- {agent_starter_pack-0.15.7.dist-info → agent_starter_pack-0.16.0.dist-info}/licenses/LICENSE +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/public/favicon.ico +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/public/index.html +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/public/robots.txt +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/App.scss +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/App.test.tsx +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/components/audio-pulse/AudioPulse.tsx +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/components/audio-pulse/audio-pulse.scss +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/components/logger/mock-logs.ts +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/contexts/LiveAPIContext.tsx +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/hooks/use-media-stream-mux.ts +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/hooks/use-screen-capture.ts +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/hooks/use-webcam.ts +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/index.css +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/index.tsx +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/react-app-env.d.ts +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/reportWebVitals.ts +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/setupTests.ts +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/utils/audioworklet-registry.ts +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/utils/store-logger.ts +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/utils/worklets/audio-processing.ts +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/src/utils/worklets/vol-meter.ts +0 -0
- /src/frontends/{live_api_react → adk_live_react}/frontend/tsconfig.json +0 -0
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
"version": "0.1.0",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"classnames": "^2.5.1",
|
|
6
|
-
"dotenv-flow": "^4.1.0",
|
|
7
6
|
"eventemitter3": "^5.0.1",
|
|
8
7
|
"lodash": "^4.17.21",
|
|
9
8
|
"react": "^18.3.1",
|
|
@@ -12,9 +11,6 @@
|
|
|
12
11
|
"react-scripts": "5.0.1",
|
|
13
12
|
"react-select": "^5.8.3",
|
|
14
13
|
"sass": "^1.80.6",
|
|
15
|
-
"vega": "^5.33.0",
|
|
16
|
-
"vega-embed": "^6.29.0",
|
|
17
|
-
"vega-lite": "^5.22.0",
|
|
18
14
|
"web-vitals": "^2.1.4",
|
|
19
15
|
"zustand": "^5.0.1"
|
|
20
16
|
},
|
|
@@ -41,13 +37,9 @@
|
|
|
41
37
|
"@google/generative-ai": "^0.21.0",
|
|
42
38
|
"@testing-library/jest-dom": "^5.17.0",
|
|
43
39
|
"@testing-library/react": "^13.4.0",
|
|
44
|
-
"@
|
|
45
|
-
"@types/jest": "^27.5.2",
|
|
46
|
-
"@types/node": "^16.18.119",
|
|
40
|
+
"@types/lodash": "^4.17.13",
|
|
47
41
|
"@types/react": "^18.3.12",
|
|
48
42
|
"@types/react-dom": "^18.3.1",
|
|
49
|
-
"@types/lodash": "^4.17.13",
|
|
50
|
-
"ts-node": "^10.9.2",
|
|
51
43
|
"typescript": "^5.6.3"
|
|
52
44
|
},
|
|
53
45
|
"overrides": {
|
|
@@ -115,10 +115,15 @@ const ToolCallLog = ({ message }: Message) => {
|
|
|
115
115
|
const { toolCall } = message as ToolCallMessage;
|
|
116
116
|
return (
|
|
117
117
|
<div className={cn("rich-log tool-call")}>
|
|
118
|
-
|
|
118
|
+
<h4 className="role-tool">Tool Call</h4>
|
|
119
|
+
{toolCall.functionCalls.map((fc) => (
|
|
119
120
|
<div key={fc.id} className="part part-functioncall">
|
|
120
|
-
<h5>Function
|
|
121
|
-
<
|
|
121
|
+
<h5>Function: {fc.name}</h5>
|
|
122
|
+
<div className="function-details">
|
|
123
|
+
<div><strong>ID:</strong> {fc.id}</div>
|
|
124
|
+
<div><strong>Args:</strong></div>
|
|
125
|
+
<pre>{JSON.stringify(fc.args, null, 2)}</pre>
|
|
126
|
+
</div>
|
|
122
127
|
</div>
|
|
123
128
|
))}
|
|
124
129
|
</div>
|
|
@@ -35,6 +35,10 @@
|
|
|
35
35
|
color: var(--Blue-500);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
.tool-call h4 {
|
|
39
|
+
color: var(--Orange-500, #ff9800);
|
|
40
|
+
}
|
|
41
|
+
|
|
38
42
|
.rich-log {
|
|
39
43
|
display: flex;
|
|
40
44
|
justify-content: center;
|
|
@@ -66,6 +70,28 @@
|
|
|
66
70
|
color: var(--Neutral-90);
|
|
67
71
|
border-radius: 8px;
|
|
68
72
|
}
|
|
73
|
+
|
|
74
|
+
.part-functioncall {
|
|
75
|
+
background: rgba(255, 152, 0, 0.1);
|
|
76
|
+
border-left: 3px solid var(--Orange-500, #ff9800);
|
|
77
|
+
|
|
78
|
+
.function-details {
|
|
79
|
+
margin-top: 8px;
|
|
80
|
+
font-size: 13px;
|
|
81
|
+
|
|
82
|
+
strong {
|
|
83
|
+
color: var(--Orange-500, #ff9800);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
pre {
|
|
87
|
+
background: var(--Neutral-10);
|
|
88
|
+
padding: 8px;
|
|
89
|
+
border-radius: 4px;
|
|
90
|
+
margin: 4px 0;
|
|
91
|
+
font-size: 12px;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
69
95
|
}
|
|
70
96
|
|
|
71
97
|
.plain-log {
|
src/frontends/{live_api_react → adk_live_react}/frontend/src/components/side-panel/SidePanel.tsx
RENAMED
|
@@ -26,6 +26,7 @@ import { useWebcam } from "../../hooks/use-webcam";
|
|
|
26
26
|
import { AudioRecorder } from "../../utils/audio-recorder";
|
|
27
27
|
import AudioPulse from "../audio-pulse/AudioPulse";
|
|
28
28
|
import Logger, { LoggerFilterType } from "../logger/Logger";
|
|
29
|
+
import TranscriptionPreview from "../transcription-preview/TranscriptionPreview";
|
|
29
30
|
import "./side-panel.scss";
|
|
30
31
|
|
|
31
32
|
const filterOptions = [
|
|
@@ -256,20 +257,22 @@ function SidePanel({
|
|
|
256
257
|
};
|
|
257
258
|
|
|
258
259
|
return (
|
|
259
|
-
<div className={`
|
|
260
|
-
<
|
|
261
|
-
<header className="top">
|
|
260
|
+
<div className={`console-container ${open ? "open" : ""}`}>
|
|
261
|
+
<header className="console-header">
|
|
262
262
|
<h2>Console</h2>
|
|
263
263
|
{open ? (
|
|
264
|
-
<button className="
|
|
264
|
+
<button className="toggle-button" onClick={() => setOpen(!open)}>
|
|
265
265
|
<RiSidebarFoldLine color="#b4b8bb" />
|
|
266
266
|
</button>
|
|
267
267
|
) : (
|
|
268
|
-
<button className="
|
|
268
|
+
<button className="toggle-button" onClick={() => setOpen(!open)}>
|
|
269
269
|
<RiSidebarUnfoldLine color="#b4b8bb" />
|
|
270
270
|
</button>
|
|
271
271
|
)}
|
|
272
272
|
</header>
|
|
273
|
+
<div className="console-content">
|
|
274
|
+
<div className="side-panel">
|
|
275
|
+
<canvas style={{ display: "none" }} ref={renderCanvasRef} />
|
|
273
276
|
|
|
274
277
|
{/* Connection Settings Section */}
|
|
275
278
|
<section className="connection-settings">
|
|
@@ -503,6 +506,9 @@ function SidePanel({
|
|
|
503
506
|
</button>
|
|
504
507
|
</div>
|
|
505
508
|
)}
|
|
509
|
+
</div>
|
|
510
|
+
<TranscriptionPreview open={open} />
|
|
511
|
+
</div>
|
|
506
512
|
</div>
|
|
507
513
|
);
|
|
508
514
|
}
|
src/frontends/{live_api_react → adk_live_react}/frontend/src/components/side-panel/side-panel.scss
RENAMED
|
@@ -15,7 +15,153 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
/* stylelint-disable */
|
|
18
|
+
.console-container {
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
height: 100vh;
|
|
22
|
+
transition: all 0.2s ease-in;
|
|
23
|
+
|
|
24
|
+
.console-header {
|
|
25
|
+
display: flex;
|
|
26
|
+
justify-content: space-between;
|
|
27
|
+
align-items: center;
|
|
28
|
+
padding: 6px 20px;
|
|
29
|
+
border-bottom: 1px solid var(--Neutral-20);
|
|
30
|
+
background: var(--Neutral-00);
|
|
31
|
+
flex-shrink: 0;
|
|
32
|
+
min-height: 38px;
|
|
33
|
+
|
|
34
|
+
h2 {
|
|
35
|
+
color: var(--Neutral-90, #e1e2e3);
|
|
36
|
+
font-family: "Google Sans";
|
|
37
|
+
font-size: 16px;
|
|
38
|
+
font-style: normal;
|
|
39
|
+
font-weight: 500;
|
|
40
|
+
line-height: 16px;
|
|
41
|
+
margin: 0;
|
|
42
|
+
opacity: 0;
|
|
43
|
+
display: none;
|
|
44
|
+
transition: opacity 0.2s ease-in;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.toggle-button {
|
|
48
|
+
background: transparent;
|
|
49
|
+
border: 0;
|
|
50
|
+
cursor: pointer;
|
|
51
|
+
padding: 4px;
|
|
52
|
+
height: 30px;
|
|
53
|
+
width: 30px;
|
|
54
|
+
display: flex;
|
|
55
|
+
align-items: center;
|
|
56
|
+
justify-content: center;
|
|
57
|
+
color: #b4b8bb;
|
|
58
|
+
flex-shrink: 0;
|
|
59
|
+
|
|
60
|
+
svg {
|
|
61
|
+
width: 20px;
|
|
62
|
+
height: 20px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
&:hover {
|
|
66
|
+
opacity: 0.7;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.console-content {
|
|
72
|
+
display: flex;
|
|
73
|
+
flex-direction: row;
|
|
74
|
+
flex: 1;
|
|
75
|
+
overflow: hidden;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
&.open {
|
|
79
|
+
.console-header h2 {
|
|
80
|
+
display: block;
|
|
81
|
+
opacity: 1;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.side-panel {
|
|
85
|
+
width: 400px;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
&:not(.open) {
|
|
90
|
+
.console-header {
|
|
91
|
+
padding: 6px 5px;
|
|
92
|
+
|
|
93
|
+
.toggle-button {
|
|
94
|
+
margin: 0 auto;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.side-panel {
|
|
99
|
+
width: 40px;
|
|
100
|
+
|
|
101
|
+
.side-panel-container {
|
|
102
|
+
opacity: 0;
|
|
103
|
+
display: none;
|
|
104
|
+
transition: all 0.2s ease-in allow-discrete;
|
|
105
|
+
transition-delay: 0.1s;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.connection-settings {
|
|
109
|
+
opacity: 0;
|
|
110
|
+
display: none;
|
|
111
|
+
transition: all 0.2s ease-in allow-discrete;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.control-tray {
|
|
115
|
+
opacity: 0;
|
|
116
|
+
display: none;
|
|
117
|
+
transition: all 0.2s ease-in allow-discrete;
|
|
118
|
+
|
|
119
|
+
.actions-nav {
|
|
120
|
+
opacity: 0;
|
|
121
|
+
display: none;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.connection-status {
|
|
125
|
+
opacity: 0;
|
|
126
|
+
display: none;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.indicators {
|
|
131
|
+
.react-select {
|
|
132
|
+
opacity: 0;
|
|
133
|
+
display: none;
|
|
134
|
+
transition: all 0.2s ease-in allow-discrete;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.streaming-indicator {
|
|
138
|
+
width: 30px;
|
|
139
|
+
opacity: 0;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.input-container {
|
|
144
|
+
opacity: 0;
|
|
145
|
+
display: none;
|
|
146
|
+
transition: all 0.2s ease-in allow-discrete;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.audio-pulse-bottom {
|
|
150
|
+
.pulse-container {
|
|
151
|
+
.pulse-label {
|
|
152
|
+
opacity: 0;
|
|
153
|
+
display: none;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
18
161
|
.side-panel {
|
|
162
|
+
width: 400px;
|
|
163
|
+
transition: width 0.2s ease-in;
|
|
164
|
+
|
|
19
165
|
.react-select {
|
|
20
166
|
background: var(--Neutral-20);
|
|
21
167
|
color: var(--Neutral-90);
|
|
@@ -47,7 +193,6 @@
|
|
|
47
193
|
}
|
|
48
194
|
}
|
|
49
195
|
background: var(--Neutral-00);
|
|
50
|
-
width: 40px; /* when closed */
|
|
51
196
|
display: flex;
|
|
52
197
|
flex-direction: column;
|
|
53
198
|
height: 100vh;
|
|
@@ -65,116 +210,6 @@
|
|
|
65
210
|
display: none !important;
|
|
66
211
|
}
|
|
67
212
|
|
|
68
|
-
&.open {
|
|
69
|
-
.top {
|
|
70
|
-
h2 {
|
|
71
|
-
left: 0%;
|
|
72
|
-
display: block;
|
|
73
|
-
opacity: 1;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.top {
|
|
79
|
-
display: flex;
|
|
80
|
-
width: calc(100% - 45px);
|
|
81
|
-
justify-content: space-between;
|
|
82
|
-
align-items: center;
|
|
83
|
-
padding: 12px 20px 12px 25px;
|
|
84
|
-
border-bottom: 1px solid var(--Neutral-20);
|
|
85
|
-
|
|
86
|
-
h2 {
|
|
87
|
-
position: relative;
|
|
88
|
-
color: var(--Neutral-90, #e1e2e3);
|
|
89
|
-
font-family: "Google Sans";
|
|
90
|
-
font-size: 21px;
|
|
91
|
-
font-style: normal;
|
|
92
|
-
font-weight: 500;
|
|
93
|
-
line-height: 16px; /* 100% */
|
|
94
|
-
|
|
95
|
-
opacity: 0;
|
|
96
|
-
display: none;
|
|
97
|
-
left: -100%;
|
|
98
|
-
transition:
|
|
99
|
-
opacity 0.2s ease-in,
|
|
100
|
-
left 0.2s ease-in,
|
|
101
|
-
display 0.2s ease-in;
|
|
102
|
-
transition-behavior: allow-discrete;
|
|
103
|
-
|
|
104
|
-
@starting-style {
|
|
105
|
-
left: 0%;
|
|
106
|
-
opacity: 1;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
.opener {
|
|
112
|
-
height: 30px;
|
|
113
|
-
transition: transform 0.2s ease-in;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
&:not(.open) {
|
|
117
|
-
.side-panel-container {
|
|
118
|
-
opacity: 0;
|
|
119
|
-
display: none;
|
|
120
|
-
transition: all 0.2s ease-in allow-discrete;
|
|
121
|
-
transition-delay: 0.1s;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
.connection-settings {
|
|
125
|
-
opacity: 0;
|
|
126
|
-
display: none;
|
|
127
|
-
transition: all 0.2s ease-in allow-discrete;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
.control-tray {
|
|
131
|
-
opacity: 0;
|
|
132
|
-
display: none;
|
|
133
|
-
transition: all 0.2s ease-in allow-discrete;
|
|
134
|
-
|
|
135
|
-
.actions-nav {
|
|
136
|
-
opacity: 0;
|
|
137
|
-
display: none;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
.connection-status {
|
|
141
|
-
opacity: 0;
|
|
142
|
-
display: none;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
.indicators {
|
|
147
|
-
.react-select {
|
|
148
|
-
opacity: 0;
|
|
149
|
-
display: none;
|
|
150
|
-
transition: all 0.2s ease-in allow-discrete;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
.streaming-indicator {
|
|
154
|
-
width: 30px;
|
|
155
|
-
opacity: 0;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
.opener {
|
|
160
|
-
transform: translate(-50%, 0);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
.input-container {
|
|
164
|
-
opacity: 0;
|
|
165
|
-
display: none;
|
|
166
|
-
transition: all 0.2s ease-in allow-discrete;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
.audio-pulse-bottom {
|
|
170
|
-
.pulse-container {
|
|
171
|
-
.pulse-label {
|
|
172
|
-
opacity: 0;
|
|
173
|
-
display: none;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
213
|
|
|
179
214
|
.indicators {
|
|
180
215
|
display: flex;
|
|
@@ -496,10 +531,6 @@
|
|
|
496
531
|
}
|
|
497
532
|
}
|
|
498
533
|
}
|
|
499
|
-
.side-panel.open {
|
|
500
|
-
width: 400px;
|
|
501
|
-
height: 100vh;
|
|
502
|
-
}
|
|
503
534
|
|
|
504
535
|
.side-panel-responses,
|
|
505
536
|
.side-panel-requests {
|
src/frontends/adk_live_react/frontend/src/components/transcription-preview/TranscriptionPreview.tsx
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
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 { useEffect, useRef, useState } from "react";
|
|
18
|
+
import { useLiveAPIContext } from "../../contexts/LiveAPIContext";
|
|
19
|
+
import cn from "classnames";
|
|
20
|
+
import "./transcription-preview.scss";
|
|
21
|
+
|
|
22
|
+
export type TranscriptionPreviewProps = {
|
|
23
|
+
open: boolean;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default function TranscriptionPreview({ open }: TranscriptionPreviewProps) {
|
|
27
|
+
const { client } = useLiveAPIContext();
|
|
28
|
+
const [inputTexts, setInputTexts] = useState<string[]>([]);
|
|
29
|
+
const [outputTexts, setOutputTexts] = useState<string[]>([]);
|
|
30
|
+
const inputRef = useRef<HTMLDivElement>(null);
|
|
31
|
+
const outputRef = useRef<HTMLDivElement>(null);
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
const handleInputTranscription = (text: string) => {
|
|
35
|
+
setInputTexts((prev) => [...prev, text]);
|
|
36
|
+
// Auto-scroll to bottom
|
|
37
|
+
setTimeout(() => {
|
|
38
|
+
if (inputRef.current) {
|
|
39
|
+
inputRef.current.scrollTop = inputRef.current.scrollHeight;
|
|
40
|
+
}
|
|
41
|
+
}, 0);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const handleOutputTranscription = (text: string) => {
|
|
45
|
+
setOutputTexts((prev) => [...prev, text]);
|
|
46
|
+
// Auto-scroll to bottom
|
|
47
|
+
setTimeout(() => {
|
|
48
|
+
if (outputRef.current) {
|
|
49
|
+
outputRef.current.scrollTop = outputRef.current.scrollHeight;
|
|
50
|
+
}
|
|
51
|
+
}, 0);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
client.on("inputtranscription", handleInputTranscription);
|
|
55
|
+
client.on("outputtranscription", handleOutputTranscription);
|
|
56
|
+
|
|
57
|
+
return () => {
|
|
58
|
+
client.off("inputtranscription", handleInputTranscription);
|
|
59
|
+
client.off("outputtranscription", handleOutputTranscription);
|
|
60
|
+
};
|
|
61
|
+
}, [client]);
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<div className={cn("transcription-preview", { open })}>
|
|
65
|
+
<div className="transcription-section input-section">
|
|
66
|
+
<div className="transcription-header">
|
|
67
|
+
<span className="material-symbols-outlined">mic</span>
|
|
68
|
+
<h3>Input</h3>
|
|
69
|
+
</div>
|
|
70
|
+
<div className="transcription-content" ref={inputRef}>
|
|
71
|
+
{inputTexts.length > 0 ? (
|
|
72
|
+
<>
|
|
73
|
+
{inputTexts.map((text, index) => (
|
|
74
|
+
<p key={index} className={index === inputTexts.length - 1 ? "current" : "previous"}>
|
|
75
|
+
{text}
|
|
76
|
+
</p>
|
|
77
|
+
))}
|
|
78
|
+
</>
|
|
79
|
+
) : (
|
|
80
|
+
<p className="placeholder">Listening...</p>
|
|
81
|
+
)}
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
<div className="transcription-section output-section">
|
|
86
|
+
<div className="transcription-header">
|
|
87
|
+
<span className="material-symbols-outlined">volume_up</span>
|
|
88
|
+
<h3>Output</h3>
|
|
89
|
+
</div>
|
|
90
|
+
<div className="transcription-content" ref={outputRef}>
|
|
91
|
+
{outputTexts.length > 0 ? (
|
|
92
|
+
<>
|
|
93
|
+
{outputTexts.map((text, index) => (
|
|
94
|
+
<p key={index} className={index === outputTexts.length - 1 ? "current" : "previous"}>
|
|
95
|
+
{text}
|
|
96
|
+
</p>
|
|
97
|
+
))}
|
|
98
|
+
</>
|
|
99
|
+
) : (
|
|
100
|
+
<p className="placeholder">Waiting for response...</p>
|
|
101
|
+
)}
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
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
|
+
.transcription-preview {
|
|
18
|
+
width: 0;
|
|
19
|
+
height: 100%;
|
|
20
|
+
background: var(--Neutral-00);
|
|
21
|
+
border-left: 1px solid var(--Neutral-20);
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: column;
|
|
24
|
+
gap: 0;
|
|
25
|
+
overflow: hidden;
|
|
26
|
+
transition: width 0.2s ease-in-out;
|
|
27
|
+
flex-shrink: 0;
|
|
28
|
+
|
|
29
|
+
&.open {
|
|
30
|
+
width: 300px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.transcription-section {
|
|
34
|
+
flex: 1;
|
|
35
|
+
display: flex;
|
|
36
|
+
flex-direction: column;
|
|
37
|
+
overflow: hidden;
|
|
38
|
+
opacity: 0;
|
|
39
|
+
transition: opacity 0.2s ease-in-out 0.1s;
|
|
40
|
+
|
|
41
|
+
&:first-child {
|
|
42
|
+
border-bottom: 1px solid var(--Neutral-20);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.transcription-header {
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
gap: 8px;
|
|
49
|
+
padding: 12px 20px;
|
|
50
|
+
background: var(--Neutral-05);
|
|
51
|
+
border-bottom: 1px solid var(--Neutral-20);
|
|
52
|
+
flex-shrink: 0;
|
|
53
|
+
|
|
54
|
+
.material-symbols-outlined {
|
|
55
|
+
font-size: 20px;
|
|
56
|
+
color: var(--Neutral-70);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
h3 {
|
|
60
|
+
margin: 0;
|
|
61
|
+
font-size: 12px;
|
|
62
|
+
font-weight: 600;
|
|
63
|
+
color: var(--Neutral-90);
|
|
64
|
+
text-transform: uppercase;
|
|
65
|
+
letter-spacing: 0.5px;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.transcription-content {
|
|
70
|
+
flex: 1;
|
|
71
|
+
padding: 12px 16px;
|
|
72
|
+
overflow-y: auto;
|
|
73
|
+
overflow-x: hidden;
|
|
74
|
+
word-wrap: break-word;
|
|
75
|
+
|
|
76
|
+
p {
|
|
77
|
+
margin: 0 0 12px 0;
|
|
78
|
+
color: var(--Neutral-90);
|
|
79
|
+
font-size: 13px;
|
|
80
|
+
line-height: 1.5;
|
|
81
|
+
white-space: pre-wrap;
|
|
82
|
+
word-break: break-word;
|
|
83
|
+
font-family: var(--font-family);
|
|
84
|
+
|
|
85
|
+
&.placeholder {
|
|
86
|
+
color: var(--Neutral-50);
|
|
87
|
+
font-style: italic;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
&.previous {
|
|
91
|
+
color: var(--Neutral-60);
|
|
92
|
+
opacity: 0.7;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
&.current {
|
|
96
|
+
color: var(--Neutral-90);
|
|
97
|
+
font-weight: 500;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
&:last-child {
|
|
101
|
+
margin-bottom: 0;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
&.open .transcription-section {
|
|
108
|
+
opacity: 1;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.input-section {
|
|
112
|
+
.transcription-header {
|
|
113
|
+
.material-symbols-outlined {
|
|
114
|
+
color: var(--Green-500);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
h3 {
|
|
118
|
+
color: var(--Green-500);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.transcription-content {
|
|
123
|
+
background: linear-gradient(
|
|
124
|
+
to bottom,
|
|
125
|
+
rgba(0, 200, 100, 0.02),
|
|
126
|
+
transparent
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.output-section {
|
|
132
|
+
.transcription-header {
|
|
133
|
+
.material-symbols-outlined {
|
|
134
|
+
color: var(--Blue-500);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
h3 {
|
|
138
|
+
color: var(--Blue-500);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.transcription-content {
|
|
143
|
+
background: linear-gradient(
|
|
144
|
+
to bottom,
|
|
145
|
+
rgba(0, 100, 255, 0.02),
|
|
146
|
+
transparent
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|