@synadia-ai/agent-fabric 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/trace.ts","../src/tracing.ts","../src/caller.ts","../src/scratchpad.ts","../src/command.ts","../src/cli.ts"],"names":["message","prompt","root"],"mappings":"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","file":"cli.js","sourcesContent":["// Tracing for the Synadia Agent Fabric — the vocabulary shared by the caller\n// side and the host side (`tracing.ts` builds the SDK's hooks from it).\n// Mirrors `synadia_ai/agent_fabric/trace.py` in the Python package; the two\n// must stay wire-identical.\n//\n// The ambient binding is what lets a client used as a tool inside a prompt\n// handler inherit lineage with no plumbing through user code:\n// AsyncLocalStorage flows into awaited work and into tasks created inside\n// the bound scope (Node and Bun alike).\n//\n// A thread ID names one prompt execution: minted by the caller at\n// `prompt()` time, 128-bit random as 32 lowercase hex characters, and\n// adopted by the receiving service. `rootId` has the same shape — it IS a\n// thread ID, the tree's first execution.\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { NatsAgentError, type AgentId } from \"@synadia-ai/agents\";\n\n// Bump every time you change the trace record schema\n// (be sure the Python package is updated in lockstep)\nexport const EDGE_RECORD_VERSION = 1;\n\n/** Default subject edge records are published to — the tenant-side short\n * form; the account's import qualifies it to `TRACE.{account}.edges`. */\nexport const DEFAULT_EDGE_SUBJECT = \"TRACE.edges\";\n\n/** The envelope fields that carry the lineage to the receiver. */\nexport const THREAD_ID_FIELD = \"thread_id\";\nexport const ROOT_ID_FIELD = \"root_id\";\n\n/** The headers an agent stamps on its model requests (see {@link traceHeaders}). */\nexport const THREAD_ID_HEADER = \"X-Synadia-Thread-ID\";\nexport const ROOT_ID_HEADER = \"X-Synadia-Root-ID\";\n\n/**\n * Tracing configuration for {@link fabricTracing}; `{}` takes every\n * default.\n */\nexport interface TraceOptions {\n /**\n * Where edge records are published. `null` selects propagate-only mode\n * — mint IDs and forward lineage, but publish no edge records.\n */\n readonly edgeSubject?: string | null;\n}\n\n// Spelled out rather than `\\s`, which means different things in the two\n// languages: JavaScript's includes U+FEFF and Python's does not, Python's\n// includes the C0 separators and JavaScript's does not. An explicit class\n// is the only way the two packages reject exactly the same subjects.\n// Shared with `served.ts`, whose harness thread id is held to the same\n// class; not part of the package's surface.\nexport const SUBJECT_FORBIDDEN =\n /[\\u0000-\\u0020\\u007f\\u00a0\\u1680\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000\\ufeff]/;\n\n/**\n * Throws {@link NatsAgentError} when `options.edgeSubject` names a subject\n * that can never be published to: empty, an empty token, whitespace or\n * NUL, or a wildcard. Publishing is fail-open, so without this check a\n * misconfigured subject would only ever show up as a warning on every\n * prompt; checking where the options are accepted makes it fail at\n * construction instead.\n */\nexport function assertValidTraceOptions(options: TraceOptions | undefined): void {\n if (options === undefined) return;\n const subject = options.edgeSubject;\n if (subject === undefined || subject === null) return;\n const reject = (reason: string): never => {\n throw new NatsAgentError(`trace.edgeSubject ${JSON.stringify(subject)}: ${reason}`);\n };\n if (typeof subject !== \"string\") reject(\"must be a string or null\");\n if (subject.length === 0) reject(\"must not be empty\");\n for (const token of subject.split(\".\")) {\n if (token.length === 0) reject(\"must not contain an empty token\");\n if (SUBJECT_FORBIDDEN.test(token)) reject(\"must not contain whitespace or control characters\");\n if (token.includes(\"*\") || token.includes(\">\")) reject(\"must not contain wildcards\");\n }\n}\n\n/**\n * How many trace records this process has published and dropped so far —\n * `edge` records today, counted from process start. Process-wide, not per\n * client: the records are written by whichever client a prompt handler\n * happens to use, while the agent service that owns the heartbeat is\n * another object; one counter for the process is the one they share. The\n * host reports both numbers as `records_published` and `records_dropped`\n * in its heartbeat's extras (`fabricTracing().heartbeatExtras`), so\n * whoever consumes the heartbeat knows how many records this process\n * failed to publish.\n */\nexport interface TraceRecordCounts {\n /**\n * Records handed to the connection for publishing. Handed, not\n * delivered: a record lost after that — a reconnect buffer that\n * overflowed, a process that exited before the flush — is not seen\n * here. The counts cover what this process could observe; nothing past\n * the connection is visible to them.\n */\n readonly published: number;\n /**\n * Records that were due but never went out: no identity to sign them\n * with, or a publish that threw. \"Due\" means the prompt the record\n * describes actually went out — a prompt never iterated or rejected by\n * validation owes no record and counts nothing. A record in\n * propagate-only mode (`edgeSubject: null`) is never due either.\n */\n readonly dropped: number;\n}\n\ninterface MutableCounters {\n published: number;\n dropped: number;\n}\n\n// Kept on `globalThis` under a well-known symbol rather than in module\n// state: a deployment can end up with two installed copies of this module\n// (a harness pinning its own version, or the ESM and CJS builds both\n// loaded), and the copy whose caller interceptor counts need not be the\n// copy whose heartbeat provider reads. Module state would split the\n// counter between the copies and the heartbeat would report 0/0 while\n// records were being dropped. One process, one counter, whichever copy\n// asks.\nconst COUNTERS_KEY = Symbol.for(\"@synadia-ai/agent-fabric:trace-record-counts\");\nconst counters: MutableCounters = (() => {\n const g = globalThis as unknown as Record<symbol, MutableCounters | undefined>;\n return (g[COUNTERS_KEY] ??= { published: 0, dropped: 0 });\n})();\n\n/** Count one trace record published. Called by the edge publisher. */\nexport function countTraceRecordPublished(): void {\n counters.published += 1;\n}\n\n/** Count one trace record dropped. Called by the edge publisher. */\nexport function countTraceRecordDropped(): void {\n counters.dropped += 1;\n}\n\n/** A snapshot of the process-wide {@link TraceRecordCounts}. */\nexport function traceRecordCounts(): TraceRecordCounts {\n return Object.freeze({ published: counters.published, dropped: counters.dropped });\n}\n\n/** Identity of the prompt execution running in the current async context. */\nexport interface TraceScope {\n /** This execution's own thread ID — the parent of any thread it spawns. */\n readonly threadId: string;\n /** The tree's root thread ID, inherited unchanged; equals `threadId` on a root. */\n readonly rootId: string;\n /**\n * Where in this execution any thread it spawns next was sent out: how\n * many times it has stamped trace headers on a model request so far.\n * Deliberately mutable and shared — work spawned inside the handler\n * holds the same scope object, so its turns count against this\n * execution.\n */\n turnCountHint: number;\n}\n\n// Kept on `globalThis` under a well-known symbol, for the reason the\n// counters above are: the scope is bound by the host interceptor and read\n// by a client's prompt interceptor used as a tool inside the handler, and\n// the two can come from different installed copies of this module — a\n// nested install, a harness pinning its own version, the ESM and CJS\n// builds both loaded. One AsyncLocalStorage per copy would keep the scope\n// the host bound invisible to the client, and every child thread would\n// silently become a root. One process, one storage, whichever copy asks.\nconst STORAGE_KEY = Symbol.for(\"@synadia-ai/agent-fabric:trace-scope\");\nconst storage: AsyncLocalStorage<TraceScope> = (() => {\n const g = globalThis as unknown as Record<symbol, AsyncLocalStorage<TraceScope> | undefined>;\n return (g[STORAGE_KEY] ??= new AsyncLocalStorage<TraceScope>());\n})();\n\n/**\n * Run `fn` with `scope` as the ambient execution (what the host\n * interceptor does around a prompt handler). AsyncLocalStorage restores\n * the previous binding on exit, so nothing leaks into the next request.\n */\nexport function bindActiveTrace<T>(scope: TraceScope, fn: () => T): T {\n return storage.run(scope, fn);\n}\n\n/** The ambient {@link TraceScope}, or `undefined` outside a bound handler. */\nexport function activeTrace(): TraceScope | undefined {\n return storage.getStore();\n}\n\n/**\n * Headers for every model request this execution issues.\n *\n * An agent stamps these on each completion request so the model proxy\n * files the call under the right thread and tree without seeing any NATS\n * traffic. Hierarchy is the edge records' job, so the proxy needs no\n * parent or tool-call header.\n *\n * `{}` outside a traced handler, so harness code needs no plumbing and\n * degrades to nothing.\n *\n * Each call counts against this execution: the running total is recorded\n * on the edge of any thread it spawns afterwards.\n */\nexport function traceHeaders(): Record<string, string> {\n const scope = activeTrace();\n if (scope === undefined) return {};\n scope.turnCountHint += 1;\n return {\n [THREAD_ID_HEADER]: scope.threadId,\n [ROOT_ID_HEADER]: scope.rootId,\n };\n}\n\n/** Length in hex characters of a thread ID — 128 bits. */\nexport const THREAD_ID_HEX_LEN = 32;\n\nconst THREAD_ID_RE = new RegExp(`^[0-9a-f]{${THREAD_ID_HEX_LEN}}$`);\n\n/**\n * `true` iff `value` has the shape of a thread ID: exactly\n * {@link THREAD_ID_HEX_LEN} lowercase hex characters. Ids arriving on the\n * wire are untrusted input that ends up in the headers an agent stamps on\n * its model requests, so a receiver adopts nothing that is not shaped\n * exactly like what the packages mint.\n */\nexport function isThreadId(value: string): boolean {\n return THREAD_ID_RE.test(value);\n}\n\nexport function randomThreadId(): string {\n // Thread IDs don't need to be secure and any random generator will\n // suffice. Still, using crypto.getRandomValues() doesn't cost us much.\n const bytes = new Uint8Array(THREAD_ID_HEX_LEN / 2);\n crypto.getRandomValues(bytes);\n let out = \"\";\n for (const b of bytes) out += b.toString(16).padStart(2, \"0\");\n return out;\n}\n\n/** Longest accepted tool call id, in Unicode code points. */\nexport const TOOL_CALL_ID_MAX = 256;\n\n// A surrogate half with no partner: not a Unicode scalar value, so it has\n// no UTF-8 form. `JSON.stringify` would escape it while Python could not\n// encode the record at all, and the two packages must write the same bytes.\n// Shared with `served.ts`; not part of the package's surface.\nexport const LONE_SURROGATE =\n /[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/;\n\nexport function validToolCallId(toolCallId: string): boolean {\n // This isn't intended as strict validation. It's just a basic\n // pass to avoid obvious garbage gets into the tracing system.\n // Counted in code points — not UTF-16 units — so the Python package,\n // whose `len()` counts code points, accepts exactly the same ids.\n if (LONE_SURROGATE.test(toolCallId)) return false;\n const codePoints = Array.from(toolCallId).length;\n return codePoints > 0 && codePoints <= TOOL_CALL_ID_MAX;\n}\n\n/** One built edge record: its wire bytes and the id that de-duplicates it. */\nexport interface BuiltEdgeRecord {\n readonly recordId: string;\n readonly payload: Uint8Array;\n}\n\n/**\n * One edge record, ready to publish. The record id comes back alongside\n * the payload: the publisher signs with it as the `Agent-Sender` nonce,\n * which the SDK's signed publish also stamps as `Nats-Msg-Id`, so body,\n * header and message id carry one id and a stream de-duplicates a record\n * it already stored. Its 32 hex characters fit the nonce's\n * `[A-Za-z0-9_-]{1,64}`.\n *\n * `agent` is the writer — the caller that spawned the thread, the parent\n * side of the edge — in canonical `{account}.{user}` form. It is the same\n * identity that signs the record's `Agent-Sender` header, so a consumer\n * can cross-check the body against the verified header.\n */\nexport function buildEdgeRecord(\n agent: AgentId,\n threadId: string,\n parentId: string | null,\n rootId: string,\n toolCallId: string | null,\n turnCountHint: number,\n): BuiltEdgeRecord {\n // `turnCountHint` says where in the spawning thread this subprompt went\n // out: turns completed when it was spawned, 0 on a root (nothing spawned\n // it). A position marker, not a total — turns the parent takes after its\n // last spawn are recorded nowhere.\n const recordId = randomThreadId();\n const record = {\n version: EDGE_RECORD_VERSION,\n kind: \"edge\",\n record_id: recordId,\n ts: Math.floor(Date.now() / 1000),\n agent,\n thread_id: threadId,\n parent_id: parentId,\n root_id: rootId,\n tool_call_id: toolCallId,\n turn_count_hint: turnCountHint,\n };\n return { recordId, payload: new TextEncoder().encode(JSON.stringify(record)) };\n}\n","// Tracing on the protocol SDK's hooks: `fabricTracing()` returns the three\n// things the SDK takes — a prompt interceptor for `Agents`, a request\n// interceptor and a heartbeat extras provider for `AgentService` — built\n// from the vocabulary in `trace.ts`. Mirrors\n// `synadia_ai/agent_fabric/tracing.py`; the two must stay wire-identical.\n//\n// The caller side, per prompt:\n// - phase one (`beforePrompt`, in the async context `prompt()` was called\n// in) mints the new thread's ID and inherits root and parent from the\n// ambient scope — a root when none is bound — and adds `thread_id` and\n// `root_id` to the envelope. The parent stays in the edge record and\n// never transits the child;\n// - phase two (`beforePublish`, after the prompt is signed and its size\n// checked, immediately before it is published) builds and publishes\n// the signed edge record, so an observer sees the node before it runs\n// and a prompt that never goes out owes no record.\n//\n// The host side, per request: adopt the envelope's pair, mint a root when\n// there is none, refuse a half pair or a malformed ID with `400` before the\n// handler runs, and run the handler inside the scope — which is what\n// `traceHeaders()` reads, and what a traced client used inside the handler\n// inherits. The host writes no record.\n\nimport { RequestRejectedError, type RequestInterceptor } from \"@synadia-ai/agent-service\";\nimport type { PromptInterceptor, PromptInterceptorContext } from \"@synadia-ai/agents\";\nimport {\n activeTrace,\n assertValidTraceOptions,\n bindActiveTrace,\n buildEdgeRecord,\n countTraceRecordDropped,\n countTraceRecordPublished,\n DEFAULT_EDGE_SUBJECT,\n isThreadId,\n randomThreadId,\n ROOT_ID_FIELD,\n THREAD_ID_FIELD,\n THREAD_ID_HEX_LEN,\n traceRecordCounts,\n validToolCallId,\n type TraceOptions,\n type TraceScope,\n} from \"./trace.js\";\n\n/** The key of `PromptOptions.context` the caller interceptor reads the tool call ID from. */\nexport const TOOL_CALL_ID_CONTEXT_KEY = \"toolCallId\";\n\n/** What {@link fabricTracing} returns: the SDK's three hooks, ready to pass in. */\nexport interface FabricTracing {\n /** For the caller: `new Agents({ ..., interceptors: [tracing.promptInterceptor] })`. */\n readonly promptInterceptor: PromptInterceptor;\n /** For the host: `new AgentService({ ..., interceptors: [tracing.requestInterceptor] })`. */\n readonly requestInterceptor: RequestInterceptor;\n /**\n * For the host: `new AgentService({ ..., heartbeatExtras: tracing.heartbeatExtras })`.\n * `records_published` and `records_dropped` — the process-wide\n * {@link traceRecordCounts} — read fresh for every heartbeat and status\n * reply. `{}` in propagate-only mode, which publishes no records and\n * would otherwise report a constant 0/0 that looks like a healthy zero.\n */\n readonly heartbeatExtras: () => Readonly<Record<string, unknown>>;\n}\n\n/**\n * Tracing for an agent on the fabric, as the protocol SDK's hooks.\n *\n * Throws `NatsAgentError` for an `edgeSubject` that can never be published\n * to (see {@link assertValidTraceOptions}). `options.edgeSubject` defaults\n * to {@link DEFAULT_EDGE_SUBJECT}; `null` is propagate-only mode.\n */\nexport function fabricTracing(options: TraceOptions = {}): FabricTracing {\n assertValidTraceOptions(options);\n const edgeSubject =\n options.edgeSubject === undefined ? DEFAULT_EDGE_SUBJECT : options.edgeSubject;\n return {\n promptInterceptor: promptInterceptor(edgeSubject),\n requestInterceptor,\n heartbeatExtras:\n edgeSubject === null\n ? () => ({})\n : () => {\n const counts = traceRecordCounts();\n return { records_published: counts.published, records_dropped: counts.dropped };\n },\n };\n}\n\n/**\n * What phase one decided to record; built into a record in phase two. The\n * lineage is fixed when the prompt is planned — when the ambient trace is\n * still the caller's — but the record's `ts` and `agent` are resolved\n * immediately before the publish.\n */\ninterface EdgePlan {\n readonly threadId: string;\n readonly parentId: string | null;\n readonly rootId: string;\n readonly toolCallId: string | null;\n readonly turnCountHint: number;\n}\n\nfunction promptInterceptor(edgeSubject: string | null): PromptInterceptor {\n return {\n beforePrompt(ctx) {\n // Tracing is best-effort and shouldn't stop an agent from sending out\n // a prompt. Invalid tool call ids are just ignored.\n const raw = ctx.context[TOOL_CALL_ID_CONTEXT_KEY];\n const toolCallId = typeof raw === \"string\" && validToolCallId(raw) ? raw : null;\n const plan = { ...mintLineage(), toolCallId };\n // The envelope carries only what the receiver must inherit; the\n // parent stays in the edge record and never transits the child.\n return {\n fields: { [THREAD_ID_FIELD]: plan.threadId, [ROOT_ID_FIELD]: plan.rootId },\n state: plan,\n };\n },\n async beforePublish(ctx, extras) {\n const plan = extras?.state as EdgePlan | undefined;\n if (edgeSubject === null || plan === undefined) return;\n await publishEdge(ctx, edgeSubject, plan);\n },\n };\n}\n\n// The thread ID names this prompt's execution. Inside a prompt handler the\n// ambient trace supplies the tree root and this prompt's parent; with none\n// bound, the prompt starts its own tree.\nfunction mintLineage(): Omit<EdgePlan, \"toolCallId\"> {\n const threadId = randomThreadId();\n const ambient = activeTrace();\n if (ambient === undefined) {\n return { threadId, parentId: null, rootId: threadId, turnCountHint: 0 };\n }\n return {\n threadId,\n parentId: ambient.threadId,\n rootId: ambient.rootId,\n turnCountHint: ambient.turnCountHint,\n };\n}\n\n/**\n * Build and publish one signed edge record.\n *\n * The signature covers the short-form subject the record is published to:\n * per the identity design a remap that only drops the account token is not\n * a rename, so no `sub` override is needed. Consumers verify in stored\n * mode. The record's `agent` is the client's own identity — the one that\n * signs it — so body and header agree. Its `record_id` is the header's\n * nonce and, through the SDK's signed publish, the `Nats-Msg-Id` as well:\n * one id, so a reader de-duplicating on `(user, record_id)` and a stream\n * de-duplicating on the message id see the same record once.\n *\n * Fail-open — a failed publish never fails the prompt. It is counted:\n * every record that goes out or fails to moves the process-wide\n * {@link traceRecordCounts}, which the host reports on its heartbeat.\n */\nasync function publishEdge(\n ctx: PromptInterceptorContext,\n subject: string,\n plan: EdgePlan,\n): Promise<void> {\n // Consumers ignore unsigned records, so publishing without a signer\n // would be pure waste: warn once per connection and skip. Minting and\n // envelope lineage need no identity and still happen, so downstream\n // agents that do have one keep tracing. The record was due — the prompt\n // is about to go out — and cannot go out: a drop, counted here rather\n // than when the prompt was planned, so a prompt that is never sent owes\n // nothing and counts nothing.\n if (!ctx.identity.canSign) {\n warnEdgesUnsigned(ctx.connection);\n countTraceRecordDropped();\n return;\n }\n try {\n const agent = await ctx.identity.selfId();\n const record = buildEdgeRecord(\n agent,\n plan.threadId,\n plan.parentId,\n plan.rootId,\n plan.toolCallId,\n plan.turnCountHint,\n );\n await ctx.identity.publishSigned(subject, record.payload, { nonce: record.recordId });\n countTraceRecordPublished();\n } catch (err) {\n countTraceRecordDropped();\n console.warn(`@synadia-ai/agent-fabric: failed to publish edge record on ${subject}`, err);\n }\n}\n\n// Connections already warned that their edge records go nowhere. One\n// warning per connection: a per-prompt log would itself be a way for\n// observability to disturb an agent.\nconst warnedUnsigned = new WeakSet<PromptInterceptorContext[\"connection\"]>();\n\nfunction warnEdgesUnsigned(nc: PromptInterceptorContext[\"connection\"]): void {\n if (warnedUnsigned.has(nc)) return;\n warnedUnsigned.add(nc);\n console.warn(\n \"@synadia-ai/agent-fabric: tracing is enabled but no identity signer is configured; \" +\n \"edge records are not published (consumers ignore unsigned records). \" +\n \"Pass identity: { signer } to sign them.\",\n );\n}\n\n/**\n * The host side: this execution's `(thread, root)`, adopted from the\n * envelope or minted, bound around the rest of the request. The host\n * writes no trace record.\n */\nconst requestInterceptor: RequestInterceptor = {\n async aroundRequest(ctx, next) {\n await bindActiveTrace(scopeFor(ctx.envelope.extras ?? {}), next);\n },\n};\n\n// The half pair's description; the pre-split SDK's decoder said the same.\nconst HALF_LINEAGE_PAIR = \"envelope `thread_id` and `root_id` must be given together\";\n\n/**\n * The execution's scope from the envelope's lineage pair: adopted\n * verbatim when both fields are there, a fresh root when neither is.\n *\n * A half pair is never completed. The pair travels together: a caller\n * that traces sends both, one that does not sends neither, unless it\n * relays an envelope it received, which keeps the pair it came with\n * (§5.6). Exactly one\n * names a broken or hand-written caller, and adopting the lone field would\n * file this execution under a tree the caller never named, or root a\n * thread the caller meant as a child — so it is a malformed envelope, the\n * same `400` as a wrongly shaped id, before the handler runs. The Python\n * package reads the wire the same way.\n */\nfunction scopeFor(extras: Readonly<Record<string, unknown>>): TraceScope {\n const threadId = lineageField(extras, THREAD_ID_FIELD);\n const rootId = lineageField(extras, ROOT_ID_FIELD);\n if ((threadId === undefined) !== (rootId === undefined)) {\n throw new RequestRejectedError(400, HALF_LINEAGE_PAIR);\n }\n if (threadId !== undefined && rootId !== undefined) {\n return { threadId, rootId, turnCountHint: 0 };\n }\n const minted = randomThreadId();\n return { threadId: minted, rootId: minted, turnCountHint: 0 };\n}\n\n/**\n * One lineage field, absent when the key is missing or `null`.\n *\n * A present-but-not-a-string value is a malformed envelope (400), the same\n * as any other wrongly-typed field — and the same as the Python package,\n * which rejects it too. Silently dropping it would make the receiver mint\n * a fresh root and file the execution under a tree of its own. An empty\n * string is absent, again matching Python.\n */\nfunction lineageField(\n extras: Readonly<Record<string, unknown>>,\n wireName: string,\n): string | undefined {\n const value = Object.hasOwn(extras, wireName) ? extras[wireName] : undefined;\n if (value === undefined || value === null) return undefined;\n if (typeof value !== \"string\") {\n throw new RequestRejectedError(400, `envelope \\`${wireName}\\` must be a string`);\n }\n // An empty id names nothing. Treating it as absent keeps a receiver\n // from adopting \"\" as a thread and filing every child under it — and\n // keeps both packages reading the same wire the same way.\n if (value === \"\") return undefined;\n // Untrusted, bounded input: the id is adopted verbatim and later stamped\n // on the agent's model requests as a header value, so anything not\n // shaped like a minted id (a CRLF, a megabyte of garbage) is malformed.\n if (!isThreadId(value)) {\n throw new RequestRejectedError(\n 400,\n `envelope \\`${wireName}\\` must be ${THREAD_ID_HEX_LEN} lowercase hex characters`,\n );\n }\n return value;\n}\n","// A caller on the fabric: code that prompts agents with a creds file and\n// nothing else. `fabricCaller()` connects with the file, signs every prompt\n// with its key, traces it (each prompt starts a task of its own), and hands\n// back the task's root id with the reply. Mirrors\n// `synadia_ai/agent_fabric/caller.py`.\n//\n// What a caller may do on the wire is narrow: it publishes prompts, status\n// and discovery requests, its edge records and its own identity lookup, and\n// it receives only on `_INBOX.agents.>` and the heartbeats. So the\n// connection's inbox prefix is `_INBOX.agents`: discovery, status and the\n// identity lookup all reply on the connection's inbox.\n//\n// The root id: tracing's prompt interceptor mints the thread and its root\n// at the stream's first iteration. The caller's own interceptor wraps it,\n// reads the root from the fields it returns, and resolves the prompt's\n// `rootId` with it. Nothing is bound around the prompt, so it is always the\n// root of a task of its own, never a child.\n\nimport { connect } from \"@nats-io/transport-node\";\nimport {\n Agents,\n assertValidSenderName,\n resolveNatsConnectionBundle,\n withAgentReconnectDefaults,\n type Agent,\n type PromptInterceptor,\n type PromptOptions,\n type PromptStream,\n type QueryEvent,\n type SignedNatsConnectionBundle,\n type StreamMessage,\n} from \"@synadia-ai/agents\";\nimport { ROOT_ID_FIELD, type TraceOptions } from \"./trace.js\";\nimport { fabricTracing } from \"./tracing.js\";\n\n/** The inbox prefix a caller's permissions allow it to receive on. */\nexport const CALLER_INBOX_PREFIX = \"_INBOX.agents\";\n\n/** What `ask()` replies to a question from the agent when no `onQuery` is given. */\nexport const CANNOT_ANSWER =\n \"The caller is a command line and cannot answer; continue with your best judgement.\";\n\n/** How long `list()` and `find()` listen for agents, by default. */\nexport const DEFAULT_DISCOVER_TIMEOUT_MS = 1_000;\n\n/** The variables {@link fabricCallerFromEnv} reads. */\nexport const NATS_URL_VAR = \"NATS_URL\";\nexport const NATS_CREDS_VAR = \"NATS_CREDS\";\n\n/**\n * Why a caller could not be set up, could not find its agent, or has no\n * root for a prompt: `config` (a missing or invalid setting), `connect`\n * (no connection), `identity` (the server would not say who the creds\n * file is), `not-found`, `ambiguous`, `not-sent` (the prompt ended before\n * it went out, so it has no root).\n */\nexport type FabricCallerErrorReason =\n \"config\" | \"connect\" | \"identity\" | \"not-found\" | \"ambiguous\" | \"not-sent\";\n\n/** A caller's own error: a missing setting, no connection, no identity, or no such agent. */\nexport class FabricCallerError extends Error {\n constructor(\n readonly reason: FabricCallerErrorReason,\n message: string,\n ) {\n super(message);\n this.name = \"FabricCallerError\";\n }\n}\n\nexport interface FabricCallerOptions {\n /** The path to the creds file. */\n readonly creds: string;\n /**\n * The server's URL, as the console showed it next to the creds file.\n * Default: `NATS_URL`. There is no built-in default.\n */\n readonly url?: string;\n /** The client's name, on the connection and in its identity. */\n readonly name?: string;\n /** Where the edge records go; `null` publishes none. Default: tracing's. */\n readonly edgeSubject?: TraceOptions[\"edgeSubject\"];\n}\n\n/** A prompt on its way: its stream, and the root of the task it starts. */\nexport interface CallerPrompt {\n /** The SDK's `PromptStream`, passed through: iterate it for the reply. */\n readonly stream: CallerStream;\n /**\n * The root id of the task the prompt starts. Resolves at the stream's\n * first iteration, before any chunk arrives; await it after iteration\n * has begun, never before. Rejects with a {@link FabricCallerError}\n * (`not-sent`), or the stream's own error, when the prompt ends before\n * it goes out: cancelled, refused before it was sent, or failed.\n */\n readonly rootId: Promise<string>;\n}\n\n/**\n * The SDK's `PromptStream`, with the prompt's root settled when iteration\n * ends or fails before the prompt went out. The messages are the SDK's,\n * unchanged.\n */\nexport class CallerStream implements AsyncIterable<StreamMessage> {\n readonly #inner: PromptStream;\n readonly #sink: RootSink;\n\n constructor(inner: PromptStream, sink: RootSink) {\n this.#inner = inner;\n this.#sink = sink;\n }\n\n /** The subject the prompt is published to. */\n get subject(): string {\n return this.#inner.subject;\n }\n\n /** Stop the stream, as `PromptStream.cancel()`. */\n cancel(): void {\n this.#sink.reject(notSent(\"it was cancelled\"));\n this.#inner.cancel();\n }\n\n async *[Symbol.asyncIterator](): AsyncIterator<StreamMessage> {\n try {\n for await (const msg of this.#inner) yield msg;\n } catch (err) {\n this.#sink.reject(err);\n throw err;\n } finally {\n // A no-op once the root is known: the prompt went out.\n this.#sink.reject(notSent(\"its stream ended first\"));\n }\n }\n}\n\nfunction notSent(why: string): FabricCallerError {\n return new FabricCallerError(\"not-sent\", `the prompt never went out, so it has no root: ${why}`);\n}\n\nexport interface AskOptions extends PromptOptions {\n /**\n * Answers a question the agent asks mid-reply. Without it, or when it\n * answers with nothing but whitespace, the agent is told the caller\n * cannot answer and goes on.\n */\n readonly onQuery?: (query: QueryEvent) => string | Promise<string>;\n}\n\n/** The whole reply to a prompt, and the root of the task it started. */\nexport interface CallerReply {\n readonly text: string;\n readonly rootId: string;\n}\n\nexport interface FabricCaller {\n /** The SDK's client, for anything beyond. */\n readonly agents: Agents;\n /** The URL the caller connected to. */\n readonly url: string;\n /** The agents on the fabric. */\n list(opts?: { readonly timeoutMs?: number }): Promise<Agent[]>;\n /**\n * One agent: by its prompt address, else by its kind when exactly one\n * agent has it. Throws {@link FabricCallerError} naming what is there.\n */\n find(who: string, opts?: { readonly timeoutMs?: number }): Promise<Agent>;\n /**\n * Prompt an agent: an address, a kind, or an `Agent` this caller's\n * `list()` or `find()` returned.\n */\n prompt(who: string | Agent, text: string, options?: PromptOptions): Promise<CallerPrompt>;\n /** Prompt an agent and wait for the whole reply. */\n ask(who: string | Agent, text: string, options?: AskOptions): Promise<CallerReply>;\n /** Close the client and the connection, then wipe the credentials. */\n close(): Promise<void>;\n}\n\n// The key of `PromptOptions.context` the root's deferred travels under. It\n// is read only by the caller's own interceptor; the SDK never reads the\n// context, and tracing reads only its tool call id key.\n/** Internal, for the tests. */\nexport const ROOT_SINK_KEY = \"agentFabricCallerRootSink\";\n\n/** Settles a prompt's root once: the first call wins. Internal. */\nexport interface RootSink {\n resolve(rootId: string): void;\n reject(err: unknown): void;\n}\n\n/** A root and its sink. Internal, for the tests. */\nexport function rootDeferred(): { readonly sink: RootSink; readonly rootId: Promise<string> } {\n let settled = false;\n let resolve!: (rootId: string) => void;\n let reject!: (err: unknown) => void;\n const rootId = new Promise<string>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n // An un-awaited rejection must never crash the process; whoever awaits\n // `rootId` still sees it.\n rootId.catch(() => {});\n const once =\n <T>(fn: (v: T) => void) =>\n (v: T): void => {\n if (settled) return;\n settled = true;\n fn(v);\n };\n return { rootId, sink: { resolve: once(resolve), reject: once(reject) } };\n}\n\n/** Connect a caller with a creds file. */\nexport async function fabricCaller(options: FabricCallerOptions): Promise<FabricCaller> {\n const creds = options.creds;\n if (typeof creds !== \"string\" || creds.length === 0) {\n throw new FabricCallerError(\n \"config\",\n `no creds file: pass creds, or set ${NATS_CREDS_VAR} to the creds file the console gave you`,\n );\n }\n const url = options.url ?? process.env[NATS_URL_VAR];\n if (url === undefined || url.length === 0) {\n throw new FabricCallerError(\n \"config\",\n `no server URL: pass url, or set ${NATS_URL_VAR} to the URL the console showed next to your creds file`,\n );\n }\n // Fails here, before anything connects, for an edge subject that can\n // never be published to, or a name the identity would refuse.\n const tracing = fabricTracing(\n options.edgeSubject !== undefined ? { edgeSubject: options.edgeSubject } : {},\n );\n if (options.name !== undefined) {\n try {\n assertValidSenderName(options.name);\n } catch (err) {\n throw new FabricCallerError(\"config\", `name: ${errorMessage(err)}`);\n }\n }\n\n // A missing or unreadable file, or one without a user seed (signing\n // needs it), is a setting to fix: one line, never a stack.\n let bundle: SignedNatsConnectionBundle;\n try {\n bundle = await resolveNatsConnectionBundle({ url, creds }, { identity: \"signed\" });\n } catch (err) {\n throw new FabricCallerError(\"config\", `creds file ${creds}: ${errorMessage(err)}`);\n }\n let nc: Awaited<ReturnType<typeof connect>>;\n try {\n nc = await connect(\n withAgentReconnectDefaults({\n ...bundle.connectionOptions,\n inboxPrefix: CALLER_INBOX_PREFIX,\n ...(options.name !== undefined ? { name: options.name } : {}),\n // A caller is short-lived: a wrong URL fails now, naming the URL,\n // instead of retrying forever before the first connection.\n waitOnFirstConnect: false,\n }),\n );\n } catch (err) {\n bundle.wipe();\n throw new FabricCallerError(\"connect\", `could not connect to ${url}: ${errorMessage(err)}`);\n }\n let agents: Agents;\n try {\n agents = new Agents({\n nc,\n identity: {\n signer: bundle.signer,\n ...(options.name !== undefined ? { name: options.name } : {}),\n },\n interceptors: [rootCapturing(tracing.promptInterceptor)],\n });\n } catch (err) {\n await nc.close();\n bundle.wipe();\n throw err;\n }\n // Every prompt is signed, and signing needs the creds file's identity,\n // which the server tells. Learnt once here, so a creds file the server\n // will not describe fails now rather than at each prompt.\n try {\n await agents.selfId();\n } catch (err) {\n await agents.close();\n await nc.close();\n bundle.wipe();\n throw new FabricCallerError(\n \"identity\",\n `the server at ${url} would not tell this creds file's identity, which signing needs: ${errorMessage(err)}`,\n );\n }\n\n const list = (opts: { readonly timeoutMs?: number } = {}): Promise<Agent[]> =>\n agents.discover({ timeoutMs: opts.timeoutMs ?? DEFAULT_DISCOVER_TIMEOUT_MS });\n\n const find = async (who: string, opts: { readonly timeoutMs?: number } = {}): Promise<Agent> =>\n pickAgent(await list(opts), who);\n\n const prompt = async (\n who: string | Agent,\n text: string,\n promptOptions: PromptOptions = {},\n ): Promise<CallerPrompt> => {\n const target = typeof who === \"string\" ? await find(who) : who;\n const { sink, rootId } = rootDeferred();\n let inner: PromptStream;\n try {\n inner = await target.prompt(text, {\n ...promptOptions,\n context: { ...(promptOptions.context ?? {}), [ROOT_SINK_KEY]: sink },\n });\n } catch (err) {\n sink.reject(err);\n throw err;\n }\n return { stream: new CallerStream(inner, sink), rootId };\n };\n\n const ask = async (\n who: string | Agent,\n text: string,\n askOptions: AskOptions = {},\n ): Promise<CallerReply> => {\n const { onQuery, ...promptOptions } = askOptions;\n const { stream, rootId } = await prompt(who, text, promptOptions);\n let reply = \"\";\n for await (const msg of stream) {\n if (msg.type === \"response\") reply += msg.text;\n else if (msg.type === \"query\") {\n // Every question is answered: an agent left waiting would stall.\n // An empty answer is no answer: the agent cannot decode zero bytes.\n const answer = onQuery !== undefined ? await onQuery(msg) : \"\";\n await msg.reply(answer.trim() === \"\" ? CANNOT_ANSWER : answer);\n }\n }\n return { text: reply, rootId: await rootId };\n };\n\n let closed = false;\n const close = async (): Promise<void> => {\n if (closed) return;\n closed = true;\n try {\n await agents.close();\n await nc.close();\n } finally {\n bundle.wipe();\n }\n };\n\n return { agents, url, list, find, prompt, ask, close };\n}\n\n/** {@link fabricCaller} from `NATS_URL` and `NATS_CREDS`. */\nexport function fabricCallerFromEnv(\n options: Omit<FabricCallerOptions, \"creds\" | \"url\"> = {},\n): Promise<FabricCaller> {\n return fabricCaller({ ...options, creds: process.env[NATS_CREDS_VAR] ?? \"\" });\n}\n\n/**\n * The rule {@link FabricCaller.find} applies: the agent whose prompt address\n * is `who`, else the one agent of kind `who`; otherwise an error that names\n * what is there.\n */\nexport function pickAgent(found: ReadonlyArray<Agent>, who: string): Agent {\n const byAddress = found.find((a) => a.promptSubject === who);\n if (byAddress !== undefined) return byAddress;\n const ofKind = distinctAddresses(found.filter((a) => a.agent === who));\n if (ofKind.length === 1) return ofKind[0]!;\n if (ofKind.length > 1) {\n throw new FabricCallerError(\n \"ambiguous\",\n `${ofKind.length} agents of kind \"${who}\": ${ofKind.map((a) => a.promptSubject).join(\", \")}; name one by its address`,\n );\n }\n const there = distinctAddresses(found)\n .map((a) => a.promptSubject)\n .join(\", \");\n throw new FabricCallerError(\"not-found\", `no agent \"${who}\"; there: ${there || \"nobody\"}`);\n}\n\n// One handle per prompt address: two instances of one agent share it.\nfunction distinctAddresses(agents: ReadonlyArray<Agent>): Agent[] {\n const seen = new Map<string, Agent>();\n for (const a of agents) if (!seen.has(a.promptSubject)) seen.set(a.promptSubject, a);\n return [...seen.values()];\n}\n\n/**\n * Tracing's prompt interceptor, with the root it mints handed to the\n * prompt's sink. Both phases are forwarded; the extras go back verbatim,\n * so the SDK hands tracing's own extras to its second phase. Internal:\n * not exported from the package; the tests reach it here.\n */\nexport function rootCapturing(inner: PromptInterceptor): PromptInterceptor {\n return {\n async beforePrompt(ctx) {\n const sink = ctx.context[ROOT_SINK_KEY] as RootSink | undefined;\n let extras;\n try {\n extras = await inner.beforePrompt(ctx);\n } catch (err) {\n sink?.reject(err);\n throw err;\n }\n const root = extras?.fields?.[ROOT_ID_FIELD];\n if (typeof root === \"string\") sink?.resolve(root);\n else sink?.reject(notSent(\"tracing minted no root\"));\n return extras;\n },\n async beforePublish(ctx, extras) {\n await inner.beforePublish?.(ctx, extras);\n },\n };\n}\n\nfunction errorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","// ScratchPad references — the vocabulary of handing content over by\n// reference on the fabric, and the port the agent's own ScratchPad client\n// plugs into. Mirrors `synadia_ai/agent_fabric/scratchpad.py`.\n//\n// A reference is one opaque token: service-issued `sp-r1:` or the existing\n// expanded `sp-ref:` form. Models copy it unchanged; clients resolve metadata.\n// Neither form grants authority. ScratchPad authenticates every reader and\n// checks current grants. The creator is a routing claim that discovery verifies.\n//\n// The rules the fabric keeps around references (the reference agents'\n// `tools/README.md`, `agent-fabric` `docs/agent-tools.md` §2.2):\n//\n// - who reads references says so, with `scratchpad_refs_ok: \"true\"` in its\n// service metadata; a reference goes to no other agent;\n// - an agent hands on only a reference it was given: it committed it, or\n// it arrived in a prompt it served or a reply it received;\n// - least authority: one grantee, one path, read only, a short expiry,\n// granted immediately before the reference goes out;\n// - being allowed to read is not being allowed to pass on: only a\n// volume's owner grants, so an agent that wants to hand on another\n// agent's reference asks its creator (`grant-request.ts`).\n//\n// This package holds that policy. It does not talk to ScratchPad: the\n// agent brings its own client, behind the {@link ScratchPad} port.\n\n/** Prefix of the expanded reference token. */\nexport const REFERENCE_PREFIX = \"sp-ref:\";\n\nexport const SHORT_REFERENCE_PREFIX = \"sp-r1:\";\n\nconst REFERENCE_RE = /sp-(?:ref|r1):[A-Za-z0-9_-]+/g;\n\n/**\n * The service metadata key an agent that reads the references it is handed\n * registers, with the value `\"true\"` (the SDK's `extraMetadata`). A caller\n * hands a reference, and grants read on it, only to an agent that says so.\n * In the style of the protocol's `attachments_ok`.\n */\nexport const READS_REFERENCES_KEY = \"scratchpad_refs_ok\";\n\n/** The served prompt's thread and root, as `activeTrace()` reports them. */\nexport interface TraceIds {\n readonly threadId: string;\n readonly rootId: string;\n}\n\n/**\n * The principal ScratchPad grants to: the two halves of an agent identity,\n * `<account>.<user>`, both public NKEYs on the fabric.\n */\nexport interface Grantee {\n readonly account: string;\n readonly user: string;\n}\n\n/**\n * How a grant came about. `first-hand`: the agent granted an agent it\n * handed the reference itself — the verified caller of its reply, or the\n * agent it prompted with a reference of its own. `on-request`: the agent\n * granted an agent because another agent asked it to (`grant-request.ts`).\n * Only a first-hand grant entitles its holder to ask for another agent, or\n * access could be relayed from agent to agent without end.\n */\nexport type GrantKind = \"first-hand\" | \"on-request\";\n\ntype MaybePromise<T> = T | Promise<T>;\n\n/**\n * What the policy needs of the agent's ScratchPad: its own volume, and a\n * ledger of the read grants it made. ScratchPad knows the grants but not\n * how they came about; that is the agent's own knowledge, so the\n * implementation keeps the ledger.\n */\nexport interface ScratchPad {\n /** Resolve reference metadata through the implementation's authenticated client. */\n resolveReference?(\n reference: string,\n trace?: TraceIds,\n ): MaybePromise<{ readonly creator: string }>;\n /** Whether `reference` points into this agent's own volume, where it may grant. */\n owns(reference: string): MaybePromise<boolean>;\n /**\n * Grant `grantee` read on the one path `reference` names, until the\n * grant's expiry, and note it in the ledger as `kind` (`first-hand` when\n * not given). Only for a reference into this agent's own volume. `trace`\n * and `toolCallId` label the grant, so it shows under the served prompt\n * and the tool call that caused it.\n */\n grantRead(\n reference: string,\n grantee: Grantee,\n trace: TraceIds | undefined,\n toolCallId?: string,\n kind?: GrantKind,\n ): MaybePromise<void>;\n /**\n * The live grant this agent made to `grantee` on what `reference` points\n * at, by kind; `undefined` when there is none or it has expired. A\n * first-hand grant still running is not hidden by a later one made on\n * request.\n */\n granted(reference: string, grantee: Grantee): MaybePromise<GrantKind | undefined>;\n}\n\n/** Every reference token in `text`, in order, repeats included. */\nexport function findReferences(text: string): string[] {\n return text.match(REFERENCE_RE) ?? [];\n}\n\n/**\n * `text` with reference tokens taken out — every one, or only those in\n * `only` — and the trailing spaces and extra blank lines that leaves\n * behind tidied away.\n */\nexport function removeReferences(text: string, only?: ReadonlyArray<string>): string {\n return text\n .replace(REFERENCE_RE, (token) => (only === undefined || only.includes(token) ? \"\" : token))\n .replace(/[ \\t]+$/gm, \"\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\n/**\n * The prompt address of the agent that made `reference`, as the token says;\n * `undefined` for a token that names none or does not decode.\n */\nexport function referenceCreator(reference: string): string | undefined {\n if (!reference.startsWith(REFERENCE_PREFIX)) return undefined;\n let made: unknown;\n try {\n made = JSON.parse(\n Buffer.from(reference.slice(REFERENCE_PREFIX.length), \"base64url\").toString(\"utf8\"),\n );\n } catch {\n return undefined;\n }\n if (typeof made !== \"object\" || made === null) return undefined;\n const creator = (made as Record<string, unknown>)[\"creator\"];\n return typeof creator === \"string\" && creator !== \"\" ? creator : undefined;\n}\n\n/** Whether an agent's registration metadata says it reads references. */\nexport function readsReferences(metadata: Readonly<Record<string, string>>): boolean {\n return metadata[READS_REFERENCES_KEY] === \"true\";\n}\n\n/**\n * The grantee behind an identity as discovery or a verified sender reports\n * it. Throws for anything that is not `<account>.<user>`.\n */\nexport function granteeFromIdentity(identity: string): Grantee {\n // The account half never contains a dot (an NKEY, a config-file account\n // name, or `$G`), so the first dot is the split.\n const dot = identity.indexOf(\".\");\n if (dot <= 0 || dot === identity.length - 1) {\n throw new Error(`not an agent identity: ${identity}`);\n }\n return { account: identity.slice(0, dot), user: identity.slice(dot + 1) };\n}\n","// The `agent-fabric` command: list the agents and prompt one, with the creds\n// file the console gave you and nothing else. `cli.ts` runs it; the tests\n// call `runCommand` with their own input and output. Mirrors\n// `synadia_ai/agent_fabric/cli.py`: the same subcommands, flags, lines and\n// exit codes.\n\nimport type { Agent } from \"@synadia-ai/agents\";\nimport {\n CANNOT_ANSWER,\n FabricCallerError,\n NATS_CREDS_VAR,\n NATS_URL_VAR,\n fabricCaller,\n type FabricCaller,\n} from \"./caller.js\";\nimport { findReferences } from \"./scratchpad.js\";\n\n/** Success. */\nexport const EXIT_OK = 0;\n/** No such agent, a refused or failed prompt, or no connection. */\nexport const EXIT_FAILED = 1;\n/** A usage error: a wrong argument, or no creds file or URL. */\nexport const EXIT_USAGE = 2;\n\n/** How long `prompt` waits for the whole reply, by default, in seconds. */\nexport const DEFAULT_TIMEOUT_S = 600;\n\nexport const USAGE = `usage: agent-fabric agents [options]\n agent-fabric prompt <address or kind> \"<text>\" [options]\n\nList the agents on the Synadia Agent Fabric, or prompt one, with the creds\nfile the console gave you. The reply streams to stdout; the server's URL,\nthe agent, the task's root id and a ScratchPad reference go to stderr. A\nquestion the agent asks is printed on stderr and answered from stdin.\n\noptions:\n --creds <file> the creds file (default: $${NATS_CREDS_VAR})\n --url <url> the URL the console showed next to your creds file\n (default: $${NATS_URL_VAR})\n --timeout <s> how long to wait for the whole reply, in seconds\n (default: ${DEFAULT_TIMEOUT_S})\n --json one JSON object on stdout instead of the stream\n -h, --help this help\n -- the rest is the text, even what starts with -\n\nexit codes: 0 done, 1 no such agent or a refused prompt, 2 usage`;\n\n/** Where the command reads and writes; the process's own in `cli.ts`. */\nexport interface CommandIO {\n /** Write to stdout. */\n out(text: string): void;\n /** Write to stderr. */\n err(text: string): void;\n /** One line from stdin, without its newline; `null` at its end. */\n readLine(): Promise<string | null>;\n /** The environment: `NATS_CREDS`, `NATS_URL`. */\n readonly env: Readonly<Record<string, string | undefined>>;\n}\n\n/** A parsed command line. */\nexport type ParsedCommand =\n | { readonly kind: \"help\" }\n | { readonly kind: \"usage\"; readonly message: string }\n | {\n readonly kind: \"agents\" | \"prompt\";\n readonly who?: string;\n readonly text?: string;\n readonly creds?: string;\n readonly url?: string;\n readonly timeoutS: number;\n readonly json: boolean;\n };\n\n/** Parse the arguments after the command's name. */\nexport function parseCommand(argv: ReadonlyArray<string>): ParsedCommand {\n const positional: string[] = [];\n let creds: string | undefined;\n let url: string | undefined;\n let timeoutS = DEFAULT_TIMEOUT_S;\n let json = false;\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i]!;\n if (arg === \"--\") {\n // Everything after it is the text, even what looks like an option.\n positional.push(...argv.slice(i + 1));\n break;\n }\n const [flag, inline] = arg.startsWith(\"--\") ? splitFlag(arg) : [arg, undefined];\n const value = (): string | undefined => inline ?? argv[++i];\n switch (flag) {\n case \"-h\":\n case \"--help\":\n return { kind: \"help\" };\n case \"--json\":\n json = true;\n break;\n case \"--creds\":\n case \"--url\":\n case \"--timeout\": {\n const v = value();\n if (v === undefined || v === \"\") return usage(`${flag} needs a value`);\n if (flag === \"--creds\") creds = v;\n else if (flag === \"--url\") url = v;\n else {\n const n = Number(v);\n if (!Number.isFinite(n) || n <= 0) {\n return usage(`--timeout must be a positive number of seconds, not \"${v}\"`);\n }\n timeoutS = n;\n }\n break;\n }\n default:\n if (arg.startsWith(\"-\") && arg !== \"-\") return usage(`unknown option ${arg}`);\n positional.push(arg);\n }\n }\n const [sub, ...rest] = positional;\n const common = {\n ...(creds !== undefined ? { creds } : {}),\n ...(url !== undefined ? { url } : {}),\n timeoutS,\n json,\n };\n if (sub === undefined) return usage(\"name a command: agents or prompt\");\n if (sub === \"help\") return { kind: \"help\" };\n if (sub === \"agents\") {\n if (rest.length > 0) return usage(`agents takes no arguments, not \"${rest.join(\" \")}\"`);\n return { kind: \"agents\", ...common };\n }\n if (sub === \"prompt\") {\n const [who, ...words] = rest;\n const text = words.join(\" \");\n if (who === undefined || text.length === 0) {\n return usage('prompt needs an agent and a text: prompt <address or kind> \"<text>\"');\n }\n return { kind: \"prompt\", who, text, ...common };\n }\n return usage(`unknown command \"${sub}\"`);\n}\n\nfunction splitFlag(arg: string): [string, string | undefined] {\n const eq = arg.indexOf(\"=\");\n return eq < 0 ? [arg, undefined] : [arg.slice(0, eq), arg.slice(eq + 1)];\n}\n\nfunction usage(message: string): ParsedCommand {\n return { kind: \"usage\", message };\n}\n\n/** Run the command; resolves with its exit code. */\nexport async function runCommand(argv: ReadonlyArray<string>, io: CommandIO): Promise<number> {\n const parsed = parseCommand(argv);\n if (parsed.kind === \"help\") {\n io.out(`${USAGE}\\n`);\n return EXIT_OK;\n }\n if (parsed.kind === \"usage\") {\n io.err(`agent-fabric: ${parsed.message}\\n\\n${USAGE}\\n`);\n return EXIT_USAGE;\n }\n const creds = parsed.creds ?? io.env[NATS_CREDS_VAR] ?? \"\";\n const url = parsed.url ?? io.env[NATS_URL_VAR] ?? \"\";\n if (creds === \"\") {\n io.err(`agent-fabric: no creds file: pass --creds, or set ${NATS_CREDS_VAR}\\n`);\n return EXIT_USAGE;\n }\n if (url === \"\") {\n io.err(\n `agent-fabric: no server URL: pass --url, or set ${NATS_URL_VAR} to the URL the console showed next to your creds file\\n`,\n );\n return EXIT_USAGE;\n }\n\n io.err(`url ${url}\\n`);\n let caller: FabricCaller;\n try {\n caller = await fabricCaller({ creds, url, name: \"agent-fabric\" });\n } catch (err) {\n io.err(`agent-fabric: ${message(err)}\\n`);\n return err instanceof FabricCallerError && err.reason === \"config\" ? EXIT_USAGE : EXIT_FAILED;\n }\n try {\n if (parsed.kind === \"agents\") return await listAgents(caller, parsed.json, io);\n return await prompt(caller, parsed.who!, parsed.text!, parsed, io);\n } catch (err) {\n if (err instanceof FabricCallerError) {\n io.err(`agent-fabric: ${err.message}\\n`);\n } else {\n // The agent refused the prompt or failed while serving it. The\n // protocol carries a code and a few words; the reason is in the\n // agent's own output.\n io.err(`agent-fabric: no reply: ${message(err)}\\n`);\n }\n return EXIT_FAILED;\n } finally {\n await caller.close();\n }\n}\n\n/** The JSON shape of one agent in `agents --json`. */\nexport interface AgentLine {\n readonly address: string;\n readonly kind: string;\n readonly identity: string | null;\n readonly verified: boolean;\n readonly description: string;\n}\n\nfunction agentLine(a: Agent): AgentLine {\n return {\n address: a.promptSubject,\n kind: a.agent,\n identity: a.identity ?? null,\n verified: a.idSigVerified,\n description: a.description,\n };\n}\n\nasync function listAgents(caller: FabricCaller, json: boolean, io: CommandIO): Promise<number> {\n const seen = new Set<string>();\n const lines: AgentLine[] = [];\n for (const a of await caller.list()) {\n if (seen.has(a.promptSubject)) continue;\n seen.add(a.promptSubject);\n lines.push(agentLine(a));\n }\n // By code point, as the Python command sorts: the same order in both.\n lines.sort((x, y) => (x.address < y.address ? -1 : x.address > y.address ? 1 : 0));\n if (json) {\n io.out(`${JSON.stringify(lines)}\\n`);\n return EXIT_OK;\n }\n if (lines.length === 0) io.err(\"no agents\\n\");\n for (const l of lines) io.out(`${l.address}\\t${l.kind}\\t${describeIdentity(l)}\\n`);\n return EXIT_OK;\n}\n\n// The agent's own registered identity, from discovery: not the prompt's\n// signature, which every prompt carries.\nfunction describeIdentity(l: AgentLine): string {\n if (l.identity === null) return \"agent identity: none\";\n return l.verified ? `agent ${l.identity}, verified` : `agent ${l.identity}`;\n}\n\nasync function prompt(\n caller: FabricCaller,\n who: string,\n text: string,\n opts: { readonly timeoutS: number; readonly json: boolean },\n io: CommandIO,\n): Promise<number> {\n const target = await caller.find(who);\n io.err(`→ ${target.promptSubject} (${describeIdentity(agentLine(target))})\\n`);\n const { stream, rootId } = await caller.prompt(target, text, {\n maxWaitMs: Math.round(opts.timeoutS * 1000),\n });\n // Printed when known; a prompt that never goes out has no root, and the\n // stream's own error says why.\n rootId.then(\n (root) => io.err(`root ${root}\\n`),\n () => {},\n );\n let reply = \"\";\n for await (const msg of stream) {\n if (msg.type === \"response\") {\n reply += msg.text;\n if (!opts.json) io.out(msg.text);\n } else if (msg.type === \"query\") {\n io.err(`? ${msg.prompt}\\n`);\n const answer = await io.readLine();\n await msg.reply(answer === null || answer.trim() === \"\" ? CANNOT_ANSWER : answer);\n }\n }\n const root = await rootId;\n const references = findReferences(reply);\n if (opts.json) {\n io.out(`${JSON.stringify({ root, text: reply, references })}\\n`);\n } else {\n io.out(\"\\n\");\n }\n const last = references.at(-1);\n if (last !== undefined) io.err(`reference: ${last}\\n`);\n return EXIT_OK;\n}\n\nfunction message(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","#!/usr/bin/env node\n// The `agent-fabric` command's entry: the process's own stdin, stdout,\n// stderr and environment around `runCommand`. No top-level await, so the\n// CommonJS build runs too.\n\nimport { createInterface } from \"node:readline\";\nimport { runCommand, type CommandIO } from \"./command.js\";\n\nfunction processIO(): CommandIO {\n let lines: AsyncIterator<string> | undefined;\n return {\n out: (text) => void process.stdout.write(text),\n err: (text) => void process.stderr.write(text),\n async readLine() {\n lines ??= createInterface({ input: process.stdin, terminal: false })[Symbol.asyncIterator]();\n const next = await lines.next();\n return next.done === true ? null : next.value;\n },\n env: process.env,\n };\n}\n\nfunction main(): Promise<number> {\n return runCommand(process.argv.slice(2), processIO());\n}\n\nmain().then(\n (code) => {\n process.exitCode = code;\n // stdin may still hold a reader open; nothing else is pending.\n process.stdin.destroy();\n },\n (err: unknown) => {\n process.stderr.write(`agent-fabric: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exitCode = 1;\n process.stdin.destroy();\n },\n);\n"]}