melchizedek-agents 0.18.0 → 0.19.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/.env.example +12 -0
- package/CHANGELOG.md +825 -0
- package/DOCUMENTATION.md +217 -59
- package/README.md +42 -1
- package/config/agents/examples/harness.yaml +3 -1
- package/config/agents/examples/model_zoo.yaml +10 -9
- package/config/agents/syndicateSchema.yaml +50 -16
- package/config/agents/templates/account_memory.yaml +2 -6
- package/config/agents/templates/case_desk.yaml +3 -9
- package/config/agents/templates/draft_review.yaml +3 -9
- package/config/agents/templates/intake_extractor.yaml +1 -3
- package/config/agents/templates/research_brief.yaml +3 -9
- package/config/agents/templates/research_desk.yaml +3 -9
- package/config/agents/templates/review_panel.yaml +4 -12
- package/config/agents/templates/support_triage.yaml +4 -12
- package/config/agents/templates/systems_operator.yaml +2 -6
- package/db/hardening.sql +7 -1
- package/db/migrations/0013_tool_credentials.sql +260 -0
- package/dist/lib/a2a/app.d.ts +70 -6
- package/dist/lib/a2a/app.js +107 -2
- package/dist/lib/a2a/executor.d.ts +20 -3
- package/dist/lib/a2a/executor.js +66 -7
- package/dist/lib/a2a/remoteAgent.d.ts +24 -9
- package/dist/lib/a2a/remoteAgent.js +31 -14
- package/dist/lib/compile.d.ts +121 -30
- package/dist/lib/compile.js +137 -124
- package/dist/lib/compileAdk.d.ts +29 -0
- package/dist/lib/compileAdk.js +132 -0
- package/dist/lib/compileNative.d.ts +85 -0
- package/dist/lib/compileNative.js +222 -0
- package/dist/lib/config.d.ts +6 -5
- package/dist/lib/config.js +6 -5
- package/dist/lib/doctor.js +1 -0
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/index.js +2 -1
- package/dist/lib/loadSyndicate.d.ts +18 -0
- package/dist/lib/memory/erase.d.ts +5 -3
- package/dist/lib/memory/erase.js +5 -2
- package/dist/lib/memory/namespace.d.ts +8 -1
- package/dist/lib/memory/namespace.js +12 -6
- package/dist/lib/memory/providers.js +2 -1
- package/dist/lib/memory/supabaseMemoryService.d.ts +37 -3
- package/dist/lib/memory/supabaseMemoryService.js +42 -2
- package/dist/lib/model.d.ts +47 -0
- package/dist/lib/model.js +37 -0
- package/dist/lib/models/adapterResolver.d.ts +113 -0
- package/dist/lib/models/adapterResolver.js +136 -0
- package/dist/lib/models/adkGeminiAdapter.d.ts +90 -0
- package/dist/lib/models/adkGeminiAdapter.js +367 -0
- package/dist/lib/models/adkShim.d.ts +111 -0
- package/dist/lib/models/adkShim.js +136 -0
- package/dist/lib/models/capabilities.d.ts +3 -0
- package/dist/lib/models/capabilities.js +20 -13
- package/dist/lib/models/chatCompletionsAdapter.d.ts +279 -0
- package/dist/lib/models/chatCompletionsAdapter.js +854 -0
- package/dist/lib/models/circuitBreaker.d.ts +42 -0
- package/dist/lib/models/circuitBreaker.js +70 -0
- package/dist/lib/models/claudeAdapter.d.ts +103 -0
- package/dist/lib/models/claudeAdapter.js +669 -0
- package/dist/lib/models/claudeLlm.d.ts +39 -62
- package/dist/lib/models/claudeLlm.js +44 -349
- package/dist/lib/models/claudeModels.d.ts +127 -0
- package/dist/lib/models/claudeModels.js +237 -0
- package/dist/lib/models/contract.d.ts +395 -0
- package/dist/lib/models/contract.js +39 -0
- package/dist/lib/models/endpoints.js +2 -1
- package/dist/lib/models/errorResponse.d.ts +50 -0
- package/dist/lib/models/errorResponse.js +48 -0
- package/dist/lib/models/fallback.d.ts +17 -10
- package/dist/lib/models/fallback.js +53 -42
- package/dist/lib/models/fallbackAdapter.d.ts +55 -0
- package/dist/lib/models/fallbackAdapter.js +62 -0
- package/dist/lib/models/gateway.js +2 -1
- package/dist/lib/models/gatewayAdapter.d.ts +51 -0
- package/dist/lib/models/gatewayAdapter.js +81 -0
- package/dist/lib/models/gatewayLlm.d.ts +12 -33
- package/dist/lib/models/gatewayLlm.js +14 -75
- package/dist/lib/models/geminiAdapter.d.ts +123 -0
- package/dist/lib/models/geminiAdapter.js +831 -0
- package/dist/lib/models/geminiState.d.ts +25 -0
- package/dist/lib/models/geminiState.js +25 -0
- package/dist/lib/models/genaiMapping.d.ts +263 -0
- package/dist/lib/models/genaiMapping.js +862 -0
- package/dist/lib/models/gptAdapter.d.ts +240 -0
- package/dist/lib/models/gptAdapter.js +804 -0
- package/dist/lib/models/gptLlm.d.ts +63 -123
- package/dist/lib/models/gptLlm.js +88 -602
- package/dist/lib/models/grokAdapter.d.ts +86 -0
- package/dist/lib/models/grokAdapter.js +142 -0
- package/dist/lib/models/grokLlm.d.ts +22 -45
- package/dist/lib/models/grokLlm.js +22 -67
- package/dist/lib/models/kimiAdapter.d.ts +157 -0
- package/dist/lib/models/kimiAdapter.js +203 -0
- package/dist/lib/models/kimiLlm.d.ts +15 -107
- package/dist/lib/models/kimiLlm.js +17 -153
- package/dist/lib/models/ollamaAdapter.d.ts +125 -0
- package/dist/lib/models/ollamaAdapter.js +155 -0
- package/dist/lib/models/ollamaLlm.d.ts +11 -107
- package/dist/lib/models/ollamaLlm.js +13 -151
- package/dist/lib/models/openAiCompatibleLlm.d.ts +73 -216
- package/dist/lib/models/openAiCompatibleLlm.js +109 -671
- package/dist/lib/models/providerState.d.ts +63 -0
- package/dist/lib/models/providerState.js +61 -0
- package/dist/lib/models/reasoning.d.ts +26 -0
- package/dist/lib/models/reasoning.js +59 -0
- package/dist/lib/models/registry.d.ts +58 -35
- package/dist/lib/models/registry.js +89 -118
- package/dist/lib/models/retry.d.ts +2 -1
- package/dist/lib/models/retry.js +3 -2
- package/dist/lib/models/schemaNormalize.d.ts +98 -0
- package/dist/lib/models/schemaNormalize.js +321 -1
- package/dist/lib/models/tracedGemini.d.ts +41 -0
- package/dist/lib/models/tracedGemini.js +98 -0
- package/dist/lib/models/urls.d.ts +11 -0
- package/dist/lib/models/urls.js +16 -0
- package/dist/lib/net/redirects.d.ts +21 -2
- package/dist/lib/net/redirects.js +11 -34
- package/dist/lib/observability/audit.d.ts +5 -1
- package/dist/lib/observability/lineage.d.ts +14 -0
- package/dist/lib/observability/lineage.js +33 -0
- package/dist/lib/observability/supabaseSpanExporter.d.ts +10 -4
- package/dist/lib/observability/supabaseSpanExporter.js +17 -9
- package/dist/lib/observability/tracer.d.ts +26 -8
- package/dist/lib/observability/tracer.js +43 -18
- package/dist/lib/runtime/adkMemoryBridge.d.ts +46 -0
- package/dist/lib/runtime/adkMemoryBridge.js +68 -0
- package/dist/lib/runtime/adkSessionBridge.d.ts +78 -0
- package/dist/lib/runtime/adkSessionBridge.js +176 -0
- package/dist/lib/runtime/credentials.d.ts +59 -0
- package/dist/lib/runtime/credentials.js +62 -0
- package/dist/lib/runtime/events.d.ts +229 -0
- package/dist/lib/runtime/events.js +274 -0
- package/dist/lib/runtime/logging.d.ts +32 -0
- package/dist/lib/runtime/logging.js +55 -0
- package/dist/lib/runtime/memoryService.d.ts +72 -0
- package/dist/lib/runtime/memoryService.js +25 -0
- package/dist/lib/runtime/native/agentLoop.d.ts +203 -0
- package/dist/lib/runtime/native/agentLoop.js +687 -0
- package/dist/lib/runtime/native/compaction.d.ts +103 -0
- package/dist/lib/runtime/native/compaction.js +191 -0
- package/dist/lib/runtime/native/delegate.d.ts +98 -0
- package/dist/lib/runtime/native/delegate.js +173 -0
- package/dist/lib/runtime/native/history.d.ts +83 -0
- package/dist/lib/runtime/native/history.js +312 -0
- package/dist/lib/runtime/native/interrupts.d.ts +126 -0
- package/dist/lib/runtime/native/interrupts.js +291 -0
- package/dist/lib/runtime/native/request.d.ts +215 -0
- package/dist/lib/runtime/native/request.js +585 -0
- package/dist/lib/runtime/native/selfCorrection.d.ts +106 -0
- package/dist/lib/runtime/native/selfCorrection.js +253 -0
- package/dist/lib/runtime/native/step.d.ts +148 -0
- package/dist/lib/runtime/native/step.js +239 -0
- package/dist/lib/runtime/native/taskMode.d.ts +64 -0
- package/dist/lib/runtime/native/taskMode.js +126 -0
- package/dist/lib/runtime/native/telemetry.d.ts +75 -0
- package/dist/lib/runtime/native/telemetry.js +299 -0
- package/dist/lib/runtime/native/tempState.d.ts +31 -0
- package/dist/lib/runtime/native/tempState.js +56 -0
- package/dist/lib/runtime/nativeTurn.d.ts +86 -0
- package/dist/lib/runtime/nativeTurn.js +107 -0
- package/dist/lib/runtime/questions.d.ts +29 -7
- package/dist/lib/runtime/questions.js +47 -32
- package/dist/lib/runtime/runtimeFlag.d.ts +30 -0
- package/dist/lib/runtime/runtimeFlag.js +50 -0
- package/dist/lib/runtime/sessions.d.ts +166 -0
- package/dist/lib/runtime/sessions.js +201 -0
- package/dist/lib/runtime/syndicateTurn.d.ts +41 -5
- package/dist/lib/runtime/syndicateTurn.js +202 -32
- package/dist/lib/session/supabaseSessionService.d.ts +64 -17
- package/dist/lib/session/supabaseSessionService.js +148 -105
- package/dist/lib/session/transcript.d.ts +68 -22
- package/dist/lib/session/transcript.js +102 -28
- package/dist/lib/skills.js +33 -7
- package/dist/lib/storage/postgres/credentialStore.d.ts +20 -0
- package/dist/lib/storage/postgres/credentialStore.js +82 -0
- package/dist/lib/storage/postgres/index.d.ts +12 -0
- package/dist/lib/storage/postgres/index.js +6 -1
- package/dist/lib/storage/postgres/sessionService.d.ts +43 -15
- package/dist/lib/storage/postgres/sessionService.js +128 -66
- package/dist/lib/syndicateSchema.d.ts +47 -0
- package/dist/lib/syndicateSchema.js +72 -3
- package/dist/lib/toolRegistry.d.ts +15 -2
- package/dist/lib/toolRegistry.js +33 -17
- package/dist/lib/tools/adkTool.d.ts +81 -0
- package/dist/lib/tools/adkTool.js +268 -0
- package/dist/lib/tools/auth.d.ts +118 -0
- package/dist/lib/tools/auth.js +89 -0
- package/dist/lib/tools/collectionsSearchTool.d.ts +7 -6
- package/dist/lib/tools/collectionsSearchTool.js +11 -26
- package/dist/lib/tools/credentialCipher.d.ts +58 -0
- package/dist/lib/tools/credentialCipher.js +116 -0
- package/dist/lib/tools/credentialStore.d.ts +77 -0
- package/dist/lib/tools/credentialStore.js +246 -0
- package/dist/lib/tools/examples.d.ts +43 -0
- package/dist/lib/tools/examples.js +62 -0
- package/dist/lib/tools/generateImageTool.d.ts +15 -6
- package/dist/lib/tools/generateImageTool.js +19 -29
- package/dist/lib/tools/inspectImageTool.d.ts +9 -6
- package/dist/lib/tools/inspectImageTool.js +13 -17
- package/dist/lib/tools/mcpToolFactory.d.ts +42 -1
- package/dist/lib/tools/mcpToolFactory.js +46 -47
- package/dist/lib/tools/memoryTools.d.ts +61 -0
- package/dist/lib/tools/memoryTools.js +119 -0
- package/dist/lib/tools/nativeTools.d.ts +38 -0
- package/dist/lib/tools/nativeTools.js +43 -0
- package/dist/lib/tools/oauthConsent.d.ts +181 -0
- package/dist/lib/tools/oauthConsent.js +330 -0
- package/dist/lib/tools/openapi/call.d.ts +108 -0
- package/dist/lib/tools/openapi/call.js +295 -0
- package/dist/lib/tools/openapi/parse.d.ts +147 -0
- package/dist/lib/tools/openapi/parse.js +570 -0
- package/dist/lib/tools/openapiTools.d.ts +25 -17
- package/dist/lib/tools/openapiTools.js +124 -121
- package/dist/lib/tools/scienceTools.d.ts +14 -14
- package/dist/lib/tools/skillToolset.d.ts +58 -87
- package/dist/lib/tools/skillToolset.js +61 -142
- package/dist/lib/tools/skills/env.d.ts +58 -0
- package/dist/lib/tools/skills/env.js +165 -0
- package/dist/lib/tools/skills/executor.d.ts +114 -0
- package/dist/lib/tools/skills/executor.js +331 -0
- package/dist/lib/tools/skills/frontmatter.d.ts +79 -0
- package/dist/lib/tools/skills/frontmatter.js +215 -0
- package/dist/lib/tools/skills/loader.d.ts +91 -0
- package/dist/lib/tools/skills/loader.js +257 -0
- package/dist/lib/tools/skills/tools.d.ts +187 -0
- package/dist/lib/tools/skills/tools.js +386 -0
- package/dist/lib/tools/taskTools.d.ts +15 -15
- package/dist/lib/tools/tool.d.ts +354 -0
- package/dist/lib/tools/tool.js +304 -0
- package/dist/lib/tools/toolContract.d.ts +89 -33
- package/dist/lib/tools/toolContract.js +104 -82
- package/dist/lib/tools/urlContextTool.d.ts +3 -0
- package/dist/lib/tools/urlContextTool.js +5 -1
- package/dist/lib/tools/webExtractTool.d.ts +2 -2
- package/dist/lib/tools/webExtractTool.js +2 -1
- package/dist/lib/tools/webSearchTool.d.ts +6 -9
- package/dist/lib/tools/webSearchTool.js +14 -59
- package/dist/lib/tools/wikiTools.d.ts +19 -19
- package/dist/lib/tools/wikiTools.js +13 -9
- package/dist/lib/tools/xApiSearchTool.d.ts +2 -2
- package/dist/lib/tools/xApiSearchTool.js +2 -1
- package/dist/lib/tools/xSearchTool.d.ts +7 -9
- package/dist/lib/tools/xSearchTool.js +11 -62
- package/dist/lib/tools/xaiSearchParams.d.ts +41 -0
- package/dist/lib/tools/xaiSearchParams.js +126 -0
- package/dist/lib/wiki/agentRun.d.ts +12 -0
- package/dist/lib/wiki/agentRun.js +72 -34
- package/dist/lib/wiki/entities.d.ts +12 -0
- package/dist/lib/wiki/entities.js +45 -3
- package/dist/lib/workflow/agentNode.d.ts +136 -0
- package/dist/lib/workflow/agentNode.js +274 -0
- package/dist/lib/workflow/graph.d.ts +177 -0
- package/dist/lib/workflow/graph.js +458 -0
- package/dist/lib/workflow/nodeEvents.d.ts +50 -0
- package/dist/lib/workflow/nodeEvents.js +101 -0
- package/dist/lib/workflow/pause.d.ts +122 -0
- package/dist/lib/workflow/pause.js +180 -0
- package/dist/lib/workflow/resume.d.ts +165 -0
- package/dist/lib/workflow/resume.js +440 -0
- package/dist/lib/workflow/route.d.ts +58 -0
- package/dist/lib/workflow/route.js +69 -0
- package/dist/lib/workflow/scheduler.d.ts +415 -0
- package/dist/lib/workflow/scheduler.js +743 -0
- package/dist/lib/workflow/toolNode.d.ts +127 -0
- package/dist/lib/workflow/toolNode.js +236 -0
- package/dist/lib/workflow/turn.d.ts +118 -0
- package/dist/lib/workflow/turn.js +216 -0
- package/dist/lib/workflowConfig.d.ts +3 -2
- package/dist/lib/workflowConfig.js +3 -12
- package/dist/scripts/a2a_server.js +4 -3
- package/dist/scripts/assistant_worker.d.ts +2 -1
- package/dist/scripts/assistant_worker.js +9 -4
- package/dist/scripts/syndicate_chat.js +19 -10
- package/package.json +4 -1
- package/skills/briefs/melchizedek-author.md +3 -2
- package/skills/briefs/melchizedek-models.md +13 -9
- package/skills/briefs/melchizedek.md +3 -3
- package/skills/melchizedek/SKILL.md +2 -1
- package/skills/melchizedek-author/SKILL.md +2 -1
- package/skills/melchizedek-author/assets/minimal.yaml +2 -0
- package/skills/melchizedek-models/SKILL.md +23 -6
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/runtime/native/interrupts.ts — approvals on the native loop: the
|
|
3
|
+
* answer to an `adk_request_confirmation` call runs or refuses the pinned
|
|
4
|
+
* call before the next model step (WS2-7a, ADR 0028, ADR 0077).
|
|
5
|
+
*
|
|
6
|
+
* WHY this file exists:
|
|
7
|
+
* A tool that requires approval does not run when called. The loop
|
|
8
|
+
* (agentLoop.ts) stores ADK's `adk_request_confirmation` call in place of
|
|
9
|
+
* the response, pinning the original call and its arguments, and the run
|
|
10
|
+
* ends paused. The person's answer arrives as the next user message: a
|
|
11
|
+
* function response to that call carrying `{ confirmed }`. On the ADK
|
|
12
|
+
* runtime, LlmAgent's request-confirmation processor reads it before every
|
|
13
|
+
* model step and runs the pinned call with the confirmation. This file is
|
|
14
|
+
* that processor, case for case, so an approval opened on either runtime
|
|
15
|
+
* resumes on the other and both store the same events.
|
|
16
|
+
*
|
|
17
|
+
* BEFORE EACH STEP, AS ADK'S PROCESSOR RUNS IT:
|
|
18
|
+
* 1. The answers: the function responses named `adk_request_confirmation`
|
|
19
|
+
* in the latest user event (events on another branch left out), each
|
|
20
|
+
* read as `{ confirmed, hint, payload }`, or as JSON under `response`.
|
|
21
|
+
* None: nothing happens, and the step goes on as usual.
|
|
22
|
+
* 2. The gates they answer: every `adk_request_confirmation` call whose id
|
|
23
|
+
* an answer names. A request authored by the user is refused
|
|
24
|
+
* (`untrusted_request`); one authored by another agent is skipped; one
|
|
25
|
+
* whose pinned call has no id or name is refused (`malformed_request`);
|
|
26
|
+
* one this agent has already answered the pinned call after is skipped,
|
|
27
|
+
* so a later step never runs the call again.
|
|
28
|
+
* 3. The binding. The pinned call must be one this agent made, by id
|
|
29
|
+
* (`unknown_original_call`); its tool must be the agent's
|
|
30
|
+
* (`unregistered_tool`); the name and the arguments must equal the
|
|
31
|
+
* call's as the model made it (`tool_name_mismatch`,
|
|
32
|
+
* `arguments_mismatch`); and the tool must require approval, or have
|
|
33
|
+
* asked for it (`confirmation_not_required`). A refusal throws ADK's
|
|
34
|
+
* IntentMismatchError text and nothing runs.
|
|
35
|
+
* 4. The bound calls run through the loop's own call path with the
|
|
36
|
+
* confirmation in their context: an approved call runs its tool, a
|
|
37
|
+
* refused one answers ADK's refusal. Their response is stored as its
|
|
38
|
+
* own event before the step builds its request, so the model reads it.
|
|
39
|
+
*
|
|
40
|
+
* Not here: a plain-text "yes" as an answer (ADK's plainTextToolConfirmation,
|
|
41
|
+
* which no surface turns on), and answers delivered by a remote peer (ADK's
|
|
42
|
+
* remoteDelivered, which no surface sets).
|
|
43
|
+
*
|
|
44
|
+
* QUESTIONS (ask_user, WS2-7b, ADR 0079) need no processor here. ADK runs its
|
|
45
|
+
* request-input processor (REQUEST_INPUT_LLM_REQUEST_PROCESSOR) next, before
|
|
46
|
+
* compaction, but it only re-runs a node tool (a workflow run as a tool) that
|
|
47
|
+
* paused on an `adk_request_input` call; for an agent that lists no node tool
|
|
48
|
+
* it returns before doing anything, and no native agent lists one (native
|
|
49
|
+
* refuses workflows). An `ask_user` call is an ordinary long-running call:
|
|
50
|
+
* the turn runner stores the person's next message as its function response
|
|
51
|
+
* (lib/runtime/questions.ts questionAnswerPart), and the step reads the call
|
|
52
|
+
* and the answer side by side from the history (history.ts), as ADK's
|
|
53
|
+
* content processor does. When workflows run natively (WS4), the node-tool
|
|
54
|
+
* resume is ported beside approvedCalls, in the same place in the order.
|
|
55
|
+
*
|
|
56
|
+
* CREDENTIALS (OAuth consent, WS6-3b, ADR 0085) run first, as ADK runs its
|
|
57
|
+
* auth preprocessor (AUTH_PREPROCESSOR) before request-confirmation.
|
|
58
|
+
* grantedCalls is that preprocessor, check for check, with one difference
|
|
59
|
+
* in what the answer carries:
|
|
60
|
+
* 1. The answers: the function responses named `adk_request_credential`
|
|
61
|
+
* in the last event with content, which must be the user's. None:
|
|
62
|
+
* nothing happens.
|
|
63
|
+
* 2. The requests they answer: `adk_request_credential` calls this agent
|
|
64
|
+
* made, by id. An answer naming no such request is ignored, as ADK
|
|
65
|
+
* ignores it.
|
|
66
|
+
* 3. The binding. ADK's answer carries the authorization response (a code
|
|
67
|
+
* or the redirect URL), which ADK exchanges in-process with the client
|
|
68
|
+
* secret its request event stored. Here the server's callback route has
|
|
69
|
+
* already exchanged the code and stored the grant
|
|
70
|
+
* (lib/tools/oauthConsent.ts), so the answer carries no credential:
|
|
71
|
+
* `{ credentialKey, granted: true }`, bound to the request by its
|
|
72
|
+
* credentialKey. An answer that does not bind is ignored.
|
|
73
|
+
* 4. The paused calls the bound requests name (`function_call_id`, ADK's
|
|
74
|
+
* toolset requests aside) run again, from the latest event that made
|
|
75
|
+
* them, through the loop's own call path. The tool now reads its grant
|
|
76
|
+
* through ctx.accessToken. The response is stored before the step
|
|
77
|
+
* builds its request. A later step finds the agent's own events last,
|
|
78
|
+
* so the call runs once.
|
|
79
|
+
*
|
|
80
|
+
* ADK stays out of this file: an ADK tool an agent still lists is asked
|
|
81
|
+
* whether it gates through its own checkRequireConfirmation, by shape.
|
|
82
|
+
*/
|
|
83
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
84
|
+
import { nativeToolOf } from '../../models/schemaNormalize.js';
|
|
85
|
+
import { instructionToolOf, isTool, toolOf } from '../../tools/tool.js';
|
|
86
|
+
import { getFunctionCalls, getFunctionResponses } from '../events.js';
|
|
87
|
+
import { REQUEST_CONFIRMATION_CALL, REQUEST_CREDENTIAL_CALL, isSegmentPrefix } from './history.js';
|
|
88
|
+
import { isToolset } from './request.js';
|
|
89
|
+
/** A confirmation that does not bind to its pinned call: ADK's IntentMismatchError, by name and text. */
|
|
90
|
+
export class IntentMismatchError extends Error {
|
|
91
|
+
reason;
|
|
92
|
+
functionCallId;
|
|
93
|
+
constructor(reason, functionCallId) {
|
|
94
|
+
super(`Tool confirmation rejected${functionCallId ? ` for function call '${functionCallId}'` : ''}: ${reason}.`);
|
|
95
|
+
this.name = 'IntentMismatchError';
|
|
96
|
+
this.reason = reason;
|
|
97
|
+
if (functionCallId !== undefined)
|
|
98
|
+
this.functionCallId = functionCallId;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const isRecord = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
102
|
+
/** ADK's parseToolConfirmation: `{ confirmed, hint, payload }`, or the same as JSON under `response`. */
|
|
103
|
+
function parseConfirmation(response) {
|
|
104
|
+
const keys = Object.keys(response);
|
|
105
|
+
const fields = (keys.length === 1 && keys[0] === 'response' ? JSON.parse(String(response.response)) : response);
|
|
106
|
+
return { hint: typeof fields.hint === 'string' ? fields.hint : '', confirmed: fields.confirmed === true, payload: fields.payload };
|
|
107
|
+
}
|
|
108
|
+
/** Step 1: the answers in the latest user event, by the request id each names. */
|
|
109
|
+
function answersIn(events) {
|
|
110
|
+
const answers = new Map();
|
|
111
|
+
let latest;
|
|
112
|
+
for (let i = events.length - 1; i >= 0 && !latest; i--)
|
|
113
|
+
if (events[i]?.author === 'user')
|
|
114
|
+
latest = events[i];
|
|
115
|
+
if (!latest)
|
|
116
|
+
return answers;
|
|
117
|
+
for (const r of getFunctionResponses(latest)) {
|
|
118
|
+
if (r.name !== REQUEST_CONFIRMATION_CALL || !r.id || !r.response)
|
|
119
|
+
continue;
|
|
120
|
+
answers.set(r.id, parseConfirmation(r.response));
|
|
121
|
+
}
|
|
122
|
+
return answers;
|
|
123
|
+
}
|
|
124
|
+
/** The agent's callable tools by name, toolsets expanded, as ADK's canonicalTools lists them. */
|
|
125
|
+
async function toolsOf(agent, scope) {
|
|
126
|
+
const state = scope.session.state;
|
|
127
|
+
const toolsetContext = {
|
|
128
|
+
agentName: agent.name,
|
|
129
|
+
invocationId: scope.invocationId,
|
|
130
|
+
state: { get: (key) => state[key], has: (key) => Object.hasOwn(state, key) },
|
|
131
|
+
};
|
|
132
|
+
const tools = new Map();
|
|
133
|
+
for (const union of agent.tools ?? []) {
|
|
134
|
+
const expanded = isToolset(union) ? await union.getTools(toolsetContext) : [union];
|
|
135
|
+
for (const listed of expanded) {
|
|
136
|
+
if (nativeToolOf(listed) || instructionToolOf(listed))
|
|
137
|
+
continue;
|
|
138
|
+
const name = listed?.name;
|
|
139
|
+
if (typeof name === 'string')
|
|
140
|
+
tools.set(name, toolOf(listed) ?? listed);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return tools;
|
|
144
|
+
}
|
|
145
|
+
/** Whether `tool` gates the call: an own Tool's requiresApproval, an ADK tool's checkRequireConfirmation. */
|
|
146
|
+
async function gates(tool, args, context) {
|
|
147
|
+
if (isTool(tool))
|
|
148
|
+
return tool.requiresApproval === true;
|
|
149
|
+
const check = tool.checkRequireConfirmation;
|
|
150
|
+
return typeof check === 'function' ? (await check.call(tool, args, context)) === true : false;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* The pinned calls the latest user message approves or refuses, bound to
|
|
154
|
+
* the calls this agent made; undefined when it answers no open request.
|
|
155
|
+
* Throws IntentMismatchError when an answer does not bind (nothing runs).
|
|
156
|
+
* `contextFor` makes the context a tool's gate check reads.
|
|
157
|
+
*/
|
|
158
|
+
export async function approvedCalls(agent, scope, contextFor) {
|
|
159
|
+
const all = scope.session.events;
|
|
160
|
+
const events = scope.branch ? all.filter((e) => !e.branch || isSegmentPrefix(scope.branch, e.branch)) : all;
|
|
161
|
+
if (events.length === 0)
|
|
162
|
+
return undefined;
|
|
163
|
+
const answers = answersIn(events);
|
|
164
|
+
if (answers.size === 0)
|
|
165
|
+
return undefined;
|
|
166
|
+
// Step 2: the gates the answers name.
|
|
167
|
+
const candidates = [];
|
|
168
|
+
for (const [index, event] of events.entries()) {
|
|
169
|
+
for (const call of getFunctionCalls(event)) {
|
|
170
|
+
const confirmation = call.id ? answers.get(call.id) : undefined;
|
|
171
|
+
if (!confirmation || call.name !== REQUEST_CONFIRMATION_CALL)
|
|
172
|
+
continue;
|
|
173
|
+
if (event.author !== agent.name) {
|
|
174
|
+
if (event.author === 'user')
|
|
175
|
+
throw new IntentMismatchError('untrusted_request', call.id);
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
const pinned = isRecord(call.args) ? call.args.originalFunctionCall : undefined;
|
|
179
|
+
if (!isRecord(pinned))
|
|
180
|
+
continue;
|
|
181
|
+
if (!pinned.id || !pinned.name)
|
|
182
|
+
throw new IntentMismatchError('malformed_request', call.id);
|
|
183
|
+
const pinnedCall = pinned;
|
|
184
|
+
const answeredAfter = events
|
|
185
|
+
.slice(index + 1)
|
|
186
|
+
.some((e) => e.author === agent.name && getFunctionResponses(e).some((r) => r.id === pinnedCall.id));
|
|
187
|
+
if (!answeredAfter)
|
|
188
|
+
candidates.push({ pinned: pinnedCall, confirmation });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (candidates.length === 0)
|
|
192
|
+
return undefined;
|
|
193
|
+
// Step 3: each pinned call bound to the call the agent made, by id, name and arguments.
|
|
194
|
+
const tools = await toolsOf(agent, scope);
|
|
195
|
+
const made = new Map();
|
|
196
|
+
const requested = new Set();
|
|
197
|
+
for (const event of events) {
|
|
198
|
+
if (event.author !== agent.name)
|
|
199
|
+
continue;
|
|
200
|
+
for (const call of getFunctionCalls(event))
|
|
201
|
+
if (call.id && call.name !== REQUEST_CONFIRMATION_CALL)
|
|
202
|
+
made.set(call.id, call);
|
|
203
|
+
for (const id of Object.keys(event.actions?.requestedToolConfirmations ?? {}))
|
|
204
|
+
requested.add(id);
|
|
205
|
+
}
|
|
206
|
+
const bound = new Map();
|
|
207
|
+
for (const { pinned, confirmation } of candidates) {
|
|
208
|
+
const id = pinned.id;
|
|
209
|
+
const original = made.get(id);
|
|
210
|
+
if (!original)
|
|
211
|
+
throw new IntentMismatchError('unknown_original_call', id);
|
|
212
|
+
const tool = tools.get(pinned.name);
|
|
213
|
+
if (!tool)
|
|
214
|
+
throw new IntentMismatchError('unregistered_tool', id);
|
|
215
|
+
if (original.name !== pinned.name)
|
|
216
|
+
throw new IntentMismatchError('tool_name_mismatch', id);
|
|
217
|
+
if (!isDeepStrictEqual(original.args ?? {}, pinned.args ?? {}))
|
|
218
|
+
throw new IntentMismatchError('arguments_mismatch', id);
|
|
219
|
+
if (!(await gates(tool, original.args ?? {}, contextFor(id))) && !requested.has(id))
|
|
220
|
+
throw new IntentMismatchError('confirmation_not_required', id);
|
|
221
|
+
bound.set(id, { call: pinned, confirmation });
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
calls: [...bound.values()].map((b) => b.call),
|
|
225
|
+
confirmations: new Map([...bound].map(([id, b]) => [id, b.confirmation])),
|
|
226
|
+
tools,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
// ── Credentials (ADK's auth preprocessor) ────────────────────────────────────
|
|
230
|
+
/** ADK's prefix for a toolset's own credential request, which resumes no call. */
|
|
231
|
+
const TOOLSET_AUTH_CREDENTIAL_ID_PREFIX = '_adk_toolset_auth_';
|
|
232
|
+
/** Whether an answer binds to the request it names: granted, for the provider the request named. */
|
|
233
|
+
function bindsGrant(config, response) {
|
|
234
|
+
if (!isRecord(response) || response.granted !== true)
|
|
235
|
+
return false;
|
|
236
|
+
return typeof config.credentialKey === 'string' && config.credentialKey !== '' && response.credentialKey === config.credentialKey;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* The paused calls the latest user message resumes by answering this
|
|
240
|
+
* agent's credential requests; undefined when it answers none (ADK's
|
|
241
|
+
* AuthPreprocessor, the exchange left to the callback route).
|
|
242
|
+
*/
|
|
243
|
+
export async function grantedCalls(agent, scope) {
|
|
244
|
+
const events = scope.session.events;
|
|
245
|
+
if (events.length === 0)
|
|
246
|
+
return undefined;
|
|
247
|
+
let last;
|
|
248
|
+
for (let i = events.length - 1; i >= 0 && !last; i--)
|
|
249
|
+
if (events[i]?.content !== undefined)
|
|
250
|
+
last = events[i];
|
|
251
|
+
if (!last || last.author !== 'user')
|
|
252
|
+
return undefined;
|
|
253
|
+
const answers = new Map();
|
|
254
|
+
for (const r of getFunctionResponses(last))
|
|
255
|
+
if (r.name === REQUEST_CREDENTIAL_CALL && r.id)
|
|
256
|
+
answers.set(r.id, r.response);
|
|
257
|
+
if (answers.size === 0)
|
|
258
|
+
return undefined;
|
|
259
|
+
// The requests this agent made, by id.
|
|
260
|
+
const requests = new Map();
|
|
261
|
+
for (const event of events) {
|
|
262
|
+
if (event.author !== agent.name)
|
|
263
|
+
continue;
|
|
264
|
+
for (const call of getFunctionCalls(event)) {
|
|
265
|
+
if (!call.id || !answers.has(call.id) || call.name !== REQUEST_CREDENTIAL_CALL || !isRecord(call.args))
|
|
266
|
+
continue;
|
|
267
|
+
const config = call.args.auth_config ?? call.args.authConfig;
|
|
268
|
+
if (isRecord(config))
|
|
269
|
+
requests.set(call.id, { config, args: call.args });
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
const resume = new Set();
|
|
273
|
+
for (const [id, response] of answers) {
|
|
274
|
+
const request = requests.get(id);
|
|
275
|
+
if (!request || !bindsGrant(request.config, response))
|
|
276
|
+
continue;
|
|
277
|
+
const callId = request.args.function_call_id ?? request.args.functionCallId;
|
|
278
|
+
if (typeof callId === 'string' && callId && !callId.startsWith(TOOLSET_AUTH_CREDENTIAL_ID_PREFIX))
|
|
279
|
+
resume.add(callId);
|
|
280
|
+
}
|
|
281
|
+
if (resume.size === 0)
|
|
282
|
+
return undefined;
|
|
283
|
+
// As ADK: the latest event before the answer that made any of the calls, those calls only.
|
|
284
|
+
for (let i = events.length - 2; i >= 0; i--) {
|
|
285
|
+
const calls = getFunctionCalls(events[i]);
|
|
286
|
+
if (!calls.some((c) => c.id && resume.has(c.id)))
|
|
287
|
+
continue;
|
|
288
|
+
return { calls: calls.filter((c) => c.id && resume.has(c.id)), tools: await toolsOf(agent, scope) };
|
|
289
|
+
}
|
|
290
|
+
return undefined;
|
|
291
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/runtime/native/request.ts — one model request of the native loop,
|
|
3
|
+
* built from an agent and its session (ADR 0045, ADR 0066).
|
|
4
|
+
*
|
|
5
|
+
* WHY this file exists:
|
|
6
|
+
* The native runtime calls a ModelAdapter (lib/models/contract.ts) with a
|
|
7
|
+
* ModelRequest it builds itself, with no LlmRequest in between. A session
|
|
8
|
+
* moves between the runtimes and an agent must behave the same on either,
|
|
9
|
+
* so the request is the one the ADK runtime hands the same adapter for
|
|
10
|
+
* the same agent and session: what ADK's LlmAgent request processors and
|
|
11
|
+
* tools build, read through the shim's mapping (llmRequestToModelRequest,
|
|
12
|
+
* lib/models/genaiMapping.ts). tests/nativeStep.test.ts asserts that on
|
|
13
|
+
* whole syndicates.
|
|
14
|
+
*
|
|
15
|
+
* THE REQUEST, in the order ADK builds it:
|
|
16
|
+
* 1. The agent's generateContentConfig, and its output schema when it has
|
|
17
|
+
* no tools (or the model takes a schema beside tools: Gemini 2 and
|
|
18
|
+
* later on Vertex AI).
|
|
19
|
+
* 2. The system prompt, each piece joined to the last by a blank line:
|
|
20
|
+
* - the identity lines ("You are an agent. Your internal name is …"),
|
|
21
|
+
* unless the agent may transfer to no one (an output schema rules
|
|
22
|
+
* transfer out);
|
|
23
|
+
* - the root agent's globalInstruction, then the agent's instruction,
|
|
24
|
+
* each with `{state_key}` placeholders filled from session state,
|
|
25
|
+
* and, in a workflow node's run, `{input.field}` and
|
|
26
|
+
* `<input.field from Node>` filled from its workflow scope;
|
|
27
|
+
* - with an output schema beside tools on a model that cannot take
|
|
28
|
+
* both, the line asking for set_model_response;
|
|
29
|
+
* - then, at each tool's place in the agent's list, the text its
|
|
30
|
+
* `instruction(ctx)` writes: few-shot examples, preload_memory, an
|
|
31
|
+
* own Tool's note (ADR 0059, ADR 0062). The skills index is part of
|
|
32
|
+
* the instruction itself (lib/compile.ts appends it).
|
|
33
|
+
* A Tool's `contents` hook then adds to the history, after it is
|
|
34
|
+
* projected (load_skill_resource's binary file, ADR 0083).
|
|
35
|
+
* 3. The history: the session's events projected by includeContents
|
|
36
|
+
* (lib/runtime/native/history.ts), with Gemini code execution's parts
|
|
37
|
+
* as text when the agent runs code.
|
|
38
|
+
* 4. The tools, in the agent's order, a toolset expanded to its tools:
|
|
39
|
+
* each client-side tool's declaration (contractToolDeclaration), at
|
|
40
|
+
* most one per name, the later one winning; each server-side tool
|
|
41
|
+
* where the ADK runtime sends it (web_search everywhere, url_context
|
|
42
|
+
* and google_search on Gemini, x_search and collections_search on
|
|
43
|
+
* xAI); `code_execution` first among Gemini's own tools; and the
|
|
44
|
+
* set_model_response tool when (2) asked for it, then the caller's
|
|
45
|
+
* `extraTools` (self-correction's reflection tool, as ADK's plugin adds
|
|
46
|
+
* it to the toolsDict last). In `mode: task`, finish_task takes
|
|
47
|
+
* set_model_response's place and the output schema is never the
|
|
48
|
+
* response schema (lib/runtime/native/taskMode.ts).
|
|
49
|
+
* 5. Tool choice, the output schema or JSON mode, reasoning and sampling,
|
|
50
|
+
* read from the config by the mapping's own readers.
|
|
51
|
+
*
|
|
52
|
+
* WHAT IT DOES NOT DO (later tickets): resume an approval or an input
|
|
53
|
+
* request (ADK's confirmation and input processors run tools before the
|
|
54
|
+
* request; WS2-7), add transfer_to_agent
|
|
55
|
+
* (compiled syndicates never set subAgents; they delegate through subagent tools, delegate.ts),
|
|
56
|
+
* artifacts in an
|
|
57
|
+
* instruction (no runtime has an artifact service), and an ADK tool's own
|
|
58
|
+
* processLlmRequest side effects beyond its declaration (an own Tool says
|
|
59
|
+
* what it writes through `instruction`).
|
|
60
|
+
*
|
|
61
|
+
* ADK STAYS OUT OF THIS FILE'S OWN LOGIC: it reads tools by marker and by
|
|
62
|
+
* the own-tool symbols (lib/tools/tool.ts), and only lib/models/
|
|
63
|
+
* genaiMapping.ts, which stored history needs anyway (ADR 0048 item 8),
|
|
64
|
+
* names @google/*. An ADK tool or toolset an agent still carries (an
|
|
65
|
+
* AgentTool, an MCP or OpenAPI tool) is read through its declaration and
|
|
66
|
+
* `getTools`, by shape, as is the engine's own skills toolset.
|
|
67
|
+
*/
|
|
68
|
+
import type { ModelRequest } from '../../models/contract.ts';
|
|
69
|
+
import type { MemoryService } from '../memoryService.ts';
|
|
70
|
+
import type { TurnContent, TurnEvent } from '../events.ts';
|
|
71
|
+
import type { Session } from '../sessions.ts';
|
|
72
|
+
import type { Tool } from '../../tools/tool.ts';
|
|
73
|
+
import type { ContextConfig } from './compaction.ts';
|
|
74
|
+
/**
|
|
75
|
+
* One agent as the native loop runs it: the fields of a compiled agent that
|
|
76
|
+
* shape its model requests, in the YAML's own spelling. lib/compile.ts
|
|
77
|
+
* builds the same fields into ADK's LlmAgent, and lib/compileNative.ts
|
|
78
|
+
* builds this from the same AgentSpec (ADR 0073).
|
|
79
|
+
*/
|
|
80
|
+
export interface NativeAgent {
|
|
81
|
+
name: string;
|
|
82
|
+
description?: string;
|
|
83
|
+
/** The model id, as the YAML names it. */
|
|
84
|
+
model: string;
|
|
85
|
+
/**
|
|
86
|
+
* The agent's instruction. A string has `{key}` placeholders filled from
|
|
87
|
+
* session state (`{key?}` is optional); a function's result is used as it is.
|
|
88
|
+
*/
|
|
89
|
+
instruction?: string | ((ctx: InstructionContext) => string | Promise<string>);
|
|
90
|
+
/** Prepended to every request of the run's root agent (ADK's global instruction). */
|
|
91
|
+
globalInstruction?: string | ((ctx: InstructionContext) => string | Promise<string>);
|
|
92
|
+
/**
|
|
93
|
+
* In the agent's order: own Tools and defineTool contracts, InstructionTools,
|
|
94
|
+
* NativeToolMarkers, and during the dual period the ADK tools and toolsets
|
|
95
|
+
* an agent may still list (their own-tool symbols are read first).
|
|
96
|
+
*/
|
|
97
|
+
tools?: readonly unknown[];
|
|
98
|
+
/** The answer's schema, as the YAML spells it (lowercase or Gemini's dialect). */
|
|
99
|
+
outputSchema?: Record<string, unknown>;
|
|
100
|
+
/** As lib/compile.ts builds it: the YAML's config with `reasoning:` mapped in (withReasoning). */
|
|
101
|
+
generateContentConfig?: Record<string, unknown>;
|
|
102
|
+
includeContents?: 'default' | 'none';
|
|
103
|
+
disallowTransferToParent?: boolean;
|
|
104
|
+
disallowTransferToPeers?: boolean;
|
|
105
|
+
/** `code_execution: gemini`: Gemini runs the code it writes. */
|
|
106
|
+
codeExecution?: 'gemini';
|
|
107
|
+
/** `mode: task` (workflow nodes): finish_task is declared after the agent's tools and the output schema is its parameters (lib/runtime/native/taskMode.ts). */
|
|
108
|
+
mode?: 'task';
|
|
109
|
+
/** The session-state key the agent's final answer is saved under (the loop writes it, lib/runtime/native/agentLoop.ts). */
|
|
110
|
+
outputKey?: string;
|
|
111
|
+
/** `fallback_model:`: answers a provider-side failure of the agent's model (ADR 0044). The loop calls it as its own leaf adapter. */
|
|
112
|
+
fallbackModel?: string;
|
|
113
|
+
/** `context:` (ADR 0033): compact the history into a summary past a token threshold. The loop runs it before each step (compaction.ts). */
|
|
114
|
+
context?: ContextConfig;
|
|
115
|
+
}
|
|
116
|
+
/** What an instruction function reads. */
|
|
117
|
+
export interface InstructionContext {
|
|
118
|
+
readonly agentName: string;
|
|
119
|
+
readonly invocationId: string;
|
|
120
|
+
readonly state: Readonly<Record<string, unknown>>;
|
|
121
|
+
readonly userContent?: TurnContent;
|
|
122
|
+
}
|
|
123
|
+
/** Where the request is made: the run, its session, and who it is for. */
|
|
124
|
+
export interface RequestContext {
|
|
125
|
+
/** The session as it stands: the run's user event already appended. */
|
|
126
|
+
session: Session;
|
|
127
|
+
invocationId: string;
|
|
128
|
+
/** The message that started the run (the examples block reads it). */
|
|
129
|
+
userContent?: TurnContent;
|
|
130
|
+
/** The run's branch; undefined at the root. */
|
|
131
|
+
branch?: string;
|
|
132
|
+
isolationScope?: string;
|
|
133
|
+
/** The run's root agent, whose globalInstruction applies. Default: the agent itself. */
|
|
134
|
+
root?: Pick<NativeAgent, 'globalInstruction'>;
|
|
135
|
+
/** The run's memory, already namespaced: preload_memory and load_memory read it. */
|
|
136
|
+
memory?: Pick<MemoryService, 'search'>;
|
|
137
|
+
/** Stream text and thinking as partial responses. Default false. */
|
|
138
|
+
stream?: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* State laid over the session's for this request: the run's `temp:` keys,
|
|
141
|
+
* which no store keeps (lib/runtime/native/tempState.ts).
|
|
142
|
+
*/
|
|
143
|
+
stateOverlay?: Readonly<Record<string, unknown>>;
|
|
144
|
+
/** Aborts the call in flight: the turn's signal. */
|
|
145
|
+
signal?: AbortSignal;
|
|
146
|
+
/**
|
|
147
|
+
* Tools declared after the agent's own, as a plugin's beforeModelCallback
|
|
148
|
+
* adds them to ADK's toolsDict last: self-correction's reflection tool
|
|
149
|
+
* (lib/runtime/native/selfCorrection.ts).
|
|
150
|
+
*/
|
|
151
|
+
extraTools?: readonly unknown[];
|
|
152
|
+
/**
|
|
153
|
+
* A workflow agent node's run: the node's input and the outputs stored so
|
|
154
|
+
* far, which fill the instruction's workflow placeholders as ADK's
|
|
155
|
+
* workflowInstructionScope does (lib/workflow/agentNode.ts).
|
|
156
|
+
*/
|
|
157
|
+
workflowScope?: WorkflowInstructionScope;
|
|
158
|
+
}
|
|
159
|
+
/** A request, and the client-side tools it declares by name (what the loop runs and checks for long-running calls). */
|
|
160
|
+
export interface BuiltRequest {
|
|
161
|
+
request: ModelRequest;
|
|
162
|
+
/** By declared name, in the request's order: the own Tool when there is one, else the object listed. */
|
|
163
|
+
tools: Map<string, unknown>;
|
|
164
|
+
}
|
|
165
|
+
/** The tool ADK adds when an agent has an output schema and tools a model cannot take together. */
|
|
166
|
+
export declare const SET_MODEL_RESPONSE = "set_model_response";
|
|
167
|
+
/** set_model_response as an own Tool: its answer is the arguments, as JSON text, and it ends the step. */
|
|
168
|
+
export declare function setModelResponseTool(outputSchema: Record<string, unknown>): Tool;
|
|
169
|
+
/** Whether the model takes an output schema beside tools in one request (ADK: Vertex AI, Gemini 2 and later). */
|
|
170
|
+
export declare function outputSchemaWithTools(model: string): boolean;
|
|
171
|
+
/**
|
|
172
|
+
* What ADK's runLlmAgentAsNode puts in a node agent's invocation context
|
|
173
|
+
* (`withWorkflowInstructionScope`): the node's input, and the output each
|
|
174
|
+
* node of the invocation stored so far, by node name, the last one winning.
|
|
175
|
+
* Its instruction then fills `{<any>.<field>}` from the input and
|
|
176
|
+
* `<<any>.<field> from <Node>>` from that node's output.
|
|
177
|
+
*/
|
|
178
|
+
export interface WorkflowInstructionScope {
|
|
179
|
+
readonly input: unknown;
|
|
180
|
+
readonly outputsByNode: Readonly<Record<string, unknown>>;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* ADK's collectPredecessorOutputs: the output every event of the invocation
|
|
184
|
+
* carries, keyed by the last segment of its node path without the run
|
|
185
|
+
* suffix (`Graph.Fan.Agent@2` is `Agent`), the later event winning.
|
|
186
|
+
*/
|
|
187
|
+
export declare function predecessorOutputs(events: readonly TurnEvent[], invocationId: string): Record<string, unknown>;
|
|
188
|
+
/**
|
|
189
|
+
* `template` with each `{key}` naming a state key replaced by the value in
|
|
190
|
+
* `state` (a string as it is, anything else as JSON). `{key?}` is optional
|
|
191
|
+
* and becomes empty when the key is absent; a required key that is absent
|
|
192
|
+
* fails, as on the ADK runtime. A placeholder that names no state key
|
|
193
|
+
* (`{ "a": 1 }` in an example) stays as it is. `{artifact.x}` fails: no
|
|
194
|
+
* runtime of this engine has an artifact service. Own keys only: a key such
|
|
195
|
+
* as `constructor` is absent unless the state holds it.
|
|
196
|
+
*
|
|
197
|
+
* With a workflow `scope` (a workflow agent node's run), ADK 2.2's two
|
|
198
|
+
* workflow placeholders are filled too, as its injectSessionState fills
|
|
199
|
+
* them: `{x.field}` (any identifier before the dot) from the node's input
|
|
200
|
+
* when it is an object holding `field`, `''` when optional and absent, else
|
|
201
|
+
* left as written (the key's first spelling); and `<x.field from Node>`
|
|
202
|
+
* from that node's stored object output, else left as written.
|
|
203
|
+
*/
|
|
204
|
+
export declare function injectSessionState(template: string, state: Readonly<Record<string, unknown>>, scope?: WorkflowInstructionScope): string;
|
|
205
|
+
/** A toolset (the skills harness, an MCP toolset): something that yields tools, and is not one. */
|
|
206
|
+
export declare function isToolset(value: unknown): value is {
|
|
207
|
+
getTools(ctx?: unknown): Promise<unknown[]>;
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* The ModelRequest the native loop sends for `agent` now, with the
|
|
211
|
+
* client-side tools it declares. Throws where the ADK runtime throws
|
|
212
|
+
* building the same request: a required state key that is absent, a
|
|
213
|
+
* Gemini-only tool on another model, a config field LlmAgent refuses.
|
|
214
|
+
*/
|
|
215
|
+
export declare function buildModelRequest(agent: NativeAgent, ctx: RequestContext): Promise<BuiltRequest>;
|