melchizedek-agents 1.0.3 → 1.2.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 +29 -2
- package/AGENT_SETUP.md +3 -1
- package/CHANGELOG.md +524 -0
- package/DOCUMENTATION.md +178 -43
- package/ONBOARDING.md +339 -0
- package/QUICKSTART.md +15 -2
- package/README.md +6 -2
- package/config/agents/README.md +2 -2
- package/config/agents/examples/ares.yaml +6 -10
- package/config/agents/examples/assistant.yaml +6 -6
- package/config/agents/examples/augustin.yaml +9 -15
- package/config/agents/examples/cartographers.yaml +6 -6
- package/config/agents/examples/council.yaml +7 -7
- package/config/agents/examples/critic.yaml +24 -24
- package/config/agents/examples/harness.yaml +4 -4
- package/config/agents/examples/image_production.yaml +37 -35
- package/config/agents/examples/librarian.yaml +4 -4
- package/config/agents/examples/patient_advocate.yaml +6 -10
- package/config/agents/examples/pipeline.yaml +20 -19
- package/config/agents/examples/research.yaml +36 -43
- package/config/agents/examples/scribe.yaml +31 -32
- package/config/agents/examples/scriptorium.yaml +6 -6
- package/config/agents/examples/structured_critic.yaml +82 -0
- package/config/agents/examples/style_council.yaml +9 -11
- package/config/agents/examples/syndicate.yaml +3 -5
- package/config/agents/examples/tutor.yaml +2 -2
- package/config/agents/examples/weather.yaml +2 -2
- package/config/agents/syndicate.schema.json +859 -13
- package/config/agents/syndicateSchema.yaml +122 -73
- package/config/agents/templates/README.md +1 -1
- package/config/agents/templates/account_memory.yaml +4 -4
- package/config/agents/templates/case_desk.yaml +6 -6
- package/config/agents/templates/conversational.yaml +2 -2
- package/config/agents/templates/draft_review.yaml +6 -6
- package/config/agents/templates/intake_extractor.yaml +64 -62
- package/config/agents/templates/research_brief.yaml +6 -6
- package/config/agents/templates/research_desk.yaml +6 -6
- package/config/agents/templates/review_panel.yaml +8 -8
- package/config/agents/templates/support_triage.yaml +30 -29
- package/config/agents/templates/systems_operator.yaml +24 -5
- package/db/migrations/0014_durable_runs.sql +31 -0
- package/dist/lib/a2a/app.d.ts +27 -0
- package/dist/lib/a2a/app.js +64 -5
- package/dist/lib/a2a/executor.d.ts +7 -1
- package/dist/lib/a2a/executor.js +43 -5
- package/dist/lib/a2a/oauthSetup.d.ts +106 -0
- package/dist/lib/a2a/oauthSetup.js +259 -0
- package/dist/lib/agentDialect.d.ts +76 -0
- package/dist/lib/agentDialect.js +151 -0
- package/dist/lib/compile.d.ts +42 -6
- package/dist/lib/compile.js +97 -45
- package/dist/lib/compileNative.d.ts +11 -3
- package/dist/lib/compileNative.js +20 -1
- package/dist/lib/dispatch.d.ts +10 -5
- package/dist/lib/dispatch.js +10 -5
- package/dist/lib/doctor.d.ts +110 -1
- package/dist/lib/doctor.js +205 -9
- package/dist/lib/loadSyndicate.d.ts +54 -2
- package/dist/lib/loadSyndicate.js +22 -2
- package/dist/lib/memory/namespace.d.ts +6 -5
- package/dist/lib/memory/namespace.js +6 -5
- package/dist/lib/memory/providers.js +3 -4
- package/dist/lib/models/capabilities.d.ts +25 -1
- package/dist/lib/models/capabilities.js +79 -1
- package/dist/lib/models/chatCompletionsAdapter.d.ts +11 -3
- package/dist/lib/models/chatCompletionsAdapter.js +19 -5
- package/dist/lib/models/claudeAdapter.js +4 -0
- package/dist/lib/models/contract.d.ts +5 -2
- package/dist/lib/models/gateway.d.ts +2 -1
- package/dist/lib/models/gateway.js +4 -2
- package/dist/lib/models/gatewayAdapter.d.ts +7 -1
- package/dist/lib/models/gatewayAdapter.js +8 -0
- package/dist/lib/models/geminiAdapter.js +8 -2
- package/dist/lib/models/genaiMapping.d.ts +8 -4
- package/dist/lib/models/genaiMapping.js +23 -9
- package/dist/lib/models/gptAdapter.d.ts +4 -2
- package/dist/lib/models/gptAdapter.js +11 -4
- package/dist/lib/models/grokAdapter.d.ts +3 -1
- package/dist/lib/models/grokAdapter.js +11 -3
- package/dist/lib/models/kimiAdapter.d.ts +2 -1
- package/dist/lib/models/kimiAdapter.js +3 -3
- package/dist/lib/models/reasoning.d.ts +30 -2
- package/dist/lib/models/reasoning.js +56 -5
- package/dist/lib/observability/tracer.d.ts +8 -1
- package/dist/lib/observability/tracer.js +33 -5
- package/dist/lib/onboarding.d.ts +134 -0
- package/dist/lib/onboarding.js +539 -0
- package/dist/lib/runtime/approvals.d.ts +8 -0
- package/dist/lib/runtime/approvals.js +4 -3
- package/dist/lib/runtime/credentials.d.ts +6 -0
- package/dist/lib/runtime/native/agentLoop.d.ts +23 -3
- package/dist/lib/runtime/native/agentLoop.js +107 -11
- package/dist/lib/runtime/native/checkpoint.d.ts +171 -0
- package/dist/lib/runtime/native/checkpoint.js +359 -0
- package/dist/lib/runtime/native/delegate.d.ts +222 -18
- package/dist/lib/runtime/native/delegate.js +390 -39
- package/dist/lib/runtime/native/interrupts.d.ts +184 -2
- package/dist/lib/runtime/native/interrupts.js +391 -1
- package/dist/lib/runtime/native/request.d.ts +13 -3
- package/dist/lib/runtime/native/request.js +28 -4
- package/dist/lib/runtime/native/telemetry.js +10 -15
- package/dist/lib/runtime/questions.d.ts +7 -4
- package/dist/lib/runtime/sessions.d.ts +1 -1
- package/dist/lib/runtime/syndicateTurn.d.ts +11 -3
- package/dist/lib/runtime/syndicateTurn.js +353 -68
- package/dist/lib/runtime/turnControl.d.ts +56 -0
- package/dist/lib/runtime/turnControl.js +10 -0
- package/dist/lib/session/transcript.d.ts +9 -0
- package/dist/lib/session/transcript.js +20 -1
- package/dist/lib/skills.d.ts +18 -0
- package/dist/lib/skills.js +73 -1
- package/dist/lib/storage/postgres/index.d.ts +12 -2
- package/dist/lib/storage/postgres/index.js +8 -3
- package/dist/lib/storage/postgres/taskQueue.d.ts +20 -4
- package/dist/lib/storage/postgres/taskQueue.js +29 -5
- package/dist/lib/storage/postgres/taskStore.d.ts +26 -2
- package/dist/lib/storage/postgres/taskStore.js +74 -8
- package/dist/lib/syndicateSchema.d.ts +316 -1
- package/dist/lib/syndicateSchema.js +203 -29
- package/dist/lib/tools/auth.d.ts +20 -6
- package/dist/lib/tools/auth.js +21 -5
- package/dist/lib/tools/credentialEnv.d.ts +28 -0
- package/dist/lib/tools/credentialEnv.js +52 -0
- package/dist/lib/tools/credentialHosts.d.ts +88 -0
- package/dist/lib/tools/credentialHosts.js +165 -0
- package/dist/lib/tools/credentialStore.js +9 -2
- package/dist/lib/tools/credentialUses.d.ts +92 -0
- package/dist/lib/tools/credentialUses.js +112 -0
- package/dist/lib/tools/mcpToolFactory.d.ts +25 -2
- package/dist/lib/tools/mcpToolFactory.js +179 -21
- package/dist/lib/tools/oauthConsent.js +8 -1
- package/dist/lib/tools/oauthHosts.d.ts +73 -0
- package/dist/lib/tools/oauthHosts.js +154 -0
- package/dist/lib/tools/oauthTools.d.ts +242 -0
- package/dist/lib/tools/oauthTools.js +447 -0
- package/dist/lib/tools/openapiTools.d.ts +11 -6
- package/dist/lib/tools/openapiTools.js +88 -38
- package/dist/lib/tools/taskTools.d.ts +61 -6
- package/dist/lib/tools/taskTools.js +145 -21
- package/dist/lib/workflow/turn.d.ts +22 -3
- package/dist/lib/workflow/turn.js +151 -31
- package/dist/lib/workflow.d.ts +14 -7
- package/dist/lib/workflow.js +14 -7
- package/dist/lib/workflowConfig.d.ts +6 -0
- package/dist/scripts/a2a_server.d.ts +36 -0
- package/dist/scripts/a2a_server.js +131 -1
- package/dist/scripts/assistant_worker.d.ts +12 -0
- package/dist/scripts/assistant_worker.js +81 -22
- package/dist/scripts/doctor.d.ts +7 -2
- package/dist/scripts/doctor.js +9 -4
- package/dist/scripts/setup.d.ts +23 -0
- package/dist/scripts/setup.js +154 -0
- package/dist/scripts/skills_install.d.ts +3 -1
- package/dist/scripts/skills_install.js +17 -2
- package/dist/scripts/yaml_codemod.d.ts +62 -0
- package/dist/scripts/yaml_codemod.js +652 -0
- package/package.json +8 -2
- package/skills/README.md +11 -2
- package/skills/briefs/_shared.md +1 -1
- package/skills/briefs/melchizedek-author.md +7 -5
- package/skills/briefs/melchizedek-models.md +7 -4
- package/skills/briefs/melchizedek.md +1 -0
- package/skills/briefs/skills-readme.md +3 -1
- package/skills/melchizedek/SKILL.md +1 -0
- package/skills/melchizedek-author/SKILL.md +7 -4
- package/skills/melchizedek-author/assets/minimal.yaml +13 -13
- package/skills/melchizedek-models/SKILL.md +11 -4
- package/skills/melchizedek-onboard/SKILL.md +49 -0
- package/skills/melchizedek-onboard-cloud/SKILL.md +38 -0
- package/skills/melchizedek-onboard-keys/SKILL.md +35 -0
- package/skills/melchizedek-onboard-local/SKILL.md +41 -0
- package/skills/melchizedek-onboard-serve/SKILL.md +43 -0
package/.env.example
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
# Not sure which of these you need? `npx melchizedek-setup` (in a clone: `npm run setup`)
|
|
2
|
+
# asks what you have and prints the names to set for it; --auto detects it.
|
|
3
|
+
# Only names and shapes live here: type the values yourself, never commit .env.
|
|
4
|
+
|
|
1
5
|
# ── Required for cloud models ─────────────────────────────────────────────────
|
|
2
6
|
# Google AI Studio API key — powers all Gemini model inference.
|
|
3
7
|
# Also required for the gemini-embedding-001 embedding model used by long-term memory.
|
|
@@ -33,8 +37,11 @@ ALLOW_PRIVATE_MCP=false
|
|
|
33
37
|
# ── Optional: OpenAPI tools (an agent's `openapi:` list) ──────────────────────
|
|
34
38
|
# ALLOW_PRIVATE_OPENAPI: set to "true" to let an OpenAPI tool call a localhost /
|
|
35
39
|
# private / link-local server. Off by default as an SSRF guard. Credentials an
|
|
36
|
-
# `openapi:` entry names (auth.bearer_env, auth.api_key.env
|
|
37
|
-
#
|
|
40
|
+
# `openapi:` entry names (auth.bearer_env, auth.api_key.env, and an OAuth
|
|
41
|
+
# grant's auth.oauth2.client_id_env / client_secret_env, which an MCP server's
|
|
42
|
+
# mcp_auth.oauth2 uses too) are read from this file or the environment, never
|
|
43
|
+
# written in YAML. Give each API its own variable: the framework's own
|
|
44
|
+
# settings below are refused (ADR 0112).
|
|
38
45
|
# ALLOW_PRIVATE_OPENAPI=false
|
|
39
46
|
|
|
40
47
|
# ── Optional: Anthropic / Claude ──────────────────────────────────────────────
|
|
@@ -245,6 +252,26 @@ PUBLIC_URL=
|
|
|
245
252
|
# out of the database and its backups. Unset = no credential store. A row
|
|
246
253
|
# sealed with another key stays unreadable (the user reconnects).
|
|
247
254
|
# MELCHIZEDEK_CREDENTIAL_KEY=
|
|
255
|
+
# The OAuth consent callback (ADR 0085), exactly as registered at every
|
|
256
|
+
# provider a YAML grant names: https, no query. Mounts the callback and lets a
|
|
257
|
+
# run ask a user to connect a provider. Needs MELCHIZEDEK_CREDENTIAL_KEY.
|
|
258
|
+
# OAUTH_REDIRECT_URI=https://agents.example.com/oauth/callback
|
|
259
|
+
# Who may complete a callback (ADR 0114): required (default) — the browser
|
|
260
|
+
# carries the user's identity, which only A2A_AUTH=header behind a gateway
|
|
261
|
+
# gives it; state — the single-use state alone binds the flow to its user.
|
|
262
|
+
# OAUTH_CALLBACK_IDENTITY=required
|
|
263
|
+
# The hosts each provider's tokens may be sent to (ADR 0114), the operator's
|
|
264
|
+
# binding, never the YAML's: provider=host,host;provider=host. A host is a
|
|
265
|
+
# hostname, *.domain (subdomains only), IPv4 or [IPv6]; no scheme or port.
|
|
266
|
+
# Unset: authorization_code grants are refused, client_credentials allowed.
|
|
267
|
+
# Set: every grant's provider is listed and every host it calls is its own.
|
|
268
|
+
# MELCHIZEDEK_OAUTH_HOSTS=tracker=api.tracker.example.com,auth.tracker.example.com
|
|
269
|
+
# The hosts each static credential variable a YAML sends may be sent to
|
|
270
|
+
# (ADR 0122): bearer_env, api_key.env and client_secret_env, each entry the
|
|
271
|
+
# variable's name, '=', then its hosts (as above). Unset: each goes to the
|
|
272
|
+
# host the YAML names, and the server and the doctor name it as unbound.
|
|
273
|
+
# Set: it is the whole list; an unlisted variable is sent nowhere.
|
|
274
|
+
# MELCHIZEDEK_CREDENTIAL_HOSTS=TRACKER_TOKEN=api.tracker.example.com;WEATHER_API_KEY=api.weather.example.com
|
|
248
275
|
|
|
249
276
|
# ── Optional: Knowledge Bundle (wiki) ─────────────────────────────────────────
|
|
250
277
|
# WIKI_ROOT: filesystem path of the OKF knowledge bundle the wiki tools serve.
|
package/AGENT_SETUP.md
CHANGED
|
@@ -26,7 +26,9 @@ Set up the melchizedek-agents framework on this machine.
|
|
|
26
26
|
it. Never ask me to paste API keys into this chat, never read keys
|
|
27
27
|
from elsewhere on my machine, and never commit .env.
|
|
28
28
|
4. Run the offline test suite (`npm test`) and confirm every shipped
|
|
29
|
-
syndicate compiles.
|
|
29
|
+
syndicate compiles. Then run `npm run setup -- --auto`: it reports
|
|
30
|
+
which authentication level my environment is at, by variable name
|
|
31
|
+
only. Follow the melchizedek-onboard skill in skills/ to pick my level.
|
|
30
32
|
5. Read README.md and QUICKSTART.md. Then report back with:
|
|
31
33
|
- what you did and the test results,
|
|
32
34
|
- the list of available syndicates (one line each, from the README
|
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,530 @@ the starter pack and the templates), not the repo's full history.
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## 1.2.0 — 2026-10-09
|
|
10
|
+
|
|
11
|
+
Release 1.2.0 carries pauses and consent further down a turn and gives the
|
|
12
|
+
YAML its last v2 keys (ADRs 0117–0123). A delegated subagent may run skill
|
|
13
|
+
scripts and ask for OAuth consent; a nested workflow pauses the turn as a
|
|
14
|
+
dispatch route or a workflow node; a nested dispatch syndicate routes as it
|
|
15
|
+
does at the top; static credentials go only to hosts the operator binds;
|
|
16
|
+
`tool_choice:` and `reasoning: xhigh | max` complete the provider-neutral
|
|
17
|
+
keys; a background job's checkpoint has a cap, and a durable run resumes
|
|
18
|
+
inside a dispatch route. `melchizedek-setup` is the new onboarding command.
|
|
19
|
+
|
|
20
|
+
### Upgrade first
|
|
21
|
+
|
|
22
|
+
Read this list before deploying 1.2.0 over 1.1.0.
|
|
23
|
+
|
|
24
|
+
- **The older spelling's `reasoningEffort: xhigh` and `max` now reach the
|
|
25
|
+
provider** (ADR 0117). Since 1.0.0 they were read by nothing and sent
|
|
26
|
+
nowhere; an agent that still carries one now asks its model for that
|
|
27
|
+
effort (or the model's highest, see Added), and beside a `thinkingConfig`
|
|
28
|
+
that says `high` the word wins. Such an agent thinks harder and costs
|
|
29
|
+
more. Remove the word to keep the old behaviour.
|
|
30
|
+
- **`ReasoningLevel` (`melchizedek-agents/models/contract`) gains `xhigh`
|
|
31
|
+
and `max`**, and `REASONING_BUDGETS` gains both keys (16,384 each,
|
|
32
|
+
`high`'s budget). An exhaustive `Record<ReasoningLevel, …>` or a `switch`
|
|
33
|
+
over the levels no longer type-checks without them (ADR 0117).
|
|
34
|
+
- **A nested dispatch syndicate answers with its route's text, not its
|
|
35
|
+
classifier's JSON** (ADR 0120). A `yaml_reference` to a plan-dispatch
|
|
36
|
+
syndicate used to compile to its classifier alone, so its caller got the
|
|
37
|
+
routing verdict and its routes never ran; a prompt or parser that relied
|
|
38
|
+
on that verdict sees the specialist's answer now. A gate or skill scripts
|
|
39
|
+
on one of its routes is no longer a load error. `compileSubagentSpec`
|
|
40
|
+
refuses a reference to a dispatch syndicate by name: compile it with
|
|
41
|
+
`compileEntrySpec`.
|
|
42
|
+
- **Child session keys for routes and nodes carry their kind and the agent
|
|
43
|
+
path** (ADR 0119, ADR 0120). A nested syndicate or nested workflow run as
|
|
44
|
+
a dispatch route is filed under `<app>/route:<route>`, and as a workflow
|
|
45
|
+
node under `<walk's app>/node:<node>` (`app/route:Writer/node:Inner` two
|
|
46
|
+
levels down), no longer under the entry's name alone, so it no longer
|
|
47
|
+
shares a row with a same-named entry of another syndicate, and neither
|
|
48
|
+
can share a key with a delegated subagent's (`<app>/<caller>/<subagent>`,
|
|
49
|
+
unchanged). A session 1.1.0 stored under the entry's name, or under
|
|
50
|
+
`<app>/<entry>`, is still continued when the entry ran in that
|
|
51
|
+
conversation before; nothing stored is rewritten. Code that read the
|
|
52
|
+
walk's events at `{ appName: '<entry>' }` or `<app>/<entry>` reads them
|
|
53
|
+
at the kind key now.
|
|
54
|
+
- **`melchizedek-doctor --check` exits 1 on a grant whose hosts the OAuth
|
|
55
|
+
host allowlist refuses.** The doctor already printed each such grant
|
|
56
|
+
(`✗ … is not one of them`, `MELCHIZEDEK_OAUTH_HOSTS`, ADR 0114) and still
|
|
57
|
+
exited 0; a CI step that runs `--check` against a served syndicate now
|
|
58
|
+
fails on it. A blocked syndicate, a runtime problem and the OAuth and
|
|
59
|
+
credential setup's problems fail it as before.
|
|
60
|
+
|
|
61
|
+
### Added
|
|
62
|
+
|
|
63
|
+
- **Skill scripts on a delegated subagent.** `skills.scripts: local` is no
|
|
64
|
+
longer a load error on a delegated subagent (or a nested delegate
|
|
65
|
+
syndicate's): a `run_skill_script` call there pauses the turn
|
|
66
|
+
`input-required` with `approval.path`, and the decision runs or refuses the
|
|
67
|
+
script in the subagent before its caller continues. An agent a map node
|
|
68
|
+
runs still may not carry scripts (ADR 0118).
|
|
69
|
+
- **OAuth consent inside a delegated subagent.** A subagent's
|
|
70
|
+
`authorization_code` tool (an `mcp_auth` or OpenAPI `auth.oauth2` grant)
|
|
71
|
+
now asks for a missing grant instead of answering `not_connected`: the turn
|
|
72
|
+
ends `input-required` with `consent`, whose new optional `path` names the
|
|
73
|
+
agents from the turn's own down to the one that asked (`PendingConsent.path`;
|
|
74
|
+
the A2A `consent_request` data part carries `path` too). The callback stores
|
|
75
|
+
the grant under the conversation's app, and the next message resumes the
|
|
76
|
+
subagent's call. The host allowlist's checks are unchanged. The
|
|
77
|
+
systems_operator template's comment says authorization_code works on its
|
|
78
|
+
Systems subagent (ADR 0118).
|
|
79
|
+
- **Nested dispatch syndicates route as at the top**
|
|
80
|
+
([ADR 0120](./wiki/decisions/0120-nested-dispatch-syndicates-route-as-at-the-top.md)).
|
|
81
|
+
A `yaml_reference` to a plan-dispatch syndicate runs as a turn of its own
|
|
82
|
+
on its own conversation, wherever it appears (a delegated subagent, a
|
|
83
|
+
dispatch route, a workflow node): its classifier picks one of its routes
|
|
84
|
+
and the route answers, under the turn's `max_steps`, deadline and cancel.
|
|
85
|
+
Approvals, `ask_user` questions and OAuth consent on its routes, and
|
|
86
|
+
inside a route's own delegation, pause the turn `input-required` with
|
|
87
|
+
the path (`["Boss", "Team", "Ops"]` delegated, `["Team", "Ops"]` as a
|
|
88
|
+
route), over `runSyndicateTurn` and A2A; the answer resumes that route
|
|
89
|
+
without classifying again. Its grants are stored under the root's app.
|
|
90
|
+
As a workflow node it fails on a consent pause. A route carrying the
|
|
91
|
+
entry's own name, a `map` node over one, and a reference cycle below it
|
|
92
|
+
are refused by name before any model call. Surface:
|
|
93
|
+
`melchizedek-agents/compile` gains the `DispatchSpec` type, a
|
|
94
|
+
`{ kind: 'dispatch'; dispatch: DispatchSpec }` variant on `EntrySpec` and
|
|
95
|
+
`SpecTool`, and an optional `WorkflowSpec.dispatches`; `melchizedek-agents/runtime/turnControl`
|
|
96
|
+
gains the optional `TurnControl.nestedDispatch` hook and the
|
|
97
|
+
`NestedDispatchRun` and `NestedDispatchEnd` types. The generated
|
|
98
|
+
`syndicate.schema.json` describes `yaml_reference` accordingly.
|
|
99
|
+
- **Static credentials go only to hosts the operator binds** (ADR 0122).
|
|
100
|
+
`MELCHIZEDEK_CREDENTIAL_HOSTS="TRACKER_TOKEN=api.tracker.example.com;…"`,
|
|
101
|
+
or `createA2AApp({ credentialHosts })`, binds each credential variable a
|
|
102
|
+
YAML sends (`bearer_env`, `api_key.env`, `client_secret_env`) to its hosts.
|
|
103
|
+
Unset, nothing changes: `melchizedek-serve` warns at boot and
|
|
104
|
+
`melchizedek-doctor` shows a `credentials` warning naming each unbound
|
|
105
|
+
variable. Set, it is the whole list, checked when a syndicate loads, when
|
|
106
|
+
it compiles and before each send; a refused call sends nothing. New
|
|
107
|
+
modules `melchizedek-agents/tools/credentialHosts` and
|
|
108
|
+
`melchizedek-agents/tools/credentialUses` (through the existing
|
|
109
|
+
`./tools/*` export); `openApiServers` in `tools/openapiTools`;
|
|
110
|
+
`DoctorResult.credentials`; the server's banner gains a `creds` line,
|
|
111
|
+
and `oauthServerSetup` returns `credentialSummary`.
|
|
112
|
+
- **`tool_choice:`**, a v2 agent key (ADR 0117): `auto` (the default),
|
|
113
|
+
`none`, `required` (some tool) or `{ name: <tool> }` (that tool). It
|
|
114
|
+
replaces `generateContentConfig.toolConfig.functionCallingConfig`, may not
|
|
115
|
+
sit beside it, and is refused on a `yaml_reference` or `a2a_agent_url`
|
|
116
|
+
subagent. Each provider sends it as before, weakening a forced choice
|
|
117
|
+
where it must (`llm.tool_choice.weakened`).
|
|
118
|
+
- **`reasoning: xhigh` and `reasoning: max`** (ADR 0117). They reach the
|
|
119
|
+
models that take them: both as `output_config.effort` on Claude's adaptive
|
|
120
|
+
generations, `max` on Kimi K3 (and `xhigh` rounds up to it, so K3 can be
|
|
121
|
+
sent `max` again), `xhigh` on GPT-5.2 and later and on grok-4.7. Every
|
|
122
|
+
other path sends the model's highest setting (`high`, Gemini's `HIGH`,
|
|
123
|
+
or `high`'s 16,384-token budget on Claude 4.6 and earlier and Gemini 2.x;
|
|
124
|
+
`high` on a gateway for any id) and marks the `llm.request` span
|
|
125
|
+
`llm.reasoning.weakened` with the level asked for. The capability
|
|
126
|
+
matrix states each path: `REASONING_ABOVE_HIGH`
|
|
127
|
+
(`melchizedek-agents/models/capabilities`), rendered under
|
|
128
|
+
`npm run doctor -- --matrix`.
|
|
129
|
+
- `melchizedek-agents/models/reasoning` exports `effortCeiling(model)`,
|
|
130
|
+
`effortWord(model, setting, ceiling?)`, `isAboveHigh` and
|
|
131
|
+
`REASONING_ORDER`. `ChatCompletionsAdapter` gains the protected hooks
|
|
132
|
+
`reasoningCeiling(model)` and `effortFor(model, setting)`.
|
|
133
|
+
- **A cap on a background job's checkpoint**
|
|
134
|
+
([ADR 0121](./wiki/decisions/0121-checkpoint-cap-and-dispatch-route-resume.md)).
|
|
135
|
+
A checkpoint above `MELCHIZEDEK_CHECKPOINT_MAX_BYTES` (the worker's
|
|
136
|
+
variable; a positive whole number of bytes of JSON, default 5 MiB) is
|
|
137
|
+
not stored: the job keeps its previous checkpoint, the save still reports
|
|
138
|
+
whether the claim holds (a cancel still stops the run), and one log line
|
|
139
|
+
names the job id and the sizes. New in `melchizedek-agents/tools/taskTools`:
|
|
140
|
+
`TaskBackendOptions` (`checkpointMaxBytes`, `log`), `fileTaskBackendWith`,
|
|
141
|
+
`checkpointJson`, `checkpointMaxBytesSetting`, `DEFAULT_CHECKPOINT_MAX_BYTES`
|
|
142
|
+
and `CHECKPOINT_MAX_BYTES_ENV`; `PostgresStorageOptions.taskQueue` passes
|
|
143
|
+
the options to the Postgres queue. The file store's checkpoint sidecar is
|
|
144
|
+
written compact; one written by 1.1.0 still reads.
|
|
145
|
+
- **`melchizedek-setup`, the onboarding command** (new bin; `npm run setup`
|
|
146
|
+
in a clone). A menu of nine authentication levels (no key / local
|
|
147
|
+
Ollama, one provider's key, several, a gateway key, Vertex AI / Bedrock /
|
|
148
|
+
Azure credentials, per-caller keys when serving, caller identities
|
|
149
|
+
through `A2A_AUTH`, OAuth tool grants, and subscription sign-ins), each
|
|
150
|
+
with a startup guide: the variables to set (names and shapes only), the
|
|
151
|
+
doctor check, the shipped templates and examples that run there, and the
|
|
152
|
+
first commands. `--auto` reads the doctor's result and prints the guide
|
|
153
|
+
for the highest level it detects, never a value; `--level <id|n>` prints
|
|
154
|
+
one guide; `--write-env` creates `.env` from `.env.example` with the
|
|
155
|
+
level's names blank, never over an existing file and only when git
|
|
156
|
+
ignores `.env` (ADR 0123).
|
|
157
|
+
- **`ONBOARDING.md`** ships in the package: the same guides, generated from
|
|
158
|
+
the same code (`npm run setup -- --markdown`).
|
|
159
|
+
- **Five onboarding skills** in `skills/`: `melchizedek-onboard` (triage:
|
|
160
|
+
"what do you have?") and `melchizedek-onboard-local`, `-keys`, `-cloud`
|
|
161
|
+
and `-serve`. `npx melchizedek-skills install` puts them in
|
|
162
|
+
`.claude/skills/` and `.agents/skills/` with the rest of the suite.
|
|
163
|
+
- **`melchizedek-skills install --agents-md`** also writes a pointer to the
|
|
164
|
+
skills into the project's `AGENTS.md` (created when absent; only the
|
|
165
|
+
block between its markers is ever rewritten).
|
|
166
|
+
- **The doctor's `serving` line.** When any A2A identity or billing variable
|
|
167
|
+
is set, `npm run doctor` prints the `A2A_AUTH` mode, `A2A_KEY_MODE`,
|
|
168
|
+
which serving variables are set and what the server would refuse to start
|
|
169
|
+
on, by name. `--json` gains `providers` (the providers line as data) and
|
|
170
|
+
`serving`.
|
|
171
|
+
- **`ToolCredentialError.allowlist`** (`melchizedek-agents/tools/auth`,
|
|
172
|
+
with the `HostAllowlist` type): on a `host_refused` error, `'oauth'` when
|
|
173
|
+
the OAuth host allowlist refused a token's host (ADR 0114) and
|
|
174
|
+
`'credential'` when the credential host allowlist refused a client
|
|
175
|
+
secret's (ADR 0122). The constructor takes it as an optional third
|
|
176
|
+
argument.
|
|
177
|
+
|
|
178
|
+
### Changed
|
|
179
|
+
|
|
180
|
+
- **A nested workflow run as a dispatch route or a workflow node pauses the
|
|
181
|
+
turn** ([ADR 0119](./wiki/decisions/0119-workflow-routes-and-nodes-pause-the-turn.md)).
|
|
182
|
+
Its `ask_user` nodes and gated agent nodes (`require_approval`, skill
|
|
183
|
+
scripts) are no longer a load error there: the turn ends `input-required`
|
|
184
|
+
with `result.input` or `result.approval`, whose `path` runs from the route
|
|
185
|
+
or node down to the node that asked (`["Writer", "Send"]`, and further
|
|
186
|
+
down through a node that is itself a nested workflow), over
|
|
187
|
+
`runSyndicateTurn` and A2A. The next message answers it: a decision, or a
|
|
188
|
+
plain-text reply to the question, resumes a paused route without running
|
|
189
|
+
the classifier (`route.decidedBy` `approval` or `answer`); any other
|
|
190
|
+
message while an approval waits repeats the request and runs nothing. A
|
|
191
|
+
workflow node resumes inside the caller's walk. The conversation of a
|
|
192
|
+
paused route ends on the route's pause record (no content, the walk's
|
|
193
|
+
open interrupt ids in `longRunningToolIds`) in place of its answer.
|
|
194
|
+
- `compileEntrySpec` and `compileWorkflowSpec` still accept their
|
|
195
|
+
`delegated` argument; it no longer changes what compiles.
|
|
196
|
+
- **`melchizedek-codemod` converts the rest of `generateContentConfig`**
|
|
197
|
+
(ADR 0117): `toolConfig` becomes `tool_choice:` (mode `ANY` with several
|
|
198
|
+
allowed names becomes `required`, which is what the engine already sent,
|
|
199
|
+
with a note), `reasoningEffort: xhigh | max` becomes `reasoning:`, and
|
|
200
|
+
`thinkingConfig.includeThoughts` is dropped whatever its value: nothing
|
|
201
|
+
reads it, and the Gemini adapter asks for the thought trace whenever
|
|
202
|
+
reasoning is not `none` (a `true` gets a note). Only `toolConfig` mode
|
|
203
|
+
`VALIDATED` and `thinkingBudget: -1` stay, with a note.
|
|
204
|
+
- **The council example's Moderator consults both subagents in one step**
|
|
205
|
+
(`config/agents/examples/council.yaml`). Its instruction asks for the
|
|
206
|
+
Advocate and the Skeptic together, both function calls in one response,
|
|
207
|
+
each given the user's full claim verbatim, so the two run at once under
|
|
208
|
+
`max_concurrency` (ADR 0116). Its role, its three-part verdict and its
|
|
209
|
+
guardrails are unchanged; the YAML keeps its v2 keys. A project that
|
|
210
|
+
copied the example keeps the old prompt until it copies it again.
|
|
211
|
+
- The header comments of `examples/critic.yaml`, `examples/image_production.yaml`
|
|
212
|
+
and `templates/intake_extractor.yaml` say that a schema on a leaf is
|
|
213
|
+
their choice, not a rule: an orchestrator that delegates may hold one
|
|
214
|
+
(ADR 0109). Comments only; the agents are unchanged.
|
|
215
|
+
|
|
216
|
+
### Fixed
|
|
217
|
+
|
|
218
|
+
- **A durable dispatch run resumes inside its agent route** (ADR 0121). A
|
|
219
|
+
background job killed mid-step inside a plan-dispatch route used to start
|
|
220
|
+
over (its checkpoint was set aside); it now resumes from its checkpoint,
|
|
221
|
+
classifying again and storing what an uninterrupted run stores. A nested
|
|
222
|
+
dispatch syndicate's route resumes the same way, and checkpoints 1.1.0
|
|
223
|
+
saved inside a route restore.
|
|
224
|
+
- **An unrecognised `MODEL_GATEWAY` is never echoed.** The doctor (its
|
|
225
|
+
`gateway` line and `--json`), `gatewayProblem()` and the boot log said
|
|
226
|
+
the value back, which may be a key pasted into the wrong variable. They
|
|
227
|
+
now say `MODEL_GATEWAY is set to an unrecognised value (not shown)` and
|
|
228
|
+
name the accepted values (`vercel`, `openrouter`).
|
|
229
|
+
- **A `host_refused` refusal names the allowlist that refused.** A client
|
|
230
|
+
secret refused by the credential host allowlist was reported as the OAuth
|
|
231
|
+
host allowlist's refusal. The message now names
|
|
232
|
+
`MELCHIZEDEK_OAUTH_HOSTS` for a token's host and
|
|
233
|
+
`MELCHIZEDEK_CREDENTIAL_HOSTS` for a client secret's.
|
|
234
|
+
|
|
235
|
+
### Not supported, on purpose
|
|
236
|
+
|
|
237
|
+
- ChatGPT / Codex, Claude.ai and Gemini CLI subscription sign-ins are not a
|
|
238
|
+
way to fund the engine, and nothing reads their tokens. The setup menu's
|
|
239
|
+
level 9 says so and routes to each vendor's API key or cloud platform.
|
|
240
|
+
|
|
241
|
+
## 1.1.0 — 2026-10-09
|
|
242
|
+
|
|
243
|
+
Release 1.1.0 closes workstream 6 of the ADK-independence plan (ADRs
|
|
244
|
+
0109–0116): the first features built on the engine's own loop. An
|
|
245
|
+
orchestrator can delegate and answer in its own JSON schema; a pause inside
|
|
246
|
+
a delegated subagent or a nested syndicate reaches the turn; tools can hold
|
|
247
|
+
OAuth grants declared in YAML, sent only to hosts the operator binds;
|
|
248
|
+
background jobs checkpoint and resume, and cancel works across replicas; a
|
|
249
|
+
step's subagent calls run at once; and the YAML gains provider-neutral v2
|
|
250
|
+
keys, with a codemod. Two fixes: `trace: false` now records nothing, and
|
|
251
|
+
MCP settings on an orchestrator are honoured.
|
|
252
|
+
|
|
253
|
+
### Upgrade
|
|
254
|
+
|
|
255
|
+
Read this list before deploying 1.1.0.
|
|
256
|
+
|
|
257
|
+
1. **Apply migration `0014_durable_runs` before you deploy**
|
|
258
|
+
(`db/migrations/0014_durable_runs.sql`, through `npx melchizedek-db
|
|
259
|
+
apply`) on any server or worker that uses `DATABASE_URL`. Every save
|
|
260
|
+
of the Postgres task stores now writes the new columns
|
|
261
|
+
(`adk_a2a_tasks.cancel_requested_at`, `melchizedek_tasks.checkpoint`),
|
|
262
|
+
so without the migration every Postgres task-store save fails. The A2A
|
|
263
|
+
server refuses to start against a database behind 0014 unless
|
|
264
|
+
`ALLOW_SCHEMA_MISMATCH=true` is set, and with that override its saves
|
|
265
|
+
fail. The migration adds nullable columns only and is safe to re-run.
|
|
266
|
+
2. **New OAuth environment variables** for `melchizedek-serve`, needed
|
|
267
|
+
only when a served syndicate declares an `oauth2` grant:
|
|
268
|
+
`MELCHIZEDEK_OAUTH_HOSTS` (which hosts each provider's tokens may go to),
|
|
269
|
+
`OAUTH_REDIRECT_URI` (the consent callback: https, or http on a loopback
|
|
270
|
+
host) and `OAUTH_CALLBACK_IDENTITY` (`required`, the default, or
|
|
271
|
+
`state`). `MELCHIZEDEK_CREDENTIAL_KEY` keys the credential store.
|
|
272
|
+
3. **`authorization_code` grants are refused until an allowlist is set.**
|
|
273
|
+
With no `MELCHIZEDEK_OAUTH_HOSTS` (or `createA2AApp({ oauthHosts })`), a
|
|
274
|
+
syndicate holding an `authorization_code` grant is refused when served;
|
|
275
|
+
`client_credentials` grants are allowed.
|
|
276
|
+
4. **`max_concurrency` now runs a step's subagent calls at once**, at most
|
|
277
|
+
four by default. Set `max_concurrency: 1` at the root of a delegate
|
|
278
|
+
syndicate to restore the old one-after-another order.
|
|
279
|
+
5. **YAML v2 keys.** `sampling:`, `output:` and `model_overrides:` replace
|
|
280
|
+
`generateContentConfig` and `outputSchema`. The old spellings are
|
|
281
|
+
deprecated, not removed: a v1 file loads and behaves as before, with one
|
|
282
|
+
deprecation line per file per process. `npx melchizedek-codemod
|
|
283
|
+
[--check] <file|dir>…` rewrites v1 files to v2.
|
|
284
|
+
6. **`trace: false` now records nothing.** A turn run with
|
|
285
|
+
`runSyndicateTurn({ trace: false })` writes no telemetry row and exports
|
|
286
|
+
no span. If you relied on its agent, model or tool spans, trace the turn.
|
|
287
|
+
7. **Child sessions are keyed by agent path.** A delegated subagent's
|
|
288
|
+
session is filed under `<app>/<caller>/<subagent>`; conversations stored
|
|
289
|
+
under the old key still resume. Code that reads a subagent's session by
|
|
290
|
+
its name alone reads the path instead.
|
|
291
|
+
8. **The capability matrix has a new member, `structured_output_with_tools`.**
|
|
292
|
+
Code that builds a `Record<Capability, …>` must add it.
|
|
293
|
+
9. **An A2A task cancelled while waiting for the turn lock now ends
|
|
294
|
+
`canceled`**, not `rejected`.
|
|
295
|
+
|
|
296
|
+
### Breaking — read before upgrading
|
|
297
|
+
|
|
298
|
+
- **Breaking: migration 0014 is required** on a Postgres deployment
|
|
299
|
+
(Upgrade item 1).
|
|
300
|
+
- **Breaking: `Capability`, `CAPABILITIES` and `CAPABILITY_MATRIX`
|
|
301
|
+
(`melchizedek-agents/models/capabilities`) gain
|
|
302
|
+
`structured_output_with_tools`**, so an exhaustive
|
|
303
|
+
`Record<Capability, …>` no longer type-checks without it.
|
|
304
|
+
- **Breaking: a step's calls to subagents run concurrently by default**
|
|
305
|
+
(ADR 0116). See Changed; `max_concurrency: 1` keeps the old order.
|
|
306
|
+
- **Breaking: a delegated subagent's own session is filed under its agent
|
|
307
|
+
path** (ADR 0111). See Changed; stored conversations still resume.
|
|
308
|
+
- **Breaking: `runSyndicateTurn({ trace: false })` records nothing**: no
|
|
309
|
+
span of any kind, no ledger row, no export. See Fixed.
|
|
310
|
+
- **Breaking: an A2A task cancelled while it waits for its conversation's
|
|
311
|
+
turn lock ends `canceled`**, not `rejected` (ADR 0113).
|
|
312
|
+
|
|
313
|
+
### Added
|
|
314
|
+
|
|
315
|
+
- **An orchestrator that delegates can answer in its own `outputSchema`**
|
|
316
|
+
(ADR 0109). An agent holding an `outputSchema` beside subagents or tools
|
|
317
|
+
calls them first, then ends its turn on one JSON object matching the
|
|
318
|
+
schema; no relay leaf or `dispatch:` block is needed (plan-dispatch stays
|
|
319
|
+
available). On Claude from Opus 4.8, Sonnet 5 and Haiku 5.5, on every
|
|
320
|
+
OpenAI id, and on Gemini 2 and later through Vertex AI, the schema now
|
|
321
|
+
travels in the provider's own structured-output field in the same request
|
|
322
|
+
as the tools (`output_config.format`, `text.format`, `responseJsonSchema`)
|
|
323
|
+
instead of as a `set_model_response` tool, on the agent's `fallback_model`
|
|
324
|
+
too; every other path keeps `set_model_response`.
|
|
325
|
+
- **The capability matrix gains `structured_output_with_tools`**
|
|
326
|
+
(`melchizedek-agents/models/capabilities`): supported on Anthropic and
|
|
327
|
+
OpenAI (and Gemini on Vertex AI), degraded (`set_model_response`) on the
|
|
328
|
+
Gemini API, xAI, Moonshot, Ollama and the gateway. `npm run doctor` names
|
|
329
|
+
it as a gap for an agent with a schema beside tools on a degraded path.
|
|
330
|
+
`outputSchemaBesideTools(model)` says whether a model's path takes both.
|
|
331
|
+
- **New starter-pack example `config/agents/examples/structured_critic.yaml`**
|
|
332
|
+
(`npm run syndicate:structured-critic`): the critic as one agent, an
|
|
333
|
+
orchestrator on `claude-opus-5-5` that asks a Drafter on
|
|
334
|
+
`claude-haiku-5-5` for a draft and grades it in its own `output.schema`.
|
|
335
|
+
It needs only `ANTHROPIC_API_KEY`.
|
|
336
|
+
- **A pause inside a delegated subagent reaches the turn** (WS6-2a,
|
|
337
|
+
[ADR 0110](./wiki/decisions/0110-pauses-inside-delegated-subagents-reach-the-turn.md)).
|
|
338
|
+
`require_approval` and `ask_user` are allowed on a delegated subagent, and
|
|
339
|
+
gates inside a nested delegate syndicate (`yaml_reference`) no longer fail
|
|
340
|
+
to load. The turn ends `input-required` with the request or question; the
|
|
341
|
+
decision or answer goes back down to the subagent, which finishes before
|
|
342
|
+
its caller continues. Before, a gate there was a load error and a pause
|
|
343
|
+
answered the call with an empty text.
|
|
344
|
+
- `PendingApproval.path` and `PendingInput.path` (optional): the agents from
|
|
345
|
+
the turn's own agent down to the one that asked, set only for a pause
|
|
346
|
+
inside a delegated subagent. The A2A `approval_request` and
|
|
347
|
+
`input_request` data parts carry `path` beside their fields when it is set.
|
|
348
|
+
- **Pauses inside nested syndicates reach the turn** (WS6-2b,
|
|
349
|
+
[ADR 0111](./wiki/decisions/0111-pauses-inside-nested-syndicates.md)). An
|
|
350
|
+
approval request or `ask_user` question raised inside a `yaml_reference`
|
|
351
|
+
subagent ends the turn `input-required` with the agent path, over
|
|
352
|
+
`runSyndicateTurn` and A2A, and the answer resumes it. A nested dispatch
|
|
353
|
+
syndicate may gate its classifier (a gate on one of its routes, which never
|
|
354
|
+
run nested, is refused by name). A nested workflow delegated to as a
|
|
355
|
+
subagent may hold `ask_user` nodes and gated agent nodes; the path ends at
|
|
356
|
+
the node. As a dispatch route or a workflow node, a nested workflow's
|
|
357
|
+
pauses stay refused, with a message that says so.
|
|
358
|
+
- **OAuth grants in YAML (`auth: { oauth2 }`, `mcp_auth: { oauth2 }`;
|
|
359
|
+
ADR 0112).** An `openapi:` entry's `auth` takes a third form, `oauth2`,
|
|
360
|
+
and an agent with `mcp_server_url` may declare `mcp_auth: { oauth2 }`.
|
|
361
|
+
The block names a `provider`, a `grant` (`authorization_code` or
|
|
362
|
+
`client_credentials`), `authorization_url`, `token_url`, `client_id` or
|
|
363
|
+
`client_id_env`, `client_secret_env` and `scopes`; secrets are
|
|
364
|
+
environment variable names, never values, under the same rule as
|
|
365
|
+
`bearer_env`. `authorization_code` sends the run's user's own token
|
|
366
|
+
(`ctx.accessToken`, so the consent pause asks a user who has not granted
|
|
367
|
+
it); `client_credentials` sends the server's own token from the token
|
|
368
|
+
endpoint, held in memory until shortly before it expires. A token goes
|
|
369
|
+
only over https (or http to a loopback host). An authorization-code MCP
|
|
370
|
+
server needs `mcp_tools` and runs each user on their own connection.
|
|
371
|
+
`npm run doctor` lists every tool that needs a grant. New module
|
|
372
|
+
`melchizedek-agents/tools/oauthTools` (`oauthClientsFor`, which builds
|
|
373
|
+
`oauthConsent({ providers })` from the YAML, `oauthRefreshProviders`,
|
|
374
|
+
which gives `credentialStore({ providers })` the matching refresh hooks,
|
|
375
|
+
`clientCredentialsGrant`, `oauthTokenSource`, `tokenTransportProblem`)
|
|
376
|
+
and `melchizedek-agents/tools/credentialEnv` (`credentialEnvProblem`,
|
|
377
|
+
still exported from `tools/openapiTools`), both under the existing
|
|
378
|
+
`./tools/*` export. `OAuthTokenSource` takes the call's destination
|
|
379
|
+
(`(ctx, destination)`), and `oauthTokenSource` accepts several servers.
|
|
380
|
+
`ToolCredentialError` gains the codes `unavailable` and `grant_failed`,
|
|
381
|
+
and `createMcpTools` / `loadMcpTools` an optional second argument. The
|
|
382
|
+
systems_operator template carries a commented `mcp_auth` block.
|
|
383
|
+
- **The OAuth host allowlist (`MELCHIZEDEK_OAUTH_HOSTS`,
|
|
384
|
+
`createA2AApp({ oauthHosts })`; ADR 0114).** The operator binds each
|
|
385
|
+
provider to the hosts its tokens and client secret may be sent to
|
|
386
|
+
(`provider=host,host;…`; `*.domain` for subdomains). With none, an
|
|
387
|
+
`authorization_code` grant is refused and `client_credentials` allowed;
|
|
388
|
+
with one, every grant's provider must be listed and its server, token
|
|
389
|
+
endpoint and authorization endpoint must be that provider's hosts. A
|
|
390
|
+
syndicate that breaks it is refused when served, when compiled and at
|
|
391
|
+
each call (`ToolCredentialError` code `host_refused`). New module
|
|
392
|
+
`melchizedek-agents/tools/oauthHosts` (`parseOAuthHosts`,
|
|
393
|
+
`checkOAuthHosts`, `setOAuthHosts`, `oauthHosts`, `hostAllowed`,
|
|
394
|
+
`oauthHostProblem`) under the existing `./tools/*` export;
|
|
395
|
+
`tools/oauthTools` gains `oauthGrantHostProblems`, `oauthCallProblem`,
|
|
396
|
+
`syndicateOAuthGrants` and `syndicateOAuthHostProblems`, and
|
|
397
|
+
`oauthClientsFor` an `allowlist` option.
|
|
398
|
+
- **`melchizedek-serve` wires tool credentials and the consent step**
|
|
399
|
+
from `MELCHIZEDEK_CREDENTIAL_KEY` (rows in Postgres with `DATABASE_URL`,
|
|
400
|
+
else process memory), `OAUTH_REDIRECT_URI`, `OAUTH_CALLBACK_IDENTITY`
|
|
401
|
+
(`required`, the default, or `state`) and `MELCHIZEDEK_OAUTH_HOSTS`, with
|
|
402
|
+
the consent clients and refresh hooks built from the served syndicate
|
|
403
|
+
files. `melchizedek-agents/server` exports `serverOAuth` and
|
|
404
|
+
`servedFileSyndicates`. `npm run doctor` prints an `oauth` line (which
|
|
405
|
+
variables are set, and each problem by name) and each grant's host
|
|
406
|
+
refusals; `--check` fails on an OAuth problem.
|
|
407
|
+
- **Durable long-running runs** (WS6-5, ADR 0113):
|
|
408
|
+
- **The worker resumes a job instead of starting over.**
|
|
409
|
+
`melchizedek-worker` checkpoints each job's sessions beside the job at
|
|
410
|
+
every step boundary (Postgres: the `checkpoint` column; the JSON store:
|
|
411
|
+
`<store>.checkpoints.json`). A job claimed again after its worker
|
|
412
|
+
stopped resumes from its last checkpoint. A dispatch syndicate
|
|
413
|
+
checkpointed inside an agent route starts over, and its classifier runs
|
|
414
|
+
again.
|
|
415
|
+
- **SIGTERM re-queues the job in hand** with its checkpoint, so the next
|
|
416
|
+
worker finishes it. Before, the job was recorded as failed.
|
|
417
|
+
- **A running background job can be cancelled.** `task_update` with
|
|
418
|
+
`status: cancelled` now accepts a running job. The worker stops at its
|
|
419
|
+
next lease renewal or checkpoint save and writes no result.
|
|
420
|
+
- **A2A cancel works across replicas**
|
|
421
|
+
(`melchizedek-agents/storage/postgres`): a `tasks/cancel` that reaches a
|
|
422
|
+
replica not running the task answers `canceled` and records the
|
|
423
|
+
request; the replica holding the task's lease aborts the run on its
|
|
424
|
+
lease heartbeat; the stored task stays `canceled`; the reaper keeps a
|
|
425
|
+
cancel that was already reported. New:
|
|
426
|
+
`PostgresTaskStore.requestCancel(taskId, context)`, the optional
|
|
427
|
+
`leases.cancelRequested` on `postgresStorage()`, and the optional
|
|
428
|
+
`storage.leases.cancelRequested` option of `createA2AApp`.
|
|
429
|
+
- **`TaskBackend` (`melchizedek-agents/tools/taskTools`), additive only:**
|
|
430
|
+
new optional members `saveCheckpoint` and `loadCheckpoint`; `renew` may
|
|
431
|
+
resolve `false` when the claim is gone; new export `taskCheckpointPath`.
|
|
432
|
+
A backend you wrote yourself still type-checks. It just does not
|
|
433
|
+
checkpoint.
|
|
434
|
+
- **YAML schema v2: provider-neutral keys** (WS6-4, ADR 0115).
|
|
435
|
+
`sampling: { temperature, top_p, max_output_tokens, stop }`,
|
|
436
|
+
`output: { schema, mime }` (`application/json` or `text/plain`) and
|
|
437
|
+
`reasoning:` (ADR 0047) replace `generateContentConfig` and
|
|
438
|
+
`outputSchema`. `model_overrides.<provider>` (`gemini`, `anthropic`,
|
|
439
|
+
`openai`, `xai`, `moonshot`, `ollama`) gives one provider its own
|
|
440
|
+
`instruction` or an `instruction_append`, applied for the provider the
|
|
441
|
+
agent's model routes to.
|
|
442
|
+
- **New bin `melchizedek-codemod [--check] <file|dir>…`** rewrites v1 YAML
|
|
443
|
+
into v2, keeping comments and layout; idempotent; `--check` exits
|
|
444
|
+
non-zero when a file would change. A registry row is migrated by running
|
|
445
|
+
it on the file it was published from and republishing.
|
|
446
|
+
- **`LoadSyndicateOptions.onWarning`** receives the v1 deprecation line
|
|
447
|
+
(default `console.warn`). The agent YAML types (`AgentYamlConfig`,
|
|
448
|
+
`SubagentYamlConfig`) gain `sampling`, `output` and `model_overrides`.
|
|
449
|
+
- **`max_concurrency`**, a new optional root key of a delegate syndicate:
|
|
450
|
+
a positive integer up to 32, default 4 (ADR 0116). See Changed.
|
|
451
|
+
- **`turnUntraced()`** (`melchizedek-agents/runtime/turnControl`) says
|
|
452
|
+
whether the running code belongs to a turn that opted out of tracing;
|
|
453
|
+
`createTurnControl` takes `untraced`, and `TurnControl` carries it.
|
|
454
|
+
**`startEngineSpan(tracerName, name, options?)`**
|
|
455
|
+
(`melchizedek-agents/observability/tracer`) starts a span the way the
|
|
456
|
+
engine does: a non-recording one, without starting the tracer, inside an
|
|
457
|
+
untraced turn.
|
|
458
|
+
- Engine internals with no exports map entry: `delegatedPauses`,
|
|
459
|
+
`openCalls`, `resumedDelegations` in `lib/runtime/native/interrupts.ts`;
|
|
460
|
+
`resumeSubagent`, `SubagentPause`, `resumeWorkflowSubagent`,
|
|
461
|
+
`childAppName`, `legacyChild` in `lib/runtime/native/delegate.ts`;
|
|
462
|
+
`runDurableTurn`, `checkpointingSessions` in
|
|
463
|
+
`lib/runtime/native/checkpoint.ts` (the worker's runner).
|
|
464
|
+
|
|
465
|
+
### Changed
|
|
466
|
+
|
|
467
|
+
- **A step's calls to subagents run at once** (ADR 0116). When an
|
|
468
|
+
orchestrator's model calls several subagents in one step (the council's
|
|
469
|
+
Advocate and Skeptic, say), they now run concurrently instead of one after
|
|
470
|
+
another, at most `max_concurrency` at a time (default 4).
|
|
471
|
+
`max_concurrency: 1` keeps the old order. Two calls to the same subagent
|
|
472
|
+
in one step still run one after the other on its one session. The stored
|
|
473
|
+
responses stay in call order whatever order the subagents finish in, so
|
|
474
|
+
stored history does not change; a pause, a cancel, `max_steps` and durable
|
|
475
|
+
checkpoints keep their rules. The key is refused beside `workflow:` (use
|
|
476
|
+
`workflow.max_concurrency`) and `dispatch:`. Other tool calls are
|
|
477
|
+
unchanged.
|
|
478
|
+
- **A delegated subagent's own session is filed under its agent path**
|
|
479
|
+
(WS6-2b, ADR 0111): `<app>/<caller>/<subagent>`, and below a nested
|
|
480
|
+
syndicate `<app>/<caller>/<subagent>/<inner>`, instead of the subagent's
|
|
481
|
+
name alone, so two syndicates with a same-named subagent on one
|
|
482
|
+
conversation no longer share it. A conversation stored before keeps its
|
|
483
|
+
subagents' sessions under the old key: they are still read, continued and
|
|
484
|
+
resumed. Code that read a subagent's session directly by its name reads
|
|
485
|
+
the path instead. The stored events do not change.
|
|
486
|
+
- **`generateContentConfig` and `outputSchema` are deprecated, not
|
|
487
|
+
removed** (ADR 0115). A v1 file loads and behaves exactly as before; each
|
|
488
|
+
load that finds them prints one line, once per file or registry id per
|
|
489
|
+
process, naming the key paths (never their values). A v2 key beside its
|
|
490
|
+
v1 spelling on one agent (`sampling.temperature` with
|
|
491
|
+
`generateContentConfig.temperature`, `output.schema` with
|
|
492
|
+
`outputSchema`, …) is a load error. `toolConfig` and the effort words
|
|
493
|
+
`xhigh` and `max` have no v2 key yet and stay readable there.
|
|
494
|
+
`syndicate.schema.json` marks both keys `deprecated`. The loader (and
|
|
495
|
+
`validateSyndicateConfig`) returns the engine form: `sampling` and
|
|
496
|
+
`output` arrive folded into `generateContentConfig` and `outputSchema`.
|
|
497
|
+
- **Every shipped example, template, the annotated `syndicateSchema.yaml`
|
|
498
|
+
and the author skill's `minimal.yaml` are in the v2 spelling.** Copies of
|
|
499
|
+
them keep working either way. The `ares` example's search agent now says
|
|
500
|
+
`reasoning: none` (`thinkingLevel: MINIMAL` on Gemini 3) where it said
|
|
501
|
+
`thinkingBudget: 0`.
|
|
502
|
+
- **An A2A task cancelled during the turn-lock wait** now ends `canceled`,
|
|
503
|
+
not `rejected` (ADR 0113).
|
|
504
|
+
- **An OpenAPI `auth` that sets two forms** now reads "exactly one of
|
|
505
|
+
bearer_env, api_key or oauth2" (was "exactly one of bearer_env or
|
|
506
|
+
api_key").
|
|
507
|
+
- **The authoring skill (`skills/melchizedek-author`) allows an
|
|
508
|
+
`output: { schema }` on an orchestrator that delegates** when the answer
|
|
509
|
+
is the orchestrator's own structured judgment (ADR 0109), and points at
|
|
510
|
+
`structured_critic.yaml`; a schema on a leaf stays the choice when the
|
|
511
|
+
user should receive a specialist's answer.
|
|
512
|
+
|
|
513
|
+
### Fixed
|
|
514
|
+
|
|
515
|
+
- **`runSyndicateTurn({ trace: false })` records nothing.** It used to drop
|
|
516
|
+
only the turn's root span: the agent, model-step, `llm.request` and tool
|
|
517
|
+
spans still started the global tracer, so with `TELEMETRY_SUPABASE=true`
|
|
518
|
+
an untraced turn still wrote `adk_telemetry` rows (and could write
|
|
519
|
+
`adk_payloads` rows), and with `OTEL_EXPORTER_OTLP_ENDPOINT` set it still
|
|
520
|
+
exported. Now a turn with `trace: false` opens no span of any kind, sends
|
|
521
|
+
nothing to the ledger, the console exporter, `onSpanEnd` listeners or an
|
|
522
|
+
OTLP endpoint, and does not start the tracer. Its step budget and its
|
|
523
|
+
`usage` are unchanged. The default (traced) is unchanged, and the A2A
|
|
524
|
+
server and the chat bin trace as before.
|
|
525
|
+
- **`mcp_server_url` and `mcp_tools` on the orchestrator are honoured.**
|
|
526
|
+
The schema accepted them there, but only subagents read them, so a
|
|
527
|
+
one-agent syndicate with an MCP server on its orchestrator got no MCP
|
|
528
|
+
tools and no warning. The orchestrator now resolves them as a subagent
|
|
529
|
+
does (narrowed by `mcp_tools`, gateable by its `require_approval`). On a
|
|
530
|
+
plan-dispatch syndicate the orchestrator is the classifier, and an MCP
|
|
531
|
+
server declared there is now dialled at compile time.
|
|
532
|
+
|
|
9
533
|
## 1.0.3 — 2026-10-09
|
|
10
534
|
|
|
11
535
|
Dependency updates and one packaging fix. No export, bin, YAML key or
|