melchizedek-agents 0.17.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 +35 -3
- package/AGENT_SETUP.md +2 -1
- package/CHANGELOG.md +929 -0
- package/DOCUMENTATION.md +290 -66
- 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 +63 -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 +10 -3
- package/db/migrations/0012_audit_log.sql +98 -0
- package/db/migrations/0013_tool_credentials.sql +260 -0
- package/dist/lib/a2a/app.d.ts +90 -6
- package/dist/lib/a2a/app.js +201 -6
- package/dist/lib/a2a/executor.d.ts +54 -7
- package/dist/lib/a2a/executor.js +134 -16
- package/dist/lib/a2a/remoteAgent.d.ts +24 -9
- package/dist/lib/a2a/remoteAgent.js +31 -14
- package/dist/lib/compile.d.ts +121 -31
- package/dist/lib/compile.js +153 -113
- 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 +13 -5
- package/dist/lib/config.js +13 -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/loadEnv.d.ts +5 -0
- package/dist/lib/loadEnv.js +7 -0
- package/dist/lib/loadSyndicate.d.ts +22 -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.d.ts +27 -0
- package/dist/lib/memory/providers.js +30 -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 +48 -0
- package/dist/lib/models/fallback.js +116 -0
- 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 +25 -0
- package/dist/lib/observability/audit.js +39 -0
- package/dist/lib/observability/lineage.d.ts +14 -0
- package/dist/lib/observability/lineage.js +33 -0
- package/dist/lib/observability/metrics.d.ts +6 -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 +39 -8
- package/dist/lib/observability/tracer.js +59 -20
- 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 +44 -6
- package/dist/lib/runtime/syndicateTurn.js +205 -33
- 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 +15 -0
- package/dist/lib/storage/postgres/index.js +7 -0
- 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 +55 -0
- package/dist/lib/syndicateSchema.js +91 -7
- 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 +68 -1
- package/dist/lib/tools/mcpToolFactory.js +106 -50
- 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 +31 -17
- package/dist/lib/tools/openapiTools.js +150 -117
- 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 +55 -11
- package/dist/scripts/assistant_worker.d.ts +2 -1
- package/dist/scripts/assistant_worker.js +9 -4
- package/dist/scripts/db.d.ts +9 -0
- package/dist/scripts/db.js +30 -15
- package/dist/scripts/syndicate_chat.js +19 -10
- package/package.json +6 -3
- 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
package/dist/lib/compile.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* lib/compile.ts — the one YAML →
|
|
2
|
+
* lib/compile.ts — the one YAML → agent compiler: a runtime-neutral
|
|
3
|
+
* AgentSpec, and the ADK agent graph built from it.
|
|
3
4
|
*
|
|
4
5
|
* WHY this file exists:
|
|
5
6
|
* The A2A server carried this logic as two closures inside its executor,
|
|
@@ -26,17 +27,30 @@
|
|
|
26
27
|
* paths build subagents through the same function, so the agent a route
|
|
27
28
|
* dispatches to is identical to the one DELEGATE would have wrapped.
|
|
28
29
|
* Contract and rationale: lib/dispatch.ts.
|
|
30
|
+
*
|
|
31
|
+
* ── One spec, two runtimes (ADR 0073) ─────────────────────────────────────
|
|
32
|
+
* compileSpec and compileSubagentSpec do the work every runtime shares:
|
|
33
|
+
* resolve and gate the tools, append the skills index, resolve the model
|
|
34
|
+
* once, build the generateContentConfig. The result is an AgentSpec.
|
|
35
|
+
* lib/compileAdk.ts builds ADK's LlmAgent from it (compileGraph and
|
|
36
|
+
* compileSubagent are spec + compileAdk), and lib/compileNative.ts builds
|
|
37
|
+
* the native loop's NativeAgent (ADR 0045). runSyndicateTurn picks one by
|
|
38
|
+
* MELCHIZEDEK_RUNTIME or its `runtime` option.
|
|
29
39
|
*/
|
|
30
|
-
import {
|
|
40
|
+
import { BaseLlm, FunctionTool } from '@google/adk';
|
|
31
41
|
import { relative } from 'node:path';
|
|
42
|
+
import { compileAdk } from './compileAdk.js';
|
|
32
43
|
import { isDispatchSyndicate } from './dispatch.js';
|
|
33
44
|
import { loadSyndicate, nestedLoader } from './loadSyndicate.js';
|
|
45
|
+
import { REASONING_OLDER_SPELLING } from './syndicateSchema.js';
|
|
46
|
+
import { reasoningConfig } from './models/reasoning.js';
|
|
34
47
|
import { resolveTools as resolveNamedTools } from './toolRegistry.js';
|
|
35
48
|
import { createMcpTools } from './tools/mcpToolFactory.js';
|
|
49
|
+
import { toAdkInstructionTool, toAdkToolset } from './tools/adkTool.js';
|
|
50
|
+
import { examplesInstructionTool } from './tools/examples.js';
|
|
36
51
|
import { capabilitySummary, describeCapabilities } from './models/capabilities.js';
|
|
37
|
-
import { remoteAgentTool } from './a2a/remoteAgent.js';
|
|
38
52
|
import { buildSkillHarness } from './tools/skillToolset.js';
|
|
39
|
-
import { buildOpenApiTools,
|
|
53
|
+
import { buildOpenApiTools, namesTool, openApiOperationId } from './tools/openapiTools.js';
|
|
40
54
|
/** generateContentConfig as every entrypoint has always sent it to ADK. */
|
|
41
55
|
function withServerSideToolInvocations(generateContentConfig) {
|
|
42
56
|
const cfg = (generateContentConfig ?? {});
|
|
@@ -48,59 +62,31 @@ function withServerSideToolInvocations(generateContentConfig) {
|
|
|
48
62
|
},
|
|
49
63
|
};
|
|
50
64
|
}
|
|
65
|
+
// ── Reasoning (ADR 0047) ─────────────────────────────────────────────────────
|
|
66
|
+
// REASONING_BUDGETS and reasoningConfig live in lib/models/reasoning.ts, so a
|
|
67
|
+
// model adapter can map `reasoning:` without importing the compiler (and ADK).
|
|
68
|
+
export { REASONING_BUDGETS, reasoningConfig } from './models/reasoning.js';
|
|
51
69
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* intake template relies on so that a document never sees an earlier one —
|
|
57
|
-
* changed nothing. Only fields the YAML sets are passed, so ADK's defaults
|
|
58
|
-
* stay in force otherwise.
|
|
70
|
+
* An agent's generateContentConfig with its `reasoning:` key mapped in for
|
|
71
|
+
* the model it runs on. Unchanged (the same object) when the agent sets no
|
|
72
|
+
* `reasoning`. The loader refuses `reasoning` next to the older spelling;
|
|
73
|
+
* this refuses it too, for a config built in code.
|
|
59
74
|
*/
|
|
60
|
-
function
|
|
61
|
-
const
|
|
62
|
-
if (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
out.globalInstruction = cfg.globalInstruction;
|
|
68
|
-
if (cfg.disallowTransferToParent !== undefined)
|
|
69
|
-
out.disallowTransferToParent = cfg.disallowTransferToParent;
|
|
70
|
-
if (cfg.disallowTransferToPeers !== undefined)
|
|
71
|
-
out.disallowTransferToPeers = cfg.disallowTransferToPeers;
|
|
72
|
-
return out;
|
|
73
|
-
}
|
|
74
|
-
export const DEFAULT_KEEP_RECENT_EVENTS = 6;
|
|
75
|
-
/**
|
|
76
|
-
* The LlmAgent fields the engine builds from YAML rather than passing
|
|
77
|
-
* through (ADR 0033): `code_execution: gemini` (Gemini's server-side
|
|
78
|
-
* sandbox runs the model's Python; nothing runs on this host), `context:`
|
|
79
|
-
* (ADK's token-based compactor with an LLM summarizer, so a long
|
|
80
|
-
* conversation is summarized instead of overflowing the window), and
|
|
81
|
-
* `mode: task` (the agent works until it calls finish_task; on a workflow
|
|
82
|
-
* node, its arguments become the node's output).
|
|
83
|
-
*/
|
|
84
|
-
function executionFields(cfg, opts) {
|
|
85
|
-
const out = {};
|
|
86
|
-
if (cfg.code_execution === 'gemini')
|
|
87
|
-
out.codeExecutor = new BuiltInCodeExecutor();
|
|
88
|
-
if (cfg.mode)
|
|
89
|
-
out.mode = cfg.mode;
|
|
90
|
-
if (cfg.context) {
|
|
91
|
-
const resolve = opts.resolveModel ?? ((m) => m);
|
|
92
|
-
const summaryModel = resolve(cfg.context.summary_model ?? cfg.model);
|
|
93
|
-
const llm = typeof summaryModel === 'string' || !summaryModel ? LLMRegistry.newLlm(String(summaryModel ?? cfg.model)) : summaryModel;
|
|
94
|
-
out.contextCompactors = [
|
|
95
|
-
new TokenBasedContextCompactor({
|
|
96
|
-
tokenThreshold: cfg.context.compact_after_tokens,
|
|
97
|
-
eventRetentionSize: cfg.context.keep_recent_events ?? DEFAULT_KEEP_RECENT_EVENTS,
|
|
98
|
-
summarizer: new LlmSummarizer({ llm }),
|
|
99
|
-
}),
|
|
100
|
-
];
|
|
75
|
+
export function withReasoning(agent, model) {
|
|
76
|
+
const cfg = agent.generateContentConfig;
|
|
77
|
+
if (agent.reasoning === undefined)
|
|
78
|
+
return cfg;
|
|
79
|
+
const clash = REASONING_OLDER_SPELLING.filter((k) => cfg?.[k] !== undefined);
|
|
80
|
+
if (clash.length) {
|
|
81
|
+
throw new Error(`${agent.name ?? 'agent'}: reasoning cannot be combined with ${clash.map((k) => `generateContentConfig.${k}`).join(' or ')}; reasoning replaces it (ADR 0047)`);
|
|
101
82
|
}
|
|
102
|
-
return
|
|
83
|
+
return { ...cfg, ...reasoningConfig(model ?? '', agent.reasoning) };
|
|
84
|
+
}
|
|
85
|
+
/** The model id an agent runs on, from its YAML or its resolved adapter. */
|
|
86
|
+
function modelIdOf(yamlModel, resolved) {
|
|
87
|
+
return yamlModel ?? (typeof resolved === 'string' ? resolved : resolved instanceof BaseLlm ? resolved.model : undefined);
|
|
103
88
|
}
|
|
89
|
+
export { DEFAULT_KEEP_RECENT_EVENTS } from './runtime/native/compaction.js';
|
|
104
90
|
/**
|
|
105
91
|
* Says, once per compiled agent, what its resolved path cannot honour — a
|
|
106
92
|
* dropped server-side tool, a gateway stand-in, or no route at all. Quiet
|
|
@@ -129,9 +115,13 @@ export function requireApprovalOn(tool) {
|
|
|
129
115
|
return gated;
|
|
130
116
|
}
|
|
131
117
|
/**
|
|
132
|
-
* A copy of an
|
|
133
|
-
*
|
|
134
|
-
*
|
|
118
|
+
* A copy of an ADK BaseTool that runs only after a person approves the
|
|
119
|
+
* call: the same confirmation interrupt FunctionTool's own gate raises, so
|
|
120
|
+
* the turn pauses and resumes exactly as ADR 0028 says. The engine no
|
|
121
|
+
* longer uses it: an OpenAPI operation is a FunctionTool over an own Tool
|
|
122
|
+
* (ADR 0067) and takes requireApprovalOn like every registry tool.
|
|
123
|
+
* @deprecated Gate a FunctionTool with requireApprovalOn, or an own Tool
|
|
124
|
+
* with requireApproval (lib/tools/tool.ts).
|
|
135
125
|
*/
|
|
136
126
|
export function requireApprovalOnBaseTool(tool) {
|
|
137
127
|
const gated = Object.create(tool);
|
|
@@ -155,17 +145,16 @@ function gateTools(tools, names, agentName) {
|
|
|
155
145
|
return tools;
|
|
156
146
|
const wanted = new Set(names);
|
|
157
147
|
const out = tools.map((t) => {
|
|
158
|
-
const
|
|
159
|
-
const name = tool?.name;
|
|
148
|
+
const name = t?.name;
|
|
160
149
|
if (!name)
|
|
161
150
|
return t;
|
|
162
151
|
// An OpenAPI operation may be named as the YAML named it (its operationId).
|
|
163
|
-
const
|
|
152
|
+
const operationId = openApiOperationId(t);
|
|
153
|
+
const match = [...wanted].find((w) => w === name || (operationId !== undefined && namesTool(w, { name, operation: { operationId } })));
|
|
164
154
|
if (!match)
|
|
165
155
|
return t;
|
|
166
156
|
wanted.delete(match);
|
|
167
|
-
|
|
168
|
-
return requireApprovalOnBaseTool(t);
|
|
157
|
+
// An OpenAPI operation is a FunctionTool over an own Tool (ADR 0067): one gate for both.
|
|
169
158
|
if (!(t instanceof FunctionTool)) {
|
|
170
159
|
throw new Error(`${agentName}: '${name}' cannot require approval — only function tools from the registry and OpenAPI operations can be gated (ADR 0028).`);
|
|
171
160
|
}
|
|
@@ -183,17 +172,16 @@ export function declaresApprovals(config) {
|
|
|
183
172
|
return agentGates(config.orchestrator) || (config.subagents ?? []).some((s) => agentGates(s));
|
|
184
173
|
}
|
|
185
174
|
/**
|
|
186
|
-
*
|
|
187
|
-
*
|
|
175
|
+
* An agent's `examples:` as the ADK tool for their InstructionTool
|
|
176
|
+
* (lib/tools/examples.ts): never called by the model, it adds the exchanges
|
|
177
|
+
* to every request's instruction as few-shot examples, in the words ADK's
|
|
178
|
+
* ExampleTool used.
|
|
188
179
|
*/
|
|
189
180
|
export function examplesTool(examples) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
return [
|
|
193
|
-
new ExampleTool(examples.map((e) => ({ input: { role: 'user', parts: [{ text: e.input }] }, output: [{ role: 'model', parts: [{ text: e.output }] }] }))),
|
|
194
|
-
];
|
|
181
|
+
const tool = examplesInstructionTool(examples);
|
|
182
|
+
return tool ? [toAdkInstructionTool(tool)] : [];
|
|
195
183
|
}
|
|
196
|
-
async function resolveAgentTools(toolNames, mcpServerUrl, opts, openapi, examples) {
|
|
184
|
+
async function resolveAgentTools(toolNames, mcpServerUrl, opts, openapi, examples, mcpAllowed) {
|
|
197
185
|
const tools = [...resolveNamedTools(toolNames, opts.onUnknownTool), ...examplesTool(examples)];
|
|
198
186
|
// OpenAPI operations become tools here, so require_approval can name them.
|
|
199
187
|
for (const entry of openapi ?? []) {
|
|
@@ -207,7 +195,20 @@ async function resolveAgentTools(toolNames, mcpServerUrl, opts, openapi, example
|
|
|
207
195
|
}
|
|
208
196
|
if (mcpServerUrl) {
|
|
209
197
|
opts.log?.(`Loading MCP tools: ${mcpServerUrl}`);
|
|
210
|
-
const
|
|
198
|
+
const offered = await createMcpTools(mcpServerUrl);
|
|
199
|
+
// mcp_tools: only the named tools are exposed (a server's list is its
|
|
200
|
+
// own to change); a name the server does not offer is reported, and a
|
|
201
|
+
// gate on it fails the compile in gateTools.
|
|
202
|
+
const allowed = mcpAllowed ? new Set(mcpAllowed) : undefined;
|
|
203
|
+
const mcpTools = allowed ? offered.filter((t) => allowed.has(t.name)) : offered;
|
|
204
|
+
if (allowed) {
|
|
205
|
+
const missing = [...allowed].filter((n) => !offered.some((t) => t.name === n));
|
|
206
|
+
if (missing.length)
|
|
207
|
+
opts.log?.(`MCP ${mcpServerUrl} does not offer ${missing.map((n) => `'${n}'`).join(', ')} (mcp_tools)`);
|
|
208
|
+
const hidden = offered.length - mcpTools.length;
|
|
209
|
+
if (hidden)
|
|
210
|
+
opts.log?.(`MCP ${mcpServerUrl}: ${hidden} tool(s) not in mcp_tools are not exposed`);
|
|
211
|
+
}
|
|
211
212
|
for (const mcpTool of mcpTools) {
|
|
212
213
|
if (!tools.some((t) => t.name === mcpTool.name))
|
|
213
214
|
tools.push(mcpTool);
|
|
@@ -231,22 +232,62 @@ async function withSkills(instruction, tools, skills, agentName, opts) {
|
|
|
231
232
|
opts.log?.(`skills · ${agentName}: ${count} skill${count === 1 ? '' : 's'} from ${skills.dir}${skills.scripts === 'local' ? ' · scripts run after approval' : ''}`);
|
|
232
233
|
for (const problem of harness.problems)
|
|
233
234
|
opts.log?.(`⚠ skills · ${skills.dir}: not loaded — ${problem}`);
|
|
234
|
-
|
|
235
|
+
// The ADK face of the engine's own toolset; compileNative reads the toolset back (toolsetOf).
|
|
236
|
+
return { instruction: `${instruction.trimEnd()}\n\n${harness.instruction}`, tools: [...tools, toAdkToolset(harness.toolset)] };
|
|
235
237
|
}
|
|
236
238
|
/** True when a turn running this agent directly may pause for a person (ADR 0028). */
|
|
237
239
|
export function agentGates(agent) {
|
|
238
240
|
return !!agent?.require_approval?.length || agent?.skills?.scripts === 'local';
|
|
239
241
|
}
|
|
242
|
+
function specOf(yaml, name, description, instruction, tools, opts) {
|
|
243
|
+
const resolvedModel = (opts.resolveModel ?? ((m) => m))(yaml.model);
|
|
244
|
+
const modelId = modelIdOf(yaml.model, resolvedModel);
|
|
245
|
+
const spec = {
|
|
246
|
+
name,
|
|
247
|
+
instruction,
|
|
248
|
+
tools,
|
|
249
|
+
resolvedModel,
|
|
250
|
+
generateContentConfig: withServerSideToolInvocations(withReasoning(yaml, modelId)),
|
|
251
|
+
};
|
|
252
|
+
if (description !== undefined)
|
|
253
|
+
spec.description = description;
|
|
254
|
+
if (yaml.model !== undefined)
|
|
255
|
+
spec.model = yaml.model;
|
|
256
|
+
if (modelId !== undefined)
|
|
257
|
+
spec.modelId = modelId;
|
|
258
|
+
if (yaml.fallback_model)
|
|
259
|
+
spec.fallbackModel = yaml.fallback_model;
|
|
260
|
+
if (yaml.outputSchema)
|
|
261
|
+
spec.outputSchema = yaml.outputSchema;
|
|
262
|
+
if (yaml.includeContents !== undefined)
|
|
263
|
+
spec.includeContents = yaml.includeContents;
|
|
264
|
+
if (yaml.outputKey !== undefined)
|
|
265
|
+
spec.outputKey = yaml.outputKey;
|
|
266
|
+
if (yaml.globalInstruction !== undefined)
|
|
267
|
+
spec.globalInstruction = yaml.globalInstruction;
|
|
268
|
+
if (yaml.disallowTransferToParent !== undefined)
|
|
269
|
+
spec.disallowTransferToParent = yaml.disallowTransferToParent;
|
|
270
|
+
if (yaml.disallowTransferToPeers !== undefined)
|
|
271
|
+
spec.disallowTransferToPeers = yaml.disallowTransferToPeers;
|
|
272
|
+
if (yaml.code_execution)
|
|
273
|
+
spec.codeExecution = yaml.code_execution;
|
|
274
|
+
if (yaml.context)
|
|
275
|
+
spec.context = yaml.context;
|
|
276
|
+
if (yaml.mode)
|
|
277
|
+
spec.mode = yaml.mode;
|
|
278
|
+
return spec;
|
|
279
|
+
}
|
|
280
|
+
const asTools = (tools) => tools.map((tool) => ({ kind: 'tool', tool }));
|
|
240
281
|
/**
|
|
241
|
-
*
|
|
242
|
-
*
|
|
282
|
+
* The spec of ONE agent from a subagent entry. A `yaml_reference` entry is
|
|
283
|
+
* the nested syndicate's whole graph under this entry's name and
|
|
243
284
|
* description, so the parent sees one tool (or one route) either way.
|
|
244
285
|
*/
|
|
245
|
-
export async function
|
|
286
|
+
export async function compileSubagentSpec(subCfg, opts = {}) {
|
|
246
287
|
if (subCfg.a2a_agent_url) {
|
|
247
288
|
// A remote agent has its own model and prompt on its own server; there
|
|
248
289
|
// is no local agent to build. It is reached as a delegation tool
|
|
249
|
-
// (
|
|
290
|
+
// (compileSpec) or a dispatch route (lib/runtime/syndicateTurn.ts).
|
|
250
291
|
throw new Error(`'${subCfg.name}' is a remote A2A agent (a2a_agent_url) and has no local agent to compile.`);
|
|
251
292
|
}
|
|
252
293
|
if (subCfg.yaml_reference) {
|
|
@@ -257,32 +298,21 @@ export async function compileSubagent(subCfg, opts = {}) {
|
|
|
257
298
|
// own subagents do): a pause there cannot reach the caller (ADR 0028).
|
|
258
299
|
throw new Error(`${subCfg.yaml_reference}: approval gates (require_approval) are not supported inside a nested syndicate.`);
|
|
259
300
|
}
|
|
260
|
-
return
|
|
301
|
+
return compileSpec(nested, opts, subCfg.name, subCfg.description);
|
|
261
302
|
}
|
|
262
|
-
const gated = gateTools(await resolveAgentTools(subCfg.tools, subCfg.mcp_server_url, opts, subCfg.openapi, subCfg.examples), subCfg.require_approval, subCfg.name);
|
|
303
|
+
const gated = gateTools(await resolveAgentTools(subCfg.tools, subCfg.mcp_server_url, opts, subCfg.openapi, subCfg.examples, subCfg.mcp_tools), subCfg.require_approval, subCfg.name);
|
|
263
304
|
const { instruction, tools } = await withSkills(subCfg.instruction ?? '', gated, subCfg.skills, subCfg.name, opts);
|
|
264
|
-
const resolveModel = opts.resolveModel ?? ((m) => m);
|
|
265
305
|
logCapabilities(opts, subCfg.name, subCfg.model, subCfg.tools);
|
|
266
|
-
return
|
|
267
|
-
name: subCfg.name,
|
|
268
|
-
description: subCfg.description,
|
|
269
|
-
model: resolveModel(subCfg.model),
|
|
270
|
-
instruction,
|
|
271
|
-
tools: tools.length > 0 ? tools : undefined,
|
|
272
|
-
outputSchema: subCfg.outputSchema,
|
|
273
|
-
generateContentConfig: withServerSideToolInvocations(subCfg.generateContentConfig),
|
|
274
|
-
...passthroughFields(subCfg),
|
|
275
|
-
...executionFields(subCfg, opts),
|
|
276
|
-
...(opts.nodeConfig?.(subCfg.name) ?? {}),
|
|
277
|
-
});
|
|
306
|
+
return specOf(subCfg, subCfg.name, subCfg.description, instruction, asTools(tools), opts);
|
|
278
307
|
}
|
|
279
308
|
/**
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
* outputSchema + AgentTool on one agent — see
|
|
283
|
-
* and the caller dispatches to
|
|
309
|
+
* The spec of a syndicate's orchestrator. In DELEGATE mode its subagents
|
|
310
|
+
* come first among its tools, as delegations; in PLAN-DISPATCH mode it gets
|
|
311
|
+
* none (ADK refuses outputSchema + AgentTool on one agent — see
|
|
312
|
+
* config/agents/critic.yaml), and the caller dispatches to a route's own
|
|
313
|
+
* spec itself.
|
|
284
314
|
*/
|
|
285
|
-
export async function
|
|
315
|
+
export async function compileSpec(config, opts = {}, overrideName, overrideDescription) {
|
|
286
316
|
// A registry definition carries its nested syndicates (ADR 0018 item 6).
|
|
287
317
|
if (config.bundled_references && !opts.loadNested)
|
|
288
318
|
opts = { ...opts, loadNested: nestedLoader(config) };
|
|
@@ -294,31 +324,41 @@ export async function compileGraph(config, opts = {}, overrideName, overrideDesc
|
|
|
294
324
|
}
|
|
295
325
|
if (config.workflow)
|
|
296
326
|
opts.log?.(`${config.syndicate_name}: nested as a subagent, so only its orchestrator runs (a Workflow cannot be a subagent yet)`);
|
|
297
|
-
const
|
|
327
|
+
const delegated = isDispatchSyndicate(config)
|
|
298
328
|
? []
|
|
299
329
|
: await Promise.all((config.subagents ?? []).map(async (subCfg) => {
|
|
300
330
|
if (subCfg.a2a_agent_url) {
|
|
301
331
|
opts.log?.(`Remote A2A agent: ${subCfg.name} → ${subCfg.a2a_agent_url}`);
|
|
302
|
-
return
|
|
332
|
+
return { kind: 'remote', name: subCfg.name, description: subCfg.description, url: subCfg.a2a_agent_url };
|
|
303
333
|
}
|
|
304
|
-
return
|
|
334
|
+
return { kind: 'agent', agent: await compileSubagentSpec(subCfg, opts) };
|
|
305
335
|
}));
|
|
336
|
+
const name = overrideName || config.orchestrator.name;
|
|
306
337
|
// Orchestrator tools are registry names only — no entrypoint has ever
|
|
307
338
|
// attached an MCP server to an orchestrator, and this compiler preserves
|
|
308
339
|
// that exactly rather than widening the contract in passing.
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
const
|
|
312
|
-
logCapabilities(opts,
|
|
313
|
-
return
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
340
|
+
const own = gateTools(await resolveAgentTools(config.orchestrator.tools, undefined, opts, config.orchestrator.openapi, config.orchestrator.examples), config.orchestrator.require_approval, name);
|
|
341
|
+
// The skills toolset goes last, after the delegations and the agent's own tools.
|
|
342
|
+
const { instruction, tools } = await withSkills(config.orchestrator.instruction, own, config.orchestrator.skills, name, opts);
|
|
343
|
+
logCapabilities(opts, name, config.orchestrator.model, config.orchestrator.tools);
|
|
344
|
+
return specOf(config.orchestrator, name, overrideDescription || config.orchestrator.description, instruction, [...delegated, ...asTools(tools)], opts);
|
|
345
|
+
}
|
|
346
|
+
// ── The ADK runtime's agents (lib/compileAdk.ts) ─────────────────────────────
|
|
347
|
+
/**
|
|
348
|
+
* Builds ONE runnable ADK agent from a subagent entry: its spec, as
|
|
349
|
+
* lib/compileAdk.ts builds it. A workflow node's settings
|
|
350
|
+
* (CompileOptions.nodeConfig) apply to a local agent, not to a nested
|
|
351
|
+
* syndicate's orchestrator.
|
|
352
|
+
*/
|
|
353
|
+
export async function compileSubagent(subCfg, opts = {}) {
|
|
354
|
+
const spec = await compileSubagentSpec(subCfg, opts);
|
|
355
|
+
return compileAdk(spec, opts, subCfg.yaml_reference ? {} : (opts.nodeConfig?.(subCfg.name) ?? {}));
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Compiles a syndicate's orchestrator for the ADK runtime. In DELEGATE mode
|
|
359
|
+
* its subagents are attached as AgentTools; in PLAN-DISPATCH mode it gets
|
|
360
|
+
* none, and the caller dispatches to `compileSubagent(route)` itself.
|
|
361
|
+
*/
|
|
362
|
+
export async function compileGraph(config, opts = {}, overrideName, overrideDescription) {
|
|
363
|
+
return compileAdk(await compileSpec(config, opts, overrideName, overrideDescription), opts);
|
|
324
364
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/compileAdk.ts — an AgentSpec as the ADK runtime runs it: today's
|
|
3
|
+
* LlmAgent (ADR 0045, ADR 0073).
|
|
4
|
+
*
|
|
5
|
+
* WHY this file exists:
|
|
6
|
+
* lib/compile.ts turns a YAML agent into a runtime-neutral AgentSpec: its
|
|
7
|
+
* tools resolved and gated, its instruction with the skills index, its
|
|
8
|
+
* model resolved once and its generateContentConfig built for that model.
|
|
9
|
+
* This file adds what only ADK's LlmAgent takes: the model wrapped in a
|
|
10
|
+
* FallbackLlm for `fallback_model:`, each delegated subagent as an
|
|
11
|
+
* AgentTool (a remote one as its A2A tool), Gemini's code executor, the
|
|
12
|
+
* context compactor, task mode and a workflow node's settings. Every field
|
|
13
|
+
* reaches LlmAgent as compileGraph and compileSubagent always passed it, so
|
|
14
|
+
* the ADK runtime runs the agent it ran before the split.
|
|
15
|
+
* lib/compileNative.ts builds the native loop's agent from the same spec.
|
|
16
|
+
*
|
|
17
|
+
* Imports from lib/compile.ts are types only, so the two modules load in
|
|
18
|
+
* either order.
|
|
19
|
+
*/
|
|
20
|
+
import { LlmAgent } from '@google/adk';
|
|
21
|
+
import type { AgentSpec, CompileOptions } from './compile.ts';
|
|
22
|
+
import { DEFAULT_KEEP_RECENT_EVENTS } from './runtime/native/compaction.ts';
|
|
23
|
+
/** Events kept verbatim after a compaction summary when `context:` names none: the native compactor's default. */
|
|
24
|
+
export { DEFAULT_KEEP_RECENT_EVENTS };
|
|
25
|
+
/**
|
|
26
|
+
* The LlmAgent for `spec`. `extra` is spread last: a workflow node's
|
|
27
|
+
* settings (CompileOptions.nodeConfig), which compileSubagent passes.
|
|
28
|
+
*/
|
|
29
|
+
export declare function compileAdk(spec: AgentSpec, opts?: CompileOptions, extra?: Record<string, unknown>): LlmAgent;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/compileAdk.ts — an AgentSpec as the ADK runtime runs it: today's
|
|
3
|
+
* LlmAgent (ADR 0045, ADR 0073).
|
|
4
|
+
*
|
|
5
|
+
* WHY this file exists:
|
|
6
|
+
* lib/compile.ts turns a YAML agent into a runtime-neutral AgentSpec: its
|
|
7
|
+
* tools resolved and gated, its instruction with the skills index, its
|
|
8
|
+
* model resolved once and its generateContentConfig built for that model.
|
|
9
|
+
* This file adds what only ADK's LlmAgent takes: the model wrapped in a
|
|
10
|
+
* FallbackLlm for `fallback_model:`, each delegated subagent as an
|
|
11
|
+
* AgentTool (a remote one as its A2A tool), Gemini's code executor, the
|
|
12
|
+
* context compactor, task mode and a workflow node's settings. Every field
|
|
13
|
+
* reaches LlmAgent as compileGraph and compileSubagent always passed it, so
|
|
14
|
+
* the ADK runtime runs the agent it ran before the split.
|
|
15
|
+
* lib/compileNative.ts builds the native loop's agent from the same spec.
|
|
16
|
+
*
|
|
17
|
+
* Imports from lib/compile.ts are types only, so the two modules load in
|
|
18
|
+
* either order.
|
|
19
|
+
*/
|
|
20
|
+
import { AgentTool, BaseLlm, BuiltInCodeExecutor, LLMRegistry, LlmAgent, LlmSummarizer, LogLevel, TokenBasedContextCompactor, setLogLevel as setAdkLogLevel } from '@google/adk';
|
|
21
|
+
import { remoteAgentTool } from './a2a/remoteAgent.js';
|
|
22
|
+
import { FallbackLlm } from './models/fallback.js';
|
|
23
|
+
import { resolveModel as resolveRegistryModel } from './models/registry.js';
|
|
24
|
+
import { onLogLevel } from './runtime/logging.js';
|
|
25
|
+
import { DEFAULT_KEEP_RECENT_EVENTS } from './runtime/native/compaction.js';
|
|
26
|
+
/**
|
|
27
|
+
* ADK's logger follows the engine's level (lib/runtime/logging.ts, ADR
|
|
28
|
+
* 0080), so a surface sets one level and never names ADK to quiet it.
|
|
29
|
+
*/
|
|
30
|
+
const ADK_LOG_LEVELS = {
|
|
31
|
+
debug: LogLevel.DEBUG,
|
|
32
|
+
info: LogLevel.INFO,
|
|
33
|
+
warn: LogLevel.WARN,
|
|
34
|
+
error: LogLevel.ERROR,
|
|
35
|
+
};
|
|
36
|
+
onLogLevel((level) => setAdkLogLevel(ADK_LOG_LEVELS[level]));
|
|
37
|
+
/** Events kept verbatim after a compaction summary when `context:` names none: the native compactor's default. */
|
|
38
|
+
export { DEFAULT_KEEP_RECENT_EVENTS };
|
|
39
|
+
/**
|
|
40
|
+
* The LlmAgent fields a YAML agent may set beyond model, instruction, tools
|
|
41
|
+
* and schemas. The schema reference (config/agents/syndicateSchema.yaml)
|
|
42
|
+
* documents each as mapping 1:1 to its ADK counterpart. Only fields the YAML
|
|
43
|
+
* sets are passed, so ADK's defaults stay in force otherwise.
|
|
44
|
+
*/
|
|
45
|
+
function passthroughFields(spec) {
|
|
46
|
+
const out = {};
|
|
47
|
+
if (spec.includeContents !== undefined)
|
|
48
|
+
out.includeContents = spec.includeContents;
|
|
49
|
+
if (spec.outputKey !== undefined)
|
|
50
|
+
out.outputKey = spec.outputKey;
|
|
51
|
+
if (spec.globalInstruction !== undefined)
|
|
52
|
+
out.globalInstruction = spec.globalInstruction;
|
|
53
|
+
if (spec.disallowTransferToParent !== undefined)
|
|
54
|
+
out.disallowTransferToParent = spec.disallowTransferToParent;
|
|
55
|
+
if (spec.disallowTransferToPeers !== undefined)
|
|
56
|
+
out.disallowTransferToPeers = spec.disallowTransferToPeers;
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The LlmAgent fields the engine builds from YAML rather than passing
|
|
61
|
+
* through (ADR 0033): `code_execution: gemini` (Gemini's server-side
|
|
62
|
+
* sandbox runs the model's Python; nothing runs on this host), `context:`
|
|
63
|
+
* (ADK's token-based compactor with an LLM summarizer, so a long
|
|
64
|
+
* conversation is summarized instead of overflowing the window), and
|
|
65
|
+
* `mode: task` (the agent works until it calls finish_task; on a workflow
|
|
66
|
+
* node, its arguments become the node's output).
|
|
67
|
+
*/
|
|
68
|
+
function executionFields(cfg, opts) {
|
|
69
|
+
const out = {};
|
|
70
|
+
if (cfg.codeExecution === 'gemini')
|
|
71
|
+
out.codeExecutor = new BuiltInCodeExecutor();
|
|
72
|
+
if (cfg.mode)
|
|
73
|
+
out.mode = cfg.mode;
|
|
74
|
+
if (cfg.context) {
|
|
75
|
+
const resolve = opts.resolveModel ?? ((m) => m);
|
|
76
|
+
const summaryModel = resolve(cfg.context.summary_model ?? cfg.model);
|
|
77
|
+
const llm = typeof summaryModel === 'string' || !summaryModel ? LLMRegistry.newLlm(String(summaryModel ?? cfg.model)) : summaryModel;
|
|
78
|
+
out.contextCompactors = [
|
|
79
|
+
new TokenBasedContextCompactor({
|
|
80
|
+
tokenThreshold: cfg.context.compact_after_tokens,
|
|
81
|
+
eventRetentionSize: cfg.context.keep_recent_events ?? DEFAULT_KEEP_RECENT_EVENTS,
|
|
82
|
+
summarizer: new LlmSummarizer({ llm }),
|
|
83
|
+
}),
|
|
84
|
+
];
|
|
85
|
+
}
|
|
86
|
+
return out;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* An agent with `fallback_model:` gets its model wrapped (lib/models/fallback.ts):
|
|
90
|
+
* the fallback answers a provider-side failure, and a provider that keeps
|
|
91
|
+
* failing is skipped for a cooldown. A model id string is resolved to its
|
|
92
|
+
* adapter first, so the wrapper always holds two adapters.
|
|
93
|
+
*/
|
|
94
|
+
function withFallback(primary, fallbackId, opts) {
|
|
95
|
+
if (!fallbackId)
|
|
96
|
+
return primary;
|
|
97
|
+
const resolve = opts.resolveModel ?? ((m) => m);
|
|
98
|
+
const asLlm = (m) => (m instanceof BaseLlm ? m : resolveRegistryModel(String(m)));
|
|
99
|
+
return new FallbackLlm(asLlm(primary), asLlm(resolve(fallbackId)), opts.log ?? ((m) => console.warn(m)));
|
|
100
|
+
}
|
|
101
|
+
/** The spec's tools as LlmAgent takes them: a delegated subagent as an AgentTool, a remote one as its A2A tool. */
|
|
102
|
+
function adkTools(spec, opts) {
|
|
103
|
+
return spec.tools.map((entry) => {
|
|
104
|
+
switch (entry.kind) {
|
|
105
|
+
case 'tool':
|
|
106
|
+
return entry.tool;
|
|
107
|
+
case 'agent':
|
|
108
|
+
return new AgentTool({ agent: compileAdk(entry.agent, opts) });
|
|
109
|
+
case 'remote':
|
|
110
|
+
return remoteAgentTool({ name: entry.name, description: entry.description, url: entry.url });
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* The LlmAgent for `spec`. `extra` is spread last: a workflow node's
|
|
116
|
+
* settings (CompileOptions.nodeConfig), which compileSubagent passes.
|
|
117
|
+
*/
|
|
118
|
+
export function compileAdk(spec, opts = {}, extra = {}) {
|
|
119
|
+
const tools = adkTools(spec, opts);
|
|
120
|
+
return new LlmAgent({
|
|
121
|
+
name: spec.name,
|
|
122
|
+
description: spec.description,
|
|
123
|
+
model: withFallback(spec.resolvedModel, spec.fallbackModel, opts),
|
|
124
|
+
instruction: spec.instruction,
|
|
125
|
+
tools: tools.length > 0 ? tools : undefined,
|
|
126
|
+
outputSchema: spec.outputSchema,
|
|
127
|
+
generateContentConfig: spec.generateContentConfig,
|
|
128
|
+
...passthroughFields(spec),
|
|
129
|
+
...executionFields(spec, opts),
|
|
130
|
+
...extra,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/compileNative.ts — an AgentSpec as the native runtime runs it: the
|
|
3
|
+
* NativeAgent the agent loop takes (ADR 0045, ADR 0073).
|
|
4
|
+
*
|
|
5
|
+
* WHY this file exists:
|
|
6
|
+
* lib/compile.ts turns a YAML agent into a runtime-neutral AgentSpec, and
|
|
7
|
+
* lib/compileAdk.ts builds ADK's LlmAgent from it. This file builds the
|
|
8
|
+
* native loop's agent from the same spec (lib/runtime/native/request.ts,
|
|
9
|
+
* NativeAgent), so both runtimes run the agent the YAML describes, with
|
|
10
|
+
* the same tools, instruction and config. tests/compile.test.ts compiles
|
|
11
|
+
* one spec both ways and requires the same first request.
|
|
12
|
+
*
|
|
13
|
+
* TOOLS: each resolved tool is handed to the loop as the own Tool or
|
|
14
|
+
* InstructionTool behind it (lib/tools/tool.ts), else as itself: an MCP
|
|
15
|
+
* tool, the skills toolset, a gated registry FunctionTool, which the loop
|
|
16
|
+
* runs by shape during the dual period (ADR 0071). A delegated subagent
|
|
17
|
+
* becomes a subagentTool holding its own NativeAgent, which the loop runs as
|
|
18
|
+
* a child loop (lib/runtime/native/delegate.ts, ADR 0074), a nested
|
|
19
|
+
* syndicate as its orchestrator's agent; a remote A2A subagent is the own
|
|
20
|
+
* Tool the ADK runtime's FunctionTool wraps (lib/a2a/remoteAgent.ts).
|
|
21
|
+
*
|
|
22
|
+
* EVERY AGENT KEY COMPILES for the native loop: `context:` is handed to
|
|
23
|
+
* the loop, which compacts as ADK does (lib/runtime/native/compaction.ts,
|
|
24
|
+
* WS2-9); `mode: task` and `code_execution: gemini` pass through, the
|
|
25
|
+
* request declaring finish_task (lib/runtime/native/taskMode.ts) and asking
|
|
26
|
+
* Gemini for its code-execution tool (lib/runtime/native/request.ts). What
|
|
27
|
+
* native does not run yet (workflows, resuming an approval or a
|
|
28
|
+
* question, a caller's agent transform) is refused by the turn runner
|
|
29
|
+
* (lib/runtime/nativeTurn.ts), which owns those choices.
|
|
30
|
+
*
|
|
31
|
+
* THE MODEL: the loop calls a model through its contract adapter. A
|
|
32
|
+
* resolver may return an id, a contract adapter, an ADK shim (which carries
|
|
33
|
+
* one) or ADK's Gemini (TracedGemini), whose key reaches the registry's
|
|
34
|
+
* Gemini adapter. Any other ADK model class has no adapter behind it, so
|
|
35
|
+
* compileNative and nativeAdapterFor refuse it with UnsupportedOnRuntimeError
|
|
36
|
+
* before any model call, naming adkShim as the way to run it on native,
|
|
37
|
+
* rather than run the registry's model for that id in its place (ADR 0088).
|
|
38
|
+
* ADK classes are told apart by ADK's own Symbol.for marks, so this file
|
|
39
|
+
* imports nothing from ADK.
|
|
40
|
+
*/
|
|
41
|
+
import type { AgentSpec, CompileOptions } from './compile.ts';
|
|
42
|
+
import type { SubagentYamlConfig, SyndicateYamlConfig } from './loadSyndicate.ts';
|
|
43
|
+
import type { ModelAdapter } from './models/contract.ts';
|
|
44
|
+
import type { NativeAgent } from './runtime/native/request.ts';
|
|
45
|
+
export { UnsupportedOnRuntimeError, unsupportedOnNative } from './runtime/runtimeFlag.ts';
|
|
46
|
+
/**
|
|
47
|
+
* The class name of an ADK model the native runtime cannot run, else
|
|
48
|
+
* undefined: an ADK BaseLlm that is neither ADK's Gemini (TracedGemini
|
|
49
|
+
* included) nor a shim carrying a contract adapter (lib/models/adkShim.ts).
|
|
50
|
+
*/
|
|
51
|
+
export declare function unrunnableModelClass(resolved: unknown): string | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* The NativeAgent for `spec`. Throws when no model id is known, and
|
|
54
|
+
* UnsupportedOnRuntimeError when the resolver returned an ADK model class
|
|
55
|
+
* the loop cannot call (see the header).
|
|
56
|
+
*/
|
|
57
|
+
export declare function compileNative(spec: AgentSpec): NativeAgent;
|
|
58
|
+
/**
|
|
59
|
+
* The model id a request is sent under, as ADK's LlmAgent sends it: the id
|
|
60
|
+
* of the model object the resolver returned (an ADK model or a contract
|
|
61
|
+
* adapter carries its own), else the id the resolver returned, else the
|
|
62
|
+
* spec's. A resolver may answer a YAML id with a model under another id (a
|
|
63
|
+
* gateway stand-in, a caller's alias); the adapter, the span and the
|
|
64
|
+
* circuit breaker then see that id on both runtimes.
|
|
65
|
+
*/
|
|
66
|
+
export declare function wireModelOf(spec: Pick<AgentSpec, 'modelId' | 'resolvedModel'>): string | undefined;
|
|
67
|
+
/** A syndicate's orchestrator for the native loop: compileSpec, then compileNative. */
|
|
68
|
+
export declare function compileNativeGraph(config: SyndicateYamlConfig, opts?: CompileOptions): Promise<NativeAgent>;
|
|
69
|
+
/** One subagent entry (a dispatch route) for the native loop: compileSubagentSpec, then compileNative. */
|
|
70
|
+
export declare function compileNativeSubagent(subCfg: SubagentYamlConfig, opts?: CompileOptions): Promise<NativeAgent>;
|
|
71
|
+
/** What nativeAdapterFor reads from a spec: its model resolution, the other ids it calls, and its delegated subagents. */
|
|
72
|
+
type NativeModelSpec = Pick<AgentSpec, 'modelId' | 'resolvedModel'> & Partial<Pick<AgentSpec, 'name' | 'fallbackModel' | 'context' | 'tools'>>;
|
|
73
|
+
/**
|
|
74
|
+
* The loop's `adapterFor` under the same model resolution the ADK runtime
|
|
75
|
+
* uses: the leaf adapter behind what CompileOptions.resolveModel returns
|
|
76
|
+
* (an ADK shim carries its contract adapter, so a caller's BYOK key on a
|
|
77
|
+
* shimmed provider reaches the call), else resolveAdapter for the id
|
|
78
|
+
* (lib/models/registry.ts). The spec's own resolution, and each delegated
|
|
79
|
+
* subagent's, is reused for the id its agent runs under (wireModelOf).
|
|
80
|
+
* Each agent's `fallback_model:` and compaction `summary_model` are
|
|
81
|
+
* resolved here, as compileAdk resolves them at compile time, so a model
|
|
82
|
+
* class native cannot run is refused before any model call; any other id
|
|
83
|
+
* is resolved when first asked for. Each is kept.
|
|
84
|
+
*/
|
|
85
|
+
export declare function nativeAdapterFor(opts?: CompileOptions, spec?: NativeModelSpec | readonly NativeModelSpec[]): (model: string) => ModelAdapter;
|