melchizedek-agents 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +12 -0
- package/CHANGELOG.md +825 -0
- package/DOCUMENTATION.md +217 -59
- package/README.md +42 -1
- package/config/agents/examples/harness.yaml +3 -1
- package/config/agents/examples/model_zoo.yaml +10 -9
- package/config/agents/syndicateSchema.yaml +50 -16
- package/config/agents/templates/account_memory.yaml +2 -6
- package/config/agents/templates/case_desk.yaml +3 -9
- package/config/agents/templates/draft_review.yaml +3 -9
- package/config/agents/templates/intake_extractor.yaml +1 -3
- package/config/agents/templates/research_brief.yaml +3 -9
- package/config/agents/templates/research_desk.yaml +3 -9
- package/config/agents/templates/review_panel.yaml +4 -12
- package/config/agents/templates/support_triage.yaml +4 -12
- package/config/agents/templates/systems_operator.yaml +2 -6
- package/db/hardening.sql +7 -1
- package/db/migrations/0013_tool_credentials.sql +260 -0
- package/dist/lib/a2a/app.d.ts +70 -6
- package/dist/lib/a2a/app.js +107 -2
- package/dist/lib/a2a/executor.d.ts +20 -3
- package/dist/lib/a2a/executor.js +66 -7
- package/dist/lib/a2a/remoteAgent.d.ts +24 -9
- package/dist/lib/a2a/remoteAgent.js +31 -14
- package/dist/lib/compile.d.ts +121 -30
- package/dist/lib/compile.js +137 -124
- package/dist/lib/compileAdk.d.ts +29 -0
- package/dist/lib/compileAdk.js +132 -0
- package/dist/lib/compileNative.d.ts +85 -0
- package/dist/lib/compileNative.js +222 -0
- package/dist/lib/config.d.ts +6 -5
- package/dist/lib/config.js +6 -5
- package/dist/lib/doctor.js +1 -0
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/index.js +2 -1
- package/dist/lib/loadSyndicate.d.ts +18 -0
- package/dist/lib/memory/erase.d.ts +5 -3
- package/dist/lib/memory/erase.js +5 -2
- package/dist/lib/memory/namespace.d.ts +8 -1
- package/dist/lib/memory/namespace.js +12 -6
- package/dist/lib/memory/providers.js +2 -1
- package/dist/lib/memory/supabaseMemoryService.d.ts +37 -3
- package/dist/lib/memory/supabaseMemoryService.js +42 -2
- package/dist/lib/model.d.ts +47 -0
- package/dist/lib/model.js +37 -0
- package/dist/lib/models/adapterResolver.d.ts +113 -0
- package/dist/lib/models/adapterResolver.js +136 -0
- package/dist/lib/models/adkGeminiAdapter.d.ts +90 -0
- package/dist/lib/models/adkGeminiAdapter.js +367 -0
- package/dist/lib/models/adkShim.d.ts +111 -0
- package/dist/lib/models/adkShim.js +136 -0
- package/dist/lib/models/capabilities.d.ts +3 -0
- package/dist/lib/models/capabilities.js +20 -13
- package/dist/lib/models/chatCompletionsAdapter.d.ts +279 -0
- package/dist/lib/models/chatCompletionsAdapter.js +854 -0
- package/dist/lib/models/circuitBreaker.d.ts +42 -0
- package/dist/lib/models/circuitBreaker.js +70 -0
- package/dist/lib/models/claudeAdapter.d.ts +103 -0
- package/dist/lib/models/claudeAdapter.js +669 -0
- package/dist/lib/models/claudeLlm.d.ts +39 -62
- package/dist/lib/models/claudeLlm.js +44 -349
- package/dist/lib/models/claudeModels.d.ts +127 -0
- package/dist/lib/models/claudeModels.js +237 -0
- package/dist/lib/models/contract.d.ts +395 -0
- package/dist/lib/models/contract.js +39 -0
- package/dist/lib/models/endpoints.js +2 -1
- package/dist/lib/models/errorResponse.d.ts +50 -0
- package/dist/lib/models/errorResponse.js +48 -0
- package/dist/lib/models/fallback.d.ts +17 -10
- package/dist/lib/models/fallback.js +53 -42
- package/dist/lib/models/fallbackAdapter.d.ts +55 -0
- package/dist/lib/models/fallbackAdapter.js +62 -0
- package/dist/lib/models/gateway.js +2 -1
- package/dist/lib/models/gatewayAdapter.d.ts +51 -0
- package/dist/lib/models/gatewayAdapter.js +81 -0
- package/dist/lib/models/gatewayLlm.d.ts +12 -33
- package/dist/lib/models/gatewayLlm.js +14 -75
- package/dist/lib/models/geminiAdapter.d.ts +123 -0
- package/dist/lib/models/geminiAdapter.js +831 -0
- package/dist/lib/models/geminiState.d.ts +25 -0
- package/dist/lib/models/geminiState.js +25 -0
- package/dist/lib/models/genaiMapping.d.ts +263 -0
- package/dist/lib/models/genaiMapping.js +862 -0
- package/dist/lib/models/gptAdapter.d.ts +240 -0
- package/dist/lib/models/gptAdapter.js +804 -0
- package/dist/lib/models/gptLlm.d.ts +63 -123
- package/dist/lib/models/gptLlm.js +88 -602
- package/dist/lib/models/grokAdapter.d.ts +86 -0
- package/dist/lib/models/grokAdapter.js +142 -0
- package/dist/lib/models/grokLlm.d.ts +22 -45
- package/dist/lib/models/grokLlm.js +22 -67
- package/dist/lib/models/kimiAdapter.d.ts +157 -0
- package/dist/lib/models/kimiAdapter.js +203 -0
- package/dist/lib/models/kimiLlm.d.ts +15 -107
- package/dist/lib/models/kimiLlm.js +17 -153
- package/dist/lib/models/ollamaAdapter.d.ts +125 -0
- package/dist/lib/models/ollamaAdapter.js +155 -0
- package/dist/lib/models/ollamaLlm.d.ts +11 -107
- package/dist/lib/models/ollamaLlm.js +13 -151
- package/dist/lib/models/openAiCompatibleLlm.d.ts +73 -216
- package/dist/lib/models/openAiCompatibleLlm.js +109 -671
- package/dist/lib/models/providerState.d.ts +63 -0
- package/dist/lib/models/providerState.js +61 -0
- package/dist/lib/models/reasoning.d.ts +26 -0
- package/dist/lib/models/reasoning.js +59 -0
- package/dist/lib/models/registry.d.ts +58 -35
- package/dist/lib/models/registry.js +89 -118
- package/dist/lib/models/retry.d.ts +2 -1
- package/dist/lib/models/retry.js +3 -2
- package/dist/lib/models/schemaNormalize.d.ts +98 -0
- package/dist/lib/models/schemaNormalize.js +321 -1
- package/dist/lib/models/tracedGemini.d.ts +41 -0
- package/dist/lib/models/tracedGemini.js +98 -0
- package/dist/lib/models/urls.d.ts +11 -0
- package/dist/lib/models/urls.js +16 -0
- package/dist/lib/net/redirects.d.ts +21 -2
- package/dist/lib/net/redirects.js +11 -34
- package/dist/lib/observability/audit.d.ts +5 -1
- package/dist/lib/observability/lineage.d.ts +14 -0
- package/dist/lib/observability/lineage.js +33 -0
- package/dist/lib/observability/supabaseSpanExporter.d.ts +10 -4
- package/dist/lib/observability/supabaseSpanExporter.js +17 -9
- package/dist/lib/observability/tracer.d.ts +26 -8
- package/dist/lib/observability/tracer.js +43 -18
- package/dist/lib/runtime/adkMemoryBridge.d.ts +46 -0
- package/dist/lib/runtime/adkMemoryBridge.js +68 -0
- package/dist/lib/runtime/adkSessionBridge.d.ts +78 -0
- package/dist/lib/runtime/adkSessionBridge.js +176 -0
- package/dist/lib/runtime/credentials.d.ts +59 -0
- package/dist/lib/runtime/credentials.js +62 -0
- package/dist/lib/runtime/events.d.ts +229 -0
- package/dist/lib/runtime/events.js +274 -0
- package/dist/lib/runtime/logging.d.ts +32 -0
- package/dist/lib/runtime/logging.js +55 -0
- package/dist/lib/runtime/memoryService.d.ts +72 -0
- package/dist/lib/runtime/memoryService.js +25 -0
- package/dist/lib/runtime/native/agentLoop.d.ts +203 -0
- package/dist/lib/runtime/native/agentLoop.js +687 -0
- package/dist/lib/runtime/native/compaction.d.ts +103 -0
- package/dist/lib/runtime/native/compaction.js +191 -0
- package/dist/lib/runtime/native/delegate.d.ts +98 -0
- package/dist/lib/runtime/native/delegate.js +173 -0
- package/dist/lib/runtime/native/history.d.ts +83 -0
- package/dist/lib/runtime/native/history.js +312 -0
- package/dist/lib/runtime/native/interrupts.d.ts +126 -0
- package/dist/lib/runtime/native/interrupts.js +291 -0
- package/dist/lib/runtime/native/request.d.ts +215 -0
- package/dist/lib/runtime/native/request.js +585 -0
- package/dist/lib/runtime/native/selfCorrection.d.ts +106 -0
- package/dist/lib/runtime/native/selfCorrection.js +253 -0
- package/dist/lib/runtime/native/step.d.ts +148 -0
- package/dist/lib/runtime/native/step.js +239 -0
- package/dist/lib/runtime/native/taskMode.d.ts +64 -0
- package/dist/lib/runtime/native/taskMode.js +126 -0
- package/dist/lib/runtime/native/telemetry.d.ts +75 -0
- package/dist/lib/runtime/native/telemetry.js +299 -0
- package/dist/lib/runtime/native/tempState.d.ts +31 -0
- package/dist/lib/runtime/native/tempState.js +56 -0
- package/dist/lib/runtime/nativeTurn.d.ts +86 -0
- package/dist/lib/runtime/nativeTurn.js +107 -0
- package/dist/lib/runtime/questions.d.ts +29 -7
- package/dist/lib/runtime/questions.js +47 -32
- package/dist/lib/runtime/runtimeFlag.d.ts +30 -0
- package/dist/lib/runtime/runtimeFlag.js +50 -0
- package/dist/lib/runtime/sessions.d.ts +166 -0
- package/dist/lib/runtime/sessions.js +201 -0
- package/dist/lib/runtime/syndicateTurn.d.ts +41 -5
- package/dist/lib/runtime/syndicateTurn.js +202 -32
- package/dist/lib/session/supabaseSessionService.d.ts +64 -17
- package/dist/lib/session/supabaseSessionService.js +148 -105
- package/dist/lib/session/transcript.d.ts +68 -22
- package/dist/lib/session/transcript.js +102 -28
- package/dist/lib/skills.js +33 -7
- package/dist/lib/storage/postgres/credentialStore.d.ts +20 -0
- package/dist/lib/storage/postgres/credentialStore.js +82 -0
- package/dist/lib/storage/postgres/index.d.ts +12 -0
- package/dist/lib/storage/postgres/index.js +6 -1
- package/dist/lib/storage/postgres/sessionService.d.ts +43 -15
- package/dist/lib/storage/postgres/sessionService.js +128 -66
- package/dist/lib/syndicateSchema.d.ts +47 -0
- package/dist/lib/syndicateSchema.js +72 -3
- package/dist/lib/toolRegistry.d.ts +15 -2
- package/dist/lib/toolRegistry.js +33 -17
- package/dist/lib/tools/adkTool.d.ts +81 -0
- package/dist/lib/tools/adkTool.js +268 -0
- package/dist/lib/tools/auth.d.ts +118 -0
- package/dist/lib/tools/auth.js +89 -0
- package/dist/lib/tools/collectionsSearchTool.d.ts +7 -6
- package/dist/lib/tools/collectionsSearchTool.js +11 -26
- package/dist/lib/tools/credentialCipher.d.ts +58 -0
- package/dist/lib/tools/credentialCipher.js +116 -0
- package/dist/lib/tools/credentialStore.d.ts +77 -0
- package/dist/lib/tools/credentialStore.js +246 -0
- package/dist/lib/tools/examples.d.ts +43 -0
- package/dist/lib/tools/examples.js +62 -0
- package/dist/lib/tools/generateImageTool.d.ts +15 -6
- package/dist/lib/tools/generateImageTool.js +19 -29
- package/dist/lib/tools/inspectImageTool.d.ts +9 -6
- package/dist/lib/tools/inspectImageTool.js +13 -17
- package/dist/lib/tools/mcpToolFactory.d.ts +42 -1
- package/dist/lib/tools/mcpToolFactory.js +46 -47
- package/dist/lib/tools/memoryTools.d.ts +61 -0
- package/dist/lib/tools/memoryTools.js +119 -0
- package/dist/lib/tools/nativeTools.d.ts +38 -0
- package/dist/lib/tools/nativeTools.js +43 -0
- package/dist/lib/tools/oauthConsent.d.ts +181 -0
- package/dist/lib/tools/oauthConsent.js +330 -0
- package/dist/lib/tools/openapi/call.d.ts +108 -0
- package/dist/lib/tools/openapi/call.js +295 -0
- package/dist/lib/tools/openapi/parse.d.ts +147 -0
- package/dist/lib/tools/openapi/parse.js +570 -0
- package/dist/lib/tools/openapiTools.d.ts +25 -17
- package/dist/lib/tools/openapiTools.js +124 -121
- package/dist/lib/tools/scienceTools.d.ts +14 -14
- package/dist/lib/tools/skillToolset.d.ts +58 -87
- package/dist/lib/tools/skillToolset.js +61 -142
- package/dist/lib/tools/skills/env.d.ts +58 -0
- package/dist/lib/tools/skills/env.js +165 -0
- package/dist/lib/tools/skills/executor.d.ts +114 -0
- package/dist/lib/tools/skills/executor.js +331 -0
- package/dist/lib/tools/skills/frontmatter.d.ts +79 -0
- package/dist/lib/tools/skills/frontmatter.js +215 -0
- package/dist/lib/tools/skills/loader.d.ts +91 -0
- package/dist/lib/tools/skills/loader.js +257 -0
- package/dist/lib/tools/skills/tools.d.ts +187 -0
- package/dist/lib/tools/skills/tools.js +386 -0
- package/dist/lib/tools/taskTools.d.ts +15 -15
- package/dist/lib/tools/tool.d.ts +354 -0
- package/dist/lib/tools/tool.js +304 -0
- package/dist/lib/tools/toolContract.d.ts +89 -33
- package/dist/lib/tools/toolContract.js +104 -82
- package/dist/lib/tools/urlContextTool.d.ts +3 -0
- package/dist/lib/tools/urlContextTool.js +5 -1
- package/dist/lib/tools/webExtractTool.d.ts +2 -2
- package/dist/lib/tools/webExtractTool.js +2 -1
- package/dist/lib/tools/webSearchTool.d.ts +6 -9
- package/dist/lib/tools/webSearchTool.js +14 -59
- package/dist/lib/tools/wikiTools.d.ts +19 -19
- package/dist/lib/tools/wikiTools.js +13 -9
- package/dist/lib/tools/xApiSearchTool.d.ts +2 -2
- package/dist/lib/tools/xApiSearchTool.js +2 -1
- package/dist/lib/tools/xSearchTool.d.ts +7 -9
- package/dist/lib/tools/xSearchTool.js +11 -62
- package/dist/lib/tools/xaiSearchParams.d.ts +41 -0
- package/dist/lib/tools/xaiSearchParams.js +126 -0
- package/dist/lib/wiki/agentRun.d.ts +12 -0
- package/dist/lib/wiki/agentRun.js +72 -34
- package/dist/lib/wiki/entities.d.ts +12 -0
- package/dist/lib/wiki/entities.js +45 -3
- package/dist/lib/workflow/agentNode.d.ts +136 -0
- package/dist/lib/workflow/agentNode.js +274 -0
- package/dist/lib/workflow/graph.d.ts +177 -0
- package/dist/lib/workflow/graph.js +458 -0
- package/dist/lib/workflow/nodeEvents.d.ts +50 -0
- package/dist/lib/workflow/nodeEvents.js +101 -0
- package/dist/lib/workflow/pause.d.ts +122 -0
- package/dist/lib/workflow/pause.js +180 -0
- package/dist/lib/workflow/resume.d.ts +165 -0
- package/dist/lib/workflow/resume.js +440 -0
- package/dist/lib/workflow/route.d.ts +58 -0
- package/dist/lib/workflow/route.js +69 -0
- package/dist/lib/workflow/scheduler.d.ts +415 -0
- package/dist/lib/workflow/scheduler.js +743 -0
- package/dist/lib/workflow/toolNode.d.ts +127 -0
- package/dist/lib/workflow/toolNode.js +236 -0
- package/dist/lib/workflow/turn.d.ts +118 -0
- package/dist/lib/workflow/turn.js +216 -0
- package/dist/lib/workflowConfig.d.ts +3 -2
- package/dist/lib/workflowConfig.js +3 -12
- package/dist/scripts/a2a_server.js +4 -3
- package/dist/scripts/assistant_worker.d.ts +2 -1
- package/dist/scripts/assistant_worker.js +9 -4
- package/dist/scripts/syndicate_chat.js +19 -10
- package/package.json +4 -1
- package/skills/briefs/melchizedek-author.md +3 -2
- package/skills/briefs/melchizedek-models.md +13 -9
- package/skills/briefs/melchizedek.md +3 -3
- package/skills/melchizedek/SKILL.md +2 -1
- package/skills/melchizedek-author/SKILL.md +2 -1
- package/skills/melchizedek-author/assets/minimal.yaml +2 -0
- package/skills/melchizedek-models/SKILL.md +23 -6
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,831 @@ Consumers of the package read this file; it records changes to the
|
|
|
4
4
|
**published API surface** (the exports map in `package.json`, the bins,
|
|
5
5
|
the starter pack and the templates), not the repo's full history.
|
|
6
6
|
|
|
7
|
+
## Unreleased
|
|
8
|
+
|
|
9
|
+
- **Workflow syndicates run on the native runtime (WS4-6, ADR 0095).**
|
|
10
|
+
A `workflow:` syndicate no longer throws `UnsupportedOnRuntimeError` on
|
|
11
|
+
`runtime: 'native'` (or `MELCHIZEDEK_RUNTIME=native`): the engine's own
|
|
12
|
+
scheduler walks the graph, and `runSyndicateTurn` returns the same
|
|
13
|
+
result, stored events, progress lines, `answer.nodeErrors`, text deltas
|
|
14
|
+
and ledger rows as on ADK. An `ask_user` node pauses the turn
|
|
15
|
+
`input-required` with `result.input`, and the next message resumes it,
|
|
16
|
+
also in a session ADK paused. Two new outcomes on native: a session
|
|
17
|
+
paused inside an agent node or a map item (which only ADK resumes) fails
|
|
18
|
+
the turn with error code `RESUME_UNSUPPORTED` instead of starting the
|
|
19
|
+
graph again, and an `ask_user` tool on a workflow node's agent in a
|
|
20
|
+
config that skipped validation throws `UnsupportedOnRuntimeError`
|
|
21
|
+
before any model call (the schema refuses it on both runtimes). A
|
|
22
|
+
native workflow turn traces `workflow.invoke`, `node.execute` and
|
|
23
|
+
`tool.execute` spans, so each model call's ledger row names its node's
|
|
24
|
+
agent. ADK turns are unchanged.
|
|
25
|
+
- **Ollama structured output enforces the schema (ADR 0096).** An
|
|
26
|
+
`ollama/` agent with an `outputSchema` now sends `response_format:
|
|
27
|
+
json_schema` with the schema in its strict form, as Kimi and the gateway
|
|
28
|
+
do, where it sent `json_object` and the schema was not enforced. JSON
|
|
29
|
+
mode without a schema still sends `json_object`. Ollama 0.5.0 or later is
|
|
30
|
+
required for the schema to hold: an older server ignores it and answers
|
|
31
|
+
in free text. The capability matrix and `npm run doctor` now report
|
|
32
|
+
Ollama's structured output as supported.
|
|
33
|
+
- **A Gemini `MALFORMED_FUNCTION_CALL` from a contract adapter is
|
|
34
|
+
retried (WS2-15, ADR 0088).** `modelResponseToLlmResponse`
|
|
35
|
+
(`melchizedek-agents/models/genaiMapping`) now sets `finishReason` to an
|
|
36
|
+
error's code when the code is one of Gemini's finish reasons, as ADK's
|
|
37
|
+
Gemini reports both. Self-correction (`retries.model_errors`) then
|
|
38
|
+
retries a malformed function call on both runtimes, where it used to fail
|
|
39
|
+
the turn on native and behind a shim. A stored Gemini error event can
|
|
40
|
+
carry its own finish reason (`RECITATION`, say) where it carried
|
|
41
|
+
`SAFETY` or `OTHER`.
|
|
42
|
+
- **On native, a custom ADK model class from `resolveModel` is refused
|
|
43
|
+
(WS2-15, ADR 0088).** A `compile.resolveModel` that returns an ADK
|
|
44
|
+
`BaseLlm` which is neither a shim nor ADK's Gemini now makes a
|
|
45
|
+
`runtime: 'native'` turn throw `UnsupportedOnRuntimeError` before any
|
|
46
|
+
model call. This covers an agent's model, a subagent's,
|
|
47
|
+
`fallback_model` and `summary_model`. Native used to run the registry's
|
|
48
|
+
model for that id instead. To run such a model on native, return its
|
|
49
|
+
`ModelAdapter`, or `adkShim(adapter)` from
|
|
50
|
+
`melchizedek-agents/models/adkShim`. ADK turns are unchanged.
|
|
51
|
+
- **A user-authored `ask_user` call is no question (WS2-15, ADR 0088).**
|
|
52
|
+
`pendingQuestion` ignores an `ask_user` call in an event the user
|
|
53
|
+
authored. A message that forges one no longer turns the next message
|
|
54
|
+
into its answer, on either runtime.
|
|
55
|
+
|
|
56
|
+
- **The native runtime sends a request, and reads a thrown failure, as
|
|
57
|
+
ADK does (WS2-12, ADR 0084).** On `runtime: 'native'` (or
|
|
58
|
+
`MELCHIZEDEK_RUNTIME=native`) a request goes out under the resolved
|
|
59
|
+
model's own id, as ADK's `LlmAgent` sends it, so a `resolveModel` that
|
|
60
|
+
answers a YAML id with a model under another id (a gateway stand-in, an
|
|
61
|
+
alias) gets that model's thinking and reasoning replay. A model that
|
|
62
|
+
throws no longer throws out of `runSyndicateTurn`: the turn fails on
|
|
63
|
+
ADK's `UNKNOWN_ERROR` event (or a JSON error body's code), and a thrown
|
|
64
|
+
provider-side failure is answered by `fallback_model`, as on ADK. The
|
|
65
|
+
turn-level test suites run on both runtimes. `npm run parity` now runs
|
|
66
|
+
its turns on the runtime `MELCHIZEDEK_RUNTIME` names. The `exports` map
|
|
67
|
+
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
|
+
- **The skills harness no longer builds on ADK (ADR 0083).** An agent's
|
|
83
|
+
`skills:` block loads, reads and runs skills through the engine's own
|
|
84
|
+
modules (`lib/tools/skills/`), the same on `runtime: 'adk'` and
|
|
85
|
+
`'native'`. A model sees the same tools, parameters, results and error
|
|
86
|
+
texts as before. Breaking for code that imports
|
|
87
|
+
`melchizedek-agents/tools/skillToolset` directly:
|
|
88
|
+
`HarnessSkillToolset` is now an engine Toolset rather than ADK's
|
|
89
|
+
`SkillToolset`, so wrap it with `toAdkToolset`
|
|
90
|
+
(`melchizedek-agents/tools/adkTool`) before handing it to an ADK
|
|
91
|
+
`LlmAgent`. `LeanLoadSkillTool` and `GatedRunSkillScriptTool` are now
|
|
92
|
+
engine Tools (`execute(args, ctx)`), not ADK `BaseTool`s. Frontmatter
|
|
93
|
+
YAML is read by the `yaml` package, so a timestamp stays a string and
|
|
94
|
+
`<<` merge keys are not merged. A SKILL.md over 1 MiB and a resource
|
|
95
|
+
file over 8 MiB are not loaded. `lib/tools/tool.ts` adds `Toolset`,
|
|
96
|
+
`ToolsetContext`, `isOwnToolset`, `toolsetOf` and an optional
|
|
97
|
+
`Tool.contents` hook. The `exports` map is unchanged.
|
|
98
|
+
- **OAuth consent for tool credentials (ADR 0085).** On the native
|
|
99
|
+
runtime, `runSyndicateTurn` takes `toolCredentials: { store, consent }`
|
|
100
|
+
(both optional additions). `store` is the sealed credential store of ADR
|
|
101
|
+
0072, and `consent` is `oauthConsent({ providers, redirectUri,
|
|
102
|
+
credentials })` from `melchizedek-agents/tools/oauthConsent`.
|
|
103
|
+
- When a call's provider is not granted, `ctx.accessToken(provider)`
|
|
104
|
+
asks for consent by itself, or a tool calls the new
|
|
105
|
+
`ctx.requestCredential(provider)`. The turn ends `input-required` with
|
|
106
|
+
`result.consent` (`id`, `agent`, `provider`, `authUri`, `state`,
|
|
107
|
+
`scopes`), stored as ADK's own `adk_request_credential` call with no
|
|
108
|
+
secret in it.
|
|
109
|
+
- The person's next message, after the grant is stored, runs the paused
|
|
110
|
+
call again. Until then, a message repeats the request and runs nothing.
|
|
111
|
+
- `createA2AApp` takes the same `toolCredentials` (plus `callbackLimit`
|
|
112
|
+
and `requireCallerIdentity`, default true: the callback refuses a
|
|
113
|
+
browser that does not carry the flow's user's identity). It publishes a `consent_request` data part
|
|
114
|
+
beside `approval_request` and `input_request`, and mounts the consent
|
|
115
|
+
callback at the path of the redirect URI. The callback completes the
|
|
116
|
+
authorization-code flow with PKCE S256 and stores the grant.
|
|
117
|
+
- New exports, all through existing entries: `./a2a` gains
|
|
118
|
+
`consentCallback`. `./runtime` gains `pendingConsent`,
|
|
119
|
+
`credentialResponsePart`, `describeConsent`, `CREDENTIAL_REQUEST` and
|
|
120
|
+
the types `PendingConsent` and `ToolCredentials`. `./tools/*` gains the
|
|
121
|
+
new module `oauthConsent`.
|
|
122
|
+
- Also additive: `RouteDecision.decidedBy` gains `'consent'`, the audit
|
|
123
|
+
trail gains the `consent.callback` event, and `ToolContext` gains
|
|
124
|
+
`requestCredential`.
|
|
125
|
+
- On the ADK runtime, an open consent request throws
|
|
126
|
+
`UnsupportedOnRuntimeError`.
|
|
127
|
+
- No change to the `exports` map.
|
|
128
|
+
- **A question is answered on the native runtime (ADR 0079).** On
|
|
129
|
+
`runtime: 'native'` (or `MELCHIZEDEK_RUNTIME=native`), a plain-text
|
|
130
|
+
message that answers an open `ask_user` call no longer throws
|
|
131
|
+
`UnsupportedOnRuntimeError`: it becomes the call's response and the agent
|
|
132
|
+
that asked resumes, in plan-dispatch the route, as on ADK. Both runtimes
|
|
133
|
+
store the same events, so a question opened on either is answered on the
|
|
134
|
+
other; `result.input` and the A2A `input_request` part are unchanged. No
|
|
135
|
+
change to the `exports` map.
|
|
136
|
+
- **`mode: task` runs on the native runtime (ADR 0081).** It no longer
|
|
137
|
+
throws `UnsupportedOnRuntimeError`: the agent's requests declare
|
|
138
|
+
`finish_task` as ADK's do, and its answers are stored as ADK stores them.
|
|
139
|
+
A `workflow:` syndicate, where task-mode nodes live, is still refused on
|
|
140
|
+
native. `code_execution: gemini` runs on native with the same stored
|
|
141
|
+
events as on ADK. No change to the exports map.
|
|
142
|
+
- **An approval resumes on the native runtime (ADR 0077).** On
|
|
143
|
+
`runtime: 'native'`, a message carrying `approvalResponsePart(id, …)` runs
|
|
144
|
+
or refuses the pinned call before the agent's next step, as on ADK, and
|
|
145
|
+
stores the same events: an approval opened on either runtime resumes on
|
|
146
|
+
the other. An answer whose pinned call does not bind (changed arguments,
|
|
147
|
+
a request the user authored) throws ADK's `IntentMismatchError` text on
|
|
148
|
+
both runtimes. No change to the `exports` map.
|
|
149
|
+
- **`createA2AApp` takes the engine's own stores (ADR 0080).**
|
|
150
|
+
`A2AAppOptions.storage.sessionService` accepts the engine's
|
|
151
|
+
`SessionService` as well as ADK's `BaseSessionService`, and
|
|
152
|
+
`storage.memoryService` the engine's `MemoryService` as well as ADK's
|
|
153
|
+
`BaseMemoryService`; a store or service you pass today works unchanged.
|
|
154
|
+
Without durable storage, sessions live in the engine's
|
|
155
|
+
`InProcessSessionService` instead of ADK's `InMemorySessionService`, with
|
|
156
|
+
the durable stores' meaning (no `app:` or `user:` state shared across
|
|
157
|
+
sessions). `resolveModel` returns what `CompileOptions.resolveModel`
|
|
158
|
+
returns, the same type as before. The `melchizedek-serve` bin no longer
|
|
159
|
+
imports `@google/adk`; ADK's logger follows the level the engine sets.
|
|
160
|
+
No change to the `exports` map, `runSyndicateTurn`, or the A2A surface.
|
|
161
|
+
- **`context:` compaction runs on the native runtime (ADR 0078).** A
|
|
162
|
+
syndicate whose orchestrator sets `context:` no longer throws
|
|
163
|
+
`UnsupportedOnRuntimeError` under `runtime: 'native'`
|
|
164
|
+
(or `MELCHIZEDEK_RUNTIME=native`): the native loop compacts as the ADK
|
|
165
|
+
runtime does, stores the same compacted event, and charges and traces the
|
|
166
|
+
summary call the same way, so a compacted session continues on either
|
|
167
|
+
runtime. No change to the exports map; `ContextConfig` and
|
|
168
|
+
`DEFAULT_KEEP_RECENT_EVENTS` stay exported from
|
|
169
|
+
`melchizedek-agents/compile` under the same names.
|
|
170
|
+
- **A turn can run on the native runtime (ADR 0073).** `runSyndicateTurn`
|
|
171
|
+
takes an optional `runtime` (`'adk'` or `'native'`). Without it,
|
|
172
|
+
`MELCHIZEDEK_RUNTIME` decides (`adk` or `native`), and without that, `adk`,
|
|
173
|
+
so nothing changes unless you ask. On `native` a single-agent, DELEGATE
|
|
174
|
+
or plan-dispatch syndicate runs on the engine's own loop, with
|
|
175
|
+
self-correction from `retries:` and the same root span, and returns the
|
|
176
|
+
same result shape; what native does not run yet (compaction, workflows,
|
|
177
|
+
task mode, `transformAgent`, answering a question) throws `UnsupportedOnRuntimeError` before any model call. Additions under the existing `exports` map:
|
|
178
|
+
- `melchizedek-agents/runtime` exports `RuntimeName`, `RUNTIMES`,
|
|
179
|
+
`DEFAULT_RUNTIME`, `chooseRuntime`, `runtimeSetting` and
|
|
180
|
+
`UnsupportedOnRuntimeError`.
|
|
181
|
+
- `melchizedek-agents/compile` exports `AgentSpec`, `SpecTool`,
|
|
182
|
+
`compileSpec` and `compileSubagentSpec`, the runtime-neutral half of the
|
|
183
|
+
compiler. `compileGraph` and `compileSubagent` build the same `LlmAgent`
|
|
184
|
+
as before.
|
|
185
|
+
- `melchizedek-agents/wiki/agentRun`: `runWikiAgent` follows the same
|
|
186
|
+
flag, and takes `runtime` and (native only) `adapterFor`.
|
|
187
|
+
- `.env.example` lists `MELCHIZEDEK_RUNTIME` and `GEMINI_ADAPTER`.
|
|
188
|
+
- **Third-party tokens for tools, sealed per end user (ADR 0072).** Apply
|
|
189
|
+
migration `0013_tool_credentials.sql` (`npx melchizedek-db apply`, or
|
|
190
|
+
`print` into the SQL editor) before using it. New, all under the existing
|
|
191
|
+
`exports` map:
|
|
192
|
+
- `melchizedek-agents/tools/auth`: the `CredentialStore` interface (`put`,
|
|
193
|
+
`get` with refresh, `revoke`, `eraseUser`), `OAuthProvider` (`refresh`,
|
|
194
|
+
`revoke` hooks), `ToolCredentialError`, `toolAccessToken` and
|
|
195
|
+
`pinnedCredentialStore`.
|
|
196
|
+
- `melchizedek-agents/tools/credentialStore`: `credentialStore({ rows,
|
|
197
|
+
cipher, providers, audit })` and `memoryCredentialRows()`.
|
|
198
|
+
- `melchizedek-agents/tools/credentialCipher`: the `CredentialCipher` plug
|
|
199
|
+
point, `aesGcmCipher` (AES-256-GCM) and `credentialCipherFromEnv`, which
|
|
200
|
+
reads the new `MELCHIZEDEK_CREDENTIAL_KEY` (32 bytes, base64 or hex).
|
|
201
|
+
- `storage/postgres`: `postgresStorage({ credentials: { cipher, providers }
|
|
202
|
+
})` adds `storage.credentials`; `postgresCredentialRows` and
|
|
203
|
+
`postgresCredentialStore` are exported.
|
|
204
|
+
- `tools/tool`: `ToolContext.accessToken(provider)`, a valid token for the
|
|
205
|
+
run's own app and user, present when `createToolContext` is given
|
|
206
|
+
`credentials`. No built-in tool uses it yet.
|
|
207
|
+
- `EraseCounts` gains `credentials`: `melchizedek_erase_scope` and
|
|
208
|
+
`DELETE /memory` remove the user's tokens too. A custom `storage.erase`
|
|
209
|
+
that builds its own counts adds the field.
|
|
210
|
+
- The audit trail gains `credential.put`, `credential.refresh`,
|
|
211
|
+
`credential.revoke` and `credential.erase` (`AuditEventName`), with the
|
|
212
|
+
provider and app and never a token.
|
|
213
|
+
|
|
214
|
+
- **The ledger reads the native loop's spans (ADR 0076).** The native loop
|
|
215
|
+
(not yet selectable, WS2-10) opens `agent.invoke <name>`, `model.call` and
|
|
216
|
+
`tool.execute <name>` spans in scope `melchizedek.runtime`, and a native
|
|
217
|
+
run writes the same `adk_turns`, `adk_telemetry` and `adk_payloads` rows as
|
|
218
|
+
an ADK run. `melchizedek-agents/observability/lineage` exports
|
|
219
|
+
`ADK_SPAN_SCOPE`, `RUNTIME_SPAN_SCOPE`, `agentOfSpanName`,
|
|
220
|
+
`isToolSpanName` and `isModelCallSpan`. In `observability/tracer`,
|
|
221
|
+
`agentForSpan` also walks up to an `agent.invoke` span, tool time also
|
|
222
|
+
sums `tool.execute` spans, and the console exporter keeps the
|
|
223
|
+
`melchizedek.runtime` scope quiet as it keeps ADK's
|
|
224
|
+
(`OTEL_CONSOLE_ALL_SPANS=true` prints both). In
|
|
225
|
+
`observability/supabaseSpanExporter`, `isPayloadSpan` also takes a
|
|
226
|
+
`model.call` span that carries `llm.payload.*`, and `toPayloadRow` reads
|
|
227
|
+
`adk.invocation_id` before the turn's.
|
|
228
|
+
- **New entry `melchizedek-agents/model`: the model layer without ADK
|
|
229
|
+
(ADR 0068).** A new path in the `exports` map, so the version is 0.19.0.
|
|
230
|
+
It exports the model contract's types, `ClaudeAdapter`, `GptAdapter`,
|
|
231
|
+
`GrokAdapter`, `ChatCompletionsAdapter`, `KimiAdapter`, `OllamaAdapter`,
|
|
232
|
+
`GatewayAdapter`, `GeminiAdapter`, `resolveAdapter`,
|
|
233
|
+
`resolveAdapterWithFallback`, `geminiAdapterSetting`, `FallbackAdapter`,
|
|
234
|
+
`isProviderError`, the circuit breaker's helpers (`breakerSettings`,
|
|
235
|
+
`circuitOpen`, `recordFailure`, `recordSuccess`, `resetCircuits`) and the
|
|
236
|
+
prefix table (`PROVIDERS`, `providerForModel`, `providerKeyPresent`), and
|
|
237
|
+
loads no `@google/adk`: install with `--legacy-peer-deps` to leave ADK out.
|
|
238
|
+
- Its `resolveAdapter` gives a Gemini id `GeminiAdapter`. Asking it for
|
|
239
|
+
`adk` (`gemini: 'adk'` or `GEMINI_ADAPTER=adk`) throws and names
|
|
240
|
+
`melchizedek-agents/models/registry`, whose `resolveAdapter` is
|
|
241
|
+
unchanged (`AdkGeminiAdapter` by default until gate G3).
|
|
242
|
+
- New module `melchizedek-agents/models/adapterResolver` (through
|
|
243
|
+
`./models/*`): `adapterResolver`, `routeFor`, `scopedKey`,
|
|
244
|
+
`normalizeProvider`, `geminiAdapterSetting` and the resolver types.
|
|
245
|
+
`models/registry` still exports `geminiAdapterChoice`,
|
|
246
|
+
`GeminiAdapterChoice` and `ResolveAdapterOptions`.
|
|
247
|
+
- New module `melchizedek-agents/tools/xaiSearchParams` holds
|
|
248
|
+
`xaiWebSearchParamsFromEnv`, `xSearchParamsFromEnv`,
|
|
249
|
+
`collectionIdsFromEnv` and `collectionsMaxResultsFromEnv`, which
|
|
250
|
+
`tools/webSearchTool`, `tools/xSearchTool` and
|
|
251
|
+
`tools/collectionsSearchTool` still re-export.
|
|
252
|
+
- **Kimi forces a tool where Moonshot allows it** (checked live on
|
|
253
|
+
2026-10-08). `kimi-k3` sends `toolChoice: 'required'` as asked and a
|
|
254
|
+
named tool as `tool_choice: "required"` (Moonshot refuses a named tool
|
|
255
|
+
while K3 thinks, and K3 always thinks); `kimi-k2.6` sends both forced
|
|
256
|
+
modes as asked when `reasoning` is `none`, and weakens them to auto
|
|
257
|
+
otherwise. Other Kimi ids keep weakening both to auto. A weakened choice
|
|
258
|
+
is still marked `llm.tool_choice.weakened` on the span. In the
|
|
259
|
+
chat-completions base, a subclass's `toolChoiceModes` now also receives
|
|
260
|
+
the request's reasoning.
|
|
261
|
+
- **Fix: `kimi-k2.7-code` with `reasoning: none`.** It sends no thinking
|
|
262
|
+
field (the model thinks at its default) instead of
|
|
263
|
+
`thinking: { type: 'disabled' }`, which Moonshot refuses for K2.7 Code
|
|
264
|
+
and its highspeed variant. `kimi-k2.6` still sends `disabled`.
|
|
265
|
+
- **The genai mapping exports two more readers (ADR 0066).**
|
|
266
|
+
`melchizedek-agents/models/genaiMapping` adds `toolChoiceOf` (an agent's
|
|
267
|
+
function-calling mode as a `ToolChoice`, and `VALIDATED` as strict tools)
|
|
268
|
+
and `samplingOf` (the sampling fields the contract carries). These are
|
|
269
|
+
additions under the existing `exports` map. The native loop
|
|
270
|
+
(`lib/runtime/native/`: one model step, and the agent loop around it,
|
|
271
|
+
ADR 0071) is not in the `exports` map and runs no turn yet.
|
|
272
|
+
- **OpenAPI tools make their own calls (ADR 0067).** Each operation is
|
|
273
|
+
the engine's own Tool, and the ADK runtime runs it through
|
|
274
|
+
`toFunctionTool`; ADK's `RestApiTool` and `OpenAPIToolset` are no longer
|
|
275
|
+
used. An API receives the same request as before. What a consumer sees:
|
|
276
|
+
- `tools/openapiTools`: `buildOpenApiTools` returns `FunctionTool`s
|
|
277
|
+
(it returned `BaseTool`s), and gains `buildOpenApiOwnTools` (own Tools,
|
|
278
|
+
for either runtime) and `openApiOperationId`. `boundResult` is
|
|
279
|
+
deprecated in favour of `capResult` (`tools/tool`).
|
|
280
|
+
- The new module `tools/openapi/call` holds the caller: `buildRequest`,
|
|
281
|
+
`callOperation`, `hostProblem`, `OPENAPI_REDIRECTS`, `redactSecrets`
|
|
282
|
+
and `MAX_RESPONSE_BYTES`.
|
|
283
|
+
- `require_approval` on an OpenAPI operation uses the gate every
|
|
284
|
+
registry tool uses, so the approval hint and the pending and rejected
|
|
285
|
+
texts are ADK's FunctionTool texts. `requireApprovalOnBaseTool`
|
|
286
|
+
(`compile`) is deprecated and no longer used.
|
|
287
|
+
- A credential's value is replaced with `[redacted]` in every error an
|
|
288
|
+
OpenAPI tool returns; at most 8 MiB of a response is read; an operation
|
|
289
|
+
whose spec requires a credential is not called when the entry sets no
|
|
290
|
+
`auth`, and returns an error saying so.
|
|
291
|
+
- A spec that is not OpenAPI 3.x (Swagger 2.0, or no `openapi` version)
|
|
292
|
+
fails the compile with a readable error, and `~1` and `~0` in a
|
|
293
|
+
`$ref` are unescaped.
|
|
294
|
+
- **`GeminiAdapter` covers Gemini's own features (ADR 0065).** In
|
|
295
|
+
`melchizedek-agents/models/geminiAdapter` (which `resolveAdapter`
|
|
296
|
+
returns only with `GEMINI_ADAPTER=engine` until gate G3):
|
|
297
|
+
- Code execution (`executableCode`, `codeExecutionResult`) and
|
|
298
|
+
server-side `toolCall` / `toolResponse` parts ride whole on the next
|
|
299
|
+
output part as `providerState` of the new kind `CARRIED_PARTS_KIND`
|
|
300
|
+
(`carried_parts`, payload `CarriedParts`), and are replayed before it
|
|
301
|
+
within the current turn.
|
|
302
|
+
- `toolConfig.includeServerSideToolInvocations` is sent when native
|
|
303
|
+
tools sit beside function declarations, on the Gemini API only.
|
|
304
|
+
- Grounding citations carry the answer span each supports, and
|
|
305
|
+
urlContext's retrieved pages are cited.
|
|
306
|
+
- Call ids minted by the genai mapping (`genai-noid-`) stay off the wire,
|
|
307
|
+
as `adk-` ids do. `MINTED_CALL_ID_PREFIX` now lives in
|
|
308
|
+
`models/geminiState` and is still exported by `models/genaiMapping`.
|
|
309
|
+
- The adapter reads only `request.signal`; it no longer falls back to the
|
|
310
|
+
turn's signal (ADR 0053: the caller passes it).
|
|
311
|
+
- New option `placeholderSignatures` (default
|
|
312
|
+
`PLACEHOLDER_SIGNATURES_BY_DEFAULT`, false) sends Gemini's documented
|
|
313
|
+
placeholder `PLACEHOLDER_THOUGHT_SIGNATURE` on an unsigned current-turn
|
|
314
|
+
call.
|
|
315
|
+
- **Fix: Gemini on Vertex AI.** The compiler asks every agent's config for
|
|
316
|
+
`includeServerSideToolInvocations`, which `@google/genai` refuses on a
|
|
317
|
+
Vertex AI client before sending anything ("only supported in Gemini
|
|
318
|
+
Developer API mode"), so every Gemini call with `GEMINI_PLATFORM=vertex`
|
|
319
|
+
failed. `TracedGemini` now leaves the flag off on Vertex AI and keeps it
|
|
320
|
+
on the Gemini API.
|
|
321
|
+
- **Web sources for Claude, GPT and Grok.** When one of these models
|
|
322
|
+
searches the web, its events now carry `groundingMetadata`, so a turn's
|
|
323
|
+
grounding and the A2A server's web-sources lines list the pages it used,
|
|
324
|
+
as they already did for Gemini. Before, only Gemini's answers showed
|
|
325
|
+
their sources.
|
|
326
|
+
- **Server-side tools are markers, and MCP, remote-agent and examples tools
|
|
327
|
+
are the engine's own (ADR 0062).** All additions, under the existing
|
|
328
|
+
`exports` map:
|
|
329
|
+
- `melchizedek-agents/tools/tool` gains `NativeToolMarker`,
|
|
330
|
+
`nativeToolMarker`, `nativeToolMarkerOf`, `isNativeToolMarker` and the
|
|
331
|
+
`NATIVE_TOOL` symbol. The new module `tools/nativeTools` holds the
|
|
332
|
+
markers for `web_search`, `x_search`, `url_context`,
|
|
333
|
+
`collections_search` and `google_search`;
|
|
334
|
+
- `tools/adkTool` gains `toAdkNativeTool` and `toAdkTool`, and
|
|
335
|
+
`registerTool` takes a marker;
|
|
336
|
+
- `tools/mcpToolFactory` gains `loadMcpTools` (own Tools) and
|
|
337
|
+
`mcpToolParameters`;
|
|
338
|
+
- `a2a/remote` gains `remoteAgentOwnTool`;
|
|
339
|
+
- the new module `tools/examples` holds an agent's `examples:` as an
|
|
340
|
+
InstructionTool that writes ADK's ExampleTool block word for word.
|
|
341
|
+
|
|
342
|
+
`nativeToolOf`, `wantsWebSearch` and the other sentinel checks now read
|
|
343
|
+
the marker, not the class. A tool that only declares nothing under a
|
|
344
|
+
server-side name is no longer treated as that tool. An MCP tool's nested
|
|
345
|
+
schemas no longer carry `default`, `propertyNames`, `$schema` or a boolean
|
|
346
|
+
`additionalProperties`. `propertyNames` was refused by the Gemini API.
|
|
347
|
+
|
|
348
|
+
- **The engine parses OpenAPI specs itself (ADR 0063).** A new module,
|
|
349
|
+
`melchizedek-agents/tools/openapi/parse` (through the existing
|
|
350
|
+
`./tools/*` pattern), exports `parseOpenApiSpec` and
|
|
351
|
+
`parseOpenApiDocument`. They read an OpenAPI 3 spec into
|
|
352
|
+
`OpenApiOperation`s, each with its arguments and the `ToolDeclaration`
|
|
353
|
+
the model receives. `openapi:` tools keep their names and declarations:
|
|
354
|
+
the parser follows ADK's rules, and `buildOpenApiTools` builds the
|
|
355
|
+
same ADK tools from it. A spec is now bounded. A file over 4 MiB, more
|
|
356
|
+
than 100 YAML aliases, more than a million values once its `$ref`s are
|
|
357
|
+
resolved, or nesting deeper than 128 levels fails the compile with a
|
|
358
|
+
readable error, as does a spec that is not an object. `toSnake` and
|
|
359
|
+
`namesTool` are still exported from `tools/openapiTools`.
|
|
360
|
+
- **JSON mode without a schema is on the model contract (ADR 0061).**
|
|
361
|
+
`ModelRequest` (`melchizedek-agents/models/contract`) gains
|
|
362
|
+
`outputFormat?: 'json'`. An agent with
|
|
363
|
+
`generateContentConfig.responseMimeType: "application/json"` and no
|
|
364
|
+
schema sends its provider's JSON mode again on GPT and Grok
|
|
365
|
+
(`text.format: { type: 'json_object' }`, as before they moved onto the
|
|
366
|
+
contract), and keeps it on Kimi, Ollama, the gateway and Gemini, on the
|
|
367
|
+
ADK runtime and on the contract. Claude, whose Messages API has no JSON
|
|
368
|
+
mode, sends nothing for it, as before. `OlderSpelling.jsonMode`
|
|
369
|
+
(`models/chatCompletionsAdapter`, new in this release) is removed:
|
|
370
|
+
the chat-completions adapters read `outputFormat` instead.
|
|
371
|
+
- **The engine's own registry (ADR 0060).** `melchizedek-agents/models/registry`
|
|
372
|
+
adds `resolveAdapter(modelId, { apiKey, keyProvider, endpoint, gemini })`,
|
|
373
|
+
which returns any model id's `ModelAdapter` on the engine's contract from
|
|
374
|
+
the same prefix table, gateway fallback, BYOK scoping and endpoints as
|
|
375
|
+
`resolveModel`, with no ADK `LLMRegistry`; `resolveAdapterWithFallback`,
|
|
376
|
+
which wraps a model and its fallback in a `FallbackAdapter`;
|
|
377
|
+
`geminiAdapterChoice` and the types `ResolveAdapterOptions` and
|
|
378
|
+
`GeminiAdapterChoice`. A Gemini id gets `AdkGeminiAdapter` unless
|
|
379
|
+
`GEMINI_ADAPTER=engine` (or `gemini: 'engine'`) selects `GeminiAdapter`.
|
|
380
|
+
`TracedGemini` moves to the new module `melchizedek-agents/models/tracedGemini`;
|
|
381
|
+
`models/registry` still exports it. `registerAvailableProviders`,
|
|
382
|
+
`resolveModel`, `providerStatuses` and the doctor are unchanged.
|
|
383
|
+
- **Base URLs lose their trailing slashes in one pass.** The Kimi
|
|
384
|
+
adapter, the gateway, the endpoints module and the embeddings provider
|
|
385
|
+
trimmed a base URL with a regular expression that backtracked
|
|
386
|
+
quadratically on a long run of slashes (CodeQL js/polynomial-redos).
|
|
387
|
+
They now share `trimTrailingSlashes` (new module
|
|
388
|
+
`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
|
+
- **Fix: a message could stall the server in the memory search.**
|
|
443
|
+
`stripHarnessBlocks` (run on every memory query and extraction
|
|
444
|
+
transcript) matched an unclosed `[System Context:` marker with a pattern
|
|
445
|
+
that rescanned the rest of the text once per marker, so a message of
|
|
446
|
+
many such markers took seconds per search (16 s for 800,000 characters).
|
|
447
|
+
The pattern now stops at any bracket and scans the text once.
|
|
448
|
+
- **Memory and its tools are the engine's own (ADR 0059).** Additions
|
|
449
|
+
only; the `exports` map is unchanged.
|
|
450
|
+
- `load_memory` and `preload_memory` are the engine's own tools, in the
|
|
451
|
+
new module `melchizedek-agents/tools/memoryTools` (`loadMemoryTool`,
|
|
452
|
+
`preloadMemoryTool`). A model reads the same declaration, the same
|
|
453
|
+
memory note and the same recalled block as with ADK's tools. Two
|
|
454
|
+
differences: a call without a string `query` returns the readable
|
|
455
|
+
error instead of searching, and a failed call's error reads
|
|
456
|
+
`Error in tool 'load_memory': …`, as every own tool's does.
|
|
457
|
+
`require_approval` can now gate `load_memory`. Neither the preload
|
|
458
|
+
tool nor the memory service's search logs the user's query any more;
|
|
459
|
+
the search logs only its length.
|
|
460
|
+
- `melchizedek-agents/tools/tool`: `ToolContext` gains `userContent` and
|
|
461
|
+
`searchMemory(query)`, which searches the run's own silo only.
|
|
462
|
+
`createToolContext` takes `memory` and `userContent`. A `Tool` may have
|
|
463
|
+
`instruction(ctx)`, text for the system instruction of each request.
|
|
464
|
+
New: `InstructionTool` (a tool that only writes into the instruction),
|
|
465
|
+
`isInstructionTool` and `instructionToolOf`.
|
|
466
|
+
- `melchizedek-agents/tools/adkTool` gains `toAdkInstructionTool`, and
|
|
467
|
+
`registerTool` takes an `InstructionTool`.
|
|
468
|
+
- `SupabaseVectorMemoryService` implements the engine's `MemoryService`
|
|
469
|
+
(`ingest`, `search`) as well as ADK's `BaseMemoryService`, whose
|
|
470
|
+
methods behave as before. `namespacedMemoryService` takes either and
|
|
471
|
+
pins `search` and `ingest` too.
|
|
472
|
+
- **Claude runs on the engine's model contract (ADR 0055).** New module
|
|
473
|
+
`melchizedek-agents/models/claudeAdapter`: `ClaudeAdapter`, a
|
|
474
|
+
`ModelAdapter` that reads a `ModelRequest` and yields `ModelResponse`s on
|
|
475
|
+
the Messages API (`anthropicTools`, `ClaudeModelRequest`,
|
|
476
|
+
`THINKING_STATE_KIND`, `STRUCTURED_OUTPUT_TOOL`, `ANTHROPIC_PROVIDER`).
|
|
477
|
+
`ClaudeLlm` keeps its name, options, `supportedModels`,
|
|
478
|
+
`registerClaudeLlm()`, `buildAnthropicTools()` and `THINKING_STATE_KIND`,
|
|
479
|
+
and is now that adapter behind the ADK shim, a subclass of `AdkShim`.
|
|
480
|
+
Request bodies are unchanged. What does change on a Claude call:
|
|
481
|
+
- its events carry `finishReason`, and `groundingMetadata` when Claude
|
|
482
|
+
searched the web (see the web-sources entry above);
|
|
483
|
+
- a failed tool's `tool_result` carries `is_error: true`;
|
|
484
|
+
- a setup error (`MISSING_API_KEY`, `ENDPOINT_MISCONFIGURED`,
|
|
485
|
+
`SDK_NOT_INSTALLED`) carries `customMetadata['error.retryable']: false`;
|
|
486
|
+
- tool schemas come from `contractToolDeclaration`: `nullable` becomes a
|
|
487
|
+
type that admits null, string integer bounds become integers, and
|
|
488
|
+
`$schema` is left out.
|
|
489
|
+
`AdkShim` gains a protected `toModelRequest(llmRequest, options)` hook.
|
|
490
|
+
`melchizedek-agents/models/claudeModels` adds `ClaudeReasoning`,
|
|
491
|
+
`claudeReasoningOf`, `claudeReasoningFromConfig` and
|
|
492
|
+
`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
|
+
- **The session services serve both runtimes from the same rows, and
|
|
500
|
+
change behaviour in five places (ADR 0058).** `SupabaseSessionService`,
|
|
501
|
+
`PostgresSessionService` and `ProjectedSessionService` also implement
|
|
502
|
+
the engine's own `SessionService` (`create`, `get`, `list`, `delete`,
|
|
503
|
+
`append`) beside ADK's `BaseSessionService`, and
|
|
504
|
+
`ProjectedSessionService` accepts a store with either interface. The
|
|
505
|
+
import paths are unchanged. Through ADK's methods, to match that
|
|
506
|
+
interface:
|
|
507
|
+
- `listSessions` without a `userId` lists every user's sessions of the
|
|
508
|
+
app on the Supabase service too, as it already did on Postgres and as
|
|
509
|
+
ADK's contract says. Before, it filtered on a user named `undefined`.
|
|
510
|
+
Nothing in the engine calls it; check your own callers.
|
|
511
|
+
- `createSession` for an id that exists returns the conversation on the
|
|
512
|
+
Supabase service, as on Postgres, instead of resetting it to no events.
|
|
513
|
+
A create drops `temp:` keys from the initial state.
|
|
514
|
+
- `lastUpdateTime` and `last_update_time` are the appended event's
|
|
515
|
+
timestamp, as in ADK's own store, instead of the clock at append.
|
|
516
|
+
- On Postgres, appending an event whose id the session already holds
|
|
517
|
+
replaces that event's row instead of adding a second one.
|
|
518
|
+
- A listing with no `order` comes back in creation order, and one with
|
|
519
|
+
an `order` breaks ties by id, on both services. A `numRecentEvents`
|
|
520
|
+
below one is ignored.
|
|
521
|
+
|
|
522
|
+
No schema change. The bridge between the two interfaces
|
|
523
|
+
(`lib/runtime/adkSessionBridge.ts`) is internal and not in the exports
|
|
524
|
+
map.
|
|
525
|
+
- **GPT and Grok run on the engine's model contract (ADR 0048, ADR 0056).**
|
|
526
|
+
New modules `melchizedek-agents/models/gptAdapter` (`GptAdapter`, the
|
|
527
|
+
Responses API as a `ModelAdapter`, with `responsesInput`,
|
|
528
|
+
`responsesFunctionTools`, `responsesUsage`, `responsesServerTools`,
|
|
529
|
+
`streamErrorDecision` and `isOpenAiReasoningModel`) and
|
|
530
|
+
`melchizedek-agents/models/grokAdapter` (`GrokAdapter`,
|
|
531
|
+
`GROK_REASONING_IDS`, `XAI_BASE_URL`). `GptLlm` and `GrokLlm` keep their
|
|
532
|
+
names, constructors, `supportedModels` and exports, and are now the ADK
|
|
533
|
+
shim around these adapters. The ledger, the turn's token charge and
|
|
534
|
+
`adk_turns.tool_calls` count GPT and Grok calls as before: output tokens
|
|
535
|
+
include reasoning, and server-side searches stay on the event's
|
|
536
|
+
`customMetadata`. `AdkShim` gains a protected `toLlmResponse(response)`
|
|
537
|
+
hook for that. What changes on the wire and in the events:
|
|
538
|
+
- `grok-4.6` takes `reasoning.effort` and replays its encrypted reasoning,
|
|
539
|
+
as `grok-4.5` and `grok-4.7` do.
|
|
540
|
+
- A failure a stream reports (`response.failed`, an `error` event, or an
|
|
541
|
+
SSE frame named `error`) carries a retry verdict when it names a
|
|
542
|
+
retryable status or the code `server_error`, `rate_limit_exceeded` or
|
|
543
|
+
`vector_store_timeout`, so the fallback model answers it.
|
|
544
|
+
- An aborted stream ends in an error final instead of the text so far.
|
|
545
|
+
- A user-turn image given by an https URL reaches GPT and Grok, and a PDF
|
|
546
|
+
goes as `input_file`; `top_p` is sent beside `temperature`; a call
|
|
547
|
+
without an id gets one minted from its position, shared with its result.
|
|
548
|
+
- JSON mode without a schema (`responseMimeType: 'application/json'`
|
|
549
|
+
alone) and the older spelling's `xhigh` and `max` effort words have no
|
|
550
|
+
contract field and are no longer sent to GPT or Grok.
|
|
551
|
+
- Final events carry `finishReason`, as every shimmed adapter's do.
|
|
552
|
+
- **The engine's own event, session and memory interfaces (ADR 0052).**
|
|
553
|
+
Internal modules for the native runtime, not in the exports map, so
|
|
554
|
+
nothing a consumer imports changes: `lib/runtime/events.ts` (`TurnEvent`,
|
|
555
|
+
the stored ADK Event JSON typed, with a parse that keeps every field and
|
|
556
|
+
ADK's `isFinal`), `lib/runtime/sessions.ts` (`SessionService` and an
|
|
557
|
+
in-process store) and `lib/runtime/memoryService.ts` (`MemoryService`).
|
|
558
|
+
Stored sessions and the session services are unchanged.
|
|
559
|
+
- **The skills say what `reasoning:` does on each Claude generation (ADR 0049).**
|
|
560
|
+
`melchizedek-models`, `melchizedek-author`, their briefs, `DOCUMENTATION.md`
|
|
561
|
+
and `syndicateSchema.yaml` say that later Claude models take `reasoning:` as
|
|
562
|
+
adaptive thinking at an effort, with `none` as the model's off switch, or
|
|
563
|
+
`low` effort on Opus 5 and 5.5, Fable and Mythos. The 1,024 floor holds on
|
|
564
|
+
Claude 4.6 and earlier only, and the non-streaming limit on a
|
|
565
|
+
`budget_tokens` above about 19,000 holds on every Claude model.
|
|
566
|
+
- **Tools are the engine's own (ADR 0051).** New module
|
|
567
|
+
`melchizedek-agents/tools/tool`:
|
|
568
|
+
- `Tool`: `name`, `declaration()` (the model contract's
|
|
569
|
+
`ToolDeclaration`) and `execute(args, ctx)`.
|
|
570
|
+
- `ToolContext`: ids, a `state` view whose writes land in
|
|
571
|
+
`stateDelta`, `actions.skipSummarization`, `requestConfirmation` and
|
|
572
|
+
`confirmation`, and the abort `signal`. `createToolContext()` and
|
|
573
|
+
`toToolContext()` build one.
|
|
574
|
+
- `requireApproval(tool)`, the `longRunning` marker with
|
|
575
|
+
`LONG_RUNNING_NOTE` and `isLongRunning`, `capResult` and
|
|
576
|
+
`MAX_RESULT_CHARS` (20,000, the limit OpenAPI and MCP results already
|
|
577
|
+
use), and `toolOf(value)`, which finds the Tool behind a registry entry.
|
|
578
|
+
|
|
579
|
+
`defineTool` returns a Tool that is still a `ToolContract`. Its
|
|
580
|
+
`execute` validates the arguments before the handler runs, and the
|
|
581
|
+
handler gets a complete `ToolContext`; `executeContract` validates such
|
|
582
|
+
a Tool once. `defineTool` takes `longRunning` and `maxResultChars`.
|
|
583
|
+
`toolContract` also exports `asTool`, `DefinedTool` and `ToolSpec`.
|
|
584
|
+
`toFunctionTool` takes a Tool or a contract, and `registerTool` takes a
|
|
585
|
+
contract, any Tool or an ADK tool.
|
|
586
|
+
- **Every registry tool that declares a function is a Tool**, wrapped for
|
|
587
|
+
the ADK runtime by `toFunctionTool`, except ADK's `load_memory`. The ADK
|
|
588
|
+
runtime runs the same `FunctionTool`s, with the same approval
|
|
589
|
+
interrupts and texts. `generate_image`, `inspect_image` and `ask_user`
|
|
590
|
+
become contracts (`generateImageContract`, `inspectImageContract`):
|
|
591
|
+
- `generate_image` and `inspect_image` now return the readable error for
|
|
592
|
+
arguments their schema refuses, instead of calling Gemini;
|
|
593
|
+
- an `ask_user` call with invalid arguments returns the error to the
|
|
594
|
+
model instead of pausing the turn on it.
|
|
595
|
+
- **Tool schemas: defaults are optional, and records keep their values.**
|
|
596
|
+
On every surface (the declaration, the ADK `FunctionTool` and the MCP
|
|
597
|
+
`tools/list` entry), a zod schema is exported for its input side
|
|
598
|
+
(`io: 'input'`), so a field with a default is no longer listed as
|
|
599
|
+
required. A record's value schema (`additionalProperties`) is kept on
|
|
600
|
+
both paths, and its `propertyNames: { type: 'string' }`, which says
|
|
601
|
+
nothing in JSON, is left out: a live Gemini call refuses that keyword
|
|
602
|
+
with a 400 and accepts the value schema. `toGeminiSchema` walks by schema keyword, so a property named
|
|
603
|
+
`additionalProperties` or `default` keeps its schema. `models/schemaNormalize`
|
|
604
|
+
exports `zodInputJsonSchema`, `zodToolParameters` and `mapSchemaNodes`,
|
|
605
|
+
and `contractToolDeclaration` reads an own Tool's `declaration()`.
|
|
606
|
+
- **Claude requests follow the model generation (ADR 0049).** `ClaudeLlm`
|
|
607
|
+
reads a per-generation table from the model id. Before, every `claude-*`
|
|
608
|
+
id got a thinking budget and a forced tool, which the current models refuse
|
|
609
|
+
with a 400. Now:
|
|
610
|
+
- Claude 4.6 and earlier keep the thinking budget.
|
|
611
|
+
- Later models get adaptive thinking with `output_config.effort` from
|
|
612
|
+
`reasoning:` (or `reasoningEffort`), and a summarized thinking display.
|
|
613
|
+
`none` becomes each model's own off switch at `low` effort, or `low`
|
|
614
|
+
effort where the model has none.
|
|
615
|
+
- Structured output is `output_config.format` from Opus 4.8, Sonnet 5 and
|
|
616
|
+
Haiku 5.5 on. Forced tool use is a 400 on Fable 5.1, Opus 5.5 and
|
|
617
|
+
Sonnet 5.5.
|
|
618
|
+
- Fable 5.1, Opus 5.5, Sonnet 5.5 and Haiku 5.5 bind thinking to the
|
|
619
|
+
conversation. Their requests set `drop_block` under the
|
|
620
|
+
`thinking-binding-controls-2026-08-01` beta, so a turn resumed from
|
|
621
|
+
storage no longer fails on a history that changed in storage.
|
|
622
|
+
- An image URL that names no type is typed by its extension. Claude on
|
|
623
|
+
Bedrock and Vertex AI drops URL images, since those platforms take base64
|
|
624
|
+
only, and the capability matrix says so.
|
|
625
|
+
- `melchizedek-agents/models/claudeModels` exports `claudeGeneration`,
|
|
626
|
+
`adaptiveThinking`, `requestedEffort`, `claudeUrlImagesOn` and
|
|
627
|
+
`THINKING_BINDING_BETA`.
|
|
628
|
+
- **`reasoning:` sets how hard an agent reasons, on any provider (ADR 0047).**
|
|
629
|
+
Write `none`, `low`, `medium` or `high`, or `{ budget_tokens: <int> }`, on
|
|
630
|
+
the orchestrator or a subagent. The compiler sends each provider the field
|
|
631
|
+
it reads:
|
|
632
|
+
- Gemini 3: a thinking level.
|
|
633
|
+
- Claude and Gemini 2.x: a thinking budget of 0, 2,048, 8,192 or 16,384
|
|
634
|
+
tokens.
|
|
635
|
+
- GPT, Grok, Kimi, Ollama and the gateway: an effort word.
|
|
636
|
+
`generateContentConfig.thinkingConfig` and `reasoningEffort` remain
|
|
637
|
+
valid as the older spelling. Setting either beside `reasoning` on the same
|
|
638
|
+
agent is a load error. Agents that set neither are unchanged.
|
|
639
|
+
- **GPT and Grok honour an effort.** `GptLlm` sends `reasoning.effort` when
|
|
640
|
+
the agent sets one (`reasoning:`, or `generateContentConfig.reasoningEffort`),
|
|
641
|
+
and `GrokLlm` sends it in place of its pinned `medium`. Before, both ignored
|
|
642
|
+
it. `reasoningParam` takes the request as an optional argument.
|
|
643
|
+
- **The model zoo and every template use `reasoning:`.** What each agent
|
|
644
|
+
asks of its provider is unchanged: the templates' `includeThoughts: false`
|
|
645
|
+
was already the default, and the zoo's Claude agent keeps its 2,048-token
|
|
646
|
+
budget as `low`.
|
|
647
|
+
- **The shipped skills teach `reasoning:`.** `melchizedek-author` and
|
|
648
|
+
`melchizedek-models` (and their briefs) set reasoning with `reasoning:`, show
|
|
649
|
+
what each level becomes per provider and per Claude model generation, and
|
|
650
|
+
describe `generateContentConfig.thinkingConfig` and `reasoningEffort` as the
|
|
651
|
+
older spelling that still loads. The author skill's `assets/minimal.yaml` sets it.
|
|
652
|
+
- `lib/compile.ts` exports `reasoningConfig`, `withReasoning` and
|
|
653
|
+
`REASONING_BUDGETS`. The `AgentYamlConfig` type gains `reasoning`, and
|
|
654
|
+
`GenerateContentConfig` gains `reasoningEffort`.
|
|
655
|
+
- **Thinking with tool use works on Claude (ADR 0046).** The adapter writes
|
|
656
|
+
the signed `thinking` / `redacted_thinking` blocks into a `providerState`
|
|
657
|
+
field on the part they preceded and replays them verbatim within the
|
|
658
|
+
turn's tool loop, so a thinking Claude agent can use tools and delegate.
|
|
659
|
+
A step continuing another provider's or Claude model's tool call runs
|
|
660
|
+
without thinking.
|
|
661
|
+
New module `melchizedek-agents/models/providerState` (`ProviderState`,
|
|
662
|
+
`providerStateOf`, `withProviderState`): the convention every adapter
|
|
663
|
+
uses for provider-opaque reasoning state. The final event no longer
|
|
664
|
+
carries `customMetadata['anthropic.thinking']`; the same blocks are on
|
|
665
|
+
the part.
|
|
666
|
+
- **Claude agents see images.** `ClaudeLlm` sends a user-turn `inlineData`
|
|
667
|
+
part as a base64 image block (`image/png` when it names no type) and an
|
|
668
|
+
`https` `fileData` part as a URL image block, in the parts' order. Before,
|
|
669
|
+
it dropped both. JPEG, PNG, GIF and WebP are sent; any other type, or a
|
|
670
|
+
non-https URL, is dropped with `llm.image.dropped` on the span and a
|
|
671
|
+
one-time warning naming the type. Images inside tool results are not sent,
|
|
672
|
+
as on GPT. The capability matrix marks Anthropic image input supported.
|
|
673
|
+
- **The engine's own model contract (ADR 0048).** New module
|
|
674
|
+
`melchizedek-agents/models/contract`, types only: `Message`, `Part`,
|
|
675
|
+
`ToolDeclaration`, `NativeTool`, `ModelRequest`, `ModelResponse`,
|
|
676
|
+
`ModelAdapter`, `ProviderCapabilities` and their parts. The native
|
|
677
|
+
runtime and every model adapter will speak it, and no adapter uses it
|
|
678
|
+
yet. `ReasoningLevel` and `ReasoningSetting` are defined there now.
|
|
679
|
+
`melchizedek-agents/loadSyndicate` re-exports them unchanged.
|
|
680
|
+
- **Tool declarations in the contract's shape.** `models/schemaNormalize`
|
|
681
|
+
exports `contractToolDeclaration(tool, { strict? })`, which builds a
|
|
682
|
+
contract `ToolDeclaration` from an ADK tool or straight from a
|
|
683
|
+
`defineTool` contract's zod schema; `nativeToolOf(tool)`, which names the
|
|
684
|
+
`NativeTool` a server-side tool or Gemini's code executor stands for; and
|
|
685
|
+
`toContractJsonSchema(schema, { strict? })`. Gemini's dialect (uppercase
|
|
686
|
+
types, int64 bounds as strings, `nullable`) is converted once, at any
|
|
687
|
+
depth, and the strict form reaches every nested object. Nothing calls
|
|
688
|
+
them yet; `toolDeclarationFor`, `toLowercaseJsonSchema` and
|
|
689
|
+
`toStrictJsonSchema` are unchanged.
|
|
690
|
+
- **genai `Content` maps to and from the model contract (ADR 0048).** New
|
|
691
|
+
module `melchizedek-agents/models/genaiMapping`: `contentsToMessages` and
|
|
692
|
+
`messagesToContents`, `contentToMessage` and `messageToContent`,
|
|
693
|
+
`partToGenai`, `llmRequestToModelRequest`, `modelResponseToLlmResponse`,
|
|
694
|
+
`reasoningOf`, `systemText`, `usageToMetadata`, `usageFromMetadata` and
|
|
695
|
+
`isMintedCallId`, the constants `GEMINI_PROVIDER`,
|
|
696
|
+
`THOUGHT_SIGNATURE_KIND`, `GENAI_PART_KIND` and `MINTED_CALL_ID_PREFIX`,
|
|
697
|
+
and the types `ContractHistory`, `GenaiHistory` and
|
|
698
|
+
`ModelRequestOptions`. A stored event's
|
|
699
|
+
content round-trips to the same JSON: a Gemini `thoughtSignature` becomes
|
|
700
|
+
`providerState` of kind `thought_signature`, a call without an id gets a
|
|
701
|
+
`genai-noid-` id that is left off again on the way back, and a part the
|
|
702
|
+
contract cannot hold (Gemini code execution, ADK's confirmation request)
|
|
703
|
+
rides whole as `providerState` of kind `genai_part`. A failed final keeps
|
|
704
|
+
its retry verdict as `customMetadata['error.retryable']` and
|
|
705
|
+
`['error.status']`, which is what `FallbackLlm` reads. Nothing calls it yet;
|
|
706
|
+
no adapter or stored shape changes.
|
|
707
|
+
- **Thinking with tool use works on GPT and Grok (ADR 0050).** On
|
|
708
|
+
reasoning ids (o-series, `gpt-5*`, `grok-4.5`, `grok-4.7`), the Responses
|
|
709
|
+
adapters write each run of encrypted reasoning items on the part after it
|
|
710
|
+
and replay them before that part within the turn's tool loop, for the same
|
|
711
|
+
provider and model only. These requests now send `store: false` and
|
|
712
|
+
`include: ['reasoning.encrypted_content']`, so OpenAI and xAI no longer
|
|
713
|
+
keep the response server-side, as they did by default. The guarded 400
|
|
714
|
+
retry also drops the `include` and the replayed items.
|
|
715
|
+
`buildResponsesInput` takes an optional `replay` argument;
|
|
716
|
+
`models/gptLlm` exports `REASONING_STATE_KIND`, and `models/providerState`
|
|
717
|
+
exports `currentTurnStart`.
|
|
718
|
+
- **Kimi keeps its reasoning across tool steps (ADR 0046).** On `kimi-k3`,
|
|
719
|
+
`kimi-k2.6` and `kimi-k2.7-code`, the adapter stores each response's
|
|
720
|
+
`reasoning_content` on the part that follows it and sends it back on that
|
|
721
|
+
assistant message within the turn's tool loop, for the same model only,
|
|
722
|
+
as Moonshot asks. A tool loop's later steps bill the replayed reasoning
|
|
723
|
+
as input. `OpenAiCompatibleLlm` gains the opt-in hook
|
|
724
|
+
`replaysReasoningContent()` (off by default; Ollama and the gateway keep
|
|
725
|
+
it off) and exports `REASONING_CONTENT_KIND`; `models/kimiLlm` exports
|
|
726
|
+
`wantsReasoningReplay`. `currentTurnStart` returns -1 when no user
|
|
727
|
+
content opens the turn, so every content is then the current turn's.
|
|
728
|
+
- **The fallback model on the engine's own contract (ADR 0044, ADR 0048).**
|
|
729
|
+
New module `melchizedek-agents/models/fallbackAdapter`: `FallbackAdapter`,
|
|
730
|
+
a `ModelAdapter` around a primary and a fallback adapter, with
|
|
731
|
+
`FallbackAdapterOptions` and `isProviderError`. It applies ADR 0044's
|
|
732
|
+
rules to a failed final's `error.retryable` and `status`, and hands the
|
|
733
|
+
fallback the request with its own model id and the caller's `reasoning`
|
|
734
|
+
unchanged. Nothing uses it yet. The breaker's state moves to the new
|
|
735
|
+
module `melchizedek-agents/models/circuitBreaker` (`circuitOpen`,
|
|
736
|
+
`recordFailure`, `recordSuccess`, `resetCircuits`, `breakerSettings`, and
|
|
737
|
+
`setBreakerClock` for tests), shared by both wrappers, so a provider
|
|
738
|
+
tripped on one path is skipped on the other. `models/fallback` still
|
|
739
|
+
exports `circuitOpen` and `resetCircuits`, and `FallbackLlm` behaves as
|
|
740
|
+
before.
|
|
741
|
+
- **Any adapter on the model contract runs under ADK (ADR 0053).** New module
|
|
742
|
+
`melchizedek-agents/models/adkShim`: `AdkShim`, an ADK `BaseLlm` that
|
|
743
|
+
wraps one `ModelAdapter` and maps ADK's request and responses through
|
|
744
|
+
`models/genaiMapping`; `adkShim(adapter, model?)`; `adkShimClass(supportedModels,
|
|
745
|
+
createAdapter)`, a class ADK's `LLMRegistry` can register; and the types
|
|
746
|
+
`AdkShimOptions` and `ModelAdapterFactory`. The shim charges each call
|
|
747
|
+
against the turn's `max_steps`, refuses a call on a spent or stopped turn
|
|
748
|
+
with the same response the ADK-path adapters give, hands the adapter the
|
|
749
|
+
turn's abort signal, and opens the `llm.request` span, so an adapter on
|
|
750
|
+
the contract does none of these itself. `connect()` is refused. Nothing
|
|
751
|
+
registers it yet; no adapter or stored shape changes.
|
|
752
|
+
- **An elided tool result's size is stored the same on every server.**
|
|
753
|
+
`trimEventForStorage` writes it with en-US digit grouping (`2,563 chars
|
|
754
|
+
dropped before storage — …`), where it followed the server's locale
|
|
755
|
+
(`2.563` in German). An en-US server stores the same bytes as before, and
|
|
756
|
+
rows already stored are untouched.
|
|
757
|
+
- The capability matrix's Ollama and gateway `thinking_with_tools` note names
|
|
758
|
+
`reasoning:` as the lever (ADR 0047), compiled to `reasoningEffort`.
|
|
759
|
+
- **The shipped skills cover Kimi.** `melchizedek-models` adds `kimi-*` to
|
|
760
|
+
Moonshot AI in its routing table, `MOONSHOT_API_KEY` to its key list and
|
|
761
|
+
`kimi-k3` to its verified ids; `melchizedek` adds the key and `kimi-*` to
|
|
762
|
+
its `Model not found` line. Their briefs match.
|
|
763
|
+
- **`wiki_relate` appends.** A new assertion goes at the end of
|
|
764
|
+
`.graph/relations.json` and every stored record keeps its place and bytes,
|
|
765
|
+
where each write used to re-sort the whole file. A store that does not
|
|
766
|
+
parse is refused rather than overwritten. `melchizedek-agents/wiki/entities`
|
|
767
|
+
exports `appendRelation(wikiRoot, record)`, which returns `false` for a
|
|
768
|
+
duplicate, and `saveRelations` writes records in the order given instead of
|
|
769
|
+
sorting them.
|
|
770
|
+
- **Fix: `fallback_model:` answers for Claude, GPT, Grok, Kimi, Ollama and
|
|
771
|
+
gateway primaries (ADR 0044).** In 0.18.0 `FallbackLlm` saw a failure only when
|
|
772
|
+
the primary threw, which only Gemini does. The other adapters yield an
|
|
773
|
+
error response, so their fallback never answered, and the failed call was
|
|
774
|
+
recorded as a success, which reset the provider's circuit breaker. Their
|
|
775
|
+
error responses now carry `customMetadata['error.retryable']` (and
|
|
776
|
+
`'error.status'` when the failure had an HTTP status), set from
|
|
777
|
+
`lib/models/retry.ts`'s classification, and `FallbackLlm` reads them: a
|
|
778
|
+
retryable error before any output is counted on the breaker and answered
|
|
779
|
+
by the fallback, a non-retryable one is passed on, and only a call that
|
|
780
|
+
produced content counts as a success. Error codes and messages are
|
|
781
|
+
unchanged, except that key-shaped text is now removed from the message.
|
|
782
|
+
A failure GPT or Grok report inside an open stream carries a verdict too,
|
|
783
|
+
from the event (see GPT and Grok on the model contract). The retry policy now counts
|
|
784
|
+
HTTP 529, Anthropic's "overloaded", as retryable, so an overloaded Claude
|
|
785
|
+
primary is answered by its fallback. New
|
|
786
|
+
module `melchizedek-agents/models/errorResponse`: `providerErrorResponse`,
|
|
787
|
+
`withRetryVerdict`, `isRetryableErrorResponse`, `errorDecision`,
|
|
788
|
+
`statusDecision`, `errorText`, `ERROR_RETRYABLE_KEY`, `ERROR_STATUS_KEY`.
|
|
789
|
+
- **A Gemini adapter on the model contract, not yet wired.** New module
|
|
790
|
+
`melchizedek-agents/models/geminiAdapter`: `GeminiAdapter` implements
|
|
791
|
+
`ModelAdapter` (ADR 0048) on `@google/genai` directly, with no ADK, on the
|
|
792
|
+
Gemini API or Vertex AI (`lib/models/endpoints.ts`). Schemas go as
|
|
793
|
+
lowercase JSON Schema (`parametersJsonSchema`, `responseJsonSchema`).
|
|
794
|
+
`reasoning:` maps through `reasoningConfig`. Thought signatures ride on
|
|
795
|
+
the part as `providerState` and are replayed within the turn. Every
|
|
796
|
+
failure is a final response. A `clientFactory` option takes an injected
|
|
797
|
+
client. Nothing registers the adapter yet: Gemini ids are still served by
|
|
798
|
+
`TracedGemini`, unchanged. `REASONING_BUDGETS` and `reasoningConfig` move
|
|
799
|
+
to the new module `melchizedek-agents/models/reasoning`, so the adapter
|
|
800
|
+
maps `reasoning:` without importing the compiler or ADK;
|
|
801
|
+
`melchizedek-agents/compile` still exports both.
|
|
802
|
+
- **A temporary Gemini adapter on the contract, over ADK's Gemini.** New
|
|
803
|
+
module `melchizedek-agents/models/adkGeminiAdapter`: `AdkGeminiAdapter`
|
|
804
|
+
(and `AdkGeminiAdapterOptions`) implements `ModelAdapter` by mapping the
|
|
805
|
+
request to an `LlmRequest` and running it through `TracedGemini` with its
|
|
806
|
+
retries. Every failure is a final response: a failed call is
|
|
807
|
+
`GEMINI_ERROR` with its status and retry verdict. Like every contract
|
|
808
|
+
adapter (ADR 0053) it opens no `llm.request` span and charges nothing;
|
|
809
|
+
behind `AdkShim` the span has `TracedGemini`'s attributes, with the
|
|
810
|
+
failed call's code as `GEMINI_ERROR` where `TracedGemini` records the
|
|
811
|
+
HTTP status. It serves Gemini on the native runtime until `GeminiAdapter`
|
|
812
|
+
passes its live parity run, and is removed after that. Nothing registers
|
|
813
|
+
it yet.
|
|
814
|
+
- `models/genaiMapping` adds the reverse directions:
|
|
815
|
+
`modelRequestToLlmRequest`, `llmResponseToModelResponse` (with the type
|
|
816
|
+
`ModelResponseOptions`) and `nativeToolsWithoutGeminiTool`.
|
|
817
|
+
- `TracedGemini` gains `generateWithRetries(llmRequest, stream?,
|
|
818
|
+
abortSignal?)`, the call that `generateContentAsync` wraps in its span.
|
|
819
|
+
Its spans are unchanged.
|
|
820
|
+
- `traceLlmGeneration`'s `LlmCallMeta` gains `request`: a `ModelRequest`,
|
|
821
|
+
or a function that returns one. `llmRequest` is deprecated and still
|
|
822
|
+
recorded when `request` is absent. Every adapter in the package and
|
|
823
|
+
`AdkShim` now pass `request`, so a failed call's `llm.payload.request`, and the
|
|
824
|
+
`adk_payloads.request` row made from it, hold the request in the model
|
|
825
|
+
contract's shape (`model`, `system`, `messages`, `tools`, …) instead of
|
|
826
|
+
ADK's (`contents`, `config`, `toolsDict`). The span's other attributes
|
|
827
|
+
are unchanged.
|
|
828
|
+
- `GEMINI_PROVIDER` and `THOUGHT_SIGNATURE_KIND` are defined once, in the
|
|
829
|
+
new module `melchizedek-agents/models/geminiState`. `models/genaiMapping`
|
|
830
|
+
and `models/geminiAdapter` still export both, with the same values.
|
|
831
|
+
|
|
7
832
|
## 0.18.0 — 2026-10-06
|
|
8
833
|
|
|
9
834
|
### Breaking — read before upgrading
|