@teamlearners/clawops 0.4.0 → 0.5.1
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.
- package/dist/agent/index.cjs +88 -159
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +4 -9
- package/dist/agent/index.d.ts +4 -9
- package/dist/agent/index.js +88 -159
- package/dist/agent/index.js.map +1 -1
- package/package.json +3 -2
package/dist/agent/index.cjs
CHANGED
|
@@ -1815,8 +1815,8 @@ var GeminiRealtime = class {
|
|
|
1815
1815
|
_voice;
|
|
1816
1816
|
_language;
|
|
1817
1817
|
_greeting;
|
|
1818
|
-
|
|
1819
|
-
|
|
1818
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1819
|
+
_session = null;
|
|
1820
1820
|
_call = null;
|
|
1821
1821
|
_tools = null;
|
|
1822
1822
|
_recorder = null;
|
|
@@ -1830,7 +1830,6 @@ var GeminiRealtime = class {
|
|
|
1830
1830
|
this._voice = options.voice ?? "Kore";
|
|
1831
1831
|
this._language = options.language ?? "ko";
|
|
1832
1832
|
this._greeting = options.greeting ?? true;
|
|
1833
|
-
this._generationConfig = options.generationConfig;
|
|
1834
1833
|
}
|
|
1835
1834
|
/** Inject per-call ToolRegistry. */
|
|
1836
1835
|
setToolRegistry(registry) {
|
|
@@ -1849,83 +1848,78 @@ var GeminiRealtime = class {
|
|
|
1849
1848
|
if (!this._apiKey) {
|
|
1850
1849
|
throw new Error("Google API key is required. Set GOOGLE_API_KEY or pass apiKey option.");
|
|
1851
1850
|
}
|
|
1852
|
-
const {
|
|
1853
|
-
const
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
if (this._greeting) {
|
|
1861
|
-
this._sendGreeting();
|
|
1851
|
+
const { GoogleGenAI } = await import('@google/genai/node');
|
|
1852
|
+
const client = new GoogleGenAI({ apiKey: this._apiKey });
|
|
1853
|
+
const config = {
|
|
1854
|
+
responseModalities: ["AUDIO"],
|
|
1855
|
+
speechConfig: {
|
|
1856
|
+
voiceConfig: {
|
|
1857
|
+
prebuiltVoiceConfig: {
|
|
1858
|
+
voiceName: this._voice
|
|
1862
1859
|
}
|
|
1863
|
-
this._receiveLoop();
|
|
1864
|
-
resolve();
|
|
1865
|
-
}).catch(reject);
|
|
1866
|
-
});
|
|
1867
|
-
ws.on("close", () => {
|
|
1868
|
-
this._closed = true;
|
|
1869
|
-
});
|
|
1870
|
-
ws.on("error", (err) => {
|
|
1871
|
-
if (!this._ws) {
|
|
1872
|
-
reject(err);
|
|
1873
1860
|
}
|
|
1874
|
-
|
|
1875
|
-
}
|
|
1861
|
+
},
|
|
1862
|
+
inputAudioTranscription: {},
|
|
1863
|
+
outputAudioTranscription: {}
|
|
1864
|
+
};
|
|
1865
|
+
if (this._systemPrompt) {
|
|
1866
|
+
config["systemInstruction"] = this._systemPrompt;
|
|
1867
|
+
}
|
|
1868
|
+
const toolSchemas = this._buildToolSchemas();
|
|
1869
|
+
if (toolSchemas.length > 0) {
|
|
1870
|
+
config["tools"] = [{ functionDeclarations: toolSchemas }];
|
|
1871
|
+
}
|
|
1872
|
+
this._session = await client.live.connect({
|
|
1873
|
+
model: this._model,
|
|
1874
|
+
config,
|
|
1875
|
+
callbacks: {
|
|
1876
|
+
onmessage: (msg) => this._handleMessage(msg),
|
|
1877
|
+
onerror: (err) => {
|
|
1878
|
+
console.error("[GeminiRealtime] SDK error:", err);
|
|
1879
|
+
},
|
|
1880
|
+
onclose: () => {
|
|
1881
|
+
this._closed = true;
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1876
1884
|
});
|
|
1885
|
+
if (this._greeting) {
|
|
1886
|
+
this._session.sendClientContent({
|
|
1887
|
+
turns: [
|
|
1888
|
+
{
|
|
1889
|
+
role: "user",
|
|
1890
|
+
parts: [{ text: "\uC778\uC0AC\uD574 \uC8FC\uC138\uC694." }]
|
|
1891
|
+
}
|
|
1892
|
+
],
|
|
1893
|
+
turnComplete: true
|
|
1894
|
+
});
|
|
1895
|
+
}
|
|
1877
1896
|
}
|
|
1878
1897
|
feedAudio(audio) {
|
|
1879
|
-
if (this.
|
|
1898
|
+
if (this._session && !this._closed) {
|
|
1880
1899
|
const pcm8k = ulawToPcm16(audio);
|
|
1900
|
+
if (this._recorder) {
|
|
1901
|
+
this._recorder.writeInbound(pcm8k);
|
|
1902
|
+
}
|
|
1881
1903
|
const pcm16k = resamplePcm16(pcm8k, 8e3, 16e3);
|
|
1882
|
-
this.
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
data: pcm16k.toString("base64")
|
|
1889
|
-
}
|
|
1890
|
-
]
|
|
1891
|
-
}
|
|
1892
|
-
})
|
|
1893
|
-
);
|
|
1904
|
+
this._session.sendRealtimeInput({
|
|
1905
|
+
audio: {
|
|
1906
|
+
data: Buffer.from(pcm16k).toString("base64"),
|
|
1907
|
+
mimeType: "audio/pcm;rate=16000"
|
|
1908
|
+
}
|
|
1909
|
+
});
|
|
1894
1910
|
}
|
|
1895
1911
|
}
|
|
1896
1912
|
async stop() {
|
|
1897
1913
|
this._closed = true;
|
|
1898
|
-
if (this.
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
}
|
|
1903
|
-
_sendSetup() {
|
|
1904
|
-
if (!this._ws || this._ws.readyState !== 1) return;
|
|
1905
|
-
const setupConfig = {
|
|
1906
|
-
model: `models/${this._model}`,
|
|
1907
|
-
generationConfig: {
|
|
1908
|
-
responseModalities: ["AUDIO"],
|
|
1909
|
-
speechConfig: {
|
|
1910
|
-
voiceConfig: {
|
|
1911
|
-
prebuiltVoiceConfig: {
|
|
1912
|
-
voiceName: this._voice
|
|
1913
|
-
}
|
|
1914
|
-
}
|
|
1915
|
-
},
|
|
1916
|
-
...this._generationConfig
|
|
1917
|
-
},
|
|
1918
|
-
realtimeInputConfig: {
|
|
1919
|
-
automaticActivityDetection: {
|
|
1920
|
-
disabled: false
|
|
1921
|
-
}
|
|
1914
|
+
if (this._session) {
|
|
1915
|
+
try {
|
|
1916
|
+
this._session.close();
|
|
1917
|
+
} catch {
|
|
1922
1918
|
}
|
|
1923
|
-
|
|
1924
|
-
if (this._systemPrompt) {
|
|
1925
|
-
setupConfig["systemInstruction"] = {
|
|
1926
|
-
parts: [{ text: this._systemPrompt }]
|
|
1927
|
-
};
|
|
1919
|
+
this._session = null;
|
|
1928
1920
|
}
|
|
1921
|
+
}
|
|
1922
|
+
_buildToolSchemas() {
|
|
1929
1923
|
const toolDefs = this._tools ? this._tools.toOpenAITools().map((t) => ({
|
|
1930
1924
|
name: t.function.name,
|
|
1931
1925
|
description: t.function.description,
|
|
@@ -1934,107 +1928,46 @@ var GeminiRealtime = class {
|
|
|
1934
1928
|
)
|
|
1935
1929
|
})) : [];
|
|
1936
1930
|
toolDefs.push(HANG_UP_TOOL2);
|
|
1937
|
-
|
|
1938
|
-
this._ws.send(JSON.stringify({ setup: setupConfig }));
|
|
1939
|
-
}
|
|
1940
|
-
_waitSetupComplete() {
|
|
1941
|
-
return new Promise((resolve, reject) => {
|
|
1942
|
-
if (!this._ws) {
|
|
1943
|
-
reject(new Error("WebSocket not connected"));
|
|
1944
|
-
return;
|
|
1945
|
-
}
|
|
1946
|
-
const onMessage = (data) => {
|
|
1947
|
-
try {
|
|
1948
|
-
const msg = JSON.parse(data.toString());
|
|
1949
|
-
if ("setupComplete" in msg) {
|
|
1950
|
-
this._ws?.removeListener("message", onMessage);
|
|
1951
|
-
resolve();
|
|
1952
|
-
}
|
|
1953
|
-
} catch {
|
|
1954
|
-
}
|
|
1955
|
-
};
|
|
1956
|
-
this._ws.on("message", onMessage);
|
|
1957
|
-
});
|
|
1958
|
-
}
|
|
1959
|
-
_sendGreeting() {
|
|
1960
|
-
if (!this._ws || this._ws.readyState !== 1) return;
|
|
1961
|
-
this._ws.send(
|
|
1962
|
-
JSON.stringify({
|
|
1963
|
-
clientContent: {
|
|
1964
|
-
turns: [
|
|
1965
|
-
{
|
|
1966
|
-
role: "user",
|
|
1967
|
-
parts: [{ text: "\uC778\uC0AC\uD574 \uC8FC\uC138\uC694." }]
|
|
1968
|
-
}
|
|
1969
|
-
],
|
|
1970
|
-
turnComplete: true
|
|
1971
|
-
}
|
|
1972
|
-
})
|
|
1973
|
-
);
|
|
1974
|
-
}
|
|
1975
|
-
_receiveLoop() {
|
|
1976
|
-
if (!this._ws) return;
|
|
1977
|
-
this._ws.on("message", (data) => {
|
|
1978
|
-
try {
|
|
1979
|
-
const msg = JSON.parse(data.toString());
|
|
1980
|
-
this._handleMessage(msg);
|
|
1981
|
-
} catch {
|
|
1982
|
-
}
|
|
1983
|
-
});
|
|
1931
|
+
return toolDefs;
|
|
1984
1932
|
}
|
|
1985
1933
|
_handleMessage(msg) {
|
|
1986
1934
|
if (!this._call) return;
|
|
1987
|
-
const serverContent = msg
|
|
1935
|
+
const serverContent = msg.serverContent;
|
|
1988
1936
|
if (serverContent) {
|
|
1989
|
-
const modelTurn = serverContent
|
|
1937
|
+
const modelTurn = serverContent.modelTurn;
|
|
1990
1938
|
if (modelTurn) {
|
|
1991
|
-
const parts
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
const
|
|
1995
|
-
if (
|
|
1996
|
-
|
|
1997
|
-
if (mimeType.includes("audio")) {
|
|
1998
|
-
this._handleAudioData(inlineData["data"]);
|
|
1999
|
-
}
|
|
2000
|
-
}
|
|
2001
|
-
const text = part["text"];
|
|
2002
|
-
if (text && this._call) {
|
|
2003
|
-
this._call._emit("transcript", "assistant", text);
|
|
1939
|
+
for (const part of modelTurn.parts ?? []) {
|
|
1940
|
+
const inlineData = part.inlineData;
|
|
1941
|
+
if (inlineData?.data) {
|
|
1942
|
+
const mimeType = inlineData.mimeType ?? "";
|
|
1943
|
+
if (mimeType.includes("audio")) {
|
|
1944
|
+
this._handleAudioData(inlineData.data);
|
|
2004
1945
|
}
|
|
2005
1946
|
}
|
|
2006
1947
|
}
|
|
2007
1948
|
}
|
|
2008
|
-
if (serverContent
|
|
1949
|
+
if (serverContent.turnComplete) {
|
|
2009
1950
|
this._flushAudioRemainder();
|
|
2010
1951
|
}
|
|
2011
|
-
if (serverContent
|
|
1952
|
+
if (serverContent.interrupted) {
|
|
2012
1953
|
if (this._call) {
|
|
2013
1954
|
this._call.clearAudio();
|
|
2014
1955
|
}
|
|
2015
1956
|
this._sentAudioChunks = 0;
|
|
2016
1957
|
this._audioRemainder = Buffer.alloc(0);
|
|
2017
1958
|
}
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
const text = inputTranscription["text"];
|
|
2022
|
-
if (text && this._call) {
|
|
2023
|
-
this._call._emit("transcript", "user", text);
|
|
1959
|
+
const inputText = serverContent.inputTranscription?.text;
|
|
1960
|
+
if (inputText && this._call) {
|
|
1961
|
+
this._call._emit("transcript", "user", inputText);
|
|
2024
1962
|
}
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
const text = outputTranscription["text"];
|
|
2029
|
-
if (text && this._call) {
|
|
2030
|
-
this._call._emit("transcript", "assistant", text);
|
|
1963
|
+
const outputText = serverContent.outputTranscription?.text;
|
|
1964
|
+
if (outputText && this._call) {
|
|
1965
|
+
this._call._emit("transcript", "assistant", outputText);
|
|
2031
1966
|
}
|
|
2032
1967
|
}
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
this._handleToolCall(toolCall);
|
|
1968
|
+
if (msg.toolCall) {
|
|
1969
|
+
this._handleToolCall(msg.toolCall);
|
|
2036
1970
|
}
|
|
2037
|
-
if (msg["toolCallCancellation"]) ;
|
|
2038
1971
|
}
|
|
2039
1972
|
_handleAudioData(b64Data) {
|
|
2040
1973
|
if (!this._call) return;
|
|
@@ -2065,13 +1998,13 @@ var GeminiRealtime = class {
|
|
|
2065
1998
|
}
|
|
2066
1999
|
}
|
|
2067
2000
|
async _handleToolCall(toolCall) {
|
|
2068
|
-
const functionCalls = toolCall
|
|
2001
|
+
const functionCalls = toolCall.functionCalls;
|
|
2069
2002
|
if (!functionCalls) return;
|
|
2070
2003
|
const responses = [];
|
|
2071
2004
|
for (const fc of functionCalls) {
|
|
2072
|
-
const name = fc
|
|
2073
|
-
const fcId = fc
|
|
2074
|
-
const args = fc
|
|
2005
|
+
const name = fc.name ?? "";
|
|
2006
|
+
const fcId = fc.id ?? "";
|
|
2007
|
+
const args = fc.args ?? {};
|
|
2075
2008
|
if (name === "hang_up") {
|
|
2076
2009
|
if (this._call) {
|
|
2077
2010
|
this._call.hangup();
|
|
@@ -2099,14 +2032,10 @@ var GeminiRealtime = class {
|
|
|
2099
2032
|
});
|
|
2100
2033
|
}
|
|
2101
2034
|
}
|
|
2102
|
-
if (this.
|
|
2103
|
-
this.
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
functionResponses: responses
|
|
2107
|
-
}
|
|
2108
|
-
})
|
|
2109
|
-
);
|
|
2035
|
+
if (this._session) {
|
|
2036
|
+
this._session.sendToolResponse({
|
|
2037
|
+
functionResponses: responses
|
|
2038
|
+
});
|
|
2110
2039
|
}
|
|
2111
2040
|
}
|
|
2112
2041
|
};
|