The lifecycle of a request
Melchizedek is a headless Node.js framework built on the Google Agent Development Kit. This walkthrough follows an incoming message from initial file loading through state compilation, tool execution, and long-term memory distillation.
-
File loading
The loader reads a single syndicate YAML file from your agents directory, confining all paths to that root. It interpolates every binding variable and injects a fresh current_date value on execution. The resulting typed configuration defines the orchestrator, its subagents, assigned model identifiers, tool schemas, instruction blocks, and the active memory mode.
loadSyndicate('augustin.yaml') → { orchestrator, subagents: [XResearcher, WebResearcher], memory_system: 'session-only' } -
Graph compilation
The runtime instantiates an ADK agent for each entry using its designated model identifier. A prefix routing table directs requests to provider adapters, which normalize tool schemas across Gemini, Claude, GPT, Grok, and local models. The framework compiles this execution graph fresh for every request, keeping the HTTP server stateless.
gemini-* → native ADK claude-* → lib/models/claudeLlm gpt-* → lib/models/gptLlm grok-* → lib/models/grokLlm ollama/* → lib/models/ollamaLlm (no key) -
Orchestrator delegation
The orchestrator evaluates incoming messages and calls the subagent whose description fits. The description defines the routing interface while the instruction block determines behavior. A subagent configured without tools reads only what peer agents provide, isolating evaluation logic in designs such as Augustin’s arbiter.
orchestrator → XResearcher (x_api_search) → WebResearcher (web_search, web_extract) → arbitration, with no tools -
Tool execution
A tool definition specifies a name, description, Zod schema, and execution function. From this single contract, the runtime generates the model-facing function definition and the MCP entry. Schema validation failures return to the model as plain error text rather than process exceptions. Subagents that name an external MCP server discover remote tools dynamically at runtime.
defineTool({ name, description, schema, execute }) → toFunctionTool() // for the model → toMcpToolDefinition() // for MCP clients -
Telemetry in the ledger
When telemetry is enabled, execution records write to three tiers: adk_turns stores one row per turn as the system of record, adk_telemetry records individual spans, and adk_payloads holds sampled full prompts with a thirty-day expiration. External dashboards query these tables, and evaluation suites can grade historical turns to gate automated deployments.
adk_turns one row per turn adk_telemetry one row per span adk_payloads sampled prompts, 30-day expiry -
Memory distillation
When a long-term session closes, the pipeline distills conversation transcripts into discrete one-line facts stored in Supabase pgvector. Each record includes a timestamp, source reference, status flag, and associated entities. Incoming corrections mark prior facts superseded. Retrieval combines vector similarity search with in-process re-ranking across entities and dates. Every record remains partitioned by user identifier and subject to deletion.
fact: "prefers the 20-day window for the daily read" date: 2026-09-12 source: session status: active keys: [window, daily-read]
Four patterns from the starter pack
Each pattern is one starter-pack file. Choosing a pattern redraws the constellation beside its source file, replays the route a captured run took, and hovering a star lights the lines in the file that declare it.
In this router pattern, RouterAgent reads the request and hands it whole to CodeExpert or MathExpert, running gemini-3.8-flash, then returns that answer. In the captured run, RouterAgent called CodeExpert.
Hover a star to light the lines declaring that agent or tool
syndicate_name: "Delegation Router Workflow"
variables:
# Example variables
domain: "general knowledge"
orchestrator:
name: "RouterAgent"
model: "gemini-3.8-flash"
instruction: |
You are a triage router.
You do NOT answer questions directly if they require specialized knowledge.
Instead, you examine the user's request and delegate to the appropriate specialist:
- If the user asks a coding or programming question, delegate to CodeExpert.
- If the user asks a math or calculation question, delegate to MathExpert.
- If it's a general greeting or unrelated to those domains, answer it yourself concisely.
subagents:
- name: "CodeExpert"
model: "gemini-3.8-flash"
description: "Expert in programming, software development, and debugging."
instruction: |
You are an expert programmer. Provide clean, correct, and well-documented code answers.
- name: "MathExpert"
model: "gemini-3.8-flash"
description: "Expert in mathematics, formulas, and calculations."
instruction: |
You are a math expert. Solve equations and explain the steps clearly.
syndicate_name: "Critic Review Workflow"
# WHY this structure: The ADK enforces that outputSchema cannot co-exist with
# agent transfer (AgentTool) on the same agent. If the orchestrator has both,
# the ADK deadlocks it. Solution: the orchestrator is a plain sequencer that
# routes Drafter → Critic, and the CriticAgent (a leaf with no tools/transfers)
# owns the outputSchema for structured JSON production.
#
# WHY multi-turn internal looping:
# The ADK's runAsync keeps executing within a single user turn as long as the
# orchestrator continues to call tools rather than producing a final response.
# By instructing the orchestrator to inspect the CriticAgent's confidence score
# and re-delegate when it's below a threshold, the syndicate autonomously
# refines answers through multiple Drafter→Critic passes — all within one
# user-facing turn — before surfacing the final result.
orchestrator:
name: "ReviewOrchestrator"
model: "gemini-3.8-flash"
instruction: |
You coordinate an iterative review process between a Drafter and a Critic.
Your goal is to ensure only HIGH-CONFIDENCE answers reach the user.
Follow these steps EXACTLY:
1. Delegate the user's question to DrafterAgent to get an initial answer.
2. Take the DrafterAgent's full response and delegate it to CriticAgent for review.
3. Parse the CriticAgent's JSON response. It contains "message" and "confidence".
4. **CONFIDENCE CHECK** — this is the critical decision point:
- If confidence >= 85: Return the CriticAgent's full JSON directly to the user. You are done.
- If confidence < 85: The answer is NOT good enough. You MUST loop:
a. Send the CriticAgent's feedback BACK to DrafterAgent with specific instructions
on what to improve (cite the Critic's concerns).
b. Take the DrafterAgent's revised answer and send it to CriticAgent again.
c. Repeat from step 4.
5. You may loop up to 3 times maximum. After 3 rounds, return whatever the
CriticAgent's latest response is, regardless of confidence.
6. Always return the raw JSON from CriticAgent as your final output. Do NOT paraphrase it.
subagents:
- name: "DrafterAgent"
model: "gemini-3.8-flash"
description: "Creates comprehensive initial draft answers for any user query. On subsequent rounds, revises its draft based on Critic feedback."
instruction: |
You are the Drafter. When given a query, produce a thorough initial answer.
Focus on gathering all necessary facts and providing a complete response.
If you receive feedback from the Critic about a previous draft, carefully address
every concern raised and produce an improved, more accurate revision.
- name: "CriticAgent"
model: "gemini-3.8-flash"
description: "Reviews a draft answer for accuracy and returns a structured JSON with the refined message and a confidence score. Low scores trigger re-drafting."
generateContentConfig:
responseMimeType: "application/json"
outputSchema:
type: "OBJECT"
properties:
message:
type: "STRING"
description: "The final, improved and fact-checked response."
confidence:
type: "INTEGER"
description: "A confidence score from 0 to 100 for the accuracy of the final message. Score below 85 means the answer needs improvement."
required: ["message", "confidence"]
instruction: |
You are the Critic. You receive a draft answer from the Drafter.
Review it rigorously for accuracy, clarity, completeness, and logical soundness.
Be honest and precise with your confidence score:
- 90-100: Excellent, factually verified, well-structured
- 70-89: Good but has minor gaps or could be clearer
- Below 70: Significant issues — factual errors, incomplete, or misleading
Output a JSON object with:
- "message": your refined and polished version of the answer
- "confidence": an integer from 0 to 100 representing your confidence in accuracy
syndicate_name: "Hierarchical Task Decomposition"
orchestrator:
name: "ProjectManager"
model: "gemini-3.8-flash"
instruction: |
You are a Project Manager. When given a complex user goal, you practice hierarchical task decomposition.
Instead of answering directly, break the problem into smaller, logical sub-tasks.
1. Delegate data-gathering or analytical tasks to the ResearcherAgent.
2. Delegate formatting, synthesis, or creative writing tasks to the WriterAgent.
3. Once both subagents have returned their work, combine their outputs into a final cohesive response for the user.
Do not skip steps or do the work yourself if a subagent is better suited.
subagents:
- name: "ResearcherAgent"
model: "gemini-3.8-flash"
tools: ["google_search"]
description: "Responsible for gathering facts, performing calculations, and providing raw analytical data."
instruction: |
You are a meticulous Researcher. Use your tools to find factual information, analyze data, and return detailed bullet points to the Project Manager.
- name: "WriterAgent"
model: "gemini-3.8-flash"
description: "Responsible for taking raw data and formatting it into a beautiful, engaging, and structured narrative."
instruction: |
You are an expert Copywriter. Take the raw research provided by the Project Manager and transform it into a polished, well-structured, and engaging response.
# ============================================================
# Council — basic orchestration on open weights
# ============================================================
#
# WHY: The curriculum's first multi-agent specimen (module 1.05).
# Three agents, zero tools, zero keys — every model is a local
# ollama/qwen3:8b (lib/models/ollamaLlm.ts), so the user's first
# orchestration runs entirely on their own machine.
#
# The shape is a COUNCIL: two specialists examine the same claim
# from opposite stances, and the orchestrator weighs their
# independent judgments into one verdict. It teaches the three
# load-bearing ideas of basic orchestration:
# 1. The delegation contract — the orchestrator's instruction
# states, in plain language, who must be consulted and when.
# 2. The description-as-API — the orchestrator decides handoffs
# by reading each subagent's `description` field.
# 3. Independent perspectives — the maker of an argument never
# grades it; the Skeptic exists so enthusiasm meets friction
# before the user does.
#
# Run it: npm run syndicate:council (requires only Ollama +
# `ollama pull qwen3:8b` — no keys, no database)
# ============================================================
syndicate_name: "Council"
memory_system: "internal-only"
orchestrator:
name: "Moderator"
model: "ollama/qwen3:8b"
instruction: |
You are the Moderator of the Council, a small deliberative body that stress-tests claims and plans.
The user brings a claim, a plan, or a decision they are weighing.
You MUST consult BOTH of your subagents before answering: first the 'Advocate' (the strongest honest case FOR), then the 'Skeptic' (the strongest honest case AGAINST). Pass each one the user's claim verbatim.
You never argue a side yourself. Once both reports are in, weigh them and deliver a verdict in exactly this shape:
- THE CASE FOR: the Advocate's two strongest points, compressed.
- THE CASE AGAINST: the Skeptic's two strongest points, compressed.
- THE VERDICT: your own judgment in 2-4 sentences, naming which single consideration weighed most and what evidence would change the answer.
generateContentConfig:
temperature: 0.5
maxOutputTokens: 2048
subagents:
- name: "Advocate"
description: "Builds the strongest honest case FOR a claim or plan. Pass it the user's claim verbatim; it returns the best supporting arguments and evidence."
model: "ollama/qwen3:8b"
instruction: |
You are the Advocate. You receive one claim or plan and build the strongest HONEST case for it.
Return exactly 3 numbered arguments in its favor, each 1-2 sentences, most compelling first.
Honest means: no invented statistics, no strawmanned objections, and if the claim is genuinely weak you say "the honest case is thin" and give what little there is.
generateContentConfig:
temperature: 0.7
maxOutputTokens: 1024
- name: "Skeptic"
description: "Builds the strongest honest case AGAINST a claim or plan. Pass it the user's claim verbatim; it returns the best objections, risks, and failure modes."
model: "ollama/qwen3:8b"
instruction: |
You are the Skeptic. You receive one claim or plan and build the strongest HONEST case against it.
Return exactly 3 numbered objections, each 1-2 sentences, most damaging first — hunting for hidden assumptions, base-rate neglect, and what breaks at scale.
Honest means: real weaknesses only. If the claim is genuinely solid, say "the honest objections are weak" and give what little there is.
generateContentConfig:
temperature: 0.7
maxOutputTokens: 1024
Long-term memory distils and recalls
Press a session to populate the haze around the Patient Advocate figure; the second session introduces a correction that retires an earlier fact to history without deleting it. Recalling by key lights every record from the engine’s verbatim distillation prompt, history included.
- No session has ended yet, so the haze holds nothing.
ActiveHistorical
Surrounding architecture
-
The A2A server
Serve any syndicate as a JSON-RPC endpoint using the Agent-to-Agent protocol. The server publishes an agent card at the well-known path, mounts per-agent routes, enforces bearer token authentication, and accepts bring-your-own-key headers for downstream provider access.
View HTTP guide -
Evaluation suite
A dependency-free Python suite connects to the engine through an NDJSON bridge. It runs script, rubric, and golden judges, calculates bootstrap confidence intervals, calibrates model scores against human annotations, and enforces deployment gates.
-
Knowledge bundles
Export repository documentation as a queryable markdown bundle structured around a typed entity graph. Framework agents maintain the index automatically and expose its contents to external clients over MCP.
Explore bundle tools -
Public release pipeline
The open-source package is generated from the private framework using an allowlist, an overlay, and hard-failing scans for secrets and private names. Before commit, the pipeline builds, packs, and installs the distribution archive in an isolated smoke test.
View repository