melchizedek-agents 0.20.0 → 1.0.1
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 +256 -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 +4 -10
- 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/adkPeer.d.ts +0 -63
- package/dist/lib/adkPeer.js +0 -240
- package/dist/lib/compileAdk.d.ts +0 -32
- package/dist/lib/compileAdk.js +0 -142
- package/dist/lib/models/adkGeminiAdapter.d.ts +0 -90
- package/dist/lib/models/adkGeminiAdapter.js +0 -369
- package/dist/lib/models/adkShim.d.ts +0 -111
- package/dist/lib/models/adkShim.js +0 -136
- package/dist/lib/models/claudeLlm.d.ts +0 -79
- package/dist/lib/models/claudeLlm.js +0 -87
- package/dist/lib/models/fallback.d.ts +0 -48
- package/dist/lib/models/fallback.js +0 -116
- package/dist/lib/models/gatewayLlm.d.ts +0 -36
- package/dist/lib/models/gatewayLlm.js +0 -44
- package/dist/lib/models/gptLlm.d.ts +0 -99
- package/dist/lib/models/gptLlm.js +0 -129
- package/dist/lib/models/grokLlm.d.ts +0 -50
- package/dist/lib/models/grokLlm.js +0 -56
- package/dist/lib/models/kimiLlm.d.ts +0 -31
- package/dist/lib/models/kimiLlm.js +0 -35
- package/dist/lib/models/ollamaLlm.d.ts +0 -37
- package/dist/lib/models/ollamaLlm.js +0 -42
- package/dist/lib/models/openAiCompatibleLlm.d.ts +0 -96
- package/dist/lib/models/openAiCompatibleLlm.js +0 -156
- package/dist/lib/models/tracedGemini.d.ts +0 -41
- package/dist/lib/models/tracedGemini.js +0 -98
- package/dist/lib/runtime/adkMemoryBridge.d.ts +0 -46
- package/dist/lib/runtime/adkMemoryBridge.js +0 -68
- package/dist/lib/runtime/adkSessionBridge.d.ts +0 -78
- package/dist/lib/runtime/adkSessionBridge.js +0 -176
- package/dist/lib/tools/adkTool.d.ts +0 -81
- package/dist/lib/tools/adkTool.js +0 -268
- package/dist/lib/tools/collectionsSearchTool.d.ts +0 -56
- package/dist/lib/tools/collectionsSearchTool.js +0 -71
- package/dist/lib/tools/urlContextTool.d.ts +0 -32
- package/dist/lib/tools/urlContextTool.js +0 -43
- package/dist/lib/tools/webSearchTool.d.ts +0 -51
- package/dist/lib/tools/webSearchTool.js +0 -82
- package/dist/lib/tools/xSearchTool.d.ts +0 -59
- package/dist/lib/tools/xSearchTool.js +0 -74
package/DOCUMENTATION.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# melchizedek-agents — reference documentation
|
|
2
2
|
|
|
3
3
|
The framework in one sentence: **a syndicate is a YAML file describing an
|
|
4
|
-
agent graph; the
|
|
4
|
+
agent graph; the engine compiles it into agents on its own loop, with
|
|
5
5
|
tools, sessions, and memory attached.** This document is the reference
|
|
6
6
|
for that file format and the machinery around it. For a guided first run,
|
|
7
7
|
see [`QUICKSTART.md`](./QUICKSTART.md).
|
|
@@ -27,13 +27,14 @@ config/agents/ YOUR syndicate definitions (the engine's input)
|
|
|
27
27
|
config/agents/examples/ the starter pack — shipped example syndicates
|
|
28
28
|
lib/loadSyndicate.ts YAML → validated config (+ variable binding)
|
|
29
29
|
lib/dispatch.ts plan-dispatch route resolution (§6)
|
|
30
|
-
lib/toolRegistry.ts tool name →
|
|
30
|
+
lib/toolRegistry.ts tool name → the engine's own Tool
|
|
31
31
|
lib/models/claudeAdapter.ts Claude on the engine's model contract
|
|
32
|
-
lib/models/claudeLlm.ts that adapter behind the ADK shim, in the ADK registry
|
|
33
32
|
lib/models/ollamaLlm.ts open-weight local adapter (Ollama, keyless)
|
|
34
33
|
lib/models/chatCompletionsAdapter.ts the chat-completions wire on the model contract
|
|
35
|
-
lib/tools/mcpToolFactory.ts MCP client: remote tools →
|
|
34
|
+
lib/tools/mcpToolFactory.ts MCP client: remote tools → the engine's own Tools
|
|
36
35
|
scripts/demo_mcp_server.ts demo MCP server (library catalog, SSE)
|
|
36
|
+
lib/runtime/native/… the native loop: steps, delegation, compaction, interrupts
|
|
37
|
+
lib/workflow/… the workflow scheduler for `workflow:` syndicates
|
|
37
38
|
lib/session/… Supabase-backed session service
|
|
38
39
|
lib/memory/… pgvector long-term memory service
|
|
39
40
|
lib/observability/… OpenTelemetry run tracing
|
|
@@ -48,33 +49,42 @@ tests/agents.test.ts compiles every shipped syndicate; opt-in live check
|
|
|
48
49
|
```
|
|
49
50
|
|
|
50
51
|
Execution flow: `loadSyndicate` reads and validates the YAML and binds
|
|
51
|
-
`{{variables}}` → the
|
|
52
|
-
subagents as
|
|
53
|
-
|
|
54
|
-
on
|
|
55
|
-
|
|
52
|
+
`{{variables}}` → the compiler builds each agent on the engine's own
|
|
53
|
+
loop, wiring subagents as delegation tools and tool names through the
|
|
54
|
+
registry → the loop runs the turn, calling each agent's model through its
|
|
55
|
+
adapter on the engine's model contract and persisting events to the
|
|
56
|
+
session service → on session end, the memory service distills the
|
|
57
|
+
transcript into tagged facts, embeds them (768-d), and stores them for
|
|
58
|
+
future recall.
|
|
56
59
|
|
|
57
60
|
The compiler (`lib/compile.ts`) first builds a runtime-neutral `AgentSpec`
|
|
58
|
-
per agent
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
selects ADK's Runner, which 1.0.0 removes; without it that choice fails
|
|
65
|
-
before the session is touched, naming the package, and
|
|
66
|
-
`npx melchizedek-doctor` prints the runtime in use and whether ADK is
|
|
67
|
-
installed. The native loop runs a single-agent, delegating or
|
|
68
|
-
plan-dispatch syndicate with the same result and the same stored events
|
|
69
|
-
the ADK runtime writes, `context:` compaction and `mode: task` included
|
|
61
|
+
per agent, and `lib/compileNative.ts` turns it into the native loop's
|
|
62
|
+
agent. The native runtime is the only runtime
|
|
63
|
+
([ADR 0107](./wiki/decisions/0107-release-1-0-0-removes-adk.md)): it owns the
|
|
64
|
+
loop, the model contract and its adapters, the tools, the sessions and
|
|
65
|
+
the workflow scheduler, and runs a single-agent, delegating,
|
|
66
|
+
plan-dispatch or `workflow:` syndicate, `context:` compaction
|
|
70
67
|
([ADR 0078](./wiki/decisions/0078-native-compaction-ports-adk-compactor.md)),
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
68
|
+
`mode: task`, and pause and resume included
|
|
69
|
+
([ADR 0095](./wiki/decisions/0095-native-workflow-turn-drains-through-the-adk-reader.md)).
|
|
70
|
+
Two configurations it refuses with `UnsupportedOnRuntimeError` before any
|
|
71
|
+
model call: a `transformAgent` hook (it transformed ADK agents), and an
|
|
72
|
+
`ask_user` tool on a workflow node (use an `ask_user` node)
|
|
76
73
|
([ADR 0073](./wiki/decisions/0073-one-agent-spec-and-a-runtime-flag.md)).
|
|
77
74
|
|
|
75
|
+
1.0.0 removed Google ADK
|
|
76
|
+
([ADR 0045](./wiki/decisions/0045-own-runtime-behind-the-seam.md),
|
|
77
|
+
[ADR 0107](./wiki/decisions/0107-release-1-0-0-removes-adk.md)).
|
|
78
|
+
`MELCHIZEDEK_RUNTIME=native` (or `runtime: 'native'` on
|
|
79
|
+
`runSyndicateTurn`) changes nothing; `adk` throws `RuntimeRemovedError`,
|
|
80
|
+
naming 1.0.0, at the startup of the A2A server, the chat and the worker,
|
|
81
|
+
and from `runSyndicateTurn` before the session is touched; any other value
|
|
82
|
+
is a configuration error. The engine stores the same event JSON ADK wrote,
|
|
83
|
+
so a session written before 1.0.0 resumes, and `npx melchizedek-doctor`
|
|
84
|
+
prints the runtime in use and where the choice came from. Upgrading from
|
|
85
|
+
0.x: read the 1.0.0 "Breaking — read before upgrading" section of
|
|
86
|
+
[`CHANGELOG.md`](./CHANGELOG.md).
|
|
87
|
+
|
|
78
88
|
## 2. The syndicate YAML
|
|
79
89
|
|
|
80
90
|
Minimal complete example:
|
|
@@ -120,18 +130,18 @@ Field reference:
|
|
|
120
130
|
| `memory_retention_days` | root | Days a fact in this syndicate's namespace is kept; the server deletes older facts when it loads the syndicate and daily after. Requires `memory_namespace` (never applied to the shared default namespace). |
|
|
121
131
|
| `dispatch` | root | Switches the syndicate from DELEGATE to PLAN-DISPATCH routing (§6). `default_route` (required) names the fail-static subagent; `route_key` / `reason_key` name the router's JSON properties (defaults `route` / `reason`). Honoured by every surface (the CLI, the server, the worker, evals). |
|
|
122
132
|
| `workflow` | root | Switches the syndicate to a WORKFLOW (§6): a graph whose nodes are its agents plus declared `join`, `map`, `tool` and `ask_user` nodes, and whose `edges` say what runs after what and on which route. The orchestrator is a node like any other; nothing delegates. Cannot be combined with `dispatch`. Contract: `lib/workflow.ts`; worked example: `examples/pipeline.yaml`. |
|
|
123
|
-
| `retries` | root | Self-correction, on by default ([ADR 0034](./wiki/decisions/0034-self-correction.md)): `model_errors` (default 2) retries a model reply
|
|
133
|
+
| `retries` | root | Self-correction, on by default ([ADR 0034](./wiki/decisions/0034-self-correction.md)): `model_errors` (default 2) retries a model reply marked malformed (`MALFORMED_FUNCTION_CALL`) instead of failing the turn; `tool_errors` (default 3) answers a tool that threw with structured reflection guidance and caps its retries. `0` turns either off. Every retry is a model call under `max_steps`. |
|
|
124
134
|
| `guards` | root | Optional list of post-answer guard NAMES (`lib/guards/index.ts`). Each runs after the answering turn and before the reply publishes, receiving the final text plus every tool-result text of that turn, and rewrites in place rather than re-asking the model; its notes land in the `[STATUS]` stream. Guards declared by a syndicate reached through `yaml_reference:` count too — the server resolves the union via `collectGuards()`. Resolved by name, never by module path, so adding one is a deliberate act in code; **the published registry ships one, `science`** (citation checks for `research.yaml`); `registerGuard()` adds your own from code, and an unregistered name is warned about and skipped. |
|
|
125
135
|
| `name` / `model` / `instruction` | agent | The agent triple. Any Gemini id, `claude-*`, or `ollama/*` for open-weight local models (see §5). |
|
|
126
136
|
| `description` | subagent | **The delegation API.** The orchestrator reads this when deciding to hand off — write it like a function signature ("Use this subagent to…, pass it…"). |
|
|
127
137
|
| `tools` | agent | Names resolved by the tool registry (§3). Long-term memory agents add `preload_memory` / `load_memory`. |
|
|
128
138
|
| `reasoning` | agent | How hard the agent reasons, on any provider: `none`, `low`, `medium`, `high`, or `{ budget_tokens: <int> }`. The compiler sends each provider the field it reads: a thinking level on Gemini 3, a thinking budget on Claude 4.6 and earlier (2,048 / 8,192 / 16,384 tokens for low / medium / high), adaptive thinking with that effort on later Claude models ([ADR 0049](./wiki/decisions/0049-claude-requests-by-model-generation.md)), an effort word on GPT, Grok, Kimi, Ollama and the gateway ([ADR 0047](./wiki/decisions/0047-provider-neutral-reasoning-key.md)). Unset, each adapter keeps its own default. |
|
|
129
139
|
| `generateContentConfig` | agent | Temperature, output caps. Its `thinkingConfig` and `reasoningEffort` are the older, provider-specific spelling of `reasoning`; setting either next to `reasoning` is a load error. |
|
|
130
|
-
| `outputSchema` | agent | Structured-JSON contract. **Constraint:** an agent holding `outputSchema` cannot also hold transfer powers —
|
|
140
|
+
| `outputSchema` | agent | Structured-JSON contract. **Constraint:** an agent holding `outputSchema` cannot also hold transfer powers — structured output does not combine with delegation on one agent. Keep schema-holders as leaf agents (see `critic.yaml`'s header comment for the war story). |
|
|
131
141
|
| `yaml_reference` | subagent | Mount another syndicate file as a nested subagent. |
|
|
132
142
|
| `a2a_agent_url` | subagent | A REMOTE agent over A2A (§6): the orchestrator delegates to it with one `request` argument; in plan-dispatch it can be a route. No `model`/`instruction` — the remote agent has its own. Credentials come from `A2A_AGENT_TOKENS`, never YAML. |
|
|
133
143
|
| `max_steps` | root | Cap on model calls per turn, counted across every agent the turn reaches (orchestrator, subagents, nested syndicates). Exceeding it fails the turn with `STEP_LIMIT`. |
|
|
134
|
-
| `includeContents` / `outputKey` / `globalInstruction` / `disallowTransferToParent` / `disallowTransferToPeers` | agent | Passed through to ADK's LlmAgent. `includeContents: none` makes an agent see only the current message. |
|
|
144
|
+
| `includeContents` / `outputKey` / `globalInstruction` / `disallowTransferToParent` / `disallowTransferToPeers` | agent | Passed through to the agent (the names are ADK's `LlmAgent` fields). `includeContents: none` makes an agent see only the current message. |
|
|
135
145
|
| `fallback_model` | any agent | A model, ideally on another provider, that answers when this agent's model fails provider-side (5xx, 429, a connection reset, after its own retries) before producing any output, or while that provider's circuit is open: after `MODEL_BREAKER_THRESHOLD` consecutive provider failures (default 5; 0 disables) the provider is skipped for `MODEL_BREAKER_COOLDOWN_MS` (default 30 s). A 4xx and a canceled turn are never redirected, and a stream that already produced text is never replayed elsewhere ([ADR 0044](./wiki/decisions/0044-fallback-model-and-circuit-breaker.md)). |
|
|
136
146
|
| `mcp_tools` | subagent | The MCP server's tools this agent may use; any other tool the server lists is not exposed. On a dispatch route `require_approval` may name them ([ADR 0041](./wiki/decisions/0041-tool-vendors-get-least-privilege.md)). |
|
|
137
147
|
| `mcp_server_url` | subagent | Discover this subagent's tools from a remote MCP server at load time (§3). SSRF-guarded; `ALLOW_PRIVATE_MCP=true` permits localhost for development. |
|
|
@@ -140,7 +150,7 @@ Field reference:
|
|
|
140
150
|
| `context` | orchestrator | Compacts a long conversation: when the last request's prompt passed `compact_after_tokens`, earlier turns become one summary (written by `summary_model`, default the agent's own) and the last `keep_recent_events` stay verbatim. The full history stays stored; only what the model reads shrinks. The orchestrator of a delegate syndicate only: a dispatch route already reads a bounded projection, a workflow node sees only its input. |
|
|
141
151
|
| `mode` | workflow node | `"task"`: the agent works with its tools until it calls `finish_task`, whose arguments (matching its `outputSchema`) become the node's output. Workflow nodes only. |
|
|
142
152
|
| `examples` | any agent | Few-shot exchanges, `[{ input, output }]` (up to 20), added to every request's instruction as a few-shot block, the one ADK's `ExampleTool` wrote (an Instruction tool, `lib/tools/examples.ts`); the model never calls it. Keeps worked examples out of the prose of `instruction`. |
|
|
143
|
-
| `skills` | any agent | Agent Skills (a directory of SKILL.md folders) the agent holds the way a coding harness does: every skill's name and description is appended to its instruction at compile time; `load_skill` reads one in full with the names of its files, `load_skill_resource` reads one file. `scripts: local` adds `run_skill_script`, which runs a skill's own scripts on this machine, each after a person approves (the `require_approval` pause), with PATH, HOME, the temp directory and the locale but none of the server's keys, plus the variable names listed under `env:` (or `secret_env:` for a secret-shaped name, ADR 0086), and stdout and stderr each cut at 20,000 characters; `tools:` names registry tools a skill's `allowed-tools` may unlock once loaded. Worked example: `examples/harness.yaml`; engine: `lib/tools/skillToolset.ts` over `lib/tools/skills
|
|
153
|
+
| `skills` | any agent | Agent Skills (a directory of SKILL.md folders) the agent holds the way a coding harness does: every skill's name and description is appended to its instruction at compile time; `load_skill` reads one in full with the names of its files, `load_skill_resource` reads one file. `scripts: local` adds `run_skill_script`, which runs a skill's own scripts on this machine, each after a person approves (the `require_approval` pause), with PATH, HOME, the temp directory and the locale but none of the server's keys, plus the variable names listed under `env:` (or `secret_env:` for a secret-shaped name, ADR 0086), and stdout and stderr each cut at 20,000 characters; `tools:` names registry tools a skill's `allowed-tools` may unlock once loaded. Worked example: `examples/harness.yaml`; engine: `lib/tools/skillToolset.ts` over `lib/tools/skills/`. |
|
|
144
154
|
|
|
145
155
|
Validation happens at load: missing names, legacy option blocks, and
|
|
146
156
|
malformed agents fail with pointed errors before any model is called.
|
|
@@ -149,16 +159,14 @@ skipped with a warning at compile time.
|
|
|
149
159
|
|
|
150
160
|
## 3. Tools
|
|
151
161
|
|
|
152
|
-
Registered in `lib/toolRegistry.ts` — one map from YAML name to
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
only writes into each request's instruction, reaching the ADK runtime
|
|
158
|
-
through `toAdkInstructionTool`. A **server-side tool** is an own marker
|
|
162
|
+
Registered in `lib/toolRegistry.ts` — one map from YAML name to tool. A
|
|
163
|
+
**Contract** is the engine's own Tool (`lib/tools/tool.ts`), defined once
|
|
164
|
+
with `defineTool`; the native loop runs it as it is. An **Instruction
|
|
165
|
+
tool** is the engine's own too: it declares no function and only writes
|
|
166
|
+
into each request's instruction. A **server-side tool** is an own marker
|
|
159
167
|
(`lib/tools/nativeTools.ts`) that names the provider's tool and declares no
|
|
160
|
-
function
|
|
161
|
-
|
|
168
|
+
function, and every adapter recognises it by marker
|
|
169
|
+
([ADR 0062](./wiki/decisions/0062-server-side-tools-as-markers.md)):
|
|
162
170
|
|
|
163
171
|
| Name | Kind | Does |
|
|
164
172
|
|---|---|---|
|
|
@@ -167,7 +175,7 @@ adapter recognises it by marker ([ADR 0062](./wiki/decisions/0062-server-side-to
|
|
|
167
175
|
| `x_search` | xAI-only | Live search over X (Twitter) posts via xAI Agent Tools. Self-gates to `grok-*` agents; a silent no-op on every other provider, so mixed-provider YAMLs stay safe. Optional server-side constraints in `.env`: `XAI_X_SEARCH_FROM_DATE`/`_TO_DATE` (inclusive `YYYY-MM-DD`) and `_ALLOWED_HANDLES`/`_EXCLUDED_HANDLES` (max 20, mutually exclusive — allowlist wins). |
|
|
168
176
|
| `collections_search` | xAI-only | Semantic search over xAI **Collections** — hosted document stores (PDFs/text/CSVs) uploaded at console.x.ai — server-side RAG with `collections://…` citations. Which collections: `XAI_COLLECTION_IDS` in `.env` (optional `XAI_COLLECTIONS_MAX_RESULTS`). Declared with no ids → omitted with a warning; non-xAI providers → silent no-op. |
|
|
169
177
|
| `url_context` | Gemini built-in | Gemini reads the pages at URLs in the conversation, server-side (Google fetches them, not this host). On any other provider it is a no-op the doctor reports as dropped; use `web_extract` there. |
|
|
170
|
-
| `google_search` |
|
|
178
|
+
| `google_search` | Gemini built-in | Live web search — Gemini agents only (legacy alias; use `web_search`). |
|
|
171
179
|
| `preload_memory` | Instruction tool | Silently injects similarity-matched facts into every request's instruction (ambient recall). The model never calls it. |
|
|
172
180
|
| `load_memory` | Contract | Explicit tool call to search the fact store (deliberate recall). Both memory tools read the caller's own silo only and send the model what ADK's tools of the same names sent ([ADR 0059](./wiki/decisions/0059-memory-on-the-engines-own-interfaces.md)). |
|
|
173
181
|
| `generate_image` | Contract | Calls the Gemini image model directly, saves the result under `outputs/`, returns the path. A function tool because binary `inlineData` cannot survive the AgentTool text boundary. |
|
|
@@ -179,8 +187,7 @@ adapter recognises it by marker ([ADR 0062](./wiki/decisions/0062-server-side-to
|
|
|
179
187
|
**MCP tools** are the exception to the registry: a subagent with
|
|
180
188
|
`mcp_server_url:` in its YAML gets its tools from a remote MCP server at
|
|
181
189
|
load time. `lib/tools/mcpToolFactory.ts` dials the server over SSE,
|
|
182
|
-
lists its tools, and makes each one an own Tool (`loadMcpTools`)
|
|
183
|
-
the ADK runtime runs as a `FunctionTool` (`createMcpTools`) — the
|
|
190
|
+
lists its tools, and makes each one an own Tool (`loadMcpTools`) — the
|
|
184
191
|
agent's reach is decided by the server, not compiled in.
|
|
185
192
|
`config/agents/examples/librarian.yaml` plus the demo catalog server
|
|
186
193
|
(`npm run mcp:demo`, `scripts/demo_mcp_server.ts`) are the worked
|
|
@@ -234,8 +241,8 @@ example: `config/agents/examples/weather.yaml`, two keyless Open-Meteo specs
|
|
|
234
241
|
in `examples/specs/`.
|
|
235
242
|
|
|
236
243
|
> **Schema dialects, handled for you.** The factory emits Gemini-style
|
|
237
|
-
> UPPERCASE schema types (`'OBJECT'`, `'STRING'`, …)
|
|
238
|
-
>
|
|
244
|
+
> UPPERCASE schema types (`'OBJECT'`, `'STRING'`, …), the `@google/genai`
|
|
245
|
+
> dialect; every non-Gemini adapter normalizes them back to
|
|
239
246
|
> standard lowercase JSON-Schema at request-build time
|
|
240
247
|
> (`lib/models/schemaNormalize.ts`). MCP tools therefore work on any
|
|
241
248
|
> provider's agents — Gemini, Claude, GPT, Grok, or Kimi.
|
|
@@ -346,13 +353,13 @@ accordingly — model optionality is a single YAML line per agent:
|
|
|
346
353
|
|
|
347
354
|
| Model id | Provider | Adapter | Key | Native `web_search` |
|
|
348
355
|
|---|---|---|---|---|
|
|
349
|
-
| `gemini-*` | Google Gemini |
|
|
350
|
-
| `claude-*` | Anthropic | `lib/models/claudeAdapter.ts` (Messages API
|
|
351
|
-
| `gpt-*`, o-series | OpenAI | `lib/models/
|
|
352
|
-
| `grok-*` | xAI | `lib/models/
|
|
353
|
-
| `kimi-*` | Moonshot AI (Kimi) | `lib/models/
|
|
354
|
-
| `ollama/*` | Local Ollama | `lib/models/
|
|
355
|
-
| *any cloud id whose direct key is absent* | the id's own provider, via a gateway | `lib/models/
|
|
356
|
+
| `gemini-*` | Google Gemini | `lib/models/geminiAdapter.ts` (`@google/genai`) | `GOOGLE_GENAI_API_KEY` | ✅ grounding |
|
|
357
|
+
| `claude-*` | Anthropic | `lib/models/claudeAdapter.ts` (Messages API) | `ANTHROPIC_API_KEY` | ✅ server tool |
|
|
358
|
+
| `gpt-*`, o-series | OpenAI | `lib/models/gptAdapter.ts` (Responses API) | `OPENAI_API_KEY` | ✅ web_search tool |
|
|
359
|
+
| `grok-*` | xAI | `lib/models/grokAdapter.ts` (Responses API) | `XAI_API_KEY` | ✅ Agent Tools search |
|
|
360
|
+
| `kimi-*` | Moonshot AI (Kimi) | `lib/models/kimiAdapter.ts` (chat completions) | `MOONSHOT_API_KEY` | ⚠ omitted + warning |
|
|
361
|
+
| `ollama/*` | Local Ollama | `lib/models/ollamaAdapter.ts` (chat completions) | none | ⚠ omitted + warning |
|
|
362
|
+
| *any cloud id whose direct key is absent* | the id's own provider, via a gateway | `lib/models/gatewayAdapter.ts` (chat completions) | `MODEL_GATEWAY` + `MODEL_GATEWAY_API_KEY` | ⚠ omitted + reported |
|
|
356
363
|
|
|
357
364
|
The xAI adapter carries the deepest capability surface: `grok-4.5`
|
|
358
365
|
requests pin `reasoning.effort: "medium"` (`lib/config.ts`), SSE
|
|
@@ -362,9 +369,8 @@ structured outputs ride `outputSchema` → `text.format`, and two
|
|
|
362
369
|
xAI-only tools — `x_search` and `collections_search` (§3) — turn on
|
|
363
370
|
live X search and hosted-document RAG. All verified live on grok-4.5.
|
|
364
371
|
|
|
365
|
-
**Moonshot AI (Kimi).** `kimi-*` ids route to `
|
|
366
|
-
|
|
367
|
-
chat-completions base), against `https://api.moonshot.ai/v1`
|
|
372
|
+
**Moonshot AI (Kimi).** `kimi-*` ids route to `KimiAdapter`
|
|
373
|
+
(`lib/models/kimiAdapter.ts`, on the chat-completions base), against `https://api.moonshot.ai/v1`
|
|
368
374
|
(`MOONSHOT_BASE_URL` for a proxy). Get a key at platform.moonshot.ai; the
|
|
369
375
|
`.cn` console serves mainland China. The family (USD per 1M tokens, October
|
|
370
376
|
2026): `kimi-k3`, the flagship — 2.8T-parameter open-weight MoE, 1M context,
|
|
@@ -461,11 +467,12 @@ configured platform with its credential source and anything missing. These
|
|
|
461
467
|
paths are tested against mocked SDK clients and have **not** been run against
|
|
462
468
|
the live clouds from this repository.
|
|
463
469
|
|
|
464
|
-
`lib/models/registry.ts` is the single routing seam:
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
470
|
+
`lib/models/registry.ts` is the single routing seam: `resolveAdapter`
|
|
471
|
+
turns the YAML's model string into its provider's adapter, and
|
|
472
|
+
`logProviderStatuses()` reports which providers have a key
|
|
473
|
+
(Ollama needs none) and, given a log function, logs a line per provider;
|
|
474
|
+
it registers nothing. Missing keys produce clear skip messages, and only
|
|
475
|
+
the providers a syndicate actually declares are required.
|
|
469
476
|
Mixed graphs are supported — each agent picks its own provider, one
|
|
470
477
|
line each. `config/agents/examples/claude.yaml` is the minimal Claude example;
|
|
471
478
|
`config/agents/examples/model_zoo.yaml` declares one lightweight agent per
|
|
@@ -475,9 +482,7 @@ prompt to every available provider, printing input, thinking (qwen3
|
|
|
475
482
|
Grok reasoning, Kimi reasoning_content), output, and a per-request token/latency trace; add
|
|
476
483
|
`-- --search` to watch four native web searches plus the local
|
|
477
484
|
omission. Providers without keys are skipped, never fatal. Each agent
|
|
478
|
-
runs as a one-agent syndicate through `runSyndicateTurn
|
|
479
|
-
`MELCHIZEDEK_RUNTIME=native npm run demo:models` runs the same demo on
|
|
480
|
-
the engine's own loop.
|
|
485
|
+
runs as a one-agent syndicate through `runSyndicateTurn`.
|
|
481
486
|
|
|
482
487
|
Reasoning/thinking: scratchpads from every provider are surfaced as
|
|
483
488
|
dimmed THINKING output and kept out of session history. On Claude, any
|
|
@@ -494,44 +499,33 @@ response (ADR 0050).
|
|
|
494
499
|
The engine's own model contract is `lib/models/contract.ts` (ADR 0048),
|
|
495
500
|
importable as `melchizedek-agents/models/contract`. It defines the message
|
|
496
501
|
format, request, response stream and adapter interface of the native
|
|
497
|
-
runtime (ADR 0045), with no `@google/*` in its import graph, and
|
|
498
|
-
|
|
499
|
-
each field's purpose and its mapping onto every provider's wire.
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
`GrokAdapter` (`melchizedek-agents/models/grokAdapter`), and keep the token
|
|
507
|
-
counts and server-side tool record the ledger has always had for them
|
|
508
|
-
(ADR 0056).
|
|
509
|
-
Gemini has two adapters on the contract:
|
|
510
|
-
`melchizedek-agents/models/geminiAdapter` (`GeminiAdapter`, on
|
|
511
|
-
`@google/genai` with no ADK) and, until that one passes its live parity
|
|
512
|
-
run, `melchizedek-agents/models/adkGeminiAdapter` (`AdkGeminiAdapter`,
|
|
513
|
-
a temporary wrapper that runs the request through `TracedGemini`, now in
|
|
514
|
-
`melchizedek-agents/models/tracedGemini`).
|
|
502
|
+
runtime (ADR 0045), with no `@google/*` in its import graph, and every
|
|
503
|
+
provider's adapter implements it. `wiki/models/model-contract.md` gives
|
|
504
|
+
each field's purpose and its mapping onto every provider's wire. The
|
|
505
|
+
native loop calls the adapters directly, charging each call against
|
|
506
|
+
`max_steps`, passing the turn's abort signal and opening the
|
|
507
|
+
`llm.request` span (ADR 0053).
|
|
508
|
+
Gemini's adapter is `GeminiAdapter`
|
|
509
|
+
(`melchizedek-agents/models/geminiAdapter`, on `@google/genai`)
|
|
510
|
+
([ADR 0100](./wiki/decisions/0100-gemini-row-asserted-on-the-engine-adapter.md)).
|
|
515
511
|
`resolveAdapter(modelId, { apiKey, keyProvider, endpoint, gemini })` in
|
|
516
512
|
`melchizedek-agents/models/registry` returns any id's contract adapter
|
|
517
|
-
from the
|
|
518
|
-
`resolveModel
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
model and `fallback_model`
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
513
|
+
from the prefix table, with the gateway rule, BYOK scoping and endpoints;
|
|
514
|
+
`resolveModel` returns the same `ModelAdapter` for a BYOK path (ADR 0060).
|
|
515
|
+
Every Gemini id gets `GeminiAdapter`: `GEMINI_ADAPTER=engine` (or
|
|
516
|
+
`gemini: 'engine'`) changes nothing, and `adk` throws, naming 1.0.0.
|
|
517
|
+
`resolveAdapterWithFallback` wraps an agent's model and `fallback_model`
|
|
518
|
+
in a `FallbackAdapter`.
|
|
519
|
+
|
|
520
|
+
`melchizedek-agents/model` is the model layer on its own (ADR 0068): the
|
|
521
|
+
contract's types,
|
|
525
522
|
`ClaudeAdapter`, `GptAdapter`, `GrokAdapter`, `KimiAdapter`,
|
|
526
523
|
`OllamaAdapter`, `GatewayAdapter`, `GeminiAdapter`, the
|
|
527
524
|
`ChatCompletionsAdapter` base, `resolveAdapter`,
|
|
528
525
|
`resolveAdapterWithFallback`, `FallbackAdapter` and the circuit breaker's
|
|
529
|
-
helpers. A project that only calls models
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
`GEMINI_ADAPTER=adk`) throws and names `melchizedek-agents/models/registry`,
|
|
533
|
-
whose `resolveAdapter` keeps the ADK default above. `AdkGeminiAdapter`, the
|
|
534
|
-
ADK shims, `TracedGemini` and `resolveModel` are not in it.
|
|
526
|
+
helpers. A project that only calls models imports from there. Its
|
|
527
|
+
`resolveAdapter` gives a Gemini id `GeminiAdapter`; `resolveModel` is not
|
|
528
|
+
in it.
|
|
535
529
|
|
|
536
530
|
Every model request also emits an `llm.request` OpenTelemetry span
|
|
537
531
|
(provider, model, input/output/thinking tokens, latency). Scripts print it
|
|
@@ -552,24 +546,24 @@ kept by policy (`TELEMETRY_PAYLOADS=off|errors|sample|all`,
|
|
|
552
546
|
`TELEMETRY_PAYLOAD_SAMPLE`, `TELEMETRY_PAYLOAD_TTL_DAYS`) and expired by
|
|
553
547
|
`melchizedek_prune_telemetry()`. A row from a failed call's `llm.request`
|
|
554
548
|
span holds the request in the model contract's shape (`model`, `system`,
|
|
555
|
-
`messages`, `tools`, …), whichever adapter made the call
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
549
|
+
`messages`, `tools`, …), whichever adapter made the call. The native loop
|
|
550
|
+
opens `agent.invoke <name>`, `model.call` and `tool.execute <name>` spans;
|
|
551
|
+
a clean call's row comes from `model.call` and holds the request and the
|
|
552
|
+
adapter's response in the contract's shapes. Rows written before 1.0.0
|
|
553
|
+
under ADK's `invoke_agent`, `call_llm` and `execute_tool` spans hold ADK's
|
|
554
|
+
request, and the ledger still reads them (ADR 0076). The view `adk_turns_production` excludes
|
|
561
555
|
eval and classifier turns. Operate it with `npm run telemetry:stats`,
|
|
562
556
|
`telemetry:prune` and `telemetry:replay` (the exporter spools failed
|
|
563
557
|
batches to `outputs/telemetry-deadletter.ndjson`).
|
|
564
558
|
|
|
565
559
|
**Open-weight local models**: `ollama/*` ids (e.g. `ollama/qwen3:8b`)
|
|
566
|
-
route through `lib/models/
|
|
560
|
+
route through `lib/models/ollamaAdapter.ts` to a local Ollama daemon over
|
|
567
561
|
its OpenAI-compatible API (`OLLAMA_BASE_URL`, default
|
|
568
562
|
`http://localhost:11434/v1`). No key is required, and a syndicate whose
|
|
569
563
|
*every* agent is `ollama/*` runs with no `.env` at all —
|
|
570
564
|
`config/agents/examples/tutor.yaml` (single agent), `council.yaml` (council)
|
|
571
565
|
and `assistant.yaml` (conversation, summaries, a task list, background jobs)
|
|
572
|
-
are the worked examples. The adapter translates
|
|
566
|
+
are the worked examples. The adapter translates the contract's messages to
|
|
573
567
|
OpenAI-style messages, including tool calls (so delegation works),
|
|
574
568
|
image parts as data URIs (so `ollama/qwen3-vl:8b` can see), and JSON
|
|
575
569
|
response mode; reasoning models' `<think>…</think>` scratchpads are
|
|
@@ -790,12 +784,12 @@ same conversation (same `contextId`; the same `taskId` works too) with the text
|
|
|
790
784
|
`{ "approval": { "id": "<approval_id>", "approved": true } }`. Approved, the
|
|
791
785
|
call runs with the arguments shown; rejected, the model is told and answers
|
|
792
786
|
without it. A message that is not an answer gets the same request back,
|
|
793
|
-
without a model call.
|
|
794
|
-
cannot run a different call.
|
|
787
|
+
without a model call. The paused call and its arguments are pinned, so an
|
|
788
|
+
approval cannot run a different call.
|
|
795
789
|
|
|
796
790
|
Gates are allowed on the orchestrator and on the subagents of a
|
|
797
791
|
plan-dispatch syndicate, which run as the turn's own agent, and on the
|
|
798
|
-
agent nodes of a workflow
|
|
792
|
+
agent nodes of a workflow (§6). A delegated
|
|
799
793
|
subagent runs inside a tool call, where a pause cannot reach the caller, so a
|
|
800
794
|
gate there is a load error, as is any gate inside a nested `yaml_reference`
|
|
801
795
|
syndicate. Only function tools from the registry can be gated, not MCP tools
|
|
@@ -838,8 +832,7 @@ A tool that acts for the person against a third-party API reads their
|
|
|
838
832
|
delegated token with `ctx.accessToken(provider)` from the sealed credential
|
|
839
833
|
store ([ADR 0072](./wiki/decisions/0072-tool-credentials-sealed-per-user.md)).
|
|
840
834
|
When they have not granted the provider yet, the turn pauses for their
|
|
841
|
-
consent ([ADR 0085](./wiki/decisions/0085-oauth-consent-pauses-on-adks-credential-request.md))
|
|
842
|
-
This runs on the native runtime:
|
|
835
|
+
consent ([ADR 0085](./wiki/decisions/0085-oauth-consent-pauses-on-adks-credential-request.md)):
|
|
843
836
|
|
|
844
837
|
```ts
|
|
845
838
|
import { createA2AApp } from 'melchizedek-agents/a2a';
|
|
@@ -882,8 +875,7 @@ No token, code, client secret or verifier is written to a page, an event, a
|
|
|
882
875
|
log line or the model's context. The pending flows live in the process: run
|
|
883
876
|
one replica, or route the callback to the instance that paused the call. In
|
|
884
877
|
code, `runSyndicateTurn({ …, toolCredentials })` returns
|
|
885
|
-
`status: 'input-required'` with `consent`.
|
|
886
|
-
request throws `UnsupportedOnRuntimeError`.
|
|
878
|
+
`status: 'input-required'` with `consent`.
|
|
887
879
|
|
|
888
880
|
#### Limits
|
|
889
881
|
|
|
@@ -1097,9 +1089,9 @@ emitted the bare tool name in place of a 2,599-character answer.
|
|
|
1097
1089
|
Plan-dispatch has no relay turn to fail, and the classifier's output
|
|
1098
1090
|
shrinks from a whole relayed answer to ~15 tokens of JSON.
|
|
1099
1091
|
|
|
1100
|
-
**Why the classifier is tool-less.**
|
|
1101
|
-
|
|
1102
|
-
|
|
1092
|
+
**Why the classifier is tool-less.** Structured output does not combine
|
|
1093
|
+
with delegation on one agent (see `config/agents/examples/critic.yaml`,
|
|
1094
|
+
whose header tells how an orchestrator holding both deadlocked on ADK).
|
|
1103
1095
|
That constraint shapes the method: the classifier is a leaf, and the
|
|
1104
1096
|
hand-off happens in code, where it can be logged, traced, and streamed
|
|
1105
1097
|
to the user as progress.
|
|
@@ -1107,8 +1099,9 @@ to the user as progress.
|
|
|
1107
1099
|
**Sessions.** Every *route* runs in the shared `<contextId>` session, so
|
|
1108
1100
|
one transcript accumulates across routes and long-term memory ingests
|
|
1109
1101
|
real answers instead of a relay copy of them. Sharing the session is
|
|
1110
|
-
necessary but not sufficient:
|
|
1111
|
-
`event.author` against the agent now running,
|
|
1102
|
+
necessary but not sufficient: a stored event is rendered by comparing
|
|
1103
|
+
`event.author` against the agent now running (ADK's rule, which the native
|
|
1104
|
+
loop keeps), and under plan-dispatch
|
|
1112
1105
|
every route is its own root agent, so the whole history fails that
|
|
1113
1106
|
comparison and `convertForeignEvent` rewrites it to `role: "user"`
|
|
1114
1107
|
prefixed "For context:". A route reading the raw shared session
|
|
@@ -1135,11 +1128,11 @@ traffic before any prompt, and the memory service's `serializeEvents` walks
|
|
|
1135
1128
|
~90% of every byte stored (`thoughtSignature` alone 73.3%), so they are
|
|
1136
1129
|
stripped from the SERIALIZED COPY — the live in-memory session keeps them,
|
|
1137
1130
|
or the agent's own tool loop breaks mid-turn. An elided tool result keeps
|
|
1138
|
-
its `id` and `name` and gains a size marker, because
|
|
1139
|
-
responses by id and
|
|
1131
|
+
its `id` and `name` and gains a size marker, because the loop pairs
|
|
1132
|
+
calls to responses by id and a widowed half breaks the history. 21.72 MB → 4.88 MB; existing
|
|
1140
1133
|
rows shrink retroactively on their next write. Note the constraint this
|
|
1141
1134
|
rests on: dropping the signature is safe only because stored events are
|
|
1142
|
-
never replayed to a model. The quadratic upload is untouched — `
|
|
1135
|
+
never replayed to a model. The quadratic upload is untouched — `append`
|
|
1143
1136
|
still rewrites the whole array per event — and is the next lever if row size
|
|
1144
1137
|
returns.
|
|
1145
1138
|
|
|
@@ -1166,9 +1159,9 @@ contract lives in `lib/dispatch.ts`.
|
|
|
1166
1159
|
specialist runs, so an A2A client can show a waiting user what is
|
|
1167
1160
|
happening. The `reason` field is written for that reader, not for logs.
|
|
1168
1161
|
|
|
1169
|
-
Implemented in `
|
|
1170
|
-
|
|
1171
|
-
|
|
1162
|
+
Implemented in `runSyndicateTurn`, so every surface honours it: the A2A
|
|
1163
|
+
server, the CLI runner (`scripts/syndicate_chat.ts`), the worker and the
|
|
1164
|
+
evals.
|
|
1172
1165
|
|
|
1173
1166
|
### Workflows (`workflow:`) — the third orchestration method
|
|
1174
1167
|
|
|
@@ -1240,30 +1233,30 @@ that node, and the graph with it: the turn ends `input-required` with
|
|
|
1240
1233
|
`result.approval`, as any approval does, and the next message, the
|
|
1241
1234
|
person's decision, resumes the node's own run, which runs or refuses the
|
|
1242
1235
|
pinned call once and walks on. Any other message repeats the request and
|
|
1243
|
-
runs nothing.
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
**Not yet.**
|
|
1258
|
-
`
|
|
1259
|
-
|
|
1260
|
-
[ADR 0098](./wiki/decisions/0098-workflow-subagent-and-node-approvals.md)
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
([ADR 0095](./wiki/decisions/0095-native-workflow-turn-drains-through-the-adk-reader.md))
|
|
1264
|
-
|
|
1265
|
-
approval, or inside a map item
|
|
1266
|
-
|
|
1236
|
+
runs nothing. Skill scripts (`skills.scripts: local`) on a node agent
|
|
1237
|
+
pause the same way, each `run_skill_script` call waiting for its approval,
|
|
1238
|
+
with the minimal script environment of ADR 0086. The schema refuses a gate or skill scripts on an agent a `map`
|
|
1239
|
+
node runs.
|
|
1240
|
+
|
|
1241
|
+
**Nested.** A `yaml_reference` to a workflow syndicate runs the whole
|
|
1242
|
+
graph, under the entry's name and description, wherever it appears: as a
|
|
1243
|
+
DELEGATE subagent its last output is the tool's answer; as a plan-dispatch
|
|
1244
|
+
route it is the turn's answer, and the conversation keeps the message and
|
|
1245
|
+
that answer; as a node of another workflow it is the node's output. The
|
|
1246
|
+
graph's events are kept in the entry's own session, as for any subagent.
|
|
1247
|
+
A nested workflow may not have an `ask_user` node (a pause inside it
|
|
1248
|
+
cannot reach the caller); it is refused by name, as is a `map` over one.
|
|
1249
|
+
|
|
1250
|
+
**Not yet.** Remote `a2a_agent_url` subagents are refused inside a
|
|
1251
|
+
workflow by the schema. An `ask_user` tool on a node agent is refused
|
|
1252
|
+
too: use an `ask_user` node. The records are [ADR 0030](./wiki/decisions/0030-workflow-graphs.md),
|
|
1253
|
+
[ADR 0098](./wiki/decisions/0098-workflow-subagent-and-node-approvals.md) and
|
|
1254
|
+
[ADR 0106](./wiki/decisions/0106-nested-workflow-routes-nodes-and-node-skill-scripts.md);
|
|
1255
|
+
the turn is `lib/workflow/turn.ts`, on the engine's own scheduler
|
|
1256
|
+
([ADR 0095](./wiki/decisions/0095-native-workflow-turn-drains-through-the-adk-reader.md)),
|
|
1257
|
+
and `lib/workflow.ts` holds the `workflow:` block's contract. A conversation paused inside an agent node on anything
|
|
1258
|
+
but an approval, or inside a map item, fails the next turn with
|
|
1259
|
+
`RESUME_UNSUPPORTED`.
|
|
1267
1260
|
|
|
1268
1261
|
## 7. Extending the framework
|
|
1269
1262
|
|
|
@@ -1274,7 +1267,7 @@ the canonical minimal block on the engine's model contract:
|
|
|
1274
1267
|
`adapter.generate({ model, system, messages, stream })`, reading partial
|
|
1275
1268
|
and final responses. The id's prefix picks the provider (`gemini-*`,
|
|
1276
1269
|
`claude-*`, `gpt-*`, `grok-*`, `kimi-*`, `ollama/*`), the key comes from
|
|
1277
|
-
the environment
|
|
1270
|
+
the environment. A turn
|
|
1278
1271
|
with tools, sessions and telemetry is `runSyndicateTurn`.
|
|
1279
1272
|
|
|
1280
1273
|
**Add a syndicate**: create `config/agents/<name>.yaml` — copy the
|
|
@@ -1286,17 +1279,16 @@ closest starter-pack file from `config/agents/examples/` or start from
|
|
|
1286
1279
|
**Add a tool**: write a `defineTool` contract in `lib/tools/` (name,
|
|
1287
1280
|
description, zod schema, execute), register the name in
|
|
1288
1281
|
`lib/toolRegistry.ts` (or call `registerTool` from your own code),
|
|
1289
|
-
reference it from YAML. The
|
|
1282
|
+
reference it from YAML. The native loop runs the contract as it is; see
|
|
1290
1283
|
`wiki/tools/tool-contracts.md`. The two image tools are the worked
|
|
1291
1284
|
examples — including why binary data forces function tools over
|
|
1292
1285
|
subagents, and how a tool signature can enforce an epistemic rule (the
|
|
1293
1286
|
blind inventory).
|
|
1294
1287
|
|
|
1295
1288
|
**Add a provider**: follow `claudeAdapter.ts` (SDK-based, key-gated, a
|
|
1296
|
-
`ModelAdapter` on the engine's model contract,
|
|
1297
|
-
`
|
|
1298
|
-
|
|
1299
|
-
by its shim `ollamaLlm.ts`), and register it behind a model-id prefix.
|
|
1289
|
+
`ModelAdapter` on the engine's model contract) or, for a chat-completions
|
|
1290
|
+
API, `ollamaAdapter.ts` (fetch-based, keyless: a `ChatCompletionsAdapter`
|
|
1291
|
+
subclass), and register it behind a model-id prefix.
|
|
1300
1292
|
|
|
1301
1293
|
**Point an agent at an MCP server**: set `mcp_server_url:` on a
|
|
1302
1294
|
subagent. `scripts/demo_mcp_server.ts` is a complete server to copy —
|
package/QUICKSTART.md
CHANGED
|
@@ -82,9 +82,10 @@ after answering:
|
|
|
82
82
|
npm run syndicate:critic -- "In two sentences, why did the Library of Alexandria decline?"
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
-
The syndicate layer itself is optional. `scripts/direct_call.ts`
|
|
86
|
-
a single
|
|
87
|
-
|
|
85
|
+
The syndicate layer itself is optional. `scripts/direct_call.ts` makes
|
|
86
|
+
a single model call with no YAML at all — the engine's model contract on
|
|
87
|
+
its own (`melchizedek-agents/model`), and the block to copy when embedding
|
|
88
|
+
a model call in your own code:
|
|
88
89
|
|
|
89
90
|
```bash
|
|
90
91
|
npm run demo:direct -- "In one sentence: what is an agent?"
|
|
@@ -180,22 +181,22 @@ Everything above runs inside a clone. When your syndicates deserve their
|
|
|
180
181
|
own repo, the same engine is a typed dependency:
|
|
181
182
|
|
|
182
183
|
```bash
|
|
183
|
-
npm install melchizedek-agents
|
|
184
|
+
npm install melchizedek-agents
|
|
184
185
|
npx melchizedek-init # config/agents/conversational.yaml + .env; --list for others
|
|
185
186
|
npx melchizedek-doctor # which keys it needs, and whether it is ready
|
|
186
187
|
```
|
|
187
188
|
|
|
188
189
|
```typescript
|
|
189
|
-
import { InProcessSessionService,
|
|
190
|
+
import { InProcessSessionService, loadSyndicate, logProviderStatuses, runSyndicateTurn } from 'melchizedek-agents';
|
|
190
191
|
|
|
191
|
-
|
|
192
|
+
logProviderStatuses(console.log); // reports which providers have a key
|
|
192
193
|
const config = loadSyndicate('mine.yaml'); // reads <your-repo>/config/agents/mine.yaml
|
|
193
194
|
|
|
194
195
|
const result = await runSyndicateTurn({
|
|
195
196
|
config,
|
|
196
197
|
parts: [{ text: 'Hello' }],
|
|
197
198
|
appName: 'my-app', userId: 'u1', sessionId: 'c1',
|
|
198
|
-
sessionService:
|
|
199
|
+
sessionService: new InProcessSessionService(),
|
|
199
200
|
});
|
|
200
201
|
console.log(result.text);
|
|
201
202
|
```
|
|
@@ -222,10 +223,10 @@ console.log(result.text);
|
|
|
222
223
|
- Deeper imports are available as subpaths — `melchizedek-agents/models/registry`,
|
|
223
224
|
`melchizedek-agents/tools/webExtractTool`, `melchizedek-agents/memory`,
|
|
224
225
|
and friends — all typed.
|
|
225
|
-
- **
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
226
|
+
- **One engine, no ADK.** Every turn runs on the engine's own agent loop;
|
|
227
|
+
1.0.0 removed Google ADK, and `MELCHIZEDEK_RUNTIME=adk` is an error.
|
|
228
|
+
Upgrading from 0.x: read the 1.0.0 "Breaking — read before upgrading"
|
|
229
|
+
section of [`CHANGELOG.md`](./CHANGELOG.md).
|
|
229
230
|
`npx melchizedek-doctor` prints which runtime is in use.
|
|
230
231
|
- **Your coding agent can learn all of this.** The package ships a
|
|
231
232
|
six-skill suite (`skills/`, the open SKILL.md standard) covering the
|