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.
- agent_starter_pack-0.0.1b0.dist-info/METADATA +143 -0
- agent_starter_pack-0.0.1b0.dist-info/RECORD +162 -0
- agent_starter_pack-0.0.1b0.dist-info/WHEEL +4 -0
- agent_starter_pack-0.0.1b0.dist-info/entry_points.txt +2 -0
- agent_starter_pack-0.0.1b0.dist-info/licenses/LICENSE +201 -0
- agents/agentic_rag_vertexai_search/README.md +22 -0
- agents/agentic_rag_vertexai_search/app/agent.py +145 -0
- agents/agentic_rag_vertexai_search/app/retrievers.py +79 -0
- agents/agentic_rag_vertexai_search/app/templates.py +53 -0
- agents/agentic_rag_vertexai_search/notebooks/evaluating_langgraph_agent.ipynb +1561 -0
- agents/agentic_rag_vertexai_search/template/.templateconfig.yaml +14 -0
- agents/agentic_rag_vertexai_search/tests/integration/test_agent.py +57 -0
- agents/crewai_coding_crew/README.md +34 -0
- agents/crewai_coding_crew/app/agent.py +86 -0
- agents/crewai_coding_crew/app/crew/config/agents.yaml +39 -0
- agents/crewai_coding_crew/app/crew/config/tasks.yaml +37 -0
- agents/crewai_coding_crew/app/crew/crew.py +71 -0
- agents/crewai_coding_crew/notebooks/evaluating_crewai_agent.ipynb +1571 -0
- agents/crewai_coding_crew/notebooks/evaluating_langgraph_agent.ipynb +1561 -0
- agents/crewai_coding_crew/template/.templateconfig.yaml +12 -0
- agents/crewai_coding_crew/tests/integration/test_agent.py +47 -0
- agents/langgraph_base_react/README.md +9 -0
- agents/langgraph_base_react/app/agent.py +73 -0
- agents/langgraph_base_react/notebooks/evaluating_langgraph_agent.ipynb +1561 -0
- agents/langgraph_base_react/template/.templateconfig.yaml +13 -0
- agents/langgraph_base_react/tests/integration/test_agent.py +48 -0
- agents/multimodal_live_api/README.md +50 -0
- agents/multimodal_live_api/app/agent.py +86 -0
- agents/multimodal_live_api/app/server.py +193 -0
- agents/multimodal_live_api/app/templates.py +51 -0
- agents/multimodal_live_api/app/vector_store.py +55 -0
- agents/multimodal_live_api/template/.templateconfig.yaml +15 -0
- agents/multimodal_live_api/tests/integration/test_server_e2e.py +254 -0
- agents/multimodal_live_api/tests/load_test/load_test.py +40 -0
- agents/multimodal_live_api/tests/unit/test_server.py +143 -0
- src/base_template/.gitignore +197 -0
- src/base_template/Makefile +37 -0
- src/base_template/README.md +91 -0
- src/base_template/app/utils/tracing.py +143 -0
- src/base_template/app/utils/typing.py +115 -0
- src/base_template/deployment/README.md +123 -0
- src/base_template/deployment/cd/deploy-to-prod.yaml +98 -0
- src/base_template/deployment/cd/staging.yaml +215 -0
- src/base_template/deployment/ci/pr_checks.yaml +51 -0
- src/base_template/deployment/terraform/apis.tf +34 -0
- src/base_template/deployment/terraform/build_triggers.tf +122 -0
- src/base_template/deployment/terraform/dev/apis.tf +42 -0
- src/base_template/deployment/terraform/dev/iam.tf +90 -0
- src/base_template/deployment/terraform/dev/log_sinks.tf +66 -0
- src/base_template/deployment/terraform/dev/providers.tf +29 -0
- src/base_template/deployment/terraform/dev/storage.tf +76 -0
- src/base_template/deployment/terraform/dev/variables.tf +126 -0
- src/base_template/deployment/terraform/dev/vars/env.tfvars +21 -0
- src/base_template/deployment/terraform/iam.tf +130 -0
- src/base_template/deployment/terraform/locals.tf +50 -0
- src/base_template/deployment/terraform/log_sinks.tf +72 -0
- src/base_template/deployment/terraform/providers.tf +35 -0
- src/base_template/deployment/terraform/service_accounts.tf +42 -0
- src/base_template/deployment/terraform/storage.tf +100 -0
- src/base_template/deployment/terraform/variables.tf +202 -0
- src/base_template/deployment/terraform/vars/env.tfvars +43 -0
- src/base_template/pyproject.toml +113 -0
- src/base_template/tests/unit/test_utils/test_tracing_exporter.py +140 -0
- src/cli/commands/create.py +534 -0
- src/cli/commands/setup_cicd.py +730 -0
- src/cli/main.py +35 -0
- src/cli/utils/__init__.py +35 -0
- src/cli/utils/cicd.py +662 -0
- src/cli/utils/gcp.py +120 -0
- src/cli/utils/logging.py +51 -0
- src/cli/utils/template.py +644 -0
- src/data_ingestion/README.md +79 -0
- src/data_ingestion/data_ingestion_pipeline/components/ingest_data.py +175 -0
- src/data_ingestion/data_ingestion_pipeline/components/process_data.py +321 -0
- src/data_ingestion/data_ingestion_pipeline/pipeline.py +58 -0
- src/data_ingestion/data_ingestion_pipeline/submit_pipeline.py +184 -0
- src/data_ingestion/pyproject.toml +17 -0
- src/data_ingestion/uv.lock +999 -0
- src/deployment_targets/agent_engine/app/agent_engine_app.py +238 -0
- src/deployment_targets/agent_engine/app/utils/gcs.py +42 -0
- src/deployment_targets/agent_engine/deployment_metadata.json +4 -0
- src/deployment_targets/agent_engine/notebooks/intro_reasoning_engine.ipynb +869 -0
- src/deployment_targets/agent_engine/tests/integration/test_agent_engine_app.py +120 -0
- src/deployment_targets/agent_engine/tests/load_test/.results/.placeholder +0 -0
- src/deployment_targets/agent_engine/tests/load_test/.results/report.html +264 -0
- src/deployment_targets/agent_engine/tests/load_test/.results/results_exceptions.csv +1 -0
- src/deployment_targets/agent_engine/tests/load_test/.results/results_failures.csv +1 -0
- src/deployment_targets/agent_engine/tests/load_test/.results/results_stats.csv +3 -0
- src/deployment_targets/agent_engine/tests/load_test/.results/results_stats_history.csv +22 -0
- src/deployment_targets/agent_engine/tests/load_test/README.md +42 -0
- src/deployment_targets/agent_engine/tests/load_test/load_test.py +100 -0
- src/deployment_targets/agent_engine/tests/unit/test_dummy.py +22 -0
- src/deployment_targets/cloud_run/Dockerfile +29 -0
- src/deployment_targets/cloud_run/app/server.py +128 -0
- src/deployment_targets/cloud_run/deployment/terraform/artifact_registry.tf +22 -0
- src/deployment_targets/cloud_run/deployment/terraform/dev/service_accounts.tf +20 -0
- src/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +192 -0
- src/deployment_targets/cloud_run/tests/load_test/.results/.placeholder +0 -0
- src/deployment_targets/cloud_run/tests/load_test/README.md +79 -0
- src/deployment_targets/cloud_run/tests/load_test/load_test.py +85 -0
- src/deployment_targets/cloud_run/tests/unit/test_server.py +142 -0
- src/deployment_targets/cloud_run/uv.lock +6952 -0
- src/frontends/live_api_react/frontend/package-lock.json +19405 -0
- src/frontends/live_api_react/frontend/package.json +56 -0
- src/frontends/live_api_react/frontend/public/favicon.ico +0 -0
- src/frontends/live_api_react/frontend/public/index.html +62 -0
- src/frontends/live_api_react/frontend/public/robots.txt +3 -0
- src/frontends/live_api_react/frontend/src/App.scss +189 -0
- src/frontends/live_api_react/frontend/src/App.test.tsx +25 -0
- src/frontends/live_api_react/frontend/src/App.tsx +205 -0
- src/frontends/live_api_react/frontend/src/components/audio-pulse/AudioPulse.tsx +64 -0
- src/frontends/live_api_react/frontend/src/components/audio-pulse/audio-pulse.scss +68 -0
- src/frontends/live_api_react/frontend/src/components/control-tray/ControlTray.tsx +217 -0
- src/frontends/live_api_react/frontend/src/components/control-tray/control-tray.scss +201 -0
- src/frontends/live_api_react/frontend/src/components/logger/Logger.tsx +241 -0
- src/frontends/live_api_react/frontend/src/components/logger/logger.scss +133 -0
- src/frontends/live_api_react/frontend/src/components/logger/mock-logs.ts +151 -0
- src/frontends/live_api_react/frontend/src/components/side-panel/SidePanel.tsx +161 -0
- src/frontends/live_api_react/frontend/src/components/side-panel/side-panel.scss +285 -0
- src/frontends/live_api_react/frontend/src/contexts/LiveAPIContext.tsx +48 -0
- src/frontends/live_api_react/frontend/src/hooks/use-live-api.ts +115 -0
- src/frontends/live_api_react/frontend/src/hooks/use-media-stream-mux.ts +23 -0
- src/frontends/live_api_react/frontend/src/hooks/use-screen-capture.ts +72 -0
- src/frontends/live_api_react/frontend/src/hooks/use-webcam.ts +69 -0
- src/frontends/live_api_react/frontend/src/index.css +28 -0
- src/frontends/live_api_react/frontend/src/index.tsx +35 -0
- src/frontends/live_api_react/frontend/src/multimodal-live-types.ts +242 -0
- src/frontends/live_api_react/frontend/src/react-app-env.d.ts +17 -0
- src/frontends/live_api_react/frontend/src/reportWebVitals.ts +31 -0
- src/frontends/live_api_react/frontend/src/setupTests.ts +21 -0
- src/frontends/live_api_react/frontend/src/utils/audio-recorder.ts +111 -0
- src/frontends/live_api_react/frontend/src/utils/audio-streamer.ts +270 -0
- src/frontends/live_api_react/frontend/src/utils/audioworklet-registry.ts +43 -0
- src/frontends/live_api_react/frontend/src/utils/multimodal-live-client.ts +329 -0
- src/frontends/live_api_react/frontend/src/utils/store-logger.ts +64 -0
- src/frontends/live_api_react/frontend/src/utils/utils.ts +86 -0
- src/frontends/live_api_react/frontend/src/utils/worklets/audio-processing.ts +73 -0
- src/frontends/live_api_react/frontend/src/utils/worklets/vol-meter.ts +65 -0
- src/frontends/live_api_react/frontend/tsconfig.json +25 -0
- src/frontends/streamlit/frontend/side_bar.py +213 -0
- src/frontends/streamlit/frontend/streamlit_app.py +263 -0
- src/frontends/streamlit/frontend/style/app_markdown.py +37 -0
- src/frontends/streamlit/frontend/utils/chat_utils.py +67 -0
- src/frontends/streamlit/frontend/utils/local_chat_history.py +125 -0
- src/frontends/streamlit/frontend/utils/message_editing.py +59 -0
- src/frontends/streamlit/frontend/utils/multimodal_utils.py +217 -0
- src/frontends/streamlit/frontend/utils/stream_handler.py +282 -0
- src/frontends/streamlit/frontend/utils/title_summary.py +77 -0
- src/resources/containers/data_processing/Dockerfile +25 -0
- src/resources/locks/uv-agentic_rag_vertexai_search-agent_engine.lock +4684 -0
- src/resources/locks/uv-agentic_rag_vertexai_search-cloud_run.lock +5799 -0
- src/resources/locks/uv-crewai_coding_crew-agent_engine.lock +5509 -0
- src/resources/locks/uv-crewai_coding_crew-cloud_run.lock +6688 -0
- src/resources/locks/uv-langgraph_base_react-agent_engine.lock +4595 -0
- src/resources/locks/uv-langgraph_base_react-cloud_run.lock +5710 -0
- src/resources/locks/uv-multimodal_live_api-cloud_run.lock +5665 -0
- src/resources/setup_cicd/cicd_variables.tf +36 -0
- src/resources/setup_cicd/github.tf +85 -0
- src/resources/setup_cicd/providers.tf +39 -0
- src/utils/generate_locks.py +135 -0
- src/utils/lock_utils.py +82 -0
- src/utils/watch_and_rebuild.py +190 -0
|
@@ -0,0 +1,133 @@
|
|
|
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
|
+
.logger {
|
|
19
|
+
color: var(--gray-300);
|
|
20
|
+
width: 100%;
|
|
21
|
+
max-width: 100%;
|
|
22
|
+
display: block;
|
|
23
|
+
|
|
24
|
+
.logger-list {
|
|
25
|
+
padding: 0 0px 0 25px;
|
|
26
|
+
overflow-x: hidden;
|
|
27
|
+
width: calc(100% - 45px);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.user h4 {
|
|
31
|
+
color: var(--Green-500);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.model h4 {
|
|
35
|
+
color: var(--Blue-500);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.rich-log {
|
|
39
|
+
display: flex;
|
|
40
|
+
justify-content: center;
|
|
41
|
+
gap: 4px;
|
|
42
|
+
|
|
43
|
+
pre {
|
|
44
|
+
overflow-x: auto;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
display: block;
|
|
48
|
+
|
|
49
|
+
h4 {
|
|
50
|
+
font-size: 14px;
|
|
51
|
+
text-transform: uppercase;
|
|
52
|
+
padding: 8px 0;
|
|
53
|
+
margin: 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
h5 {
|
|
57
|
+
margin: 0;
|
|
58
|
+
padding-bottom: 8px;
|
|
59
|
+
border-bottom: 1px solid var(--Neutral-20);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.part {
|
|
63
|
+
background: var(--Neutral-5);
|
|
64
|
+
padding: 14px;
|
|
65
|
+
margin-bottom: 4px;
|
|
66
|
+
color: var(--Neutral-90);
|
|
67
|
+
border-radius: 8px;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.plain-log {
|
|
72
|
+
& > * {
|
|
73
|
+
padding-right: 4px;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.inline-code:not(:last-child) {
|
|
78
|
+
font-style: italic;
|
|
79
|
+
|
|
80
|
+
&::after {
|
|
81
|
+
content: ", ";
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.logger li {
|
|
87
|
+
display: block;
|
|
88
|
+
padding: 8px 0;
|
|
89
|
+
color: var(--Neutral-50, #707577);
|
|
90
|
+
font-family: "Space Mono";
|
|
91
|
+
font-size: 14px;
|
|
92
|
+
font-style: normal;
|
|
93
|
+
font-weight: 400;
|
|
94
|
+
line-height: normal;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.logger li .timestamp {
|
|
98
|
+
width: 70px;
|
|
99
|
+
flex-grow: 0;
|
|
100
|
+
flex-shrink: 0;
|
|
101
|
+
color: var(--Neutral-50);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.logger li .source {
|
|
105
|
+
flex-shrink: 0;
|
|
106
|
+
font-weight: bold;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.logger li.source-server,
|
|
110
|
+
.logger li.receive {
|
|
111
|
+
color: var(--Blue-500);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.logger li.source-client,
|
|
115
|
+
.logger li.send:not(.source-server) {
|
|
116
|
+
color: var(--Green-500);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.logger li .count {
|
|
120
|
+
background-color: var(--Neutral-5);
|
|
121
|
+
font-size: x-small;
|
|
122
|
+
padding: 0em 0.6em;
|
|
123
|
+
padding: 0.3em 0.5em;
|
|
124
|
+
line-height: 1em;
|
|
125
|
+
vertical-align: middle;
|
|
126
|
+
border-radius: 8px;
|
|
127
|
+
color: var(--Blue-500);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.logger li .message {
|
|
131
|
+
flex-grow: 1;
|
|
132
|
+
color: var(--Neutral-50);
|
|
133
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
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
|
+
/**
|
|
18
|
+
* this module is just mock data, intended to make it easier to develop and style the logger
|
|
19
|
+
*/
|
|
20
|
+
import type { StreamingLog } from "../../multimodal-live-types";
|
|
21
|
+
|
|
22
|
+
const soundLogs = (n: number): StreamingLog[] =>
|
|
23
|
+
new Array(n).fill(0).map(
|
|
24
|
+
(): StreamingLog => ({
|
|
25
|
+
date: new Date(),
|
|
26
|
+
type: "server.audio",
|
|
27
|
+
message: "buffer (11250)",
|
|
28
|
+
}),
|
|
29
|
+
);
|
|
30
|
+
//
|
|
31
|
+
const realtimeLogs = (n: number): StreamingLog[] =>
|
|
32
|
+
new Array(n).fill(0).map(
|
|
33
|
+
(): StreamingLog => ({
|
|
34
|
+
date: new Date(),
|
|
35
|
+
type: "client.realtimeInput",
|
|
36
|
+
message: "audio",
|
|
37
|
+
}),
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
export const mockLogs: StreamingLog[] = [
|
|
41
|
+
{
|
|
42
|
+
date: new Date(),
|
|
43
|
+
type: "client.open",
|
|
44
|
+
message: "connected to socket",
|
|
45
|
+
},
|
|
46
|
+
...realtimeLogs(10),
|
|
47
|
+
...soundLogs(10),
|
|
48
|
+
{
|
|
49
|
+
date: new Date(),
|
|
50
|
+
type: "receive.content",
|
|
51
|
+
message: {
|
|
52
|
+
serverContent: {
|
|
53
|
+
interrupted: true,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
date: new Date(),
|
|
59
|
+
type: "receive.content",
|
|
60
|
+
message: {
|
|
61
|
+
serverContent: {
|
|
62
|
+
turnComplete: true,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
//this one is just a string
|
|
67
|
+
// {
|
|
68
|
+
// date: new Date(),
|
|
69
|
+
// type: "server.send",
|
|
70
|
+
// message: {
|
|
71
|
+
// serverContent: {
|
|
72
|
+
// turnComplete: true,
|
|
73
|
+
// },
|
|
74
|
+
// },
|
|
75
|
+
// },
|
|
76
|
+
...realtimeLogs(10),
|
|
77
|
+
...soundLogs(20),
|
|
78
|
+
{
|
|
79
|
+
date: new Date(),
|
|
80
|
+
type: "receive.content",
|
|
81
|
+
message: {
|
|
82
|
+
serverContent: {
|
|
83
|
+
modelTurn: {
|
|
84
|
+
parts: [{ text: "Hey its text" }, { text: "more" }],
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
date: new Date(),
|
|
91
|
+
type: "client.send",
|
|
92
|
+
message: {
|
|
93
|
+
clientContent: {
|
|
94
|
+
turns: [
|
|
95
|
+
{
|
|
96
|
+
role: "User",
|
|
97
|
+
parts: [
|
|
98
|
+
{
|
|
99
|
+
text: "How much wood could a woodchuck chuck if a woodchuck could chuck wood",
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
turnComplete: true,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
date: new Date(),
|
|
110
|
+
type: "server.toolCall",
|
|
111
|
+
message: {
|
|
112
|
+
toolCall: {
|
|
113
|
+
functionCalls: [
|
|
114
|
+
{
|
|
115
|
+
id: "akadjlasdfla-askls",
|
|
116
|
+
name: "take_photo",
|
|
117
|
+
args: {},
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
id: "akldjsjskldsj-102",
|
|
121
|
+
name: "move_camera",
|
|
122
|
+
args: { x: 20, y: 4 },
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
date: new Date(),
|
|
130
|
+
type: "server.toolCallCancellation",
|
|
131
|
+
message: {
|
|
132
|
+
toolCallCancellation: {
|
|
133
|
+
ids: ["akladfjadslfk", "adkafsdljfsdk"],
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
date: new Date(),
|
|
139
|
+
type: "client.toolResponse",
|
|
140
|
+
message: {
|
|
141
|
+
toolResponse: {
|
|
142
|
+
functionResponses: [
|
|
143
|
+
{
|
|
144
|
+
response: { success: true },
|
|
145
|
+
id: "akslaj-10102",
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
];
|
|
@@ -0,0 +1,161 @@
|
|
|
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 cn from "classnames";
|
|
18
|
+
import { useEffect, useRef, useState } from "react";
|
|
19
|
+
import { RiSidebarFoldLine, RiSidebarUnfoldLine } from "react-icons/ri";
|
|
20
|
+
import Select from "react-select";
|
|
21
|
+
import { useLiveAPIContext } from "../../contexts/LiveAPIContext";
|
|
22
|
+
import { useLoggerStore } from "../../utils/store-logger";
|
|
23
|
+
import Logger, { LoggerFilterType } from "../logger/Logger";
|
|
24
|
+
import "./side-panel.scss";
|
|
25
|
+
|
|
26
|
+
const filterOptions = [
|
|
27
|
+
{ value: "conversations", label: "Conversations" },
|
|
28
|
+
{ value: "tools", label: "Tool Use" },
|
|
29
|
+
{ value: "none", label: "All" },
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
export default function SidePanel() {
|
|
33
|
+
const { connected, client } = useLiveAPIContext();
|
|
34
|
+
const [open, setOpen] = useState(true);
|
|
35
|
+
const loggerRef = useRef<HTMLDivElement>(null);
|
|
36
|
+
const loggerLastHeightRef = useRef<number>(-1);
|
|
37
|
+
const { log, logs } = useLoggerStore();
|
|
38
|
+
|
|
39
|
+
const [textInput, setTextInput] = useState("");
|
|
40
|
+
const [selectedOption, setSelectedOption] = useState<{
|
|
41
|
+
value: string;
|
|
42
|
+
label: string;
|
|
43
|
+
} | null>(null);
|
|
44
|
+
const inputRef = useRef<HTMLTextAreaElement>(null);
|
|
45
|
+
|
|
46
|
+
//scroll the log to the bottom when new logs come in
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (loggerRef.current) {
|
|
49
|
+
const el = loggerRef.current;
|
|
50
|
+
const scrollHeight = el.scrollHeight;
|
|
51
|
+
if (scrollHeight !== loggerLastHeightRef.current) {
|
|
52
|
+
el.scrollTop = scrollHeight;
|
|
53
|
+
loggerLastHeightRef.current = scrollHeight;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}, [logs]);
|
|
57
|
+
|
|
58
|
+
// listen for log events and store them
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
client.on("log", log);
|
|
61
|
+
return () => {
|
|
62
|
+
client.off("log", log);
|
|
63
|
+
};
|
|
64
|
+
}, [client, log]);
|
|
65
|
+
|
|
66
|
+
const handleSubmit = () => {
|
|
67
|
+
client.send([{ text: textInput }]);
|
|
68
|
+
|
|
69
|
+
setTextInput("");
|
|
70
|
+
if (inputRef.current) {
|
|
71
|
+
inputRef.current.innerText = "";
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<div className={`side-panel ${open ? "open" : ""}`}>
|
|
77
|
+
<header className="top">
|
|
78
|
+
<h2>Console</h2>
|
|
79
|
+
{open ? (
|
|
80
|
+
<button className="opener" onClick={() => setOpen(false)}>
|
|
81
|
+
<RiSidebarFoldLine color="#b4b8bb" />
|
|
82
|
+
</button>
|
|
83
|
+
) : (
|
|
84
|
+
<button className="opener" onClick={() => setOpen(true)}>
|
|
85
|
+
<RiSidebarUnfoldLine color="#b4b8bb" />
|
|
86
|
+
</button>
|
|
87
|
+
)}
|
|
88
|
+
</header>
|
|
89
|
+
<section className="indicators">
|
|
90
|
+
<Select
|
|
91
|
+
className="react-select"
|
|
92
|
+
classNamePrefix="react-select"
|
|
93
|
+
styles={{
|
|
94
|
+
control: (baseStyles) => ({
|
|
95
|
+
...baseStyles,
|
|
96
|
+
background: "var(--Neutral-15)",
|
|
97
|
+
color: "var(--Neutral-90)",
|
|
98
|
+
minHeight: "33px",
|
|
99
|
+
maxHeight: "33px",
|
|
100
|
+
border: 0,
|
|
101
|
+
}),
|
|
102
|
+
option: (styles, { isFocused, isSelected }) => ({
|
|
103
|
+
...styles,
|
|
104
|
+
backgroundColor: isFocused
|
|
105
|
+
? "var(--Neutral-30)"
|
|
106
|
+
: isSelected
|
|
107
|
+
? "var(--Neutral-20)"
|
|
108
|
+
: undefined,
|
|
109
|
+
}),
|
|
110
|
+
}}
|
|
111
|
+
defaultValue={selectedOption}
|
|
112
|
+
options={filterOptions}
|
|
113
|
+
onChange={(e) => {
|
|
114
|
+
setSelectedOption(e);
|
|
115
|
+
}}
|
|
116
|
+
/>
|
|
117
|
+
<div className={cn("streaming-indicator", { connected })}>
|
|
118
|
+
{connected
|
|
119
|
+
? `🔵${open ? " Streaming" : ""}`
|
|
120
|
+
: `⏸️${open ? " Paused" : ""}`}
|
|
121
|
+
</div>
|
|
122
|
+
</section>
|
|
123
|
+
<div className="side-panel-container" ref={loggerRef}>
|
|
124
|
+
<Logger
|
|
125
|
+
filter={(selectedOption?.value as LoggerFilterType) || "none"}
|
|
126
|
+
/>
|
|
127
|
+
</div>
|
|
128
|
+
<div className={cn("input-container", { disabled: !connected })}>
|
|
129
|
+
<div className="input-content">
|
|
130
|
+
<textarea
|
|
131
|
+
className="input-area"
|
|
132
|
+
ref={inputRef}
|
|
133
|
+
onKeyDown={(e) => {
|
|
134
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
135
|
+
e.preventDefault();
|
|
136
|
+
e.stopPropagation();
|
|
137
|
+
handleSubmit();
|
|
138
|
+
}
|
|
139
|
+
}}
|
|
140
|
+
onChange={(e) => setTextInput(e.target.value)}
|
|
141
|
+
value={textInput}
|
|
142
|
+
></textarea>
|
|
143
|
+
<span
|
|
144
|
+
className={cn("input-content-placeholder", {
|
|
145
|
+
hidden: textInput.length,
|
|
146
|
+
})}
|
|
147
|
+
>
|
|
148
|
+
Type something...
|
|
149
|
+
</span>
|
|
150
|
+
|
|
151
|
+
<button
|
|
152
|
+
className="send-button material-symbols-outlined filled"
|
|
153
|
+
onClick={handleSubmit}
|
|
154
|
+
>
|
|
155
|
+
send
|
|
156
|
+
</button>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
@@ -0,0 +1,285 @@
|
|
|
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
|
+
.side-panel {
|
|
19
|
+
.react-select {
|
|
20
|
+
background: var(--Neutral-20);
|
|
21
|
+
color: var(--Neutral-90);
|
|
22
|
+
width: 193px;
|
|
23
|
+
height: 30px;
|
|
24
|
+
|
|
25
|
+
.react-select__single-value {
|
|
26
|
+
color: var(--Neutral-90);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.react-select__menu {
|
|
30
|
+
background: var(--Neutral-20);
|
|
31
|
+
color: var(--Neutral-90);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.react-select__option {
|
|
35
|
+
}
|
|
36
|
+
.react-select__value-container {
|
|
37
|
+
}
|
|
38
|
+
.react-select__indicators {
|
|
39
|
+
}
|
|
40
|
+
.react-select__option:hover,
|
|
41
|
+
.react-select__option:focus,
|
|
42
|
+
.react-select_option:focus-within {
|
|
43
|
+
background: var(--Neutral-30);
|
|
44
|
+
}
|
|
45
|
+
.react-select__option--is-focused: {
|
|
46
|
+
background: var(--Neutral-30);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
background: var(--Neutral-00);
|
|
50
|
+
width: 40px; /* when closed */
|
|
51
|
+
display: flex;
|
|
52
|
+
flex-direction: column;
|
|
53
|
+
height: 100vh;
|
|
54
|
+
transition: all 0.2s ease-in;
|
|
55
|
+
font-family: Arial, sans-serif;
|
|
56
|
+
border-right: 1px solid var(--gray-600);
|
|
57
|
+
color: var(--Neutral-90, #e1e2e3);
|
|
58
|
+
font-family: var(--font-family);
|
|
59
|
+
font-size: 13px;
|
|
60
|
+
font-style: normal;
|
|
61
|
+
font-weight: 400;
|
|
62
|
+
line-height: 160%; /* 20.8px */
|
|
63
|
+
|
|
64
|
+
.hidden {
|
|
65
|
+
display: none !important;
|
|
66
|
+
}
|
|
67
|
+
|
|
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
|
+
.indicators .streaming-indicator {
|
|
125
|
+
width: 30px;
|
|
126
|
+
opacity: 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.opener {
|
|
130
|
+
transform: translate(-50%, 0);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.input-container {
|
|
134
|
+
opacity: 0;
|
|
135
|
+
display: none;
|
|
136
|
+
transition: all 0.2s ease-in allow-discrete;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.indicators {
|
|
141
|
+
display: flex;
|
|
142
|
+
padding: 24px 25px;
|
|
143
|
+
justify-content: flex-end;
|
|
144
|
+
gap: 21px;
|
|
145
|
+
.streaming-indicator {
|
|
146
|
+
user-select: none;
|
|
147
|
+
border-radius: 4px;
|
|
148
|
+
border: 1px solid var(--Neutral-20, #2a2f31);
|
|
149
|
+
background: var(--Neutral-10, #1c1f21);
|
|
150
|
+
display: flex;
|
|
151
|
+
width: 136px;
|
|
152
|
+
height: 30px;
|
|
153
|
+
padding-left: 4px;
|
|
154
|
+
justify-content: center;
|
|
155
|
+
align-items: center;
|
|
156
|
+
gap: 6px;
|
|
157
|
+
flex-shrink: 0;
|
|
158
|
+
text-align: center;
|
|
159
|
+
font-family: "Space Mono";
|
|
160
|
+
font-size: 14px;
|
|
161
|
+
font-style: normal;
|
|
162
|
+
font-weight: 400;
|
|
163
|
+
line-height: normal;
|
|
164
|
+
transition: width 0.2s ease-in;
|
|
165
|
+
|
|
166
|
+
&.connected {
|
|
167
|
+
color: var(--Blue-500, #0d9c53);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.side-panel-container {
|
|
173
|
+
align-self: flex-end;
|
|
174
|
+
width: 400px;
|
|
175
|
+
flex-grow: 1;
|
|
176
|
+
overflow-x: hidden;
|
|
177
|
+
overflow-y: auto;
|
|
178
|
+
/*scrollbar-gutter: stable both-edges;*/
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.input-container {
|
|
182
|
+
height: 50px;
|
|
183
|
+
flex-grow: 0;
|
|
184
|
+
flex-shrink: 0;
|
|
185
|
+
border-top: 1px solid var(--Neutral-20);
|
|
186
|
+
padding: 14px 25px;
|
|
187
|
+
overflow: hidden;
|
|
188
|
+
|
|
189
|
+
.input-content {
|
|
190
|
+
position: relative;
|
|
191
|
+
background: var(--Neutral-10);
|
|
192
|
+
border: 1px solid var(--Neutral-15);
|
|
193
|
+
height: 22px;
|
|
194
|
+
border-radius: 10px;
|
|
195
|
+
padding: 11px 18px;
|
|
196
|
+
|
|
197
|
+
.send-button {
|
|
198
|
+
position: absolute;
|
|
199
|
+
top: 50%;
|
|
200
|
+
right: 0;
|
|
201
|
+
transform: translate(0, -50%);
|
|
202
|
+
background: none;
|
|
203
|
+
border: 0;
|
|
204
|
+
color: var(--Neutral-20);
|
|
205
|
+
cursor: pointer;
|
|
206
|
+
transition: color 0.1s ease-in;
|
|
207
|
+
z-index: 2;
|
|
208
|
+
|
|
209
|
+
&:hover {
|
|
210
|
+
color: var(--Neutral-60);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.input-area {
|
|
215
|
+
background: none;
|
|
216
|
+
color: var(--Neutral-90);
|
|
217
|
+
field-sizing: content;
|
|
218
|
+
position: absolute;
|
|
219
|
+
top: 0;
|
|
220
|
+
left: 0;
|
|
221
|
+
z-index: 2;
|
|
222
|
+
display: inline-block;
|
|
223
|
+
width: calc(100% - 72px);
|
|
224
|
+
max-height: 20px;
|
|
225
|
+
outline: none;
|
|
226
|
+
--webkit-box-flex: 1;
|
|
227
|
+
flex: 1;
|
|
228
|
+
word-break: break-word;
|
|
229
|
+
overflow: auto;
|
|
230
|
+
padding: 14px 18px;
|
|
231
|
+
border: 0;
|
|
232
|
+
resize: none;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.input-content-placeholder {
|
|
236
|
+
position: absolute;
|
|
237
|
+
left: 0;
|
|
238
|
+
top: 0;
|
|
239
|
+
display: flex;
|
|
240
|
+
align-items: center;
|
|
241
|
+
z-index: 1;
|
|
242
|
+
height: 100%;
|
|
243
|
+
width: 100%;
|
|
244
|
+
pointer-events: none;
|
|
245
|
+
user-select: none;
|
|
246
|
+
padding: 0px 18px;
|
|
247
|
+
white-space: pre-wrap;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
.side-panel.open {
|
|
253
|
+
width: 400px;
|
|
254
|
+
height: 100vh;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.side-panel-responses,
|
|
258
|
+
.side-panel-requests {
|
|
259
|
+
flex-grow: 1;
|
|
260
|
+
flex-shrink: 1;
|
|
261
|
+
overflow-x: hidden;
|
|
262
|
+
overflow-y: auto;
|
|
263
|
+
width: 100%;
|
|
264
|
+
display: block;
|
|
265
|
+
margin-left: 8px;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.top {
|
|
269
|
+
width: 100%;
|
|
270
|
+
flex-grow: 0;
|
|
271
|
+
flex-shrink: 0;
|
|
272
|
+
height: 30px;
|
|
273
|
+
display: flex;
|
|
274
|
+
align-self: flex-end;
|
|
275
|
+
align-items: center;
|
|
276
|
+
transition: all 0.2s ease-in;
|
|
277
|
+
}
|
|
278
|
+
.top button {
|
|
279
|
+
background: transparent;
|
|
280
|
+
border: 0;
|
|
281
|
+
cursor: pointer;
|
|
282
|
+
font-size: 1.25rem;
|
|
283
|
+
line-height: 1.75rem;
|
|
284
|
+
padding: 4px;
|
|
285
|
+
}
|