melchizedek-agents 0.20.0 → 1.0.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 +4 -5
- package/AGENT_SETUP.md +3 -3
- package/CHANGELOG.md +240 -0
- package/DOCUMENTATION.md +142 -150
- package/QUICKSTART.md +12 -11
- package/README.md +11 -11
- package/config/agents/examples/image_production.yaml +2 -2
- package/config/agents/syndicateSchema.yaml +52 -26
- package/dist/lib/a2a/app.d.ts +17 -12
- package/dist/lib/a2a/app.js +16 -6
- package/dist/lib/a2a/executor.d.ts +10 -14
- package/dist/lib/a2a/executor.js +10 -18
- package/dist/lib/a2a/remoteAgent.d.ts +5 -12
- package/dist/lib/a2a/remoteAgent.js +5 -12
- package/dist/lib/compile.d.ts +76 -86
- package/dist/lib/compile.js +100 -116
- package/dist/lib/compileNative.d.ts +44 -56
- package/dist/lib/compileNative.js +91 -89
- package/dist/lib/config.d.ts +6 -6
- package/dist/lib/config.js +6 -6
- package/dist/lib/doctor.d.ts +8 -14
- package/dist/lib/doctor.js +10 -46
- package/dist/lib/index.d.ts +12 -9
- package/dist/lib/index.js +10 -11
- package/dist/lib/loadSyndicate.d.ts +3 -3
- package/dist/lib/loadSyndicate.js +2 -2
- package/dist/lib/memory/erase.d.ts +1 -1
- package/dist/lib/memory/erase.js +1 -1
- package/dist/lib/memory/namespace.d.ts +12 -14
- package/dist/lib/memory/namespace.js +13 -14
- package/dist/lib/memory/providers.d.ts +4 -5
- package/dist/lib/memory/providers.js +12 -6
- package/dist/lib/memory/supabaseMemoryService.d.ts +9 -30
- package/dist/lib/memory/supabaseMemoryService.js +8 -30
- package/dist/lib/model.d.ts +6 -12
- package/dist/lib/model.js +6 -12
- package/dist/lib/models/adapterResolver.d.ts +21 -40
- package/dist/lib/models/adapterResolver.js +32 -40
- package/dist/lib/models/chatCompletionsAdapter.d.ts +12 -33
- package/dist/lib/models/chatCompletionsAdapter.js +13 -18
- package/dist/lib/models/circuitBreaker.d.ts +5 -5
- package/dist/lib/models/circuitBreaker.js +5 -5
- package/dist/lib/models/claudeAdapter.d.ts +9 -26
- package/dist/lib/models/claudeAdapter.js +11 -15
- package/dist/lib/models/claudeModels.d.ts +4 -4
- package/dist/lib/models/claudeModels.js +4 -4
- package/dist/lib/models/contract.d.ts +11 -11
- package/dist/lib/models/contract.js +6 -6
- package/dist/lib/models/errorResponse.d.ts +13 -20
- package/dist/lib/models/errorResponse.js +0 -12
- package/dist/lib/models/fallbackAdapter.d.ts +7 -8
- package/dist/lib/models/gatewayAdapter.d.ts +1 -1
- package/dist/lib/models/gatewayAdapter.js +1 -1
- package/dist/lib/models/geminiAdapter.d.ts +5 -6
- package/dist/lib/models/geminiAdapter.js +9 -10
- package/dist/lib/models/geminiState.d.ts +8 -8
- package/dist/lib/models/geminiState.js +8 -8
- package/dist/lib/models/genaiMapping.d.ts +82 -36
- package/dist/lib/models/genaiMapping.js +41 -41
- package/dist/lib/models/gptAdapter.d.ts +11 -11
- package/dist/lib/models/gptAdapter.js +13 -13
- package/dist/lib/models/kimiAdapter.d.ts +6 -7
- package/dist/lib/models/kimiAdapter.js +6 -9
- package/dist/lib/models/ollamaAdapter.d.ts +3 -3
- package/dist/lib/models/ollamaAdapter.js +3 -3
- package/dist/lib/models/providerMap.d.ts +6 -5
- package/dist/lib/models/providerMap.js +6 -5
- package/dist/lib/models/providerState.d.ts +3 -2
- package/dist/lib/models/providerState.js +3 -2
- package/dist/lib/models/reasoning.d.ts +1 -1
- package/dist/lib/models/registry.d.ts +26 -73
- package/dist/lib/models/registry.js +31 -144
- package/dist/lib/models/retry.d.ts +2 -2
- package/dist/lib/models/retry.js +2 -2
- package/dist/lib/models/schemaNormalize.d.ts +25 -55
- package/dist/lib/models/schemaNormalize.js +30 -100
- package/dist/lib/observability/lineage.d.ts +3 -3
- package/dist/lib/observability/lineage.js +10 -10
- package/dist/lib/observability/supabaseSpanExporter.js +1 -1
- package/dist/lib/observability/tracer.d.ts +25 -23
- package/dist/lib/observability/tracer.js +26 -63
- package/dist/lib/persistence/supabaseProvider.d.ts +4 -3
- package/dist/lib/runtime/approvals.d.ts +1 -1
- package/dist/lib/runtime/credentials.d.ts +1 -1
- package/dist/lib/runtime/events.d.ts +3 -4
- package/dist/lib/runtime/events.js +3 -4
- package/dist/lib/runtime/logging.d.ts +3 -8
- package/dist/lib/runtime/logging.js +3 -8
- package/dist/lib/runtime/memoryService.d.ts +4 -6
- package/dist/lib/runtime/memoryService.js +3 -5
- package/dist/lib/runtime/native/agentLoop.d.ts +18 -16
- package/dist/lib/runtime/native/agentLoop.js +38 -26
- package/dist/lib/runtime/native/compaction.d.ts +10 -11
- package/dist/lib/runtime/native/compaction.js +10 -11
- package/dist/lib/runtime/native/delegate.d.ts +13 -14
- package/dist/lib/runtime/native/delegate.js +11 -18
- package/dist/lib/runtime/native/history.d.ts +5 -6
- package/dist/lib/runtime/native/history.js +5 -6
- package/dist/lib/runtime/native/interrupts.d.ts +6 -6
- package/dist/lib/runtime/native/interrupts.js +6 -6
- package/dist/lib/runtime/native/request.d.ts +24 -24
- package/dist/lib/runtime/native/request.js +35 -24
- package/dist/lib/runtime/native/selfCorrection.d.ts +32 -32
- package/dist/lib/runtime/native/selfCorrection.js +34 -34
- package/dist/lib/runtime/native/step.d.ts +23 -23
- package/dist/lib/runtime/native/step.js +49 -27
- package/dist/lib/runtime/native/taskMode.d.ts +8 -8
- package/dist/lib/runtime/native/taskMode.js +8 -8
- package/dist/lib/runtime/native/telemetry.d.ts +11 -11
- package/dist/lib/runtime/native/telemetry.js +11 -11
- package/dist/lib/runtime/native/tempState.d.ts +4 -4
- package/dist/lib/runtime/native/tempState.js +4 -4
- package/dist/lib/runtime/nativeTurn.d.ts +29 -32
- package/dist/lib/runtime/nativeTurn.js +30 -41
- package/dist/lib/runtime/questions.d.ts +8 -9
- package/dist/lib/runtime/questions.js +1 -2
- package/dist/lib/runtime/runtimeFlag.d.ts +28 -14
- package/dist/lib/runtime/runtimeFlag.js +38 -16
- package/dist/lib/runtime/sessions.d.ts +10 -12
- package/dist/lib/runtime/sessions.js +10 -12
- package/dist/lib/runtime/syndicateTurn.d.ts +44 -45
- package/dist/lib/runtime/syndicateTurn.js +163 -158
- package/dist/lib/runtime/turnControl.d.ts +8 -8
- package/dist/lib/runtime/turnControl.js +8 -8
- package/dist/lib/session/supabaseSessionService.d.ts +7 -21
- package/dist/lib/session/supabaseSessionService.js +7 -43
- package/dist/lib/session/transcript.d.ts +16 -26
- package/dist/lib/session/transcript.js +17 -57
- package/dist/lib/storage/postgres/sessionService.d.ts +6 -20
- package/dist/lib/storage/postgres/sessionService.js +6 -39
- package/dist/lib/syndicateSchema.js +7 -6
- package/dist/lib/toolRegistry.d.ts +9 -14
- package/dist/lib/toolRegistry.js +36 -33
- package/dist/lib/tools/auth.d.ts +1 -1
- package/dist/lib/tools/auth.js +1 -1
- package/dist/lib/tools/examples.d.ts +2 -4
- package/dist/lib/tools/examples.js +2 -4
- package/dist/lib/tools/generateImageTool.d.ts +3 -3
- package/dist/lib/tools/generateImageTool.js +4 -5
- package/dist/lib/tools/inspectImageTool.d.ts +2 -2
- package/dist/lib/tools/inspectImageTool.js +3 -4
- package/dist/lib/tools/mcpToolFactory.d.ts +4 -24
- package/dist/lib/tools/mcpToolFactory.js +19 -9
- package/dist/lib/tools/memoryTools.d.ts +5 -6
- package/dist/lib/tools/memoryTools.js +5 -6
- package/dist/lib/tools/nativeTools.d.ts +9 -14
- package/dist/lib/tools/nativeTools.js +9 -14
- package/dist/lib/tools/openapiTools.d.ts +5 -7
- package/dist/lib/tools/openapiTools.js +6 -13
- package/dist/lib/tools/scienceTools.d.ts +3 -3
- package/dist/lib/tools/scienceTools.js +8 -10
- package/dist/lib/tools/skillToolset.d.ts +1 -2
- package/dist/lib/tools/skillToolset.js +1 -2
- package/dist/lib/tools/skills/executor.d.ts +1 -1
- package/dist/lib/tools/skills/executor.js +1 -1
- package/dist/lib/tools/skills/frontmatter.d.ts +2 -2
- package/dist/lib/tools/skills/frontmatter.js +2 -2
- package/dist/lib/tools/skills/tools.d.ts +8 -10
- package/dist/lib/tools/skills/tools.js +9 -11
- package/dist/lib/tools/tool.d.ts +24 -40
- package/dist/lib/tools/tool.js +24 -56
- package/dist/lib/tools/toolContract.d.ts +8 -13
- package/dist/lib/tools/toolContract.js +6 -17
- package/dist/lib/tools/webExtractTool.d.ts +2 -2
- package/dist/lib/tools/webExtractTool.js +3 -4
- package/dist/lib/tools/wikiTools.d.ts +2 -2
- package/dist/lib/tools/wikiTools.js +5 -6
- package/dist/lib/tools/xApiSearchTool.d.ts +2 -2
- package/dist/lib/tools/xApiSearchTool.js +3 -4
- package/dist/lib/tools/xaiSearchParams.d.ts +2 -5
- package/dist/lib/tools/xaiSearchParams.js +2 -5
- package/dist/lib/wiki/agentRun.d.ts +10 -11
- package/dist/lib/wiki/agentRun.js +24 -42
- package/dist/lib/workflow/agentNode.d.ts +10 -1
- package/dist/lib/workflow/agentNode.js +5 -3
- package/dist/lib/workflow/graph.d.ts +8 -9
- package/dist/lib/workflow/graph.js +12 -12
- package/dist/lib/workflow/nodeEvents.d.ts +5 -5
- package/dist/lib/workflow/nodeEvents.js +5 -5
- package/dist/lib/workflow/pause.d.ts +5 -4
- package/dist/lib/workflow/pause.js +5 -4
- package/dist/lib/workflow/resume.d.ts +4 -4
- package/dist/lib/workflow/resume.js +4 -4
- package/dist/lib/workflow/route.d.ts +7 -7
- package/dist/lib/workflow/route.js +8 -8
- package/dist/lib/workflow/scheduler.d.ts +44 -2
- package/dist/lib/workflow/scheduler.js +60 -6
- package/dist/lib/workflow/toolNode.d.ts +18 -29
- package/dist/lib/workflow/toolNode.js +29 -35
- package/dist/lib/workflow/turn.d.ts +29 -20
- package/dist/lib/workflow/turn.js +111 -24
- package/dist/lib/workflow.d.ts +34 -60
- package/dist/lib/workflow.js +34 -168
- package/dist/lib/workflowConfig.d.ts +2 -10
- package/dist/lib/workflowConfig.js +2 -31
- package/dist/scripts/a2a_server.js +1 -2
- package/dist/scripts/assistant_worker.d.ts +2 -2
- package/dist/scripts/assistant_worker.js +8 -7
- package/dist/scripts/doctor.d.ts +2 -2
- package/dist/scripts/doctor.js +2 -2
- package/dist/scripts/syndicate_chat.js +14 -24
- package/package.json +3 -9
- package/skills/briefs/_shared.md +2 -2
- package/skills/briefs/melchizedek-author.md +2 -2
- package/skills/briefs/melchizedek-models.md +6 -6
- package/skills/melchizedek-author/SKILL.md +2 -2
- package/skills/melchizedek-models/SKILL.md +5 -5
package/dist/lib/compile.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* lib/compile.ts — the one YAML → agent compiler:
|
|
3
|
-
*
|
|
2
|
+
* lib/compile.ts — the one YAML → agent compiler: an AgentSpec per agent,
|
|
3
|
+
* which lib/compileNative.ts turns into what the runtime runs.
|
|
4
4
|
*
|
|
5
5
|
* WHY this file exists:
|
|
6
6
|
* The A2A server carried this logic as two closures inside its executor,
|
|
@@ -12,44 +12,40 @@
|
|
|
12
12
|
* So the compiler moved here and both callers import it.
|
|
13
13
|
*
|
|
14
14
|
* What it does NOT own: model resolution and nested-config loading. Both are
|
|
15
|
-
* injected, because the
|
|
16
|
-
* - the A2A server resolves `model` to a
|
|
15
|
+
* injected, because the callers differ precisely there:
|
|
16
|
+
* - the A2A server resolves `model` to a ModelAdapter carrying the
|
|
17
17
|
* caller's BYOK key (lib/models/registry.ts resolveModel);
|
|
18
|
-
* - the observatory passes the model id through as a string (the
|
|
19
|
-
*
|
|
20
|
-
* per-variant overrides already applied.
|
|
18
|
+
* - the observatory passes the model id through as a string (the loop
|
|
19
|
+
* resolves it, lib/models/registry.ts resolveAdapter) and loads nested
|
|
20
|
+
* syndicates with its per-variant overrides already applied.
|
|
21
21
|
*
|
|
22
22
|
* ── Two orchestration methods, one compiler ───────────────────────────────
|
|
23
|
-
* DELEGATE (no `dispatch:` block): every subagent becomes
|
|
24
|
-
* the orchestrator. PLAN-DISPATCH (`dispatch:` present): the orchestrator
|
|
23
|
+
* DELEGATE (no `dispatch:` block): every subagent becomes a delegation tool
|
|
24
|
+
* on the orchestrator. PLAN-DISPATCH (`dispatch:` present): the orchestrator
|
|
25
25
|
* is compiled WITHOUT subagent tools — it is a pure classifier — and the
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
26
|
+
* turn runner compiles the chosen route's own spec. Both paths build
|
|
27
|
+
* subagents through the same function, so the agent a route dispatches to
|
|
28
|
+
* is identical to the one DELEGATE would have delegated to.
|
|
29
29
|
* Contract and rationale: lib/dispatch.ts.
|
|
30
30
|
*
|
|
31
|
-
* ──
|
|
32
|
-
* compileSpec and compileSubagentSpec
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
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.
|
|
31
|
+
* ── The spec (ADR 0073, ADR 0107) ─────────────────────────────────────────
|
|
32
|
+
* compileSpec and compileSubagentSpec resolve and gate the tools, append the
|
|
33
|
+
* skills index, resolve the model once and build the generateContentConfig.
|
|
34
|
+
* The result is an AgentSpec; lib/compileNative.ts builds the loop's
|
|
35
|
+
* NativeAgent from it.
|
|
39
36
|
*/
|
|
40
|
-
import { BaseLlm, FunctionTool } from './adkPeer.ts';
|
|
41
|
-
import type { BaseTool, LlmAgent } from '@google/adk';
|
|
42
37
|
import type { ReasoningSetting, SubagentYamlConfig, SyndicateYamlConfig } from './loadSyndicate.ts';
|
|
38
|
+
import type { ModelAdapter } from './models/contract.ts';
|
|
43
39
|
import type { ExampleConfig } from './tools/examples.ts';
|
|
44
40
|
import type { SkillsConfig } from './tools/skillToolset.ts';
|
|
45
41
|
export interface CompileOptions {
|
|
46
42
|
/**
|
|
47
|
-
* Turns the YAML `model` string into what
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* The A2A server substitutes a BYOK
|
|
43
|
+
* Turns the YAML `model` string into what the agent runs on: a model id,
|
|
44
|
+
* or a ModelAdapter (lib/models/contract.ts). Default: identity — the id
|
|
45
|
+
* resolves through lib/models/registry.ts resolveAdapter when the agent
|
|
46
|
+
* first calls it. The A2A server substitutes a BYOK adapter factory here.
|
|
51
47
|
*/
|
|
52
|
-
resolveModel?: (model: string | undefined) => string |
|
|
48
|
+
resolveModel?: (model: string | undefined) => string | ModelAdapter | undefined;
|
|
53
49
|
/**
|
|
54
50
|
* Loads a nested `yaml_reference:` syndicate. Default: `loadSyndicate(ref)`
|
|
55
51
|
* with no bindings — the same call the server makes. The observatory wraps
|
|
@@ -60,12 +56,6 @@ export interface CompileOptions {
|
|
|
60
56
|
onUnknownTool?: (name: string) => void;
|
|
61
57
|
/** Progress/diagnostic line sink (nested loads, MCP discovery). */
|
|
62
58
|
log?: (message: string) => void;
|
|
63
|
-
/**
|
|
64
|
-
* Node settings for an agent compiled as a workflow node (lib/workflow.ts):
|
|
65
|
-
* ADK's `retryConfig` and `timeout`, which an LlmAgent takes only at
|
|
66
|
-
* construction. Called with the agent's name; undefined means none.
|
|
67
|
-
*/
|
|
68
|
-
nodeConfig?: (agentName: string) => Record<string, unknown> | undefined;
|
|
69
59
|
}
|
|
70
60
|
export { REASONING_BUDGETS, reasoningConfig } from './models/reasoning.ts';
|
|
71
61
|
/**
|
|
@@ -79,36 +69,17 @@ export declare function withReasoning(agent: {
|
|
|
79
69
|
reasoning?: ReasoningSetting;
|
|
80
70
|
generateContentConfig?: object;
|
|
81
71
|
}, model: string | undefined): Record<string, unknown> | undefined;
|
|
82
|
-
/** An agent's `context:` block and its default, owned by the
|
|
72
|
+
/** An agent's `context:` block and its default, owned by the compactor (ADR 0033). */
|
|
83
73
|
export type { ContextConfig } from './runtime/native/compaction.ts';
|
|
84
74
|
import type { ContextConfig } from './runtime/native/compaction.ts';
|
|
85
75
|
export { DEFAULT_KEEP_RECENT_EVENTS } from './runtime/native/compaction.ts';
|
|
86
|
-
/**
|
|
87
|
-
* A copy of a FunctionTool that runs only after a person approves the call
|
|
88
|
-
* (ADR 0028). ADK's own gate does the work: the call raises an
|
|
89
|
-
* `adk_request_confirmation` interrupt pinning the call and its arguments,
|
|
90
|
-
* and only an approval bound to that exact call runs it. The original stays
|
|
91
|
-
* ungated for every other agent that lists the same tool.
|
|
92
|
-
*/
|
|
93
|
-
export declare function requireApprovalOn(tool: FunctionTool): FunctionTool;
|
|
94
|
-
/**
|
|
95
|
-
* A copy of an ADK BaseTool that runs only after a person approves the
|
|
96
|
-
* call: the same confirmation interrupt FunctionTool's own gate raises, so
|
|
97
|
-
* the turn pauses and resumes exactly as ADR 0028 says. The engine no
|
|
98
|
-
* longer uses it: an OpenAPI operation is a FunctionTool over an own Tool
|
|
99
|
-
* (ADR 0067) and takes requireApprovalOn like every registry tool.
|
|
100
|
-
* @deprecated Gate a FunctionTool with requireApprovalOn, or an own Tool
|
|
101
|
-
* with requireApproval (lib/tools/tool.ts).
|
|
102
|
-
*/
|
|
103
|
-
export declare function requireApprovalOnBaseTool<T extends BaseTool>(tool: T): T;
|
|
104
76
|
/** True when any agent of a syndicate may pause for approval: a gated tool, or skill scripts. */
|
|
105
77
|
export declare function declaresApprovals(config: SyndicateYamlConfig): boolean;
|
|
106
78
|
export type { ExampleConfig };
|
|
107
79
|
/**
|
|
108
|
-
* An agent's `examples:` as
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
* ExampleTool used.
|
|
80
|
+
* An agent's `examples:` as their InstructionTool (lib/tools/examples.ts):
|
|
81
|
+
* never called by the model, it adds the exchanges to every request's
|
|
82
|
+
* instruction as few-shot examples, in the words ADK's ExampleTool used.
|
|
112
83
|
*/
|
|
113
84
|
export declare function examplesTool(examples: ExampleConfig[] | undefined): unknown[];
|
|
114
85
|
/** True when a turn running this agent directly may pause for a person (ADR 0028). */
|
|
@@ -118,10 +89,9 @@ export declare function agentGates(agent: {
|
|
|
118
89
|
} | undefined): boolean;
|
|
119
90
|
/**
|
|
120
91
|
* One entry of an agent's tool list, in the order the model sees it.
|
|
121
|
-
* `tool` is a resolved tool as the registry gives it:
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* require_approval where the YAML says so. `agent` is a delegated subagent
|
|
92
|
+
* `tool` is a resolved tool as the registry gives it: an own Tool,
|
|
93
|
+
* InstructionTool, NativeToolMarker or Toolset (lib/tools/tool.ts), gated
|
|
94
|
+
* by require_approval where the YAML says so. `agent` is a delegated subagent
|
|
125
95
|
* (DELEGATE mode), `remote` a subagent served over A2A, `workflow` a
|
|
126
96
|
* `yaml_reference` to a workflow syndicate, whose whole graph is the tool
|
|
127
97
|
* (ADR 0098).
|
|
@@ -142,11 +112,10 @@ export type SpecTool = {
|
|
|
142
112
|
workflow: WorkflowSpec;
|
|
143
113
|
};
|
|
144
114
|
/**
|
|
145
|
-
* A workflow syndicate, compiled
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
* root of every node path, as ADK names a Workflow's nodes after it.
|
|
115
|
+
* A workflow syndicate, compiled: lib/compileNative.ts builds the walk's
|
|
116
|
+
* graph and agents from it. Nested as a subagent (a `yaml_reference` in
|
|
117
|
+
* DELEGATE mode), the graph runs under the entry's name and description,
|
|
118
|
+
* and that name is the root of every node path.
|
|
150
119
|
*/
|
|
151
120
|
export interface WorkflowSpec {
|
|
152
121
|
/** The workflow's name: the syndicate's, or the subagent entry's when nested. */
|
|
@@ -160,12 +129,20 @@ export interface WorkflowSpec {
|
|
|
160
129
|
yaml: SubagentYamlConfig;
|
|
161
130
|
spec: AgentSpec;
|
|
162
131
|
}>;
|
|
132
|
+
/**
|
|
133
|
+
* Every node that is a `yaml_reference` to a workflow syndicate, with its
|
|
134
|
+
* YAML entry: the nested graph under the entry's name (ADR 0106). The
|
|
135
|
+
* walk runs it as the node, on its own child session.
|
|
136
|
+
*/
|
|
137
|
+
workflows: Array<{
|
|
138
|
+
yaml: SubagentYamlConfig;
|
|
139
|
+
workflow: WorkflowSpec;
|
|
140
|
+
}>;
|
|
163
141
|
/** The registry entry for a tool node's tool name, or undefined (CompileOptions.onUnknownTool applies). */
|
|
164
142
|
resolveTool: (name: string) => unknown;
|
|
165
143
|
}
|
|
166
144
|
/**
|
|
167
|
-
* One YAML agent, compiled
|
|
168
|
-
* turns into ADK's LlmAgent and lib/compileNative.ts into the native loop's
|
|
145
|
+
* One YAML agent, compiled: what lib/compileNative.ts turns into the loop's
|
|
169
146
|
* NativeAgent. Built once per agent by compileSpec and compileSubagentSpec:
|
|
170
147
|
* the tools resolved (OpenAPI operations built, MCP tools listed) and
|
|
171
148
|
* gated, the skills index appended to the instruction, the model resolved
|
|
@@ -181,14 +158,14 @@ export interface AgentSpec {
|
|
|
181
158
|
resolvedModel?: unknown;
|
|
182
159
|
/** The id the agent runs on: the YAML's, else the resolved adapter's. */
|
|
183
160
|
modelId?: string;
|
|
184
|
-
/** `fallback_model:`, unresolved:
|
|
161
|
+
/** `fallback_model:`, unresolved: the loop resolves it where it calls it. */
|
|
185
162
|
fallbackModel?: string;
|
|
186
163
|
/** The YAML instruction, with the skills index appended when the agent has `skills:`. */
|
|
187
164
|
instruction: string;
|
|
188
165
|
globalInstruction?: string;
|
|
189
166
|
tools: SpecTool[];
|
|
190
167
|
outputSchema?: Record<string, unknown>;
|
|
191
|
-
/** The YAML's config with `reasoning:` mapped in and server-side tool invocations on
|
|
168
|
+
/** The YAML's config with `reasoning:` mapped in and server-side tool invocations on. */
|
|
192
169
|
generateContentConfig: Record<string, unknown>;
|
|
193
170
|
includeContents?: 'default' | 'none';
|
|
194
171
|
outputKey?: string;
|
|
@@ -209,33 +186,46 @@ export interface AgentSpec {
|
|
|
209
186
|
*
|
|
210
187
|
* A nested workflow runs inside its caller's tool call, so a pause inside it
|
|
211
188
|
* could not reach the caller (ADR 0028, as for any nested syndicate): an
|
|
212
|
-
* `ask_user` node is refused by name here
|
|
189
|
+
* `ask_user` node is refused by name here.
|
|
213
190
|
*/
|
|
214
191
|
export declare function compileWorkflowSpec(config: SyndicateYamlConfig, opts?: CompileOptions, name?: string, description?: string, ref?: string): Promise<WorkflowSpec>;
|
|
192
|
+
/** Every agent spec a workflow runs, its nested workflow nodes' agents included, for one adapter lookup (nativeAdapterFor). */
|
|
193
|
+
export declare function workflowAgentSpecs(spec: WorkflowSpec): AgentSpec[];
|
|
194
|
+
/** A subagent entry, compiled: one agent, or a nested workflow syndicate's whole graph (ADR 0098, ADR 0106). */
|
|
195
|
+
export type EntrySpec = {
|
|
196
|
+
kind: 'agent';
|
|
197
|
+
spec: AgentSpec;
|
|
198
|
+
} | {
|
|
199
|
+
kind: 'workflow';
|
|
200
|
+
workflow: WorkflowSpec;
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* A subagent entry as what it runs: an inline agent or a nested syndicate's
|
|
204
|
+
* orchestrator as one agent, or a `yaml_reference` to a workflow syndicate
|
|
205
|
+
* as its whole graph under the entry's name and description. A delegated
|
|
206
|
+
* subagent, a dispatch route and a workflow node all compile through here,
|
|
207
|
+
* so the graph a file describes is the graph that runs (ADR 0106).
|
|
208
|
+
*/
|
|
209
|
+
export declare function compileEntrySpec(subCfg: SubagentYamlConfig, opts?: CompileOptions): Promise<EntrySpec>;
|
|
210
|
+
/**
|
|
211
|
+
* The names of a syndicate's subagent entries that are `yaml_reference`s to
|
|
212
|
+
* a workflow syndicate. Loads each reference once and compiles nothing, so a
|
|
213
|
+
* runtime can refuse what it cannot run before the session is touched.
|
|
214
|
+
*/
|
|
215
|
+
export declare function workflowEntryNames(config: SyndicateYamlConfig, opts?: CompileOptions): string[];
|
|
215
216
|
/**
|
|
216
217
|
* The spec of ONE agent from a subagent entry. A `yaml_reference` entry is
|
|
217
|
-
* the nested syndicate's
|
|
218
|
-
* description,
|
|
218
|
+
* the nested syndicate's orchestrator under this entry's name and
|
|
219
|
+
* description, its own subagents delegated to as in any DELEGATE graph. A
|
|
220
|
+
* `yaml_reference` to a workflow syndicate has no one agent to build: it
|
|
221
|
+
* runs as its whole graph (compileEntrySpec), and is refused here by name.
|
|
219
222
|
*/
|
|
220
223
|
export declare function compileSubagentSpec(subCfg: SubagentYamlConfig, opts?: CompileOptions): Promise<AgentSpec>;
|
|
221
224
|
/**
|
|
222
225
|
* The spec of a syndicate's orchestrator. In DELEGATE mode its subagents
|
|
223
226
|
* come first among its tools, as delegations; in PLAN-DISPATCH mode it gets
|
|
224
|
-
* none (
|
|
227
|
+
* none (a classifier answers with its outputSchema — see
|
|
225
228
|
* config/agents/critic.yaml), and the caller dispatches to a route's own
|
|
226
229
|
* spec itself.
|
|
227
230
|
*/
|
|
228
231
|
export declare function compileSpec(config: SyndicateYamlConfig, opts?: CompileOptions, overrideName?: string, overrideDescription?: string): Promise<AgentSpec>;
|
|
229
|
-
/**
|
|
230
|
-
* Builds ONE runnable ADK agent from a subagent entry: its spec, as
|
|
231
|
-
* lib/compileAdk.ts builds it. A workflow node's settings
|
|
232
|
-
* (CompileOptions.nodeConfig) apply to a local agent, not to a nested
|
|
233
|
-
* syndicate's orchestrator.
|
|
234
|
-
*/
|
|
235
|
-
export declare function compileSubagent(subCfg: SubagentYamlConfig, opts?: CompileOptions): Promise<LlmAgent>;
|
|
236
|
-
/**
|
|
237
|
-
* Compiles a syndicate's orchestrator for the ADK runtime. In DELEGATE mode
|
|
238
|
-
* its subagents are attached as AgentTools; in PLAN-DISPATCH mode it gets
|
|
239
|
-
* none, and the caller dispatches to `compileSubagent(route)` itself.
|
|
240
|
-
*/
|
|
241
|
-
export declare function compileGraph(config: SyndicateYamlConfig, opts?: CompileOptions, overrideName?: string, overrideDescription?: string): Promise<LlmAgent>;
|
package/dist/lib/compile.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* lib/compile.ts — the one YAML → agent compiler:
|
|
3
|
-
*
|
|
2
|
+
* lib/compile.ts — the one YAML → agent compiler: an AgentSpec per agent,
|
|
3
|
+
* which lib/compileNative.ts turns into what the runtime runs.
|
|
4
4
|
*
|
|
5
5
|
* WHY this file exists:
|
|
6
6
|
* The A2A server carried this logic as two closures inside its executor,
|
|
@@ -12,34 +12,29 @@
|
|
|
12
12
|
* So the compiler moved here and both callers import it.
|
|
13
13
|
*
|
|
14
14
|
* What it does NOT own: model resolution and nested-config loading. Both are
|
|
15
|
-
* injected, because the
|
|
16
|
-
* - the A2A server resolves `model` to a
|
|
15
|
+
* injected, because the callers differ precisely there:
|
|
16
|
+
* - the A2A server resolves `model` to a ModelAdapter carrying the
|
|
17
17
|
* caller's BYOK key (lib/models/registry.ts resolveModel);
|
|
18
|
-
* - the observatory passes the model id through as a string (the
|
|
19
|
-
*
|
|
20
|
-
* per-variant overrides already applied.
|
|
18
|
+
* - the observatory passes the model id through as a string (the loop
|
|
19
|
+
* resolves it, lib/models/registry.ts resolveAdapter) and loads nested
|
|
20
|
+
* syndicates with its per-variant overrides already applied.
|
|
21
21
|
*
|
|
22
22
|
* ── Two orchestration methods, one compiler ───────────────────────────────
|
|
23
|
-
* DELEGATE (no `dispatch:` block): every subagent becomes
|
|
24
|
-
* the orchestrator. PLAN-DISPATCH (`dispatch:` present): the orchestrator
|
|
23
|
+
* DELEGATE (no `dispatch:` block): every subagent becomes a delegation tool
|
|
24
|
+
* on the orchestrator. PLAN-DISPATCH (`dispatch:` present): the orchestrator
|
|
25
25
|
* is compiled WITHOUT subagent tools — it is a pure classifier — and the
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
26
|
+
* turn runner compiles the chosen route's own spec. Both paths build
|
|
27
|
+
* subagents through the same function, so the agent a route dispatches to
|
|
28
|
+
* is identical to the one DELEGATE would have delegated to.
|
|
29
29
|
* Contract and rationale: lib/dispatch.ts.
|
|
30
30
|
*
|
|
31
|
-
* ──
|
|
32
|
-
* compileSpec and compileSubagentSpec
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
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.
|
|
31
|
+
* ── The spec (ADR 0073, ADR 0107) ─────────────────────────────────────────
|
|
32
|
+
* compileSpec and compileSubagentSpec resolve and gate the tools, append the
|
|
33
|
+
* skills index, resolve the model once and build the generateContentConfig.
|
|
34
|
+
* The result is an AgentSpec; lib/compileNative.ts builds the loop's
|
|
35
|
+
* NativeAgent from it.
|
|
39
36
|
*/
|
|
40
|
-
import { BaseLlm, FunctionTool } from './adkPeer.js';
|
|
41
37
|
import { relative } from 'node:path';
|
|
42
|
-
import { compileAdk } from './compileAdk.js';
|
|
43
38
|
import { isDispatchSyndicate } from './dispatch.js';
|
|
44
39
|
import { isWorkflowSyndicate, nodeKind } from './workflowConfig.js';
|
|
45
40
|
import { loadSyndicate, nestedLoader } from './loadSyndicate.js';
|
|
@@ -47,12 +42,12 @@ import { REASONING_OLDER_SPELLING } from './syndicateSchema.js';
|
|
|
47
42
|
import { reasoningConfig } from './models/reasoning.js';
|
|
48
43
|
import { resolveTools as resolveNamedTools } from './toolRegistry.js';
|
|
49
44
|
import { createMcpTools } from './tools/mcpToolFactory.js';
|
|
50
|
-
import {
|
|
45
|
+
import { requireApproval, toolOf } from './tools/tool.js';
|
|
51
46
|
import { examplesInstructionTool } from './tools/examples.js';
|
|
52
47
|
import { capabilitySummary, describeCapabilities } from './models/capabilities.js';
|
|
53
48
|
import { buildSkillHarness } from './tools/skillToolset.js';
|
|
54
49
|
import { buildOpenApiTools, namesTool, openApiOperationId } from './tools/openapiTools.js';
|
|
55
|
-
/** generateContentConfig as every entrypoint
|
|
50
|
+
/** generateContentConfig as every entrypoint sends it: server-side tool invocations on. */
|
|
56
51
|
function withServerSideToolInvocations(generateContentConfig) {
|
|
57
52
|
const cfg = (generateContentConfig ?? {});
|
|
58
53
|
return {
|
|
@@ -65,7 +60,7 @@ function withServerSideToolInvocations(generateContentConfig) {
|
|
|
65
60
|
}
|
|
66
61
|
// ── Reasoning (ADR 0047) ─────────────────────────────────────────────────────
|
|
67
62
|
// REASONING_BUDGETS and reasoningConfig live in lib/models/reasoning.ts, so a
|
|
68
|
-
// model adapter can map `reasoning:` without importing the compiler
|
|
63
|
+
// model adapter can map `reasoning:` without importing the compiler.
|
|
69
64
|
export { REASONING_BUDGETS, reasoningConfig } from './models/reasoning.js';
|
|
70
65
|
/**
|
|
71
66
|
* An agent's generateContentConfig with its `reasoning:` key mapped in for
|
|
@@ -85,7 +80,12 @@ export function withReasoning(agent, model) {
|
|
|
85
80
|
}
|
|
86
81
|
/** The model id an agent runs on, from its YAML or its resolved adapter. */
|
|
87
82
|
function modelIdOf(yamlModel, resolved) {
|
|
88
|
-
|
|
83
|
+
if (yamlModel !== undefined)
|
|
84
|
+
return yamlModel;
|
|
85
|
+
if (typeof resolved === 'string')
|
|
86
|
+
return resolved;
|
|
87
|
+
const own = resolved && typeof resolved === 'object' ? resolved.model : undefined;
|
|
88
|
+
return typeof own === 'string' ? own : undefined;
|
|
89
89
|
}
|
|
90
90
|
export { DEFAULT_KEEP_RECENT_EVENTS } from './runtime/native/compaction.js';
|
|
91
91
|
/**
|
|
@@ -103,44 +103,6 @@ function logCapabilities(opts, agentName, model, tools) {
|
|
|
103
103
|
if (line)
|
|
104
104
|
opts.log(`capability · ${line}`);
|
|
105
105
|
}
|
|
106
|
-
/**
|
|
107
|
-
* A copy of a FunctionTool that runs only after a person approves the call
|
|
108
|
-
* (ADR 0028). ADK's own gate does the work: the call raises an
|
|
109
|
-
* `adk_request_confirmation` interrupt pinning the call and its arguments,
|
|
110
|
-
* and only an approval bound to that exact call runs it. The original stays
|
|
111
|
-
* ungated for every other agent that lists the same tool.
|
|
112
|
-
*/
|
|
113
|
-
export function requireApprovalOn(tool) {
|
|
114
|
-
const gated = Object.create(tool);
|
|
115
|
-
Object.defineProperty(gated, 'requireConfirmation', { value: true, enumerable: false });
|
|
116
|
-
return gated;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* A copy of an ADK BaseTool that runs only after a person approves the
|
|
120
|
-
* call: the same confirmation interrupt FunctionTool's own gate raises, so
|
|
121
|
-
* the turn pauses and resumes exactly as ADR 0028 says. The engine no
|
|
122
|
-
* longer uses it: an OpenAPI operation is a FunctionTool over an own Tool
|
|
123
|
-
* (ADR 0067) and takes requireApprovalOn like every registry tool.
|
|
124
|
-
* @deprecated Gate a FunctionTool with requireApprovalOn, or an own Tool
|
|
125
|
-
* with requireApproval (lib/tools/tool.ts).
|
|
126
|
-
*/
|
|
127
|
-
export function requireApprovalOnBaseTool(tool) {
|
|
128
|
-
const gated = Object.create(tool);
|
|
129
|
-
Object.defineProperty(gated, 'runAsync', {
|
|
130
|
-
value: async (request) => {
|
|
131
|
-
const ctx = request.toolContext;
|
|
132
|
-
if (!ctx.toolConfirmation) {
|
|
133
|
-
ctx.requestConfirmation({ hint: `Approval is required before ${tool.name} runs.`, payload: request.args });
|
|
134
|
-
ctx.actions.skipSummarization = true;
|
|
135
|
-
return { error: 'This call requires approval, please approve or reject.' };
|
|
136
|
-
}
|
|
137
|
-
if (!ctx.toolConfirmation.confirmed)
|
|
138
|
-
return { error: 'This call was rejected.' };
|
|
139
|
-
return tool.runAsync(request);
|
|
140
|
-
},
|
|
141
|
-
});
|
|
142
|
-
return gated;
|
|
143
|
-
}
|
|
144
106
|
function gateTools(tools, names, agentName) {
|
|
145
107
|
if (!names?.length)
|
|
146
108
|
return tools;
|
|
@@ -155,11 +117,12 @@ function gateTools(tools, names, agentName) {
|
|
|
155
117
|
if (!match)
|
|
156
118
|
return t;
|
|
157
119
|
wanted.delete(match);
|
|
158
|
-
//
|
|
159
|
-
|
|
160
|
-
|
|
120
|
+
// A registry tool, an OpenAPI operation and an MCP tool are own Tools (ADR 0067): one gate for all.
|
|
121
|
+
const own = toolOf(t);
|
|
122
|
+
if (!own) {
|
|
123
|
+
throw new Error(`${agentName}: '${name}' cannot require approval — only function tools from the registry, OpenAPI operations and MCP tools can be gated (ADR 0028).`);
|
|
161
124
|
}
|
|
162
|
-
return
|
|
125
|
+
return requireApproval(own);
|
|
163
126
|
});
|
|
164
127
|
if (wanted.size) {
|
|
165
128
|
// Fail closed: a gate on a tool that did not resolve must not leave an
|
|
@@ -173,14 +136,13 @@ export function declaresApprovals(config) {
|
|
|
173
136
|
return agentGates(config.orchestrator) || (config.subagents ?? []).some((s) => agentGates(s));
|
|
174
137
|
}
|
|
175
138
|
/**
|
|
176
|
-
* An agent's `examples:` as
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
* ExampleTool used.
|
|
139
|
+
* An agent's `examples:` as their InstructionTool (lib/tools/examples.ts):
|
|
140
|
+
* never called by the model, it adds the exchanges to every request's
|
|
141
|
+
* instruction as few-shot examples, in the words ADK's ExampleTool used.
|
|
180
142
|
*/
|
|
181
143
|
export function examplesTool(examples) {
|
|
182
144
|
const tool = examplesInstructionTool(examples);
|
|
183
|
-
return tool ? [
|
|
145
|
+
return tool ? [tool] : [];
|
|
184
146
|
}
|
|
185
147
|
async function resolveAgentTools(toolNames, mcpServerUrl, opts, openapi, examples, mcpAllowed) {
|
|
186
148
|
const tools = [...resolveNamedTools(toolNames, opts.onUnknownTool), ...examplesTool(examples)];
|
|
@@ -233,8 +195,7 @@ async function withSkills(instruction, tools, skills, agentName, opts) {
|
|
|
233
195
|
opts.log?.(`skills · ${agentName}: ${count} skill${count === 1 ? '' : 's'} from ${skills.dir}${skills.scripts === 'local' ? ' · scripts run after approval' : ''}`);
|
|
234
196
|
for (const problem of harness.problems)
|
|
235
197
|
opts.log?.(`⚠ skills · ${skills.dir}: not loaded — ${problem}`);
|
|
236
|
-
|
|
237
|
-
return { instruction: `${instruction.trimEnd()}\n\n${harness.instruction}`, tools: [...tools, toAdkToolset(harness.toolset)] };
|
|
198
|
+
return { instruction: `${instruction.trimEnd()}\n\n${harness.instruction}`, tools: [...tools, harness.toolset] };
|
|
238
199
|
}
|
|
239
200
|
/** True when a turn running this agent directly may pause for a person (ADR 0028). */
|
|
240
201
|
export function agentGates(agent) {
|
|
@@ -320,7 +281,7 @@ function loadNestedSyndicate(ref, opts) {
|
|
|
320
281
|
*
|
|
321
282
|
* A nested workflow runs inside its caller's tool call, so a pause inside it
|
|
322
283
|
* could not reach the caller (ADR 0028, as for any nested syndicate): an
|
|
323
|
-
* `ask_user` node is refused by name here
|
|
284
|
+
* `ask_user` node is refused by name here.
|
|
324
285
|
*/
|
|
325
286
|
export async function compileWorkflowSpec(config, opts = {}, name, description, ref) {
|
|
326
287
|
if (!isWorkflowSyndicate(config))
|
|
@@ -328,26 +289,72 @@ export async function compileWorkflowSpec(config, opts = {}, name, description,
|
|
|
328
289
|
if (name) {
|
|
329
290
|
const asking = Object.entries(config.workflow.nodes ?? {}).find(([, node]) => nodeKind(node) === 'ask_user');
|
|
330
291
|
if (asking) {
|
|
331
|
-
throw new Error(`${ref ?? config.syndicate_name}: the ask_user node '${asking[0]}' pauses for a person, which a workflow nested
|
|
292
|
+
throw new Error(`${ref ?? config.syndicate_name}: the ask_user node '${asking[0]}' pauses for a person, which a workflow nested in another syndicate (${name}) cannot carry to its caller; run the workflow as its own syndicate, or remove the node.`);
|
|
332
293
|
}
|
|
333
294
|
}
|
|
334
295
|
const workflowName = name || config.syndicate_name;
|
|
335
296
|
const agents = [];
|
|
297
|
+
const workflows = [];
|
|
336
298
|
for (const yaml of [{ description: '', ...config.orchestrator }, ...(config.subagents ?? [])]) {
|
|
337
|
-
|
|
299
|
+
const entry = await compileEntrySpec(yaml, opts);
|
|
300
|
+
if (entry.kind === 'workflow')
|
|
301
|
+
workflows.push({ yaml, workflow: entry.workflow });
|
|
302
|
+
else
|
|
303
|
+
agents.push({ yaml, spec: entry.spec });
|
|
304
|
+
}
|
|
305
|
+
// A map runs one agent per item; a nested graph is not an agent a map item can be (ADR 0106).
|
|
306
|
+
for (const [node, entry] of Object.entries(config.workflow.nodes ?? {})) {
|
|
307
|
+
const mapped = nodeKind(entry) === 'map' ? workflows.find((w) => w.yaml.name === entry.map) : undefined;
|
|
308
|
+
if (mapped) {
|
|
309
|
+
throw new Error(`${ref ?? config.syndicate_name}: the map node '${node}' runs '${mapped.yaml.name}', a workflow syndicate (${mapped.yaml.yaml_reference}); a map runs one agent per item, so make the workflow a node of its own.`);
|
|
310
|
+
}
|
|
338
311
|
}
|
|
339
312
|
return {
|
|
340
313
|
name: workflowName,
|
|
341
314
|
description: description ?? '',
|
|
342
315
|
config: { ...config, syndicate_name: workflowName },
|
|
343
316
|
agents,
|
|
317
|
+
workflows,
|
|
344
318
|
resolveTool: (tool) => resolveNamedTools([tool], opts.onUnknownTool)[0],
|
|
345
319
|
};
|
|
346
320
|
}
|
|
321
|
+
/** Every agent spec a workflow runs, its nested workflow nodes' agents included, for one adapter lookup (nativeAdapterFor). */
|
|
322
|
+
export function workflowAgentSpecs(spec) {
|
|
323
|
+
return [...spec.agents.map((a) => a.spec), ...spec.workflows.flatMap((w) => workflowAgentSpecs(w.workflow))];
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* A subagent entry as what it runs: an inline agent or a nested syndicate's
|
|
327
|
+
* orchestrator as one agent, or a `yaml_reference` to a workflow syndicate
|
|
328
|
+
* as its whole graph under the entry's name and description. A delegated
|
|
329
|
+
* subagent, a dispatch route and a workflow node all compile through here,
|
|
330
|
+
* so the graph a file describes is the graph that runs (ADR 0106).
|
|
331
|
+
*/
|
|
332
|
+
export async function compileEntrySpec(subCfg, opts = {}) {
|
|
333
|
+
if (subCfg.yaml_reference && !subCfg.a2a_agent_url) {
|
|
334
|
+
const nestedOpts = nestedOptions(subCfg.yaml_reference, opts);
|
|
335
|
+
const nested = loadNestedSyndicate(subCfg.yaml_reference, nestedOpts);
|
|
336
|
+
if (isWorkflowSyndicate(nested)) {
|
|
337
|
+
return { kind: 'workflow', workflow: await compileWorkflowSpec(nested, nestedOpts, subCfg.name, subCfg.description, subCfg.yaml_reference) };
|
|
338
|
+
}
|
|
339
|
+
return { kind: 'agent', spec: await compileSpec(nested, nestedOpts, subCfg.name, subCfg.description) };
|
|
340
|
+
}
|
|
341
|
+
return { kind: 'agent', spec: await compileSubagentSpec(subCfg, opts) };
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* The names of a syndicate's subagent entries that are `yaml_reference`s to
|
|
345
|
+
* a workflow syndicate. Loads each reference once and compiles nothing, so a
|
|
346
|
+
* runtime can refuse what it cannot run before the session is touched.
|
|
347
|
+
*/
|
|
348
|
+
export function workflowEntryNames(config, opts = {}) {
|
|
349
|
+
const load = opts.loadNested ?? (config.bundled_references ? nestedLoader(config) : loadSyndicate);
|
|
350
|
+
return (config.subagents ?? []).filter((s) => !!s.yaml_reference && !s.a2a_agent_url && isWorkflowSyndicate(load(s.yaml_reference))).map((s) => s.name);
|
|
351
|
+
}
|
|
347
352
|
/**
|
|
348
353
|
* The spec of ONE agent from a subagent entry. A `yaml_reference` entry is
|
|
349
|
-
* the nested syndicate's
|
|
350
|
-
* description,
|
|
354
|
+
* the nested syndicate's orchestrator under this entry's name and
|
|
355
|
+
* description, its own subagents delegated to as in any DELEGATE graph. A
|
|
356
|
+
* `yaml_reference` to a workflow syndicate has no one agent to build: it
|
|
357
|
+
* runs as its whole graph (compileEntrySpec), and is refused here by name.
|
|
351
358
|
*/
|
|
352
359
|
export async function compileSubagentSpec(subCfg, opts = {}) {
|
|
353
360
|
if (subCfg.a2a_agent_url) {
|
|
@@ -358,7 +365,11 @@ export async function compileSubagentSpec(subCfg, opts = {}) {
|
|
|
358
365
|
}
|
|
359
366
|
if (subCfg.yaml_reference) {
|
|
360
367
|
const nestedOpts = nestedOptions(subCfg.yaml_reference, opts);
|
|
361
|
-
|
|
368
|
+
const nested = loadNestedSyndicate(subCfg.yaml_reference, nestedOpts);
|
|
369
|
+
if (isWorkflowSyndicate(nested)) {
|
|
370
|
+
throw new Error(`${subCfg.yaml_reference}: '${subCfg.name}' is a workflow syndicate, which runs as its whole graph, not as one agent; compile the entry with compileEntrySpec (ADR 0106).`);
|
|
371
|
+
}
|
|
372
|
+
return compileSpec(nested, nestedOpts, subCfg.name, subCfg.description);
|
|
362
373
|
}
|
|
363
374
|
const gated = gateTools(await resolveAgentTools(subCfg.tools, subCfg.mcp_server_url, opts, subCfg.openapi, subCfg.examples, subCfg.mcp_tools), subCfg.require_approval, subCfg.name);
|
|
364
375
|
const { instruction, tools } = await withSkills(subCfg.instruction ?? '', gated, subCfg.skills, subCfg.name, opts);
|
|
@@ -368,7 +379,7 @@ export async function compileSubagentSpec(subCfg, opts = {}) {
|
|
|
368
379
|
/**
|
|
369
380
|
* The spec of a syndicate's orchestrator. In DELEGATE mode its subagents
|
|
370
381
|
* come first among its tools, as delegations; in PLAN-DISPATCH mode it gets
|
|
371
|
-
* none (
|
|
382
|
+
* none (a classifier answers with its outputSchema — see
|
|
372
383
|
* config/agents/critic.yaml), and the caller dispatches to a route's own
|
|
373
384
|
* spec itself.
|
|
374
385
|
*/
|
|
@@ -377,14 +388,12 @@ export async function compileSpec(config, opts = {}, overrideName, overrideDescr
|
|
|
377
388
|
if (config.bundled_references && !opts.loadNested)
|
|
378
389
|
opts = { ...opts, loadNested: nestedLoader(config) };
|
|
379
390
|
// A graph has no orchestrator-with-tools shape to build: its agents are
|
|
380
|
-
// nodes (lib/workflow.ts). A
|
|
381
|
-
//
|
|
382
|
-
//
|
|
383
|
-
if (config.workflow
|
|
384
|
-
throw new Error(`${config.syndicate_name}: a workflow syndicate is compiled with
|
|
391
|
+
// nodes (lib/workflow.ts). A yaml_reference to one runs the whole graph, as
|
|
392
|
+
// a delegated tool (ADR 0098), a dispatch route or a workflow node (ADR
|
|
393
|
+
// 0106), through compileEntrySpec, which never compiles one here.
|
|
394
|
+
if (config.workflow) {
|
|
395
|
+
throw new Error(`${config.syndicate_name}: a workflow syndicate is compiled with compileWorkflowSpec, not compileSpec`);
|
|
385
396
|
}
|
|
386
|
-
if (config.workflow)
|
|
387
|
-
opts.log?.(`${config.syndicate_name}: a dispatch route or a workflow node, so only its orchestrator runs (a delegated subagent runs the whole graph)`);
|
|
388
397
|
const delegated = isDispatchSyndicate(config)
|
|
389
398
|
? []
|
|
390
399
|
: await Promise.all((config.subagents ?? []).map(async (subCfg) => {
|
|
@@ -392,14 +401,8 @@ export async function compileSpec(config, opts = {}, overrideName, overrideDescr
|
|
|
392
401
|
opts.log?.(`Remote A2A agent: ${subCfg.name} → ${subCfg.a2a_agent_url}`);
|
|
393
402
|
return { kind: 'remote', name: subCfg.name, description: subCfg.description, url: subCfg.a2a_agent_url };
|
|
394
403
|
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
const nested = loadNestedSyndicate(subCfg.yaml_reference, nestedOpts);
|
|
398
|
-
if (isWorkflowSyndicate(nested))
|
|
399
|
-
return { kind: 'workflow', workflow: await compileWorkflowSpec(nested, nestedOpts, subCfg.name, subCfg.description, subCfg.yaml_reference) };
|
|
400
|
-
return { kind: 'agent', agent: await compileSpec(nested, nestedOpts, subCfg.name, subCfg.description) };
|
|
401
|
-
}
|
|
402
|
-
return { kind: 'agent', agent: await compileSubagentSpec(subCfg, opts) };
|
|
404
|
+
const entry = await compileEntrySpec(subCfg, opts);
|
|
405
|
+
return entry.kind === 'workflow' ? entry : { kind: 'agent', agent: entry.spec };
|
|
403
406
|
}));
|
|
404
407
|
const name = overrideName || config.orchestrator.name;
|
|
405
408
|
// Orchestrator tools are registry names only — no entrypoint has ever
|
|
@@ -411,22 +414,3 @@ export async function compileSpec(config, opts = {}, overrideName, overrideDescr
|
|
|
411
414
|
logCapabilities(opts, name, config.orchestrator.model, config.orchestrator.tools);
|
|
412
415
|
return specOf(config.orchestrator, name, overrideDescription || config.orchestrator.description, instruction, [...delegated, ...asTools(tools)], opts);
|
|
413
416
|
}
|
|
414
|
-
// ── The ADK runtime's agents (lib/compileAdk.ts) ─────────────────────────────
|
|
415
|
-
/**
|
|
416
|
-
* Builds ONE runnable ADK agent from a subagent entry: its spec, as
|
|
417
|
-
* lib/compileAdk.ts builds it. A workflow node's settings
|
|
418
|
-
* (CompileOptions.nodeConfig) apply to a local agent, not to a nested
|
|
419
|
-
* syndicate's orchestrator.
|
|
420
|
-
*/
|
|
421
|
-
export async function compileSubagent(subCfg, opts = {}) {
|
|
422
|
-
const spec = await compileSubagentSpec(subCfg, opts);
|
|
423
|
-
return compileAdk(spec, opts, subCfg.yaml_reference ? {} : (opts.nodeConfig?.(subCfg.name) ?? {}));
|
|
424
|
-
}
|
|
425
|
-
/**
|
|
426
|
-
* Compiles a syndicate's orchestrator for the ADK runtime. In DELEGATE mode
|
|
427
|
-
* its subagents are attached as AgentTools; in PLAN-DISPATCH mode it gets
|
|
428
|
-
* none, and the caller dispatches to `compileSubagent(route)` itself.
|
|
429
|
-
*/
|
|
430
|
-
export async function compileGraph(config, opts = {}, overrideName, overrideDescription) {
|
|
431
|
-
return compileAdk(await compileSpec(config, opts, overrideName, overrideDescription), opts);
|
|
432
|
-
}
|