@tangle-network/agent-app 0.43.66 → 0.43.68

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.
Files changed (60) hide show
  1. package/dist/assistant/index.d.ts +4 -2
  2. package/dist/assistant/index.js +6 -3
  3. package/dist/assistant/index.js.map +1 -1
  4. package/dist/{attachment-validation-B2FFna9E.d.ts → attachment-validation-Dv1A_Puy.d.ts} +1 -1
  5. package/dist/chat-routes/index.d.ts +4 -3
  6. package/dist/chat-routes/index.js +6 -4
  7. package/dist/chat-routes/index.js.map +1 -1
  8. package/dist/chat-store/index.d.ts +3 -2
  9. package/dist/chat-store/index.js +4 -1
  10. package/dist/chat-store/index.js.map +1 -1
  11. package/dist/{chunk-JWBZ74TW.js → chunk-7ESQUSAC.js} +5 -3
  12. package/dist/{chunk-JWBZ74TW.js.map → chunk-7ESQUSAC.js.map} +1 -1
  13. package/dist/{chunk-X3N2H6JE.js → chunk-AFNTRJQ7.js} +10 -1
  14. package/dist/chunk-AFNTRJQ7.js.map +1 -0
  15. package/dist/chunk-F2CBC4DY.js +193 -0
  16. package/dist/chunk-F2CBC4DY.js.map +1 -0
  17. package/dist/chunk-HRH7ASAG.js +759 -0
  18. package/dist/chunk-HRH7ASAG.js.map +1 -0
  19. package/dist/{chunk-YTSEDJWA.js → chunk-RXOTWZ4G.js} +22 -6
  20. package/dist/chunk-RXOTWZ4G.js.map +1 -0
  21. package/dist/chunk-UDSY2F6N.js +331 -0
  22. package/dist/chunk-UDSY2F6N.js.map +1 -0
  23. package/dist/chunk-UOAYS72M.js +80 -0
  24. package/dist/chunk-UOAYS72M.js.map +1 -0
  25. package/dist/chunk-UP33Z633.js +141 -0
  26. package/dist/chunk-UP33Z633.js.map +1 -0
  27. package/dist/{chunk-FMDMI25K.js → chunk-V55WJSR4.js} +2 -2
  28. package/dist/{chunk-YKBDH2UY.js → chunk-WL7XHLDK.js} +2 -2
  29. package/dist/{chunk-7CTIUCQ4.js → chunk-YEFFHORB.js} +2 -73
  30. package/dist/chunk-YEFFHORB.js.map +1 -0
  31. package/dist/eval-campaign/index.d.ts +2 -81
  32. package/dist/index.d.ts +5 -1
  33. package/dist/index.js +62 -8
  34. package/dist/model-resolution/index.d.ts +100 -1
  35. package/dist/model-resolution/index.js +108 -0
  36. package/dist/model-resolution/index.js.map +1 -1
  37. package/dist/{parts-Bg8qcDvB.d.ts → parts-2ymE5cs-.d.ts} +15 -2
  38. package/dist/queue-C24V13h9.d.ts +68 -0
  39. package/dist/runtime/index.js +3 -2
  40. package/dist/sandbox/index.js +3 -2
  41. package/dist/teams/index.js +5 -5
  42. package/dist/teams/invitations-api.js +4 -4
  43. package/dist/teams-react/index.js +3 -3
  44. package/dist/tools/index.js +8 -6
  45. package/dist/trust-gate-Dcm5xSva.d.ts +83 -0
  46. package/dist/types-CEchbvgz.d.ts +268 -0
  47. package/dist/web-react/index.d.ts +97 -5
  48. package/dist/web-react/index.js +31 -4
  49. package/dist/work-product/index.d.ts +331 -0
  50. package/dist/work-product/index.js +54 -0
  51. package/dist/work-product/index.js.map +1 -0
  52. package/dist/work-product-react/index.d.ts +36 -0
  53. package/dist/work-product-react/index.js +180 -0
  54. package/dist/work-product-react/index.js.map +1 -0
  55. package/package.json +15 -1
  56. package/dist/chunk-7CTIUCQ4.js.map +0 -1
  57. package/dist/chunk-X3N2H6JE.js.map +0 -1
  58. package/dist/chunk-YTSEDJWA.js.map +0 -1
  59. /package/dist/{chunk-FMDMI25K.js.map → chunk-V55WJSR4.js.map} +0 -0
  60. /package/dist/{chunk-YKBDH2UY.js.map → chunk-WL7XHLDK.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/work-product/queue.ts"],"sourcesContent":["/**\n * The review queue is a PROJECTION, not a store — a client-safe pure fold of\n * existing sources into queue items (the `/missions` events.ts pattern: pure\n * data, re-validation at JSON boundaries). The only genuinely-new durable\n * state behind it is the {@link WorkProductRecord} row and its status\n * machine; everything else reads what already exists:\n *\n * - intake: a chat thread for the engagement scope with NO record yet\n * - missing_info: the open record's thread has a PENDING `/interactions` ask\n * - working: record status `draft` (the live token tail stays on the chat\n * surface's existing running-turns endpoint — the projection tracks no\n * live runs, per the reuse-the-primitive invariant)\n * - ready_for_review / changes_requested / approved / blocked: read directly\n * off `WorkProductRecord.status` (blocked surfaces its unresolved count)\n */\n\nimport {\n isWorkProductStatus,\n unresolvedBlockingExceptions,\n type WorkProductProvenance,\n type WorkProductRecord,\n type WorkProductRef,\n} from './types'\n\nexport type ReviewQueueState =\n | 'intake'\n | 'missing_info'\n | 'working'\n | 'ready_for_review'\n | 'changes_requested'\n | 'approved'\n | 'blocked'\n\n/** One row of the review queue projection for an engagement scope */\nexport interface ReviewQueueItem {\n scopeKey: string\n state: ReviewQueueState\n threadId: string | null\n workProduct?: WorkProductRef & { title: string; kind: string }\n /** The pending `/interactions` ask parking this scope, when any. */\n pendingAsk?: { interactionId: string; title: string }\n blockingExceptions: number\n failedChecks: number\n provenance?: Pick<WorkProductProvenance, 'profileHash' | 'servingModels'>\n updatedAt: number\n}\n\n/** An engagement-scoped chat thread — the intake candidate source. Products\n * that scope threads already carry a scopeKey-style column. */\nexport interface ReviewQueueThread {\n scopeKey: string\n threadId: string\n updatedAt: number\n}\n\n/** A pending `/interactions` ask on a thread (from the existing list\n * endpoint) — the missing_info source. */\nexport interface ReviewQueuePendingAsk {\n threadId: string\n interactionId: string\n title: string\n}\n\n/** Existing-source inputs the projection folds — no new stores */\nexport interface ReviewQueueInputs {\n workProducts: readonly WorkProductRecord[]\n /** Engagement threads with no work product yet → intake items. */\n threads?: readonly ReviewQueueThread[]\n /** Pending asks by thread → missing_info override on open records. */\n pendingAsks?: readonly ReviewQueuePendingAsk[]\n}\n\nconst OPEN_STATUSES = new Set(['draft', 'blocked', 'ready', 'changes_requested'])\n\n/** The record that represents a scope in the queue: its single open row when\n * one exists, else its latest approved version. Superseded rows are history\n * and never surface. */\nfunction currentRecordPerScope(records: readonly WorkProductRecord[]): Map<string, WorkProductRecord> {\n const byScope = new Map<string, WorkProductRecord>()\n for (const record of records) {\n if (record.status === 'superseded') continue\n const held = byScope.get(record.scopeKey)\n if (!held) {\n byScope.set(record.scopeKey, record)\n continue\n }\n const heldOpen = OPEN_STATUSES.has(held.status)\n const recordOpen = OPEN_STATUSES.has(record.status)\n if (recordOpen !== heldOpen) {\n if (recordOpen) byScope.set(record.scopeKey, record)\n continue\n }\n if (record.version > held.version || (record.version === held.version && record.updatedAt > held.updatedAt)) {\n byScope.set(record.scopeKey, record)\n }\n }\n return byScope\n}\n\nfunction stateOf(record: WorkProductRecord, pendingAsk: ReviewQueuePendingAsk | undefined): ReviewQueueState {\n switch (record.status) {\n case 'ready':\n return 'ready_for_review'\n case 'changes_requested':\n return 'changes_requested'\n case 'approved':\n return 'approved'\n case 'blocked':\n return pendingAsk ? 'missing_info' : 'blocked'\n case 'draft':\n return pendingAsk ? 'missing_info' : 'working'\n // 'superseded' is filtered before this switch.\n default:\n return 'working'\n }\n}\n\n/** Fold the existing sources into queue items, newest first. */\nexport function projectReviewQueue(inputs: ReviewQueueInputs): ReviewQueueItem[] {\n const asksByThread = new Map<string, ReviewQueuePendingAsk>()\n for (const ask of inputs.pendingAsks ?? []) {\n if (!asksByThread.has(ask.threadId)) asksByThread.set(ask.threadId, ask)\n }\n\n const items: ReviewQueueItem[] = []\n const byScope = currentRecordPerScope(inputs.workProducts)\n for (const [scopeKey, record] of byScope) {\n const pendingAsk = record.threadId ? asksByThread.get(record.threadId) : undefined\n const item: ReviewQueueItem = {\n scopeKey,\n state: stateOf(record, pendingAsk),\n threadId: record.threadId,\n workProduct: {\n id: record.id,\n version: record.version,\n title: record.artifact?.title ?? scopeKey,\n kind: record.artifact?.kind ?? '',\n },\n blockingExceptions: unresolvedBlockingExceptions(record.exceptions).length,\n failedChecks: record.checks.filter((check) => !check.passed).length,\n provenance: { profileHash: record.provenance.profileHash, servingModels: record.provenance.servingModels },\n updatedAt: record.updatedAt,\n }\n if (pendingAsk) item.pendingAsk = { interactionId: pendingAsk.interactionId, title: pendingAsk.title }\n items.push(item)\n }\n\n // Intake: an engagement thread with no record for its scope.\n for (const thread of inputs.threads ?? []) {\n if (byScope.has(thread.scopeKey)) continue\n if (items.some((item) => item.scopeKey === thread.scopeKey)) continue\n items.push({\n scopeKey: thread.scopeKey,\n state: 'intake',\n threadId: thread.threadId,\n blockingExceptions: 0,\n failedChecks: 0,\n updatedAt: thread.updatedAt,\n })\n }\n\n return items.sort((a, b) => b.updatedAt - a.updatedAt)\n}\n\n/** Re-validate one JSON-boundary row into a queue item; null for junk. The\n * client-side twin of the server projection, for payloads that cross a\n * fetch boundary. */\nexport function parseReviewQueueItem(raw: unknown): ReviewQueueItem | null {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null\n const record = raw as Record<string, unknown>\n const states: readonly ReviewQueueState[] = [\n 'intake',\n 'missing_info',\n 'working',\n 'ready_for_review',\n 'changes_requested',\n 'approved',\n 'blocked',\n ]\n if (typeof record.scopeKey !== 'string' || record.scopeKey.length === 0) return null\n if (!states.includes(record.state as ReviewQueueState)) return null\n if (record.threadId !== null && typeof record.threadId !== 'string') return null\n if (typeof record.blockingExceptions !== 'number' || typeof record.failedChecks !== 'number') return null\n if (typeof record.updatedAt !== 'number') return null\n const item: ReviewQueueItem = {\n scopeKey: record.scopeKey,\n state: record.state as ReviewQueueState,\n threadId: record.threadId,\n blockingExceptions: record.blockingExceptions,\n failedChecks: record.failedChecks,\n updatedAt: record.updatedAt,\n }\n const workProduct = record.workProduct as Record<string, unknown> | undefined\n if (workProduct && typeof workProduct === 'object') {\n if (\n typeof workProduct.id === 'string' &&\n typeof workProduct.version === 'number' &&\n typeof workProduct.title === 'string' &&\n typeof workProduct.kind === 'string'\n ) {\n item.workProduct = {\n id: workProduct.id,\n version: workProduct.version,\n title: workProduct.title,\n kind: workProduct.kind,\n }\n }\n }\n const pendingAsk = record.pendingAsk as Record<string, unknown> | undefined\n if (pendingAsk && typeof pendingAsk === 'object') {\n if (typeof pendingAsk.interactionId === 'string' && typeof pendingAsk.title === 'string') {\n item.pendingAsk = { interactionId: pendingAsk.interactionId, title: pendingAsk.title }\n }\n }\n const provenance = record.provenance as Record<string, unknown> | undefined\n if (provenance && typeof provenance === 'object') {\n if (\n typeof provenance.profileHash === 'string' &&\n Array.isArray(provenance.servingModels) &&\n provenance.servingModels.every((model) => typeof model === 'string')\n ) {\n item.provenance = { profileHash: provenance.profileHash, servingModels: provenance.servingModels as string[] }\n }\n }\n return item\n}\n\n/** Convenience guard used when a status string crosses a JSON boundary. */\nexport { isWorkProductStatus }\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  formatBytes
3
- } from "./chunk-X3N2H6JE.js";
3
+ } from "./chunk-AFNTRJQ7.js";
4
4
 
5
5
  // src/chat-routes/binary-sniff.ts
6
6
  function bytesStartWith(bytes, offset, signature) {
@@ -236,4 +236,4 @@ export {
236
236
  attachmentTotalSizeErrorMessage,
237
237
  createSandboxFileIndexRoute
238
238
  };
239
- //# sourceMappingURL=chunk-FMDMI25K.js.map
239
+ //# sourceMappingURL=chunk-V55WJSR4.js.map
@@ -10,7 +10,7 @@ import {
10
10
  import {
11
11
  dispatchAppTool,
12
12
  outcomeStatus
13
- } from "./chunk-7CTIUCQ4.js";
13
+ } from "./chunk-UOAYS72M.js";
14
14
 
15
15
  // src/tools/capability.ts
16
16
  async function createCapabilityToken(userId, opts) {
@@ -126,4 +126,4 @@ export {
126
126
  restrictTaxonomy,
127
127
  handleAppToolRequest
128
128
  };
129
- //# sourceMappingURL=chunk-YKBDH2UY.js.map
129
+ //# sourceMappingURL=chunk-WL7XHLDK.js.map
@@ -105,74 +105,6 @@ function findCustomTool(name, tools) {
105
105
  return tools?.find((t) => t.name === name);
106
106
  }
107
107
 
108
- // src/tools/dispatch.ts
109
- async function dispatchAppTool(toolName, rawArgs, ctx, opts) {
110
- try {
111
- if (!isAppToolName(toolName)) {
112
- const custom = findCustomTool(toolName, opts.customTools);
113
- if (!custom) return { ok: false, code: "unknown_tool", message: `${toolName} is not an app tool.` };
114
- const result = await custom.execute(rawArgs, ctx);
115
- return { ok: true, result };
116
- }
117
- if (toolName === "submit_proposal") {
118
- const type = String(rawArgs.type ?? "").trim();
119
- const title = String(rawArgs.title ?? "").trim();
120
- if (!type || !opts.taxonomy.proposalTypes.includes(type)) {
121
- return { ok: false, code: "invalid_type", message: `type must be one of: ${opts.taxonomy.proposalTypes.join(", ")}.` };
122
- }
123
- if (!title) return { ok: false, code: "missing_title", message: "title is required." };
124
- const description = rawArgs.description == null ? null : String(rawArgs.description);
125
- let regulated = opts.taxonomy.regulatedTypes.includes(type);
126
- if (opts.needsApproval) {
127
- try {
128
- regulated = await opts.needsApproval(type, { title, description }, ctx);
129
- } catch {
130
- regulated = true;
131
- }
132
- }
133
- const r2 = await opts.handlers.submitProposal({ type, title, description, regulated }, ctx);
134
- const { proposalId, deduped, status, ...extra } = r2;
135
- const effectiveStatus = status ?? "queued_for_approval";
136
- opts.onProduced?.({
137
- type: "proposal_created",
138
- proposalId,
139
- title,
140
- status: effectiveStatus === "executed" ? "executed" : "pending",
141
- content: description ?? void 0
142
- });
143
- return { ok: true, result: { ...extra, status: effectiveStatus, proposalId, deduped, regulated } };
144
- }
145
- if (toolName === "schedule_followup") {
146
- const r2 = await opts.handlers.scheduleFollowup(
147
- { title: String(rawArgs.title ?? ""), dueDate: String(rawArgs.dueDate ?? ""), priority: rawArgs.priority },
148
- ctx
149
- );
150
- return { ok: true, result: { followupId: r2.id, dueDate: r2.dueDate, deduped: r2.deduped } };
151
- }
152
- if (toolName === "render_ui") {
153
- const r2 = await opts.handlers.renderUi({ title: String(rawArgs.title ?? ""), schema: rawArgs.schema }, ctx);
154
- opts.onProduced?.({ type: "artifact", path: r2.path, content: r2.content });
155
- return { ok: true, result: { path: r2.path } };
156
- }
157
- const r = await opts.handlers.addCitation(
158
- { path: String(rawArgs.path ?? ""), quote: String(rawArgs.quote ?? ""), label: rawArgs.label },
159
- ctx
160
- );
161
- return { ok: true, result: { citationId: r.citationId, path: r.path } };
162
- } catch (err) {
163
- if (err instanceof ToolInputError) return { ok: false, code: err.code, message: err.message, status: err.status };
164
- return { ok: false, code: "app_tool_error", message: err instanceof Error ? err.message : String(err), status: 500 };
165
- }
166
- }
167
- function outcomeStatus(outcome) {
168
- return outcome.status ?? 400;
169
- }
170
-
171
- // src/tools/runtime.ts
172
- function createAppToolRuntimeExecutor(opts) {
173
- return ({ toolName, args }) => dispatchAppTool(toolName, args, opts.ctx, opts);
174
- }
175
-
176
108
  export {
177
109
  ToolInputError,
178
110
  APP_TOOL_NAMES,
@@ -180,9 +112,6 @@ export {
180
112
  buildAppToolOpenAITools,
181
113
  defineAppTool,
182
114
  customToolToOpenAI,
183
- findCustomTool,
184
- dispatchAppTool,
185
- outcomeStatus,
186
- createAppToolRuntimeExecutor
115
+ findCustomTool
187
116
  };
188
- //# sourceMappingURL=chunk-7CTIUCQ4.js.map
117
+ //# sourceMappingURL=chunk-YEFFHORB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/errors.ts","../src/tools/openai.ts","../src/tools/registry.ts"],"sourcesContent":["/** A correctable bad-input error a tool handler throws; the HTTP layer maps it\n * to a 4xx with the code, the runtime layer to a failed tool_result. So the\n * agent learns the call failed and can correct, instead of a silent success. */\nexport class ToolInputError extends Error {\n constructor(\n public code: string,\n message: string,\n public status = 400,\n ) {\n super(message)\n this.name = 'ToolInputError'\n }\n}\n","import type { AppToolTaxonomy, BuildAppToolsOptions } from './types'\n\n/** The four canonical app-tool names. Stable identifiers the model calls in\n * both the sandbox (MCP server name) and runtime (function-tool name) paths. */\nexport const APP_TOOL_NAMES = ['submit_proposal', 'schedule_followup', 'render_ui', 'add_citation'] as const\n/** Resolve a valid application tool name from the predefined list of tool names */\nexport type AppToolName = (typeof APP_TOOL_NAMES)[number]\n\nconst NAME_SET = new Set<string>(APP_TOOL_NAMES)\n/** Determine if a string matches a valid application tool name */\nexport function isAppToolName(name: string): name is AppToolName {\n return NAME_SET.has(name)\n}\n\n/** A minimal OpenAI Chat Completions function-tool shape — structurally\n * compatible with `@tangle-network/agent-runtime`'s `OpenAIChatTool` without\n * importing it (keeps this package runtime-free). */\nexport interface OpenAIFunctionTool {\n type: 'function'\n function: {\n name: string\n description: string\n parameters: Record<string, unknown>\n }\n}\n\n/**\n * Build the four app tools in OpenAI function-tool shape. `submit_proposal`'s\n * `type` enum is the product's {@link AppToolTaxonomy.proposalTypes}; the\n * model-facing descriptions and the follow-up priority enum default to the\n * Tangle reference vocabulary and can be retuned via {@link BuildAppToolsOptions}\n * (the tool names + JSON-Schema shapes stay fixed — they are mechanism). Pass\n * the result to the agent-runtime backend's `tools`.\n */\nexport function buildAppToolOpenAITools(\n taxonomy: AppToolTaxonomy,\n opts?: BuildAppToolsOptions,\n): OpenAIFunctionTool[] {\n const d = opts?.descriptions\n const priorityValues = opts?.priorityValues ?? ['low', 'medium', 'high']\n const custom: OpenAIFunctionTool[] = (opts?.customTools ?? []).map((t) => ({\n type: 'function',\n function: { name: t.name, description: t.description, parameters: t.parameters },\n }))\n return [\n {\n type: 'function',\n function: {\n name: 'submit_proposal',\n description:\n d?.submit_proposal ??\n 'Route a regulated or state-changing action to a human for approval (a recommendation, contacting/soliciting a contact, outreach, a record/account change, scheduling). Queues it for a named certified human to approve before it executes.',\n parameters: {\n type: 'object',\n properties: {\n type: { type: 'string', enum: [...taxonomy.proposalTypes] },\n title: { type: 'string', description: 'Short label for the approval queue.' },\n description: { type: 'string', description: 'The full drafted message/recommendation, with sources.' },\n },\n required: ['type', 'title'],\n },\n },\n },\n {\n type: 'function',\n function: {\n name: 'schedule_followup',\n description:\n d?.schedule_followup ??\n 'Register a dated cadence step (a reminder, chase, or check-in) on the follow-up calendar. Executes immediately.',\n parameters: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n dueDate: { type: 'string', description: 'ISO date YYYY-MM-DD.' },\n priority: { type: 'string', enum: [...priorityValues] },\n },\n required: ['title', 'dueDate'],\n },\n },\n },\n {\n type: 'function',\n function: {\n name: 'render_ui',\n description:\n d?.render_ui ??\n 'Show a generated view live in the workspace. Validates the OpenUI JSON and persists the artifact. Executes immediately.',\n parameters: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n schema: { type: 'object', description: 'The OpenUI JSON object.' },\n },\n required: ['title', 'schema'],\n },\n },\n },\n {\n type: 'function',\n function: {\n name: 'add_citation',\n description:\n d?.add_citation ??\n 'Anchor a grounding reference: the exact quote from a file backing a figure or claim. Verifies the quote appears in the file. Executes immediately.',\n parameters: {\n type: 'object',\n properties: {\n path: { type: 'string', description: 'The vault file path.' },\n quote: { type: 'string', description: 'The exact text from it.' },\n },\n required: ['path', 'quote'],\n },\n },\n },\n ...custom,\n ]\n}\n","import { isAppToolName } from './openai'\nimport type { AppToolContext } from './types'\nimport type { OpenAIFunctionTool } from './openai'\n\n/**\n * A product-defined app tool — the open registration seam.\n *\n * The four built-ins (`submit_proposal`/`schedule_followup`/`render_ui`/\n * `add_citation`) are mechanism and stay hard-typed. This is how a product adds\n * a fifth+ tool (e.g. gtm-agent's `set_config`) WITHOUT forking the shell: the\n * `name` + JSON-Schema `parameters` are what the model sees, and `execute` is\n * dispatched through the SAME validation/outcome path as the built-ins — a\n * thrown {@link ToolInputError} becomes a correctable 4xx, any other throw an\n * internal error, and a tool call never silently \"succeeds\" without its effect.\n */\nexport interface AppToolDefinition<Args = Record<string, unknown>> {\n /** Stable identifier the model calls (and the MCP server name). Must not\n * collide with a built-in app tool. */\n name: string\n /** Model-facing description. */\n description: string\n /** JSON-Schema for the parameters (the OpenAI `function.parameters` object). */\n parameters: Record<string, unknown>\n /** Default route path the per-turn MCP server / HTTP handler is mounted at.\n * Overridable per call via `paths`/`buildHttpMcpServer`. */\n path?: string\n /** Fulfil the call; the return value is the tool result the model sees.\n * `ctx` is the trusted per-turn identity (never from tool args). */\n execute: (args: Args, ctx: AppToolContext) => Promise<unknown> | unknown\n}\n\n/**\n * Validate + brand a product tool definition. Throws when the name is empty or\n * collides with a built-in (those are reserved mechanism). Identity otherwise —\n * call it at module scope so a bad definition fails at boot, not first use.\n */\nexport function defineAppTool<Args = Record<string, unknown>>(def: AppToolDefinition<Args>): AppToolDefinition<Args> {\n const name = def.name?.trim()\n if (!name) throw new Error('defineAppTool: name is required')\n if (isAppToolName(name)) throw new Error(`defineAppTool: \"${name}\" is a built-in app tool — choose a different name`)\n if (typeof def.execute !== 'function') throw new Error(`defineAppTool: \"${name}\" needs an execute() handler`)\n return def\n}\n\n/** The OpenAI function-tool def for a custom tool — appended to the built-ins by\n * `buildAppToolOpenAITools`. */\nexport function customToolToOpenAI(def: AppToolDefinition): OpenAIFunctionTool {\n return { type: 'function', function: { name: def.name, description: def.description, parameters: def.parameters } }\n}\n\n/** Find a registered custom tool by the name the model called. */\nexport function findCustomTool(\n name: string,\n tools: readonly AppToolDefinition[] | undefined,\n): AppToolDefinition | undefined {\n return tools?.find((t) => t.name === name)\n}\n"],"mappings":"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","names":[]}
@@ -2,88 +2,9 @@ import { JudgeVerdict } from '@tangle-network/agent-eval';
2
2
  export { EnsembleAggregate, JudgeVerdict, RunRecord, aggregateJudgeVerdicts } from '@tangle-network/agent-eval';
3
3
  import { Scenario, JudgeConfig } from '@tangle-network/agent-eval/campaign';
4
4
  export { CampaignResult, DispatchContext, Gate, JudgeConfig, JudgeDimension, JudgeScore, LabeledScenarioStore, MutableSurface, Mutator, Scenario, SurfaceProposer, defaultProductionGate, evolutionaryProposer, gepaProposer, paretoSignificanceGate, runCampaign } from '@tangle-network/agent-eval/campaign';
5
+ export { T as TrustItem, a as TrustThresholds, b as TrustVerdict, t as trustVerdicts } from '../trust-gate-Dcm5xSva.js';
5
6
  export { SelfImproveBudget, SelfImproveOptions, SelfImproveResult, selfImprove } from '@tangle-network/agent-eval/contract';
6
7
 
7
- /**
8
- * Trust gate — decides whether an ensemble's scores are allowed to be BELIEVED,
9
- * one level up from {@link aggregateJudgeVerdicts} (which only reduces ONE
10
- * artifact's raters to a composite). A composite is a number; this is the check
11
- * that the number means anything. It is the code "Enforced by" for the
12
- * measurement-validation skill's after-gate ("is this result allowed to be
13
- * believed").
14
- *
15
- * Three checks, each fail-loud and named in `trustReasons`:
16
- * (1) inter-rater reliability over the corpus ≥ `irrFloor` — raters that
17
- * disagree no better than chance carry no signal to optimize against.
18
- * (2) per-item rater spread ≤ `spreadCeiling` — for EACH item, raters must
19
- * converge on THAT item.
20
- * (3) surviving raters per item ≥ `minSurvivors` — a mean over one or two
21
- * raters is an anecdote, not an ensemble.
22
- *
23
- * CRITICAL metric semantics — per-item spread is rater disagreement about the
24
- * SAME item: `max(score) − min(score)` across the raters that scored THAT item
25
- * (max over its dimensions), never pooled across different items or across the
26
- * baseline/candidate sides. Pooling reads a genuine quality gap BETWEEN items as
27
- * "the raters split" and so trips the gate exactly when the finding is largest —
28
- * the failure mode the after-gate exists to prevent. The corpus IRR (check 1)
29
- * leans on the substrate's `interRaterReliability`, whose expected-disagreement
30
- * denominator already pools across items, so genuine item-to-item variation
31
- * RAISES reliability rather than lowering it.
32
- */
33
-
34
- /** One item's raters: the per-judge verdicts {@link aggregateJudgeVerdicts}
35
- * reduces, tagged with the item they scored so spread stays within-item. */
36
- interface TrustItem<D extends string = string> {
37
- /** Stable item identifier — surfaces in `perItemSpread` and `trustReasons`. */
38
- itemId: string;
39
- /** The raters' verdicts for THIS item (one per judge call). A failed judge
40
- * (`perDimension: null`) is dropped before spread/IRR, never folded as 0. */
41
- verdicts: readonly JudgeVerdict<D>[];
42
- }
43
- /** Thresholds for {@link trustVerdicts}. All overridable; defaults are the
44
- * conservative after-gate bar. */
45
- interface TrustThresholds {
46
- /** Minimum corpus inter-rater reliability (Krippendorff-style α). Below this
47
- * the raters agree no better than chance. Default 0.2. */
48
- irrFloor?: number;
49
- /** Maximum per-item rater spread (`max − min` over a single item's surviving
50
- * raters, across its dimensions). Above this the raters split ON THAT ITEM.
51
- * Default 0.5. */
52
- spreadCeiling?: number;
53
- /** Minimum surviving (non-failed) raters required per item. Default 3. */
54
- minSurvivors?: number;
55
- }
56
- /** Result of the trust gate. `trustworthy` iff every check passed; `trustReasons`
57
- * is empty iff `trustworthy`. */
58
- interface TrustVerdict {
59
- /** True iff IRR ≥ floor AND every item's spread ≤ ceiling AND every item has
60
- * ≥ `minSurvivors` surviving raters. */
61
- trustworthy: boolean;
62
- /** One entry per FAILED check, each naming its number + the offending value.
63
- * Empty iff `trustworthy`. */
64
- trustReasons: string[];
65
- /** Corpus inter-rater reliability actually measured (the check-1 value). */
66
- interRaterReliability: number;
67
- /** Per-item spread (`max − min` over surviving raters, max over dimensions),
68
- * keyed by `itemId`. The check-2 input, surfaced for drill-down. */
69
- perItemSpread: Record<string, number>;
70
- }
71
- /**
72
- * Decide whether an ensemble's per-item verdicts are trustworthy enough to
73
- * believe a lift computed from them. Pure: no LLM, no I/O, no clock, no random —
74
- * the same `items` + `thresholds` always yield the same verdict.
75
- *
76
- * Sibling to {@link aggregateJudgeVerdicts}: that reduces ONE item's raters to a
77
- * composite; this audits the raters ACROSS items and reports whether the
78
- * composites are believable. Run it on the corpus of held-out items before
79
- * reporting any lift over their scores.
80
- *
81
- * @throws if `items` is empty — an empty corpus has no measurable trust, and a
82
- * silent `trustworthy: true` over zero evidence is the exact lie the gate
83
- * exists to refuse.
84
- */
85
- declare function trustVerdicts<D extends string>(items: readonly TrustItem<D>[], thresholds?: TrustThresholds): TrustVerdict;
86
-
87
8
  /**
88
9
  * Eval-campaign — the app-shell's curated surface for a product's
89
10
  * self-improvement loop, NOT a reimplementation.
@@ -152,4 +73,4 @@ interface EnsembleJudgeConfig<TArtifact, TScenario extends Scenario, D extends s
152
73
  */
153
74
  declare function buildEnsembleJudge<TArtifact, TScenario extends Scenario, D extends string>(cfg: EnsembleJudgeConfig<TArtifact, TScenario, D>): JudgeConfig<TArtifact, TScenario>;
154
75
 
155
- export { type EnsembleJudgeConfig, type TrustItem, type TrustThresholds, type TrustVerdict, buildEnsembleJudge, trustVerdicts };
76
+ export { type EnsembleJudgeConfig, buildEnsembleJudge };
package/dist/index.d.ts CHANGED
@@ -17,7 +17,7 @@ export { KeyCrypto, KeyProvisioner, PlanLimit, PlatformBalanceInfo, PlatformBala
17
17
  export { HttpHeadProbeConfig, PreflightProbe, PreflightProbeResult, PreflightProbeVerdict, PreflightReport, RouterChatProbeConfig, SandboxAuthProbeConfig, formatPreflightReport, httpHeadProbe, routerChatProbe, runPreflight, sandboxAuthProbe } from './preflight/index.js';
18
18
  export { ObjectBody, ObjectKeyParts, ObjectStore, PutObjectOptions, R2LikeBucket, R2LikeObjectBody, R2LikeObjectHead, SignObjectUrlArgs, VerifyObjectUrlResult, assertSafeKeySegment, createProxiedArtifactRoute, createR2ObjectStore, objectKey, signObjectUrl, verifyObjectUrl } from './object-store/index.js';
19
19
  export { B as BULK_DELETE_MAX_THREADS, C as ChatStoreInputError, t as threadTitleFromMessage } from './core-7qIM7svy.js';
20
- export { C as ChatAttachmentKind, a as ChatAttachmentPart, b as ChatFilePart, c as ChatImagePart, d as ChatInteractionPart, e as ChatMentionKind, f as ChatMentionPart, g as ChatMessagePart, h as ChatNoticePart, i as ChatPartTime, j as ChatPlanPart, k as ChatReasoningPart, l as ChatStepFinishPart, m as ChatStepStartPart, n as ChatSubtaskPart, o as ChatTextPart, p as ChatToolPart, q as ChatToolState, r as ChatToolStatus, s as ChatUsageTokens, D as DEFAULT_ATTACHMENT_PROMPT_HEADER, S as StorableHarnessPartKind, t as attachmentInputToPart, u as attachmentKindForMime, v as attachmentPartsFromMessageParts, w as buildAttachmentPromptBlock, x as historyContentWithAttachments, y as isChatAttachmentPart, z as isChatInteractionPart, A as isChatMentionPart, B as isChatPlanPart, E as isChatStepFinishPart, F as isChatTextPart, G as isChatToolPart, H as mentionInputToPart, I as mentionPartsFromMessageParts, J as toChatMessageParts } from './parts-Bg8qcDvB.js';
20
+ export { C as ChatAttachmentKind, a as ChatAttachmentPart, b as ChatFilePart, c as ChatImagePart, d as ChatInteractionPart, e as ChatMentionKind, f as ChatMentionPart, g as ChatMessagePart, h as ChatNoticePart, i as ChatPartTime, j as ChatPlanPart, k as ChatReasoningPart, l as ChatStepFinishPart, m as ChatStepStartPart, n as ChatSubtaskPart, o as ChatTextPart, p as ChatToolPart, q as ChatToolState, r as ChatToolStatus, s as ChatUsageTokens, t as ChatWorkProductPart, D as DEFAULT_ATTACHMENT_PROMPT_HEADER, S as StorableHarnessPartKind, u as attachmentInputToPart, v as attachmentKindForMime, w as attachmentPartsFromMessageParts, x as buildAttachmentPromptBlock, y as historyContentWithAttachments, z as isChatAttachmentPart, A as isChatInteractionPart, B as isChatMentionPart, E as isChatPlanPart, F as isChatStepFinishPart, G as isChatTextPart, H as isChatToolPart, I as isChatWorkProductPart, J as mentionInputToPart, K as mentionPartsFromMessageParts, L as toChatMessageParts } from './parts-2ymE5cs-.js';
21
21
  export { DeriveKeyOptions, createFieldCrypto, decodeHexKey, decryptAesGcm, decryptBytes, decryptWithKey, deriveKey, encryptAesGcm, encryptBytes, encryptWithKey } from './crypto/index.js';
22
22
  export { J as JsonRecord, M as MISSING_TOOL_TERMINAL_ERROR, a as MISSING_TOOL_TERMINAL_REASON, S as StreamEvent, b as asRecord, c as asString, d as attachmentPartKey, e as collapseRedundantTextParts, f as draftAssistantParts, g as encodeEvent, h as finalizeAssistantParts, i as finalizePendingInteractionParts, j as getPartKey, m as mergePersistedPart, n as normalizePersistedPart, k as normalizeTime, l as normalizeToolEvent, r as resolveToolId, o as resolveToolName, t as terminalizeDanglingAssistantToolUpdates, p as terminalizeDanglingToolPart, q as terminalizeDanglingToolParts } from './stream-normalizer-QYUl4vnl.js';
23
23
  export { PersistedChatMessageForTurn, ResolvedChatTurn, buildUserTextParts, messageHasTurnId, normalizeClientTurnId, resolveChatTurn } from './stream/index.js';
@@ -29,6 +29,9 @@ export { ChatPlan, ChatPlanPersistedPart, ChatPlanStatus, PLAN_SUBMITTED_EVENT,
29
29
  export { CreateDurableInteractionRoutePersistenceOptions, DurableAnswerIntentJournal, DurableAnswerIntentRecord, DurableAnswerIntentState, DurableChatConflictError, DurableChatError, DurableChatErrorCode, DurableChatEventProjection, DurableChatGoneError, DurableChatScope, DurableChatStateStore, DurableChatUnavailableError, DurableFollowUpReceipt, DurableInteractionAcknowledgement, DurableInteractionGuarantee, DurableInteractionProjection, DurableInteractionProjectionAdapter, DurableInteractionSettlement, DurableInteractionSettlementFactoryOptions, DurableInteractionSettlementOptions, DurablePlanAuthority, DurablePlanAuthorityCurrentResult, DurablePlanAuthorityDecision, DurablePlanAuthorityResult, DurablePlanAuthorization, DurablePlanCommandJournal, DurablePlanCommandKey, DurablePlanCommandRecord, DurablePlanCommandState, DurablePlanDecision, DurablePlanEffectRecord, DurablePlanProjection, DurablePlanRouteAuthorizeArgs, DurablePlanRouteOptions, DurablePlanRoutes, DurablePlanStateStore, DurablePlanStore, InMemoryDurableChatStateStore, InMemoryDurableChatStore, PreparedDurableInteractionAnswer, applyDurableInteractionAnswer, applyDurableInteractionAsk, applyDurableInteractionCancel, createDurableChatEventProjection, createDurableChatScope, createDurableInteractionProjectionAdapter, createDurableInteractionRoutePersistence, createDurableInteractionSettlement, createDurablePlanRoutes, createInMemoryDurableChatStateStore, durableChatScopeKey, durableInteractionIntentKey, normalizePlanDecision, planAuthorityIdempotencyKey, planCommandKey, planEffectKey, recordDurableInteractionAnswer, recordDurableInteractionCancel, stablePlanReceipt, upsertDurableInteractionAsk } from './durable-chat/index.js';
30
30
  export { CompleteMissionInput, CreateMissionInput, DEFAULT_MISSION_STEP_KINDS, InMemoryMissionStore, MISSION_CONTROL_CHANNEL_ID, MissionApprovalsPort, MissionAuditEvent, MissionConcurrencyError, MissionCostLedger, MissionEngine, MissionEngineOptions, MissionEventSink, MissionGateKind, MissionGateOptions, MissionGateProposal, MissionOutcome, MissionPlanRunOptions, MissionProposalResolution, MissionRecord, MissionService, MissionServiceOptions, MissionState, MissionStatus, MissionStep, MissionStepState, MissionStepStatus, MissionStorePort, MissionStreamEvent, MissionStreamStatus, MissionStreamStep, MissionStreamStepStatus, MissionUpdateGuard, MissionUpdatePatch, ParseMissionBlocksOptions, ParsedMission, ParsedMissionStep, PlanOutcome, RetryableStepError, SandboxDispatch, SandboxDispatchDoneResult, SandboxDispatchInProgressResult, SandboxDispatchInput, SandboxDispatchResult, SetStepStatusPatch, StepGateClassification, StepOutcome, applyMissionEvent, asMissionStreamEvent, budgetGateProposalId, buildAgentMissionPlan, createInMemoryMissionStore, createMissionEngine, createMissionService, isMissionStopRequested, isMissionTerminal, mergeMissionState, noopEventSink, parseMissionBlocks, parseSessionStreamEnvelope, reduceMissionEvents, stepGateProposalId, volumeGateProposalId } from './missions/index.js';
31
31
  export { S as StepAgentActivity, W as WithAgentActivity, s as stepAgentActivity } from './agent-activity-C8ZG0F0M.js';
32
+ export { A as AgentCheckInput, E as EvidenceEntry, a as EvidenceLocator, b as ExceptionEntry, c as ExceptionSeverity, P as ProfileBacktestSummary, Q as QualityCheck, W as WorkProductArtifact, d as WorkProductAuditEvent, e as WorkProductParseResult, f as WorkProductPatch, g as WorkProductPersistedPart, h as WorkProductProvenance, i as WorkProductRecord, j as WorkProductRef, k as WorkProductStatus, l as WorkProductStorePort, m as WorkProductUpdateGuard, n as WorkProductVersionEntry, o as isWorkProductStatus, p as parseAgentCheckInput, q as parseArtifactInput, r as parseEvidenceInput, s as parseExceptionInput, t as persistedPartToWorkProduct, u as unresolvedBlockingExceptions, w as workProductToPersistedPart } from './types-CEchbvgz.js';
33
+ export { CreateWorkProductInput, EVIDENCE_COVERAGE_CHECK, FinalizeWorkProductProvenanceInput, InMemoryWorkProductStore, MAX_WORK_PRODUCT_BATCH, SubmitWorkProductInput, WorkProductAuthorizeArgs, WorkProductOutcome, WorkProductProvenanceBase, WorkProductRouteAuthorization, WorkProductRoutes, WorkProductRoutesOptions, WorkProductService, WorkProductServiceOptions, WorkProductToolConfig, WorkProductVerdictBody, WorkProductVerdictInput, buildWorkProductTools, canTransitionWorkProduct, createInMemoryWorkProductStore, createWorkProductRoutes, createWorkProductService, finalizeWorkProductProvenance, isWorkProductTerminal, stampProvenance, validateWorkProductVerdictBody, workProductTrustInputs } from './work-product/index.js';
34
+ export { R as ReviewQueueInputs, a as ReviewQueueItem, b as ReviewQueuePendingAsk, c as ReviewQueueState, d as ReviewQueueThread, p as parseReviewQueueItem, e as projectReviewQueue } from './queue-C24V13h9.js';
32
35
  export { AppToolDescriptor, AuthenticatedSandboxUser, BuildAppToolMcpServersOptions, BuildSandboxToolFileMountsOptions, DEFAULT_SANDBOX_RESOURCES, DriveSandboxTurnOptions, ENV_TOTAL_MAX_BYTES, ENV_VALUE_MAX_BYTES, EnsureWorkspaceSandboxOptions, LivenessProbeConfig, MemberSyncSeam, Outcome, PROVISION_PAYLOAD_MAX_BYTES, PeekWorkspaceSandboxOutcome, ProfileComposeOptions, PromptInputPart, ProviderResolutionConfig, ProvisionPayloadSections, ProvisionProfileSection, ResolveSandboxClientCredentialsOptions, ResolvedModel, SandboxApiCredentials, SandboxBuildContext, SandboxClientCredentials, SandboxCredentialEnvironment, SandboxExecChannel, SandboxExecOptions, SandboxFileBytesOutcome, SandboxFileSizeOutcome, SandboxPermissionLevel, SandboxResourceConfig, SandboxRestoreSpec, SandboxRuntimeAuthRefreshError, SandboxRuntimeConfig, SandboxRuntimeConnection, SandboxScope, SandboxStepTransition, SandboxTerminalTokenOptions, SandboxTerminalTokenResult, SandboxTerminalTokenSubject, SandboxTerminalWsMatch, SandboxToolPathOptions, SandboxToolSpec, ScopedTokenResult, SecretStore, StoppedSandboxResumeFailure, StoppedSandboxResumeRecovery, StreamSandboxPromptOptions, TerminalProxyIdentity, WorkspaceSandboxConnectionArgs, WorkspaceSandboxConnectionHandlerOptions, WorkspaceSandboxEnsureContext, WorkspaceSandboxInstanceLike, WorkspaceSandboxManager, WorkspaceSandboxManagerOptions, WorkspaceSandboxRuntimeProxyArgs, WorkspaceSandboxRuntimeProxyHandlerOptions, WorkspaceSandboxTerminalUpgradeHandlerOptions, WriteProfileFilesOptions, assertEnvWithinLimits, assertProvisionPayloadWithinCap, attachReasoningEffort, bearerSubprotocolToken, bearerToken, buildAppToolMcpServers, buildSandboxRuntimeProxyHeaders, buildSandboxToolFileMounts, buildSandboxToolPathSetupScript, classifySeveredStream, createSandboxTerminalToken, createWorkspaceSandboxConnectionHandler, createWorkspaceSandboxManager, createWorkspaceSandboxRuntimeProxyHandler, createWorkspaceSandboxTerminalUpgradeHandler, deferredCorpusHash, deleteSecret, detectInteractiveQuestion, driveSandboxTurn, encodeSandboxRuntimePath, ensureWorkspaceSandbox, flattenHistory, getClient, isSandboxTerminalWsUpgrade, isTerminalPromptEvent, matchSandboxTerminalWsPath, mergeExtraMcp, mergeHistoryIntoParts, mintSandboxScopedToken, mintTerminalProxyToken, peekWorkspaceSandbox, readSandboxBinaryBytes, readSecret, resetClientCache, resolveModel, resolveSandboxClientCredentials, runSandboxPrompt, runSandboxToolPathSetup, sandboxToolBinDir, sandboxToolPath, sandboxToolRootDir, secretStoreFromClient, shellQuote, splitDeferredProfileFiles, statSandboxFileSize, storeSecret, streamSandboxPrompt, syncSandboxMemberAdd, syncSandboxMemberRemove, syncSandboxMemberRole, terminalTokenFromRequest, verifySandboxTerminalToken, verifyTerminalProxyToken, writeProfileFilesToBox } from './sandbox/index.js';
33
36
  export { CookieOptions, JsonObject, KvLike, RateLimitResult, RequestContext, SecurityHeaderOptions, addSecurityHeaders, assertMediaUrl, checkRateLimit, clearCookieHeader, extractRequestContext, parseJsonObjectBody, readCookieValue, requireString, serializeCookie } from './web/index.js';
34
37
  export { BuildRedactedDocumentOptions, DEFAULT_REDACTION_PATTERNS, RedactForIngestionOptions, RedactedDocSegment, RedactedDocument, RedactionPattern, RedactionSpan, RevealResult, RevealSpanOptions, buildRedactedDocument, detectSpans, maskSpans, redactForIngestion, revealSpan } from './redact/index.js';
@@ -41,6 +44,7 @@ export { CompletionRequirement, CompletionVerdict, CorrectnessChecker, ProducedS
41
44
  export { F as FlowSpan, a as FlowTrace } from './flow-types-CqomVAUN.js';
42
45
  export { InteractionData, InteractionOutcome, InteractionRequest, modelProvider } from '@tangle-network/agent-interface';
43
46
  export { StorageConfig } from '@tangle-network/sandbox';
47
+ export { T as TrustItem } from './trust-gate-Dcm5xSva.js';
44
48
  import '@tangle-network/agent-runtime/intelligence';
45
49
  import '@tangle-network/agent-knowledge';
46
50
  import 'zod';
package/dist/index.js CHANGED
@@ -43,6 +43,24 @@ import {
43
43
  loopTraceEventsToFlowSpans,
44
44
  stepActivityFlowTrace
45
45
  } from "./chunk-FBVLEGEG.js";
46
+ import {
47
+ EVIDENCE_COVERAGE_CHECK,
48
+ MAX_WORK_PRODUCT_BATCH,
49
+ buildWorkProductTools,
50
+ canTransitionWorkProduct,
51
+ createInMemoryWorkProductStore,
52
+ createWorkProductRoutes,
53
+ createWorkProductService,
54
+ finalizeWorkProductProvenance,
55
+ isWorkProductTerminal,
56
+ stampProvenance,
57
+ validateWorkProductVerdictBody,
58
+ workProductTrustInputs
59
+ } from "./chunk-HRH7ASAG.js";
60
+ import {
61
+ parseReviewQueueItem,
62
+ projectReviewQueue
63
+ } from "./chunk-UP33Z633.js";
46
64
  import {
47
65
  HubExecClient,
48
66
  invokeIntegrationHub,
@@ -197,10 +215,21 @@ import {
197
215
  isChatStepFinishPart,
198
216
  isChatTextPart,
199
217
  isChatToolPart,
218
+ isChatWorkProductPart,
200
219
  mentionInputToPart,
201
220
  mentionPartsFromMessageParts,
202
221
  toChatMessageParts
203
- } from "./chunk-X3N2H6JE.js";
222
+ } from "./chunk-AFNTRJQ7.js";
223
+ import {
224
+ isWorkProductStatus,
225
+ parseAgentCheckInput,
226
+ parseArtifactInput,
227
+ parseEvidenceInput,
228
+ parseExceptionInput,
229
+ persistedPartToWorkProduct,
230
+ unresolvedBlockingExceptions,
231
+ workProductToPersistedPart
232
+ } from "./chunk-F2CBC4DY.js";
204
233
  import {
205
234
  MISSING_TOOL_TERMINAL_ERROR,
206
235
  MISSING_TOOL_TERMINAL_REASON,
@@ -344,7 +373,7 @@ import {
344
373
  restrictTaxonomy,
345
374
  verifyCapabilityToken,
346
375
  verifyExpiringCapabilityToken
347
- } from "./chunk-YKBDH2UY.js";
376
+ } from "./chunk-WL7XHLDK.js";
348
377
  import {
349
378
  DEFAULT_APP_TOOL_PATHS,
350
379
  DEFAULT_HEADER_NAMES,
@@ -371,7 +400,7 @@ import {
371
400
  runToolLoop,
372
401
  streamToolLoop,
373
402
  toLoopEvents
374
- } from "./chunk-JWBZ74TW.js";
403
+ } from "./chunk-7ESQUSAC.js";
375
404
  import {
376
405
  DEFAULT_TANGLE_BILLING_ENFORCEMENT_ENV_VAR,
377
406
  DEFAULT_TANGLE_ROUTER_BASE_URL,
@@ -387,18 +416,20 @@ import {
387
416
  tangleExecutionKeyHttpError,
388
417
  trimOrNull
389
418
  } from "./chunk-JML7WKWU.js";
419
+ import {
420
+ createAppToolRuntimeExecutor,
421
+ dispatchAppTool,
422
+ outcomeStatus
423
+ } from "./chunk-UOAYS72M.js";
390
424
  import {
391
425
  APP_TOOL_NAMES,
392
426
  ToolInputError,
393
427
  buildAppToolOpenAITools,
394
- createAppToolRuntimeExecutor,
395
428
  customToolToOpenAI,
396
429
  defineAppTool,
397
- dispatchAppTool,
398
430
  findCustomTool,
399
- isAppToolName,
400
- outcomeStatus
401
- } from "./chunk-7CTIUCQ4.js";
431
+ isAppToolName
432
+ } from "./chunk-YEFFHORB.js";
402
433
  import {
403
434
  __resetCatalogCache,
404
435
  buildCatalog,
@@ -440,6 +471,7 @@ export {
440
471
  DurableChatUnavailableError,
441
472
  ENV_TOTAL_MAX_BYTES,
442
473
  ENV_VALUE_MAX_BYTES,
474
+ EVIDENCE_COVERAGE_CHECK,
443
475
  EmailContentSchema,
444
476
  HubExecClient,
445
477
  INTERACTION_CANCEL_EVENT,
@@ -449,6 +481,7 @@ export {
449
481
  InMemoryDurableChatStateStore,
450
482
  InMemoryDurableChatStore,
451
483
  KNOWN_HARNESSES,
484
+ MAX_WORK_PRODUCT_BATCH,
452
485
  MCP_PROTOCOL_VERSIONS,
453
486
  MISSING_TOOL_TERMINAL_ERROR,
454
487
  MISSING_TOOL_TERMINAL_REASON,
@@ -505,8 +538,10 @@ export {
505
538
  buildSandboxToolPathSetupScript,
506
539
  buildScopedMcpServerEntry,
507
540
  buildUserTextParts,
541
+ buildWorkProductTools,
508
542
  canTransitionInteractionStatus,
509
543
  canTransitionPlanStatus,
544
+ canTransitionWorkProduct,
510
545
  cancelStatusFor,
511
546
  checkRateLimit,
512
547
  checkThemeContract,
@@ -538,6 +573,7 @@ export {
538
573
  createFieldCrypto,
539
574
  createInMemoryDurableChatStateStore,
540
575
  createInMemoryMissionStore,
576
+ createInMemoryWorkProductStore,
541
577
  createInteractionAnswerRoute,
542
578
  createKnowledgeLoop,
543
579
  createLlmCorrectnessChecker,
@@ -561,6 +597,8 @@ export {
561
597
  createTangleRouterModelConfig,
562
598
  createTcloudKeyProvisioner,
563
599
  createTokenRecallChecker,
600
+ createWorkProductRoutes,
601
+ createWorkProductService,
564
602
  createWorkspaceKeyManager,
565
603
  createWorkspaceSandboxConnectionHandler,
566
604
  createWorkspaceSandboxManager,
@@ -600,6 +638,7 @@ export {
600
638
  fieldAcceptsFreeText,
601
639
  finalizeAssistantParts,
602
640
  finalizePendingInteractionParts,
641
+ finalizeWorkProductProvenance,
603
642
  findCustomTool,
604
643
  flattenHistory,
605
644
  formatPreflightReport,
@@ -620,6 +659,7 @@ export {
620
659
  isChatStepFinishPart,
621
660
  isChatTextPart,
622
661
  isChatToolPart,
662
+ isChatWorkProductPart,
623
663
  isHarness,
624
664
  isMissionStopRequested,
625
665
  isMissionTerminal,
@@ -631,6 +671,8 @@ export {
631
671
  isTangleExecutionKeyError,
632
672
  isTerminalInteractionStatus,
633
673
  isTerminalPromptEvent,
674
+ isWorkProductStatus,
675
+ isWorkProductTerminal,
634
676
  lightTheme,
635
677
  listSessionInteractions,
636
678
  loopTraceEventsToFlowSpans,
@@ -659,17 +701,23 @@ export {
659
701
  noticePartKey,
660
702
  objectKey,
661
703
  outcomeStatus,
704
+ parseAgentCheckInput,
705
+ parseArtifactInput,
662
706
  parseAssetSpec,
707
+ parseEvidenceInput,
708
+ parseExceptionInput,
663
709
  parseInteractionAnswers,
664
710
  parseInteractionCancel,
665
711
  parseInteractionRequest,
666
712
  parseJsonObjectBody,
667
713
  parseMissionBlocks,
668
714
  parsePlanSubmittedEvent,
715
+ parseReviewQueueItem,
669
716
  parseSessionStreamEnvelope,
670
717
  peekWorkspaceSandbox,
671
718
  persistedPartToInteraction,
672
719
  persistedPartToPlan,
720
+ persistedPartToWorkProduct,
673
721
  planAuthorityIdempotencyKey,
674
722
  planCommandKey,
675
723
  planEffectKey,
@@ -678,6 +726,7 @@ export {
678
726
  planRevisionKey,
679
727
  planToPersistedPart,
680
728
  producedFromToolEvents,
729
+ projectReviewQueue,
681
730
  pumpBufferedTurn,
682
731
  questionInteractionContentSignature,
683
732
  readCookieValue,
@@ -729,6 +778,7 @@ export {
729
778
  splitDeferredProfileFiles,
730
779
  stablePlanReceipt,
731
780
  stampInteractionAnswers,
781
+ stampProvenance,
732
782
  statSandboxFileSize,
733
783
  stepActivityFlowTrace,
734
784
  stepAgentActivity,
@@ -753,8 +803,10 @@ export {
753
803
  toLoopEvents,
754
804
  traceEnv,
755
805
  trimOrNull,
806
+ unresolvedBlockingExceptions,
756
807
  upsertDurableInteractionAsk,
757
808
  validateInteractionAnswerBody,
809
+ validateWorkProductVerdictBody,
758
810
  verifyCapabilityToken,
759
811
  verifyCompletion,
760
812
  verifyExpiringCapabilityToken,
@@ -763,6 +815,8 @@ export {
763
815
  verifyTerminalProxyToken,
764
816
  volumeGateProposalId,
765
817
  weightedComposite,
818
+ workProductToPersistedPart,
819
+ workProductTrustInputs,
766
820
  writeProfileFilesToBox
767
821
  };
768
822
  //# sourceMappingURL=index.js.map
@@ -1,3 +1,102 @@
1
+ /**
2
+ * Model failover — the answer to "one upstream hit a quota wall and the customer
3
+ * got a Bad Gateway even though the router had abundant healthy capacity".
4
+ *
5
+ * This is deliberately NOT a health probe. Probing before every turn buys a
6
+ * round-trip of latency on the happy path and still races the outage (a model
7
+ * healthy at probe time can 502 a second later). Failover is REACTIVE: run the
8
+ * preferred model, and on an upstream-outage signal move to the next model in
9
+ * the chain. Zero added latency when the preferred model works.
10
+ *
11
+ * Two facts drive the design, both measured against a live box during the
12
+ * 2026-07-25 Anthropic/DeepSeek outage:
13
+ *
14
+ * 1. An outage is NOT always a thrown error. The sandbox resolves with a
15
+ * payload — `{ success: false, errorCode: 'provider_inference_unavailable' }`
16
+ * — so a classifier that only inspects `catch` misses the customer-visible
17
+ * case entirely. `isUpstreamUnavailable` inspects resolved values too.
18
+ * 2. Catalog membership is NOT liveness. The router's `/v1/models` still listed
19
+ * every dead model during the outage, so `validateChatModelId` admitted
20
+ * `claude-sonnet-4-6` while every call to it returned 502. Nothing upstream
21
+ * of the actual call can be trusted to tell you a model is serving.
22
+ *
23
+ * Substrate-free: the caller injects `run`, so this composes with a sandbox
24
+ * turn, a router chat completion, or a test fake without importing any of them.
25
+ */
26
+ /**
27
+ * Error codes that mean "this model's upstream is unavailable — a different
28
+ * model may still work". Deliberately excludes codes that would fail identically
29
+ * on every model (bad request, auth, content filter): retrying those down a
30
+ * chain burns latency and money to reach the same failure.
31
+ */
32
+ declare const UPSTREAM_UNAVAILABLE_CODES: readonly string[];
33
+ /** HTTP statuses that indicate an upstream capacity/availability problem. */
34
+ declare const UPSTREAM_UNAVAILABLE_STATUSES: readonly number[];
35
+ /**
36
+ * True when `signal` — a thrown error OR a resolved result payload — indicates
37
+ * the model's upstream is unavailable and another model is worth trying.
38
+ *
39
+ * Checked in order of decreasing confidence: explicit code, HTTP status, then
40
+ * message text. A resolved payload only counts as a failure when it carries an
41
+ * explicit failure marker (`success: false`, or an `error`/`errorCode` field) —
42
+ * a successful result is never misread as an outage.
43
+ */
44
+ declare function isUpstreamUnavailable(signal: unknown): boolean;
45
+ /** One model tried, and how it went. */
46
+ interface ModelFailoverAttempt {
47
+ model: string;
48
+ ok: boolean;
49
+ /** Why this model was abandoned. Absent when `ok`. */
50
+ reason?: string;
51
+ }
52
+ /** The outcome of a failover run: the value plus the full attempt trail. */
53
+ interface ModelFailoverResult<T> {
54
+ value: T;
55
+ /** The model that actually produced `value`. */
56
+ model: string;
57
+ attempts: ModelFailoverAttempt[];
58
+ /** True when the preferred (first) model did not serve the request. */
59
+ usedFallback: boolean;
60
+ }
61
+ /** Every model in the chain failed; carries the trail for logging. */
62
+ declare class ModelFailoverExhaustedError extends Error {
63
+ readonly attempts: ModelFailoverAttempt[];
64
+ constructor(attempts: ModelFailoverAttempt[]);
65
+ }
66
+ /** Inputs to {@link runWithModelFailover}. */
67
+ interface RunWithModelFailoverInput<T> {
68
+ /** Preferred model first, then fallbacks in descending preference. */
69
+ models: readonly string[];
70
+ /** Executes one turn with the given model. */
71
+ run: (model: string) => Promise<T>;
72
+ /**
73
+ * Classifies a resolved result as an upstream outage. Defaults to
74
+ * {@link isUpstreamUnavailable}, which understands the sandbox's
75
+ * `{ success: false, errorCode }` payload.
76
+ */
77
+ isUnavailableResult?: (result: T) => boolean;
78
+ /** Classifies a thrown error. Defaults to {@link isUpstreamUnavailable}. */
79
+ isUnavailableError?: (error: unknown) => boolean;
80
+ /** Observability hook fired each time a model is abandoned. */
81
+ onFallback?: (attempt: ModelFailoverAttempt, nextModel: string) => void;
82
+ }
83
+ /**
84
+ * Run `run` against the first model in `models` that does not report an upstream
85
+ * outage, falling through the chain in order.
86
+ *
87
+ * A non-outage failure (bad request, auth, content filter) is re-thrown
88
+ * immediately rather than retried down the chain — those fail identically on
89
+ * every model, so walking the chain would only multiply latency and spend.
90
+ *
91
+ * @throws ModelFailoverExhaustedError when every model reports an outage.
92
+ */
93
+ declare function runWithModelFailover<T>(input: RunWithModelFailoverInput<T>): Promise<ModelFailoverResult<T>>;
94
+ /**
95
+ * Build a failover chain: the preferred model first, then `fallbacks`, with
96
+ * duplicates removed so a model is never retried twice in one turn.
97
+ */
98
+ declare function buildModelChain(preferred: string, fallbacks: readonly string[]): string[];
99
+
1
100
  /**
2
101
  * Canonical chat-model resolution — identical across every agent app.
3
102
  *
@@ -85,4 +184,4 @@ declare function isWellFormedModelId(modelId: string): boolean;
85
184
  /** Resolve unique catalog IDs associated with a given model including its canonical form if applicable */
86
185
  declare function catalogIdsForModel(model: ModelInfo): string[];
87
186
 
88
- export { type ChatModelSource, type ChatModelValidationFailure, type ChatModelValidationResult, type ChatModelValidationSuccess, type LoadModels, type ModelInfo, type ResolveChatModelInput, type ResolvedChatModel, type ValidateChatModelIdInput, catalogIdsForModel, cleanModelId, isWellFormedModelId, resolveChatModel, validateChatModelId };
187
+ export { type ChatModelSource, type ChatModelValidationFailure, type ChatModelValidationResult, type ChatModelValidationSuccess, type LoadModels, type ModelFailoverAttempt, ModelFailoverExhaustedError, type ModelFailoverResult, type ModelInfo, type ResolveChatModelInput, type ResolvedChatModel, type RunWithModelFailoverInput, UPSTREAM_UNAVAILABLE_CODES, UPSTREAM_UNAVAILABLE_STATUSES, type ValidateChatModelIdInput, buildModelChain, catalogIdsForModel, cleanModelId, isUpstreamUnavailable, isWellFormedModelId, resolveChatModel, runWithModelFailover, validateChatModelId };