melchizedek-agents 0.19.0 → 0.20.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/CHANGELOG.md +252 -76
- package/DOCUMENTATION.md +44 -15
- package/QUICKSTART.md +9 -6
- package/README.md +6 -9
- package/config/agents/syndicateSchema.yaml +3 -0
- package/dist/lib/adkPeer.d.ts +63 -0
- package/dist/lib/adkPeer.js +240 -0
- package/dist/lib/compile.d.ts +40 -2
- package/dist/lib/compile.js +80 -12
- package/dist/lib/compileAdk.d.ts +7 -4
- package/dist/lib/compileAdk.js +22 -12
- package/dist/lib/compileNative.d.ts +28 -2
- package/dist/lib/compileNative.js +60 -4
- package/dist/lib/doctor.d.ts +28 -1
- package/dist/lib/doctor.js +63 -2
- package/dist/lib/index.d.ts +4 -0
- package/dist/lib/index.js +5 -0
- package/dist/lib/models/adapterResolver.d.ts +13 -11
- package/dist/lib/models/adapterResolver.js +11 -10
- package/dist/lib/models/adkGeminiAdapter.js +2 -0
- package/dist/lib/models/adkShim.d.ts +1 -1
- package/dist/lib/models/adkShim.js +1 -1
- package/dist/lib/models/capabilities.js +13 -10
- package/dist/lib/models/claudeLlm.js +2 -2
- package/dist/lib/models/fallback.d.ts +1 -1
- package/dist/lib/models/fallback.js +1 -1
- package/dist/lib/models/gatewayLlm.js +2 -2
- package/dist/lib/models/geminiAdapter.d.ts +6 -4
- package/dist/lib/models/geminiAdapter.js +28 -5
- package/dist/lib/models/geminiState.d.ts +21 -0
- package/dist/lib/models/geminiState.js +26 -0
- package/dist/lib/models/genaiMapping.d.ts +24 -4
- package/dist/lib/models/genaiMapping.js +109 -6
- package/dist/lib/models/gptLlm.js +2 -2
- package/dist/lib/models/grokLlm.js +2 -2
- package/dist/lib/models/kimiLlm.js +2 -2
- package/dist/lib/models/ollamaLlm.js +2 -2
- package/dist/lib/models/registry.d.ts +5 -1
- package/dist/lib/models/registry.js +17 -12
- package/dist/lib/models/tracedGemini.d.ts +1 -1
- package/dist/lib/models/tracedGemini.js +1 -1
- package/dist/lib/runtime/adkSessionBridge.d.ts +1 -1
- package/dist/lib/runtime/adkSessionBridge.js +1 -1
- package/dist/lib/runtime/approvals.d.ts +5 -0
- package/dist/lib/runtime/approvals.js +39 -8
- package/dist/lib/runtime/credentials.d.ts +3 -1
- package/dist/lib/runtime/credentials.js +6 -1
- package/dist/lib/runtime/native/agentLoop.d.ts +7 -1
- package/dist/lib/runtime/native/agentLoop.js +31 -13
- package/dist/lib/runtime/native/delegate.d.ts +53 -0
- package/dist/lib/runtime/native/delegate.js +91 -8
- package/dist/lib/runtime/native/interrupts.d.ts +6 -3
- package/dist/lib/runtime/native/interrupts.js +23 -4
- package/dist/lib/runtime/native/request.d.ts +1 -1
- package/dist/lib/runtime/native/request.js +1 -1
- package/dist/lib/runtime/native/selfCorrection.d.ts +64 -6
- package/dist/lib/runtime/native/selfCorrection.js +82 -8
- package/dist/lib/runtime/native/step.d.ts +14 -6
- package/dist/lib/runtime/native/step.js +34 -10
- package/dist/lib/runtime/runtimeFlag.d.ts +13 -5
- package/dist/lib/runtime/runtimeFlag.js +14 -6
- package/dist/lib/runtime/syndicateTurn.d.ts +15 -10
- package/dist/lib/runtime/syndicateTurn.js +59 -32
- package/dist/lib/runtime/valueDepth.d.ts +23 -0
- package/dist/lib/runtime/valueDepth.js +41 -0
- package/dist/lib/session/supabaseSessionService.d.ts +1 -1
- package/dist/lib/session/supabaseSessionService.js +1 -1
- package/dist/lib/session/transcript.d.ts +1 -1
- package/dist/lib/session/transcript.js +5 -3
- package/dist/lib/storage/postgres/sessionService.d.ts +1 -1
- package/dist/lib/storage/postgres/sessionService.js +1 -1
- package/dist/lib/syndicateSchema.d.ts +2 -0
- package/dist/lib/syndicateSchema.js +27 -6
- package/dist/lib/toolRegistry.d.ts +12 -1
- package/dist/lib/toolRegistry.js +42 -2
- package/dist/lib/tools/adkTool.d.ts +1 -1
- package/dist/lib/tools/adkTool.js +1 -1
- package/dist/lib/tools/collectionsSearchTool.d.ts +1 -1
- package/dist/lib/tools/collectionsSearchTool.js +1 -1
- package/dist/lib/tools/generateImageTool.d.ts +1 -1
- package/dist/lib/tools/inspectImageTool.d.ts +1 -1
- package/dist/lib/tools/urlContextTool.d.ts +1 -1
- package/dist/lib/tools/urlContextTool.js +1 -1
- package/dist/lib/tools/webExtractTool.d.ts +1 -1
- package/dist/lib/tools/webSearchTool.d.ts +1 -1
- package/dist/lib/tools/webSearchTool.js +1 -1
- package/dist/lib/tools/xApiSearchTool.d.ts +1 -1
- package/dist/lib/tools/xSearchTool.d.ts +1 -1
- package/dist/lib/tools/xSearchTool.js +1 -1
- package/dist/lib/wiki/agentRun.d.ts +1 -1
- package/dist/lib/wiki/agentRun.js +2 -1
- package/dist/lib/workflow/agentNode.d.ts +21 -4
- package/dist/lib/workflow/agentNode.js +96 -5
- package/dist/lib/workflow/graph.d.ts +5 -4
- package/dist/lib/workflow/graph.js +14 -4
- package/dist/lib/workflow/resume.d.ts +10 -9
- package/dist/lib/workflow/resume.js +13 -12
- package/dist/lib/workflow/scheduler.d.ts +10 -7
- package/dist/lib/workflow/scheduler.js +15 -2
- package/dist/lib/workflow.d.ts +33 -11
- package/dist/lib/workflow.js +49 -27
- package/dist/lib/workflowConfig.d.ts +4 -0
- package/dist/lib/workflowConfig.js +4 -0
- package/dist/scripts/doctor.d.ts +3 -1
- package/dist/scripts/doctor.js +4 -2
- package/package.json +6 -3
|
@@ -17,6 +17,27 @@
|
|
|
17
17
|
export declare const GEMINI_PROVIDER = "gemini";
|
|
18
18
|
/** The providerState kind for a Gemini thought signature; the payload is the signature. */
|
|
19
19
|
export declare const THOUGHT_SIGNATURE_KIND = "thought_signature";
|
|
20
|
+
/**
|
|
21
|
+
* The thought signature Gemini documents for a function call that has no
|
|
22
|
+
* real one. Gemini 3 rejects a current-turn function call without a
|
|
23
|
+
* signature; this value passes its validator (ADR 0065).
|
|
24
|
+
*/
|
|
25
|
+
export declare const PLACEHOLDER_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
|
|
26
|
+
/**
|
|
27
|
+
* The providerState kind the Gemini adapter writes for the Gemini parts the
|
|
28
|
+
* contract has no type for (code execution, server-side invocations),
|
|
29
|
+
* carried whole on the next output part (ADR 0065). The payload is
|
|
30
|
+
* `{ before: <the genai parts>, signature?: <the part's own signature> }`.
|
|
31
|
+
* The genai mapping writes them back out as the parts they were (ADR 0100).
|
|
32
|
+
*/
|
|
33
|
+
export declare const CARRIED_PARTS_KIND = "carried_parts";
|
|
34
|
+
/**
|
|
35
|
+
* The providerState kind the genai mapping writes for a genai part the
|
|
36
|
+
* contract cannot hold exactly; the payload is the part, verbatim.
|
|
37
|
+
*/
|
|
38
|
+
export declare const GENAI_PART_KIND = "genai_part";
|
|
39
|
+
/** A Gemini part the contract has no type for and Gemini wants back within the turn: code execution, a server-side invocation. */
|
|
40
|
+
export declare function isCarriedWirePart(part: unknown): boolean;
|
|
20
41
|
/**
|
|
21
42
|
* The prefix of an id the genai mapping (lib/models/genaiMapping.ts) made
|
|
22
43
|
* for a call or result that had none. Such an id never goes on the wire: the
|
|
@@ -17,6 +17,32 @@
|
|
|
17
17
|
export const GEMINI_PROVIDER = 'gemini';
|
|
18
18
|
/** The providerState kind for a Gemini thought signature; the payload is the signature. */
|
|
19
19
|
export const THOUGHT_SIGNATURE_KIND = 'thought_signature';
|
|
20
|
+
/**
|
|
21
|
+
* The thought signature Gemini documents for a function call that has no
|
|
22
|
+
* real one. Gemini 3 rejects a current-turn function call without a
|
|
23
|
+
* signature; this value passes its validator (ADR 0065).
|
|
24
|
+
*/
|
|
25
|
+
export const PLACEHOLDER_THOUGHT_SIGNATURE = 'skip_thought_signature_validator';
|
|
26
|
+
/**
|
|
27
|
+
* The providerState kind the Gemini adapter writes for the Gemini parts the
|
|
28
|
+
* contract has no type for (code execution, server-side invocations),
|
|
29
|
+
* carried whole on the next output part (ADR 0065). The payload is
|
|
30
|
+
* `{ before: <the genai parts>, signature?: <the part's own signature> }`.
|
|
31
|
+
* The genai mapping writes them back out as the parts they were (ADR 0100).
|
|
32
|
+
*/
|
|
33
|
+
export const CARRIED_PARTS_KIND = 'carried_parts';
|
|
34
|
+
/**
|
|
35
|
+
* The providerState kind the genai mapping writes for a genai part the
|
|
36
|
+
* contract cannot hold exactly; the payload is the part, verbatim.
|
|
37
|
+
*/
|
|
38
|
+
export const GENAI_PART_KIND = 'genai_part';
|
|
39
|
+
/** A Gemini part the contract has no type for and Gemini wants back within the turn: code execution, a server-side invocation. */
|
|
40
|
+
export function isCarriedWirePart(part) {
|
|
41
|
+
if (typeof part !== 'object' || part === null)
|
|
42
|
+
return false;
|
|
43
|
+
const p = part;
|
|
44
|
+
return p.executableCode !== undefined || p.codeExecutionResult !== undefined || p.toolCall !== undefined || p.toolResponse !== undefined;
|
|
45
|
+
}
|
|
20
46
|
/**
|
|
21
47
|
* The prefix of an id the genai mapping (lib/models/genaiMapping.ts) made
|
|
22
48
|
* for a call or result that had none. Such an id never goes on the wire: the
|
|
@@ -152,7 +152,7 @@
|
|
|
152
152
|
import type { Content, ContentUnion, GenerateContentConfig, GenerateContentResponseUsageMetadata, Part as GenaiPart } from '@google/genai';
|
|
153
153
|
import type { LlmRequest, LlmResponse } from '@google/adk';
|
|
154
154
|
import type { Message, ModelRequest, ModelResponse, NativeTool, Part, ReasoningSetting, Sampling, ToolChoice, Usage } from './contract.ts';
|
|
155
|
-
import { GEMINI_PROVIDER, MINTED_CALL_ID_PREFIX, THOUGHT_SIGNATURE_KIND } from './geminiState.ts';
|
|
155
|
+
import { GEMINI_PROVIDER, GENAI_PART_KIND, MINTED_CALL_ID_PREFIX, THOUGHT_SIGNATURE_KIND } from './geminiState.ts';
|
|
156
156
|
/**
|
|
157
157
|
* The provider id the mapping writes its own state under (only a Gemini
|
|
158
158
|
* adapter replays it), and the providerState kind for a Gemini
|
|
@@ -160,8 +160,8 @@ import { GEMINI_PROVIDER, MINTED_CALL_ID_PREFIX, THOUGHT_SIGNATURE_KIND } from '
|
|
|
160
160
|
* lib/models/geminiState.ts, so the Gemini adapter spells them the same.
|
|
161
161
|
*/
|
|
162
162
|
export { GEMINI_PROVIDER, THOUGHT_SIGNATURE_KIND };
|
|
163
|
-
/** providerState kind for a genai part the contract cannot hold exactly; the payload is the part. */
|
|
164
|
-
export
|
|
163
|
+
/** providerState kind for a genai part the contract cannot hold exactly; the payload is the part (defined in lib/models/geminiState.ts). */
|
|
164
|
+
export { GENAI_PART_KIND };
|
|
165
165
|
/** The prefix of an id the mapping made for a call or result that had none (defined in lib/models/geminiState.ts). */
|
|
166
166
|
export { MINTED_CALL_ID_PREFIX };
|
|
167
167
|
/** A conversation as the contract holds it: the system prompt and the messages. */
|
|
@@ -193,6 +193,15 @@ export declare function systemText(instruction: ContentUnion | undefined): strin
|
|
|
193
193
|
export declare function contentsToMessages(contents: readonly Content[], systemInstruction?: ContentUnion): ContractHistory;
|
|
194
194
|
/** One contract part as the genai part it maps to. */
|
|
195
195
|
export declare function partToGenai(part: Part): GenaiPart;
|
|
196
|
+
/**
|
|
197
|
+
* Contract parts as genai parts. A part the Gemini adapter wrote with
|
|
198
|
+
* `carried_parts` state (code execution, server-side invocations, ADR 0065)
|
|
199
|
+
* becomes the genai parts it carries, verbatim, then itself with its own
|
|
200
|
+
* signature as `thoughtSignature`. An empty text part that only carried them
|
|
201
|
+
* is left out unless it has a signature. So a stored event holds the parts as
|
|
202
|
+
* Gemini sent them, as ADK's Gemini stores them (ADR 0100).
|
|
203
|
+
*/
|
|
204
|
+
export declare function partsToGenai(parts: readonly Part[]): GenaiPart[];
|
|
196
205
|
/** One contract message as a genai content. */
|
|
197
206
|
export declare function messageToContent(message: Message): Content;
|
|
198
207
|
/** The inverse of contentsToMessages; the system instruction comes back as a string. */
|
|
@@ -240,8 +249,19 @@ export declare function llmRequestToModelRequest(llmRequest: LlmRequest, options
|
|
|
240
249
|
export declare function usageToMetadata(usage: Usage): GenerateContentResponseUsageMetadata;
|
|
241
250
|
/** Gemini's usageMetadata as contract Usage, or undefined when it counts nothing. */
|
|
242
251
|
export declare function usageFromMetadata(meta: GenerateContentResponseUsageMetadata | undefined): Usage | undefined;
|
|
252
|
+
/** What a call's arguments become when they nest past MAX_VALUE_DEPTH (contractOutputPart). */
|
|
253
|
+
export declare const TOO_DEEP_ARGUMENTS = "[arguments nested deeper than 64 levels were dropped]";
|
|
254
|
+
/**
|
|
255
|
+
* `response` with each part held to the contract (contractOutputPart): the
|
|
256
|
+
* same object when every part already is, else a copy with the parts
|
|
257
|
+
* checked. Used by modelResponseToLlmResponse (the ADK shim's mapping) and
|
|
258
|
+
* by the native step, so both runtimes read and store the same answer. A
|
|
259
|
+
* response that is not an object is returned as it is: the caller fails on
|
|
260
|
+
* it as on any adapter that broke the contract.
|
|
261
|
+
*/
|
|
262
|
+
export declare function contractModelResponse<R extends ModelResponse>(response: R): R;
|
|
243
263
|
/** A ModelResponse as the LlmResponse ADK expects from a model (see the header). */
|
|
244
|
-
export declare function modelResponseToLlmResponse(
|
|
264
|
+
export declare function modelResponseToLlmResponse(unchecked: ModelResponse): LlmResponse;
|
|
245
265
|
/** The native tools in `tools` that Gemini has no tool for, each once: modelRequestToLlmRequest leaves them out. */
|
|
246
266
|
export declare function nativeToolsWithoutGeminiTool(tools?: readonly NativeTool[]): NativeTool[];
|
|
247
267
|
/** A ModelRequest as the LlmRequest ADK's path builds for a Gemini model (see the header for what does not come back the same). */
|
|
@@ -151,9 +151,10 @@
|
|
|
151
151
|
*/
|
|
152
152
|
import { FinishReason, FunctionCallingConfigMode } from '@google/genai';
|
|
153
153
|
import { ERROR_RETRYABLE_KEY, ERROR_STATUS_KEY, errorText, withRetryVerdict } from './errorResponse.js';
|
|
154
|
-
import { GEMINI_PROVIDER, MINTED_CALL_ID_PREFIX, THOUGHT_SIGNATURE_KIND } from './geminiState.js';
|
|
154
|
+
import { CARRIED_PARTS_KIND, GEMINI_PROVIDER, GENAI_PART_KIND, MINTED_CALL_ID_PREFIX, THOUGHT_SIGNATURE_KIND } from './geminiState.js';
|
|
155
155
|
import { reasoningConfig } from './reasoning.js';
|
|
156
156
|
import { contractToolDeclaration, nativeToolOf, toContractJsonSchema } from './schemaNormalize.js';
|
|
157
|
+
import { MAX_VALUE_DEPTH, nestedDeeperThan } from '../runtime/valueDepth.js';
|
|
157
158
|
/**
|
|
158
159
|
* The provider id the mapping writes its own state under (only a Gemini
|
|
159
160
|
* adapter replays it), and the providerState kind for a Gemini
|
|
@@ -161,8 +162,8 @@ import { contractToolDeclaration, nativeToolOf, toContractJsonSchema } from './s
|
|
|
161
162
|
* lib/models/geminiState.ts, so the Gemini adapter spells them the same.
|
|
162
163
|
*/
|
|
163
164
|
export { GEMINI_PROVIDER, THOUGHT_SIGNATURE_KIND };
|
|
164
|
-
/** providerState kind for a genai part the contract cannot hold exactly; the payload is the part. */
|
|
165
|
-
export
|
|
165
|
+
/** providerState kind for a genai part the contract cannot hold exactly; the payload is the part (defined in lib/models/geminiState.ts). */
|
|
166
|
+
export { GENAI_PART_KIND };
|
|
166
167
|
/** The prefix of an id the mapping made for a call or result that had none (defined in lib/models/geminiState.ts). */
|
|
167
168
|
export { MINTED_CALL_ID_PREFIX };
|
|
168
169
|
const ALLOWED = {
|
|
@@ -431,9 +432,39 @@ export function partToGenai(part) {
|
|
|
431
432
|
}
|
|
432
433
|
return out;
|
|
433
434
|
}
|
|
435
|
+
/**
|
|
436
|
+
* Contract parts as genai parts. A part the Gemini adapter wrote with
|
|
437
|
+
* `carried_parts` state (code execution, server-side invocations, ADR 0065)
|
|
438
|
+
* becomes the genai parts it carries, verbatim, then itself with its own
|
|
439
|
+
* signature as `thoughtSignature`. An empty text part that only carried them
|
|
440
|
+
* is left out unless it has a signature. So a stored event holds the parts as
|
|
441
|
+
* Gemini sent them, as ADK's Gemini stores them (ADR 0100).
|
|
442
|
+
*/
|
|
443
|
+
export function partsToGenai(parts) {
|
|
444
|
+
const out = [];
|
|
445
|
+
for (const part of parts) {
|
|
446
|
+
const state = part.providerState;
|
|
447
|
+
if (state?.provider !== GEMINI_PROVIDER || state.kind !== CARRIED_PARTS_KIND || !isObject(state.payload)) {
|
|
448
|
+
out.push(partToGenai(part));
|
|
449
|
+
continue;
|
|
450
|
+
}
|
|
451
|
+
const { before, signature } = state.payload;
|
|
452
|
+
if (Array.isArray(before))
|
|
453
|
+
for (const carried of before)
|
|
454
|
+
if (isObject(carried))
|
|
455
|
+
out.push({ ...carried });
|
|
456
|
+
const { providerState: _carried, ...bare } = part;
|
|
457
|
+
const own = typeof signature === 'string' && signature ? signature : undefined;
|
|
458
|
+
if (bare.type === 'text' && !bare.text && !own)
|
|
459
|
+
continue;
|
|
460
|
+
const genai = partToGenai(bare);
|
|
461
|
+
out.push(own ? { ...genai, thoughtSignature: own } : genai);
|
|
462
|
+
}
|
|
463
|
+
return out;
|
|
464
|
+
}
|
|
434
465
|
/** One contract message as a genai content. */
|
|
435
466
|
export function messageToContent(message) {
|
|
436
|
-
return { role: GENAI_ROLE[message.role], parts: message.parts
|
|
467
|
+
return { role: GENAI_ROLE[message.role], parts: partsToGenai(message.parts) };
|
|
437
468
|
}
|
|
438
469
|
/** The inverse of contentsToMessages; the system instruction comes back as a string. */
|
|
439
470
|
export function messagesToContents(history) {
|
|
@@ -626,9 +657,81 @@ const GEMINI_FINISH_REASONS = new Set(Object.values(FinishReason).filter((r) =>
|
|
|
626
657
|
function finishReasonOfCode(code) {
|
|
627
658
|
return code !== undefined && GEMINI_FINISH_REASONS.has(code) ? code : undefined;
|
|
628
659
|
}
|
|
660
|
+
/** What a call's arguments become when they nest past MAX_VALUE_DEPTH (contractOutputPart). */
|
|
661
|
+
export const TOO_DEEP_ARGUMENTS = `[arguments nested deeper than ${MAX_VALUE_DEPTH} levels were dropped]`;
|
|
662
|
+
/**
|
|
663
|
+
* One part of a model's answer as the contract allows it (lib/models/
|
|
664
|
+
* contract.ts), or undefined to drop it. The contract binds an adapter, and
|
|
665
|
+
* a model's answer is untrusted input to the runtime that stores it, so the
|
|
666
|
+
* runtimes hold an adapter to it here rather than store a part no reader
|
|
667
|
+
* expects (WS5-5, wiki/operations/native-loop-security.md):
|
|
668
|
+
* - a part that is not an object, of no known kind, or a tool result (an
|
|
669
|
+
* answer holds none) is dropped;
|
|
670
|
+
* - a text or thinking part whose text is not a string is dropped;
|
|
671
|
+
* - a tool call's name and id that are not strings become `''` (the
|
|
672
|
+
* runtime then mints the id), and its arguments that are not an object
|
|
673
|
+
* become `{}` when absent or null, else `{ raw: <value> }`, the
|
|
674
|
+
* contract's form for arguments that do not parse;
|
|
675
|
+
* - arguments that nest deeper than MAX_VALUE_DEPTH levels (lib/runtime/
|
|
676
|
+
* valueDepth.ts) become `{ raw: TOO_DEEP_ARGUMENTS }`: every later
|
|
677
|
+
* reader of the session would overflow its stack on them;
|
|
678
|
+
* - a blob needs a string mimeType and a string `data` or `url`;
|
|
679
|
+
* - a Gemini part carried whole must be an object.
|
|
680
|
+
* A part the contract allows is returned as it is, so a well-behaved
|
|
681
|
+
* adapter's answer maps exactly as before.
|
|
682
|
+
*/
|
|
683
|
+
function contractOutputPart(part) {
|
|
684
|
+
if (!isObject(part))
|
|
685
|
+
return undefined;
|
|
686
|
+
const state = part.providerState;
|
|
687
|
+
if (state?.provider === GEMINI_PROVIDER && state.kind === GENAI_PART_KIND && !isObject(state.payload))
|
|
688
|
+
return undefined;
|
|
689
|
+
switch (part.type) {
|
|
690
|
+
case 'text':
|
|
691
|
+
case 'thinking':
|
|
692
|
+
return typeof part.text === 'string' ? part : undefined;
|
|
693
|
+
case 'toolCall': {
|
|
694
|
+
const { name, id, args } = part;
|
|
695
|
+
const tooDeep = nestedDeeperThan(args);
|
|
696
|
+
if (typeof name === 'string' && typeof id === 'string' && (isObject(args) || Array.isArray(args)) && !tooDeep)
|
|
697
|
+
return part;
|
|
698
|
+
const checkedArgs = tooDeep
|
|
699
|
+
? { raw: TOO_DEEP_ARGUMENTS }
|
|
700
|
+
: isObject(args) || Array.isArray(args)
|
|
701
|
+
? args
|
|
702
|
+
: args === undefined || args === null
|
|
703
|
+
? {}
|
|
704
|
+
: { raw: args };
|
|
705
|
+
return { ...part, type: 'toolCall', name: typeof name === 'string' ? name : '', id: typeof id === 'string' ? id : '', args: checkedArgs };
|
|
706
|
+
}
|
|
707
|
+
case 'blob':
|
|
708
|
+
return typeof part.mimeType === 'string' && (typeof part.data === 'string' || typeof part.url === 'string') ? part : undefined;
|
|
709
|
+
default:
|
|
710
|
+
return undefined;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* `response` with each part held to the contract (contractOutputPart): the
|
|
715
|
+
* same object when every part already is, else a copy with the parts
|
|
716
|
+
* checked. Used by modelResponseToLlmResponse (the ADK shim's mapping) and
|
|
717
|
+
* by the native step, so both runtimes read and store the same answer. A
|
|
718
|
+
* response that is not an object is returned as it is: the caller fails on
|
|
719
|
+
* it as on any adapter that broke the contract.
|
|
720
|
+
*/
|
|
721
|
+
export function contractModelResponse(response) {
|
|
722
|
+
if (!isObject(response))
|
|
723
|
+
return response;
|
|
724
|
+
const raw = response.parts;
|
|
725
|
+
const parts = Array.isArray(raw) ? raw : [];
|
|
726
|
+
const checked = parts.map(contractOutputPart);
|
|
727
|
+
if (Array.isArray(raw) && checked.every((p, i) => p === parts[i]))
|
|
728
|
+
return response;
|
|
729
|
+
return { ...response, parts: checked.filter((p) => p !== undefined) };
|
|
730
|
+
}
|
|
629
731
|
/** A ModelResponse as the LlmResponse ADK expects from a model (see the header). */
|
|
630
|
-
export function modelResponseToLlmResponse(
|
|
631
|
-
const
|
|
732
|
+
export function modelResponseToLlmResponse(unchecked) {
|
|
733
|
+
const response = contractModelResponse(unchecked);
|
|
734
|
+
const parts = partsToGenai(response.parts);
|
|
632
735
|
if (response.partial)
|
|
633
736
|
return { content: { role: 'model', parts }, partial: true };
|
|
634
737
|
const finishReason = finishReasonOfCode(response.error?.code) ?? FINISH_REASONS[response.finishReason];
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
* The LlmRequest builders below (buildResponsesInput, buildResponsesTools)
|
|
34
34
|
* are the adapter's own, run on the LlmRequest mapped to the contract.
|
|
35
35
|
*/
|
|
36
|
-
import {
|
|
36
|
+
import { requireAdk } from '../adkPeer.js';
|
|
37
37
|
import { AdkShim } from './adkShim.js';
|
|
38
38
|
import { llmRequestToModelRequest, reasoningOf } from './genaiMapping.js';
|
|
39
39
|
import { GptAdapter, responsesFunctionTools, responsesInput, responsesServerTools } from './gptAdapter.js';
|
|
@@ -125,5 +125,5 @@ export class GptLlm extends AdkShim {
|
|
|
125
125
|
* registerAvailableProviders() when OPENAI_API_KEY is present.
|
|
126
126
|
*/
|
|
127
127
|
export function registerGptLlm() {
|
|
128
|
-
LLMRegistry.register(GptLlm);
|
|
128
|
+
requireAdk("Registering a model class with ADK's LLMRegistry").LLMRegistry.register(GptLlm);
|
|
129
129
|
}
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
* "grok-4.3"), which may differ from the requested id; invalid ids are
|
|
35
35
|
* rejected with "Model not found".
|
|
36
36
|
*/
|
|
37
|
-
import {
|
|
37
|
+
import { requireAdk } from '../adkPeer.js';
|
|
38
38
|
import { GptLlm } from './gptLlm.js';
|
|
39
39
|
import { GrokAdapter } from './grokAdapter.js';
|
|
40
40
|
export { DEFAULT_GROK_TIMEOUT_MS, grokTimeoutMs } from './grokAdapter.js';
|
|
@@ -52,5 +52,5 @@ export class GrokLlm extends GptLlm {
|
|
|
52
52
|
* registerAvailableProviders() when XAI_API_KEY is present.
|
|
53
53
|
*/
|
|
54
54
|
export function registerGrokLlm() {
|
|
55
|
-
LLMRegistry.register(GrokLlm);
|
|
55
|
+
requireAdk("Registering a model class with ADK's LLMRegistry").LLMRegistry.register(GrokLlm);
|
|
56
56
|
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* this path an agent's older spelling `reasoningEffort: max` still reaches
|
|
16
16
|
* K3, which the contract has no level for.
|
|
17
17
|
*/
|
|
18
|
-
import {
|
|
18
|
+
import { requireAdk } from '../adkPeer.js';
|
|
19
19
|
import { KimiAdapter } from './kimiAdapter.js';
|
|
20
20
|
import { OpenAiCompatibleLlm } from './openAiCompatibleLlm.js';
|
|
21
21
|
export { MOONSHOT_BASE_URL, isKimiK3, wantsReasoningReplay } from './kimiAdapter.js';
|
|
@@ -31,5 +31,5 @@ export class KimiLlm extends OpenAiCompatibleLlm {
|
|
|
31
31
|
// ── Registration helper ───────────────────────────────────────────────────────
|
|
32
32
|
/** Registers KimiLlm with the ADK LLMRegistry (called when MOONSHOT_API_KEY is set). */
|
|
33
33
|
export function registerKimiLlm() {
|
|
34
|
-
LLMRegistry.register(KimiLlm);
|
|
34
|
+
requireAdk("Registering a model class with ADK's LLMRegistry").LLMRegistry.register(KimiLlm);
|
|
35
35
|
}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* supportedModels are what they were before the adapter moved onto the
|
|
13
13
|
* contract, so lib/models/registry.ts and every caller are unchanged.
|
|
14
14
|
*/
|
|
15
|
-
import {
|
|
15
|
+
import { requireAdk } from '../adkPeer.js';
|
|
16
16
|
import { OllamaAdapter } from './ollamaAdapter.js';
|
|
17
17
|
import { OpenAiCompatibleLlm } from './openAiCompatibleLlm.js';
|
|
18
18
|
// ── OllamaLlm ─────────────────────────────────────────────────────────────────
|
|
@@ -38,5 +38,5 @@ export class OllamaLlm extends OpenAiCompatibleLlm {
|
|
|
38
38
|
* OLLAMA_UNREACHABLE message that says how to start it.
|
|
39
39
|
*/
|
|
40
40
|
export function registerOllamaLlm() {
|
|
41
|
-
LLMRegistry.register(OllamaLlm);
|
|
41
|
+
requireAdk("Registering a model class with ADK's LLMRegistry").LLMRegistry.register(OllamaLlm);
|
|
42
42
|
}
|
|
@@ -84,6 +84,10 @@ export declare function providerStatuses(): ProviderStatus[];
|
|
|
84
84
|
* provider whose direct key is ABSENT is served by the gateway stand-in
|
|
85
85
|
* instead (lib/models/gateway.ts — the fallback rule). Returns the
|
|
86
86
|
* per-provider statuses so entrypoints can log which models are routable.
|
|
87
|
+
*
|
|
88
|
+
* Without @google/adk installed there is no LLMRegistry to register into:
|
|
89
|
+
* the native runtime resolves every id through resolveAdapter, so nothing is
|
|
90
|
+
* registered and the statuses are returned as they are (ADR 0102).
|
|
87
91
|
*/
|
|
88
92
|
export declare function registerAvailableProviders(log?: (msg: string) => void): ProviderStatus[];
|
|
89
93
|
export interface ResolveModelOptions {
|
|
@@ -109,7 +113,7 @@ export interface ResolveModelOptions {
|
|
|
109
113
|
* `defaultProvider` (or Gemini).
|
|
110
114
|
*/
|
|
111
115
|
export declare function resolveModel(model: string | undefined, options?: ResolveModelOptions): BaseLlm;
|
|
112
|
-
/** GEMINI_ADAPTER (`
|
|
116
|
+
/** GEMINI_ADAPTER (`engine`, the default, or `adk`). Any other value is a configuration error. */
|
|
113
117
|
export declare function geminiAdapterChoice(env?: NodeJS.ProcessEnv): GeminiAdapterChoice;
|
|
114
118
|
/**
|
|
115
119
|
* Resolves a model id to the engine's own ModelAdapter (ADR 0048), from the
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
* Register BEFORE constructing any agent: the LLMRegistry caches model→class
|
|
41
41
|
* resolution (LRU), so late registration can be masked by stale cache hits.
|
|
42
42
|
*/
|
|
43
|
-
import { Gemini,
|
|
43
|
+
import { Gemini, adkInstalled, requireAdk } from '../adkPeer.js';
|
|
44
44
|
import { endpointFromEnv, endpointProblems, providerReady } from './endpoints.js';
|
|
45
45
|
import { DEFAULT_CLAUDE_MODEL, DEFAULT_GEMINI_MODEL, DEFAULT_GPT_MODEL, DEFAULT_GROK_MODEL, DEFAULT_KIMI_MODEL, DEFAULT_OLLAMA_MODEL, } from '../config.js';
|
|
46
46
|
import { AdkGeminiAdapter } from './adkGeminiAdapter.js';
|
|
@@ -98,7 +98,7 @@ export function providerStatuses() {
|
|
|
98
98
|
});
|
|
99
99
|
}
|
|
100
100
|
const REGISTRARS = {
|
|
101
|
-
gemini: () => LLMRegistry.register(TracedGemini),
|
|
101
|
+
gemini: () => requireAdk("Registering a model class with ADK's LLMRegistry").LLMRegistry.register(TracedGemini),
|
|
102
102
|
anthropic: registerClaudeLlm,
|
|
103
103
|
openai: registerGptLlm,
|
|
104
104
|
xai: registerGrokLlm,
|
|
@@ -113,13 +113,13 @@ const REGISTRARS = {
|
|
|
113
113
|
* are registered at import time — replacing them is how TracedGemini works
|
|
114
114
|
* too.
|
|
115
115
|
*/
|
|
116
|
-
const PATTERNS = {
|
|
116
|
+
const PATTERNS = () => ({
|
|
117
117
|
gemini: Gemini.supportedModels,
|
|
118
118
|
anthropic: ClaudeLlm.supportedModels,
|
|
119
119
|
openai: GptLlm.supportedModels,
|
|
120
120
|
xai: GrokLlm.supportedModels,
|
|
121
121
|
moonshot: KimiLlm.supportedModels,
|
|
122
|
-
};
|
|
122
|
+
});
|
|
123
123
|
let providersRegistered = false;
|
|
124
124
|
/**
|
|
125
125
|
* Registers every adapter whose credentials exist into the ADK LLMRegistry
|
|
@@ -129,14 +129,18 @@ let providersRegistered = false;
|
|
|
129
129
|
* provider whose direct key is ABSENT is served by the gateway stand-in
|
|
130
130
|
* instead (lib/models/gateway.ts — the fallback rule). Returns the
|
|
131
131
|
* per-provider statuses so entrypoints can log which models are routable.
|
|
132
|
+
*
|
|
133
|
+
* Without @google/adk installed there is no LLMRegistry to register into:
|
|
134
|
+
* the native runtime resolves every id through resolveAdapter, so nothing is
|
|
135
|
+
* registered and the statuses are returned as they are (ADR 0102).
|
|
132
136
|
*/
|
|
133
137
|
export function registerAvailableProviders(log) {
|
|
134
138
|
const statuses = providerStatuses();
|
|
135
|
-
if (!providersRegistered) {
|
|
139
|
+
if (!providersRegistered && adkInstalled()) {
|
|
136
140
|
providersRegistered = true;
|
|
137
141
|
for (const status of statuses) {
|
|
138
142
|
if (status.transport === 'gateway' && status.provider !== 'ollama') {
|
|
139
|
-
registerGatewayLlm(PATTERNS[status.provider]);
|
|
143
|
+
registerGatewayLlm(PATTERNS()[status.provider]);
|
|
140
144
|
}
|
|
141
145
|
else if (status.available || status.provider === 'gemini') {
|
|
142
146
|
REGISTRARS[status.provider]();
|
|
@@ -213,16 +217,17 @@ export function resolveModel(model, options = {}) {
|
|
|
213
217
|
return route.transport === 'gateway' ? new GatewayLlm({ model: resolved }) : ADK_LLM[route.provider](route);
|
|
214
218
|
}
|
|
215
219
|
// ── Contract adapters (the native runtime) ───────────────────────────────────
|
|
216
|
-
/** GEMINI_ADAPTER (`
|
|
220
|
+
/** GEMINI_ADAPTER (`engine`, the default, or `adk`). Any other value is a configuration error. */
|
|
217
221
|
export function geminiAdapterChoice(env = process.env) {
|
|
218
|
-
return geminiAdapterSetting(env) ?? '
|
|
222
|
+
return geminiAdapterSetting(env) ?? 'engine';
|
|
219
223
|
}
|
|
220
224
|
/**
|
|
221
225
|
* The contract resolver with the temporary AdkGeminiAdapter (ADR 0060): a
|
|
222
|
-
* Gemini id gets
|
|
223
|
-
* GEMINI_ADAPTER=
|
|
224
|
-
*
|
|
225
|
-
* `melchizedek-agents/model`
|
|
226
|
+
* Gemini id gets the engine's GeminiAdapter (the default since 0.20.0, ADR
|
|
227
|
+
* 0100), or AdkGeminiAdapter when GEMINI_ADAPTER=adk or `{ gemini: 'adk' }`
|
|
228
|
+
* asks for it, for one release, which needs @google/adk. The ADK-free
|
|
229
|
+
* resolver in lib/models/adapterResolver.ts, which `melchizedek-agents/model`
|
|
230
|
+
* exports, refuses `adk` (ADR 0068).
|
|
226
231
|
*/
|
|
227
232
|
const WITH_ADK_GEMINI = adapterResolver((r) => new AdkGeminiAdapter(r));
|
|
228
233
|
/**
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* cycle. registry.ts re-exports it, so `TracedGemini` imports from there keep
|
|
12
12
|
* working.
|
|
13
13
|
*/
|
|
14
|
-
import { Gemini } from '
|
|
14
|
+
import { Gemini } from '../adkPeer.ts';
|
|
15
15
|
import type { GeminiParams, LlmRequest, LlmResponse } from '@google/adk';
|
|
16
16
|
import type { ProviderEndpoint } from './endpoints.ts';
|
|
17
17
|
export declare class TracedGemini extends Gemini {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* cycle. registry.ts re-exports it, so `TracedGemini` imports from there keep
|
|
12
12
|
* working.
|
|
13
13
|
*/
|
|
14
|
-
import { Gemini } from '
|
|
14
|
+
import { Gemini } from '../adkPeer.js';
|
|
15
15
|
import { endpointFromEnv, platformModel } from './endpoints.js';
|
|
16
16
|
import { llmRequestToModelRequest } from './genaiMapping.js';
|
|
17
17
|
import { errorStatus, retryUntilFirstYield } from './retry.js';
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* This module loads ADK at run time, so it is not one of the engine's leaf
|
|
32
32
|
* modules (tests/events.test.ts names those).
|
|
33
33
|
*/
|
|
34
|
-
import { BaseSessionService } from '
|
|
34
|
+
import { BaseSessionService } from '../adkPeer.ts';
|
|
35
35
|
import type { CreateSessionRequest as AdkCreateSessionRequest, DeleteSessionRequest as AdkDeleteSessionRequest, Event as AdkEvent, GetSessionRequest as AdkGetSessionRequest, ListSessionsRequest as AdkListSessionsRequest, ListSessionsResponse as AdkListSessionsResponse, Session as AdkSession } from '@google/adk';
|
|
36
36
|
import type { TurnEvent } from './events.ts';
|
|
37
37
|
import type { CreateSessionRequest, GetSessionOptions, ListSessionsRequest, ListSessionsResult, Session, SessionKey, SessionService } from './sessions.ts';
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* This module loads ADK at run time, so it is not one of the engine's leaf
|
|
32
32
|
* modules (tests/events.test.ts names those).
|
|
33
33
|
*/
|
|
34
|
-
import { BaseSessionService } from '
|
|
34
|
+
import { BaseSessionService } from '../adkPeer.js';
|
|
35
35
|
import { applyEvent, listPage, listWindow, selectEvents, withoutTempKeys } from './sessions.js';
|
|
36
36
|
/** Every method the engine's interface names. */
|
|
37
37
|
export function isSessionService(value) {
|
|
@@ -29,6 +29,11 @@ export interface PendingApproval {
|
|
|
29
29
|
* The approval request still waiting for an answer, or undefined. A request
|
|
30
30
|
* the user moved on from (a new text message after it) is not pending: its
|
|
31
31
|
* call never runs.
|
|
32
|
+
*
|
|
33
|
+
* In a workflow (ADR 0098) the walk stores each node's input as a user text
|
|
34
|
+
* turn, so a sibling node's input may follow a gated node's request. The
|
|
35
|
+
* walk's pause record, stored last, names every interrupt it left open: a
|
|
36
|
+
* request it names is pending whatever node turns came after it.
|
|
32
37
|
*/
|
|
33
38
|
export declare function pendingApproval(events: readonly Event[]): PendingApproval | undefined;
|
|
34
39
|
/** Index of the user message that started the turn holding request `id` (its events are replayed raw on resume). */
|
|
@@ -4,15 +4,53 @@ const partsOf = (e) => (e.content?.parts ?? []);
|
|
|
4
4
|
function hasUserText(e) {
|
|
5
5
|
return e.author === 'user' && partsOf(e).some((p) => typeof p.text === 'string' && p.text.trim() && !p.thought);
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* A workflow's pause record (lib/workflow/pause.ts workflowPauseEvent, ADK's
|
|
9
|
+
* recordInputForResume): no content, every interrupt the walk left open in
|
|
10
|
+
* `longRunningToolIds`, at the workflow's own path. Its ids, else undefined.
|
|
11
|
+
*/
|
|
12
|
+
function workflowPauseIds(e) {
|
|
13
|
+
if (e.author === 'user' || partsOf(e).length > 0)
|
|
14
|
+
return undefined;
|
|
15
|
+
const path = e.nodeInfo?.path;
|
|
16
|
+
if (typeof path !== 'string' || !path || path.includes('.'))
|
|
17
|
+
return undefined;
|
|
18
|
+
return e.longRunningToolIds?.length ? [...e.longRunningToolIds] : undefined;
|
|
19
|
+
}
|
|
20
|
+
const requestOf = (e, call) => {
|
|
21
|
+
const original = call.args?.originalFunctionCall ?? {};
|
|
22
|
+
return {
|
|
23
|
+
id: call.id,
|
|
24
|
+
agent: e.author ?? '',
|
|
25
|
+
tool: String(original.name ?? ''),
|
|
26
|
+
args: (original.args ?? {}),
|
|
27
|
+
...(original.id ? { callId: String(original.id) } : {}),
|
|
28
|
+
};
|
|
29
|
+
};
|
|
7
30
|
/**
|
|
8
31
|
* The approval request still waiting for an answer, or undefined. A request
|
|
9
32
|
* the user moved on from (a new text message after it) is not pending: its
|
|
10
33
|
* call never runs.
|
|
34
|
+
*
|
|
35
|
+
* In a workflow (ADR 0098) the walk stores each node's input as a user text
|
|
36
|
+
* turn, so a sibling node's input may follow a gated node's request. The
|
|
37
|
+
* walk's pause record, stored last, names every interrupt it left open: a
|
|
38
|
+
* request it names is pending whatever node turns came after it.
|
|
11
39
|
*/
|
|
12
40
|
export function pendingApproval(events) {
|
|
13
41
|
const answered = new Set();
|
|
14
42
|
for (let i = events.length - 1; i >= 0; i--) {
|
|
15
43
|
const e = events[i];
|
|
44
|
+
const paused = workflowPauseIds(e);
|
|
45
|
+
if (paused) {
|
|
46
|
+
const open = new Set(paused.filter((id) => !answered.has(id)));
|
|
47
|
+
for (let j = i - 1; j >= 0 && open.size > 0; j--) {
|
|
48
|
+
const request = partsOf(events[j]).find((p) => p.functionCall?.name === APPROVAL_REQUEST && open.has(p.functionCall.id));
|
|
49
|
+
if (request)
|
|
50
|
+
return requestOf(events[j], request.functionCall);
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
16
54
|
if (hasUserText(e))
|
|
17
55
|
return undefined;
|
|
18
56
|
for (const p of partsOf(e)) {
|
|
@@ -23,14 +61,7 @@ export function pendingApproval(events) {
|
|
|
23
61
|
const call = p.functionCall;
|
|
24
62
|
if (call?.name !== APPROVAL_REQUEST || !call.id || answered.has(call.id))
|
|
25
63
|
continue;
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
id: call.id,
|
|
29
|
-
agent: e.author ?? '',
|
|
30
|
-
tool: String(original.name ?? ''),
|
|
31
|
-
args: (original.args ?? {}),
|
|
32
|
-
...(original.id ? { callId: String(original.id) } : {}),
|
|
33
|
-
};
|
|
64
|
+
return requestOf(e, call);
|
|
34
65
|
}
|
|
35
66
|
}
|
|
36
67
|
return undefined;
|
|
@@ -46,7 +46,9 @@ export declare function consentFrom(author: string | undefined, call: {
|
|
|
46
46
|
/**
|
|
47
47
|
* The consent request still waiting in a session, or undefined. One that is
|
|
48
48
|
* answered (a function response with its id), or that the person moved past
|
|
49
|
-
* with a text message, is not pending.
|
|
49
|
+
* with a text message, is not pending. Only an agent asks: a request in an
|
|
50
|
+
* event the user authored is none, so a forged request never makes the next
|
|
51
|
+
* message a grant (as pendingQuestion reads ask_user).
|
|
50
52
|
*/
|
|
51
53
|
export declare function pendingConsent(events: readonly Event[]): PendingConsent | undefined;
|
|
52
54
|
/**
|
|
@@ -27,7 +27,9 @@ export function consentFrom(author, call) {
|
|
|
27
27
|
/**
|
|
28
28
|
* The consent request still waiting in a session, or undefined. One that is
|
|
29
29
|
* answered (a function response with its id), or that the person moved past
|
|
30
|
-
* with a text message, is not pending.
|
|
30
|
+
* with a text message, is not pending. Only an agent asks: a request in an
|
|
31
|
+
* event the user authored is none, so a forged request never makes the next
|
|
32
|
+
* message a grant (as pendingQuestion reads ask_user).
|
|
31
33
|
*/
|
|
32
34
|
export function pendingConsent(events) {
|
|
33
35
|
const answered = new Set();
|
|
@@ -39,6 +41,9 @@ export function pendingConsent(events) {
|
|
|
39
41
|
if (p.functionResponse?.name === CREDENTIAL_REQUEST && p.functionResponse.id)
|
|
40
42
|
answered.add(p.functionResponse.id);
|
|
41
43
|
}
|
|
44
|
+
// Only an agent asks: a credential request in an event the user authored is none, as pendingQuestion reads ask_user (WS5-5).
|
|
45
|
+
if (e.author === 'user')
|
|
46
|
+
continue;
|
|
42
47
|
for (const p of partsOf(e)) {
|
|
43
48
|
const call = p.functionCall;
|
|
44
49
|
if (call?.name !== CREDENTIAL_REQUEST || !call.id || answered.has(call.id))
|
|
@@ -36,7 +36,11 @@
|
|
|
36
36
|
* - a long-running tool (ask_user) that returns nothing answers
|
|
37
37
|
* nothing; its actions, when it set any, make an event of their own;
|
|
38
38
|
* - a result that is not an object is wrapped `{ result }`, an array
|
|
39
|
-
* `{ results }`, as ADK wraps them
|
|
39
|
+
* `{ results }`, as ADK wraps them;
|
|
40
|
+
* - a result nested deeper than MAX_VALUE_DEPTH levels answers
|
|
41
|
+
* `{ error: TOO_DEEP_RESULT }` instead: every later reader of the
|
|
42
|
+
* session would overflow its stack on it (lib/runtime/valueDepth.ts,
|
|
43
|
+
* ADR 0101). ADK keeps it.
|
|
40
44
|
* One call's response is stored as its own event; several are merged
|
|
41
45
|
* into one, parts in call order and actions merged (ADK's
|
|
42
46
|
* mergeParallelFunctionResponseEvents). ADK runs the calls one after
|
|
@@ -189,6 +193,8 @@ export interface AgentLoopEnd {
|
|
|
189
193
|
* when it does not validate).
|
|
190
194
|
*/
|
|
191
195
|
export declare function saveOutput(agent: Pick<NativeAgent, 'name' | 'outputKey' | 'outputSchema'>, event: TurnEvent): void;
|
|
196
|
+
/** What a tool's result becomes when it nests past MAX_VALUE_DEPTH (ADR 0101). */
|
|
197
|
+
export declare const TOO_DEEP_RESULT: (toolName: string) => string;
|
|
192
198
|
/**
|
|
193
199
|
* Runs `agent` on the session in `ctx` until its answer is final, yielding
|
|
194
200
|
* every event in order: partials as they arrive (never stored), then each
|