melchizedek-agents 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +252 -76
- package/DOCUMENTATION.md +44 -15
- package/QUICKSTART.md +9 -6
- package/README.md +6 -9
- package/config/agents/syndicateSchema.yaml +3 -0
- package/dist/lib/adkPeer.d.ts +63 -0
- package/dist/lib/adkPeer.js +240 -0
- package/dist/lib/compile.d.ts +40 -2
- package/dist/lib/compile.js +80 -12
- package/dist/lib/compileAdk.d.ts +7 -4
- package/dist/lib/compileAdk.js +22 -12
- package/dist/lib/compileNative.d.ts +28 -2
- package/dist/lib/compileNative.js +60 -4
- package/dist/lib/doctor.d.ts +28 -1
- package/dist/lib/doctor.js +63 -2
- package/dist/lib/index.d.ts +4 -0
- package/dist/lib/index.js +5 -0
- package/dist/lib/models/adapterResolver.d.ts +13 -11
- package/dist/lib/models/adapterResolver.js +11 -10
- package/dist/lib/models/adkGeminiAdapter.js +2 -0
- package/dist/lib/models/adkShim.d.ts +1 -1
- package/dist/lib/models/adkShim.js +1 -1
- package/dist/lib/models/capabilities.js +13 -10
- package/dist/lib/models/claudeLlm.js +2 -2
- package/dist/lib/models/fallback.d.ts +1 -1
- package/dist/lib/models/fallback.js +1 -1
- package/dist/lib/models/gatewayLlm.js +2 -2
- package/dist/lib/models/geminiAdapter.d.ts +6 -4
- package/dist/lib/models/geminiAdapter.js +28 -5
- package/dist/lib/models/geminiState.d.ts +21 -0
- package/dist/lib/models/geminiState.js +26 -0
- package/dist/lib/models/genaiMapping.d.ts +24 -4
- package/dist/lib/models/genaiMapping.js +109 -6
- package/dist/lib/models/gptLlm.js +2 -2
- package/dist/lib/models/grokLlm.js +2 -2
- package/dist/lib/models/kimiLlm.js +2 -2
- package/dist/lib/models/ollamaLlm.js +2 -2
- package/dist/lib/models/registry.d.ts +5 -1
- package/dist/lib/models/registry.js +17 -12
- package/dist/lib/models/tracedGemini.d.ts +1 -1
- package/dist/lib/models/tracedGemini.js +1 -1
- package/dist/lib/runtime/adkSessionBridge.d.ts +1 -1
- package/dist/lib/runtime/adkSessionBridge.js +1 -1
- package/dist/lib/runtime/approvals.d.ts +5 -0
- package/dist/lib/runtime/approvals.js +39 -8
- package/dist/lib/runtime/credentials.d.ts +3 -1
- package/dist/lib/runtime/credentials.js +6 -1
- package/dist/lib/runtime/native/agentLoop.d.ts +7 -1
- package/dist/lib/runtime/native/agentLoop.js +31 -13
- package/dist/lib/runtime/native/delegate.d.ts +53 -0
- package/dist/lib/runtime/native/delegate.js +91 -8
- package/dist/lib/runtime/native/interrupts.d.ts +6 -3
- package/dist/lib/runtime/native/interrupts.js +23 -4
- package/dist/lib/runtime/native/request.d.ts +1 -1
- package/dist/lib/runtime/native/request.js +1 -1
- package/dist/lib/runtime/native/selfCorrection.d.ts +64 -6
- package/dist/lib/runtime/native/selfCorrection.js +82 -8
- package/dist/lib/runtime/native/step.d.ts +14 -6
- package/dist/lib/runtime/native/step.js +34 -10
- package/dist/lib/runtime/runtimeFlag.d.ts +13 -5
- package/dist/lib/runtime/runtimeFlag.js +14 -6
- package/dist/lib/runtime/syndicateTurn.d.ts +15 -10
- package/dist/lib/runtime/syndicateTurn.js +59 -32
- package/dist/lib/runtime/valueDepth.d.ts +23 -0
- package/dist/lib/runtime/valueDepth.js +41 -0
- package/dist/lib/session/supabaseSessionService.d.ts +1 -1
- package/dist/lib/session/supabaseSessionService.js +1 -1
- package/dist/lib/session/transcript.d.ts +1 -1
- package/dist/lib/session/transcript.js +5 -3
- package/dist/lib/storage/postgres/sessionService.d.ts +1 -1
- package/dist/lib/storage/postgres/sessionService.js +1 -1
- package/dist/lib/syndicateSchema.d.ts +2 -0
- package/dist/lib/syndicateSchema.js +27 -6
- package/dist/lib/toolRegistry.d.ts +12 -1
- package/dist/lib/toolRegistry.js +42 -2
- package/dist/lib/tools/adkTool.d.ts +1 -1
- package/dist/lib/tools/adkTool.js +1 -1
- package/dist/lib/tools/collectionsSearchTool.d.ts +1 -1
- package/dist/lib/tools/collectionsSearchTool.js +1 -1
- package/dist/lib/tools/generateImageTool.d.ts +1 -1
- package/dist/lib/tools/inspectImageTool.d.ts +1 -1
- package/dist/lib/tools/urlContextTool.d.ts +1 -1
- package/dist/lib/tools/urlContextTool.js +1 -1
- package/dist/lib/tools/webExtractTool.d.ts +1 -1
- package/dist/lib/tools/webSearchTool.d.ts +1 -1
- package/dist/lib/tools/webSearchTool.js +1 -1
- package/dist/lib/tools/xApiSearchTool.d.ts +1 -1
- package/dist/lib/tools/xSearchTool.d.ts +1 -1
- package/dist/lib/tools/xSearchTool.js +1 -1
- package/dist/lib/wiki/agentRun.d.ts +1 -1
- package/dist/lib/wiki/agentRun.js +2 -1
- package/dist/lib/workflow/agentNode.d.ts +21 -4
- package/dist/lib/workflow/agentNode.js +96 -5
- package/dist/lib/workflow/graph.d.ts +5 -4
- package/dist/lib/workflow/graph.js +14 -4
- package/dist/lib/workflow/resume.d.ts +10 -9
- package/dist/lib/workflow/resume.js +13 -12
- package/dist/lib/workflow/scheduler.d.ts +10 -7
- package/dist/lib/workflow/scheduler.js +15 -2
- package/dist/lib/workflow.d.ts +33 -11
- package/dist/lib/workflow.js +49 -27
- package/dist/lib/workflowConfig.d.ts +4 -0
- package/dist/lib/workflowConfig.js +4 -0
- package/dist/scripts/doctor.d.ts +3 -1
- package/dist/scripts/doctor.js +4 -2
- package/package.json +6 -3
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,258 @@ the starter pack and the templates), not the repo's full history.
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## 0.20.0 — 2026-10-08
|
|
10
|
+
|
|
11
|
+
Release 0.20.0: the native runtime is the default, and `@google/adk` is an
|
|
12
|
+
optional peer (ADR 0102).
|
|
13
|
+
|
|
14
|
+
### Breaking — read before upgrading
|
|
15
|
+
|
|
16
|
+
- **Breaking: the native runtime is the default (WS5-1, ADR 0102).** A
|
|
17
|
+
turn with no `runtime` option and no `MELCHIZEDEK_RUNTIME` now runs on the
|
|
18
|
+
engine's own loop and scheduler (`DEFAULT_RUNTIME` is `native`), on every
|
|
19
|
+
surface: `runSyndicateTurn`, the A2A server, the bins, the wiki agents.
|
|
20
|
+
It stores the events the ADK runtime stores, and every session ADK wrote
|
|
21
|
+
resumes under it (`tests/sessionFixtures.test.ts`, ADR 0045's stop rule),
|
|
22
|
+
so a deployment that upgrades keeps its conversations. **To stay on ADK**
|
|
23
|
+
for this release: install `@google/adk@~2.2.0` beside the package and set
|
|
24
|
+
`MELCHIZEDEK_RUNTIME=adk` (or pass `runtime: 'adk'`); a conversation can
|
|
25
|
+
move between the runtimes either way. What differs on native: approval
|
|
26
|
+
gates on workflow nodes run on native only (ADR 0098); `context:`
|
|
27
|
+
compaction, `mode: task` and workflows run on the engine's ports of ADK's
|
|
28
|
+
compactor, task mode and scheduler (ADR 0078, ADR 0081, ADR 0087, ADR
|
|
29
|
+
0095); a Gemini agent is not shown the reflection tool and stores no
|
|
30
|
+
`turnComplete` (ADR 0097, ADR 0100); self-correction's reflection call on
|
|
31
|
+
Gemini 3 is signed (ADR 0103); a caller's `transformAgent` is ADK-only,
|
|
32
|
+
and an `ask_user` tool listed on a workflow agent node (rather than an
|
|
33
|
+
`ask_user` node) is refused, each with `UnsupportedOnRuntimeError` before
|
|
34
|
+
any model call (ADR 0073, ADR 0092). **1.0.0
|
|
35
|
+
removes the adk runtime** (ADR 0045).
|
|
36
|
+
- **Breaking: `@google/adk` is an optional peer dependency.** npm no longer
|
|
37
|
+
installs it with the package; nothing on the native runtime loads it, and
|
|
38
|
+
`lib/adkPeer.ts` is the one module that tries to. Without it, everything
|
|
39
|
+
only ADK runs fails with the new `AdkNotInstalledError`, which names the
|
|
40
|
+
package and the install command: `MELCHIZEDEK_RUNTIME=adk`,
|
|
41
|
+
`compileGraph` / `compileSubagent` / `compileWorkflow`, `retryPlugins`,
|
|
42
|
+
`GEMINI_ADAPTER=adk`, a wiki agent on adk, and the ADK face of a tool, a
|
|
43
|
+
model shim or a session store (their `runAsync`, `generateContentAsync`,
|
|
44
|
+
`appendEvent`). The engine's classes that extend ADK's (the
|
|
45
|
+
`FunctionTool`s in the tool registry, the model shims, the session
|
|
46
|
+
stores) still construct and still carry their own Tool, adapter or store;
|
|
47
|
+
with ADK installed they are ADK's own classes, as before. An install of
|
|
48
|
+
ADK that fails to load for another reason is still an error. A
|
|
49
|
+
TypeScript consumer without ADK sees ADK's types in the declarations as
|
|
50
|
+
unresolved (use `skipLibCheck`). The package now uses a top-level
|
|
51
|
+
`await` to load the peer, so it cannot be `require()`d from CommonJS.
|
|
52
|
+
- **Breaking: a Gemini id gets the engine's `GeminiAdapter` by default
|
|
53
|
+
(ADR 0100).** `resolveAdapter` from `melchizedek-agents/models/registry`
|
|
54
|
+
and `geminiAdapterChoice()` default to `engine`; `GEMINI_ADAPTER=adk`
|
|
55
|
+
(or `{ gemini: 'adk' }`) keeps `AdkGeminiAdapter` for this release, with
|
|
56
|
+
`@google/adk` installed. The adk runtime keeps `TracedGemini`.
|
|
57
|
+
- **Breaking: `registerTool` refuses the framework's reserved names.**
|
|
58
|
+
`adk_request_confirmation`, `adk_request_credential`,
|
|
59
|
+
`adk_request_input`, `adk_handle_model_error`, `transfer_to_agent`,
|
|
60
|
+
`set_model_response`, `finish_task`, and `ask_user` unless it is the
|
|
61
|
+
framework's own tool, are refused as the registry name or the tool's own
|
|
62
|
+
name, with `{ override: true }` too: a tool under one of them would be
|
|
63
|
+
read as the framework's interrupt, delegation or answer.
|
|
64
|
+
`RESERVED_TOOL_NAMES` is exported from `melchizedek-agents/tools`.
|
|
65
|
+
- **Breaking: a workflow `map:` node refuses `retry` and `timeout`
|
|
66
|
+
(ADR 0103).** Neither runtime ever applied them: each item of a map runs
|
|
67
|
+
under the mapped agent's own node entry, as ADK runs it. A YAML that set
|
|
68
|
+
them on the map entry loaded and silently ignored them; it is now refused
|
|
69
|
+
at load with `workflow.nodes.<Map>.retry — retry on a map node is not
|
|
70
|
+
applied: each item runs under its agent's own retry; set it on
|
|
71
|
+
nodes.<Agent>` (and the same for `timeout`). Move the keys to the mapped
|
|
72
|
+
agent's entry. No shipped example or template sets them.
|
|
73
|
+
|
|
74
|
+
### Added and changed
|
|
75
|
+
|
|
76
|
+
- **The doctor prints the runtime (ADR 0102).** `melchizedek-doctor` opens
|
|
77
|
+
with a `runtime` line: the runtime in use, where it came from
|
|
78
|
+
(`MELCHIZEDEK_RUNTIME` or the default) and whether `@google/adk` is
|
|
79
|
+
installed, with its version. `--check` also fails when
|
|
80
|
+
`MELCHIZEDEK_RUNTIME=adk` is set without ADK, or holds a value no turn
|
|
81
|
+
accepts. `runDoctor()` returns it as `runtime`, and `runtimeReport` is
|
|
82
|
+
exported from `lib/doctor.ts`.
|
|
83
|
+
- **New exports.** From the barrel and `melchizedek-agents/runtime`:
|
|
84
|
+
`describeRuntime` (the runtime and its source), `RuntimeSource`,
|
|
85
|
+
`AdkNotInstalledError`, `adkInstalled`, `InProcessSessionService` (a
|
|
86
|
+
session store that needs no ADK) and `asAdkSessionService` /
|
|
87
|
+
`asSessionService`; the barrel also exports `DEFAULT_RUNTIME` and
|
|
88
|
+
`RuntimeName`. A turn without ADK takes
|
|
89
|
+
`sessionService: asAdkSessionService(new InProcessSessionService())`.
|
|
90
|
+
The exports map does not change.
|
|
91
|
+
- **CI consumes the packed tarball twice**: without `@google/adk` a shipped
|
|
92
|
+
example's turn runs on native, and with it the same turn runs on adk.
|
|
93
|
+
|
|
94
|
+
- **The native loop's security gate (WS5-5, ADR 0101).** A model's answer is
|
|
95
|
+
now held to the model contract before either runtime stores it:
|
|
96
|
+
`modelResponseToLlmResponse` in `melchizedek-agents/models/genaiMapping`
|
|
97
|
+
drops a part the contract does not allow (an unknown kind, `null`, a text
|
|
98
|
+
part whose text is not a string, a tool result) and coerces a tool call's
|
|
99
|
+
name, id and arguments (`{}` for none, `{ raw }` otherwise); the new
|
|
100
|
+
`contractModelResponse` export is that check. A call's arguments or a
|
|
101
|
+
tool's result nested deeper than 64 levels is replaced by a short note
|
|
102
|
+
(`TOO_DEEP_ARGUMENTS`; on the native runtime `TOO_DEEP_RESULT`), where it
|
|
103
|
+
used to fail that turn and every later one on the session. A
|
|
104
|
+
`yaml_reference` chain that reaches itself, or goes past 16 levels, now
|
|
105
|
+
fails the compile with an Error naming the chain, on both runtimes; it
|
|
106
|
+
used to overflow the stack and stop the process. On the native runtime a
|
|
107
|
+
call id `__proto__` opens its approval as any id does, a credential
|
|
108
|
+
request in an event the user wrote is not pending, a resumed OAuth call
|
|
109
|
+
is the one the agent made, and a replayed grant runs nothing.
|
|
110
|
+
`wiki/operations/native-loop-security.md` is the threat model;
|
|
111
|
+
`tests/nativeFuzz.test.ts` fuzzes the loop.
|
|
112
|
+
- **On the native runtime, self-correction's reflection call is signed on
|
|
113
|
+
Gemini (ADR 0103).** When a Gemini 3 model calls the reserved
|
|
114
|
+
`adk_handle_model_error` tool, or answers `MALFORMED_FUNCTION_CALL`, the
|
|
115
|
+
reflection call stored in its place now carries the replaced call's
|
|
116
|
+
`thoughtSignature`, or Gemini's documented placeholder
|
|
117
|
+
(`skip_thought_signature_validator`) when there was none, so the next
|
|
118
|
+
request no longer fails with Gemini's "missing a thought_signature" 400.
|
|
119
|
+
On Gemini 2.x only a carried signature is added. The ADK runtime is
|
|
120
|
+
unchanged: ADK's plugin still stores the call unsigned. The stored event
|
|
121
|
+
differs from ADK's by that one field. `PLACEHOLDER_THOUGHT_SIGNATURE` is
|
|
122
|
+
still exported from `melchizedek-agents/models/geminiAdapter`.
|
|
123
|
+
|
|
124
|
+
- **A workflow node's `retry` takes `exceptions` and `jitter` (ADR 0103).**
|
|
125
|
+
`retry: { exceptions: [NodeTimeoutError] }` retries only a failure whose
|
|
126
|
+
error class or `name` is listed; `jitter` sets the backoff's randomness
|
|
127
|
+
(0 = none, default 1). Both runtimes honour them: the ADK runtime hands
|
|
128
|
+
them to ADK's `retryConfig`, the native scheduler applies them as ADK's
|
|
129
|
+
`retry_utils` does. `syndicate.schema.json` is regenerated; the `exports`
|
|
130
|
+
map is unchanged.
|
|
131
|
+
|
|
132
|
+
- **The capability matrix's Gemini column is asserted on the engine's own
|
|
133
|
+
Gemini adapter (WS3-6, ADR 0100).** Every Gemini cell is now evidence
|
|
134
|
+
`test`, checked against the request `GeminiAdapter` sends through the
|
|
135
|
+
real `@google/genai` client, as every other column is; `npm run doctor --
|
|
136
|
+
--matrix` says so. On the native runtime a Gemini agent's stored events no
|
|
137
|
+
longer carry `turnComplete`, as the ADK runtime's never have; nothing reads
|
|
138
|
+
the field. A Gemini answer that ran code through the engine's adapter
|
|
139
|
+
(`GEMINI_ADAPTER=engine`, or `GeminiAdapter` behind the shim) now stores
|
|
140
|
+
the `executableCode` and `codeExecutionResult` parts as ADK's Gemini stores
|
|
141
|
+
them, where the session held none before; `partsToGenai` in
|
|
142
|
+
`melchizedek-agents/models/genaiMapping` is the mapping that writes them
|
|
143
|
+
out. `scripts/gemini_engine_check.ts` is the live check gate G3 runs:
|
|
144
|
+
grounding, code execution, a function tool beside server-side tools, and a
|
|
145
|
+
two-turn session, with `GeminiAdapter` on both runtimes. `GeminiAdapter`
|
|
146
|
+
becomes the default in 0.20.0 (see Breaking above).
|
|
147
|
+
|
|
148
|
+
- **A workflow syndicate can be a subagent, and a workflow node can carry
|
|
149
|
+
an approval gate (WS4-7, ADR 0098).** A DELEGATE syndicate's
|
|
150
|
+
`yaml_reference` to a `workflow:` syndicate now runs the whole graph as
|
|
151
|
+
the subagent tool, under the entry's name and description, on both
|
|
152
|
+
runtimes: the graph's last output is the tool's answer. Before, only the
|
|
153
|
+
nested syndicate's orchestrator ran. A nested workflow with an
|
|
154
|
+
`ask_user` node is now refused by name at compile time (its pause could
|
|
155
|
+
not reach the caller); as a dispatch route or a workflow node, a
|
|
156
|
+
workflow syndicate is still its orchestrator alone. `require_approval`
|
|
157
|
+
on a workflow node's agent now validates (except on an agent a `map`
|
|
158
|
+
node runs): on the native runtime the gated call pauses the node and the
|
|
159
|
+
turn ends `input-required` with `result.approval`, and the person's
|
|
160
|
+
decision runs or refuses the pinned call once and walks on; another
|
|
161
|
+
message repeats the request. On the ADK runtime a gated workflow throws
|
|
162
|
+
`UnsupportedOnRuntimeError` before any model call, because ADK's resume
|
|
163
|
+
restarts the node and never runs the call. `melchizedek-agents/compile`
|
|
164
|
+
adds the `workflow` kind to `SpecTool`, and exports
|
|
165
|
+
`compileWorkflowSpec` and the `WorkflowSpec` type.
|
|
166
|
+
- **A Gemini agent on the native runtime is no longer shown the reflection
|
|
167
|
+
tool (WS4-6b, ADR 0097).** With `retries.model_errors` on (the default),
|
|
168
|
+
native declared `adk_handle_model_error` to every model. ADK's own Gemini
|
|
169
|
+
never sends it, and a Gemini 3 model that called it on native failed its
|
|
170
|
+
next step with Gemini's missing `thought_signature` 400 (a workflow
|
|
171
|
+
node then failed the turn `NODE_FAILED`). Native now sends a Gemini model
|
|
172
|
+
the same tools as ADK; a model on any other provider, or a Gemini adapter
|
|
173
|
+
a resolver returns behind `adkShim`, is still told of the tool, as on ADK.
|
|
174
|
+
ADK turns are unchanged.
|
|
175
|
+
|
|
176
|
+
## 0.19.0 — 2026-10-08
|
|
177
|
+
|
|
178
|
+
The native runtime ships in this release as an opt-in: set
|
|
179
|
+
`MELCHIZEDEK_RUNTIME=native` or pass `runtime: 'native'` to `runSyndicateTurn`.
|
|
180
|
+
`adk` stays the default (ADR 0099). The `@google/adk` peer dependency is
|
|
181
|
+
unchanged.
|
|
182
|
+
|
|
183
|
+
### Breaking — read before upgrading
|
|
184
|
+
|
|
185
|
+
- **Breaking: a skill script no longer inherits the server's environment
|
|
186
|
+
(ADR 0086).** An approved `run_skill_script` starts from PATH,
|
|
187
|
+
HOME/USERPROFILE, TMPDIR/TEMP/TMP, LANG, LC_*, TZ, the user's name and
|
|
188
|
+
the Windows essentials, and nothing else: provider keys, `DATABASE_URL`
|
|
189
|
+
and the server's bearer secrets no longer reach it. A script that relied
|
|
190
|
+
on an inherited variable must now name it in the agent's YAML, under the
|
|
191
|
+
new `skills.env` (names only), or under `skills.secret_env` when the
|
|
192
|
+
name looks like a secret (KEY, TOKEN, SECRET, PASSWORD, AUTH, DATABASE,
|
|
193
|
+
…), which `skills.env` refuses. Both need `scripts: local`. A script's
|
|
194
|
+
stdout and stderr are each cut at 20,000 characters, ending with
|
|
195
|
+
`[stdout truncated: N more characters not shown (the limit is 20000)]`.
|
|
196
|
+
The same on both runtimes. `LocalScriptExecutor` takes `envNames`,
|
|
197
|
+
`sourceEnv` and `maxOutputChars`; `lib/tools/skills/env.ts` is new. The
|
|
198
|
+
`exports` map is unchanged.
|
|
199
|
+
- **Breaking for subclasses of `OpenAiCompatibleLlm`: the chat-completions
|
|
200
|
+
adapters move onto the model contract (ADR 0057).** New modules under
|
|
201
|
+
`melchizedek-agents/models/`:
|
|
202
|
+
- `chatCompletionsAdapter`: `ChatCompletionsAdapter`, the base that turns a
|
|
203
|
+
`ModelRequest` into a chat-completions body and a completion (JSON or
|
|
204
|
+
SSE) into contract responses; `ChatCompletionsRequest` and
|
|
205
|
+
`OlderSpelling`; `chatUsage` and `sumUsage` (usage in the contract's
|
|
206
|
+
meaning); `splitThinkBlocks`, `ThinkStreamSplitter`,
|
|
207
|
+
`REASONING_CONTENT_KIND` and `ENGINE_CALL_ID_PREFIX`.
|
|
208
|
+
- `ollamaAdapter` (`OllamaAdapter`), `kimiAdapter` (`KimiAdapter`, and
|
|
209
|
+
`isKimiK3`, `wantsReasoningReplay`, `MOONSHOT_BASE_URL`, which
|
|
210
|
+
`models/kimiLlm` still exports) and `gatewayAdapter` (`GatewayAdapter`).
|
|
211
|
+
|
|
212
|
+
`OpenAiCompatibleLlm` is now an `AdkShim` whose constructor takes the
|
|
213
|
+
adapter, and its protected hooks (`endpointUrl`, `headers`,
|
|
214
|
+
`wireModelName`, `extraBodyFields`, `httpError`, `noAnswerError` and the
|
|
215
|
+
rest) move to `ChatCompletionsAdapter`, on contract types. A provider of
|
|
216
|
+
your own subclasses `ChatCompletionsAdapter` and runs under ADK as
|
|
217
|
+
`adkShim(adapter)` or as an `OpenAiCompatibleLlm` subclass. `OllamaLlm`,
|
|
218
|
+
`KimiLlm` and `GatewayLlm` keep their constructors, ids, error codes and
|
|
219
|
+
wording, and the shape of what they yield: usage counts the reasoning in
|
|
220
|
+
`candidatesTokenCount` as before, so the ledger's counts are unchanged.
|
|
221
|
+
`models/openAiCompatibleLlm` adds `olderSpellingOf` and
|
|
222
|
+
`chatUsageMetadata`. `AdkShim` gains a protected `toModelRequest` seam
|
|
223
|
+
beside `toLlmResponse` (ADR 0056); the chat shims override both.
|
|
224
|
+
|
|
225
|
+
What reaches the provider changes only where the contract maps a field
|
|
226
|
+
the old classes ignored or spelled as written:
|
|
227
|
+
- `stopSequences` are sent as `stop`.
|
|
228
|
+
- A function-calling mode is honoured: `NONE` sends no tools; the gateway
|
|
229
|
+
sends `ANY` as `tool_choice: required` or the named tool, and Kimi and
|
|
230
|
+
Ollama weaken it to auto (`llm.tool_choice.weakened` on the span).
|
|
231
|
+
- The older spelling's reasoning follows ADR 0047's mapping, as
|
|
232
|
+
`reasoning:` already did: `thinkingConfig.thinkingBudget` alone now
|
|
233
|
+
travels as its level (`0` is `none`), `reasoningEffort: medium` on
|
|
234
|
+
`kimi-k3` is sent as `high`, and `minimal` as each model's `none`.
|
|
235
|
+
A word that is no level (`max`, `xhigh`) is still sent as written.
|
|
236
|
+
- A tool call stored without an id is sent with one, matched to its
|
|
237
|
+
result, where the result's `tool_call_id` was empty.
|
|
238
|
+
- The no-answer hints name `reasoning: none` (the older spelling too).
|
|
239
|
+
- Every error a chat shim yields carries its retry verdict
|
|
240
|
+
(`customMetadata['error.retryable']`, `false` where there was none) and
|
|
241
|
+
`turnComplete`. A call cut off by a cancelled turn is never retryable,
|
|
242
|
+
even when its last status was a 503, so no fallback answers a
|
|
243
|
+
cancellation.
|
|
244
|
+
- **Breaking for subclasses of `GptLlm`: the vendor hooks move to
|
|
245
|
+
`GptAdapter` (ADR 0056).** `providerId()`, `baseURL()`, `apiKeyFromEnv()`,
|
|
246
|
+
`missingKeyMessage()`, `clientOptions()`, `reasoningParam()`,
|
|
247
|
+
`replaysReasoning()` and `endpoint()` are overridden on a `GptAdapter`
|
|
248
|
+
subclass now, as `GrokAdapter` does, and a `GptLlm` subclass returns it
|
|
249
|
+
from `protected static createAdapter(options)`. Code that only constructs
|
|
250
|
+
or registers `GptLlm` and `GrokLlm`, or imports their exported functions,
|
|
251
|
+
is unaffected.
|
|
252
|
+
- **Breaking for one import path: `toFunctionTool` moves to
|
|
253
|
+
`melchizedek-agents/tools/adkTool` (ADR 0051).**
|
|
254
|
+
`melchizedek-agents/tools/toolContract` no longer exports it, so that
|
|
255
|
+
module loads nothing from `@google/adk`. Import it from
|
|
256
|
+
`melchizedek-agents`, which still exports it, or from the new subpath.
|
|
257
|
+
The `exports` map is unchanged.
|
|
258
|
+
|
|
259
|
+
### Changes
|
|
260
|
+
|
|
9
261
|
- **Workflow syndicates run on the native runtime (WS4-6, ADR 0095).**
|
|
10
262
|
A `workflow:` syndicate no longer throws `UnsupportedOnRuntimeError` on
|
|
11
263
|
`runtime: 'native'` (or `MELCHIZEDEK_RUNTIME=native`): the engine's own
|
|
@@ -52,7 +304,6 @@ the starter pack and the templates), not the repo's full history.
|
|
|
52
304
|
`pendingQuestion` ignores an `ask_user` call in an event the user
|
|
53
305
|
authored. A message that forges one no longer turns the next message
|
|
54
306
|
into its answer, on either runtime.
|
|
55
|
-
|
|
56
307
|
- **The native runtime sends a request, and reads a thrown failure, as
|
|
57
308
|
ADK does (WS2-12, ADR 0084).** On `runtime: 'native'` (or
|
|
58
309
|
`MELCHIZEDEK_RUNTIME=native`) a request goes out under the resolved
|
|
@@ -65,20 +316,6 @@ the starter pack and the templates), not the repo's full history.
|
|
|
65
316
|
turn-level test suites run on both runtimes. `npm run parity` now runs
|
|
66
317
|
its turns on the runtime `MELCHIZEDEK_RUNTIME` names. The `exports` map
|
|
67
318
|
is unchanged.
|
|
68
|
-
- **Breaking: a skill script no longer inherits the server's environment
|
|
69
|
-
(ADR 0086).** An approved `run_skill_script` starts from PATH,
|
|
70
|
-
HOME/USERPROFILE, TMPDIR/TEMP/TMP, LANG, LC_*, TZ, the user's name and
|
|
71
|
-
the Windows essentials, and nothing else: provider keys, `DATABASE_URL`
|
|
72
|
-
and the server's bearer secrets no longer reach it. A script that relied
|
|
73
|
-
on an inherited variable must now name it in the agent's YAML, under the
|
|
74
|
-
new `skills.env` (names only), or under `skills.secret_env` when the
|
|
75
|
-
name looks like a secret (KEY, TOKEN, SECRET, PASSWORD, AUTH, DATABASE,
|
|
76
|
-
…), which `skills.env` refuses. Both need `scripts: local`. A script's
|
|
77
|
-
stdout and stderr are each cut at 20,000 characters, ending with
|
|
78
|
-
`[stdout truncated: N more characters not shown (the limit is 20000)]`.
|
|
79
|
-
The same on both runtimes. `LocalScriptExecutor` takes `envNames`,
|
|
80
|
-
`sourceEnv` and `maxOutputChars`; `lib/tools/skills/env.ts` is new. The
|
|
81
|
-
`exports` map is unchanged.
|
|
82
319
|
- **The skills harness no longer builds on ADK (ADR 0083).** An agent's
|
|
83
320
|
`skills:` block loads, reads and runs skills through the engine's own
|
|
84
321
|
modules (`lib/tools/skills/`), the same on `runtime: 'adk'` and
|
|
@@ -210,7 +447,6 @@ the starter pack and the templates), not the repo's full history.
|
|
|
210
447
|
- The audit trail gains `credential.put`, `credential.refresh`,
|
|
211
448
|
`credential.revoke` and `credential.erase` (`AuditEventName`), with the
|
|
212
449
|
provider and app and never a token.
|
|
213
|
-
|
|
214
450
|
- **The ledger reads the native loop's spans (ADR 0076).** The native loop
|
|
215
451
|
(not yet selectable, WS2-10) opens `agent.invoke <name>`, `model.call` and
|
|
216
452
|
`tool.execute <name>` spans in scope `melchizedek.runtime`, and a native
|
|
@@ -344,7 +580,6 @@ the starter pack and the templates), not the repo's full history.
|
|
|
344
580
|
server-side name is no longer treated as that tool. An MCP tool's nested
|
|
345
581
|
schemas no longer carry `default`, `propertyNames`, `$schema` or a boolean
|
|
346
582
|
`additionalProperties`. `propertyNames` was refused by the Gemini API.
|
|
347
|
-
|
|
348
583
|
- **The engine parses OpenAPI specs itself (ADR 0063).** A new module,
|
|
349
584
|
`melchizedek-agents/tools/openapi/parse` (through the existing
|
|
350
585
|
`./tools/*` pattern), exports `parseOpenApiSpec` and
|
|
@@ -386,59 +621,6 @@ the starter pack and the templates), not the repo's full history.
|
|
|
386
621
|
quadratically on a long run of slashes (CodeQL js/polynomial-redos).
|
|
387
622
|
They now share `trimTrailingSlashes` (new module
|
|
388
623
|
`melchizedek-agents/models/urls`). Results are unchanged.
|
|
389
|
-
- **Breaking for subclasses of `OpenAiCompatibleLlm`: the chat-completions
|
|
390
|
-
adapters move onto the model contract (ADR 0057).** New modules under
|
|
391
|
-
`melchizedek-agents/models/`:
|
|
392
|
-
- `chatCompletionsAdapter`: `ChatCompletionsAdapter`, the base that turns a
|
|
393
|
-
`ModelRequest` into a chat-completions body and a completion (JSON or
|
|
394
|
-
SSE) into contract responses; `ChatCompletionsRequest` and
|
|
395
|
-
`OlderSpelling`; `chatUsage` and `sumUsage` (usage in the contract's
|
|
396
|
-
meaning); `splitThinkBlocks`, `ThinkStreamSplitter`,
|
|
397
|
-
`REASONING_CONTENT_KIND` and `ENGINE_CALL_ID_PREFIX`.
|
|
398
|
-
- `ollamaAdapter` (`OllamaAdapter`), `kimiAdapter` (`KimiAdapter`, and
|
|
399
|
-
`isKimiK3`, `wantsReasoningReplay`, `MOONSHOT_BASE_URL`, which
|
|
400
|
-
`models/kimiLlm` still exports) and `gatewayAdapter` (`GatewayAdapter`).
|
|
401
|
-
|
|
402
|
-
`OpenAiCompatibleLlm` is now an `AdkShim` whose constructor takes the
|
|
403
|
-
adapter, and its protected hooks (`endpointUrl`, `headers`,
|
|
404
|
-
`wireModelName`, `extraBodyFields`, `httpError`, `noAnswerError` and the
|
|
405
|
-
rest) move to `ChatCompletionsAdapter`, on contract types. A provider of
|
|
406
|
-
your own subclasses `ChatCompletionsAdapter` and runs under ADK as
|
|
407
|
-
`adkShim(adapter)` or as an `OpenAiCompatibleLlm` subclass. `OllamaLlm`,
|
|
408
|
-
`KimiLlm` and `GatewayLlm` keep their constructors, ids, error codes and
|
|
409
|
-
wording, and the shape of what they yield: usage counts the reasoning in
|
|
410
|
-
`candidatesTokenCount` as before, so the ledger's counts are unchanged.
|
|
411
|
-
`models/openAiCompatibleLlm` adds `olderSpellingOf` and
|
|
412
|
-
`chatUsageMetadata`. `AdkShim` gains a protected `toModelRequest` seam
|
|
413
|
-
beside `toLlmResponse` (ADR 0056); the chat shims override both.
|
|
414
|
-
|
|
415
|
-
What reaches the provider changes only where the contract maps a field
|
|
416
|
-
the old classes ignored or spelled as written:
|
|
417
|
-
- `stopSequences` are sent as `stop`.
|
|
418
|
-
- A function-calling mode is honoured: `NONE` sends no tools; the gateway
|
|
419
|
-
sends `ANY` as `tool_choice: required` or the named tool, and Kimi and
|
|
420
|
-
Ollama weaken it to auto (`llm.tool_choice.weakened` on the span).
|
|
421
|
-
- The older spelling's reasoning follows ADR 0047's mapping, as
|
|
422
|
-
`reasoning:` already did: `thinkingConfig.thinkingBudget` alone now
|
|
423
|
-
travels as its level (`0` is `none`), `reasoningEffort: medium` on
|
|
424
|
-
`kimi-k3` is sent as `high`, and `minimal` as each model's `none`.
|
|
425
|
-
A word that is no level (`max`, `xhigh`) is still sent as written.
|
|
426
|
-
- A tool call stored without an id is sent with one, matched to its
|
|
427
|
-
result, where the result's `tool_call_id` was empty.
|
|
428
|
-
- The no-answer hints name `reasoning: none` (the older spelling too).
|
|
429
|
-
- Every error a chat shim yields carries its retry verdict
|
|
430
|
-
(`customMetadata['error.retryable']`, `false` where there was none) and
|
|
431
|
-
`turnComplete`. A call cut off by a cancelled turn is never retryable,
|
|
432
|
-
even when its last status was a 503, so no fallback answers a
|
|
433
|
-
cancellation.
|
|
434
|
-
- **Breaking for subclasses of `GptLlm`: the vendor hooks move to
|
|
435
|
-
`GptAdapter` (ADR 0056).** `providerId()`, `baseURL()`, `apiKeyFromEnv()`,
|
|
436
|
-
`missingKeyMessage()`, `clientOptions()`, `reasoningParam()`,
|
|
437
|
-
`replaysReasoning()` and `endpoint()` are overridden on a `GptAdapter`
|
|
438
|
-
subclass now, as `GrokAdapter` does, and a `GptLlm` subclass returns it
|
|
439
|
-
from `protected static createAdapter(options)`. Code that only constructs
|
|
440
|
-
or registers `GptLlm` and `GrokLlm`, or imports their exported functions,
|
|
441
|
-
is unaffected.
|
|
442
624
|
- **Fix: a message could stall the server in the memory search.**
|
|
443
625
|
`stripHarnessBlocks` (run on every memory query and extraction
|
|
444
626
|
transcript) matched an unclosed `[System Context:` marker with a pattern
|
|
@@ -490,12 +672,6 @@ the starter pack and the templates), not the repo's full history.
|
|
|
490
672
|
`melchizedek-agents/models/claudeModels` adds `ClaudeReasoning`,
|
|
491
673
|
`claudeReasoningOf`, `claudeReasoningFromConfig` and
|
|
492
674
|
`adaptiveThinkingFor`. The `exports` map is unchanged.
|
|
493
|
-
- **Breaking for one import path: `toFunctionTool` moves to
|
|
494
|
-
`melchizedek-agents/tools/adkTool` (ADR 0051).**
|
|
495
|
-
`melchizedek-agents/tools/toolContract` no longer exports it, so that
|
|
496
|
-
module loads nothing from `@google/adk`. Import it from
|
|
497
|
-
`melchizedek-agents`, which still exports it, or from the new subpath.
|
|
498
|
-
The `exports` map is unchanged.
|
|
499
675
|
- **The session services serve both runtimes from the same rows, and
|
|
500
676
|
change behaviour in five places (ADR 0058).** `SupabaseSessionService`,
|
|
501
677
|
`PostgresSessionService` and `ProjectedSessionService` also implement
|
package/DOCUMENTATION.md
CHANGED
|
@@ -56,11 +56,17 @@ facts, embeds them (768-d), and stores them for future recall.
|
|
|
56
56
|
|
|
57
57
|
The compiler (`lib/compile.ts`) first builds a runtime-neutral `AgentSpec`
|
|
58
58
|
per agent; `lib/compileAdk.ts` turns it into the `LlmAgent`, and
|
|
59
|
-
`lib/compileNative.ts` into the engine's own loop's agent.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
`lib/compileNative.ts` into the engine's own loop's agent. Since 0.20.0
|
|
60
|
+
the native loop runs every turn by default
|
|
61
|
+
([ADR 0102](./wiki/decisions/0102-native-default-and-optional-adk-peer.md)):
|
|
62
|
+
`@google/adk` is an optional peer, needed only when
|
|
63
|
+
`MELCHIZEDEK_RUNTIME=adk`, or `runtime: 'adk'` on `runSyndicateTurn`,
|
|
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
|
|
64
70
|
([ADR 0078](./wiki/decisions/0078-native-compaction-ports-adk-compactor.md)),
|
|
65
71
|
and a `workflow:` syndicate on the engine's own scheduler, its pause and
|
|
66
72
|
resume included
|
|
@@ -788,7 +794,8 @@ without a model call. ADK pins the call and its arguments, so an approval
|
|
|
788
794
|
cannot run a different call.
|
|
789
795
|
|
|
790
796
|
Gates are allowed on the orchestrator and on the subagents of a
|
|
791
|
-
plan-dispatch syndicate, which run as the turn's own agent
|
|
797
|
+
plan-dispatch syndicate, which run as the turn's own agent, and on the
|
|
798
|
+
agent nodes of a workflow on the native runtime (§6). A delegated
|
|
792
799
|
subagent runs inside a tool call, where a pause cannot reach the caller, so a
|
|
793
800
|
gate there is a load error, as is any gate inside a nested `yaml_reference`
|
|
794
801
|
syndicate. Only function tools from the registry can be gated, not MCP tools
|
|
@@ -1199,7 +1206,11 @@ the list of results); `tool: <registry name>` (runs the tool with the
|
|
|
1199
1206
|
node input as its arguments); `ask_user: "<question>"` (below). An entry
|
|
1200
1207
|
named after an agent carries modifiers only: `route_key`, `retry`
|
|
1201
1208
|
(`max_attempts`, `initial_delay`, `max_delay`, `backoff_factor`, in
|
|
1202
|
-
seconds
|
|
1209
|
+
seconds; `jitter`, the backoff's randomness, 0 for none; `exceptions`,
|
|
1210
|
+
the error names to retry on, every error when absent) and `timeout`
|
|
1211
|
+
(seconds), which any node but a `map` may carry. A map's items run under
|
|
1212
|
+
the mapped agent's own `retry` and `timeout`, so a `map` entry refuses
|
|
1213
|
+
both and the load error names the agent's entry instead.
|
|
1203
1214
|
|
|
1204
1215
|
**The pause.** An `ask_user` node ends the turn `input-required`
|
|
1205
1216
|
(`result.input`: the node, the question, and what it was asked about).
|
|
@@ -1224,17 +1235,35 @@ again (the attempt is recorded in `answer.nodeErrors`), and a node that
|
|
|
1224
1235
|
gives up fails the turn with `NODE_FAILED` naming it. `max_steps` and
|
|
1225
1236
|
the deadline cap the whole graph as they cap any turn.
|
|
1226
1237
|
|
|
1227
|
-
**
|
|
1228
|
-
and
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1238
|
+
**Approval gates.** A tool in a node agent's `require_approval` pauses
|
|
1239
|
+
that node, and the graph with it: the turn ends `input-required` with
|
|
1240
|
+
`result.approval`, as any approval does, and the next message, the
|
|
1241
|
+
person's decision, resumes the node's own run, which runs or refuses the
|
|
1242
|
+
pinned call once and walks on. Any other message repeats the request and
|
|
1243
|
+
runs nothing. Gates on workflow nodes run on the native runtime only: on
|
|
1244
|
+
ADK, `runSyndicateTurn` refuses such a workflow with
|
|
1245
|
+
`UnsupportedOnRuntimeError` before any model call, because ADK's resume
|
|
1246
|
+
starts the node afresh and never runs the pinned call. The schema refuses
|
|
1247
|
+
a gate on an agent a `map` node runs.
|
|
1248
|
+
|
|
1249
|
+
**As a subagent.** A DELEGATE syndicate's `yaml_reference` to a workflow
|
|
1250
|
+
syndicate runs the whole graph as the subagent tool, under the entry's
|
|
1251
|
+
name and description: the graph's last output is the tool's answer, and
|
|
1252
|
+
its events are kept in the subagent's own session, as for any subagent.
|
|
1253
|
+
A nested workflow may not have an `ask_user` node (a pause inside a tool
|
|
1254
|
+
call cannot reach the caller); it is refused by name. As a dispatch route
|
|
1255
|
+
or a workflow node, a workflow syndicate is still its orchestrator alone.
|
|
1256
|
+
|
|
1257
|
+
**Not yet.** Skill scripts (`skills.scripts: local`) and remote
|
|
1258
|
+
`a2a_agent_url` subagents are refused inside a workflow by the schema. An
|
|
1259
|
+
`ask_user` tool on a node agent is refused too: use an `ask_user` node. The records are [ADR 0030](./wiki/decisions/0030-workflow-graphs.md) and
|
|
1260
|
+
[ADR 0098](./wiki/decisions/0098-workflow-subagent-and-node-approvals.md);
|
|
1233
1261
|
the contract is `lib/workflow.ts`, on ADK's `Workflow`, and on the native
|
|
1234
1262
|
runtime `lib/workflow/turn.ts`, on the engine's own scheduler
|
|
1235
1263
|
([ADR 0095](./wiki/decisions/0095-native-workflow-turn-drains-through-the-adk-reader.md)).
|
|
1236
|
-
On native, a conversation paused inside an agent node
|
|
1237
|
-
(which only ADK resumes) fails the next
|
|
1264
|
+
On native, a conversation paused inside an agent node on anything but an
|
|
1265
|
+
approval, or inside a map item (which only ADK resumes), fails the next
|
|
1266
|
+
turn with `RESUME_UNSUPPORTED`.
|
|
1238
1267
|
|
|
1239
1268
|
## 7. Extending the framework
|
|
1240
1269
|
|
package/QUICKSTART.md
CHANGED
|
@@ -180,14 +180,13 @@ Everything above runs inside a clone. When your syndicates deserve their
|
|
|
180
180
|
own repo, the same engine is a typed dependency:
|
|
181
181
|
|
|
182
182
|
```bash
|
|
183
|
-
npm install melchizedek-agents @google/adk
|
|
183
|
+
npm install melchizedek-agents # @google/adk only for MELCHIZEDEK_RUNTIME=adk
|
|
184
184
|
npx melchizedek-init # config/agents/conversational.yaml + .env; --list for others
|
|
185
185
|
npx melchizedek-doctor # which keys it needs, and whether it is ready
|
|
186
186
|
```
|
|
187
187
|
|
|
188
188
|
```typescript
|
|
189
|
-
import {
|
|
190
|
-
import { loadSyndicate, registerAvailableProviders, runSyndicateTurn } from 'melchizedek-agents';
|
|
189
|
+
import { InProcessSessionService, asAdkSessionService, loadSyndicate, registerAvailableProviders, runSyndicateTurn } from 'melchizedek-agents';
|
|
191
190
|
|
|
192
191
|
registerAvailableProviders(); // registers every model whose key is present
|
|
193
192
|
const config = loadSyndicate('mine.yaml'); // reads <your-repo>/config/agents/mine.yaml
|
|
@@ -196,7 +195,7 @@ const result = await runSyndicateTurn({
|
|
|
196
195
|
config,
|
|
197
196
|
parts: [{ text: 'Hello' }],
|
|
198
197
|
appName: 'my-app', userId: 'u1', sessionId: 'c1',
|
|
199
|
-
sessionService: new
|
|
198
|
+
sessionService: asAdkSessionService(new InProcessSessionService()),
|
|
200
199
|
});
|
|
201
200
|
console.log(result.text);
|
|
202
201
|
```
|
|
@@ -222,8 +221,12 @@ console.log(result.text);
|
|
|
222
221
|
`config/agents/`.
|
|
223
222
|
- Deeper imports are available as subpaths — `melchizedek-agents/models/registry`,
|
|
224
223
|
`melchizedek-agents/tools/webExtractTool`, `melchizedek-agents/memory`,
|
|
225
|
-
and friends — all typed.
|
|
226
|
-
|
|
224
|
+
and friends — all typed.
|
|
225
|
+
- **Native by default; ADK optional.** Since 0.20.0 every turn runs on the
|
|
226
|
+
engine's own loop. `@google/adk` is an optional peer: install it
|
|
227
|
+
(`npm install @google/adk@~2.2.0`) and set `MELCHIZEDEK_RUNTIME=adk` to
|
|
228
|
+
run on ADK, which 1.0.0 removes; your app then owns the ADK version.
|
|
229
|
+
`npx melchizedek-doctor` prints which runtime is in use.
|
|
227
230
|
- **Your coding agent can learn all of this.** The package ships a
|
|
228
231
|
six-skill suite (`skills/`, the open SKILL.md standard) covering the
|
|
229
232
|
catalog, authoring, serving, memory, models, and the Scribe:
|
package/README.md
CHANGED
|
@@ -73,11 +73,12 @@ Install into your existing project:
|
|
|
73
73
|
npm install melchizedek-agents
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
+
`@google/adk` is an optional peer since 0.20.0: install it beside the package (`npm install @google/adk@~2.2.0`) only to run on the `adk` runtime.
|
|
77
|
+
|
|
76
78
|
Define your agents in `./config/agents/mine.yaml`, then run turns programmatically:
|
|
77
79
|
|
|
78
80
|
```typescript
|
|
79
|
-
import {
|
|
80
|
-
import { loadSyndicate, registerAvailableProviders, runSyndicateTurn } from 'melchizedek-agents';
|
|
81
|
+
import { InProcessSessionService, asAdkSessionService, loadSyndicate, registerAvailableProviders, runSyndicateTurn } from 'melchizedek-agents';
|
|
81
82
|
|
|
82
83
|
// 1. Register a provider for every key that is set
|
|
83
84
|
registerAvailableProviders();
|
|
@@ -92,7 +93,7 @@ const result = await runSyndicateTurn({
|
|
|
92
93
|
appName: 'my-app',
|
|
93
94
|
userId: 'user-42',
|
|
94
95
|
sessionId: 'conversation-7', // same id, same conversation
|
|
95
|
-
sessionService: new
|
|
96
|
+
sessionService: asAdkSessionService(new InProcessSessionService()),
|
|
96
97
|
events: {
|
|
97
98
|
onProgress: (line) => console.log('…', line)
|
|
98
99
|
},
|
|
@@ -101,7 +102,7 @@ const result = await runSyndicateTurn({
|
|
|
101
102
|
console.log(result.status, result.text);
|
|
102
103
|
```
|
|
103
104
|
|
|
104
|
-
`runSyndicateTurn` is the same runtime the server, CLI, and eval harness use.
|
|
105
|
+
`runSyndicateTurn` is the same runtime the server, CLI, and eval harness use. Since 0.20.0 it runs every syndicate on the engine's own loop and scheduler (the `native` runtime) by default. `MELCHIZEDEK_RUNTIME=adk` (or `runtime: 'adk'`) runs it on Google ADK instead, with `@google/adk` installed, until 1.0.0 removes that runtime; `npx melchizedek-doctor` prints the runtime in use and whether ADK is installed ([ADR 0102](./wiki/decisions/0102-native-default-and-optional-adk-peer.md)). To read syndicates from somewhere else, pass `loadSyndicate(file, { agentsDir })` or set `MELCHIZEDEK_AGENTS_DIR`. To serve inside your own Express app, mount `(await createA2AApp({ defaultSyndicate: 'mine.yaml', serverSecret })).app`.
|
|
105
106
|
|
|
106
107
|
The example syndicates ship inside the package at `node_modules/melchizedek-agents/config/agents/examples/`; copy one out as a starting point.
|
|
107
108
|
|
|
@@ -118,11 +119,7 @@ registerGuard(myGuardInstance);
|
|
|
118
119
|
|
|
119
120
|
### The Model Adapters Alone
|
|
120
121
|
|
|
121
|
-
`melchizedek-agents/model` is the engine's model layer on its own: one message format for every provider, an adapter per provider, `resolveAdapter` over the same model-id prefixes the YAML uses, and `FallbackAdapter`. It loads no `@google/adk
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
npm install melchizedek-agents --legacy-peer-deps
|
|
125
|
-
```
|
|
122
|
+
`melchizedek-agents/model` is the engine's model layer on its own: one message format for every provider, an adapter per provider, `resolveAdapter` over the same model-id prefixes the YAML uses, and `FallbackAdapter`. It loads no `@google/adk`. Since 0.20.0 ADK is an optional peer, so `npm install melchizedek-agents` leaves it out; the other peers (redis, the cloud SDKs) are optional too.
|
|
126
123
|
|
|
127
124
|
```typescript
|
|
128
125
|
import { ClaudeAdapter, OllamaAdapter, resolveAdapter } from 'melchizedek-agents/model';
|
|
@@ -154,6 +154,9 @@ dispatch:
|
|
|
154
154
|
# Each: { map: "MySubagent", max_parallel: 4 } # one run per list item
|
|
155
155
|
# Lookup: { tool: "web_extract" } # a registry tool as a node
|
|
156
156
|
# Review: { retry: { max_attempts: 2, initial_delay: 1 }, timeout: 120 }
|
|
157
|
+
# # retry also takes max_delay, backoff_factor, jitter (0 = none) and
|
|
158
|
+
# # exceptions: [NodeTimeoutError] (retry only on these error names).
|
|
159
|
+
# # A map node takes neither retry nor timeout: set them on its agent.
|
|
157
160
|
# Confirm: { ask_user: "Publish? Reply yes, or say what to change." }
|
|
158
161
|
# max_concurrency: 4
|
|
159
162
|
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/adkPeer.ts — @google/adk as an optional peer (ADR 0102).
|
|
3
|
+
*
|
|
4
|
+
* WHY this file exists:
|
|
5
|
+
* From 0.20.0 the native runtime is the default, and @google/adk is needed
|
|
6
|
+
* only for MELCHIZEDEK_RUNTIME=adk and the features only ADK runs. Until
|
|
7
|
+
* 1.0.0 removes ADK (ADR 0045), the engine's objects still carry an ADK
|
|
8
|
+
* face: the tool registry holds FunctionTools that carry their own Tool,
|
|
9
|
+
* the model shims are BaseLlm classes that carry their contract adapter,
|
|
10
|
+
* and the durable session stores are ADK BaseSessionServices as well as
|
|
11
|
+
* the engine's SessionService. Those classes extend ADK's at load time.
|
|
12
|
+
*
|
|
13
|
+
* This module is the one place the package loads ADK. It tries once, when
|
|
14
|
+
* it is first imported, and every other module takes ADK's values from
|
|
15
|
+
* here, never from '@google/adk' directly (a type-only import is fine):
|
|
16
|
+
* - When ADK is installed, each export below IS ADK's own value, so the
|
|
17
|
+
* ADK runtime, `instanceof` and ADK's registry behave exactly as before.
|
|
18
|
+
* - When it is not, the base classes are stand-ins: they construct as
|
|
19
|
+
* ADK's do (a tool's name, a model's id, a toolset's filter) and carry
|
|
20
|
+
* ADK's own Symbol.for marks, so the engine reads them as it reads ADK's,
|
|
21
|
+
* and every method only ADK calls throws AdkNotInstalledError, which
|
|
22
|
+
* names the package. Everything else (`Runner`, `LlmAgent`, the plugins)
|
|
23
|
+
* is reached through requireAdk(feature), which throws the same error.
|
|
24
|
+
*
|
|
25
|
+
* A package that is installed but fails to load for another reason (a
|
|
26
|
+
* missing dependency of its own, a syntax error) is not "absent": that
|
|
27
|
+
* error is rethrown, so nothing hides a broken install.
|
|
28
|
+
*
|
|
29
|
+
* The load is a top-level await of a dynamic import: an ES module cannot
|
|
30
|
+
* load another synchronously, and the exported classes must exist before
|
|
31
|
+
* any subclass is defined.
|
|
32
|
+
*/
|
|
33
|
+
import type * as AdkModule from '@google/adk';
|
|
34
|
+
/** The package this module loads. */
|
|
35
|
+
export declare const ADK_PACKAGE = "@google/adk";
|
|
36
|
+
/** @google/adk's module namespace, as its types describe it. */
|
|
37
|
+
export type Adk = typeof AdkModule;
|
|
38
|
+
/** ADK's module when it is installed, else undefined. */
|
|
39
|
+
export declare const adk: Adk | undefined;
|
|
40
|
+
/** Whether @google/adk is installed and loaded. */
|
|
41
|
+
export declare function adkInstalled(): boolean;
|
|
42
|
+
/** The installed @google/adk version, read from its package.json, or undefined when it is not installed. */
|
|
43
|
+
export declare function adkVersion(): Promise<string | undefined>;
|
|
44
|
+
/** A feature only ADK runs was used without @google/adk installed. */
|
|
45
|
+
export declare class AdkNotInstalledError extends Error {
|
|
46
|
+
readonly feature: string;
|
|
47
|
+
constructor(feature: string);
|
|
48
|
+
}
|
|
49
|
+
/** ADK's module, or AdkNotInstalledError naming `feature` when it is not installed. */
|
|
50
|
+
export declare function requireAdk(feature: string): Adk;
|
|
51
|
+
export declare const BaseTool: Adk['BaseTool'];
|
|
52
|
+
export type BaseTool = AdkModule.BaseTool;
|
|
53
|
+
export declare const FunctionTool: Adk['FunctionTool'];
|
|
54
|
+
export type FunctionTool<TParameters extends AdkModule.ToolInputParameters = undefined> = AdkModule.FunctionTool<TParameters>;
|
|
55
|
+
export declare const BaseToolset: Adk['BaseToolset'];
|
|
56
|
+
export type BaseToolset = AdkModule.BaseToolset;
|
|
57
|
+
export declare const BaseLlm: Adk['BaseLlm'];
|
|
58
|
+
export type BaseLlm = AdkModule.BaseLlm;
|
|
59
|
+
export declare const Gemini: Adk['Gemini'];
|
|
60
|
+
export type Gemini = AdkModule.Gemini;
|
|
61
|
+
export declare const BaseSessionService: Adk['BaseSessionService'];
|
|
62
|
+
export type BaseSessionService = AdkModule.BaseSessionService;
|
|
63
|
+
export declare const GOOGLE_SEARCH: Adk['GOOGLE_SEARCH'];
|