@tangle-network/agent-runtime 0.348.1 → 0.350.2
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/dist/{activation-BEGalhOL.js → activation-CfJMyzEs.js} +12 -14
- package/dist/{activation-BEGalhOL.js.map → activation-CfJMyzEs.js.map} +1 -1
- package/dist/{activation-NQZP_mdI.d.ts → activation-DyiHrTlS.d.ts} +2 -24
- package/dist/agent.d.ts +8 -12
- package/dist/agent.js +9 -12
- package/dist/agent.js.map +1 -1
- package/dist/{analyst-loop-DZw5QWT9.js → analyst-loop-BZvXCDKy.js} +2 -3
- package/dist/{analyst-loop-DZw5QWT9.js.map → analyst-loop-BZvXCDKy.js.map} +1 -1
- package/dist/analyst-loop.d.ts +3 -5
- package/dist/analyst-loop.js +1 -2
- package/dist/{bundle-DKQtOO9d.js → bundle-Ze8pd07a.js} +3 -4
- package/dist/{bundle-DKQtOO9d.js.map → bundle-Ze8pd07a.js.map} +1 -1
- package/dist/candidate-execution/index.d.ts +13 -33
- package/dist/candidate-execution/index.js +16 -18
- package/dist/candidate-execution/index.js.map +1 -1
- package/dist/{coordination-manager-Bm6leXc6.js → coordination-manager-BkVfWlMz.js} +101 -132
- package/dist/coordination-manager-BkVfWlMz.js.map +1 -0
- package/dist/{delegate-Cp5-PsaX.js → delegate-DgEie4ad.js} +19 -21
- package/dist/delegate-DgEie4ad.js.map +1 -0
- package/dist/durable.d.ts +13 -23
- package/dist/durable.js +48 -43
- package/dist/durable.js.map +1 -1
- package/dist/{errors-DodWX-cb.js → errors-wuhGvpE3.js} +2 -3
- package/dist/{errors-DodWX-cb.js.map → errors-wuhGvpE3.js.map} +1 -1
- package/dist/{graph-CE_pzU31.js → graph-Cx0FhKSE.js} +192 -15
- package/dist/graph-Cx0FhKSE.js.map +1 -0
- package/dist/{improve-wT11zteg.js → improve-i0HU1-aa.js} +35 -53
- package/dist/{improve-wT11zteg.js.map → improve-i0HU1-aa.js.map} +1 -1
- package/dist/{improvement-adapter-sIthWkcN.d.ts → improvement-adapter-D5GRU1eY.d.ts} +2 -6
- package/dist/index.d.ts +41 -89
- package/dist/index.js +43 -61
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +39 -59
- package/dist/intelligence.js +23 -33
- package/dist/intelligence.js.map +1 -1
- package/dist/kernel.d.ts +5 -5
- package/dist/kernel.js +11 -11
- package/dist/{loop-runner-CZzeeJTG.js → loop-runner-BwN9MhdP.js} +5 -6
- package/dist/{loop-runner-CZzeeJTG.js.map → loop-runner-BwN9MhdP.js.map} +1 -1
- package/dist/{loop-runner-CY5HHhtR.d.ts → loop-runner-DvfOXVx9.d.ts} +3 -5
- package/dist/loop-runner-bin.d.ts +5 -8
- package/dist/loop-runner-bin.js +2 -3
- package/dist/mcp/bin.js +6 -8
- package/dist/mcp/bin.js.map +1 -1
- package/dist/mcp/index.d.ts +8 -18
- package/dist/mcp/index.js +17 -25
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/memory-bin.js +4 -6
- package/dist/mcp/memory-bin.js.map +1 -1
- package/dist/{model-policy-CyCUwHed.js → model-policy-GSxWwP-b.js} +11 -13
- package/dist/model-policy-GSxWwP-b.js.map +1 -0
- package/dist/placement.d.ts +12 -14
- package/dist/placement.js +1 -2
- package/dist/platform.d.ts +7 -13
- package/dist/platform.js +3 -6
- package/dist/platform.js.map +1 -1
- package/dist/{prepare-TEEHSJwq.js → prepare-DE8TQnLu.js} +49 -69
- package/dist/{prepare-TEEHSJwq.js.map → prepare-DE8TQnLu.js.map} +1 -1
- package/dist/{profile-6OLpbjvV.js → profile-CAhZDW2T.js} +58 -92
- package/dist/profile-CAhZDW2T.js.map +1 -0
- package/dist/{profile-materialization-bPm0gGLO.d.ts → profile-materialization-BRY22Oh8.d.ts} +1 -3
- package/dist/profiles.d.ts +25 -12
- package/dist/profiles.js +52 -11
- package/dist/profiles.js.map +1 -1
- package/dist/{protected-model-port-DVVh-hEk.d.ts → protected-model-port-IKqhTypD.d.ts} +2 -14
- package/dist/{protected-redaction-DFCeo4vg.js → protected-redaction-DilFZch5.js} +2 -3
- package/dist/{protected-redaction-DFCeo4vg.js.map → protected-redaction-DilFZch5.js.map} +1 -1
- package/dist/{provision-supervisor-CC0HdOHo.js → provision-supervisor-Bde_FF0R.js} +11 -15
- package/dist/{provision-supervisor-CC0HdOHo.js.map → provision-supervisor-Bde_FF0R.js.map} +1 -1
- package/dist/{record-events-D93DkpAx.js → record-events-B2GUgYdz.js} +12 -14
- package/dist/{record-events-D93DkpAx.js.map → record-events-B2GUgYdz.js.map} +1 -1
- package/dist/{run-cancellation-CzFhQGMa.js → run-cancellation-BLy_Zz-w.js} +6 -7
- package/dist/{run-cancellation-CzFhQGMa.js.map → run-cancellation-BLy_Zz-w.js.map} +1 -1
- package/dist/{runtime-B_40dXlF.js → runtime-6Ec9sHRe.js} +833 -215
- package/dist/runtime-6Ec9sHRe.js.map +1 -0
- package/dist/{runtime-hooks-tXpAarhW.js → runtime-hooks-CsW2pfFk.js} +2 -3
- package/dist/{runtime-hooks-tXpAarhW.js.map → runtime-hooks-CsW2pfFk.js.map} +1 -1
- package/dist/{runtime-hooks-nsqxSUFL.d.ts → runtime-hooks-ZQqPw-0g.d.ts} +1 -3
- package/dist/{sandbox-profile-compat-_fEtHPCj.js → sandbox-profile-compat-BxMQ1VXv.js} +62 -44
- package/dist/sandbox-profile-compat-BxMQ1VXv.js.map +1 -0
- package/dist/{search-executor-COd2F2wp.js → search-executor-B7g_5Wjl.js} +12 -17
- package/dist/search-executor-B7g_5Wjl.js.map +1 -0
- package/dist/{server-BGB4R4wQ.js → server-fvEMwGMQ.js} +19 -30
- package/dist/{server-BGB4R4wQ.js.map → server-fvEMwGMQ.js.map} +1 -1
- package/dist/{structural-rollout-Wl_rCuzM.js → structural-rollout-B86bSixU.js} +69 -70
- package/dist/structural-rollout-B86bSixU.js.map +1 -0
- package/dist/{substrate-CGDFTSRh.js → substrate-Db2pp6y3.js} +2 -3
- package/dist/{substrate-CGDFTSRh.js.map → substrate-Db2pp6y3.js.map} +1 -1
- package/dist/{supervise-BUOeThuB.js → supervise-CaeZcgAW.js} +615 -203
- package/dist/supervise-CaeZcgAW.js.map +1 -0
- package/dist/{supervisor-DDy0aEtR.js → supervisor-C1OePYE-.js} +526 -642
- package/dist/supervisor-C1OePYE-.js.map +1 -0
- package/dist/{task-queue-0fKkoweu.d.ts → task-queue-kefGy79U.d.ts} +1 -3
- package/dist/task-queue.d.ts +1 -1
- package/dist/task-queue.js +1 -2
- package/dist/testing.d.ts +8 -16
- package/dist/testing.js +241 -244
- package/dist/testing.js.map +1 -1
- package/dist/tool-loop.d.ts +16 -19
- package/dist/tool-loop.js +2 -3
- package/dist/{tool-server-XV4aJwoQ.js → tool-server-CwuYeW_Z.js} +3 -4
- package/dist/{tool-server-XV4aJwoQ.js.map → tool-server-CwuYeW_Z.js.map} +1 -1
- package/dist/{top-snapshot-CflmaDgk.js → top-snapshot-ChwpTr7A.js} +4 -5
- package/dist/{top-snapshot-CflmaDgk.js.map → top-snapshot-ChwpTr7A.js.map} +1 -1
- package/dist/tui/bin.js +7 -9
- package/dist/tui/bin.js.map +1 -1
- package/dist/tui/index.d.ts +3 -5
- package/dist/tui/index.js +2 -2
- package/dist/{types-hc4cmSc7.d.ts → types-Fowuwdz2.d.ts} +555 -503
- package/dist/{types-Cwrea-bU.d.ts → types-qsqfyQoY.d.ts} +1 -3
- package/dist/workspace-store/index.d.ts +12 -22
- package/dist/workspace-store/index.js +4 -7
- package/dist/workspace-store/index.js.map +1 -1
- package/dist/{workspace-streams-BiS4ABah.d.ts → workspace-streams-Dq2Fzk3c.d.ts} +1 -11
- package/package.json +25 -25
- package/skills/agent-graphs/SKILL.md +19 -4
- package/skills/be-ambitious/SKILL.md +46 -0
- package/skills/graph-designer/SKILL.md +15 -2
- package/skills/profile-authoring/SKILL.md +1 -1
- package/dist/coordination-manager-Bm6leXc6.js.map +0 -1
- package/dist/delegate-Cp5-PsaX.js.map +0 -1
- package/dist/graph-CE_pzU31.js.map +0 -1
- package/dist/model-policy-CyCUwHed.js.map +0 -1
- package/dist/profile-6OLpbjvV.js.map +0 -1
- package/dist/runtime-B_40dXlF.js.map +0 -1
- package/dist/sandbox-profile-compat-_fEtHPCj.js.map +0 -1
- package/dist/search-executor-COd2F2wp.js.map +0 -1
- package/dist/structural-rollout-Wl_rCuzM.js.map +0 -1
- package/dist/supervise-BUOeThuB.js.map +0 -1
- package/dist/supervisor-DDy0aEtR.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-bin.js","names":[],"sources":["../../src/mcp/memory-server.ts","../../src/mcp/memory-bin.ts"],"sourcesContent":["/**\n * Memory MCP server — the LIVE serving half of the `memory` profile surface\n * (Phase 5). A curated memory (lessons distilled from prior runs) is only\n * real if the DRIVEN agent can query it mid-task; this module serves a flat\n * store of `MemoryItem` rows as `memory_search` / `memory_get` tools over the\n * ONE in-repo stdio JSON-RPC core (`createStdioToolServer`), so the exact\n * wire protocol the same-host client (`connectStdioMcp` /\n * `materializeLocalMcp`, runtime/stdio-mcp-client.ts) speaks is guaranteed by\n * construction — serve and consume cannot drift.\n *\n * Retrieval is DETERMINISTIC lexical overlap (no vectors, no LLM): a lift\n * measured with this memory mounted is attributable to the lessons\n * themselves, never to retrieval-model noise. Every\n * `memory_search` can append one JSONL row to a retrieval log (`logPath`) —\n * the per-query record an off-policy retrieval estimator (agent-knowledge's\n * `RetrievalHoldout`) consumes. agent-knowledge is NOT a dependency of this\n * repo, so the log file is the flagged cross-package seam, not an import.\n *\n * Fail-loud discipline (mirrors `materializeLocalMcp`): an EMPTY memory is\n * never served — a profile without memory simply omits the artifact, and\n * silently serving zero rows would fake the with/without ablation.\n *\n * @experimental\n */\n\nimport { appendFileSync, mkdirSync, readFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { ValidationError } from '../errors'\nimport { createStdioToolServer, type McpToolDescriptor, type StdioToolServer } from './tool-server'\n\n/** One row of agent memory: a crisp lesson/fact with provenance. */\nexport interface MemoryItem {\n /** Stable id (content-hash by convention; see `memoryArtifactFromLessons`). */\n id: string\n /** The lesson itself — one imperative or observation the agent should recall. */\n text: string\n /** Optional retrieval tags, matched by `memory_search` alongside the text. */\n tags?: string[]\n /** Provenance: the finding / trace / curation pass this row came from. */\n source?: string\n}\n\n/** Env var naming the durable row store file the memory bin loads (the\n * `memoryMcpServer` ↔ memory-bin contract). */\nexport const MEMORY_FILE_ENV = 'AGENT_MEMORY_FILE'\n/** Env var carrying inline JSON `MemoryItem` rows (win over file rows on id). */\nexport const MEMORY_ITEMS_ENV = 'AGENT_MEMORY_ITEMS'\n/** Env var naming the JSONL retrieval log (one row per `memory_search`). */\nconst MEMORY_LOG_ENV = 'AGENT_MEMORY_LOG'\n/** Env var overriding the served display name (default 'agent-memory'). */\nconst MEMORY_NAME_ENV = 'AGENT_MEMORY_NAME'\n\ninterface CreateMemoryToolServerOptions {\n /** The rows to serve. MUST be non-empty (an empty memory is never served). */\n items: readonly MemoryItem[]\n /** Server display name surfaced via `initialize`. Default 'agent-memory'. */\n serverName?: string\n /** Server version surfaced via `initialize`. Default '0'. */\n serverVersion?: string\n /** Default result count for `memory_search`. Default 5. */\n defaultK?: number\n /** Append one JSONL row per `memory_search` (the retrieval-holdout seam). */\n logPath?: string\n}\n\n/**\n * Build the memory MCP server: `memory_search` (lexical top-k over the rows)\n * and `memory_get` (one row by id) on the generic stdio JSON-RPC core.\n */\nexport function createMemoryToolServer(opts: CreateMemoryToolServerOptions): StdioToolServer {\n if (opts.items.length === 0) {\n throw new ValidationError(\n 'createMemoryToolServer: refusing to serve an EMPTY memory — a profile without memory omits the artifact; serving zero rows would fake the with/without ablation',\n )\n }\n const byId = new Map<string, MemoryItem>()\n for (const item of opts.items) {\n if (byId.has(item.id)) {\n throw new ValidationError(`createMemoryToolServer: duplicate memory item id '${item.id}'`)\n }\n byId.set(item.id, item)\n }\n const items = [...byId.values()]\n const defaultK = opts.defaultK ?? 5\n const logPath = opts.logPath\n if (logPath) mkdirSync(dirname(logPath), { recursive: true })\n\n const search: McpToolDescriptor = {\n name: 'memory_search',\n description:\n 'Search the agent memory of lessons learned from prior runs. Give what you are about to do or the problem you face; returns the top-k lessons ranked by relevance. Consult it BEFORE repeating work a prior run already learned from.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'The task/problem at hand — matched against lesson text and tags.',\n },\n k: { type: 'number', description: `Max results (default ${defaultK}).` },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Only return items carrying at least one of these tags.',\n },\n },\n required: ['query'],\n },\n handler: async (raw) => {\n const args = (raw ?? {}) as { query?: unknown; k?: unknown; tags?: unknown }\n if (typeof args.query !== 'string' || args.query.trim().length === 0) {\n throw new TypeError('memory_search: query must be a non-empty string')\n }\n const k = args.k === undefined ? defaultK : Math.floor(Number(args.k))\n if (!Number.isFinite(k) || k < 1) {\n throw new TypeError('memory_search: k must be a positive integer')\n }\n let tagFilter: string[] | undefined\n if (args.tags !== undefined) {\n if (!Array.isArray(args.tags) || args.tags.some((t) => typeof t !== 'string')) {\n throw new TypeError('memory_search: tags must be an array of strings')\n }\n tagFilter = args.tags as string[]\n }\n const queryTokens = tokenize(args.query)\n const pool = tagFilter\n ? items.filter((i) => (i.tags ?? []).some((t) => tagFilter.includes(t)))\n : items\n const results = pool\n .map((item) => ({ item, score: scoreItem(queryTokens, item) }))\n .filter((r) => r.score > 0)\n // Highest score first; stable on ties (curation order is the tiebreak).\n .sort((a, b) => b.score - a.score)\n .slice(0, k)\n .map(({ item, score }) => ({\n id: item.id,\n text: item.text,\n score: Number(score.toFixed(4)),\n ...(item.tags ? { tags: item.tags } : {}),\n ...(item.source ? { source: item.source } : {}),\n }))\n if (logPath) {\n // The retrieval log: what was asked, what came back, at what rank —\n // exactly the per-query record an off-policy estimator needs.\n appendFileSync(\n logPath,\n `${JSON.stringify({\n ts: new Date().toISOString(),\n query: args.query,\n k,\n returned: results.map((r) => ({ id: r.id, score: r.score })),\n })}\\n`,\n )\n }\n return { query: args.query, results }\n },\n }\n\n const get: McpToolDescriptor = {\n name: 'memory_get',\n description: 'Fetch one memory item verbatim by its id (ids come from memory_search results).',\n inputSchema: {\n type: 'object',\n properties: { id: { type: 'string', description: 'The memory item id.' } },\n required: ['id'],\n },\n handler: async (raw) => {\n const args = (raw ?? {}) as { id?: unknown }\n if (typeof args.id !== 'string' || args.id.trim().length === 0) {\n throw new TypeError('memory_get: id must be a non-empty string')\n }\n const item = byId.get(args.id)\n if (!item) throw new Error(`memory_get: no memory item with id '${args.id}'`)\n return item\n },\n }\n\n return createStdioToolServer({\n serverName: opts.serverName ?? 'agent-memory',\n serverVersion: opts.serverVersion ?? '0',\n tools: [search, get],\n })\n}\n\n/** Coerce an untrusted JSON array into validated `MemoryItem` rows. */\nexport function parseMemoryItems(value: unknown, source: string): MemoryItem[] {\n if (!Array.isArray(value)) {\n throw new ValidationError(`${source}: expected a JSON array of memory items`)\n }\n return value.map((row, i) => coerceMemoryItem(row, `${source}[${i}]`))\n}\n\n/** Read a memory store file: a JSON array, or JSONL (one `MemoryItem` per line). */\nexport function readMemoryItemsFile(path: string): MemoryItem[] {\n let raw: string\n try {\n raw = readFileSync(path, 'utf8')\n } catch (err) {\n throw new ValidationError(\n `readMemoryItemsFile: cannot read '${path}': ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n const trimmed = raw.trim()\n if (trimmed.length === 0) return []\n if (trimmed.startsWith('[')) {\n let parsed: unknown\n try {\n parsed = JSON.parse(trimmed)\n } catch (err) {\n throw new ValidationError(\n `readMemoryItemsFile: '${path}' is not valid JSON: ${(err as Error).message}`,\n )\n }\n return parseMemoryItems(parsed, path)\n }\n return trimmed\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .map((line, i) => {\n let parsed: unknown\n try {\n parsed = JSON.parse(line)\n } catch (err) {\n throw new ValidationError(\n `readMemoryItemsFile: '${path}' line ${i + 1} is not valid JSON: ${(err as Error).message}`,\n )\n }\n return coerceMemoryItem(parsed, `${path}:${i + 1}`)\n })\n}\n\n/** What the memory bin resolved from its environment. */\ninterface ResolvedMemoryEnv {\n items: MemoryItem[]\n serverName?: string\n logPath?: string\n}\n\n/**\n * Resolve the bin's memory from `AGENT_MEMORY_FILE` (durable store) and/or\n * `AGENT_MEMORY_ITEMS` (inline JSON rows; wins on id collision). Zero rows is\n * a boot FAILURE, matching the fail-closed materialization discipline.\n */\nexport function resolveMemoryFromEnv(env: Record<string, string | undefined>): ResolvedMemoryEnv {\n const filePath = env[MEMORY_FILE_ENV]\n const inlineRaw = env[MEMORY_ITEMS_ENV]\n const fromFile = filePath ? readMemoryItemsFile(filePath) : []\n let inline: MemoryItem[] = []\n if (inlineRaw) {\n let parsed: unknown\n try {\n parsed = JSON.parse(inlineRaw)\n } catch (err) {\n throw new ValidationError(\n `${MEMORY_ITEMS_ENV} is not valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n inline = parseMemoryItems(parsed, MEMORY_ITEMS_ENV)\n }\n const byId = new Map<string, MemoryItem>()\n for (const item of fromFile) byId.set(item.id, item)\n for (const item of inline) byId.set(item.id, item)\n if (byId.size === 0) {\n throw new ValidationError(\n `memory bin: no memory items — set ${MEMORY_FILE_ENV} and/or ${MEMORY_ITEMS_ENV}; an EMPTY memory must never be served (a profile without memory omits the artifact)`,\n )\n }\n const serverName = env[MEMORY_NAME_ENV]\n const logPath = env[MEMORY_LOG_ENV]\n return {\n items: [...byId.values()],\n ...(serverName ? { serverName } : {}),\n ...(logPath ? { logPath } : {}),\n }\n}\n\nfunction coerceMemoryItem(row: unknown, at: string): MemoryItem {\n if (!row || typeof row !== 'object' || Array.isArray(row)) {\n throw new ValidationError(`${at}: memory item must be an object`)\n }\n const r = row as Record<string, unknown>\n if (typeof r.id !== 'string' || r.id.trim().length === 0) {\n throw new ValidationError(`${at}: 'id' must be a non-empty string`)\n }\n if (typeof r.text !== 'string' || r.text.trim().length === 0) {\n throw new ValidationError(`${at}: 'text' must be a non-empty string`)\n }\n let tags: string[] | undefined\n if (r.tags !== undefined) {\n if (!Array.isArray(r.tags) || r.tags.some((t) => typeof t !== 'string')) {\n throw new ValidationError(`${at}: 'tags' must be an array of strings`)\n }\n tags = r.tags as string[]\n }\n if (r.source !== undefined && typeof r.source !== 'string') {\n throw new ValidationError(`${at}: 'source' must be a string`)\n }\n return {\n id: r.id,\n text: r.text,\n ...(tags ? { tags } : {}),\n ...(typeof r.source === 'string' ? { source: r.source } : {}),\n }\n}\n\n/** Unique lowercase alphanumeric tokens of length >= 2. */\nfunction tokenize(text: string): string[] {\n return [\n ...new Set(\n text\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((t) => t.length >= 2),\n ),\n ]\n}\n\n/** Fraction of query tokens present in the item's text + tags (0..1). */\nfunction scoreItem(queryTokens: readonly string[], item: MemoryItem): number {\n if (queryTokens.length === 0) return 0\n const hay = new Set(tokenize(`${item.text} ${(item.tags ?? []).join(' ')}`))\n let hit = 0\n for (const t of queryTokens) if (hay.has(t)) hit += 1\n return hit / queryTokens.length\n}\n","#!/usr/bin/env node\n\n/**\n * `agent-runtime-memory-mcp` — stdio memory MCP server entry point.\n *\n * Serves `memory_search` / `memory_get` over an agent's curated memory rows,\n * on the generic in-repo JSON-RPC core (`createStdioToolServer`). This is the\n * process `memoryMcpServer` (lifecycle/memory.ts) mounts into `profile.mcp`,\n * which the same-host client (`materializeLocalMcp`) spawns next to the\n * driven worker during a scored run.\n *\n * Environment variables (the `memoryMcpServer` contract):\n * AGENT_MEMORY_FILE optional — path to the durable row store (JSON array\n * or JSONL of MemoryItem).\n * AGENT_MEMORY_ITEMS optional — inline JSON array of MemoryItem rows;\n * wins over file rows on id collision.\n * AGENT_MEMORY_LOG optional — JSONL retrieval log, one row per\n * memory_search (the retrieval-holdout seam).\n * AGENT_MEMORY_NAME optional — server display name (default 'agent-memory').\n *\n * At least one of AGENT_MEMORY_FILE / AGENT_MEMORY_ITEMS must resolve rows:\n * an EMPTY memory refuses to boot (fail-closed, so a memory-carrying profile\n * whose store is missing fails the materialization, never a silent no-tool run).\n *\n * @experimental\n */\n\nimport { createMemoryToolServer, resolveMemoryFromEnv } from './memory-server'\n\nasync function main(): Promise<void> {\n const { items, serverName, logPath } = resolveMemoryFromEnv(process.env)\n const server = createMemoryToolServer({\n items,\n ...(serverName ? { serverName } : {}),\n ...(logPath ? { logPath } : {}),\n })\n await server.serve()\n}\n\nmain().catch((err: unknown) => {\n console.error(`agent-runtime-memory-mcp: ${err instanceof Error ? err.message : String(err)}`)\n process.exit(1)\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,MAAa,kBAAkB;;AAE/B,MAAa,mBAAmB;;AAEhC,MAAM,iBAAiB;;AAEvB,MAAM,kBAAkB;;;;;AAmBxB,SAAgB,uBAAuB,MAAsD;CAC3F,IAAI,KAAK,MAAM,WAAW,GACxB,MAAM,IAAI,gBACR,iKACF;CAEF,MAAM,uBAAO,IAAI,IAAwB;CACzC,KAAK,MAAM,QAAQ,KAAK,OAAO;EAC7B,IAAI,KAAK,IAAI,KAAK,EAAE,GAClB,MAAM,IAAI,gBAAgB,qDAAqD,KAAK,GAAG,EAAE;EAE3F,KAAK,IAAI,KAAK,IAAI,IAAI;CACxB;CACA,MAAM,QAAQ,CAAC,GAAG,KAAK,OAAO,CAAC;CAC/B,MAAM,WAAW,KAAK,YAAY;CAClC,MAAM,UAAU,KAAK;CACrB,IAAI,SAAS,UAAU,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;CAE5D,MAAM,SAA4B;EAChC,MAAM;EACN,aACE;EACF,aAAa;GACX,MAAM;GACN,YAAY;IACV,OAAO;KACL,MAAM;KACN,aAAa;IACf;IACA,GAAG;KAAE,MAAM;KAAU,aAAa,wBAAwB,SAAS;IAAI;IACvE,MAAM;KACJ,MAAM;KACN,OAAO,EAAE,MAAM,SAAS;KACxB,aAAa;IACf;GACF;GACA,UAAU,CAAC,OAAO;EACpB;EACA,SAAS,OAAO,QAAQ;GACtB,MAAM,OAAQ,OAAO,CAAC;GACtB,IAAI,OAAO,KAAK,UAAU,YAAY,KAAK,MAAM,KAAK,CAAC,CAAC,WAAW,GACjE,MAAM,IAAI,UAAU,iDAAiD;GAEvE,MAAM,IAAI,KAAK,MAAM,KAAA,IAAY,WAAW,KAAK,MAAM,OAAO,KAAK,CAAC,CAAC;GACrE,IAAI,CAAC,OAAO,SAAS,CAAC,KAAK,IAAI,GAC7B,MAAM,IAAI,UAAU,6CAA6C;GAEnE,IAAI;GACJ,IAAI,KAAK,SAAS,KAAA,GAAW;IAC3B,IAAI,CAAC,MAAM,QAAQ,KAAK,IAAI,KAAK,KAAK,KAAK,MAAM,MAAM,OAAO,MAAM,QAAQ,GAC1E,MAAM,IAAI,UAAU,iDAAiD;IAEvE,YAAY,KAAK;GACnB;GACA,MAAM,cAAc,SAAS,KAAK,KAAK;GAIvC,MAAM,WAHO,YACT,MAAM,QAAQ,OAAO,EAAE,QAAQ,CAAC,EAAA,CAAG,MAAM,MAAM,UAAU,SAAS,CAAC,CAAC,CAAC,IACrE,MAAA,CAED,KAAK,UAAU;IAAE;IAAM,OAAO,UAAU,aAAa,IAAI;GAAE,EAAE,CAAC,CAC9D,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,CAE1B,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CACjC,MAAM,GAAG,CAAC,CAAC,CACX,KAAK,EAAE,MAAM,aAAa;IACzB,IAAI,KAAK;IACT,MAAM,KAAK;IACX,OAAO,OAAO,MAAM,QAAQ,CAAC,CAAC;IAC9B,GAAI,KAAK,OAAO,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;IACvC,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;GAC/C,EAAE;GACJ,IAAI,SAGF,eACE,SACA,GAAG,KAAK,UAAU;IAChB,qBAAI,IAAI,KAAK,EAAA,CAAE,YAAY;IAC3B,OAAO,KAAK;IACZ;IACA,UAAU,QAAQ,KAAK,OAAO;KAAE,IAAI,EAAE;KAAI,OAAO,EAAE;IAAM,EAAE;GAC7D,CAAC,EAAE,GACL;GAEF,OAAO;IAAE,OAAO,KAAK;IAAO;GAAQ;EACtC;CACF;CAqBA,OAAO,sBAAsB;EAC3B,YAAY,KAAK,cAAc;EAC/B,eAAe,KAAK,iBAAiB;EACrC,OAAO,CAAC,QAAQ;GArBhB,MAAM;GACN,aAAa;GACb,aAAa;IACX,MAAM;IACN,YAAY,EAAE,IAAI;KAAE,MAAM;KAAU,aAAa;IAAsB,EAAE;IACzE,UAAU,CAAC,IAAI;GACjB;GACA,SAAS,OAAO,QAAQ;IACtB,MAAM,OAAQ,OAAO,CAAC;IACtB,IAAI,OAAO,KAAK,OAAO,YAAY,KAAK,GAAG,KAAK,CAAC,CAAC,WAAW,GAC3D,MAAM,IAAI,UAAU,2CAA2C;IAEjE,MAAM,OAAO,KAAK,IAAI,KAAK,EAAE;IAC7B,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,uCAAuC,KAAK,GAAG,EAAE;IAC5E,OAAO;GACT;EAMkB,CAAC;CACrB,CAAC;AACH;;AAGA,SAAgB,iBAAiB,OAAgB,QAA8B;CAC7E,IAAI,CAAC,MAAM,QAAQ,KAAK,GACtB,MAAM,IAAI,gBAAgB,GAAG,OAAO,wCAAwC;CAE9E,OAAO,MAAM,KAAK,KAAK,MAAM,iBAAiB,KAAK,GAAG,OAAO,GAAG,EAAE,EAAE,CAAC;AACvE;;AAGA,SAAgB,oBAAoB,MAA4B;CAC9D,IAAI;CACJ,IAAI;EACF,MAAM,aAAa,MAAM,MAAM;CACjC,SAAS,KAAK;EACZ,MAAM,IAAI,gBACR,qCAAqC,KAAK,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GAChG;CACF;CACA,MAAM,UAAU,IAAI,KAAK;CACzB,IAAI,QAAQ,WAAW,GAAG,OAAO,CAAC;CAClC,IAAI,QAAQ,WAAW,GAAG,GAAG;EAC3B,IAAI;EACJ,IAAI;GACF,SAAS,KAAK,MAAM,OAAO;EAC7B,SAAS,KAAK;GACZ,MAAM,IAAI,gBACR,yBAAyB,KAAK,uBAAwB,IAAc,SACtE;EACF;EACA,OAAO,iBAAiB,QAAQ,IAAI;CACtC;CACA,OAAO,QACJ,MAAM,IAAI,CAAC,CACX,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,QAAQ,SAAS,KAAK,SAAS,CAAC,CAAC,CACjC,KAAK,MAAM,MAAM;EAChB,IAAI;EACJ,IAAI;GACF,SAAS,KAAK,MAAM,IAAI;EAC1B,SAAS,KAAK;GACZ,MAAM,IAAI,gBACR,yBAAyB,KAAK,SAAS,IAAI,EAAE,sBAAuB,IAAc,SACpF;EACF;EACA,OAAO,iBAAiB,QAAQ,GAAG,KAAK,GAAG,IAAI,GAAG;CACpD,CAAC;AACL;;;;;;AAcA,SAAgB,qBAAqB,KAA4D;CAC/F,MAAM,WAAW,IAAI;CACrB,MAAM,YAAY,IAAI;CACtB,MAAM,WAAW,WAAW,oBAAoB,QAAQ,IAAI,CAAC;CAC7D,IAAI,SAAuB,CAAC;CAC5B,IAAI,WAAW;EACb,IAAI;EACJ,IAAI;GACF,SAAS,KAAK,MAAM,SAAS;EAC/B,SAAS,KAAK;GACZ,MAAM,IAAI,gBACR,GAAG,iBAAiB,sBAAsB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GAC3F;EACF;EACA,SAAS,iBAAiB,QAAQ,gBAAgB;CACpD;CACA,MAAM,uBAAO,IAAI,IAAwB;CACzC,KAAK,MAAM,QAAQ,UAAU,KAAK,IAAI,KAAK,IAAI,IAAI;CACnD,KAAK,MAAM,QAAQ,QAAQ,KAAK,IAAI,KAAK,IAAI,IAAI;CACjD,IAAI,KAAK,SAAS,GAChB,MAAM,IAAI,gBACR,qCAAqC,gBAAgB,UAAU,iBAAiB,qFAClF;CAEF,MAAM,aAAa,IAAI;CACvB,MAAM,UAAU,IAAI;CACpB,OAAO;EACL,OAAO,CAAC,GAAG,KAAK,OAAO,CAAC;EACxB,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;EACnC,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;CAC/B;AACF;AAEA,SAAS,iBAAiB,KAAc,IAAwB;CAC9D,IAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,GACtD,MAAM,IAAI,gBAAgB,GAAG,GAAG,gCAAgC;CAElE,MAAM,IAAI;CACV,IAAI,OAAO,EAAE,OAAO,YAAY,EAAE,GAAG,KAAK,CAAC,CAAC,WAAW,GACrD,MAAM,IAAI,gBAAgB,GAAG,GAAG,kCAAkC;CAEpE,IAAI,OAAO,EAAE,SAAS,YAAY,EAAE,KAAK,KAAK,CAAC,CAAC,WAAW,GACzD,MAAM,IAAI,gBAAgB,GAAG,GAAG,oCAAoC;CAEtE,IAAI;CACJ,IAAI,EAAE,SAAS,KAAA,GAAW;EACxB,IAAI,CAAC,MAAM,QAAQ,EAAE,IAAI,KAAK,EAAE,KAAK,MAAM,MAAM,OAAO,MAAM,QAAQ,GACpE,MAAM,IAAI,gBAAgB,GAAG,GAAG,qCAAqC;EAEvE,OAAO,EAAE;CACX;CACA,IAAI,EAAE,WAAW,KAAA,KAAa,OAAO,EAAE,WAAW,UAChD,MAAM,IAAI,gBAAgB,GAAG,GAAG,4BAA4B;CAE9D,OAAO;EACL,IAAI,EAAE;EACN,MAAM,EAAE;EACR,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;EACvB,GAAI,OAAO,EAAE,WAAW,WAAW,EAAE,QAAQ,EAAE,OAAO,IAAI,CAAC;CAC7D;AACF;;AAGA,SAAS,SAAS,MAAwB;CACxC,OAAO,CACL,GAAG,IAAI,IACL,KACG,YAAY,CAAC,CACb,MAAM,YAAY,CAAC,CACnB,QAAQ,MAAM,EAAE,UAAU,CAAC,CAChC,CACF;AACF;;AAGA,SAAS,UAAU,aAAgC,MAA0B;CAC3E,IAAI,YAAY,WAAW,GAAG,OAAO;CACrC,MAAM,MAAM,IAAI,IAAI,SAAS,GAAG,KAAK,KAAK,IAAI,KAAK,QAAQ,CAAC,EAAA,CAAG,KAAK,GAAG,GAAG,CAAC;CAC3E,IAAI,MAAM;CACV,KAAK,MAAM,KAAK,aAAa,IAAI,IAAI,IAAI,CAAC,GAAG,OAAO;CACpD,OAAO,MAAM,YAAY;AAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvSA,eAAe,OAAsB;CACnC,MAAM,EAAE,OAAO,YAAY,YAAY,qBAAqB,QAAQ,GAAG;CAMvE,MALe,uBAAuB;EACpC;EACA,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;EACnC,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;CAC/B,CACW,CAAC,CAAC,MAAM;AACrB;AAEA,KAAK,CAAC,CAAC,OAAO,QAAiB;CAC7B,QAAQ,MAAM,6BAA6B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GAAG;CAC7F,QAAQ,KAAK,CAAC;AAChB,CAAC"}
|
|
1
|
+
{"version":3,"file":"memory-bin.js","names":[],"sources":["../../src/mcp/memory-server.ts","../../src/mcp/memory-bin.ts"],"sourcesContent":["/**\n * Memory MCP server — the LIVE serving half of the `memory` profile surface\n * (Phase 5). A curated memory (lessons distilled from prior runs) is only\n * real if the DRIVEN agent can query it mid-task; this module serves a flat\n * store of `MemoryItem` rows as `memory_search` / `memory_get` tools over the\n * ONE in-repo stdio JSON-RPC core (`createStdioToolServer`), so the exact\n * wire protocol the same-host client (`connectStdioMcp` /\n * `materializeLocalMcp`, runtime/stdio-mcp-client.ts) speaks is guaranteed by\n * construction — serve and consume cannot drift.\n *\n * Retrieval is DETERMINISTIC lexical overlap (no vectors, no LLM): a lift\n * measured with this memory mounted is attributable to the lessons\n * themselves, never to retrieval-model noise. Every\n * `memory_search` can append one JSONL row to a retrieval log (`logPath`) —\n * the per-query record an off-policy retrieval estimator (agent-knowledge's\n * `RetrievalHoldout`) consumes. agent-knowledge is NOT a dependency of this\n * repo, so the log file is the flagged cross-package seam, not an import.\n *\n * Fail-loud discipline (mirrors `materializeLocalMcp`): an EMPTY memory is\n * never served — a profile without memory simply omits the artifact, and\n * silently serving zero rows would fake the with/without ablation.\n *\n * @experimental\n */\n\nimport { appendFileSync, mkdirSync, readFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { ValidationError } from '../errors'\nimport { createStdioToolServer, type McpToolDescriptor, type StdioToolServer } from './tool-server'\n\n/** One row of agent memory: a crisp lesson/fact with provenance. */\nexport interface MemoryItem {\n /** Stable id (content-hash by convention; see `memoryArtifactFromLessons`). */\n id: string\n /** The lesson itself — one imperative or observation the agent should recall. */\n text: string\n /** Optional retrieval tags, matched by `memory_search` alongside the text. */\n tags?: string[]\n /** Provenance: the finding / trace / curation pass this row came from. */\n source?: string\n}\n\n/** Env var naming the durable row store file the memory bin loads (the\n * `memoryMcpServer` ↔ memory-bin contract). */\nexport const MEMORY_FILE_ENV = 'AGENT_MEMORY_FILE'\n/** Env var carrying inline JSON `MemoryItem` rows (win over file rows on id). */\nexport const MEMORY_ITEMS_ENV = 'AGENT_MEMORY_ITEMS'\n/** Env var naming the JSONL retrieval log (one row per `memory_search`). */\nconst MEMORY_LOG_ENV = 'AGENT_MEMORY_LOG'\n/** Env var overriding the served display name (default 'agent-memory'). */\nconst MEMORY_NAME_ENV = 'AGENT_MEMORY_NAME'\n\ninterface CreateMemoryToolServerOptions {\n /** The rows to serve. MUST be non-empty (an empty memory is never served). */\n items: readonly MemoryItem[]\n /** Server display name surfaced via `initialize`. Default 'agent-memory'. */\n serverName?: string\n /** Server version surfaced via `initialize`. Default '0'. */\n serverVersion?: string\n /** Default result count for `memory_search`. Default 5. */\n defaultK?: number\n /** Append one JSONL row per `memory_search` (the retrieval-holdout seam). */\n logPath?: string\n}\n\n/**\n * Build the memory MCP server: `memory_search` (lexical top-k over the rows)\n * and `memory_get` (one row by id) on the generic stdio JSON-RPC core.\n */\nexport function createMemoryToolServer(opts: CreateMemoryToolServerOptions): StdioToolServer {\n if (opts.items.length === 0) {\n throw new ValidationError(\n 'createMemoryToolServer: refusing to serve an EMPTY memory — a profile without memory omits the artifact; serving zero rows would fake the with/without ablation',\n )\n }\n const byId = new Map<string, MemoryItem>()\n for (const item of opts.items) {\n if (byId.has(item.id)) {\n throw new ValidationError(`createMemoryToolServer: duplicate memory item id '${item.id}'`)\n }\n byId.set(item.id, item)\n }\n const items = [...byId.values()]\n const defaultK = opts.defaultK ?? 5\n const logPath = opts.logPath\n if (logPath) mkdirSync(dirname(logPath), { recursive: true })\n\n const search: McpToolDescriptor = {\n name: 'memory_search',\n description:\n 'Search the agent memory of lessons learned from prior runs. Give what you are about to do or the problem you face; returns the top-k lessons ranked by relevance. Consult it BEFORE repeating work a prior run already learned from.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'The task/problem at hand — matched against lesson text and tags.',\n },\n k: { type: 'number', description: `Max results (default ${defaultK}).` },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Only return items carrying at least one of these tags.',\n },\n },\n required: ['query'],\n },\n handler: async (raw) => {\n const args = (raw ?? {}) as { query?: unknown; k?: unknown; tags?: unknown }\n if (typeof args.query !== 'string' || args.query.trim().length === 0) {\n throw new TypeError('memory_search: query must be a non-empty string')\n }\n const k = args.k === undefined ? defaultK : Math.floor(Number(args.k))\n if (!Number.isFinite(k) || k < 1) {\n throw new TypeError('memory_search: k must be a positive integer')\n }\n let tagFilter: string[] | undefined\n if (args.tags !== undefined) {\n if (!Array.isArray(args.tags) || args.tags.some((t) => typeof t !== 'string')) {\n throw new TypeError('memory_search: tags must be an array of strings')\n }\n tagFilter = args.tags as string[]\n }\n const queryTokens = tokenize(args.query)\n const pool = tagFilter\n ? items.filter((i) => (i.tags ?? []).some((t) => tagFilter.includes(t)))\n : items\n const results = pool\n .map((item) => ({ item, score: scoreItem(queryTokens, item) }))\n .filter((r) => r.score > 0)\n // Highest score first; stable on ties (curation order is the tiebreak).\n .sort((a, b) => b.score - a.score)\n .slice(0, k)\n .map(({ item, score }) => ({\n id: item.id,\n text: item.text,\n score: Number(score.toFixed(4)),\n ...(item.tags ? { tags: item.tags } : {}),\n ...(item.source ? { source: item.source } : {}),\n }))\n if (logPath) {\n // The retrieval log: what was asked, what came back, at what rank —\n // exactly the per-query record an off-policy estimator needs.\n appendFileSync(\n logPath,\n `${JSON.stringify({\n ts: new Date().toISOString(),\n query: args.query,\n k,\n returned: results.map((r) => ({ id: r.id, score: r.score })),\n })}\\n`,\n )\n }\n return { query: args.query, results }\n },\n }\n\n const get: McpToolDescriptor = {\n name: 'memory_get',\n description: 'Fetch one memory item verbatim by its id (ids come from memory_search results).',\n inputSchema: {\n type: 'object',\n properties: { id: { type: 'string', description: 'The memory item id.' } },\n required: ['id'],\n },\n handler: async (raw) => {\n const args = (raw ?? {}) as { id?: unknown }\n if (typeof args.id !== 'string' || args.id.trim().length === 0) {\n throw new TypeError('memory_get: id must be a non-empty string')\n }\n const item = byId.get(args.id)\n if (!item) throw new Error(`memory_get: no memory item with id '${args.id}'`)\n return item\n },\n }\n\n return createStdioToolServer({\n serverName: opts.serverName ?? 'agent-memory',\n serverVersion: opts.serverVersion ?? '0',\n tools: [search, get],\n })\n}\n\n/** Coerce an untrusted JSON array into validated `MemoryItem` rows. */\nexport function parseMemoryItems(value: unknown, source: string): MemoryItem[] {\n if (!Array.isArray(value)) {\n throw new ValidationError(`${source}: expected a JSON array of memory items`)\n }\n return value.map((row, i) => coerceMemoryItem(row, `${source}[${i}]`))\n}\n\n/** Read a memory store file: a JSON array, or JSONL (one `MemoryItem` per line). */\nexport function readMemoryItemsFile(path: string): MemoryItem[] {\n let raw: string\n try {\n raw = readFileSync(path, 'utf8')\n } catch (err) {\n throw new ValidationError(\n `readMemoryItemsFile: cannot read '${path}': ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n const trimmed = raw.trim()\n if (trimmed.length === 0) return []\n if (trimmed.startsWith('[')) {\n let parsed: unknown\n try {\n parsed = JSON.parse(trimmed)\n } catch (err) {\n throw new ValidationError(\n `readMemoryItemsFile: '${path}' is not valid JSON: ${(err as Error).message}`,\n )\n }\n return parseMemoryItems(parsed, path)\n }\n return trimmed\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .map((line, i) => {\n let parsed: unknown\n try {\n parsed = JSON.parse(line)\n } catch (err) {\n throw new ValidationError(\n `readMemoryItemsFile: '${path}' line ${i + 1} is not valid JSON: ${(err as Error).message}`,\n )\n }\n return coerceMemoryItem(parsed, `${path}:${i + 1}`)\n })\n}\n\n/** What the memory bin resolved from its environment. */\ninterface ResolvedMemoryEnv {\n items: MemoryItem[]\n serverName?: string\n logPath?: string\n}\n\n/**\n * Resolve the bin's memory from `AGENT_MEMORY_FILE` (durable store) and/or\n * `AGENT_MEMORY_ITEMS` (inline JSON rows; wins on id collision). Zero rows is\n * a boot FAILURE, matching the fail-closed materialization discipline.\n */\nexport function resolveMemoryFromEnv(env: Record<string, string | undefined>): ResolvedMemoryEnv {\n const filePath = env[MEMORY_FILE_ENV]\n const inlineRaw = env[MEMORY_ITEMS_ENV]\n const fromFile = filePath ? readMemoryItemsFile(filePath) : []\n let inline: MemoryItem[] = []\n if (inlineRaw) {\n let parsed: unknown\n try {\n parsed = JSON.parse(inlineRaw)\n } catch (err) {\n throw new ValidationError(\n `${MEMORY_ITEMS_ENV} is not valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n inline = parseMemoryItems(parsed, MEMORY_ITEMS_ENV)\n }\n const byId = new Map<string, MemoryItem>()\n for (const item of fromFile) byId.set(item.id, item)\n for (const item of inline) byId.set(item.id, item)\n if (byId.size === 0) {\n throw new ValidationError(\n `memory bin: no memory items — set ${MEMORY_FILE_ENV} and/or ${MEMORY_ITEMS_ENV}; an EMPTY memory must never be served (a profile without memory omits the artifact)`,\n )\n }\n const serverName = env[MEMORY_NAME_ENV]\n const logPath = env[MEMORY_LOG_ENV]\n return {\n items: [...byId.values()],\n ...(serverName ? { serverName } : {}),\n ...(logPath ? { logPath } : {}),\n }\n}\n\nfunction coerceMemoryItem(row: unknown, at: string): MemoryItem {\n if (!row || typeof row !== 'object' || Array.isArray(row)) {\n throw new ValidationError(`${at}: memory item must be an object`)\n }\n const r = row as Record<string, unknown>\n if (typeof r.id !== 'string' || r.id.trim().length === 0) {\n throw new ValidationError(`${at}: 'id' must be a non-empty string`)\n }\n if (typeof r.text !== 'string' || r.text.trim().length === 0) {\n throw new ValidationError(`${at}: 'text' must be a non-empty string`)\n }\n let tags: string[] | undefined\n if (r.tags !== undefined) {\n if (!Array.isArray(r.tags) || r.tags.some((t) => typeof t !== 'string')) {\n throw new ValidationError(`${at}: 'tags' must be an array of strings`)\n }\n tags = r.tags as string[]\n }\n if (r.source !== undefined && typeof r.source !== 'string') {\n throw new ValidationError(`${at}: 'source' must be a string`)\n }\n return {\n id: r.id,\n text: r.text,\n ...(tags ? { tags } : {}),\n ...(typeof r.source === 'string' ? { source: r.source } : {}),\n }\n}\n\n/** Unique lowercase alphanumeric tokens of length >= 2. */\nfunction tokenize(text: string): string[] {\n return [\n ...new Set(\n text\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((t) => t.length >= 2),\n ),\n ]\n}\n\n/** Fraction of query tokens present in the item's text + tags (0..1). */\nfunction scoreItem(queryTokens: readonly string[], item: MemoryItem): number {\n if (queryTokens.length === 0) return 0\n const hay = new Set(tokenize(`${item.text} ${(item.tags ?? []).join(' ')}`))\n let hit = 0\n for (const t of queryTokens) if (hay.has(t)) hit += 1\n return hit / queryTokens.length\n}\n","#!/usr/bin/env node\n\n/**\n * `agent-runtime-memory-mcp` — stdio memory MCP server entry point.\n *\n * Serves `memory_search` / `memory_get` over an agent's curated memory rows,\n * on the generic in-repo JSON-RPC core (`createStdioToolServer`). This is the\n * process `memoryMcpServer` (lifecycle/memory.ts) mounts into `profile.mcp`,\n * which the same-host client (`materializeLocalMcp`) spawns next to the\n * driven worker during a scored run.\n *\n * Environment variables (the `memoryMcpServer` contract):\n * AGENT_MEMORY_FILE optional — path to the durable row store (JSON array\n * or JSONL of MemoryItem).\n * AGENT_MEMORY_ITEMS optional — inline JSON array of MemoryItem rows;\n * wins over file rows on id collision.\n * AGENT_MEMORY_LOG optional — JSONL retrieval log, one row per\n * memory_search (the retrieval-holdout seam).\n * AGENT_MEMORY_NAME optional — server display name (default 'agent-memory').\n *\n * At least one of AGENT_MEMORY_FILE / AGENT_MEMORY_ITEMS must resolve rows:\n * an EMPTY memory refuses to boot (fail-closed, so a memory-carrying profile\n * whose store is missing fails the materialization, never a silent no-tool run).\n *\n * @experimental\n */\n\nimport { createMemoryToolServer, resolveMemoryFromEnv } from './memory-server'\n\nasync function main(): Promise<void> {\n const { items, serverName, logPath } = resolveMemoryFromEnv(process.env)\n const server = createMemoryToolServer({\n items,\n ...(serverName ? { serverName } : {}),\n ...(logPath ? { logPath } : {}),\n })\n await server.serve()\n}\n\nmain().catch((err: unknown) => {\n console.error(`agent-runtime-memory-mcp: ${err instanceof Error ? err.message : String(err)}`)\n process.exit(1)\n})\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { i as ConfigError, m as ValidationError } from "./errors-
|
|
1
|
+
import { i as ConfigError, m as ValidationError } from "./errors-wuhGvpE3.js";
|
|
2
2
|
import { harnessTypeSchema } from "@tangle-network/agent-interface";
|
|
3
3
|
import { HARNESS_NATIVE_MODEL } from "@tangle-network/agent-eval";
|
|
4
|
-
|
|
4
|
+
// src/runtime/harness-role.ts
|
|
5
5
|
/**
|
|
6
6
|
* Harness ids that select a router/no-agent mode rather than a coding-agent runtime.
|
|
7
7
|
*
|
|
@@ -22,8 +22,7 @@ function harnessRunsAgent(harness) {
|
|
|
22
22
|
function agentHarness(harness) {
|
|
23
23
|
return harnessRunsAgent(harness) ? harness : void 0;
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
//#region src/runtime/model-identity.ts
|
|
25
|
+
// src/runtime/model-identity.ts
|
|
27
26
|
const SNAPSHOT_TOKEN = /^[A-Za-z0-9._-]+$/u;
|
|
28
27
|
const datedIsoSuffix = /^(.*)-(\d{4})-(\d{2})-(\d{2})$/u;
|
|
29
28
|
const datedCompactSuffix = /^(.*)-(\d{4})(\d{2})(\d{2})$/u;
|
|
@@ -166,8 +165,7 @@ function isValidCalendarMonth(yearText, monthText) {
|
|
|
166
165
|
const month = Number(monthText);
|
|
167
166
|
return year >= 2e3 && year <= 2099 && month >= 1 && month <= 12;
|
|
168
167
|
}
|
|
169
|
-
|
|
170
|
-
//#region src/runtime/router-auto-evidence.ts
|
|
168
|
+
// src/runtime/router-auto-evidence.ts
|
|
171
169
|
function object(value) {
|
|
172
170
|
if (value === null || typeof value !== "object" || Array.isArray(value)) throw new ValidationError("Router Auto requires an inline policy and routing receipt");
|
|
173
171
|
return value;
|
|
@@ -207,8 +205,7 @@ function routerAutoDeclaredModels(value) {
|
|
|
207
205
|
for (const phase of ["selector", "review"]) if (policy[phase] !== void 0) models.push(String(object(policy[phase]).model));
|
|
208
206
|
return [...new Set(models)];
|
|
209
207
|
}
|
|
210
|
-
|
|
211
|
-
//#region src/runtime/router-retry-policy.ts
|
|
208
|
+
// src/runtime/router-retry-policy.ts
|
|
212
209
|
const maximumTimerMs = 2147483647;
|
|
213
210
|
const defaultRetryStatuses = Object.freeze([
|
|
214
211
|
408,
|
|
@@ -275,8 +272,7 @@ function timerInteger(value, fallback, context, maximum = maximumTimerMs) {
|
|
|
275
272
|
if (typeof parsed !== "number" || !Number.isSafeInteger(parsed) || parsed < 0 || parsed > maximum) throw new ValidationError(`${context} must be a nonnegative safe integer no greater than ${maximum}`);
|
|
276
273
|
return parsed;
|
|
277
274
|
}
|
|
278
|
-
|
|
279
|
-
//#region src/runtime/supervise/model-policy.ts
|
|
275
|
+
// src/runtime/supervise/model-policy.ts
|
|
280
276
|
/**
|
|
281
277
|
* `assertModelAllowed` — a fail-loud guard that restricts a run to a chosen subset of
|
|
282
278
|
* models. The two front doors (`supervise()` / `improve()`) call it once per configured
|
|
@@ -336,7 +332,10 @@ function profileBridgeWireModel(profile) {
|
|
|
336
332
|
function assertExecutableAgentProfile(profile, context) {
|
|
337
333
|
if (profile.harness === void 0) throw new ConfigError(`${context}: AgentProfile.harness must be explicit before execution`);
|
|
338
334
|
const declared = profile.model?.default;
|
|
339
|
-
if (!concreteModelId(declared))
|
|
335
|
+
if (!concreteModelId(declared)) {
|
|
336
|
+
const reason = isHarnessNativeModel(declared) ? "runtime-selected" : "missing";
|
|
337
|
+
throw new ConfigError(`${context}: AgentProfile.model.default is ${reason}; execution requires a concrete model`);
|
|
338
|
+
}
|
|
340
339
|
if (!profile.model?.provider?.trim()) throw new ConfigError(`${context}: AgentProfile.model.provider must be explicit before execution`);
|
|
341
340
|
}
|
|
342
341
|
const PROFILE_MODEL_METADATA_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -525,7 +524,6 @@ function assertProfileModelsAllowed(profile, allowed) {
|
|
|
525
524
|
for (const subagent of Object.values(profile.subagents ?? {})) assertModelAllowed(subagent.model, allowed);
|
|
526
525
|
for (const mode of Object.values(profile.modes ?? {})) assertModelAllowed(mode.model, allowed);
|
|
527
526
|
}
|
|
528
|
-
//#endregion
|
|
529
527
|
export { agentHarness as _, concreteProfileModel as a, profileModelExecutionSettings as c, assertRouterAutoDeclaration as d, assertRouterAutoResponse as f, observedModelMatchesDeclared as g, observedModelHasSnapshot as h, concreteModelId as i, profileProviderModel as l, mergeObservedModelIdentity as m, assertModelAllowed as n, enforceTokenLimits as o, canonicalObservedModelParts as p, assertProfileModelsAllowed as r, profileBridgeWireModel as s, assertExecutableAgentProfile as t, resolveRouterRetryPolicy as u, harnessRunsAgent as v };
|
|
530
528
|
|
|
531
|
-
//# sourceMappingURL=model-policy-
|
|
529
|
+
//# sourceMappingURL=model-policy-GSxWwP-b.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-policy-GSxWwP-b.js","names":["positiveInteger"],"sources":["../src/runtime/harness-role.ts","../src/runtime/model-identity.ts","../src/runtime/router-auto-evidence.ts","../src/runtime/router-retry-policy.ts","../src/runtime/supervise/model-policy.ts"],"sourcesContent":["/**\n * Which `HarnessType` values name a real coding-agent runtime, and which name a MODE that has no\n * agent behind it.\n *\n * `cli-base` is the router-backed mode — a plain multi-turn router call with no coding-agent\n * harness (`@tangle-network/agent-interface`'s `HarnessType` doc, and the same table's\n * `harnessReasoningCeiling['cli-base'] = 'none'` commented \"cli-base has no agent\"). The\n * distinction is REAL; what was accidental is that three call sites each spelled the test\n * themselves, so a second no-agent mode would have to be remembered in three places.\n *\n * SHOULD UPSTREAM: this belongs next to `harnessHonorsEffort` in agent-interface's\n * `harness-capabilities.ts`, which already encodes the fact but exports no predicate for it.\n * Until it does, this is the one local copy — extend the set here, never re-test the name.\n */\n\nimport type { HarnessType } from '@tangle-network/agent-interface'\n\n/**\n * Harness ids that select a router/no-agent mode rather than a coding-agent runtime.\n *\n * `nanoclaw` is deliberately ABSENT: the shared capability table clamps its reasoning ceiling the\n * same way it clamps `cli-base`, but nanoclaw does run an agent (a socket-bridge runner to the\n * NanoClaw daemon) and every caller here treats it as a full harness. Add a row only with the\n * behavior change stated, never to make the two clamps look symmetric.\n */\nconst NO_AGENT_HARNESSES: ReadonlySet<string> = new Set<string>(['cli-base' satisfies HarnessType])\n\n/** Whether this profile harness selects a real coding-agent runtime (vs. the router/no-agent mode\n * or no preference at all). Accepts the looser `string` some local profile shapes declare, and\n * preserves the caller's own harness type when it is narrower. */\nexport function harnessRunsAgent<T extends string>(harness: T | null | undefined): harness is T {\n return harness != null && !NO_AGENT_HARNESSES.has(harness)\n}\n\n/** The coding-agent harness this profile selects, or `undefined` when it selects none — the shape\n * callers want when a no-agent mode must fall through to the router arm. */\nexport function agentHarness<T extends string>(harness: T | null | undefined): T | undefined {\n return harnessRunsAgent(harness) ? harness : undefined\n}\n","import { harnessTypeSchema } from '@tangle-network/agent-interface'\n\nconst SNAPSHOT_TOKEN = /^[A-Za-z0-9._-]+$/u\nconst datedIsoSuffix = /^(.*)-(\\d{4})-(\\d{2})-(\\d{2})$/u\nconst datedCompactSuffix = /^(.*)-(\\d{4})(\\d{2})(\\d{2})$/u\nconst datedMonthSuffix = /^(.*)-(\\d{4})-(\\d{2})$/u\n\ntype SnapshotKind = 'date' | 'opaque'\n\ninterface ModelIdentityParts {\n readonly base: string\n readonly snapshot?: string\n readonly snapshotKind?: SnapshotKind\n}\n\ninterface CanonicalObservedModelParts {\n readonly base: string\n readonly snapshot?: string\n readonly snapshotKind?: SnapshotKind\n readonly canonical: string\n}\n\n/** Match equivalent bare and provider-qualified spellings without discarding observed identity. */\nexport function observedModelMatchesDeclared(observed: string, declared: string): boolean {\n const observedIdentity = modelIdentityParts(observed)\n const declaredIdentity = modelIdentityParts(declared)\n if (!observedIdentity || !declaredIdentity) return false\n if (\n declaredIdentity.snapshot !== undefined &&\n (observedIdentity.snapshot !== declaredIdentity.snapshot ||\n observedIdentity.snapshotKind !== declaredIdentity.snapshotKind)\n ) {\n return false\n }\n return equivalentModelBase(observedIdentity.base, declaredIdentity.base)\n}\n\n/** Merge two observations of one served model while retaining a snapshot-bearing raw identity. */\nexport function mergeObservedModelIdentity(current: string, next: string): string | undefined {\n const currentIdentity = modelIdentityParts(current)\n const nextIdentity = modelIdentityParts(next)\n if (!currentIdentity || !nextIdentity) return undefined\n if (!equivalentModelBase(currentIdentity.base, nextIdentity.base)) return undefined\n if (\n currentIdentity.snapshot !== undefined &&\n nextIdentity.snapshot !== undefined &&\n (currentIdentity.snapshot !== nextIdentity.snapshot ||\n currentIdentity.snapshotKind !== nextIdentity.snapshotKind)\n ) {\n return undefined\n }\n return currentIdentity.snapshot === undefined && nextIdentity.snapshot !== undefined\n ? next\n : current\n}\n\n/** Canonicalize a served model for cross-route identity comparisons. */\nexport function canonicalObservedModel(model: string): string | undefined {\n return canonicalObservedModelParts(model)?.canonical\n}\n\n/** Return the canonical model and its validated snapshot kind for runtime evidence reduction. */\nexport function canonicalObservedModelParts(\n model: string,\n): CanonicalObservedModelParts | undefined {\n const identity = modelIdentityParts(model)\n if (!identity) return undefined\n const base = identity.base.slice(identity.base.lastIndexOf('/') + 1)\n const canonical =\n identity.snapshot === undefined\n ? base\n : identity.snapshotKind === 'date'\n ? `${base}-${identity.snapshot}`\n : `${base}@${identity.snapshot}`\n return {\n base,\n ...(identity.snapshot !== undefined ? { snapshot: identity.snapshot } : {}),\n ...(identity.snapshotKind !== undefined ? { snapshotKind: identity.snapshotKind } : {}),\n canonical,\n }\n}\n\n/** Return whether an observed identity includes a provider snapshot. */\nexport function observedModelHasSnapshot(model: string): boolean {\n return modelIdentityParts(model)?.snapshot !== undefined\n}\n\nfunction modelIdentityParts(model: string): ModelIdentityParts | null {\n if (model.length === 0) return null\n const at = model.lastIndexOf('@')\n if (at < 0) {\n const dated = datedModelIdentity(model)\n if (dated !== undefined) return dated\n return modelLeaf(model).length === 0 ? null : { base: model }\n }\n const base = model.slice(0, at)\n const snapshot = model.slice(at + 1)\n if (base.length === 0 || modelLeaf(base).length === 0 || !SNAPSHOT_TOKEN.test(snapshot)) {\n return null\n }\n return { base, snapshot, snapshotKind: 'opaque' }\n}\n\nfunction equivalentModelBase(observed: string, declared: string): boolean {\n const observedPath = modelBaseParts(observed)\n const declaredPath = modelBaseParts(declared)\n if (!samePath(observedPath.path, declaredPath.path)) return false\n\n // A bare id omits provider routing. It can match an explicitly qualified spelling\n // only when the model path is otherwise identical.\n if (\n observedPath.provider === undefined ||\n declaredPath.provider === undefined ||\n sameProvider(observedPath.provider, declaredPath.provider)\n ) {\n return true\n }\n\n // Tangle Router may report the upstream provider's qualified spelling. Preserve this\n // one documented alias without allowing arbitrary provider-to-provider substitutions.\n if (observedPath.provider === 'tangle-router' || declaredPath.provider === 'tangle-router') {\n const router = observedPath.provider === 'tangle-router' ? observedPath : declaredPath\n const upstream = observedPath.provider === 'tangle-router' ? declaredPath : observedPath\n if (upstream.provider === undefined) return false\n return (\n samePath(router.path, upstream.path) ||\n (router.path[0] === upstream.provider && samePath(router.path.slice(1), upstream.path))\n )\n }\n\n return false\n}\n\n/**\n * Compare provider slugs across catalogs that spell one vendor with or without hyphens,\n * such as `zai` and OpenRouter's `z-ai`. Any other provider difference is a substitution.\n */\nfunction sameProvider(left: string, right: string): boolean {\n return left.replaceAll('-', '') === right.replaceAll('-', '')\n}\n\ninterface ModelBaseParts {\n readonly provider: string | undefined\n readonly path: ReadonlyArray<string>\n}\n\nfunction modelBaseParts(model: string): ModelBaseParts {\n const segments = model.split('/')\n const normalized =\n segments.length > 1 && isHarnessPrefix(segments[0]) ? segments.slice(1) : segments\n if (normalized.length === 1) return { provider: undefined, path: normalized }\n return { provider: normalized[0], path: normalized.slice(1) }\n}\n\nfunction isHarnessPrefix(segment: string | undefined): boolean {\n return segment !== undefined && harnessTypeSchema.safeParse(segment).success\n}\n\nfunction samePath(left: ReadonlyArray<string>, right: ReadonlyArray<string>): boolean {\n return left.length === right.length && left.every((segment, index) => segment === right[index])\n}\n\nfunction modelLeaf(model: string): string {\n return model.slice(model.lastIndexOf('/') + 1)\n}\n\n/**\n * Parse the provider's documented dated snapshot forms.\n *\n * `undefined` means that the model has no dated shape and must be treated as a normal base.\n * `null` means that it has a dated shape but the date is invalid, so identity matching fails.\n */\nfunction datedModelIdentity(model: string): ModelIdentityParts | null | undefined {\n const iso = datedIsoSuffix.exec(model)\n if (iso) {\n const [, base, yearText, monthText, dayText] = iso\n return buildDatedIdentity(\n base,\n `${yearText}-${monthText}-${dayText}`,\n isValidCalendarDate(yearText, monthText, dayText),\n )\n }\n\n const compact = datedCompactSuffix.exec(model)\n if (compact) {\n const [, base, yearText, monthText, dayText] = compact\n return buildDatedIdentity(\n base,\n `${yearText}-${monthText}-${dayText}`,\n isValidCalendarDate(yearText, monthText, dayText),\n )\n }\n\n const month = datedMonthSuffix.exec(model)\n if (month) {\n const [, base, yearText, monthText] = month\n return buildDatedIdentity(\n base,\n `${yearText}-${monthText}`,\n isValidCalendarMonth(yearText, monthText),\n )\n }\n\n return undefined\n}\n\nfunction buildDatedIdentity(\n base: string | undefined,\n snapshot: string,\n valid: boolean,\n): ModelIdentityParts | null | undefined {\n // A date that is the entire model segment is not a snapshot suffix.\n if (base === undefined || base.length === 0 || base.endsWith('/')) return undefined\n return valid ? { base, snapshot, snapshotKind: 'date' } : null\n}\n\nfunction isValidCalendarDate(\n yearText: string | undefined,\n monthText: string | undefined,\n dayText: string | undefined,\n): boolean {\n if (yearText === undefined || monthText === undefined || dayText === undefined) return false\n const year = Number(yearText)\n const month = Number(monthText)\n const day = Number(dayText)\n if (year < 2000 || year > 2099 || month < 1 || month > 12 || day < 1 || day > 31) {\n return false\n }\n const date = new Date(Date.UTC(year, month - 1, day))\n return (\n date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day\n )\n}\n\nfunction isValidCalendarMonth(\n yearText: string | undefined,\n monthText: string | undefined,\n): boolean {\n if (yearText === undefined || monthText === undefined) return false\n const year = Number(yearText)\n const month = Number(monthText)\n return year >= 2000 && year <= 2099 && month >= 1 && month <= 12\n}\n","import { ValidationError } from '../errors'\nimport { observedModelMatchesDeclared } from './model-identity'\n\nfunction object(value: unknown): Record<string, unknown> {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new ValidationError('Router Auto requires an inline policy and routing receipt')\n }\n return value as Record<string, unknown>\n}\n\n/** Router owns policy parsing. Runtime requires visible model authority before dispatch. */\nexport function assertRouterAutoDeclaration(value: unknown, stream: boolean | undefined): void {\n const policy = object(value)\n if (stream === true) throw new ValidationError('Router Auto requires buffered transport')\n if (\n policy.version !== 1 ||\n typeof policy.id !== 'string' ||\n typeof policy.revision !== 'string' ||\n !Array.isArray(policy.strategies) ||\n policy.strategies.length === 0\n ) {\n throw new ValidationError(\n 'Router Auto requires a versioned inline policy with concrete strategies',\n )\n }\n for (const raw of policy.strategies) {\n const strategy = object(raw)\n if (\n typeof strategy.id !== 'string' ||\n typeof strategy.model !== 'string' ||\n strategy.model === 'tangle/auto' ||\n strategy.model.length === 0\n ) {\n throw new ValidationError('Router Auto strategy model authority is missing')\n }\n }\n for (const phase of ['selector', 'review']) {\n if (policy[phase] !== undefined && typeof object(policy[phase]).model !== 'string') {\n throw new ValidationError('Router Auto assessment model authority is missing')\n }\n }\n}\n\n/** An alias does not waive identity checks. Every reported child must match its declared phase. */\nexport function assertRouterAutoResponse(\n policyValue: unknown,\n response: unknown,\n served: string | undefined,\n): void {\n const policy = object(policyValue)\n const receipt = object(object(response).tangle_auto)\n const decision = object(receipt.decision)\n const strategies = policy.strategies as unknown[]\n const selected = strategies.map(object).find((strategy) => strategy.id === decision.strategyId)\n if (\n decision.requestedModel !== 'tangle/auto' ||\n decision.policyId !== policy.id ||\n decision.policyRevision !== policy.revision ||\n typeof decision.policyDigest !== 'string' ||\n !selected ||\n decision.selectedModel !== selected.model ||\n served === undefined ||\n !observedModelMatchesDeclared(served, String(selected.model))\n ) {\n throw new ValidationError(\n 'Router Auto response does not match AgentProfile policy/model authority',\n )\n }\n if (!Array.isArray(receipt.calls) || receipt.calls.length === 0) {\n throw new ValidationError('Router Auto response is missing physical call receipts')\n }\n for (const raw of receipt.calls) {\n const call = object(raw)\n const declared =\n call.phase === 'selector'\n ? object(policy.selector).model\n : call.phase === 'review'\n ? object(policy.review).model\n : call.phase === 'initial' || call.phase === 'escalation'\n ? strategies.map(object).map((strategy) => strategy.model)\n : []\n const allowed = Array.isArray(declared) ? declared : [declared]\n if (\n typeof call.model !== 'string' ||\n !allowed.some(\n (model) =>\n typeof model === 'string' && observedModelMatchesDeclared(call.model as string, model),\n )\n )\n throw new ValidationError('Router Auto physical call exceeds AgentProfile model authority')\n }\n}\n\n/** The concrete authority declared by an inline Auto policy, including paid assessments. */\nexport function routerAutoDeclaredModels(value: unknown): readonly string[] {\n assertRouterAutoDeclaration(value, undefined)\n const policy = object(value)\n const models = (policy.strategies as unknown[]).map((raw) => String(object(raw).model))\n for (const phase of ['selector', 'review']) {\n if (policy[phase] !== undefined) models.push(String(object(policy[phase]).model))\n }\n return [...new Set(models)]\n}\n","import { ValidationError } from '../errors'\n\n/** Exact retry controls accepted at `AgentProfile.model.metadata.retry`. */\nexport interface RouterRetryPolicy {\n /** Total attempts, including the first request. */\n readonly maxAttempts?: number\n /** Delay before the second attempt. Later delays grow exponentially. */\n readonly initialBackoffMs?: number\n /** Maximum delay between attempts. */\n readonly maxBackoffMs?: number\n /** Symmetric random variation around each delay, from 0 through 1. */\n readonly jitter?: number\n /** HTTP statuses that may be retried. */\n readonly retryStatuses?: ReadonlyArray<number>\n /** Deadline for receiving one attempt's response headers. Zero disables it. */\n readonly requestTimeoutMs?: number\n}\n\nexport interface ResolvedRouterRetryPolicy {\n readonly maxAttempts: number\n readonly initialBackoffMs: number\n readonly maxBackoffMs: number\n readonly jitter: number\n readonly retryStatuses: ReadonlyArray<number>\n readonly requestTimeoutMs: number\n}\n\nconst maximumTimerMs = 2_147_483_647\nconst defaultRetryStatuses = Object.freeze([408, 425, 429, 500, 502, 503, 504, 520, 522, 524])\nconst retryPolicyKeys = new Set([\n 'initialBackoffMs',\n 'jitter',\n 'maxAttempts',\n 'maxBackoffMs',\n 'requestTimeoutMs',\n 'retryStatuses',\n])\n\n/** Parse untrusted profile/config data once and return an immutable complete policy. */\nexport function resolveRouterRetryPolicy(\n input: unknown,\n context: string,\n): ResolvedRouterRetryPolicy {\n if (\n input !== undefined &&\n (typeof input !== 'object' || input === null || Array.isArray(input))\n ) {\n throw new ValidationError(`${context} must be an object`)\n }\n const policy = input === undefined ? {} : Object.fromEntries(Object.entries(input))\n const unknown = Object.keys(policy).filter((key) => !retryPolicyKeys.has(key))\n if (unknown.length > 0) {\n throw new ValidationError(`${context} has unsupported fields: ${unknown.join(', ')}`)\n }\n const maxAttempts = positiveInteger(policy.maxAttempts, 5, `${context}.maxAttempts`)\n const initialBackoffMs = timerInteger(\n policy.initialBackoffMs,\n 1_000,\n `${context}.initialBackoffMs`,\n )\n const maxBackoffMs = timerInteger(policy.maxBackoffMs, 30_000, `${context}.maxBackoffMs`)\n const requestTimeoutMs = timerInteger(\n policy.requestTimeoutMs,\n 0,\n `${context}.requestTimeoutMs`,\n Number.MAX_SAFE_INTEGER - Date.now(),\n )\n const jitter = policy.jitter ?? 0.25\n if (typeof jitter !== 'number' || !Number.isFinite(jitter) || jitter < 0 || jitter > 1) {\n throw new ValidationError(`${context}.jitter must be a finite number from 0 through 1`)\n }\n const retryStatuses = parseRetryStatuses(policy.retryStatuses, context)\n return Object.freeze({\n maxAttempts,\n initialBackoffMs,\n maxBackoffMs,\n jitter,\n retryStatuses,\n requestTimeoutMs,\n })\n}\n\nfunction parseRetryStatuses(value: unknown, context: string): ReadonlyArray<number> {\n if (value === undefined) return defaultRetryStatuses\n if (!Array.isArray(value)) {\n throw new ValidationError(`${context}.retryStatuses must be an array of HTTP statuses`)\n }\n const statuses: number[] = []\n const seen = new Set<number>()\n for (const status of value) {\n if (!Number.isSafeInteger(status) || status < 100 || status > 599) {\n throw new ValidationError(\n `${context}.retryStatuses must contain integer HTTP statuses from 100 through 599`,\n )\n }\n if (seen.has(status)) {\n throw new ValidationError(`${context}.retryStatuses must not contain duplicates`)\n }\n seen.add(status)\n statuses.push(status)\n }\n return Object.freeze(statuses)\n}\n\nfunction positiveInteger(value: unknown, fallback: number, context: string): number {\n const parsed = value ?? fallback\n if (typeof parsed !== 'number' || !Number.isSafeInteger(parsed) || parsed < 1) {\n throw new ValidationError(`${context} must be a positive safe integer`)\n }\n return parsed\n}\n\nfunction timerInteger(\n value: unknown,\n fallback: number,\n context: string,\n maximum = maximumTimerMs,\n): number {\n const parsed = value ?? fallback\n if (\n typeof parsed !== 'number' ||\n !Number.isSafeInteger(parsed) ||\n parsed < 0 ||\n parsed > maximum\n ) {\n throw new ValidationError(\n `${context} must be a nonnegative safe integer no greater than ${maximum}`,\n )\n }\n return parsed\n}\n","/**\n * `assertModelAllowed` — a fail-loud guard that restricts a run to a chosen subset of\n * models. The two front doors (`supervise()` / `improve()`) call it once per configured\n * model at resolve time, so a run that names a model outside the allowed set throws before\n * any compute is spent — never silently swapped or silently allowed.\n */\nimport { HARNESS_NATIVE_MODEL } from '@tangle-network/agent-eval'\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport { ConfigError } from '../../errors'\nimport { agentHarness } from '../harness-role'\nimport { routerAutoDeclaredModels } from '../router-auto-evidence'\nimport { type ResolvedRouterRetryPolicy, resolveRouterRetryPolicy } from '../router-retry-policy'\n\n/**\n * Return the model id an executor may send to a provider.\n *\n * Eval stamps {@link HARNESS_NATIVE_MODEL} into a profile when model selection is deliberately\n * delegated to the configured runtime. That marker belongs in experiment identity and cost\n * admission; it is not a provider model id.\n */\nexport function concreteModelId(model: string | undefined): string | undefined {\n if (model === undefined) return undefined\n const id = model.trim()\n return id.length > 0 && !isHarnessNativeModel(id) ? id : undefined\n}\n\n/** Whether a model value delegates selection to the chosen execution system. */\nfunction isHarnessNativeModel(model: string | undefined): boolean {\n return model?.trim() === HARNESS_NATIVE_MODEL\n}\n\n/** Return a profile's explicitly selected provider model, if it has one. */\nexport function concreteProfileModel(profile: Pick<AgentProfile, 'model'>): string | undefined {\n return concreteModelId(profile.model?.default)\n}\n\n/**\n * Return the model id for a direct provider request.\n *\n * A portable profile can qualify its model with the selected provider. The direct endpoint already\n * selects that provider, so remove only the exact matching prefix. Preserve every other prefix\n * because it can identify a provider-owned nested route, such as `anthropic/claude-sonnet`.\n */\nexport function profileProviderModel(profile: Pick<AgentProfile, 'model'>): string | undefined {\n const model = concreteProfileModel(profile)\n const provider = profile.model?.provider?.trim()\n if (!model || !provider || !model.startsWith(`${provider}/`)) return model\n return concreteModelId(model.slice(provider.length + 1))\n}\n\n/** The full cli-bridge wire id declared by a profile: harness/provider/model. */\nexport function profileBridgeWireModel(\n profile: Pick<AgentProfile, 'harness' | 'model'>,\n): string | undefined {\n const model = concreteProfileModel(profile)\n const provider = profile.model?.provider\n const harness = agentHarness(profile.harness)\n const modelWithoutHarness =\n model && harness && model.startsWith(`${harness}/`) ? model.slice(harness.length + 1) : model\n const providerModel = modelWithoutHarness\n ? provider && !modelWithoutHarness.startsWith(`${provider}/`)\n ? `${provider}/${modelWithoutHarness}`\n : modelWithoutHarness\n : undefined\n if (!harness) return providerModel\n if (!providerModel) return harness\n // Always add the harness segment: a provider may share the harness's name. opencode's own keyless\n // provider is `opencode`, so `opencode/glm-5.3-flash-free` is a provider/model pair; reading it as\n // already harness-prefixed sent `opencode/glm-5.3-flash-free`, cli-bridge removed the harness, and\n // opencode received the bare model and could not resolve it (\"Model not found\").\n return `${harness}/${providerModel}`\n}\n\n/**\n * Refuse an incomplete execution identity before any backend may fill it from ambient config.\n * `AgentProfile` is the sole behavioral authority: harness, provider, and concrete model all\n * participate in its digest. Eval's runtime-selected marker is a matrix-planning value, never an\n * executable model.\n */\nexport function assertExecutableAgentProfile(profile: AgentProfile, context: string): void {\n if (profile.harness === undefined) {\n throw new ConfigError(`${context}: AgentProfile.harness must be explicit before execution`)\n }\n const declared = profile.model?.default\n const model = concreteModelId(declared)\n if (!model) {\n const reason = isHarnessNativeModel(declared) ? 'runtime-selected' : 'missing'\n throw new ConfigError(\n `${context}: AgentProfile.model.default is ${reason}; execution requires a concrete model`,\n )\n }\n if (!profile.model?.provider?.trim()) {\n throw new ConfigError(\n `${context}: AgentProfile.model.provider must be explicit before execution`,\n )\n }\n}\n\n/**\n * Separate completion ceilings an exact profile may request.\n *\n * They are distinct because providers do not share one meaning for a single number: measured\n * through the Tangle Router, `glm-5.2` accepted `max_tokens: 8` and still billed 135\n * completion tokens — 132 reasoning, 3 visible — while `max_completion_tokens: 256` bounded the\n * total. A path that cannot enforce a requested ceiling refuses the run instead of sending a\n * number that means something else there.\n */\nexport interface ProfileTokenLimits {\n /** Visible answer tokens, from `AgentProfile.model.maxVisibleOutputTokens`. */\n readonly visible?: number\n /** Hidden reasoning tokens, from `AgentProfile.model.maxReasoningTokens`. */\n readonly reasoning?: number\n /** Visible and reasoning tokens together, from `AgentProfile.model.maxTotalOutputTokens`. */\n readonly total?: number\n}\n\n/** The ceilings one execution path actually sends, in the request fields it sends them as. */\nexport interface AppliedTokenLimits {\n /** Sent as `max_tokens`. */\n readonly maxTokens?: number\n /** Sent as `max_completion_tokens`. */\n readonly maxCompletionTokens?: number\n}\n\n/** What a path was asked to enforce and what it sent, for the execution receipt. */\nexport interface TokenLimitDecision {\n readonly requested: ProfileTokenLimits\n readonly applied: AppliedTokenLimits\n}\n\n/** The execution paths that lower a profile into a provider request. */\ntype ModelExecutionPath = 'router' | 'bridge' | 'sandbox' | 'provider'\n\n/** Generation and loop controls that may affect one model execution. */\nexport interface ProfileModelExecutionSettings {\n readonly temperature?: number\n /** Completion ceilings the profile requested. Empty when it requested none. */\n readonly tokenLimits: ProfileTokenLimits\n readonly retry?: ResolvedRouterRetryPolicy\n readonly seed?: number\n readonly toolChoice?: 'auto' | 'required' | 'none'\n readonly extraBody?: Readonly<Record<string, unknown>>\n /** Zero means no turn-count cap; conserved budgets and deadlines still apply. */\n readonly maxTurns?: number\n /**\n * Take each Router completion over SSE, with or without tools. The Router's request deadline ends\n * when response headers are committed, so a long thinking-model answer needs a stream to finish.\n * Requires the HTTP transport; an injected buffered `complete` transport is refused.\n */\n readonly stream?: boolean\n /**\n * This node's action space is CODE, not JSON tool calls (router-tools backend\n * only): the model is shown `tool_search` + `codemode` instead of the raw tool\n * set, and composes the granted handlers as one QuickJS program. `true` takes\n * host settings or engine defaults; an object can tighten host ceilings and\n * add direct-only tools. `false` selects ordinary tools for this node. Host\n * state and direct-only restrictions survive every enabled profile declaration.\n */\n readonly codeMode?: boolean | ProfileCodeModeSettings\n}\n\n/** The per-node code-mode controls a profile may pin — the seam's subset, minus\n * host-only (wasm/workerUrl) and executor-owned (store) options. */\nexport interface ProfileCodeModeSettings {\n /** Includes time in tools; at most 2,147,483,647 ms. */\n readonly timeoutMs?: number\n readonly memoryLimitBytes?: number\n /** Excess calls queue; Promise.all does not fail simply because the queue is full. */\n readonly concurrency?: number\n /** Bounds total admitted calls, including queued calls. */\n readonly maxCalls?: number\n /** These capabilities keep their direct model tools and are not callable from code. */\n readonly directTools?: ReadonlyArray<string>\n}\n\nconst PROFILE_MODEL_METADATA_KEYS = new Set([\n 'codeMode',\n 'extraBody',\n 'maxTurns',\n 'retry',\n 'seed',\n 'stream',\n 'temperature',\n 'toolChoice',\n])\n\n/**\n * Read execution controls from the exact profile and reject unknown controls.\n * Credential intent reaches environment providers unchanged; other paths cannot enforce it.\n * Backends receive endpoint/auth and executable ports only; they cannot silently alter behavior.\n */\nexport function profileModelExecutionSettings(\n profile: Pick<AgentProfile, 'model'>,\n context: string,\n path: ModelExecutionPath = 'router',\n): ProfileModelExecutionSettings {\n const metadata = profile.model?.metadata ?? {}\n if (metadata.maxTokens !== undefined) {\n throw new ConfigError(\n `${context}: AgentProfile.model.metadata.maxTokens is ambiguous across providers; declare AgentProfile.model.maxVisibleOutputTokens, maxReasoningTokens, or maxTotalOutputTokens instead`,\n )\n }\n const unknown = Object.keys(metadata).filter(\n (key) =>\n !PROFILE_MODEL_METADATA_KEYS.has(key) && !(path === 'provider' && key === 'credentialSource'),\n )\n if (unknown.length > 0) {\n throw new ConfigError(\n `${context}: unsupported AgentProfile.model.metadata fields: ${unknown.join(', ')}`,\n )\n }\n if (\n metadata.credentialSource !== undefined &&\n metadata.credentialSource !== 'managed' &&\n metadata.credentialSource !== 'subscription'\n ) {\n throw new ConfigError(\n `${context}: AgentProfile.model.metadata.credentialSource must be managed or subscription`,\n )\n }\n const temperature = finiteNumber(metadata.temperature, `${context}: temperature`)\n const tokenLimits = profileTokenLimits(profile, context)\n const retryInput = metadata.retry\n const retry =\n retryInput === undefined\n ? undefined\n : resolveRouterRetryPolicy(retryInput, `${context}: AgentProfile.model.metadata.retry`)\n const seed = safeInteger(metadata.seed, `${context}: seed`)\n const maxTurns = nonnegativeInteger(metadata.maxTurns, `${context}: maxTurns`)\n const stream = optionalBoolean(metadata.stream, `${context}: stream`)\n const toolChoice = metadata.toolChoice\n if (\n toolChoice !== undefined &&\n toolChoice !== 'auto' &&\n toolChoice !== 'required' &&\n toolChoice !== 'none'\n ) {\n throw new ConfigError(`${context}: toolChoice must be auto, required, or none`)\n }\n const extraBody = metadata.extraBody\n if (\n extraBody !== undefined &&\n (typeof extraBody !== 'object' || extraBody === null || Array.isArray(extraBody))\n ) {\n throw new ConfigError(`${context}: extraBody must be an object`)\n }\n const codeMode = profileCodeModeSettings(metadata.codeMode, context)\n return {\n ...(temperature !== undefined ? { temperature } : {}),\n tokenLimits,\n ...(retry !== undefined ? { retry } : {}),\n ...(seed !== undefined ? { seed } : {}),\n ...(toolChoice !== undefined ? { toolChoice } : {}),\n ...(extraBody !== undefined\n ? { extraBody: Object.freeze({ ...(extraBody as Record<string, unknown>) }) }\n : {}),\n ...(maxTurns !== undefined ? { maxTurns } : {}),\n ...(stream !== undefined ? { stream } : {}),\n ...(codeMode !== undefined ? { codeMode } : {}),\n }\n}\n\nconst PROFILE_CODE_MODE_KEYS = new Set([\n 'concurrency',\n 'directTools',\n 'maxCalls',\n 'memoryLimitBytes',\n 'timeoutMs',\n])\n\n/** Validate `AgentProfile.model.metadata.codeMode`: a boolean, or an object pinning\n * exactly the subset a node may choose (host-only wasm/workerUrl and the\n * executor-owned store are refused — those belong to the seam). */\nfunction profileCodeModeSettings(\n value: unknown,\n context: string,\n): boolean | ProfileCodeModeSettings | undefined {\n if (value === undefined) return undefined\n if (typeof value === 'boolean') return value\n const label = `${context}: codeMode`\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new ConfigError(`${label} must be a boolean or an object of engine settings`)\n }\n const input = value as Record<string, unknown>\n const unknown = Object.keys(input).filter((key) => !PROFILE_CODE_MODE_KEYS.has(key))\n if (unknown.length > 0) {\n throw new ConfigError(\n `${label} refuses unsupported fields: ${unknown.join(', ')} (allowed: ${[...PROFILE_CODE_MODE_KEYS].join(', ')}; wasm/workerUrl/store belong to the executor seam)`,\n )\n }\n const timeoutMs = positiveInteger(input.timeoutMs, `${label}.timeoutMs`)\n const memoryLimitBytes = positiveInteger(input.memoryLimitBytes, `${label}.memoryLimitBytes`)\n const concurrency = positiveInteger(input.concurrency, `${label}.concurrency`)\n const maxCalls = positiveInteger(input.maxCalls, `${label}.maxCalls`)\n const directTools = input.directTools\n if (\n directTools !== undefined &&\n (!Array.isArray(directTools) || directTools.some((name) => typeof name !== 'string' || !name))\n ) {\n throw new ConfigError(`${label}.directTools must be an array of tool names`)\n }\n return Object.freeze({\n ...(timeoutMs !== undefined ? { timeoutMs } : {}),\n ...(memoryLimitBytes !== undefined ? { memoryLimitBytes } : {}),\n ...(concurrency !== undefined ? { concurrency } : {}),\n ...(maxCalls !== undefined ? { maxCalls } : {}),\n ...(Array.isArray(directTools) ? { directTools: Object.freeze([...directTools]) } : {}),\n })\n}\n\n/**\n * Read the completion ceilings an exact profile declares. The Interface schema already refines\n * these fields, but a profile can reach an executor without a parse, so the same rules are\n * enforced here: positive integers, and no single ceiling above the total.\n */\nfunction profileTokenLimits(\n profile: Pick<AgentProfile, 'model'>,\n context: string,\n): ProfileTokenLimits {\n const model = profile.model\n const visible = positiveInteger(\n model?.maxVisibleOutputTokens,\n `${context}: maxVisibleOutputTokens`,\n )\n const reasoning = positiveInteger(model?.maxReasoningTokens, `${context}: maxReasoningTokens`)\n const total = positiveInteger(model?.maxTotalOutputTokens, `${context}: maxTotalOutputTokens`)\n if (total !== undefined) {\n for (const [name, value] of [\n ['maxVisibleOutputTokens', visible],\n ['maxReasoningTokens', reasoning],\n ] as const) {\n if (value !== undefined && value > total) {\n throw new ConfigError(\n `${context}: AgentProfile.model.${name} (${value}) exceeds maxTotalOutputTokens (${total})`,\n )\n }\n }\n }\n return {\n ...(visible !== undefined ? { visible } : {}),\n ...(reasoning !== undefined ? { reasoning } : {}),\n ...(total !== undefined ? { total } : {}),\n }\n}\n\n/**\n * Lower the requested ceilings onto one execution path, or refuse the run before any paid\n * transport.\n *\n * - Router and OpenAI-compatible routes send the visible ceiling as `max_tokens` and the total as\n * `max_completion_tokens`.\n * - The CLI Bridge lowers ONE completion cap into the run's model catalog, so it carries the total\n * as `max_tokens` and cannot bound the visible half on its own.\n * - The Sandbox and environment-provider paths expose no completion cap at all.\n * - No route publishes a reasoning-token budget, so a reasoning ceiling is refused everywhere.\n * `AgentProfile.model.reasoningEffort` is an intensity dial, not a token bound.\n */\nexport function enforceTokenLimits(\n limits: ProfileTokenLimits,\n path: ModelExecutionPath,\n context: string,\n): TokenLimitDecision {\n const refuse = (field: string, reason: string): never => {\n throw new ConfigError(\n `${context}: AgentProfile.model.${field} cannot be enforced on the ${path} path (${reason}); remove the ceiling or select a path that enforces it`,\n )\n }\n if (limits.reasoning !== undefined) {\n refuse('maxReasoningTokens', 'no route exposes a reasoning-token budget')\n }\n if (path === 'router') {\n return {\n requested: limits,\n applied: {\n ...(limits.visible !== undefined ? { maxTokens: limits.visible } : {}),\n ...(limits.total !== undefined ? { maxCompletionTokens: limits.total } : {}),\n },\n }\n }\n if (path === 'bridge') {\n if (limits.visible !== undefined) {\n refuse('maxVisibleOutputTokens', 'the bridge lowers one completion cap covering both halves')\n }\n return {\n requested: limits,\n applied: {\n ...(limits.total !== undefined ? { maxTokens: limits.total } : {}),\n },\n }\n }\n if (limits.visible !== undefined) refuse('maxVisibleOutputTokens', 'the backend accepts no cap')\n if (limits.total !== undefined) refuse('maxTotalOutputTokens', 'the backend accepts no cap')\n return { requested: limits, applied: {} }\n}\n\nfunction finiteNumber(value: unknown, context: string): number | undefined {\n if (value === undefined) return undefined\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n throw new ConfigError(`${context} must be a finite number`)\n }\n return value\n}\n\nfunction safeInteger(value: unknown, context: string): number | undefined {\n if (value === undefined) return undefined\n if (!Number.isSafeInteger(value)) throw new ConfigError(`${context} must be a safe integer`)\n return value as number\n}\n\nfunction positiveInteger(value: unknown, context: string): number | undefined {\n const parsed = safeInteger(value, context)\n if (parsed !== undefined && parsed < 1) {\n throw new ConfigError(`${context} must be positive`)\n }\n return parsed\n}\n\nfunction nonnegativeInteger(value: unknown, context: string): number | undefined {\n const parsed = safeInteger(value, context)\n if (parsed !== undefined && parsed < 0) {\n throw new ConfigError(`${context} must be nonnegative`)\n }\n return parsed\n}\n\nfunction optionalBoolean(value: unknown, context: string): boolean | undefined {\n if (value === undefined) return undefined\n if (typeof value !== 'boolean') throw new ConfigError(`${context} must be boolean`)\n return value\n}\n\n/**\n * Throw a `ConfigError` when `allowed` is set, `model` is defined, and `model` is not a\n * member of `allowed`. No-op when `allowed` is unset (the unrestricted default) or when\n * `model` is undefined (nothing was configured to check).\n */\nexport function assertModelAllowed(\n model: string | undefined,\n allowed: readonly string[] | undefined,\n): void {\n if (!allowed || model === undefined) return\n if (!allowed.includes(model)) {\n throw new ConfigError(\n `model ${JSON.stringify(model)} is not in the allowed set ${JSON.stringify([...allowed])}`,\n )\n }\n}\n\n/** Check every canonical model-bearing field in a complete profile, including the models a\n * backend may select for cheap work, named subagents, or modes.\n *\n * Every compared value is a bare model id. The composed `harness/provider/model` wire id\n * (`profileBridgeWireModel`) is neither built nor compared here, so this admits any route that\n * declares an allowed id, and a qualified entry in `allowed` matches nothing. Route pinning\n * belongs to `SuperviseOptions.authorizeSpawn`. */\nexport function assertProfileModelsAllowed(\n profile: AgentProfile,\n allowed: readonly string[] | undefined,\n): void {\n assertModelAllowed(profile.model?.default, allowed)\n assertModelAllowed(profile.model?.small, allowed)\n if (profile.model?.default === 'tangle/auto') {\n const extra = profile.model.metadata?.extraBody\n const policy =\n extra !== null && typeof extra === 'object'\n ? (extra as Record<string, unknown>).auto\n : undefined\n for (const model of routerAutoDeclaredModels(policy)) assertModelAllowed(model, allowed)\n }\n for (const subagent of Object.values(profile.subagents ?? {})) {\n assertModelAllowed(subagent.model, allowed)\n }\n for (const mode of Object.values(profile.modes ?? {})) {\n assertModelAllowed(mode.model, allowed)\n }\n}\n"],"mappings":"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"}
|
package/dist/placement.d.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { a as ProfileMaterializationContract, i as KnownAgentProfileMaterializationAxis, t as AgentProfileMaterializationAxis } from "./profile-materialization-
|
|
1
|
+
import { a as ProfileMaterializationContract, i as KnownAgentProfileMaterializationAxis, t as AgentProfileMaterializationAxis } from "./profile-materialization-BRY22Oh8.js";
|
|
2
2
|
import { AgentProfile } from "@tangle-network/agent-interface";
|
|
3
|
-
//#region src/placement/index.d.ts
|
|
4
3
|
/** The policy version every {@link PlacementRecord} carries. */
|
|
5
|
-
declare const PLACEMENT_POLICY = "agent-placement/3";
|
|
4
|
+
export declare const PLACEMENT_POLICY = "agent-placement/3";
|
|
6
5
|
/** Where one unit of agent work runs, cheapest first. */
|
|
7
|
-
type ExecutionTier = 'inference' | 'loop' | 'sandbox';
|
|
6
|
+
export type ExecutionTier = 'inference' | 'loop' | 'sandbox';
|
|
8
7
|
/** What was chosen, under which policy, why, and why each other tier was refused. */
|
|
9
|
-
interface PlacementRecord {
|
|
8
|
+
export interface PlacementRecord {
|
|
10
9
|
chosen: ExecutionTier;
|
|
11
10
|
policy: typeof PLACEMENT_POLICY;
|
|
12
11
|
reason: string;
|
|
@@ -26,7 +25,7 @@ interface PlacementRecord {
|
|
|
26
25
|
* Platform's `agent.run` action, the first consumer; an app's chat turn usually
|
|
27
26
|
* declares none of them.
|
|
28
27
|
*/
|
|
29
|
-
interface PlacementRequirements {
|
|
28
|
+
export interface PlacementRequirements {
|
|
30
29
|
/** A pinned harness. Always runs in the sandbox. */
|
|
31
30
|
harness?: string;
|
|
32
31
|
/** A model other than the profile's own needs the sandbox to choose between them. */
|
|
@@ -53,7 +52,7 @@ interface PlacementRequirements {
|
|
|
53
52
|
tools?: readonly string[];
|
|
54
53
|
}
|
|
55
54
|
/** Which tiers this deployment has wired. */
|
|
56
|
-
interface PlacementContext {
|
|
55
|
+
export interface PlacementContext {
|
|
57
56
|
interactive: boolean;
|
|
58
57
|
inferenceAvailable: boolean;
|
|
59
58
|
loopAvailable: boolean;
|
|
@@ -61,8 +60,8 @@ interface PlacementContext {
|
|
|
61
60
|
loopUnavailableReason?: string;
|
|
62
61
|
}
|
|
63
62
|
/** Profile axes a tier may count as covered when their declared value grants nothing. */
|
|
64
|
-
type VacuousAxis = 'permissions';
|
|
65
|
-
interface PlaceExecutionInput {
|
|
63
|
+
export type VacuousAxis = 'permissions';
|
|
64
|
+
export interface PlaceExecutionInput {
|
|
66
65
|
requirements?: PlacementRequirements;
|
|
67
66
|
/** The RESOLVED profile: a named profile is read before the decision. */
|
|
68
67
|
profile?: AgentProfile | object;
|
|
@@ -82,7 +81,7 @@ interface PlaceExecutionInput {
|
|
|
82
81
|
inlineSkills?: boolean;
|
|
83
82
|
}
|
|
84
83
|
/** No tier can meet every declared requirement. Raised before any spend. */
|
|
85
|
-
declare class PlacementRefusedError extends Error {
|
|
84
|
+
export declare class PlacementRefusedError extends Error {
|
|
86
85
|
readonly reason: string;
|
|
87
86
|
constructor(reason: string);
|
|
88
87
|
}
|
|
@@ -90,12 +89,11 @@ declare class PlacementRefusedError extends Error {
|
|
|
90
89
|
* The profile axes `inference` and `loop` carry: identity, prompt, model controls and
|
|
91
90
|
* metadata. No harness, native tools, files, MCP, subagents, hooks or modes.
|
|
92
91
|
*/
|
|
93
|
-
declare const loopTierProfileMaterialization: ProfileMaterializationContract;
|
|
92
|
+
export declare const loopTierProfileMaterialization: ProfileMaterializationContract;
|
|
94
93
|
/**
|
|
95
94
|
* Choose where work runs: the cheapest tier every declared requirement allows.
|
|
96
95
|
* Throws {@link PlacementRefusedError} when no tier can meet every requirement.
|
|
97
96
|
*/
|
|
98
|
-
declare function placeExecution(input: PlaceExecutionInput): PlacementRecord;
|
|
99
|
-
|
|
100
|
-
export { type AgentProfileMaterializationAxis, ExecutionTier, type KnownAgentProfileMaterializationAxis, PLACEMENT_POLICY, PlaceExecutionInput, PlacementContext, PlacementRecord, PlacementRefusedError, PlacementRequirements, VacuousAxis, loopTierProfileMaterialization, placeExecution };
|
|
97
|
+
export declare function placeExecution(input: PlaceExecutionInput): PlacementRecord;
|
|
98
|
+
export type { AgentProfileMaterializationAxis, KnownAgentProfileMaterializationAxis };
|
|
101
99
|
//# sourceMappingURL=placement.d.ts.map
|
package/dist/placement.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/placement/index.ts
|
|
2
2
|
/** The policy version every {@link PlacementRecord} carries. */
|
|
3
3
|
const PLACEMENT_POLICY = "agent-placement/3";
|
|
4
4
|
/** No tier can meet every declared requirement. Raised before any spend. */
|
|
@@ -279,7 +279,6 @@ function declaredAxes(profile) {
|
|
|
279
279
|
}
|
|
280
280
|
return axes;
|
|
281
281
|
}
|
|
282
|
-
//#endregion
|
|
283
282
|
export { PLACEMENT_POLICY, PlacementRefusedError, loopTierProfileMaterialization, placeExecution };
|
|
284
283
|
|
|
285
284
|
//# sourceMappingURL=placement.js.map
|
package/dist/platform.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
//#region src/platform/auth.d.ts
|
|
2
1
|
/**
|
|
3
2
|
* Server-side client for the Tangle platform's cross-site SSO bridge.
|
|
4
3
|
*
|
|
@@ -47,13 +46,13 @@ interface ExchangeCodeResult {
|
|
|
47
46
|
} | null;
|
|
48
47
|
}
|
|
49
48
|
/** Thrown when a `PlatformAuthClient` request returns a non-success status. */
|
|
50
|
-
declare class PlatformAuthError extends Error {
|
|
49
|
+
export declare class PlatformAuthError extends Error {
|
|
51
50
|
readonly status: number;
|
|
52
51
|
readonly body: unknown;
|
|
53
52
|
constructor(message: string, status: number, body: unknown);
|
|
54
53
|
}
|
|
55
54
|
/** HTTP client for the Tangle Platform SSO: builds authorize URLs and exchanges auth codes for API keys. */
|
|
56
|
-
declare class PlatformAuthClient {
|
|
55
|
+
export declare class PlatformAuthClient {
|
|
57
56
|
private readonly baseUrl;
|
|
58
57
|
private readonly appId;
|
|
59
58
|
private readonly fetchImpl;
|
|
@@ -71,8 +70,6 @@ declare class PlatformAuthClient {
|
|
|
71
70
|
*/
|
|
72
71
|
exchange(code: string): Promise<ExchangeCodeResult>;
|
|
73
72
|
}
|
|
74
|
-
//#endregion
|
|
75
|
-
//#region src/platform/integrations.d.ts
|
|
76
73
|
/**
|
|
77
74
|
* Server-side client for the Tangle platform's integration hub
|
|
78
75
|
* (`/v1/hub/*`). Consumer apps use this instead of rolling their own
|
|
@@ -201,14 +198,14 @@ interface PlatformHubStatus {
|
|
|
201
198
|
};
|
|
202
199
|
}
|
|
203
200
|
/** Thrown when a `PlatformHubClient` request returns a non-success status. */
|
|
204
|
-
declare class PlatformHubError extends Error {
|
|
201
|
+
export declare class PlatformHubError extends Error {
|
|
205
202
|
readonly status: number;
|
|
206
203
|
readonly code: string | undefined;
|
|
207
204
|
readonly body: unknown;
|
|
208
205
|
constructor(message: string, status: number, code: string | undefined, body: unknown);
|
|
209
206
|
}
|
|
210
207
|
/** HTTP client for the Tangle Platform Hub API: provider catalog, connection flow, and status. */
|
|
211
|
-
declare class PlatformHubClient {
|
|
208
|
+
export declare class PlatformHubClient {
|
|
212
209
|
private readonly baseUrl;
|
|
213
210
|
private readonly bearer;
|
|
214
211
|
private readonly fetchImpl;
|
|
@@ -259,8 +256,6 @@ declare class PlatformHubClient {
|
|
|
259
256
|
exec(input: ExecInput): Promise<unknown>;
|
|
260
257
|
private request;
|
|
261
258
|
}
|
|
262
|
-
//#endregion
|
|
263
|
-
//#region src/platform/oidc.d.ts
|
|
264
259
|
/**
|
|
265
260
|
* OpenID Connect client for the Tangle authorization server. Identity tokens
|
|
266
261
|
* are not platform API keys. Resource scopes and audiences must be registered
|
|
@@ -316,12 +311,12 @@ interface OidcDeviceAuthorization {
|
|
|
316
311
|
interval: number;
|
|
317
312
|
}
|
|
318
313
|
/** Create an RFC 7636 verifier and its S256 challenge with Web Crypto. */
|
|
319
|
-
declare function createPkcePair(): Promise<{
|
|
314
|
+
export declare function createPkcePair(): Promise<{
|
|
320
315
|
verifier: string;
|
|
321
316
|
challenge: string;
|
|
322
317
|
}>;
|
|
323
318
|
/** OIDC code + PKCE, refresh/revoke and discovery-bound RFC 8628 device grants. */
|
|
324
|
-
declare class PlatformOidcClient {
|
|
319
|
+
export declare class PlatformOidcClient {
|
|
325
320
|
private readonly baseUrl;
|
|
326
321
|
private readonly clientId;
|
|
327
322
|
private readonly clientSecret;
|
|
@@ -352,6 +347,5 @@ declare class PlatformOidcClient {
|
|
|
352
347
|
private token;
|
|
353
348
|
private post;
|
|
354
349
|
}
|
|
355
|
-
|
|
356
|
-
export { type AuthorizeUrlOptions, type CatalogResult, type ConnectionHealth, type ConnectionHealthResult, type ExchangeCodeResult, type ExecInput, type HealthCheck, type MintTokenInput, type MintTokenResult, type OidcAuthorizeUrlOptions, type OidcDeviceAuthorization, type OidcExchangeResult, type OidcTokens, type OidcUser, PlatformAuthClient, type PlatformAuthClientOptions, PlatformAuthError, type PlatformCatalogProvider, type PlatformConnection, PlatformHubClient, type PlatformHubClientOptions, PlatformHubError, type PlatformHubStatus, PlatformOidcClient, type PlatformOidcClientOptions, type StartAuthInput, type StartAuthResult, createPkcePair };
|
|
350
|
+
export type { AuthorizeUrlOptions, CatalogResult, ConnectionHealth, ConnectionHealthResult, ExchangeCodeResult, ExecInput, HealthCheck, MintTokenInput, MintTokenResult, OidcAuthorizeUrlOptions, OidcDeviceAuthorization, OidcExchangeResult, OidcTokens, OidcUser, PlatformAuthClientOptions, PlatformCatalogProvider, PlatformConnection, PlatformHubClientOptions, PlatformHubStatus, PlatformOidcClientOptions, StartAuthInput, StartAuthResult };
|
|
357
351
|
//# sourceMappingURL=platform.d.ts.map
|
package/dist/platform.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isRecord } from "@tangle-network/agent-core";
|
|
2
|
-
|
|
2
|
+
// src/platform/auth.ts
|
|
3
3
|
/**
|
|
4
4
|
* Server-side client for the Tangle platform's cross-site SSO bridge.
|
|
5
5
|
*
|
|
@@ -101,8 +101,7 @@ var PlatformAuthClient = class {
|
|
|
101
101
|
return parseExchangeResult(body, res.status);
|
|
102
102
|
}
|
|
103
103
|
};
|
|
104
|
-
|
|
105
|
-
//#region src/platform/integrations.ts
|
|
104
|
+
// src/platform/integrations.ts
|
|
106
105
|
/** Thrown when a `PlatformHubClient` request returns a non-success status. */
|
|
107
106
|
var PlatformHubError = class extends Error {
|
|
108
107
|
status;
|
|
@@ -230,8 +229,7 @@ var PlatformHubClient = class {
|
|
|
230
229
|
return parsed.data;
|
|
231
230
|
}
|
|
232
231
|
};
|
|
233
|
-
|
|
234
|
-
//#region src/platform/oidc.ts
|
|
232
|
+
// src/platform/oidc.ts
|
|
235
233
|
/**
|
|
236
234
|
* OpenID Connect client for the Tangle authorization server. Identity tokens
|
|
237
235
|
* are not platform API keys. Resource scopes and audiences must be registered
|
|
@@ -476,7 +474,6 @@ var PlatformOidcClient = class {
|
|
|
476
474
|
});
|
|
477
475
|
}
|
|
478
476
|
};
|
|
479
|
-
//#endregion
|
|
480
477
|
export { PlatformAuthClient, PlatformAuthError, PlatformHubClient, PlatformHubError, PlatformOidcClient, createPkcePair };
|
|
481
478
|
|
|
482
479
|
//# sourceMappingURL=platform.js.map
|