@teamlearners/clawops 0.25.0 → 0.26.0
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/README.md +0 -13
- package/dist/agent/index.cjs +171 -83
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +29 -0
- package/dist/agent/index.d.ts +29 -0
- package/dist/agent/index.js +108 -20
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/livekit/index.cjs +8 -8
- package/dist/agent/livekit/index.js +1 -1
- package/dist/{chunk-IVJXHNUN.cjs → chunk-AF2MNFN4.cjs} +3 -3
- package/dist/{chunk-IVJXHNUN.cjs.map → chunk-AF2MNFN4.cjs.map} +1 -1
- package/dist/{chunk-THZNZBP2.js → chunk-WIA54H3X.js} +3 -3
- package/dist/{chunk-THZNZBP2.js.map → chunk-WIA54H3X.js.map} +1 -1
- package/dist/{chunk-2BAYUQ7O.js → chunk-WKGTY7QT.js} +4 -3
- package/dist/chunk-WKGTY7QT.js.map +1 -0
- package/dist/{chunk-U4UFTVLX.cjs → chunk-XAOA3XFQ.cjs} +4 -2
- package/dist/chunk-XAOA3XFQ.cjs.map +1 -0
- package/dist/index.cjs +35 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -62
- package/dist/index.d.ts +1 -62
- package/dist/index.js +2 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-2BAYUQ7O.js.map +0 -1
- package/dist/chunk-U4UFTVLX.cjs.map +0 -1
package/dist/agent/index.d.cts
CHANGED
|
@@ -242,6 +242,14 @@ declare class ClawOpsAgent {
|
|
|
242
242
|
* multiple times — only the first invocation starts the task. Failures are
|
|
243
243
|
* recorded in _prewarmFailed so the call-session path can fall back to start().
|
|
244
244
|
*/
|
|
245
|
+
/**
|
|
246
|
+
* 세션에 콜별 의존성(도구·내장도구·hold audio·recorder·logger)을 주입한다.
|
|
247
|
+
*
|
|
248
|
+
* prewarm 과 _startCallSession 양쪽에서 부른다. prewarm 은 세션이 LLM 에 보낼
|
|
249
|
+
* tool 스키마를 그 시점에 확정하므로(OpenAI session.update / Gemini live connect
|
|
250
|
+
* config), prewarm **전에** 최소 한 번은 도구가 들어가 있어야 한다.
|
|
251
|
+
*/
|
|
252
|
+
private _injectSessionDeps;
|
|
245
253
|
private _startPrewarm;
|
|
246
254
|
private _handleRinging;
|
|
247
255
|
private _handleFailed;
|
|
@@ -533,6 +541,11 @@ declare class OpenAIRealtime implements Session {
|
|
|
533
541
|
private _greeting;
|
|
534
542
|
private _log;
|
|
535
543
|
private _builtinTools;
|
|
544
|
+
/**
|
|
545
|
+
* 마지막 session.update 로 LLM 에 알린 tool 이름들. attach() 가 이 값과 현재
|
|
546
|
+
* registry 를 비교해 달라졌을 때만(=MCP 도구 등 뒤늦게 붙은 경우) 재전송한다.
|
|
547
|
+
*/
|
|
548
|
+
private _sentToolNames;
|
|
536
549
|
setLogger(logger: Logger): void;
|
|
537
550
|
setBuiltinTools(tools: Set<BuiltinTool>): void;
|
|
538
551
|
getTelemetry(): SessionTelemetry;
|
|
@@ -562,6 +575,15 @@ declare class OpenAIRealtime implements Session {
|
|
|
562
575
|
feedDtmf(digits: string): Promise<void>;
|
|
563
576
|
feedAudio(audio: Buffer, timestamp?: number): void;
|
|
564
577
|
stop(): Promise<void>;
|
|
578
|
+
/** Current tool schemas: user tools + builtin tools (flat realtime format). */
|
|
579
|
+
private _currentToolSchemas;
|
|
580
|
+
/**
|
|
581
|
+
* prewarm 이후 도구가 바뀌었으면 session.update 로 재전송한다.
|
|
582
|
+
*
|
|
583
|
+
* MCP 도구는 통화 시작 시점에 registry 에 붙으므로 prewarm 시점의 스키마에는
|
|
584
|
+
* 없다. 여기서 맞춰주지 않으면 발신 통화에서 MCP 도구를 영영 못 쓴다.
|
|
585
|
+
*/
|
|
586
|
+
private _resyncTools;
|
|
565
587
|
private _sendSessionUpdate;
|
|
566
588
|
private _handleMessage;
|
|
567
589
|
private _handleAudioDelta;
|
|
@@ -595,6 +617,13 @@ interface GeminiRealtimeOptions {
|
|
|
595
617
|
realtimeInputConfig?: Record<string, unknown>;
|
|
596
618
|
}
|
|
597
619
|
declare class GeminiRealtime implements Session {
|
|
620
|
+
/**
|
|
621
|
+
* Gemini Live 는 connect 시점의 config 로 도구가 고정되어 세션 도중 변경할 수 없다.
|
|
622
|
+
*
|
|
623
|
+
* 통화 시작 시점에야 붙는 MCP 도구는 prewarm 된 세션에 넣을 방법이 없으므로,
|
|
624
|
+
* `ClawOpsAgent` 가 MCP 서버 설정과 이 플래그를 보고 prewarm 을 건너뛴다.
|
|
625
|
+
*/
|
|
626
|
+
readonly toolsFrozenAfterPrewarm = true;
|
|
598
627
|
private _apiKey;
|
|
599
628
|
private _systemPrompt;
|
|
600
629
|
private _model;
|
package/dist/agent/index.d.ts
CHANGED
|
@@ -242,6 +242,14 @@ declare class ClawOpsAgent {
|
|
|
242
242
|
* multiple times — only the first invocation starts the task. Failures are
|
|
243
243
|
* recorded in _prewarmFailed so the call-session path can fall back to start().
|
|
244
244
|
*/
|
|
245
|
+
/**
|
|
246
|
+
* 세션에 콜별 의존성(도구·내장도구·hold audio·recorder·logger)을 주입한다.
|
|
247
|
+
*
|
|
248
|
+
* prewarm 과 _startCallSession 양쪽에서 부른다. prewarm 은 세션이 LLM 에 보낼
|
|
249
|
+
* tool 스키마를 그 시점에 확정하므로(OpenAI session.update / Gemini live connect
|
|
250
|
+
* config), prewarm **전에** 최소 한 번은 도구가 들어가 있어야 한다.
|
|
251
|
+
*/
|
|
252
|
+
private _injectSessionDeps;
|
|
245
253
|
private _startPrewarm;
|
|
246
254
|
private _handleRinging;
|
|
247
255
|
private _handleFailed;
|
|
@@ -533,6 +541,11 @@ declare class OpenAIRealtime implements Session {
|
|
|
533
541
|
private _greeting;
|
|
534
542
|
private _log;
|
|
535
543
|
private _builtinTools;
|
|
544
|
+
/**
|
|
545
|
+
* 마지막 session.update 로 LLM 에 알린 tool 이름들. attach() 가 이 값과 현재
|
|
546
|
+
* registry 를 비교해 달라졌을 때만(=MCP 도구 등 뒤늦게 붙은 경우) 재전송한다.
|
|
547
|
+
*/
|
|
548
|
+
private _sentToolNames;
|
|
536
549
|
setLogger(logger: Logger): void;
|
|
537
550
|
setBuiltinTools(tools: Set<BuiltinTool>): void;
|
|
538
551
|
getTelemetry(): SessionTelemetry;
|
|
@@ -562,6 +575,15 @@ declare class OpenAIRealtime implements Session {
|
|
|
562
575
|
feedDtmf(digits: string): Promise<void>;
|
|
563
576
|
feedAudio(audio: Buffer, timestamp?: number): void;
|
|
564
577
|
stop(): Promise<void>;
|
|
578
|
+
/** Current tool schemas: user tools + builtin tools (flat realtime format). */
|
|
579
|
+
private _currentToolSchemas;
|
|
580
|
+
/**
|
|
581
|
+
* prewarm 이후 도구가 바뀌었으면 session.update 로 재전송한다.
|
|
582
|
+
*
|
|
583
|
+
* MCP 도구는 통화 시작 시점에 registry 에 붙으므로 prewarm 시점의 스키마에는
|
|
584
|
+
* 없다. 여기서 맞춰주지 않으면 발신 통화에서 MCP 도구를 영영 못 쓴다.
|
|
585
|
+
*/
|
|
586
|
+
private _resyncTools;
|
|
565
587
|
private _sendSessionUpdate;
|
|
566
588
|
private _handleMessage;
|
|
567
589
|
private _handleAudioDelta;
|
|
@@ -595,6 +617,13 @@ interface GeminiRealtimeOptions {
|
|
|
595
617
|
realtimeInputConfig?: Record<string, unknown>;
|
|
596
618
|
}
|
|
597
619
|
declare class GeminiRealtime implements Session {
|
|
620
|
+
/**
|
|
621
|
+
* Gemini Live 는 connect 시점의 config 로 도구가 고정되어 세션 도중 변경할 수 없다.
|
|
622
|
+
*
|
|
623
|
+
* 통화 시작 시점에야 붙는 MCP 도구는 prewarm 된 세션에 넣을 방법이 없으므로,
|
|
624
|
+
* `ClawOpsAgent` 가 MCP 서버 설정과 이 플래그를 보고 prewarm 을 건너뛴다.
|
|
625
|
+
*/
|
|
626
|
+
readonly toolsFrozenAfterPrewarm = true;
|
|
598
627
|
private _apiKey;
|
|
599
628
|
private _systemPrompt;
|
|
600
629
|
private _model;
|
package/dist/agent/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { DEFAULT_BASE_URL, AgentError, AgentConnectionError, VERSION } from '../chunk-
|
|
2
|
-
import { NOOP_LOGGER, resolveBuiltinTools, createAgentLogger, createPipelineLogger, BufferingCall, attachBuffered, ulawToPcm16, resamplePcm16, getBuiltinToolSchemas, BUILTIN_TOOL_NAMES, executeBuiltinTool, pcm16ToUlaw, applyUlawGain } from '../chunk-
|
|
3
|
-
export { BUILTIN_TOOL_NAMES, BuiltinTool, DECODE_TABLE, createAgentLogger, createPipelineLogger, executeBuiltinTool, getBuiltinToolSchemas, isBuiltinTool, pcm16ToUlaw, resamplePcm16, ulawToPcm16 } from '../chunk-
|
|
1
|
+
import { DEFAULT_BASE_URL, AgentError, AgentConnectionError, VERSION } from '../chunk-WIA54H3X.js';
|
|
2
|
+
import { NOOP_LOGGER, resolveBuiltinTools, createAgentLogger, createPipelineLogger, BufferingCall, attachBuffered, ulawToPcm16, resamplePcm16, getBuiltinToolSchemas, BUILTIN_TOOL_NAMES, executeBuiltinTool, CALL_NOT_READY_RESULT, pcm16ToUlaw, applyUlawGain } from '../chunk-WKGTY7QT.js';
|
|
3
|
+
export { BUILTIN_TOOL_NAMES, BuiltinTool, DECODE_TABLE, createAgentLogger, createPipelineLogger, executeBuiltinTool, getBuiltinToolSchemas, isBuiltinTool, pcm16ToUlaw, resamplePcm16, ulawToPcm16 } from '../chunk-WKGTY7QT.js';
|
|
4
4
|
import * as fs from 'fs';
|
|
5
5
|
import * as path from 'path';
|
|
6
6
|
import os from 'os';
|
|
@@ -1697,10 +1697,43 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1697
1697
|
* multiple times — only the first invocation starts the task. Failures are
|
|
1698
1698
|
* recorded in _prewarmFailed so the call-session path can fall back to start().
|
|
1699
1699
|
*/
|
|
1700
|
+
/**
|
|
1701
|
+
* 세션에 콜별 의존성(도구·내장도구·hold audio·recorder·logger)을 주입한다.
|
|
1702
|
+
*
|
|
1703
|
+
* prewarm 과 _startCallSession 양쪽에서 부른다. prewarm 은 세션이 LLM 에 보낼
|
|
1704
|
+
* tool 스키마를 그 시점에 확정하므로(OpenAI session.update / Gemini live connect
|
|
1705
|
+
* config), prewarm **전에** 최소 한 번은 도구가 들어가 있어야 한다.
|
|
1706
|
+
*/
|
|
1707
|
+
_injectSessionDeps(tools, recorder) {
|
|
1708
|
+
const sessionHandler = this._session;
|
|
1709
|
+
if ("setToolRegistry" in sessionHandler && typeof sessionHandler.setToolRegistry === "function") {
|
|
1710
|
+
sessionHandler.setToolRegistry(tools);
|
|
1711
|
+
}
|
|
1712
|
+
if (recorder && "setRecorder" in sessionHandler && typeof sessionHandler.setRecorder === "function") {
|
|
1713
|
+
sessionHandler.setRecorder(recorder);
|
|
1714
|
+
}
|
|
1715
|
+
if ("setBuiltinTools" in sessionHandler && typeof sessionHandler.setBuiltinTools === "function") {
|
|
1716
|
+
sessionHandler.setBuiltinTools(this._builtinTools);
|
|
1717
|
+
}
|
|
1718
|
+
if ("setLogger" in sessionHandler && typeof sessionHandler.setLogger === "function") {
|
|
1719
|
+
sessionHandler.setLogger(this._isPipelineSession ? this._pipelineLog : this._log);
|
|
1720
|
+
}
|
|
1721
|
+
if (this._holdAudioChunks && "setHoldAudio" in sessionHandler && typeof sessionHandler.setHoldAudio === "function") {
|
|
1722
|
+
sessionHandler.setHoldAudio(this._holdAudioChunks);
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1700
1725
|
_startPrewarm(callId) {
|
|
1701
1726
|
if (this._prewarmTasks.has(callId)) return;
|
|
1702
1727
|
const sessionHandler = this._session;
|
|
1703
1728
|
if (typeof sessionHandler.prewarm !== "function") return;
|
|
1729
|
+
if (this._mcpServers.length > 0 && sessionHandler.toolsFrozenAfterPrewarm) {
|
|
1730
|
+
this._log.info(
|
|
1731
|
+
{ callId },
|
|
1732
|
+
"Skipping prewarm \u2014 \uC138\uC158\uC774 \uC5F0\uACB0 \uD6C4 \uB3C4\uAD6C \uBCC0\uACBD\uC744 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC544 MCP \uB3C4\uAD6C\uAC00 \uB204\uB77D\uB41C\uB2E4."
|
|
1733
|
+
);
|
|
1734
|
+
return;
|
|
1735
|
+
}
|
|
1736
|
+
this._injectSessionDeps(this._tools.fork());
|
|
1704
1737
|
const PREWARM_TIMEOUT_MS = 1e4;
|
|
1705
1738
|
const t0 = Date.now();
|
|
1706
1739
|
this._log.info(`[PREWARM-T] start call_id=${callId} t=${(t0 / 1e3).toFixed(3)}`);
|
|
@@ -1866,21 +1899,7 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1866
1899
|
session._waitForMark = (name, timeoutMs) => mediaWs.waitForMark(name, timeoutMs);
|
|
1867
1900
|
session._flushTransport = () => mediaWs.flush();
|
|
1868
1901
|
const sessionHandler = this._session;
|
|
1869
|
-
|
|
1870
|
-
sessionHandler.setToolRegistry(sessionTools);
|
|
1871
|
-
}
|
|
1872
|
-
if (recorder && "setRecorder" in sessionHandler && typeof sessionHandler.setRecorder === "function") {
|
|
1873
|
-
sessionHandler.setRecorder(recorder);
|
|
1874
|
-
}
|
|
1875
|
-
if ("setBuiltinTools" in sessionHandler && typeof sessionHandler.setBuiltinTools === "function") {
|
|
1876
|
-
sessionHandler.setBuiltinTools(this._builtinTools);
|
|
1877
|
-
}
|
|
1878
|
-
if ("setLogger" in sessionHandler && typeof sessionHandler.setLogger === "function") {
|
|
1879
|
-
sessionHandler.setLogger(this._isPipelineSession ? this._pipelineLog : this._log);
|
|
1880
|
-
}
|
|
1881
|
-
if (this._holdAudioChunks && "setHoldAudio" in sessionHandler && typeof sessionHandler.setHoldAudio === "function") {
|
|
1882
|
-
sessionHandler.setHoldAudio(this._holdAudioChunks);
|
|
1883
|
-
}
|
|
1902
|
+
this._injectSessionDeps(sessionTools, recorder);
|
|
1884
1903
|
this._callSessions.set(session.callId, sessionHandler);
|
|
1885
1904
|
mediaWs.onAudio((ulawAudio, timestamp) => {
|
|
1886
1905
|
latestMediaTs = timestamp;
|
|
@@ -2208,6 +2227,17 @@ var PipelineSession = class {
|
|
|
2208
2227
|
return;
|
|
2209
2228
|
}
|
|
2210
2229
|
}
|
|
2230
|
+
if (BUILTIN_TOOL_NAMES.has(name) && this._callSession instanceof BufferingCall) {
|
|
2231
|
+
this._log.warn("Builtin tool %s called before answer \u2014 deferring", name);
|
|
2232
|
+
this._conversation.push({
|
|
2233
|
+
role: "tool",
|
|
2234
|
+
content: CALL_NOT_READY_RESULT,
|
|
2235
|
+
tool_call_id: id,
|
|
2236
|
+
name
|
|
2237
|
+
});
|
|
2238
|
+
await this._respond();
|
|
2239
|
+
return;
|
|
2240
|
+
}
|
|
2211
2241
|
if (!this._tools) return;
|
|
2212
2242
|
this._callSession?.recordToolCall();
|
|
2213
2243
|
const player = this._holdAudioChunks && this._callSession && !(this._callSession instanceof BufferingCall) ? new HoldAudioPlayer(this._callSession, this._holdAudioChunks) : null;
|
|
@@ -2291,6 +2321,11 @@ var OpenAIRealtime = class {
|
|
|
2291
2321
|
_greeting;
|
|
2292
2322
|
_log = NOOP_LOGGER;
|
|
2293
2323
|
_builtinTools = null;
|
|
2324
|
+
/**
|
|
2325
|
+
* 마지막 session.update 로 LLM 에 알린 tool 이름들. attach() 가 이 값과 현재
|
|
2326
|
+
* registry 를 비교해 달라졌을 때만(=MCP 도구 등 뒤늦게 붙은 경우) 재전송한다.
|
|
2327
|
+
*/
|
|
2328
|
+
_sentToolNames = null;
|
|
2294
2329
|
setLogger(logger) {
|
|
2295
2330
|
this._log = logger;
|
|
2296
2331
|
}
|
|
@@ -2400,6 +2435,7 @@ var OpenAIRealtime = class {
|
|
|
2400
2435
|
}
|
|
2401
2436
|
/** Attach a real CallSession to the prewarmed session and flush buffered audio. */
|
|
2402
2437
|
async attach(callSession) {
|
|
2438
|
+
this._resyncTools();
|
|
2403
2439
|
const prev = this._call;
|
|
2404
2440
|
this._call = callSession;
|
|
2405
2441
|
attachBuffered(prev, callSession);
|
|
@@ -2460,10 +2496,36 @@ var OpenAIRealtime = class {
|
|
|
2460
2496
|
});
|
|
2461
2497
|
}
|
|
2462
2498
|
}
|
|
2463
|
-
|
|
2464
|
-
|
|
2499
|
+
/** Current tool schemas: user tools + builtin tools (flat realtime format). */
|
|
2500
|
+
_currentToolSchemas() {
|
|
2465
2501
|
const toolSchemas = this._tools ? this._tools.toOpenAITools().map((t) => ({ type: "function", ...t.function })) : [];
|
|
2466
2502
|
toolSchemas.push(...getBuiltinToolSchemas(this._builtinTools, "realtime"));
|
|
2503
|
+
return toolSchemas;
|
|
2504
|
+
}
|
|
2505
|
+
/**
|
|
2506
|
+
* prewarm 이후 도구가 바뀌었으면 session.update 로 재전송한다.
|
|
2507
|
+
*
|
|
2508
|
+
* MCP 도구는 통화 시작 시점에 registry 에 붙으므로 prewarm 시점의 스키마에는
|
|
2509
|
+
* 없다. 여기서 맞춰주지 않으면 발신 통화에서 MCP 도구를 영영 못 쓴다.
|
|
2510
|
+
*/
|
|
2511
|
+
_resyncTools() {
|
|
2512
|
+
if (!this._ws || this._ws.readyState !== 1) return;
|
|
2513
|
+
const toolSchemas = this._currentToolSchemas();
|
|
2514
|
+
const names = toolSchemas.map((t) => String(t["name"] ?? ""));
|
|
2515
|
+
if (this._sentToolNames && names.length === this._sentToolNames.length && names.every((n, i) => n === this._sentToolNames[i])) {
|
|
2516
|
+
return;
|
|
2517
|
+
}
|
|
2518
|
+
this._send({
|
|
2519
|
+
type: "session.update",
|
|
2520
|
+
session: { type: "realtime", tools: toolSchemas }
|
|
2521
|
+
});
|
|
2522
|
+
this._sentToolNames = names;
|
|
2523
|
+
this._log.info("Tool schema resynced after prewarm: %s", names.join(", "));
|
|
2524
|
+
}
|
|
2525
|
+
_sendSessionUpdate() {
|
|
2526
|
+
if (!this._ws || this._ws.readyState !== 1) return;
|
|
2527
|
+
const toolSchemas = this._currentToolSchemas();
|
|
2528
|
+
this._sentToolNames = toolSchemas.map((t) => String(t["name"] ?? ""));
|
|
2467
2529
|
this._send({
|
|
2468
2530
|
type: "session.update",
|
|
2469
2531
|
session: {
|
|
@@ -2627,6 +2689,20 @@ var OpenAIRealtime = class {
|
|
|
2627
2689
|
return;
|
|
2628
2690
|
}
|
|
2629
2691
|
}
|
|
2692
|
+
if (BUILTIN_TOOL_NAMES.has(funcName) && this._call instanceof BufferingCall) {
|
|
2693
|
+
this._log.warn("Builtin tool %s called before answer \u2014 deferring", funcName);
|
|
2694
|
+
await this._waitForResponseDone();
|
|
2695
|
+
this._send({
|
|
2696
|
+
type: "conversation.item.create",
|
|
2697
|
+
item: {
|
|
2698
|
+
type: "function_call_output",
|
|
2699
|
+
call_id: callId,
|
|
2700
|
+
output: CALL_NOT_READY_RESULT
|
|
2701
|
+
}
|
|
2702
|
+
});
|
|
2703
|
+
this._send({ type: "response.create" });
|
|
2704
|
+
return;
|
|
2705
|
+
}
|
|
2630
2706
|
if (!this._tools || !this._tools.has(funcName)) {
|
|
2631
2707
|
this._log.error("Unknown tool: %s", funcName);
|
|
2632
2708
|
await this._waitForResponseDone();
|
|
@@ -2764,6 +2840,13 @@ function sanitizeSchemaForGemini(schema, defs, depth = 0) {
|
|
|
2764
2840
|
return result;
|
|
2765
2841
|
}
|
|
2766
2842
|
var GeminiRealtime = class _GeminiRealtime {
|
|
2843
|
+
/**
|
|
2844
|
+
* Gemini Live 는 connect 시점의 config 로 도구가 고정되어 세션 도중 변경할 수 없다.
|
|
2845
|
+
*
|
|
2846
|
+
* 통화 시작 시점에야 붙는 MCP 도구는 prewarm 된 세션에 넣을 방법이 없으므로,
|
|
2847
|
+
* `ClawOpsAgent` 가 MCP 서버 설정과 이 플래그를 보고 prewarm 을 건너뛴다.
|
|
2848
|
+
*/
|
|
2849
|
+
toolsFrozenAfterPrewarm = true;
|
|
2767
2850
|
_apiKey;
|
|
2768
2851
|
_systemPrompt;
|
|
2769
2852
|
_model;
|
|
@@ -3069,6 +3152,11 @@ var GeminiRealtime = class _GeminiRealtime {
|
|
|
3069
3152
|
continue;
|
|
3070
3153
|
}
|
|
3071
3154
|
}
|
|
3155
|
+
if (BUILTIN_TOOL_NAMES.has(name) && this._call instanceof BufferingCall) {
|
|
3156
|
+
this._log.warn("Builtin tool %s called before answer \u2014 deferring", name);
|
|
3157
|
+
responses.push({ id: fcId, name, response: { result: CALL_NOT_READY_RESULT } });
|
|
3158
|
+
continue;
|
|
3159
|
+
}
|
|
3072
3160
|
if (!this._tools || !this._tools.has(name)) {
|
|
3073
3161
|
this._log.error("Unknown tool: %s", name);
|
|
3074
3162
|
responses.push({ id: fcId, name, response: { error: `Unknown tool: ${name}` } });
|