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,48 @@
|
|
|
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 { createContext, FC, ReactNode, useContext } from "react";
|
|
18
|
+
import { useLiveAPI, UseLiveAPIResults } from "../hooks/use-live-api";
|
|
19
|
+
|
|
20
|
+
const LiveAPIContext = createContext<UseLiveAPIResults | undefined>(undefined);
|
|
21
|
+
|
|
22
|
+
export type LiveAPIProviderProps = {
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
url?: string;
|
|
25
|
+
userId?: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const LiveAPIProvider: FC<LiveAPIProviderProps> = ({
|
|
29
|
+
url,
|
|
30
|
+
userId,
|
|
31
|
+
children,
|
|
32
|
+
}) => {
|
|
33
|
+
const liveAPI = useLiveAPI({ url, userId });
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<LiveAPIContext.Provider value={liveAPI}>
|
|
37
|
+
{children}
|
|
38
|
+
</LiveAPIContext.Provider>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const useLiveAPIContext = () => {
|
|
43
|
+
const context = useContext(LiveAPIContext);
|
|
44
|
+
if (!context) {
|
|
45
|
+
throw new Error("useLiveAPIContext must be used within a LiveAPIProvider");
|
|
46
|
+
}
|
|
47
|
+
return context;
|
|
48
|
+
};
|
|
@@ -0,0 +1,115 @@
|
|
|
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 {
|
|
18
|
+
useCallback,
|
|
19
|
+
useEffect,
|
|
20
|
+
useMemo,
|
|
21
|
+
useRef,
|
|
22
|
+
useState,
|
|
23
|
+
Dispatch,
|
|
24
|
+
SetStateAction,
|
|
25
|
+
} from "react";
|
|
26
|
+
import { MultimodalLiveClient } from "../utils/multimodal-live-client";
|
|
27
|
+
import { AudioStreamer } from "../utils/audio-streamer";
|
|
28
|
+
import { audioContext } from "../utils/utils";
|
|
29
|
+
import VolMeterWorket from "../utils/worklets/vol-meter";
|
|
30
|
+
|
|
31
|
+
export type UseLiveAPIResults = {
|
|
32
|
+
client: MultimodalLiveClient;
|
|
33
|
+
connected: boolean;
|
|
34
|
+
connect: () => Promise<void>;
|
|
35
|
+
disconnect: () => Promise<void>;
|
|
36
|
+
volume: number;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type UseLiveAPIProps = {
|
|
40
|
+
url?: string;
|
|
41
|
+
userId?: string;
|
|
42
|
+
onRunIdChange?: Dispatch<SetStateAction<string>>;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export function useLiveAPI({
|
|
46
|
+
url,
|
|
47
|
+
userId,
|
|
48
|
+
}: UseLiveAPIProps): UseLiveAPIResults {
|
|
49
|
+
const client = useMemo(
|
|
50
|
+
() => new MultimodalLiveClient({ url, userId }),
|
|
51
|
+
[url, userId],
|
|
52
|
+
);
|
|
53
|
+
const audioStreamerRef = useRef<AudioStreamer | null>(null);
|
|
54
|
+
|
|
55
|
+
const [connected, setConnected] = useState(false);
|
|
56
|
+
const [volume, setVolume] = useState(0);
|
|
57
|
+
|
|
58
|
+
// register audio for streaming server -> speakers
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
if (!audioStreamerRef.current) {
|
|
61
|
+
audioContext({ id: "audio-out" }).then((audioCtx: AudioContext) => {
|
|
62
|
+
audioStreamerRef.current = new AudioStreamer(audioCtx);
|
|
63
|
+
audioStreamerRef.current
|
|
64
|
+
.addWorklet<any>("vumeter-out", VolMeterWorket, (ev: any) => {
|
|
65
|
+
setVolume(ev.data.volume);
|
|
66
|
+
})
|
|
67
|
+
.then(() => {
|
|
68
|
+
// Successfully added worklet
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}, [audioStreamerRef]);
|
|
73
|
+
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
const onClose = () => {
|
|
76
|
+
setConnected(false);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const stopAudioStreamer = () => audioStreamerRef.current?.stop();
|
|
80
|
+
|
|
81
|
+
const onAudio = (data: ArrayBuffer) =>
|
|
82
|
+
audioStreamerRef.current?.addPCM16(new Uint8Array(data));
|
|
83
|
+
|
|
84
|
+
client
|
|
85
|
+
.on("close", onClose)
|
|
86
|
+
.on("interrupted", stopAudioStreamer)
|
|
87
|
+
.on("audio", onAudio);
|
|
88
|
+
|
|
89
|
+
return () => {
|
|
90
|
+
client
|
|
91
|
+
.off("close", onClose)
|
|
92
|
+
.off("interrupted", stopAudioStreamer)
|
|
93
|
+
.off("audio", onAudio);
|
|
94
|
+
};
|
|
95
|
+
}, [client]);
|
|
96
|
+
|
|
97
|
+
const connect = useCallback(async () => {
|
|
98
|
+
client.disconnect();
|
|
99
|
+
await client.connect();
|
|
100
|
+
setConnected(true);
|
|
101
|
+
}, [client, setConnected]);
|
|
102
|
+
|
|
103
|
+
const disconnect = useCallback(async () => {
|
|
104
|
+
client.disconnect();
|
|
105
|
+
setConnected(false);
|
|
106
|
+
}, [setConnected, client]);
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
client,
|
|
110
|
+
connected,
|
|
111
|
+
connect,
|
|
112
|
+
disconnect,
|
|
113
|
+
volume,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
export type UseMediaStreamResult = {
|
|
18
|
+
type: "webcam" | "screen";
|
|
19
|
+
start: () => Promise<MediaStream>;
|
|
20
|
+
stop: () => void;
|
|
21
|
+
isStreaming: boolean;
|
|
22
|
+
stream: MediaStream | null;
|
|
23
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
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 { useState, useEffect } from "react";
|
|
18
|
+
import { UseMediaStreamResult } from "./use-media-stream-mux";
|
|
19
|
+
|
|
20
|
+
export function useScreenCapture(): UseMediaStreamResult {
|
|
21
|
+
const [stream, setStream] = useState<MediaStream | null>(null);
|
|
22
|
+
const [isStreaming, setIsStreaming] = useState(false);
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
const handleStreamEnded = () => {
|
|
26
|
+
setIsStreaming(false);
|
|
27
|
+
setStream(null);
|
|
28
|
+
};
|
|
29
|
+
if (stream) {
|
|
30
|
+
stream
|
|
31
|
+
.getTracks()
|
|
32
|
+
.forEach((track) => track.addEventListener("ended", handleStreamEnded));
|
|
33
|
+
return () => {
|
|
34
|
+
stream
|
|
35
|
+
.getTracks()
|
|
36
|
+
.forEach((track) =>
|
|
37
|
+
track.removeEventListener("ended", handleStreamEnded),
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}, [stream]);
|
|
42
|
+
|
|
43
|
+
const start = async () => {
|
|
44
|
+
// const controller = new CaptureController();
|
|
45
|
+
// controller.setFocusBehavior("no-focus-change");
|
|
46
|
+
const mediaStream = await navigator.mediaDevices.getDisplayMedia({
|
|
47
|
+
video: true,
|
|
48
|
+
// controller
|
|
49
|
+
});
|
|
50
|
+
setStream(mediaStream);
|
|
51
|
+
setIsStreaming(true);
|
|
52
|
+
return mediaStream;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const stop = () => {
|
|
56
|
+
if (stream) {
|
|
57
|
+
stream.getTracks().forEach((track) => track.stop());
|
|
58
|
+
setStream(null);
|
|
59
|
+
setIsStreaming(false);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const result: UseMediaStreamResult = {
|
|
64
|
+
type: "screen",
|
|
65
|
+
start,
|
|
66
|
+
stop,
|
|
67
|
+
isStreaming,
|
|
68
|
+
stream,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
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 { useState, useEffect } from "react";
|
|
18
|
+
import { UseMediaStreamResult } from "./use-media-stream-mux";
|
|
19
|
+
|
|
20
|
+
export function useWebcam(): UseMediaStreamResult {
|
|
21
|
+
const [stream, setStream] = useState<MediaStream | null>(null);
|
|
22
|
+
const [isStreaming, setIsStreaming] = useState(false);
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
const handleStreamEnded = () => {
|
|
26
|
+
setIsStreaming(false);
|
|
27
|
+
setStream(null);
|
|
28
|
+
};
|
|
29
|
+
if (stream) {
|
|
30
|
+
stream
|
|
31
|
+
.getTracks()
|
|
32
|
+
.forEach((track) => track.addEventListener("ended", handleStreamEnded));
|
|
33
|
+
return () => {
|
|
34
|
+
stream
|
|
35
|
+
.getTracks()
|
|
36
|
+
.forEach((track) =>
|
|
37
|
+
track.removeEventListener("ended", handleStreamEnded),
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}, [stream]);
|
|
42
|
+
|
|
43
|
+
const start = async () => {
|
|
44
|
+
const mediaStream = await navigator.mediaDevices.getUserMedia({
|
|
45
|
+
video: true,
|
|
46
|
+
});
|
|
47
|
+
setStream(mediaStream);
|
|
48
|
+
setIsStreaming(true);
|
|
49
|
+
return mediaStream;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const stop = () => {
|
|
53
|
+
if (stream) {
|
|
54
|
+
stream.getTracks().forEach((track) => track.stop());
|
|
55
|
+
setStream(null);
|
|
56
|
+
setIsStreaming(false);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const result: UseMediaStreamResult = {
|
|
61
|
+
type: "webcam",
|
|
62
|
+
start,
|
|
63
|
+
stop,
|
|
64
|
+
isStreaming,
|
|
65
|
+
stream,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
body {
|
|
18
|
+
margin: 0;
|
|
19
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
|
|
20
|
+
Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
|
21
|
+
-webkit-font-smoothing: antialiased;
|
|
22
|
+
-moz-osx-font-smoothing: grayscale;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
code {
|
|
26
|
+
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
|
27
|
+
monospace;
|
|
28
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
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 ReactDOM from 'react-dom/client';
|
|
19
|
+
import './index.css';
|
|
20
|
+
import App from './App';
|
|
21
|
+
import reportWebVitals from './reportWebVitals';
|
|
22
|
+
|
|
23
|
+
const root = ReactDOM.createRoot(
|
|
24
|
+
document.getElementById('root') as HTMLElement
|
|
25
|
+
);
|
|
26
|
+
root.render(
|
|
27
|
+
<React.StrictMode>
|
|
28
|
+
<App />
|
|
29
|
+
</React.StrictMode>
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
// If you want to start measuring performance in your app, pass a function
|
|
33
|
+
// to log results (for example: reportWebVitals(console.log))
|
|
34
|
+
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
|
35
|
+
reportWebVitals();
|
|
@@ -0,0 +1,242 @@
|
|
|
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 type {
|
|
18
|
+
Content,
|
|
19
|
+
FunctionCall,
|
|
20
|
+
GenerationConfig,
|
|
21
|
+
GenerativeContentBlob,
|
|
22
|
+
Part,
|
|
23
|
+
Tool,
|
|
24
|
+
} from "@google/generative-ai";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* this module contains type-definitions and Type-Guards
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
// Type-definitions
|
|
31
|
+
|
|
32
|
+
/* outgoing types */
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* the config to initiate the session
|
|
36
|
+
*/
|
|
37
|
+
export type LiveConfig = {
|
|
38
|
+
model: string;
|
|
39
|
+
systemInstruction?: { parts: Part[] };
|
|
40
|
+
generationConfig?: Partial<LiveGenerationConfig>;
|
|
41
|
+
tools?: Array<Tool | { googleSearch: {} } | { codeExecution: {} }>;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type LiveGenerationConfig = GenerationConfig & {
|
|
45
|
+
responseModalities: "text" | "audio" | "image";
|
|
46
|
+
speechConfig?: {
|
|
47
|
+
voiceConfig?: {
|
|
48
|
+
prebuiltVoiceConfig?: {
|
|
49
|
+
voiceName: "Puck" | "Charon" | "Kore" | "Fenrir" | "Aoede" | string;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export type LiveOutgoingMessage =
|
|
56
|
+
| SetupMessage
|
|
57
|
+
| ClientContentMessage
|
|
58
|
+
| RealtimeInputMessage
|
|
59
|
+
| ToolResponseMessage;
|
|
60
|
+
|
|
61
|
+
export type SetupMessage = {
|
|
62
|
+
setup: LiveConfig;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export type ClientContentMessage = {
|
|
66
|
+
clientContent: {
|
|
67
|
+
turns: Content[];
|
|
68
|
+
turnComplete: boolean;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export type RealtimeInputMessage = {
|
|
73
|
+
realtimeInput: {
|
|
74
|
+
mediaChunks: GenerativeContentBlob[];
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export type ToolResponseMessage = {
|
|
79
|
+
toolResponse: {
|
|
80
|
+
functionResponses: LiveFunctionResponse[];
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export type ToolResponse = ToolResponseMessage["toolResponse"];
|
|
85
|
+
|
|
86
|
+
export type LiveFunctionResponse = {
|
|
87
|
+
response: object;
|
|
88
|
+
id: string;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/** Incoming types */
|
|
92
|
+
|
|
93
|
+
export type LiveIncomingMessage =
|
|
94
|
+
| ToolCallMessage
|
|
95
|
+
| ToolCallCancellationMessage
|
|
96
|
+
| SetupCompleteMessage
|
|
97
|
+
| ServerContentMessage;
|
|
98
|
+
|
|
99
|
+
export type SetupCompleteMessage = { setupComplete: {} };
|
|
100
|
+
|
|
101
|
+
export type ServerContentMessage = {
|
|
102
|
+
serverContent: ServerContent;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export type ServerContent = ModelTurn | TurnComplete | Interrupted;
|
|
106
|
+
|
|
107
|
+
export type ModelTurn = {
|
|
108
|
+
modelTurn: {
|
|
109
|
+
parts: Part[];
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export type TurnComplete = { turnComplete: boolean };
|
|
114
|
+
|
|
115
|
+
export type Interrupted = { interrupted: true };
|
|
116
|
+
|
|
117
|
+
export type ToolCallCancellationMessage = {
|
|
118
|
+
toolCallCancellation: {
|
|
119
|
+
ids: string[];
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export type ToolCallCancellation =
|
|
124
|
+
ToolCallCancellationMessage["toolCallCancellation"];
|
|
125
|
+
|
|
126
|
+
export type ToolCallMessage = {
|
|
127
|
+
toolCall: ToolCall;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export type LiveFunctionCall = FunctionCall & {
|
|
131
|
+
id: string;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* A `toolCall` message
|
|
136
|
+
*/
|
|
137
|
+
export type ToolCall = {
|
|
138
|
+
functionCalls: LiveFunctionCall[];
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/** log types */
|
|
142
|
+
export type StreamingLog = {
|
|
143
|
+
date: Date;
|
|
144
|
+
type: string;
|
|
145
|
+
count?: number;
|
|
146
|
+
message: string | LiveOutgoingMessage | LiveIncomingMessage;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
// Type-Guards
|
|
150
|
+
|
|
151
|
+
const prop = (a: any, prop: string, kind: string = "object") =>
|
|
152
|
+
typeof a === "object" && typeof a[prop] === "object";
|
|
153
|
+
|
|
154
|
+
// outgoing messages
|
|
155
|
+
export const isSetupMessage = (a: unknown): a is SetupMessage =>
|
|
156
|
+
prop(a, "setup");
|
|
157
|
+
|
|
158
|
+
export const isClientContentMessage = (a: unknown): a is ClientContentMessage =>
|
|
159
|
+
prop(a, "clientContent");
|
|
160
|
+
|
|
161
|
+
export const isRealtimeInputMessage = (a: unknown): a is RealtimeInputMessage =>
|
|
162
|
+
prop(a, "realtimeInput");
|
|
163
|
+
|
|
164
|
+
export const isToolResponseMessage = (a: unknown): a is ToolResponseMessage =>
|
|
165
|
+
prop(a, "toolResponse");
|
|
166
|
+
|
|
167
|
+
// incoming messages
|
|
168
|
+
export const isSetupCompleteMessage = (a: unknown): a is SetupCompleteMessage =>
|
|
169
|
+
prop(a, "setupComplete");
|
|
170
|
+
|
|
171
|
+
export const isServerContenteMessage = (a: any): a is ServerContentMessage =>
|
|
172
|
+
prop(a, "serverContent");
|
|
173
|
+
|
|
174
|
+
export const isToolCallMessage = (a: any): a is ToolCallMessage =>
|
|
175
|
+
prop(a, "toolCall");
|
|
176
|
+
|
|
177
|
+
export const isToolCallCancellationMessage = (
|
|
178
|
+
a: unknown,
|
|
179
|
+
): a is ToolCallCancellationMessage =>
|
|
180
|
+
prop(a, "toolCallCancellation") &&
|
|
181
|
+
isToolCallCancellation((a as any).toolCallCancellation);
|
|
182
|
+
|
|
183
|
+
export const isModelTurn = (a: any): a is ModelTurn =>
|
|
184
|
+
typeof (a as ModelTurn).modelTurn === "object";
|
|
185
|
+
|
|
186
|
+
export const isTurnComplete = (a: any): a is TurnComplete =>
|
|
187
|
+
typeof (a as TurnComplete).turnComplete === "boolean";
|
|
188
|
+
|
|
189
|
+
export const isInterrupted = (a: any): a is Interrupted =>
|
|
190
|
+
(a as Interrupted).interrupted;
|
|
191
|
+
|
|
192
|
+
export function isToolCall(value: unknown): value is ToolCall {
|
|
193
|
+
if (!value || typeof value !== "object") return false;
|
|
194
|
+
|
|
195
|
+
const candidate = value as Record<string, unknown>;
|
|
196
|
+
|
|
197
|
+
return (
|
|
198
|
+
Array.isArray(candidate.functionCalls) &&
|
|
199
|
+
candidate.functionCalls.every((call) => isLiveFunctionCall(call))
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export function isToolResponse(value: unknown): value is ToolResponse {
|
|
204
|
+
if (!value || typeof value !== "object") return false;
|
|
205
|
+
|
|
206
|
+
const candidate = value as Record<string, unknown>;
|
|
207
|
+
|
|
208
|
+
return (
|
|
209
|
+
Array.isArray(candidate.functionResponses) &&
|
|
210
|
+
candidate.functionResponses.every((resp) => isLiveFunctionResponse(resp))
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function isLiveFunctionCall(value: unknown): value is LiveFunctionCall {
|
|
215
|
+
if (!value || typeof value !== "object") return false;
|
|
216
|
+
|
|
217
|
+
const candidate = value as Record<string, unknown>;
|
|
218
|
+
|
|
219
|
+
return (
|
|
220
|
+
typeof candidate.name === "string" &&
|
|
221
|
+
typeof candidate.id === "string" &&
|
|
222
|
+
typeof candidate.args === "object" &&
|
|
223
|
+
candidate.args !== null
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export function isLiveFunctionResponse(
|
|
228
|
+
value: unknown,
|
|
229
|
+
): value is LiveFunctionResponse {
|
|
230
|
+
if (!value || typeof value !== "object") return false;
|
|
231
|
+
|
|
232
|
+
const candidate = value as Record<string, unknown>;
|
|
233
|
+
|
|
234
|
+
return (
|
|
235
|
+
typeof candidate.response === "object" && typeof candidate.id === "string"
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export const isToolCallCancellation = (
|
|
240
|
+
a: unknown,
|
|
241
|
+
): a is ToolCallCancellationMessage["toolCallCancellation"] =>
|
|
242
|
+
typeof a === "object" && Array.isArray((a as any).ids);
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
/// <reference types="react-scripts" />
|
|
@@ -0,0 +1,31 @@
|
|
|
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 { ReportHandler } from "web-vitals";
|
|
18
|
+
|
|
19
|
+
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
|
|
20
|
+
if (onPerfEntry && onPerfEntry instanceof Function) {
|
|
21
|
+
import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
|
22
|
+
getCLS(onPerfEntry);
|
|
23
|
+
getFID(onPerfEntry);
|
|
24
|
+
getFCP(onPerfEntry);
|
|
25
|
+
getLCP(onPerfEntry);
|
|
26
|
+
getTTFB(onPerfEntry);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default reportWebVitals;
|