melchizedek-agents 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +78 -0
- package/DOCUMENTATION.md +11 -9
- package/config/agents/examples/critic.yaml +12 -7
- package/config/agents/examples/image_production.yaml +2 -2
- package/config/agents/examples/librarian.yaml +1 -1
- package/config/agents/examples/pipeline.yaml +1 -1
- package/config/agents/examples/research.yaml +3 -2
- package/config/agents/examples/scribe.yaml +5 -4
- package/config/agents/examples/weather.yaml +2 -1
- package/config/agents/syndicate.schema.json +1191 -0
- package/config/agents/syndicateSchema.yaml +18 -15
- package/dist/lib/dispatch.d.ts +4 -4
- package/dist/lib/dispatch.js +4 -4
- package/dist/lib/syndicateSchema.js +6 -6
- package/package.json +7 -6
- package/skills/briefs/melchizedek-author.md +1 -1
- package/skills/melchizedek-author/SKILL.md +1 -1
- package/skills/melchizedek-author/assets/minimal.yaml +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,84 @@ the starter pack and the templates), not the repo's full history.
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## 1.0.3 — 2026-10-09
|
|
10
|
+
|
|
11
|
+
Dependency updates and one packaging fix. No export, bin, YAML key or
|
|
12
|
+
adapter behaviour changes; no source file under `lib/` changes.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- **`config/agents/syndicate.schema.json` ships in the package.** The
|
|
17
|
+
shipped `config/agents/syndicateSchema.yaml` names it in its
|
|
18
|
+
`yaml-language-server` modeline, and `melchizedek-init` locates the
|
|
19
|
+
package root by it; it was missing from `files`, so editors could not
|
|
20
|
+
resolve the schema and, in an installed package, `melchizedek-init`
|
|
21
|
+
stopped with "config/agents/ not found next to this package".
|
|
22
|
+
`tests/packageSurface.test.ts` now checks that `files` ships it and
|
|
23
|
+
every shipped modeline's target.
|
|
24
|
+
|
|
25
|
+
### Changed — dependencies
|
|
26
|
+
|
|
27
|
+
- `@anthropic-ai/sdk` ^0.129.0 → ^0.131.0. Additive (Admin and Managed
|
|
28
|
+
Agents endpoints). The SDK now marks `claude-sonnet-4-5` and
|
|
29
|
+
`claude-sonnet-4-5-20250929` deprecated (end of life 2026-11-30) and
|
|
30
|
+
logs a `console.warn` when a request names them; no shipped syndicate
|
|
31
|
+
uses either id.
|
|
32
|
+
- `openai` ^7.23.0 → ^7.28.0. Additive (Agents, Realtime, Responses
|
|
33
|
+
WebSocket features). The client now keeps a base URL's query string
|
|
34
|
+
when joining endpoints; this reaches the GPT adapter only when
|
|
35
|
+
an `OPENAI_BASE_URL` carries a query (the Azure and xAI base URLs carry none;
|
|
36
|
+
the Kimi, Ollama and gateway adapters do not use the SDK).
|
|
37
|
+
- `@modelcontextprotocol/sdk` ^1.29.0 → ^1.32.1 (lock 1.31.0 → 1.32.1).
|
|
38
|
+
The SDK's HTTP client transports now follow redirects only within the
|
|
39
|
+
endpoint's origin unless `redirectPolicy: 'follow'` is set. The MCP
|
|
40
|
+
client's own fetch (`mcpFetch`, `lib/net/redirects.ts`) already follows
|
|
41
|
+
every hop itself under `MCP_REDIRECTS`, so the SDK sees the final
|
|
42
|
+
response and redirect behaviour is unchanged.
|
|
43
|
+
- `@google/genai` 2.25.0 → 2.27.0, still pinned exact. Additive
|
|
44
|
+
(`continuation_token` in GenerateContent and Interactions, new model
|
|
45
|
+
enum values).
|
|
46
|
+
- `@types/node` ^22 → ^25 (dev only). `engines.node` stays `>=22.6.0`; the
|
|
47
|
+
source type-checks against both the Node 22 and Node 25 types.
|
|
48
|
+
- Dockerfile base image `node:22-slim` → `node:25-slim`, pinned by digest.
|
|
49
|
+
|
|
50
|
+
## 1.0.2 — 2026-10-09
|
|
51
|
+
|
|
52
|
+
A test and documentation patch. Nothing a consumer imports, configures or
|
|
53
|
+
runs changes behaviour, and no YAML key is added, removed or renamed.
|
|
54
|
+
|
|
55
|
+
### Fixed
|
|
56
|
+
|
|
57
|
+
- **`npm test`, and so `npm publish`, pass again from 2026-10-09.** The
|
|
58
|
+
harness-example parity test (`tests/skillHarness.test.ts`) compared a
|
|
59
|
+
native run against a recording made on 2026-10-08, and the
|
|
60
|
+
`{{current_date}}` the example's instruction resolves moved with the
|
|
61
|
+
clock, so from 2026-10-09 the comparison failed. The test now pins
|
|
62
|
+
`current_date` to the recording's date.
|
|
63
|
+
- **The SIGTERM test holds under load.** `tests/serverShutdown.test.ts`
|
|
64
|
+
waits up to 30 seconds for the server to start, polls for readiness to
|
|
65
|
+
fail after the signal instead of checking once after a fixed 300 ms,
|
|
66
|
+
and runs with a 3-second delay and a 6-second grace budget, so a busy
|
|
67
|
+
machine no longer fails it on timing.
|
|
68
|
+
|
|
69
|
+
### Changed
|
|
70
|
+
|
|
71
|
+
- **Wording only: the shipped files describe the engine, not ADK.** The
|
|
72
|
+
example syndicates' comments (`critic.yaml`, `scribe.yaml`,
|
|
73
|
+
`research.yaml`, `image_production.yaml`, `librarian.yaml`,
|
|
74
|
+
`weather.yaml`, `pipeline.yaml`), `config/agents/syndicateSchema.yaml`,
|
|
75
|
+
`DOCUMENTATION.md` and the `melchizedek-author` skill no longer describe
|
|
76
|
+
Google ADK as running or enforcing anything; ADK appears only as history
|
|
77
|
+
or as the origin of a key's spelling. The rule that an `outputSchema`
|
|
78
|
+
belongs on a leaf is stated as what it is: the engine accepts the schema
|
|
79
|
+
on an agent that delegates, and that agent then answers with the JSON
|
|
80
|
+
instead of relaying a subagent's answer. The same wording reaches the
|
|
81
|
+
schema descriptions in `lib/syndicateSchema.ts` and the generated
|
|
82
|
+
`config/agents/syndicate.schema.json` (`outputSchema`, the root agent,
|
|
83
|
+
the workflow `retry` defaults, `retries`), and the reserved-name message
|
|
84
|
+
for an agent called `user`. No key, default or behaviour changes;
|
|
85
|
+
`thinkingBudget` and the other older spellings are still accepted.
|
|
86
|
+
|
|
9
87
|
## 1.0.1 — 2026-10-08
|
|
10
88
|
|
|
11
89
|
### Fixed
|
package/DOCUMENTATION.md
CHANGED
|
@@ -141,7 +141,7 @@ Field reference:
|
|
|
141
141
|
| `yaml_reference` | subagent | Mount another syndicate file as a nested subagent. |
|
|
142
142
|
| `a2a_agent_url` | subagent | A REMOTE agent over A2A (§6): the orchestrator delegates to it with one `request` argument; in plan-dispatch it can be a route. No `model`/`instruction` — the remote agent has its own. Credentials come from `A2A_AGENT_TOKENS`, never YAML. |
|
|
143
143
|
| `max_steps` | root | Cap on model calls per turn, counted across every agent the turn reaches (orchestrator, subagents, nested syndicates). Exceeding it fails the turn with `STEP_LIMIT`. |
|
|
144
|
-
| `includeContents` / `outputKey` / `globalInstruction` / `disallowTransferToParent` / `disallowTransferToPeers` | agent | Passed through to the agent (
|
|
144
|
+
| `includeContents` / `outputKey` / `globalInstruction` / `disallowTransferToParent` / `disallowTransferToPeers` | agent | Passed through to the agent (spelled after ADK's `LlmAgent` fields). `includeContents: none` makes an agent see only the current message. |
|
|
145
145
|
| `fallback_model` | any agent | A model, ideally on another provider, that answers when this agent's model fails provider-side (5xx, 429, a connection reset, after its own retries) before producing any output, or while that provider's circuit is open: after `MODEL_BREAKER_THRESHOLD` consecutive provider failures (default 5; 0 disables) the provider is skipped for `MODEL_BREAKER_COOLDOWN_MS` (default 30 s). A 4xx and a canceled turn are never redirected, and a stream that already produced text is never replayed elsewhere ([ADR 0044](./wiki/decisions/0044-fallback-model-and-circuit-breaker.md)). |
|
|
146
146
|
| `mcp_tools` | subagent | The MCP server's tools this agent may use; any other tool the server lists is not exposed. On a dispatch route `require_approval` may name them ([ADR 0041](./wiki/decisions/0041-tool-vendors-get-least-privilege.md)). |
|
|
147
147
|
| `mcp_server_url` | subagent | Discover this subagent's tools from a remote MCP server at load time (§3). SSRF-guarded; `ALLOW_PRIVATE_MCP=true` permits localhost for development. |
|
|
@@ -178,7 +178,7 @@ function, and every adapter recognises it by marker
|
|
|
178
178
|
| `google_search` | Gemini built-in | Live web search — Gemini agents only (legacy alias; use `web_search`). |
|
|
179
179
|
| `preload_memory` | Instruction tool | Silently injects similarity-matched facts into every request's instruction (ambient recall). The model never calls it. |
|
|
180
180
|
| `load_memory` | Contract | Explicit tool call to search the fact store (deliberate recall). Both memory tools read the caller's own silo only and send the model what ADK's tools of the same names sent ([ADR 0059](./wiki/decisions/0059-memory-on-the-engines-own-interfaces.md)). |
|
|
181
|
-
| `generate_image` | Contract | Calls the Gemini image model directly, saves the result under `outputs/`, returns the path. A function tool because binary `inlineData` cannot survive
|
|
181
|
+
| `generate_image` | Contract | Calls the Gemini image model directly, saves the result under `outputs/`, returns the path. A function tool because binary `inlineData` cannot survive delegation, where a subagent returns only its final text. |
|
|
182
182
|
| `inspect_image` | Contract | **Blind visual inventory** of a file under `outputs/`: subjects with exact counts, composition, light, palette, medium cues, artifacts — zero quality judgments. Its signature accepts *only* a file path, so an orchestrator cannot leak expectations into the observation (see `image_production.yaml`). |
|
|
183
183
|
| `task_add` / `task_list` / `task_get` / `task_update` | Contract | A to-do list and job queue. Default: a single-user JSON file (`MELCHIZEDEK_TASKS_FILE`, default `outputs/tasks.json`), so every caller of a shared endpoint shares one list. With `DATABASE_URL` (migration 0009) each caller has its own list, scoped by the caller's scope key, and any number of workers take jobs safely. |
|
|
184
184
|
| `ask_user` | Contract, long-running | Asks the person one question (optionally with `options`) and ends the turn `input-required`; the next message on the conversation is the call's result. Orchestrator or plan-dispatch route only (§6, Questions). |
|
|
@@ -575,7 +575,7 @@ Model floor: agent transfer (subagent delegation) requires
|
|
|
575
575
|
`gemini-3.8-flash` or newer — older flash models reject it with
|
|
576
576
|
`[400] Tool call context circulation is not enabled`. For `ollama/*`
|
|
577
577
|
agents the equivalent floor is tool-calling support in the model
|
|
578
|
-
itself; delegation
|
|
578
|
+
itself; delegation runs through ordinary function calls to the subagent tools.
|
|
579
579
|
|
|
580
580
|
## 6. A2A service mode
|
|
581
581
|
|
|
@@ -1055,7 +1055,7 @@ user:
|
|
|
1055
1055
|
|
|
1056
1056
|
| | DELEGATE (default) | PLAN-DISPATCH (`dispatch:` present) |
|
|
1057
1057
|
|---|---|---|
|
|
1058
|
-
| Subagents are |
|
|
1058
|
+
| Subagents are | tools on the orchestrator | plain configs the server selects from |
|
|
1059
1059
|
| Orchestrator holds | subagent tools, no `outputSchema` | an `outputSchema`, no subagent tools |
|
|
1060
1060
|
| Routing decision is | implicit in which tool it calls | an explicit value in code |
|
|
1061
1061
|
| The final answer comes from | the orchestrator re-emitting the answer | **the specialist itself** |
|
|
@@ -1089,9 +1089,11 @@ emitted the bare tool name in place of a 2,599-character answer.
|
|
|
1089
1089
|
Plan-dispatch has no relay turn to fail, and the classifier's output
|
|
1090
1090
|
shrinks from a whole relayed answer to ~15 tokens of JSON.
|
|
1091
1091
|
|
|
1092
|
-
**Why the classifier is tool-less.**
|
|
1093
|
-
with
|
|
1094
|
-
|
|
1092
|
+
**Why the classifier is tool-less.** An agent that holds an
|
|
1093
|
+
`outputSchema` answers with that JSON and nothing else, so the schema sits
|
|
1094
|
+
on a leaf that delegates nothing (see `config/agents/examples/critic.yaml`,
|
|
1095
|
+
whose header also tells how an orchestrator holding both deadlocked on
|
|
1096
|
+
ADK before 1.0.0).
|
|
1095
1097
|
That constraint shapes the method: the classifier is a leaf, and the
|
|
1096
1098
|
hand-off happens in code, where it can be logged, traced, and streamed
|
|
1097
1099
|
to the user as progress.
|
|
@@ -1100,8 +1102,8 @@ to the user as progress.
|
|
|
1100
1102
|
one transcript accumulates across routes and long-term memory ingests
|
|
1101
1103
|
real answers instead of a relay copy of them. Sharing the session is
|
|
1102
1104
|
necessary but not sufficient: a stored event is rendered by comparing
|
|
1103
|
-
`event.author` against the agent now running (ADK
|
|
1104
|
-
loop keeps), and under plan-dispatch
|
|
1105
|
+
`event.author` against the agent now running (the rule ADK had, which the
|
|
1106
|
+
engine's loop keeps), and under plan-dispatch
|
|
1105
1107
|
every route is its own root agent, so the whole history fails that
|
|
1106
1108
|
comparison and `convertForeignEvent` rewrites it to `role: "user"`
|
|
1107
1109
|
prefixed "For context:". A route reading the raw shared session
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
# tier: gemini — needs only GOOGLE_GENAI_API_KEY; `npm run doctor` shows what each key unlocks.
|
|
2
2
|
syndicate_name: "Critic Review Workflow"
|
|
3
3
|
|
|
4
|
-
# WHY this structure:
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
4
|
+
# WHY this structure: an agent with an outputSchema answers in that schema and
|
|
5
|
+
# nothing else. On an orchestrator that delegates, the engine (on most
|
|
6
|
+
# models) adds a set_model_response tool beside the subagent tools and the
|
|
7
|
+
# turn ends on the JSON it receives (lib/runtime/native/request.ts), so the
|
|
8
|
+
# user would get the review object instead of the answer; under Google ADK,
|
|
9
|
+
# before 1.0.0, an orchestrator holding both deadlocked. Solution: the
|
|
10
|
+
# orchestrator is a plain sequencer that routes Drafter → Critic, and the
|
|
11
|
+
# CriticAgent (a leaf with no tools and no subagents) owns the outputSchema
|
|
12
|
+
# for structured JSON production.
|
|
9
13
|
#
|
|
10
14
|
# WHY multi-turn internal looping:
|
|
11
|
-
# The
|
|
12
|
-
# orchestrator continues to call tools rather than producing a final
|
|
15
|
+
# The engine's agent loop keeps executing within a single user turn as long
|
|
16
|
+
# as the orchestrator continues to call tools rather than producing a final
|
|
17
|
+
# response (lib/runtime/native/agentLoop.ts, capped by max_steps).
|
|
13
18
|
# By instructing the orchestrator to inspect the CriticAgent's confidence score
|
|
14
19
|
# and re-delegate when it's below a threshold, the syndicate autonomously
|
|
15
20
|
# refines answers through multiple Drafter→Critic passes — all within one
|
|
@@ -16,8 +16,8 @@ memory_system: "session-only"
|
|
|
16
16
|
# path — the spec physically cannot reach the inventory, so expectation bias
|
|
17
17
|
# is blocked by the tool signature, not by good intentions. SpecAuditor is a
|
|
18
18
|
# text-only leaf that receives spec + inventory but never the image, and
|
|
19
|
-
# holds the outputSchema (same
|
|
20
|
-
#
|
|
19
|
+
# holds the outputSchema (the same rule as critic.yaml: the schema-holder
|
|
20
|
+
# is a leaf that delegates nothing). Perception, judgment, and decision are three
|
|
21
21
|
# different minds.
|
|
22
22
|
#
|
|
23
23
|
# WHY the instruction maps payload fields to tool parameters by name
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# subagent declares NO tools of its own — its entire capability
|
|
8
8
|
# arrives at runtime from an MCP server (mcp_server_url below).
|
|
9
9
|
# The framework dials the server, asks "what tools do you offer?",
|
|
10
|
-
# and wraps each answer as a live
|
|
10
|
+
# and wraps each answer as a live engine tool (lib/tools/mcpToolFactory.ts).
|
|
11
11
|
#
|
|
12
12
|
# That is the point of MCP: the agent's reach is no longer fixed
|
|
13
13
|
# at design time. Point the same agent at a different server and
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
# what they produce, edit it, ask the person, then publish". A
|
|
10
10
|
# `workflow:` block says exactly that: the agents below are the
|
|
11
11
|
# nodes of a graph, and `edges` says what runs after what
|
|
12
|
-
# (lib/workflow.ts;
|
|
12
|
+
# (lib/workflow.ts; the engine's own scheduler, lib/workflow/, runs it).
|
|
13
13
|
#
|
|
14
14
|
# START → Planner ─(article)→ Writer ──┐
|
|
15
15
|
# │ ├→ Both → Editor → Confirm → Publisher
|
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
# SHAPE: plan-dispatch (lib/dispatch.ts). A small triage model names one of
|
|
13
13
|
# three routes, and that route's output IS the answer. Each route HOLDS its
|
|
14
14
|
# own tools instead of delegating to researcher subagents. That choice is
|
|
15
|
-
# deliberate:
|
|
16
|
-
# output from a delegated subagent
|
|
15
|
+
# deliberate: the engine's subagent tool returns only a subagent's final text
|
|
16
|
+
# (lib/runtime/native/delegate.ts), so tool output from a delegated subagent
|
|
17
|
+
# never reaches the outer stream, and the
|
|
17
18
|
# `science` guard below checks the answer against exactly that output. When
|
|
18
19
|
# the answering route makes the calls itself, every identifier it cites is
|
|
19
20
|
# on its own stream. It also means an A2A client sees each tool call live.
|
|
@@ -36,10 +36,11 @@
|
|
|
36
36
|
# the two lists lived apart they drifted, and drafts failed rules the
|
|
37
37
|
# writer had never been given. Edit the rule in one place.
|
|
38
38
|
#
|
|
39
|
-
# WHY the orchestrator has no outputSchema:
|
|
40
|
-
#
|
|
41
|
-
# contract sits on the Auditor (the
|
|
42
|
-
# plain text. See critic.yaml for the
|
|
39
|
+
# WHY the orchestrator has no outputSchema: an agent that holds
|
|
40
|
+
# one answers in that JSON and nothing else, and the Scribe's answer
|
|
41
|
+
# is the document. So the JSON contract sits on the Auditor (the
|
|
42
|
+
# leaf) and the Scribe returns plain text. See critic.yaml for the
|
|
43
|
+
# same rule.
|
|
43
44
|
#
|
|
44
45
|
# Run it: npm run syndicate:scribe
|
|
45
46
|
# npm run syndicate:scribe -- "$(cat brief.md)" # one shot
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
# that uses it. No tool code: the `openapi:` list below points at two
|
|
8
8
|
# spec files, and every operation in them becomes a tool, its
|
|
9
9
|
# parameters the tool's arguments and its summary the description the
|
|
10
|
-
# model reads (lib/tools/openapiTools.ts
|
|
10
|
+
# model reads (lib/tools/openapiTools.ts, the engine's own parser and
|
|
11
|
+
# caller, by the rules ADK's OpenAPIToolset had).
|
|
11
12
|
#
|
|
12
13
|
# The specs are hand-written subsets of Open-Meteo's free, keyless
|
|
13
14
|
# APIs (specs/): find a place, then forecast its weather. Swap in
|