melchizedek-agents 1.11.0 → 1.12.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 +53 -10
- package/AGENT_SETUP.md +4 -1
- package/CHANGELOG.md +126 -0
- package/DOCUMENTATION.md +108 -7
- package/ONBOARDING.md +11 -5
- package/QUICKSTART.md +5 -3
- package/README.md +7 -4
- package/config/agents/examples/classifier.yaml +104 -0
- package/config/agents/examples/model_zoo.yaml +5 -0
- package/config/agents/syndicate.schema.json +59 -1
- package/config/agents/syndicateSchema.yaml +9 -1
- package/db/hardening.sql +5 -0
- package/db/migrations/0020_embedding_flash_grok_pricing.sql +38 -0
- package/db/migrations/0021_correct_gemini_flash_grok_rates.sql +46 -0
- package/db/migrations/0022_typesafe_jev_pricing.sql +36 -0
- package/db/migrations/0023_memory_embedder.sql +66 -0
- package/dist/lib/config.d.ts +6 -0
- package/dist/lib/config.js +6 -0
- package/dist/lib/doctor.d.ts +8 -0
- package/dist/lib/doctor.js +17 -0
- package/dist/lib/loadSyndicate.d.ts +1 -1
- package/dist/lib/memory/providers.d.ts +31 -0
- package/dist/lib/memory/providers.js +82 -2
- package/dist/lib/memory/reembed.d.ts +47 -0
- package/dist/lib/memory/reembed.js +71 -0
- package/dist/lib/memory/store.d.ts +22 -0
- package/dist/lib/memory/store.js +33 -0
- package/dist/lib/memory/supabaseMemoryService.d.ts +17 -0
- package/dist/lib/memory/supabaseMemoryService.js +55 -1
- package/dist/lib/model.d.ts +4 -0
- package/dist/lib/model.js +3 -0
- package/dist/lib/models/adapterResolver.js +5 -2
- package/dist/lib/models/capabilities.d.ts +2 -0
- package/dist/lib/models/capabilities.js +28 -6
- package/dist/lib/models/chatCompletionsAdapter.d.ts +6 -1
- package/dist/lib/models/chatCompletionsAdapter.js +35 -6
- package/dist/lib/models/contract.d.ts +7 -1
- package/dist/lib/models/endpoints.d.ts +3 -2
- package/dist/lib/models/endpoints.js +6 -2
- package/dist/lib/models/gateway.d.ts +123 -7
- package/dist/lib/models/gateway.js +204 -22
- package/dist/lib/models/gatewayAdapter.d.ts +17 -6
- package/dist/lib/models/gatewayAdapter.js +28 -10
- package/dist/lib/models/jev.d.ts +190 -0
- package/dist/lib/models/jev.js +316 -0
- package/dist/lib/models/jevAdapter.d.ts +79 -0
- package/dist/lib/models/jevAdapter.js +136 -0
- package/dist/lib/models/providerMap.d.ts +2 -1
- package/dist/lib/models/providerMap.js +4 -0
- package/dist/lib/models/registry.d.ts +3 -3
- package/dist/lib/models/registry.js +11 -4
- package/dist/lib/observability/tracer.d.ts +1 -1
- package/dist/lib/onboarding.js +9 -4
- package/dist/lib/storage/postgres/memoryStore.js +27 -0
- package/dist/lib/syndicateSchema.d.ts +16 -0
- package/dist/lib/syndicateSchema.js +2 -1
- package/dist/lib/tools/credentialEnv.js +1 -1
- package/package.json +2 -1
- package/skills/briefs/melchizedek-author.md +1 -1
- package/skills/briefs/melchizedek-models.md +6 -5
- package/skills/briefs/melchizedek.md +2 -2
- package/skills/melchizedek-onboard/SKILL.md +1 -1
- package/skills/melchizedek-onboard-keys/SKILL.md +2 -2
package/.env.example
CHANGED
|
@@ -2,7 +2,38 @@
|
|
|
2
2
|
# asks what you have and prints the names to set for it; --auto detects it.
|
|
3
3
|
# Only names and shapes live here: type the values yourself, never commit .env.
|
|
4
4
|
|
|
5
|
-
# ──
|
|
5
|
+
# ── The quickest start: ONE gateway key for every cloud model ─────────────────
|
|
6
|
+
# A Vercel AI Gateway or OpenRouter key serves every cloud model id whose
|
|
7
|
+
# direct key is absent (Claude, GPT, Gemini, Grok, Kimi, DeepSeek, and
|
|
8
|
+
# TypeSafe Jev on the gateway's System One route), billed to that one account.
|
|
9
|
+
# Set these two and every multi-provider syndicate runs. By default a direct
|
|
10
|
+
# key set beside it wins for its own provider, at full fidelity: native search
|
|
11
|
+
# tools are dropped on the gateway path (the doctor says which), and the
|
|
12
|
+
# gateway never serves ollama/* models; it embeds for long-term memory only
|
|
13
|
+
# where it carries the same model (Vercel does; OpenRouter has no Gemini one).
|
|
14
|
+
# MODEL_GATEWAY_PREFER=gateway turns that round (every cloud id through the
|
|
15
|
+
# gateway, one bill), and MODEL_GATEWAY_EXCEPT names the providers that take
|
|
16
|
+
# the opposite of the preference, e.g. gemini kept on its own key for grounding.
|
|
17
|
+
# What a gateway gives back: web_search runs as the gateway's own search on
|
|
18
|
+
# any model (Vercel's exa_search server tool; OpenRouter's web plugin, the
|
|
19
|
+
# provider's native search where it has one, with citations), and long-term
|
|
20
|
+
# memory embeds through the gateway when it carries the same embedding model
|
|
21
|
+
# (Vercel: google/gemini-embedding-001). x_search and Collections stay direct-only.
|
|
22
|
+
# A gateway is for billing and breadth, not for grounding: for a search-heavy
|
|
23
|
+
# agent keep the provider that does the searching on its own key and let the
|
|
24
|
+
# gateway serve the rest (a direct key beside the gateway key does that by
|
|
25
|
+
# default; MODEL_GATEWAY_EXCEPT keeps it so under MODEL_GATEWAY_PREFER=gateway).
|
|
26
|
+
# Keys: https://vercel.com/ai-gateway or https://openrouter.ai/keys
|
|
27
|
+
# MODEL_GATEWAY=vercel # or openrouter
|
|
28
|
+
# MODEL_GATEWAY_API_KEY=
|
|
29
|
+
# MODEL_GATEWAY_PREFER=direct # or gateway: the gateway wins even beside a direct key
|
|
30
|
+
# MODEL_GATEWAY_EXCEPT= # optional: providers that take the opposite of the preference, e.g. gemini,xai
|
|
31
|
+
# MODEL_GATEWAY_SEARCH= # optional: off, or the gateway's engine (Vercel: exa | perplexity | parallel | browserbase | tako; OpenRouter: native | exa | firecrawl | parallel | perplexity)
|
|
32
|
+
# MODEL_GATEWAY_SEARCH_RESULTS=3 # optional: results per search, folded into the prompt as input tokens (Exa pages run 2k-10k tokens each; perplexity caps tokens)
|
|
33
|
+
# MODEL_GATEWAY_BASE_URL= # optional: a self-hosted proxy speaking the same chat-completions dialect
|
|
34
|
+
# MODEL_GATEWAY_MODEL_MAP= # optional: "claude-sonnet-4-6=anthropic/claude-sonnet-4.6,jev-latest=typesafe-ai/jev,..."
|
|
35
|
+
|
|
36
|
+
# ── Required for cloud models (without a gateway) ─────────────────────────────
|
|
6
37
|
# Google AI Studio API key — powers all Gemini model inference.
|
|
7
38
|
# Also required for the gemini-embedding-001 embedding model used by long-term memory.
|
|
8
39
|
# Get yours free at: https://aistudio.google.com
|
|
@@ -102,6 +133,19 @@ MOONSHOT_API_KEY=
|
|
|
102
133
|
DEEPSEEK_API_KEY=
|
|
103
134
|
# DEEPSEEK_BASE_URL= # a proxy speaking the same chat-completions dialect
|
|
104
135
|
|
|
136
|
+
# ── Optional: TypeSafe Jev (a decision model, not a chat model) ──────────────
|
|
137
|
+
# Required only when using jev-* model identifiers in YAML (jev-latest is the
|
|
138
|
+
# alias for the newest release; jev-1.14.0 and jev-1.13.0 are the ids). Jev
|
|
139
|
+
# answers an agent's output.schema as typed decisions with calibrated
|
|
140
|
+
# probabilities, at $0.042 per million input tokens and nothing for output;
|
|
141
|
+
# it writes no prose, calls no tool and shows no reasoning, so it is the model
|
|
142
|
+
# of a classifier agent (examples/classifier.yaml), never of an orchestrator.
|
|
143
|
+
# Get your key at: https://console.typesafe.ai/keys. Without it, MODEL_GATEWAY
|
|
144
|
+
# serves jev-* ids on the gateway's System One route (typesafe-ai/jev on
|
|
145
|
+
# Vercel, typesafe/jev-1.14 on OpenRouter).
|
|
146
|
+
TYPESAFE_API_KEY=
|
|
147
|
+
# TYPESAFE_BASE_URL= # a proxy speaking TypeSafe's System One wire
|
|
148
|
+
|
|
105
149
|
# XAI_COLLECTION_IDS: comma-separated xAI Collection ids searched by the
|
|
106
150
|
# `collections_search` tool (grok-* agents only). Create collections and
|
|
107
151
|
# upload documents at console.x.ai. Declared with no ids set, the tool is
|
|
@@ -320,15 +364,6 @@ MCP_WIKI_PORT=
|
|
|
320
364
|
# string (gemini-*, claude-*, ollama/*, ...). Default: gemini-3.8-flash.
|
|
321
365
|
WIKI_AGENT_MODEL=
|
|
322
366
|
|
|
323
|
-
# ── Optional: one gateway key for providers you have no key for ───────────────
|
|
324
|
-
# A model whose direct key is ABSENT is served through the gateway's OpenAI-
|
|
325
|
-
# compatible endpoint (native search tools are dropped on that path; the
|
|
326
|
-
# doctor says which). A present direct key always wins.
|
|
327
|
-
# MODEL_GATEWAY=vercel # or openrouter
|
|
328
|
-
# MODEL_GATEWAY_API_KEY=
|
|
329
|
-
# MODEL_GATEWAY_BASE_URL= # optional: a self-hosted proxy speaking the same dialect
|
|
330
|
-
# MODEL_GATEWAY_MODEL_MAP= # optional: "claude-sonnet-4-6=anthropic/claude-sonnet-4.6,..."
|
|
331
|
-
|
|
332
367
|
# ── Optional: tracing ─────────────────────────────────────────────────────────
|
|
333
368
|
# Send every span to any OTLP/HTTP backend (Phoenix, Langfuse, Jaeger, Tempo):
|
|
334
369
|
# a local Phoenix is `docker run -p 6006:6006 arizephoenix/phoenix`.
|
|
@@ -378,6 +413,14 @@ WIKI_AGENT_MODEL=
|
|
|
378
413
|
# Fact extraction runs on any model id (routed like an agent's model); the
|
|
379
414
|
# embedder is gemini (default), openai, ollama or any OpenAI-compatible
|
|
380
415
|
# endpoint. The dimension must match the vector column (768 in db/migrations).
|
|
416
|
+
# With no key for the embedding provider, or MODEL_GATEWAY_PREFER=gateway, the
|
|
417
|
+
# embedder goes through the gateway when it carries the same model (Vercel does
|
|
418
|
+
# for gemini-embedding-001; OpenRouter has no Gemini one: set
|
|
419
|
+
# MEMORY_EMBEDDING_PROVIDER=openai to embed text-embedding-3-small at 768 through
|
|
420
|
+
# it). The store records the model its vectors come from on the first write
|
|
421
|
+
# (migration 0023) and refuses a different one at start: switching models means
|
|
422
|
+
# re-embedding every stored fact, never mixing them. `npm run doctor` says what
|
|
423
|
+
# would embed here.
|
|
381
424
|
# MEMORY_EXTRACTION_MODEL=gemini-3.8-flash
|
|
382
425
|
# MEMORY_EMBEDDING_PROVIDER=gemini
|
|
383
426
|
# MEMORY_EMBEDDING_MODEL=
|
package/AGENT_SETUP.md
CHANGED
|
@@ -74,7 +74,10 @@ After the agent reports back:
|
|
|
74
74
|
`OPENAI_API_KEY` for `gpt-*` (https://platform.openai.com/api-keys),
|
|
75
75
|
`XAI_API_KEY` for `grok-*` (https://console.x.ai),
|
|
76
76
|
`MOONSHOT_API_KEY` for `kimi-*` (https://platform.moonshot.ai),
|
|
77
|
-
`DEEPSEEK_API_KEY` for `deepseek-*` (https://platform.deepseek.com/api_keys)
|
|
77
|
+
`DEEPSEEK_API_KEY` for `deepseek-*` (https://platform.deepseek.com/api_keys),
|
|
78
|
+
`TYPESAFE_API_KEY` for `jev-*` (https://console.typesafe.ai/keys; a decision
|
|
79
|
+
model for classifier agents). Or one `MODEL_GATEWAY` + `MODEL_GATEWAY_API_KEY`
|
|
80
|
+
(Vercel AI Gateway or OpenRouter) for every cloud id at once. Not sure which
|
|
78
81
|
you need? `npm run doctor` reads every syndicate and prints what is
|
|
79
82
|
ready, what is blocked, and which variable unlocks what — read-only,
|
|
80
83
|
no key value shown. Verify the whole multi-provider surface live with
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,132 @@ 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
|
+
## 1.12.0 — 2026-10-23
|
|
8
|
+
|
|
9
|
+
A minor release: TypeSafe's Jev joins the providers as a decision model, and
|
|
10
|
+
one gateway key is the first thing the setup offers.
|
|
11
|
+
|
|
12
|
+
**TypeSafe Jev is a provider** (ADR 0144). `jev-*` ids route to the new
|
|
13
|
+
`JevAdapter` (exported from `melchizedek-agents/model`, beside
|
|
14
|
+
`DeepSeekAdapter`), against `https://api.typesafe.ai/v1/systemone` with
|
|
15
|
+
`TYPESAFE_API_KEY` (`TYPESAFE_BASE_URL` for a proxy); `jev-latest` is the
|
|
16
|
+
default (`DEFAULT_JEV_MODEL`). Jev is not a chat model: it answers an
|
|
17
|
+
agent's `output.schema` as typed decisions with calibrated probabilities,
|
|
18
|
+
in about a tenth of a second, at $0.042 per million input tokens and nothing
|
|
19
|
+
for output. The schema is the request: a boolean property becomes a yes/no
|
|
20
|
+
question, a string with `enum` or a `oneOf` of described constants a
|
|
21
|
+
choice, an integer whose `oneOf` describes the levels 0..n-1 a score; the
|
|
22
|
+
instruction and the conversation are the state; the final is the schema's
|
|
23
|
+
object with the raw answers under a reserved `jev` key. The same call from
|
|
24
|
+
code is `decide()`, typed on its questions (`noul`, `choice`, `score`), with
|
|
25
|
+
`questionsFromSchema` and `objectFromAnswers` beside it. Jev takes no tools,
|
|
26
|
+
no reasoning, no streaming and no images, and says so in the capability
|
|
27
|
+
matrix; an agent with no schema, or with a property Jev cannot decide, fails
|
|
28
|
+
before any call (`TYPESAFE_SCHEMA_REQUIRED`, `TYPESAFE_SCHEMA_UNSUPPORTED`,
|
|
29
|
+
naming the property). The starter pack gains `classifier.yaml`, a
|
|
30
|
+
support-triage classifier on `jev-latest` (`npm run syndicate:classifier`).
|
|
31
|
+
The doctor, the setup guide (`ONBOARDING.md`), `.env.example`, the
|
|
32
|
+
`model_overrides` keys (`typesafe`), the onboarding skills and the skill
|
|
33
|
+
briefs know it. Run live through Vercel AI Gateway (the classifier and
|
|
34
|
+
every id, 2026-10-23); TypeSafe's own API and OpenRouter not yet.
|
|
35
|
+
|
|
36
|
+
**A gateway serves Jev too.** With no `TYPESAFE_API_KEY`, `MODEL_GATEWAY`
|
|
37
|
+
serves `jev-*` ids on the gateway's own System One route: Vercel AI
|
|
38
|
+
Gateway's `/typesafe/v1/systemone` as `typesafe-ai/jev`, OpenRouter's
|
|
39
|
+
`/api/v1/systemone` as `typesafe/jev-1.14` (`MODEL_GATEWAY_MODEL_MAP` fixes
|
|
40
|
+
an id). The gateway's `slugs` table has a `typesafe` entry and each gateway a
|
|
41
|
+
`systemOne` route (`GatewayInfo`).
|
|
42
|
+
|
|
43
|
+
**The gateway settings read through the credential source.**
|
|
44
|
+
`MODEL_GATEWAY`, `MODEL_GATEWAY_BASE_URL` and `MODEL_GATEWAY_MODEL_MAP` are
|
|
45
|
+
read with `credentialValue`, as the key already was (ADR 0133), so an
|
|
46
|
+
embedding application that holds them in a keychain, not the environment,
|
|
47
|
+
turns the gateway on too.
|
|
48
|
+
|
|
49
|
+
**The gateway can come first** (ADR 0145). `MODEL_GATEWAY_PREFER=gateway`
|
|
50
|
+
sends every cloud id through the configured gateway even beside its direct
|
|
51
|
+
key (one bill, one dashboard); `MODEL_GATEWAY_EXCEPT=gemini,xai` names the
|
|
52
|
+
providers that take the opposite of the preference either way (Gemini kept
|
|
53
|
+
on its own key for grounding under `prefer=gateway`; Grok sent through the
|
|
54
|
+
gateway under the default). Unset, nothing changes: a direct key wins.
|
|
55
|
+
Ollama and an A2A caller's own key stay direct; a preferred path that is
|
|
56
|
+
not funded falls back to the other; the doctor names a misspelt preference
|
|
57
|
+
or an unknown provider. `gatewayPreference`, `gatewayExceptions` and
|
|
58
|
+
`providerTransport` are exported from `melchizedek-agents/registry`.
|
|
59
|
+
|
|
60
|
+
**A gateway searches and embeds** (ADR 0146). On the gateway path an
|
|
61
|
+
agent's `web_search` is no longer dropped: Vercel AI Gateway runs its
|
|
62
|
+
server search tool (`vercel:exa_search` by default) and OpenRouter its web
|
|
63
|
+
plugin (the provider's native search where the model has one, else Exa),
|
|
64
|
+
whose `url_citation` annotations the chat-completions base now keeps as the
|
|
65
|
+
final's `grounding.citations` (`groundingOf`). `MODEL_GATEWAY_SEARCH` names
|
|
66
|
+
the engine or turns it off; `x_search` and `collections_search` stay
|
|
67
|
+
dropped. Long-term memory's embedder goes through the gateway's
|
|
68
|
+
`/embeddings` when the gateway carries the same model (Vercel:
|
|
69
|
+
`google/gemini-embedding-001`, `openai/text-embedding-3-small`; OpenRouter:
|
|
70
|
+
OpenAI's) and the provider's own key is absent or the gateway is preferred,
|
|
71
|
+
so the vectors stay the model's own. `GatewayInfo` gains `search` and
|
|
72
|
+
`embeddings`; `gatewaySearch`, `gatewaySearchProblem` and
|
|
73
|
+
`gatewayEmbedding` are exported from `melchizedek-agents/models/gateway`;
|
|
74
|
+
`gatewayConfig`, `gatewayPreference`, `gatewayExceptions` and
|
|
75
|
+
`gatewayWanted` take an optional `env`. The capability matrix's gateway
|
|
76
|
+
row reads `native_search` as degraded, with the note.
|
|
77
|
+
|
|
78
|
+
**A gateway's search is bounded, and a memory store can be re-embedded**
|
|
79
|
+
(ADR 0148). `MODEL_GATEWAY_SEARCH_RESULTS` (default 3) is passed as each
|
|
80
|
+
gateway search engine's count, Exa on its instant type and Perplexity under
|
|
81
|
+
a token cap, since the results are billed as prompt tokens (an unbounded Exa
|
|
82
|
+
search measured about 20,000 of them). `npm run memory -- reembed` re-embeds
|
|
83
|
+
every stored fact with the environment's embedder in id-ordered pages and
|
|
84
|
+
records the new model last (`MemoryStore` gains `listFacts`,
|
|
85
|
+
`updateEmbeddings`, `setEmbedder`; migration 0023 gains
|
|
86
|
+
`melchizedek_memory_set_embedder`), under an advisory lock on
|
|
87
|
+
`DATABASE_URL`. The setup note and the env template state the posture: a
|
|
88
|
+
gateway is for billing and breadth, not for grounding; keep the searching
|
|
89
|
+
provider on its own key. The lockfile moves `body-parser`, `fast-uri` and
|
|
90
|
+
`ip-address` past their advisories (no API change).
|
|
91
|
+
|
|
92
|
+
**A memory store records its embedding model; the doctor says what embeds**
|
|
93
|
+
(ADR 0147, migration `0023_memory_embedder`). On its first successful write
|
|
94
|
+
the memory service records the provider, model and dimension the store's
|
|
95
|
+
vectors come from, and at start it refuses an embedder whose model differs,
|
|
96
|
+
naming the recorded one and the two ways out (set the embedder back, or
|
|
97
|
+
re-embed every fact); a gateway's spelling of the same model passes. The
|
|
98
|
+
doctor gains a `memory` line from `embedderPlan` (exported from
|
|
99
|
+
`melchizedek-agents/memory`): what embeds long-term memory, on which path,
|
|
100
|
+
or what to set, with OpenRouter's documented answer
|
|
101
|
+
(`MEMORY_EMBEDDING_PROVIDER=openai`, `text-embedding-3-small` at 768) and
|
|
102
|
+
the re-embed caveat (`memoryProvidersFromEnv` is exported there too). `MemoryStore` gains optional `embedderRecord` and
|
|
103
|
+
`recordEmbedder`; `db/hardening.sql` locks the new table like the others.
|
|
104
|
+
|
|
105
|
+
**One gateway key is the first thing offered.** `.env.example` opens with
|
|
106
|
+
the `MODEL_GATEWAY` block (one Vercel AI Gateway or OpenRouter key for every
|
|
107
|
+
cloud model whose direct key is absent), the README's cloud quick start
|
|
108
|
+
leads with it, and the keys onboarding skill suggests it first when a person
|
|
109
|
+
has no preference. The routing rule is unchanged: a direct key beside it
|
|
110
|
+
always wins for its provider.
|
|
111
|
+
|
|
112
|
+
**Price rows for Jev** (migration `0022_typesafe_jev_pricing`): `jev-latest`,
|
|
113
|
+
`jev-preview`, `jev-1.14.0` and `jev-1.13.0` at $0.042 input, $0 output. An
|
|
114
|
+
existing row is never overwritten.
|
|
115
|
+
|
|
116
|
+
## 1.11.1 — 2026-10-22
|
|
117
|
+
|
|
118
|
+
**Price rows for `grok-4.3`, `gemini-embedding-001` and `gemini-3.5-flash`**
|
|
119
|
+
(migration `0020_embedding_flash_grok_pricing`). Ledgers held calls of these
|
|
120
|
+
models priced NULL for want of a row. `grok-4.3` is checked against xAI's
|
|
121
|
+
list (its rate under 200k prompt tokens); the two Gemini rows come from
|
|
122
|
+
sources other than Google's current page, which no longer lists them, so
|
|
123
|
+
their `verified_at` is NULL. An existing row is never overwritten.
|
|
124
|
+
|
|
125
|
+
**`gemini-3.8-flash` and `grok-4.7` at their vendors' lists** (migration
|
|
126
|
+
`0021_correct_gemini_flash_grok_rates`). Both were 0015 placeholders:
|
|
127
|
+
`gemini-3.8-flash` is now $0.75 / $0.075 cached / $3.75 (was $0.30 / $2.50;
|
|
128
|
+
Google lists a rise to $1.50 / $0.15 / $7.50 from 2027-01-01), `grok-4.7`
|
|
129
|
+
$2.00 / $0.50 / $6.00 (was $3.00 / $15.00). A row changes only while it is
|
|
130
|
+
still the seed, at the seed's rates; an operator's rate is kept. Calls
|
|
131
|
+
already priced keep the rate they were written at.
|
|
132
|
+
|
|
7
133
|
## 1.11.0 — 2026-10-22
|
|
8
134
|
|
|
9
135
|
A minor release: DeepSeek joins the providers, and Kimi calls are priced.
|
package/DOCUMENTATION.md
CHANGED
|
@@ -143,7 +143,7 @@ Field reference:
|
|
|
143
143
|
| `reasoning` | agent | How hard the agent reasons, on any provider: `none`, `low`, `medium`, `high`, `xhigh`, `max`, or `{ budget_tokens: <int> }`. The compiler sends each provider the field it reads: a thinking level on Gemini 3, a thinking budget on Claude 4.6 and earlier (2,048 / 8,192 / 16,384 tokens for low / medium / high), adaptive thinking with that effort on later Claude models ([ADR 0049](./wiki/decisions/0049-claude-requests-by-model-generation.md)), an effort word on GPT, Grok, Kimi, DeepSeek (beside its thinking switch), Ollama and the gateway ([ADR 0047](./wiki/decisions/0047-provider-neutral-reasoning-key.md)). `xhigh` and `max` reach the models that take them (both on Claude from Opus 4.7 and Sonnet 5, `max` on Kimi K3, `xhigh` on GPT-5.2 and later and grok-4.7); elsewhere the model's highest setting is sent and the span carries `llm.reasoning.weakened` (`npm run doctor -- --matrix` lists each path, [ADR 0117](./wiki/decisions/0117-tool-choice-and-effort-above-high-in-v2.md)). Unset, each adapter keeps its own default. |
|
|
144
144
|
| `sampling` | agent | `{ temperature, top_p, max_output_tokens, stop }`, the fields the engine sends to every provider; each adapter sends the ones its API takes ([ADR 0115](./wiki/decisions/0115-yaml-schema-v2-provider-neutral-keys.md)). |
|
|
145
145
|
| `output` | agent | `{ schema, mime }`. `mime` is `application/json` (JSON mode, with or without a schema) or `text/plain` (the default). `schema` is the structured-JSON contract: the agent ends its turn on one JSON object matching it. An orchestrator may hold one beside its subagents: it delegates first, then answers in the schema itself. The schema travels in the provider's own structured-output field beside the tools on Claude from Opus 4.8, Sonnet 5 and Haiku 5.5, on OpenAI, and on Gemini 2+ through Vertex AI, and as a `set_model_response` tool elsewhere (the capability matrix's `structured_output_with_tools`, [ADR 0109](./wiki/decisions/0109-structured-output-beside-tools.md)). Worked example: `examples/structured_critic.yaml`. A leaf that holds the schema (`critic.yaml`) and plan-dispatch remain the choices when the answer should be a specialist's. |
|
|
146
|
-
| `model_overrides` | agent | A prompt nuance for one provider: keyed by `gemini`, `anthropic`, `openai`, `xai`, `moonshot`, `deepseek` or `ollama`, each entry holds `instruction` (replaces the agent's instruction on that provider) or `instruction_append` (added after a blank line). The entry for the provider of the agent's `model` applies, before the skills index is appended; a `fallback_model` gets the primary's instruction. |
|
|
146
|
+
| `model_overrides` | agent | A prompt nuance for one provider: keyed by `gemini`, `anthropic`, `openai`, `xai`, `moonshot`, `deepseek`, `typesafe` or `ollama`, each entry holds `instruction` (replaces the agent's instruction on that provider) or `instruction_append` (added after a blank line). The entry for the provider of the agent's `model` applies, before the skills index is appended; a `fallback_model` gets the primary's instruction. |
|
|
147
147
|
| `tool_choice` | agent | Which tools the model may call: `auto` (the default), `none`, `required` (some tool), or `{ name: <tool> }` (that tool). A provider that rejects forcing sends a weaker choice and marks the span `llm.tool_choice.weakened` ([ADR 0117](./wiki/decisions/0117-tool-choice-and-effort-above-high-in-v2.md)). |
|
|
148
148
|
| `generateContentConfig` / `outputSchema` | agent | The deprecated v1 spelling of `sampling`, `output.mime`, `reasoning` (as `thinkingConfig` / `reasoningEffort`), `tool_choice` (as `toolConfig.functionCallingConfig`) and `output.schema`. Both still load and behave the same; a load that finds either prints one deprecation line per file per process (`LoadSyndicateOptions.onWarning`, default `console.warn`), and a v2 key beside its v1 spelling on one agent is a load error. Only `toolConfig.functionCallingConfig.mode: VALIDATED` and Gemini's dynamic budget (`thinkingBudget: -1`) have no v2 form; `topK`, `seed`, the penalties, `candidateCount`, `safetySettings` and `includeThoughts` reach no provider, and the codemod drops `includeThoughts`. `npx melchizedek-codemod [--check] <file|dir>` rewrites a v1 file to v2, comments kept ([ADR 0115](./wiki/decisions/0115-yaml-schema-v2-provider-neutral-keys.md)). |
|
|
149
149
|
| `yaml_reference` | subagent | Mount another syndicate file as a nested subagent. |
|
|
@@ -291,7 +291,8 @@ in `examples/specs/`.
|
|
|
291
291
|
> dialect; every non-Gemini adapter normalizes them back to
|
|
292
292
|
> standard lowercase JSON-Schema at request-build time
|
|
293
293
|
> (`lib/models/schemaNormalize.ts`). MCP tools therefore work on any
|
|
294
|
-
> provider's agents — Gemini, Claude, GPT, Grok, Kimi, or DeepSeek
|
|
294
|
+
> provider's agents — Gemini, Claude, GPT, Grok, Kimi, or DeepSeek (never
|
|
295
|
+
> Jev, which calls no tool).
|
|
295
296
|
|
|
296
297
|
## 4. Sessions & long-term memory
|
|
297
298
|
|
|
@@ -413,8 +414,9 @@ accordingly — model optionality is a single YAML line per agent:
|
|
|
413
414
|
| `grok-*` | xAI | `lib/models/grokAdapter.ts` (Responses API) | `XAI_API_KEY` | ✅ Agent Tools search |
|
|
414
415
|
| `kimi-*` | Moonshot AI (Kimi) | `lib/models/kimiAdapter.ts` (chat completions) | `MOONSHOT_API_KEY` | ⚠ omitted + warning |
|
|
415
416
|
| `deepseek-*` | DeepSeek | `lib/models/deepseekAdapter.ts` (chat completions) | `DEEPSEEK_API_KEY` | ⚠ omitted + warning |
|
|
417
|
+
| `jev-*` | TypeSafe (Jev, a decision model) | `lib/models/jevAdapter.ts` (System One) | `TYPESAFE_API_KEY` | ✗ no tools at all |
|
|
416
418
|
| `ollama/*` | Local Ollama | `lib/models/ollamaAdapter.ts` (chat completions) | none | ⚠ omitted + warning |
|
|
417
|
-
| *any cloud id whose direct key is absent
|
|
419
|
+
| *any cloud id whose direct key is absent, or every cloud id under `MODEL_GATEWAY_PREFER=gateway`* | the id's own provider, via a gateway | `lib/models/gatewayAdapter.ts` (chat completions; `jev-*` keeps `JevAdapter` on the gateway's System One route) | `MODEL_GATEWAY` + `MODEL_GATEWAY_API_KEY` | ◐ the gateway's own search (`MODEL_GATEWAY_SEARCH`) |
|
|
418
420
|
|
|
419
421
|
The xAI adapter carries the deepest capability surface: `grok-4.5`
|
|
420
422
|
requests pin `reasoning.effort: "medium"` (`lib/config.ts`), SSE
|
|
@@ -498,6 +500,102 @@ warning, `web_extract` works). Through `MODEL_GATEWAY` the ids go as
|
|
|
498
500
|
capability matrix is asserted against the request body the adapter sends;
|
|
499
501
|
it has not been run live.
|
|
500
502
|
|
|
503
|
+
**TypeSafe (Jev).** `jev-*` ids route to `JevAdapter`
|
|
504
|
+
(`lib/models/jevAdapter.ts`), against `https://api.typesafe.ai/v1/systemone`
|
|
505
|
+
(`TYPESAFE_BASE_URL` for a proxy). Get a key at console.typesafe.ai/keys.
|
|
506
|
+
Jev is a System One model, not a chat model: one request carries a `state`
|
|
507
|
+
and typed `questions`, and the answer is one typed decision per question
|
|
508
|
+
with calibrated probabilities, never prose, never a tool call, in about a
|
|
509
|
+
tenth of a second at $0.042 per million input tokens and nothing for output
|
|
510
|
+
(migration 0022). The engine makes it the model of a classifier agent: the
|
|
511
|
+
agent's `output.schema` becomes the questions (`lib/models/jev.ts`
|
|
512
|
+
`questionsFromSchema`: a boolean property is a yes/no `noul` question, a
|
|
513
|
+
string with `enum` or a `oneOf` of described constants is a `choice`, an
|
|
514
|
+
integer whose `oneOf` describes the levels 0..n-1 in order is a `score`;
|
|
515
|
+
the property's `description` is the question), the instruction and the
|
|
516
|
+
conversation's text are the state, and the final is the schema's object
|
|
517
|
+
with the raw answers under a reserved `jev` key, so code acts on
|
|
518
|
+
confidence. The ids are `jev-latest` (the default, TypeSafe's alias for the
|
|
519
|
+
newest stable release), `jev-preview`, `jev-1.14.0` and `jev-1.13.0`
|
|
520
|
+
(`GET /v1/models` lists them); 64k tokens per request, 32k per question.
|
|
521
|
+
What works: structured output, direct or through either gateway (Vercel AI
|
|
522
|
+
Gateway's `/typesafe/v1/systemone` as `typesafe-ai/jev`, OpenRouter's
|
|
523
|
+
`/api/v1/systemone` as `typesafe/jev-1.14`, `MODEL_GATEWAY_MODEL_MAP` for
|
|
524
|
+
either). What does not, by the nature of the model: tools and delegation
|
|
525
|
+
(dropped; the doctor names an agent with tools on a Jev id as a gap),
|
|
526
|
+
`reasoning:`, streaming (the final is the only response), images (dropped)
|
|
527
|
+
and native search. An agent with no `output.schema`, or with a property Jev
|
|
528
|
+
cannot decide (a free string, an array, a nested object), fails before any
|
|
529
|
+
call with `TYPESAFE_SCHEMA_REQUIRED` or `TYPESAFE_SCHEMA_UNSUPPORTED`,
|
|
530
|
+
naming the property and the shapes Jev takes. `examples/classifier.yaml`
|
|
531
|
+
is the pattern, and `decide()` from `melchizedek-agents/model` is the same
|
|
532
|
+
call from code, typed on its questions (`noul`, `choice`, `score`). The
|
|
533
|
+
row in the capability matrix is asserted against the request body the
|
|
534
|
+
adapter sends; the classifier and all four ids were run live through
|
|
535
|
+
Vercel AI Gateway on 2026-10-23 (answers in 150 to 715 ms); TypeSafe's own
|
|
536
|
+
API and OpenRouter's route were not.
|
|
537
|
+
|
|
538
|
+
**Which path wins.** By default a provider's own key wins for its
|
|
539
|
+
provider and the gateway serves only what has no key (ADR 0012).
|
|
540
|
+
`MODEL_GATEWAY_PREFER=gateway` turns that round: every cloud id goes
|
|
541
|
+
through the configured gateway even beside a direct key, one bill and one
|
|
542
|
+
dashboard, at the gateway's fidelity (no native search). `MODEL_GATEWAY_EXCEPT`
|
|
543
|
+
is a comma list of provider ids that take the opposite of the preference
|
|
544
|
+
either way: `gemini` under `prefer=gateway` keeps Gemini on its own key for
|
|
545
|
+
grounding; `xai` under the default sends Grok through the gateway while
|
|
546
|
+
everything else stays direct. Two things never move: `ollama/*` is always
|
|
547
|
+
direct, and an A2A caller's own key (BYOK) funds its provider directly. A
|
|
548
|
+
preference whose path is not funded falls back to the other; an unknown
|
|
549
|
+
preference word or a provider name the list does not know is named by the
|
|
550
|
+
doctor (ADR 0145). Both variables are read through the credential source,
|
|
551
|
+
like the key.
|
|
552
|
+
|
|
553
|
+
**What a gateway gives back** (ADR 0146). An agent's `web_search` (or
|
|
554
|
+
`google_search`) is not dropped on the gateway path: it runs as the
|
|
555
|
+
gateway's own search, on any model. Vercel AI Gateway runs a server tool
|
|
556
|
+
(`vercel:exa_search` by default; `MODEL_GATEWAY_SEARCH` picks `exa`,
|
|
557
|
+
`perplexity`, `parallel`, `browserbase` or `tako`): the gateway searches,
|
|
558
|
+
folds the results into the model's context and answers in the same
|
|
559
|
+
response, the span counts the calls, and no citations come back. OpenRouter
|
|
560
|
+
runs its web plugin, which is the provider's native search where the model
|
|
561
|
+
has one (OpenAI, Anthropic, Google, xAI) and Exa elsewhere
|
|
562
|
+
(`MODEL_GATEWAY_SEARCH` picks `native`, `exa`, `firecrawl`, `parallel` or
|
|
563
|
+
`perplexity`), and returns `url_citation` annotations the adapter keeps as
|
|
564
|
+
the final's `grounding.citations`. `MODEL_GATEWAY_SEARCH=off` drops the tool
|
|
565
|
+
as before. `MODEL_GATEWAY_SEARCH_RESULTS` (default 3) is passed as each
|
|
566
|
+
engine's count, Exa on its instant type and Perplexity under a cap of
|
|
567
|
+
2,000 tokens a result (ADR 0148), because the gateway folds the results into
|
|
568
|
+
the prompt as input tokens: measured live, Exa at three results carried
|
|
569
|
+
7,000 to 17,600 prompt tokens for a one-line question (unbounded, 13,000 to
|
|
570
|
+
20,000), Perplexity at three 6,200. Each gateway also bills its search on
|
|
571
|
+
top of the tokens (Exa about $0.007 a request on OpenRouter; Vercel prices
|
|
572
|
+
its engines). A gateway is for billing and breadth, not for grounding: for a
|
|
573
|
+
search-heavy agent, keep the provider that does the searching on its own key
|
|
574
|
+
(its native search and citations) and let the gateway serve the rest, which
|
|
575
|
+
a direct key beside the gateway key does by default and
|
|
576
|
+
`MODEL_GATEWAY_EXCEPT` keeps under `MODEL_GATEWAY_PREFER=gateway`. xAI's `x_search`
|
|
577
|
+
and `collections_search` have no gateway form and are dropped. Long-term
|
|
578
|
+
memory's embedder follows the same rule: with no key for the embedding
|
|
579
|
+
provider, or under `MODEL_GATEWAY_PREFER=gateway`, it embeds through the
|
|
580
|
+
gateway's `/embeddings` when the gateway carries the same model (Vercel
|
|
581
|
+
carries `google/gemini-embedding-001` and `openai/text-embedding-3-small`
|
|
582
|
+
and honours `dimensions`, checked live at 768; OpenRouter carries OpenAI's
|
|
583
|
+
only), so a store embedded directly and one embedded through the gateway
|
|
584
|
+
hold the same vectors; a gateway that lacks the model changes nothing.
|
|
585
|
+
OpenRouter carries no Gemini embedding model, so with no Gemini key the
|
|
586
|
+
documented answer there is `MEMORY_EMBEDDING_PROVIDER=openai`
|
|
587
|
+
(`text-embedding-3-small` at 768, a tenth of Gemini's price), with one
|
|
588
|
+
caveat the store now enforces (migration 0023, ADR 0147): a memory store
|
|
589
|
+
records the provider, model and dimension its vectors come from on its
|
|
590
|
+
first write and refuses a different model at start, since two models'
|
|
591
|
+
vectors do not compare even at the same size; switching means re-embedding
|
|
592
|
+
every stored fact, which `npm run memory -- reembed` does (a dry run first;
|
|
593
|
+
`--yes` writes): with `MEMORY_EMBEDDING_*` set to the new embedder it walks
|
|
594
|
+
the facts in id order, writes each page's vectors back and records the new
|
|
595
|
+
model last, under an advisory lock on `DATABASE_URL`, so an interrupted run
|
|
596
|
+
leaves the old record in place (ADR 0148). `npm run doctor` prints a
|
|
597
|
+
`memory` line saying what would embed here, or what to set.
|
|
598
|
+
|
|
501
599
|
**Which keys do I need?** `npm run doctor` (the `melchizedek-doctor` bin)
|
|
502
600
|
reads every syndicate YAML, resolves each agent's model under your `.env`,
|
|
503
601
|
and prints one table — agent, model, provider, which declared server-side
|
|
@@ -626,7 +724,9 @@ in a `FallbackAdapter`.
|
|
|
626
724
|
`melchizedek-agents/model` is the model layer on its own (ADR 0068): the
|
|
627
725
|
contract's types,
|
|
628
726
|
`ClaudeAdapter`, `GptAdapter`, `GrokAdapter`, `KimiAdapter`, `DeepSeekAdapter`,
|
|
629
|
-
`
|
|
727
|
+
`JevAdapter` (with `decide`, `noul`, `choice`, `score`, `questionsFromSchema`
|
|
728
|
+
and `objectFromAnswers` beside it), `OllamaAdapter`, `GatewayAdapter`,
|
|
729
|
+
`GeminiAdapter`, the
|
|
630
730
|
`ChatCompletionsAdapter` base, `resolveAdapter`,
|
|
631
731
|
`resolveAdapterWithFallback`, `FallbackAdapter` and the circuit breaker's
|
|
632
732
|
helpers. A project that only calls models imports from there. Its
|
|
@@ -698,7 +798,8 @@ calls), and `syndicate.usage` carries `cache_read` / `cache_write` per
|
|
|
698
798
|
model. `model_pricing.cache_read_per_mtok` / `cache_write_per_mtok` price
|
|
699
799
|
them (migration 0017; NULL prices them as input), seeded for Anthropic and
|
|
700
800
|
OpenAI from their price lists (ADR 0139). Migration 0019 adds DeepSeek (at
|
|
701
|
-
its peak rate) and Moonshot Kimi rows
|
|
801
|
+
its peak rate) and Moonshot Kimi rows; 0022 adds TypeSafe Jev (input only,
|
|
802
|
+
output free).
|
|
702
803
|
Operate it with `npm run telemetry:stats`,
|
|
703
804
|
`telemetry:prune` and `telemetry:replay` (the exporter spools failed
|
|
704
805
|
batches to `outputs/telemetry-deadletter.ndjson`).
|
|
@@ -880,7 +981,7 @@ names; nothing is kept by the framework anywhere else.
|
|
|
880
981
|
| The prompt: the user's message, the conversation, tool results | The model provider of each agent that runs (the model-id prefix) | The provider's policy | The `model:` lines in the YAML; `ollama/` ids stay on your machine |
|
|
881
982
|
| Tool calls (`web_search`, `web_extract`, OpenAPI, MCP) | The tool's own host | That host's policy | The agent's `tools:`, `openapi:`, `mcp_server_url` / `mcp_tools` |
|
|
882
983
|
| Sessions (conversation history) | Your Postgres, `adk_sessions` | 7 days after the last message | `ttlDays` (`postgresStorage`) |
|
|
883
|
-
| Long-term memory facts | Your Postgres, `adk_memory_facts`; **the transcript is also sent to the extraction and embedding providers, Gemini by default whatever the agents run on** (the server warns at boot when they differ) | Until erased, or `memory_retention_days` | `MEMORY_EXTRACTION_MODEL`, `MEMORY_EMBEDDING_PROVIDER`, `memory_retention_days` |
|
|
984
|
+
| Long-term memory facts | Your Postgres, `adk_memory_facts`; **the transcript is also sent to the extraction and embedding providers, Gemini by default whatever the agents run on** (the server warns at boot when they differ; through the gateway when it carries the embedding model, ADR 0146) | Until erased, or `memory_retention_days` | `MEMORY_EXTRACTION_MODEL`, `MEMORY_EMBEDDING_PROVIDER`, `memory_retention_days` |
|
|
884
985
|
| The ledger: each turn's input, output and tool results (key-shaped secrets redacted) | Your Postgres, `adk_turns`, `adk_telemetry` | **Until you prune it**: schedule `melchizedek_prune_telemetry(<days>)` | `TELEMETRY_REDACT`, the prune's `turn_days` |
|
|
885
986
|
| Sampled full model requests | Your Postgres, `adk_payloads` | 30 days | `TELEMETRY_PAYLOADS`, `TELEMETRY_PAYLOAD_TTL_DAYS` |
|
|
886
987
|
| Traces, when `OTEL_EXPORTER_OTLP_ENDPOINT` is set | Your OTLP collector, conversation content included with key-shaped secrets redacted (`off` drops it) | Your collector's policy | `OTEL_EXPORT_CONTENT` (`redacted`, `off`, `raw`) |
|
|
@@ -1680,7 +1781,7 @@ the canonical minimal block on the engine's model contract:
|
|
|
1680
1781
|
`resolveAdapter(modelId)` from `melchizedek-agents/model`, then
|
|
1681
1782
|
`adapter.generate({ model, system, messages, stream })`, reading partial
|
|
1682
1783
|
and final responses. The id's prefix picks the provider (`gemini-*`,
|
|
1683
|
-
`claude-*`, `gpt-*`, `grok-*`, `kimi-*`, `deepseek-*`, `ollama/*`), the key comes from
|
|
1784
|
+
`claude-*`, `gpt-*`, `grok-*`, `kimi-*`, `deepseek-*`, `jev-*`, `ollama/*`), the key comes from
|
|
1684
1785
|
the environment. A turn
|
|
1685
1786
|
with tools, sessions and telemetry is `runSyndicateTurn`.
|
|
1686
1787
|
|
package/ONBOARDING.md
CHANGED
|
@@ -9,7 +9,7 @@ In a clone, the commands are spelled as npm scripts (`npm run doctor`, `npm run
|
|
|
9
9
|
| # | You have | Guide |
|
|
10
10
|
|---|---|---|
|
|
11
11
|
| 1 | Nothing yet: run open-weight models locally (Ollama, no key) | `--level local` |
|
|
12
|
-
| 2 | One provider's API key (Gemini, Anthropic, OpenAI, xAI, Moonshot or
|
|
12
|
+
| 2 | One provider's API key (Gemini, Anthropic, OpenAI, xAI, Moonshot, DeepSeek or TypeSafe) | `--level one-provider` |
|
|
13
13
|
| 3 | API keys for several providers | `--level several-providers` |
|
|
14
14
|
| 4 | One gateway key (Vercel AI Gateway or OpenRouter) | `--level gateway` |
|
|
15
15
|
| 5 | Cloud platform credentials (Vertex AI, Amazon Bedrock, Azure OpenAI) | `--level cloud-platform` |
|
|
@@ -63,6 +63,7 @@ The model id's prefix picks the provider, and that provider's key funds it. One
|
|
|
63
63
|
| `XAI_API_KEY` | an API key from https://console.x.ai | xAI Grok: model ids grok-* |
|
|
64
64
|
| `MOONSHOT_API_KEY` | an API key from https://platform.moonshot.ai | Moonshot Kimi: model ids kimi-* |
|
|
65
65
|
| `DEEPSEEK_API_KEY` | an API key from https://platform.deepseek.com/api_keys | DeepSeek: model ids deepseek-* |
|
|
66
|
+
| `TYPESAFE_API_KEY` | an API key from https://console.typesafe.ai/keys | TypeSafe Jev: model ids jev-* (a decision model: it answers an output.schema, never prose) |
|
|
66
67
|
|
|
67
68
|
**Confirm:** `npx melchizedek-doctor`: the providers line shows a ✓ beside your provider, and the files of that tier read `ready`.
|
|
68
69
|
|
|
@@ -74,6 +75,7 @@ The model id's prefix picks the provider, and that provider's key funds it. One
|
|
|
74
75
|
- XAI_API_KEY: no shipped file yet (change a `model:` line to use one)
|
|
75
76
|
- MOONSHOT_API_KEY: no shipped file yet (change a `model:` line to use one)
|
|
76
77
|
- DEEPSEEK_API_KEY: no shipped file yet (change a `model:` line to use one)
|
|
78
|
+
- TYPESAFE_API_KEY: classifier (example)
|
|
77
79
|
- with no key at all: conversational (template), assistant (example), council (example), event_assistant (example), tutor (example)
|
|
78
80
|
|
|
79
81
|
**First commands:**
|
|
@@ -104,6 +106,7 @@ Each key funds its own provider, and a syndicate may mix them: one agent on Clau
|
|
|
104
106
|
| `XAI_API_KEY` | an API key from https://console.x.ai | xAI Grok: model ids grok-* |
|
|
105
107
|
| `MOONSHOT_API_KEY` | an API key from https://platform.moonshot.ai | Moonshot Kimi: model ids kimi-* |
|
|
106
108
|
| `DEEPSEEK_API_KEY` | an API key from https://platform.deepseek.com/api_keys | DeepSeek: model ids deepseek-* |
|
|
109
|
+
| `TYPESAFE_API_KEY` | an API key from https://console.typesafe.ai/keys | TypeSafe Jev: model ids jev-* (a decision model: it answers an output.schema, never prose) |
|
|
107
110
|
|
|
108
111
|
**Confirm:** `npx melchizedek-doctor`: a ✓ beside each provider you set; `multi-provider` files read `ready` once every provider they use has its key.
|
|
109
112
|
|
|
@@ -127,7 +130,7 @@ npx melchizedek-chat --syndicate model_zoo
|
|
|
127
130
|
|
|
128
131
|
## 4. A gateway key
|
|
129
132
|
|
|
130
|
-
One key serves every cloud model id whose direct key is absent, through the gateway's OpenAI-compatible endpoint.
|
|
133
|
+
One key serves every cloud model id whose direct key is absent, through the gateway's OpenAI-compatible endpoint (and TypeSafe Jev on its System One route). By default it is a fallback: a direct key wins for its provider; MODEL_GATEWAY_PREFER=gateway turns that round, and MODEL_GATEWAY_EXCEPT names the providers that take the opposite. Ollama never goes through it.
|
|
131
134
|
|
|
132
135
|
**Set in `.env`** (names and shapes only; you type the values yourself):
|
|
133
136
|
|
|
@@ -137,12 +140,14 @@ One key serves every cloud model id whose direct key is absent, through the gate
|
|
|
137
140
|
| `MODEL_GATEWAY_API_KEY` | the gateway key (https://vercel.com/ai-gateway or https://openrouter.ai/keys) | funds every id with no direct key |
|
|
138
141
|
| `MODEL_GATEWAY_BASE_URL` | https URL | optional: a self-hosted proxy speaking the same dialect (LiteLLM) |
|
|
139
142
|
| `MODEL_GATEWAY_MODEL_MAP` | yaml-id=gateway-id,yaml-id=gateway-id | optional: fix an id the default mapping gets wrong |
|
|
143
|
+
| `MODEL_GATEWAY_PREFER` | direct | gateway | optional: gateway sends every cloud id through the gateway even beside a direct key (one bill); direct, the default, lets each provider's own key win |
|
|
144
|
+
| `MODEL_GATEWAY_EXCEPT` | gemini,xai | optional: providers that take the opposite of the preference (never ollama) |
|
|
140
145
|
|
|
141
146
|
**Confirm:** `npx melchizedek-doctor`: a `gateway` line with no ✗, and providers without a direct key marked `◇ via gateway`.
|
|
142
147
|
|
|
143
148
|
**Runs at this level:**
|
|
144
149
|
|
|
145
|
-
- every cloud file: account_memory (template), case_desk (template), draft_review (template), intake_extractor (template), research_brief (template), research_desk (template), review_panel (template), support_triage (template), systems_operator (template), ares (example), cartographers (example), connectors (example), critic (example), current_events (example), delegation (example), harness (example), hierarchical (example), image_production (example), librarian (example), patient_advocate (example), pipeline (example), research (example), scribe (example), scriptorium (example), style_council (example), syndicate (example), weather (example), claude (example), structured_critic (example), model_zoo (example)
|
|
150
|
+
- every cloud file: account_memory (template), case_desk (template), draft_review (template), intake_extractor (template), research_brief (template), research_desk (template), review_panel (template), support_triage (template), systems_operator (template), ares (example), cartographers (example), connectors (example), critic (example), current_events (example), delegation (example), harness (example), hierarchical (example), image_production (example), librarian (example), patient_advocate (example), pipeline (example), research (example), scribe (example), scriptorium (example), style_council (example), syndicate (example), weather (example), claude (example), structured_critic (example), classifier (example), model_zoo (example)
|
|
146
151
|
|
|
147
152
|
**First commands:**
|
|
148
153
|
|
|
@@ -153,8 +158,9 @@ npx melchizedek-chat --syndicate research_brief
|
|
|
153
158
|
|
|
154
159
|
**Notes:**
|
|
155
160
|
|
|
156
|
-
-
|
|
157
|
-
-
|
|
161
|
+
- web_search runs as the gateway's own search on the gateway path (Vercel's exa_search server tool; OpenRouter's web plugin, the provider's native search where it has one, with citations); MODEL_GATEWAY_SEARCH names the engine or turns it off, MODEL_GATEWAY_SEARCH_RESULTS (default 3) bounds what it folds into the prompt, and xAI's x_search and Collections are dropped; the doctor marks each.
|
|
162
|
+
- A gateway is for billing and breadth, not for grounding: for a search-heavy agent, keep the provider that does the searching on its own key (its native search, citations and all) and let the gateway serve the rest; a direct key beside the gateway key does that by default, and MODEL_GATEWAY_EXCEPT keeps it so under MODEL_GATEWAY_PREFER=gateway.
|
|
163
|
+
- Long-term memory embeds through the gateway when it carries the same embedding model (Vercel carries google/gemini-embedding-001). OpenRouter has no Gemini one: set GOOGLE_GENAI_API_KEY, or MEMORY_EMBEDDING_PROVIDER=openai to embed text-embedding-3-small at 768 through it; a store already embedded with Gemini must be re-embedded if the model changes, and the store refuses a different model at start (the doctor's memory line says what would embed).
|
|
158
164
|
|
|
159
165
|
**Onboarding skill:** `melchizedek-onboard-keys` (`npx melchizedek-setup --level gateway` prints this guide)
|
|
160
166
|
|
package/QUICKSTART.md
CHANGED
|
@@ -24,8 +24,9 @@ are the two most common paths spelled out.
|
|
|
24
24
|
- Optional: **Ollama** ([ollama.com](https://ollama.com)) for the
|
|
25
25
|
open-weight local syndicates; provider keys only for the models you
|
|
26
26
|
actually declare — **Anthropic** (`claude-*`), **OpenAI** (`gpt-*`),
|
|
27
|
-
**xAI** (`grok-*`), **Moonshot** (`kimi-*`), **DeepSeek** (`deepseek-*`)
|
|
28
|
-
|
|
27
|
+
**xAI** (`grok-*`), **Moonshot** (`kimi-*`), **DeepSeek** (`deepseek-*`), **TypeSafe** (`jev-*`, a decision model) — or one
|
|
28
|
+
`MODEL_GATEWAY` key (Vercel AI Gateway or OpenRouter) that serves every cloud id whose direct key is missing, Jev included
|
|
29
|
+
(web search then runs as the gateway's own search; x_search is lost on that path);
|
|
29
30
|
and a free **Supabase project** (only for persistent sessions / memory).
|
|
30
31
|
Not sure which you need? `npm run doctor` tells you, read-only.
|
|
31
32
|
|
|
@@ -260,7 +261,8 @@ console.log(result.text);
|
|
|
260
261
|
|---|---|
|
|
261
262
|
| `Gemini API Key is not configured` | `.env` missing or key not set — step 2. |
|
|
262
263
|
| `[400] Tool call context circulation is not enabled` | The agent's `model:` is too old for agent transfer. Use `gemini-3.8-flash` or newer (all shipped configs already do). |
|
|
263
|
-
| `Model not found` for `claude-*` / `gpt-*` / `grok-*` / `kimi-*` / `deepseek-*` | The matching provider key (`ANTHROPIC_API_KEY` / `OPENAI_API_KEY` / `XAI_API_KEY` / `MOONSHOT_API_KEY` / `DEEPSEEK_API_KEY`) is not set in `.env`, so the provider wasn't registered — `npm run doctor` names the variable. Or set `MODEL_GATEWAY` + `MODEL_GATEWAY_API_KEY` once for every cloud provider (
|
|
264
|
+
| `Model not found` for `claude-*` / `gpt-*` / `grok-*` / `kimi-*` / `deepseek-*` / `jev-*` | The matching provider key (`ANTHROPIC_API_KEY` / `OPENAI_API_KEY` / `XAI_API_KEY` / `MOONSHOT_API_KEY` / `DEEPSEEK_API_KEY` / `TYPESAFE_API_KEY`) is not set in `.env`, so the provider wasn't registered — `npm run doctor` names the variable. Or set `MODEL_GATEWAY` + `MODEL_GATEWAY_API_KEY` once for every cloud provider (web search then runs as the gateway's own). |
|
|
265
|
+
| `TYPESAFE_SCHEMA_REQUIRED` / `TYPESAFE_SCHEMA_UNSUPPORTED` | A `jev-*` agent has no `output.schema`, or one of its properties is not a decision Jev can make. Give every property a decision shape: a boolean, a string with `enum` or a `oneOf` of described constants, or an integer whose `oneOf` describes the levels 0..n-1; the error names the property. `examples/classifier.yaml` is the pattern. |
|
|
264
266
|
| `GATEWAY_HTTP_ERROR … 404/400` | The gateway rejected the mapped model id. Fix the name once in `.env`: `MODEL_GATEWAY_MODEL_MAP=<your id>=<the gateway's id>`. `GATEWAY_KEY_MISSING` means `MODEL_GATEWAY` is set without `MODEL_GATEWAY_API_KEY`. |
|
|
265
267
|
| `OLLAMA_UNREACHABLE` for `ollama/*` | Ollama isn't running — start the app or `ollama serve`; then check the model is pulled (`ollama list`). |
|
|
266
268
|
| `Refusing to connect to private/loopback MCP host` | The SSRF guard is on (correctly). For the local demo set `ALLOW_PRIVATE_MCP=true` in `.env`. |
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A multi-model, multi-agent orchestration framework with its own agent loop, model contract, tools, sessions and workflow engine. Agent hierarchies, prompts, models, tools, and delegation rules are declared in YAML files called **Syndicates**; the engine in `lib/` runs whatever you put in `config/agents/`.
|
|
4
4
|
|
|
5
|
-
Gemini, Claude, GPT, Grok, Kimi, and DeepSeek each run on the engine's own adapter for their provider's API, and open-weight models run locally through Ollama with no API key. A subagent can also pick up tools at runtime from a Model Context Protocol (MCP) server.
|
|
5
|
+
Gemini, Claude, GPT, Grok, Kimi, and DeepSeek each run on the engine's own adapter for their provider's API, TypeSafe's Jev answers a classifier's schema as calibrated decisions, and open-weight models run locally through Ollama with no API key. One Vercel AI Gateway or OpenRouter key serves every cloud model you have no direct key for. A subagent can also pick up tools at runtime from a Model Context Protocol (MCP) server.
|
|
6
6
|
|
|
7
7
|
> Companion repository for the curriculum at [lyceumagents.com/curriculum](https://lyceumagents.com/curriculum/). The framework works standalone or alongside the course.
|
|
8
8
|
|
|
@@ -11,7 +11,7 @@ Gemini, Claude, GPT, Grok, Kimi, and DeepSeek each run on the engine's own adapt
|
|
|
11
11
|
## Features
|
|
12
12
|
|
|
13
13
|
- **Declarative YAML configuration** — Orchestrators, subagents, routing, output schemas, and tool assignments in one readable document. Tools and guards are registered in code; YAML names them.
|
|
14
|
-
- **Multi-model routing** — Mix providers within the same agent graph (`gemini-*`, `claude-*`, `gpt-*`, `grok-*`, `kimi-*`, `deepseek-*`, and local `ollama/*`). Switching an agent's model is a one-line change.
|
|
14
|
+
- **Multi-model routing** — Mix providers within the same agent graph (`gemini-*`, `claude-*`, `gpt-*`, `grok-*`, `kimi-*`, `deepseek-*`, `jev-*`, and local `ollama/*`). Switching an agent's model is a one-line change, and one gateway key (`MODEL_GATEWAY`) stands in for every direct key you have not set.
|
|
15
15
|
- **MCP integration** — Give an agent an `mcp_server_url:`, or several servers under `mcp_servers:`, and their tools are discovered over Streamable HTTP (or legacy SSE) and wrapped as agent tools at runtime. URLs are SSRF-guarded; an OAuth server with no pre-issued client is discovered and registered at, within the operator's host allowlist. In the other direction, `melchizedek-mcp` serves your syndicates as MCP tools to Claude Code, Codex and other MCP clients.
|
|
16
16
|
- **Persistent sessions & long-term memory** — Optional Supabase backend for session persistence and pgvector memory: transcripts are distilled into structured records and recalled by similarity in later sessions. Without it, sessions run in memory.
|
|
17
17
|
- **Native tools** — Web search, image generation, and a blind image-inventory tool that accepts only a file path, so the expected result can never reach the observer.
|
|
@@ -50,13 +50,15 @@ npm run syndicate:council
|
|
|
50
50
|
|
|
51
51
|
### 2. Cloud models
|
|
52
52
|
|
|
53
|
+
The quickest way to every cloud model is one gateway key: set `MODEL_GATEWAY=vercel` (or `openrouter`) and `MODEL_GATEWAY_API_KEY` in `.env`, and every shipped syndicate runs, billed to that one account (web search runs as the gateway's own search, and xAI's x_search is the one tool a gateway cannot run; a direct key set beside it wins for its provider by default, and `MODEL_GATEWAY_PREFER=gateway` turns that round, with `MODEL_GATEWAY_EXCEPT` for the providers that take the opposite). Or bring the providers' own keys:
|
|
54
|
+
|
|
53
55
|
```bash
|
|
54
56
|
cp .env.example .env # add GOOGLE_GENAI_API_KEY (free from Google AI Studio)
|
|
55
57
|
npm run chat:syndicate # interactive REPL with the default syndicate (Gemini)
|
|
56
58
|
npm run doctor # shows which syndicates your current keys unlock
|
|
57
59
|
```
|
|
58
60
|
|
|
59
|
-
Other providers are optional: `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `XAI_API_KEY`, `MOONSHOT_API_KEY`, and `
|
|
61
|
+
Other providers are optional: `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `XAI_API_KEY`, `MOONSHOT_API_KEY`, `DEEPSEEK_API_KEY` and `TYPESAFE_API_KEY` unlock the syndicates that use them (for example `npm run syndicate:claude`, or `npm run syndicate:classifier` for the Jev decision model).
|
|
60
62
|
|
|
61
63
|
Test the providers you have keys for:
|
|
62
64
|
|
|
@@ -199,6 +201,7 @@ Configurations live in `config/agents/examples/` and each demonstrates a differe
|
|
|
199
201
|
| `council.yaml` | Advocate/skeptic council weighed by an orchestrator (local) | [1.05 · Workflows & Voice](https://lyceumagents.com/curriculum/workflows-and-voice/) |
|
|
200
202
|
| `critic.yaml` | Drafter → Critic loop that re-drafts until a parsed confidence score clears the bar | [1.04 · Testing & Refinement](https://lyceumagents.com/curriculum/testing-and-refinement/) |
|
|
201
203
|
| `structured_critic.yaml` | The critic as one agent: it delegates to a Drafter, then answers in its own JSON schema (Claude) | — |
|
|
204
|
+
| `classifier.yaml` | A support-triage classifier on TypeSafe's Jev: the output schema is the questions, the answer is typed decisions with calibrated probabilities | — |
|
|
202
205
|
| `delegation.yaml` | Intent routing to specialists via agent descriptions | [1.05 · Workflows & Voice](https://lyceumagents.com/curriculum/workflows-and-voice/) |
|
|
203
206
|
| `hierarchical.yaml` | Goal decomposition into sequential research and writing stages, then a checked merge | [1.05 · Workflows & Voice](https://lyceumagents.com/curriculum/workflows-and-voice/) |
|
|
204
207
|
| `style_council.yaml` | Three stylists with identical knowledge and different voices, behind one router | [1.05 · Workflows & Voice](https://lyceumagents.com/curriculum/workflows-and-voice/) |
|
|
@@ -209,7 +212,7 @@ Configurations live in `config/agents/examples/` and each demonstrates a differe
|
|
|
209
212
|
| `image_production.yaml` | Spec-first image generation, a blind inventory, and a separate spec auditor | [2.04 · Multimodal Agents](https://lyceumagents.com/curriculum/multimodal-agents/) |
|
|
210
213
|
| `current_events.yaml` | Current-event aggregation and fact-checking: an X researcher and a web researcher report to a tool-free arbiter | [2.05 · Fact-Checking Arbiter](https://lyceumagents.com/curriculum/fact-checking-agent/) |
|
|
211
214
|
| `claude.yaml` | Minimal configuration using the Anthropic adapter | — |
|
|
212
|
-
| `model_zoo.yaml` | One agent per provider (Qwen, Claude, Grok, GPT, Gemini, Kimi, DeepSeek) | — |
|
|
215
|
+
| `model_zoo.yaml` | One agent per chat provider (Qwen, Claude, Grok, GPT, Gemini, Kimi, DeepSeek); Jev, a decision model, has `classifier.yaml` | — |
|
|
213
216
|
| `research.yaml` | Plan-and-dispatch over keyless clinical and literature sources, with an identifier and retraction guard | — |
|
|
214
217
|
| `scriptorium.yaml` | Agents over the `wiki/` bundle: answer with citations, author through a validated save gate | — |
|
|
215
218
|
| `cartographers.yaml` | Agents that record the judgments in the wiki's prose as graph relations | — |
|