@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.d.cts
CHANGED
|
@@ -464,7 +464,8 @@ declare class OpenAIRealtime implements Session {
|
|
|
464
464
|
/**
|
|
465
465
|
* Google Gemini Realtime API session (speech-to-speech).
|
|
466
466
|
*
|
|
467
|
-
*
|
|
467
|
+
* Uses @google/genai SDK's live.connect() method.
|
|
468
|
+
* Matches Python SDK's GeminiRealtime implementation (v0.14.0).
|
|
468
469
|
*/
|
|
469
470
|
|
|
470
471
|
interface GeminiRealtimeOptions {
|
|
@@ -480,8 +481,6 @@ interface GeminiRealtimeOptions {
|
|
|
480
481
|
language?: string;
|
|
481
482
|
/** Send initial greeting. Default: true */
|
|
482
483
|
greeting?: boolean;
|
|
483
|
-
/** Generation config overrides. */
|
|
484
|
-
generationConfig?: Record<string, unknown>;
|
|
485
484
|
}
|
|
486
485
|
declare class GeminiRealtime implements Session {
|
|
487
486
|
private _apiKey;
|
|
@@ -490,8 +489,7 @@ declare class GeminiRealtime implements Session {
|
|
|
490
489
|
private _voice;
|
|
491
490
|
private _language;
|
|
492
491
|
private _greeting;
|
|
493
|
-
private
|
|
494
|
-
private _ws;
|
|
492
|
+
private _session;
|
|
495
493
|
private _call;
|
|
496
494
|
private _tools;
|
|
497
495
|
private _recorder;
|
|
@@ -506,10 +504,7 @@ declare class GeminiRealtime implements Session {
|
|
|
506
504
|
start(callSession: CallSession, tools?: ToolRegistry): Promise<void>;
|
|
507
505
|
feedAudio(audio: Buffer): void;
|
|
508
506
|
stop(): Promise<void>;
|
|
509
|
-
private
|
|
510
|
-
private _waitSetupComplete;
|
|
511
|
-
private _sendGreeting;
|
|
512
|
-
private _receiveLoop;
|
|
507
|
+
private _buildToolSchemas;
|
|
513
508
|
private _handleMessage;
|
|
514
509
|
private _handleAudioData;
|
|
515
510
|
private _flushAudioRemainder;
|
package/dist/agent/index.d.ts
CHANGED
|
@@ -464,7 +464,8 @@ declare class OpenAIRealtime implements Session {
|
|
|
464
464
|
/**
|
|
465
465
|
* Google Gemini Realtime API session (speech-to-speech).
|
|
466
466
|
*
|
|
467
|
-
*
|
|
467
|
+
* Uses @google/genai SDK's live.connect() method.
|
|
468
|
+
* Matches Python SDK's GeminiRealtime implementation (v0.14.0).
|
|
468
469
|
*/
|
|
469
470
|
|
|
470
471
|
interface GeminiRealtimeOptions {
|
|
@@ -480,8 +481,6 @@ interface GeminiRealtimeOptions {
|
|
|
480
481
|
language?: string;
|
|
481
482
|
/** Send initial greeting. Default: true */
|
|
482
483
|
greeting?: boolean;
|
|
483
|
-
/** Generation config overrides. */
|
|
484
|
-
generationConfig?: Record<string, unknown>;
|
|
485
484
|
}
|
|
486
485
|
declare class GeminiRealtime implements Session {
|
|
487
486
|
private _apiKey;
|
|
@@ -490,8 +489,7 @@ declare class GeminiRealtime implements Session {
|
|
|
490
489
|
private _voice;
|
|
491
490
|
private _language;
|
|
492
491
|
private _greeting;
|
|
493
|
-
private
|
|
494
|
-
private _ws;
|
|
492
|
+
private _session;
|
|
495
493
|
private _call;
|
|
496
494
|
private _tools;
|
|
497
495
|
private _recorder;
|
|
@@ -506,10 +504,7 @@ declare class GeminiRealtime implements Session {
|
|
|
506
504
|
start(callSession: CallSession, tools?: ToolRegistry): Promise<void>;
|
|
507
505
|
feedAudio(audio: Buffer): void;
|
|
508
506
|
stop(): Promise<void>;
|
|
509
|
-
private
|
|
510
|
-
private _waitSetupComplete;
|
|
511
|
-
private _sendGreeting;
|
|
512
|
-
private _receiveLoop;
|
|
507
|
+
private _buildToolSchemas;
|
|
513
508
|
private _handleMessage;
|
|
514
509
|
private _handleAudioData;
|
|
515
510
|
private _flushAudioRemainder;
|
package/dist/agent/index.js
CHANGED
|
@@ -1792,8 +1792,8 @@ var GeminiRealtime = class {
|
|
|
1792
1792
|
_voice;
|
|
1793
1793
|
_language;
|
|
1794
1794
|
_greeting;
|
|
1795
|
-
|
|
1796
|
-
|
|
1795
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1796
|
+
_session = null;
|
|
1797
1797
|
_call = null;
|
|
1798
1798
|
_tools = null;
|
|
1799
1799
|
_recorder = null;
|
|
@@ -1807,7 +1807,6 @@ var GeminiRealtime = class {
|
|
|
1807
1807
|
this._voice = options.voice ?? "Kore";
|
|
1808
1808
|
this._language = options.language ?? "ko";
|
|
1809
1809
|
this._greeting = options.greeting ?? true;
|
|
1810
|
-
this._generationConfig = options.generationConfig;
|
|
1811
1810
|
}
|
|
1812
1811
|
/** Inject per-call ToolRegistry. */
|
|
1813
1812
|
setToolRegistry(registry) {
|
|
@@ -1826,83 +1825,78 @@ var GeminiRealtime = class {
|
|
|
1826
1825
|
if (!this._apiKey) {
|
|
1827
1826
|
throw new Error("Google API key is required. Set GOOGLE_API_KEY or pass apiKey option.");
|
|
1828
1827
|
}
|
|
1829
|
-
const {
|
|
1830
|
-
const
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
if (this._greeting) {
|
|
1838
|
-
this._sendGreeting();
|
|
1828
|
+
const { GoogleGenAI } = await import('@google/genai/node');
|
|
1829
|
+
const client = new GoogleGenAI({ apiKey: this._apiKey });
|
|
1830
|
+
const config = {
|
|
1831
|
+
responseModalities: ["AUDIO"],
|
|
1832
|
+
speechConfig: {
|
|
1833
|
+
voiceConfig: {
|
|
1834
|
+
prebuiltVoiceConfig: {
|
|
1835
|
+
voiceName: this._voice
|
|
1839
1836
|
}
|
|
1840
|
-
this._receiveLoop();
|
|
1841
|
-
resolve();
|
|
1842
|
-
}).catch(reject);
|
|
1843
|
-
});
|
|
1844
|
-
ws.on("close", () => {
|
|
1845
|
-
this._closed = true;
|
|
1846
|
-
});
|
|
1847
|
-
ws.on("error", (err) => {
|
|
1848
|
-
if (!this._ws) {
|
|
1849
|
-
reject(err);
|
|
1850
1837
|
}
|
|
1851
|
-
|
|
1852
|
-
}
|
|
1838
|
+
},
|
|
1839
|
+
inputAudioTranscription: {},
|
|
1840
|
+
outputAudioTranscription: {}
|
|
1841
|
+
};
|
|
1842
|
+
if (this._systemPrompt) {
|
|
1843
|
+
config["systemInstruction"] = this._systemPrompt;
|
|
1844
|
+
}
|
|
1845
|
+
const toolSchemas = this._buildToolSchemas();
|
|
1846
|
+
if (toolSchemas.length > 0) {
|
|
1847
|
+
config["tools"] = [{ functionDeclarations: toolSchemas }];
|
|
1848
|
+
}
|
|
1849
|
+
this._session = await client.live.connect({
|
|
1850
|
+
model: this._model,
|
|
1851
|
+
config,
|
|
1852
|
+
callbacks: {
|
|
1853
|
+
onmessage: (msg) => this._handleMessage(msg),
|
|
1854
|
+
onerror: (err) => {
|
|
1855
|
+
console.error("[GeminiRealtime] SDK error:", err);
|
|
1856
|
+
},
|
|
1857
|
+
onclose: () => {
|
|
1858
|
+
this._closed = true;
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1853
1861
|
});
|
|
1862
|
+
if (this._greeting) {
|
|
1863
|
+
this._session.sendClientContent({
|
|
1864
|
+
turns: [
|
|
1865
|
+
{
|
|
1866
|
+
role: "user",
|
|
1867
|
+
parts: [{ text: "\uC778\uC0AC\uD574 \uC8FC\uC138\uC694." }]
|
|
1868
|
+
}
|
|
1869
|
+
],
|
|
1870
|
+
turnComplete: true
|
|
1871
|
+
});
|
|
1872
|
+
}
|
|
1854
1873
|
}
|
|
1855
1874
|
feedAudio(audio) {
|
|
1856
|
-
if (this.
|
|
1875
|
+
if (this._session && !this._closed) {
|
|
1857
1876
|
const pcm8k = ulawToPcm16(audio);
|
|
1877
|
+
if (this._recorder) {
|
|
1878
|
+
this._recorder.writeInbound(pcm8k);
|
|
1879
|
+
}
|
|
1858
1880
|
const pcm16k = resamplePcm16(pcm8k, 8e3, 16e3);
|
|
1859
|
-
this.
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
data: pcm16k.toString("base64")
|
|
1866
|
-
}
|
|
1867
|
-
]
|
|
1868
|
-
}
|
|
1869
|
-
})
|
|
1870
|
-
);
|
|
1881
|
+
this._session.sendRealtimeInput({
|
|
1882
|
+
audio: {
|
|
1883
|
+
data: Buffer.from(pcm16k).toString("base64"),
|
|
1884
|
+
mimeType: "audio/pcm;rate=16000"
|
|
1885
|
+
}
|
|
1886
|
+
});
|
|
1871
1887
|
}
|
|
1872
1888
|
}
|
|
1873
1889
|
async stop() {
|
|
1874
1890
|
this._closed = true;
|
|
1875
|
-
if (this.
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
}
|
|
1880
|
-
_sendSetup() {
|
|
1881
|
-
if (!this._ws || this._ws.readyState !== 1) return;
|
|
1882
|
-
const setupConfig = {
|
|
1883
|
-
model: `models/${this._model}`,
|
|
1884
|
-
generationConfig: {
|
|
1885
|
-
responseModalities: ["AUDIO"],
|
|
1886
|
-
speechConfig: {
|
|
1887
|
-
voiceConfig: {
|
|
1888
|
-
prebuiltVoiceConfig: {
|
|
1889
|
-
voiceName: this._voice
|
|
1890
|
-
}
|
|
1891
|
-
}
|
|
1892
|
-
},
|
|
1893
|
-
...this._generationConfig
|
|
1894
|
-
},
|
|
1895
|
-
realtimeInputConfig: {
|
|
1896
|
-
automaticActivityDetection: {
|
|
1897
|
-
disabled: false
|
|
1898
|
-
}
|
|
1891
|
+
if (this._session) {
|
|
1892
|
+
try {
|
|
1893
|
+
this._session.close();
|
|
1894
|
+
} catch {
|
|
1899
1895
|
}
|
|
1900
|
-
|
|
1901
|
-
if (this._systemPrompt) {
|
|
1902
|
-
setupConfig["systemInstruction"] = {
|
|
1903
|
-
parts: [{ text: this._systemPrompt }]
|
|
1904
|
-
};
|
|
1896
|
+
this._session = null;
|
|
1905
1897
|
}
|
|
1898
|
+
}
|
|
1899
|
+
_buildToolSchemas() {
|
|
1906
1900
|
const toolDefs = this._tools ? this._tools.toOpenAITools().map((t) => ({
|
|
1907
1901
|
name: t.function.name,
|
|
1908
1902
|
description: t.function.description,
|
|
@@ -1911,107 +1905,46 @@ var GeminiRealtime = class {
|
|
|
1911
1905
|
)
|
|
1912
1906
|
})) : [];
|
|
1913
1907
|
toolDefs.push(HANG_UP_TOOL2);
|
|
1914
|
-
|
|
1915
|
-
this._ws.send(JSON.stringify({ setup: setupConfig }));
|
|
1916
|
-
}
|
|
1917
|
-
_waitSetupComplete() {
|
|
1918
|
-
return new Promise((resolve, reject) => {
|
|
1919
|
-
if (!this._ws) {
|
|
1920
|
-
reject(new Error("WebSocket not connected"));
|
|
1921
|
-
return;
|
|
1922
|
-
}
|
|
1923
|
-
const onMessage = (data) => {
|
|
1924
|
-
try {
|
|
1925
|
-
const msg = JSON.parse(data.toString());
|
|
1926
|
-
if ("setupComplete" in msg) {
|
|
1927
|
-
this._ws?.removeListener("message", onMessage);
|
|
1928
|
-
resolve();
|
|
1929
|
-
}
|
|
1930
|
-
} catch {
|
|
1931
|
-
}
|
|
1932
|
-
};
|
|
1933
|
-
this._ws.on("message", onMessage);
|
|
1934
|
-
});
|
|
1935
|
-
}
|
|
1936
|
-
_sendGreeting() {
|
|
1937
|
-
if (!this._ws || this._ws.readyState !== 1) return;
|
|
1938
|
-
this._ws.send(
|
|
1939
|
-
JSON.stringify({
|
|
1940
|
-
clientContent: {
|
|
1941
|
-
turns: [
|
|
1942
|
-
{
|
|
1943
|
-
role: "user",
|
|
1944
|
-
parts: [{ text: "\uC778\uC0AC\uD574 \uC8FC\uC138\uC694." }]
|
|
1945
|
-
}
|
|
1946
|
-
],
|
|
1947
|
-
turnComplete: true
|
|
1948
|
-
}
|
|
1949
|
-
})
|
|
1950
|
-
);
|
|
1951
|
-
}
|
|
1952
|
-
_receiveLoop() {
|
|
1953
|
-
if (!this._ws) return;
|
|
1954
|
-
this._ws.on("message", (data) => {
|
|
1955
|
-
try {
|
|
1956
|
-
const msg = JSON.parse(data.toString());
|
|
1957
|
-
this._handleMessage(msg);
|
|
1958
|
-
} catch {
|
|
1959
|
-
}
|
|
1960
|
-
});
|
|
1908
|
+
return toolDefs;
|
|
1961
1909
|
}
|
|
1962
1910
|
_handleMessage(msg) {
|
|
1963
1911
|
if (!this._call) return;
|
|
1964
|
-
const serverContent = msg
|
|
1912
|
+
const serverContent = msg.serverContent;
|
|
1965
1913
|
if (serverContent) {
|
|
1966
|
-
const modelTurn = serverContent
|
|
1914
|
+
const modelTurn = serverContent.modelTurn;
|
|
1967
1915
|
if (modelTurn) {
|
|
1968
|
-
const parts
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
const
|
|
1972
|
-
if (
|
|
1973
|
-
|
|
1974
|
-
if (mimeType.includes("audio")) {
|
|
1975
|
-
this._handleAudioData(inlineData["data"]);
|
|
1976
|
-
}
|
|
1977
|
-
}
|
|
1978
|
-
const text = part["text"];
|
|
1979
|
-
if (text && this._call) {
|
|
1980
|
-
this._call._emit("transcript", "assistant", text);
|
|
1916
|
+
for (const part of modelTurn.parts ?? []) {
|
|
1917
|
+
const inlineData = part.inlineData;
|
|
1918
|
+
if (inlineData?.data) {
|
|
1919
|
+
const mimeType = inlineData.mimeType ?? "";
|
|
1920
|
+
if (mimeType.includes("audio")) {
|
|
1921
|
+
this._handleAudioData(inlineData.data);
|
|
1981
1922
|
}
|
|
1982
1923
|
}
|
|
1983
1924
|
}
|
|
1984
1925
|
}
|
|
1985
|
-
if (serverContent
|
|
1926
|
+
if (serverContent.turnComplete) {
|
|
1986
1927
|
this._flushAudioRemainder();
|
|
1987
1928
|
}
|
|
1988
|
-
if (serverContent
|
|
1929
|
+
if (serverContent.interrupted) {
|
|
1989
1930
|
if (this._call) {
|
|
1990
1931
|
this._call.clearAudio();
|
|
1991
1932
|
}
|
|
1992
1933
|
this._sentAudioChunks = 0;
|
|
1993
1934
|
this._audioRemainder = Buffer.alloc(0);
|
|
1994
1935
|
}
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
const text = inputTranscription["text"];
|
|
1999
|
-
if (text && this._call) {
|
|
2000
|
-
this._call._emit("transcript", "user", text);
|
|
1936
|
+
const inputText = serverContent.inputTranscription?.text;
|
|
1937
|
+
if (inputText && this._call) {
|
|
1938
|
+
this._call._emit("transcript", "user", inputText);
|
|
2001
1939
|
}
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
const text = outputTranscription["text"];
|
|
2006
|
-
if (text && this._call) {
|
|
2007
|
-
this._call._emit("transcript", "assistant", text);
|
|
1940
|
+
const outputText = serverContent.outputTranscription?.text;
|
|
1941
|
+
if (outputText && this._call) {
|
|
1942
|
+
this._call._emit("transcript", "assistant", outputText);
|
|
2008
1943
|
}
|
|
2009
1944
|
}
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
this._handleToolCall(toolCall);
|
|
1945
|
+
if (msg.toolCall) {
|
|
1946
|
+
this._handleToolCall(msg.toolCall);
|
|
2013
1947
|
}
|
|
2014
|
-
if (msg["toolCallCancellation"]) ;
|
|
2015
1948
|
}
|
|
2016
1949
|
_handleAudioData(b64Data) {
|
|
2017
1950
|
if (!this._call) return;
|
|
@@ -2042,13 +1975,13 @@ var GeminiRealtime = class {
|
|
|
2042
1975
|
}
|
|
2043
1976
|
}
|
|
2044
1977
|
async _handleToolCall(toolCall) {
|
|
2045
|
-
const functionCalls = toolCall
|
|
1978
|
+
const functionCalls = toolCall.functionCalls;
|
|
2046
1979
|
if (!functionCalls) return;
|
|
2047
1980
|
const responses = [];
|
|
2048
1981
|
for (const fc of functionCalls) {
|
|
2049
|
-
const name = fc
|
|
2050
|
-
const fcId = fc
|
|
2051
|
-
const args = fc
|
|
1982
|
+
const name = fc.name ?? "";
|
|
1983
|
+
const fcId = fc.id ?? "";
|
|
1984
|
+
const args = fc.args ?? {};
|
|
2052
1985
|
if (name === "hang_up") {
|
|
2053
1986
|
if (this._call) {
|
|
2054
1987
|
this._call.hangup();
|
|
@@ -2076,14 +2009,10 @@ var GeminiRealtime = class {
|
|
|
2076
2009
|
});
|
|
2077
2010
|
}
|
|
2078
2011
|
}
|
|
2079
|
-
if (this.
|
|
2080
|
-
this.
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
functionResponses: responses
|
|
2084
|
-
}
|
|
2085
|
-
})
|
|
2086
|
-
);
|
|
2012
|
+
if (this._session) {
|
|
2013
|
+
this._session.sendToolResponse({
|
|
2014
|
+
functionResponses: responses
|
|
2015
|
+
});
|
|
2087
2016
|
}
|
|
2088
2017
|
}
|
|
2089
2018
|
};
|