@tangle-network/agent-runtime 0.131.3 → 0.131.5

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 (45) hide show
  1. package/dist/{activation-CrVCSWLi.js → activation-D-gsrgSq.js} +2 -2
  2. package/dist/{activation-CrVCSWLi.js.map → activation-D-gsrgSq.js.map} +1 -1
  3. package/dist/agent.js +2 -2
  4. package/dist/{authoring-tkyJHE0o.js → authoring-DI778qK7.js} +2 -2
  5. package/dist/{authoring-tkyJHE0o.js.map → authoring-DI778qK7.js.map} +1 -1
  6. package/dist/{conversation-DNtxaJ1Z.js → conversation-9ZmilKp8.js} +3 -3
  7. package/dist/{conversation-DNtxaJ1Z.js.map → conversation-9ZmilKp8.js.map} +1 -1
  8. package/dist/conversation.js +1 -1
  9. package/dist/{graph-RVorX4TM.js → graph-CoN60QtH.js} +2 -2
  10. package/dist/{graph-RVorX4TM.js.map → graph-CoN60QtH.js.map} +1 -1
  11. package/dist/{improvement-cycle-CSprJl2t.js → improvement-cycle-BGF0osPC.js} +5 -5
  12. package/dist/{improvement-cycle-CSprJl2t.js.map → improvement-cycle-BGF0osPC.js.map} +1 -1
  13. package/dist/index.js +9 -9
  14. package/dist/intelligence.js +3 -3
  15. package/dist/kernel.js +8 -8
  16. package/dist/{knowledge-DqcVhYYF.js → knowledge-D4zNvxw5.js} +5 -5
  17. package/dist/{knowledge-DqcVhYYF.js.map → knowledge-D4zNvxw5.js.map} +1 -1
  18. package/dist/knowledge.js +1 -1
  19. package/dist/{loop-runner-bin-BXdUq87C.js → loop-runner-bin-CI9Y0sxT.js} +3 -3
  20. package/dist/{loop-runner-bin-BXdUq87C.js.map → loop-runner-bin-CI9Y0sxT.js.map} +1 -1
  21. package/dist/loop-runner-bin.js +1 -1
  22. package/dist/{materialization-COJ1UYQ-.js → materialization-DBXuH34A.js} +2 -2
  23. package/dist/{materialization-COJ1UYQ-.js.map → materialization-DBXuH34A.js.map} +1 -1
  24. package/dist/mcp/bin.js +3 -3
  25. package/dist/mcp/index.js +5 -5
  26. package/dist/{model-policy-CqziaqS1.js → model-policy-mWSoToiQ.js} +3 -2
  27. package/dist/model-policy-mWSoToiQ.js.map +1 -0
  28. package/dist/{openai-tools-CPhN7uKC.js → openai-tools-CupeHJEv.js} +2 -2
  29. package/dist/{openai-tools-CPhN7uKC.js.map → openai-tools-CupeHJEv.js.map} +1 -1
  30. package/dist/profiles.js +1 -1
  31. package/dist/{researcher-Skz5-Uc8.js → researcher-CYmr4VJy.js} +2 -2
  32. package/dist/{researcher-Skz5-Uc8.js.map → researcher-CYmr4VJy.js.map} +1 -1
  33. package/dist/{runtime-B4z0Z1sM.js → runtime-ZNVnT8h1.js} +9 -9
  34. package/dist/{runtime-B4z0Z1sM.js.map → runtime-ZNVnT8h1.js.map} +1 -1
  35. package/dist/{stream-agent-turn-rYgaOLO0.js → stream-agent-turn-DE8_alvm.js} +3 -3
  36. package/dist/{stream-agent-turn-rYgaOLO0.js.map → stream-agent-turn-DE8_alvm.js.map} +1 -1
  37. package/dist/{structural-rollout-UO3ue9OI.js → structural-rollout-n089ZP33.js} +5 -5
  38. package/dist/{structural-rollout-UO3ue9OI.js.map → structural-rollout-n089ZP33.js.map} +1 -1
  39. package/dist/{supervise-BVNSL3N0.js → supervise-msTRhTN7.js} +4 -4
  40. package/dist/{supervise-BVNSL3N0.js.map → supervise-msTRhTN7.js.map} +1 -1
  41. package/dist/{supervisor-D4G47raS.js → supervisor-C16p9KqO.js} +10 -4
  42. package/dist/{supervisor-D4G47raS.js.map → supervisor-C16p9KqO.js.map} +1 -1
  43. package/dist/testing.js +11 -11
  44. package/package.json +1 -1
  45. package/dist/model-policy-CqziaqS1.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"materialization-COJ1UYQ-.js","names":[],"sources":["../src/runtime/supervise/executable-spec.ts","../src/runtime/supervise/materialization.ts"],"sourcesContent":["import { type AgentProfile, agentProfileSchema } from '@tangle-network/agent-interface'\nimport { assertExecutableAgentProfile } from './model-policy'\nimport { detachedSnapshot } from './snapshot'\nimport type { AgentSpec } from './types'\n\n/**\n * Parse one untrusted profile into the exact immutable value execution may consume.\n *\n * Snapshotting before schema parsing reads caller-owned fields once. Snapshotting the parsed\n * result prevents downstream custom code from changing any identity or authority field.\n */\nexport function executableAgentProfileSnapshot(raw: unknown, context: string): AgentProfile {\n const input = detachedSnapshot(raw, `${context}: AgentProfile input`)\n const profile = agentProfileSchema.parse(input)\n assertExecutableAgentProfile(profile, context)\n return detachedSnapshot(profile, `${context}: parsed AgentProfile`)\n}\n\n/** Snapshot an executable spec while retaining trusted callbacks by reference. */\nexport function executableAgentSpecSnapshot(raw: AgentSpec, context: string): AgentSpec {\n const {\n profile: rawProfile,\n harness,\n execution: rawExecution,\n ...runtimeExtensions\n } = raw as AgentSpec & Readonly<Record<string, unknown>>\n const profile = executableAgentProfileSnapshot(rawProfile, context)\n const execution =\n rawExecution === undefined\n ? undefined\n : detachedSnapshot(rawExecution, `${context}: execution attribution`)\n return Object.freeze({\n ...runtimeExtensions,\n profile,\n harness,\n ...(execution === undefined ? {} : { execution }),\n }) as AgentSpec\n}\n","import { randomUUID } from 'node:crypto'\nimport {\n agentProfileSchema,\n canonicalAgentProfileDigest,\n canonicalCandidateDigest,\n type Sha256Digest,\n} from '@tangle-network/agent-interface'\nimport { ValidationError } from '../../errors'\nimport { detachedSnapshot } from './snapshot'\nimport type {\n ExecutionBindingReceipt,\n Executor,\n ExecutorExecutionBinding,\n ExecutorMaterialization,\n ProfileMaterializationReceipt,\n Runtime,\n UnknownMaterializationReason,\n} from './types'\n\ntype RuntimeOwnedExecutorMaterialization =\n | {\n readonly kind: 'known'\n readonly declaration: ExecutorMaterialization\n readonly binding?: ExecutorExecutionBinding\n }\n | {\n /** A Runtime-owned external executor whose exact launch is known, but whose remote\n * materializer has not yet returned its terminal acknowledgement. This private state lets\n * Runtime validate the planned authority before execution without presenting it as proof\n * that the remote process actually used that plan. */\n readonly kind: 'pending'\n readonly runtime: Runtime\n readonly declaration: ExecutorMaterialization\n readonly binding: ExecutorExecutionBinding\n }\n | { readonly kind: 'deferred'; readonly runtime: Runtime }\n\ninterface RuntimeOwnedExecutorMaterializationRef {\n current: RuntimeOwnedExecutorMaterialization\n}\n\nconst runtimeOwnedExecutorMaterializations = new WeakMap<\n object,\n RuntimeOwnedExecutorMaterializationRef\n>()\nconst runtimeOwnedScopeOwners = new WeakMap<object, Runtime>()\n\ninterface KnownReceiptInput {\n readonly authoredProfileDigest: Sha256Digest\n readonly runtime: Runtime\n readonly declaration: ExecutorMaterialization\n}\n\ninterface UnknownReceiptInput {\n readonly authoredProfileDigest?: Sha256Digest\n readonly runtime: Runtime\n readonly reason: UnknownMaterializationReason\n}\n\nconst declarationKeys = new Set([\n 'effectiveProfile',\n 'backend',\n 'model',\n 'execution',\n 'materializer',\n 'plan',\n 'platformAttachments',\n])\n\n/**\n * Bind a declaration to a runtime-owned executor without putting an attestable method on the\n * public Executor interface. This module is not a package export: arbitrary caller executors stay\n * unknown even if they add a lookalike `materialization()` property.\n */\nexport function attestRuntimeOwnedExecutor<Out>(\n executor: Executor<Out>,\n declaration: ExecutorMaterialization,\n binding?: ExecutorExecutionBinding,\n): Executor<Out> {\n runtimeOwnedExecutorMaterializations.set(executor as object, {\n current: Object.freeze({\n kind: 'known',\n declaration: detachedSnapshot(declaration, 'runtime-owned executor materialization'),\n ...(binding === undefined\n ? {}\n : {\n binding: detachedSnapshot(binding, 'runtime-owned executor execution binding'),\n }),\n }),\n })\n return executor\n}\n\n/** Brand an external Runtime executor whose exact remote materialization is provable only after\n * its terminal protocol acknowledgement. The declaration is a planned authority check, never a\n * known receipt; callers must finalize this same object after validating the acknowledgement. */\nexport function attestRuntimeOwnedPendingExecutor<Out>(\n executor: Executor<Out>,\n runtime: Runtime,\n declaration: ExecutorMaterialization,\n binding: ExecutorExecutionBinding,\n): Executor<Out> {\n runtimeOwnedExecutorMaterializations.set(executor as object, {\n current: Object.freeze({\n kind: 'pending',\n runtime,\n declaration: detachedSnapshot(declaration, 'pending executor materialization'),\n binding: detachedSnapshot(binding, 'pending executor execution binding'),\n }),\n })\n return executor\n}\n\n/** Replace a private pending brand with terminally acknowledged evidence. A caller-owned executor\n * cannot enter this path because only this module can create the pending WeakMap entry. */\nexport function finalizeRuntimeOwnedPendingExecutor<Out>(\n executor: Executor<Out>,\n declaration: ExecutorMaterialization,\n binding: ExecutorExecutionBinding,\n): Executor<Out> {\n const ref = runtimeOwnedExecutorMaterializations.get(executor as object)\n if (ref?.current.kind !== 'pending' || ref.current.runtime !== executor.runtime) {\n throw new ValidationError(\n 'executor materialization: terminal acknowledgement has no matching Runtime-owned pending executor',\n )\n }\n ref.current = Object.freeze({\n kind: 'known',\n declaration: detachedSnapshot(declaration, 'runtime-owned executor materialization'),\n binding: detachedSnapshot(binding, 'runtime-owned executor execution binding'),\n })\n return executor\n}\n\n/** Mark a runtime-owned orchestration executor whose exact leaf declaration is published through\n * its private nested Scope before the first backend inference. Arbitrary executors cannot opt in. */\nexport function attestRuntimeOwnedDeferredExecutor<Out>(\n executor: Executor<Out>,\n runtime: Runtime,\n): Executor<Out> {\n runtimeOwnedExecutorMaterializations.set(executor as object, {\n current: Object.freeze({ kind: 'deferred', runtime }),\n })\n return executor\n}\n\n/** Preserve the runtime-owned attestation when a trusted wrapper changes result semantics only. */\nexport function inheritRuntimeOwnedExecutorAttestation<In, Out>(\n source: Executor<In>,\n wrapper: Executor<Out>,\n): Executor<Out> {\n const ref = runtimeOwnedExecutorMaterializations.get(source as object)\n if (ref !== undefined) {\n runtimeOwnedExecutorMaterializations.set(wrapper as object, ref)\n }\n return wrapper\n}\n\n/** Read a declaration only when Runtime itself branded this exact executor object. */\nexport function runtimeOwnedExecutorMaterialization<Out>(\n executor: Executor<Out>,\n): ExecutorMaterialization | undefined {\n const attestation = runtimeOwnedExecutorMaterializations.get(executor as object)?.current\n return attestation?.kind === 'known' ? attestation.declaration : undefined\n}\n\n/** Read one attempt binding only from the private brand on this exact executor object. */\nexport function runtimeOwnedExecutorExecutionBinding<Out>(\n executor: Executor<Out>,\n): ExecutorExecutionBinding | undefined {\n const attestation = runtimeOwnedExecutorMaterializations.get(executor as object)?.current\n return attestation?.kind === 'known' ? attestation.binding : undefined\n}\n\n/** Read a planned external declaration only for Runtime's private pending brand. This is useful for\n * pre-execution authority checks, but must never be turned into a known durable receipt. */\nexport function runtimeOwnedPendingExecutorMaterialization<Out>(executor: Executor<Out>):\n | {\n readonly runtime: Runtime\n readonly declaration: ExecutorMaterialization\n readonly binding: ExecutorExecutionBinding\n }\n | undefined {\n const attestation = runtimeOwnedExecutorMaterializations.get(executor as object)?.current\n return attestation?.kind === 'pending'\n ? {\n runtime: attestation.runtime,\n declaration: attestation.declaration,\n binding: attestation.binding,\n }\n : undefined\n}\n\n/** Read the expected leaf runtime only for a privately branded deferred orchestration executor. */\nexport function runtimeOwnedDeferredExecutorRuntime<Out>(\n executor: Executor<Out>,\n): Runtime | undefined {\n const attestation = runtimeOwnedExecutorMaterializations.get(executor as object)?.current\n return attestation?.kind === 'deferred' ? attestation.runtime : undefined\n}\n\n/** Propagate trust from a built-in driver adapter to the Agent and recursive executor it owns. */\nexport function attestRuntimeOwnedScopeOwner<T extends object>(owner: T, runtime: Runtime): T {\n runtimeOwnedScopeOwners.set(owner, runtime)\n return owner\n}\n\n/** Return a built-in scope owner's expected concrete leaf runtime; caller-owned functions/Agents\n * deliberately have no entry even if they add lookalike fields. */\nexport function runtimeOwnedScopeOwnerRuntime(owner: object): Runtime | undefined {\n return runtimeOwnedScopeOwners.get(owner)\n}\n\n/** Build one kernel-owned known receipt from a data-only executor declaration. */\nexport function knownMaterializationReceipt(\n input: KnownReceiptInput,\n): ProfileMaterializationReceipt {\n const declaration = detachedSnapshot(input.declaration, 'executor materialization')\n assertExactDeclaration(declaration)\n const effectiveProfile = agentProfileSchema.safeParse(declaration.effectiveProfile)\n if (!effectiveProfile.success) {\n throw new ValidationError('executor materialization: effectiveProfile must be an AgentProfile')\n }\n assertNonEmpty(declaration.backend, 'backend')\n assertNonEmpty(declaration.materializer, 'materializer')\n assertNonEmpty(declaration.execution?.kind, 'execution.kind')\n assertNonEmpty(declaration.execution?.id, 'execution.id')\n assertModel(declaration.model)\n\n let effectiveProfileDigest: Sha256Digest\n let materializationPlanDigest: Sha256Digest\n let platformAttachmentsDigest: Sha256Digest | undefined\n try {\n effectiveProfileDigest = canonicalAgentProfileDigest(effectiveProfile.data)\n materializationPlanDigest = canonicalCandidateDigest(jsonWireSnapshot(declaration.plan))\n platformAttachmentsDigest =\n declaration.platformAttachments === undefined\n ? undefined\n : canonicalCandidateDigest(jsonWireSnapshot(declaration.platformAttachments))\n } catch (error) {\n throw new ValidationError(\n 'executor materialization: profile, plan, and attachments must be finite RFC 8785 JSON',\n { cause: error },\n )\n }\n\n return Object.freeze({\n status: 'known' as const,\n authoredProfileDigest: input.authoredProfileDigest,\n effectiveProfileDigest,\n materializationPlanDigest,\n ...(platformAttachmentsDigest === undefined ? {} : { platformAttachmentsDigest }),\n runtime: input.runtime,\n backend: declaration.backend,\n model: declaration.model,\n execution: declaration.execution,\n materializer: declaration.materializer,\n })\n}\n\n/** Build an explicit unknown receipt without fabricating any executor-owned identity. */\nexport function unknownMaterializationReceipt(\n input: UnknownReceiptInput,\n): ProfileMaterializationReceipt {\n return Object.freeze({\n status: 'unknown' as const,\n ...(input.authoredProfileDigest === undefined\n ? {}\n : { authoredProfileDigest: input.authoredProfileDigest }),\n runtime: input.runtime,\n reason: input.reason,\n })\n}\n\n/** Mint a process-unique attempt id before executor construction. */\nexport function newExecutionAttemptId(nodeId: string): string {\n return `${nodeId}:attempt:${randomUUID()}`\n}\n\n/** Build the immutable safe receipt for a full, transient execution binding. */\nexport function knownExecutionBindingReceipt(\n materialization: ProfileMaterializationReceipt,\n bindingInput: ExecutorExecutionBinding,\n): ExecutionBindingReceipt {\n const binding = detachedSnapshot(bindingInput, 'executor execution binding')\n assertNonEmpty(binding.attemptId, 'binding.attemptId')\n assertSafeDescriptor(binding.descriptor)\n let materializationReceiptDigest: Sha256Digest\n let bindingDigest: Sha256Digest\n try {\n materializationReceiptDigest = canonicalCandidateDigest(materialization)\n // Bind the exact JSON document a backend receives. Optional AgentProfile fields are represented\n // as `undefined` in memory but omitted by JSON transport; normalize that one distinction while\n // rejecting every non-finite/non-data value instead of silently coercing it.\n bindingDigest = canonicalCandidateDigest(jsonWireSnapshot(binding.binding))\n } catch (error) {\n throw new ValidationError('executor binding must be finite RFC 8785 JSON', { cause: error })\n }\n return Object.freeze({\n status: 'known' as const,\n attemptId: binding.attemptId,\n materializationReceiptDigest,\n bindingDigest,\n descriptor: binding.descriptor,\n })\n}\n\n/** Preserve an attempt boundary even when its caller-owned transport cannot be attested. */\nexport function unknownExecutionBindingReceipt(\n materialization: ProfileMaterializationReceipt,\n attemptId: string,\n reason: UnknownMaterializationReason,\n): ExecutionBindingReceipt {\n assertNonEmpty(attemptId, 'binding.attemptId')\n return Object.freeze({\n status: 'unknown' as const,\n attemptId,\n materializationReceiptDigest: canonicalCandidateDigest(materialization),\n reason,\n })\n}\n\n/** Derive an authored-profile digest without turning non-canonical input into a fake identity. */\nexport function authoredProfileDigest(profile: unknown): Sha256Digest | undefined {\n try {\n return canonicalAgentProfileDigest(agentProfileSchema.parse(profile))\n } catch {\n return undefined\n }\n}\n\nfunction assertExactDeclaration(value: ExecutorMaterialization): void {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new ValidationError('executor materialization: declaration must be an object')\n }\n const unknown = Object.keys(value).filter((key) => !declarationKeys.has(key))\n if (unknown.length > 0) {\n throw new ValidationError(\n `executor materialization: unknown declaration fields: ${unknown.sort().join(', ')}`,\n )\n }\n if (!Object.hasOwn(value, 'plan')) {\n throw new ValidationError('executor materialization: plan is required')\n }\n}\n\nfunction assertModel(model: ExecutorMaterialization['model']): void {\n if (typeof model !== 'object' || model === null || Array.isArray(model)) {\n throw new ValidationError('executor materialization: model must be a known/unknown identity')\n }\n const keys = Object.keys(model).sort()\n if (model.status === 'known') {\n if (keys.join(',') !== 'id,status') {\n throw new ValidationError('executor materialization: known model accepts only status and id')\n }\n assertNonEmpty(model.id, 'model.id')\n return\n }\n if (model.status === 'unknown') {\n if (keys.join(',') !== 'reason,status') {\n throw new ValidationError(\n 'executor materialization: unknown model accepts only status and reason',\n )\n }\n assertNonEmpty(model.reason, 'model.reason')\n return\n }\n throw new ValidationError('executor materialization: model.status must be known or unknown')\n}\n\nfunction assertNonEmpty(value: unknown, field: string): asserts value is string {\n if (typeof value !== 'string' || value.trim().length === 0) {\n throw new ValidationError(`executor materialization: ${field} must be a non-empty string`)\n }\n}\n\nfunction assertSafeDescriptor(descriptor: ExecutorExecutionBinding['descriptor']): void {\n if (typeof descriptor !== 'object' || descriptor === null || Array.isArray(descriptor)) {\n throw new ValidationError('executor binding: descriptor must be an object')\n }\n for (const [key, value] of Object.entries(descriptor)) {\n if (/(url|uri|token|key|secret|bearer|credential|authorization)/i.test(key)) {\n throw new ValidationError(`executor binding: unsafe descriptor key ${JSON.stringify(key)}`)\n }\n if (\n value !== null &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n ) {\n throw new ValidationError(\n `executor binding: descriptor ${JSON.stringify(key)} must be scalar`,\n )\n }\n if (typeof value === 'string' && (value.includes('://') || value.includes('@'))) {\n throw new ValidationError(\n `executor binding: descriptor ${JSON.stringify(key)} contains transport or credential text`,\n )\n }\n }\n}\n\nfunction jsonWireSnapshot(value: unknown, path = '$'): unknown {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return value\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) {\n throw new ValidationError(`executor binding: ${path} must be finite`)\n }\n return value\n }\n if (Array.isArray(value)) {\n return value.map((item, index) => {\n if (item === undefined) {\n throw new ValidationError(`executor binding: ${path}[${index}] cannot be undefined`)\n }\n return jsonWireSnapshot(item, `${path}[${index}]`)\n })\n }\n if (typeof value !== 'object' || value === null) {\n throw new ValidationError(`executor binding: ${path} must be JSON data`)\n }\n const prototype = Object.getPrototypeOf(value)\n if (prototype !== Object.prototype && prototype !== null) {\n throw new ValidationError(`executor binding: ${path} must be a plain object`)\n }\n const out: Record<string, unknown> = {}\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n if (item === undefined) continue\n out[key] = jsonWireSnapshot(item, `${path}.${key}`)\n }\n return out\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"materialization-DBXuH34A.js","names":[],"sources":["../src/runtime/supervise/executable-spec.ts","../src/runtime/supervise/materialization.ts"],"sourcesContent":["import { type AgentProfile, agentProfileSchema } from '@tangle-network/agent-interface'\nimport { assertExecutableAgentProfile } from './model-policy'\nimport { detachedSnapshot } from './snapshot'\nimport type { AgentSpec } from './types'\n\n/**\n * Parse one untrusted profile into the exact immutable value execution may consume.\n *\n * Snapshotting before schema parsing reads caller-owned fields once. Snapshotting the parsed\n * result prevents downstream custom code from changing any identity or authority field.\n */\nexport function executableAgentProfileSnapshot(raw: unknown, context: string): AgentProfile {\n const input = detachedSnapshot(raw, `${context}: AgentProfile input`)\n const profile = agentProfileSchema.parse(input)\n assertExecutableAgentProfile(profile, context)\n return detachedSnapshot(profile, `${context}: parsed AgentProfile`)\n}\n\n/** Snapshot an executable spec while retaining trusted callbacks by reference. */\nexport function executableAgentSpecSnapshot(raw: AgentSpec, context: string): AgentSpec {\n const {\n profile: rawProfile,\n harness,\n execution: rawExecution,\n ...runtimeExtensions\n } = raw as AgentSpec & Readonly<Record<string, unknown>>\n const profile = executableAgentProfileSnapshot(rawProfile, context)\n const execution =\n rawExecution === undefined\n ? undefined\n : detachedSnapshot(rawExecution, `${context}: execution attribution`)\n return Object.freeze({\n ...runtimeExtensions,\n profile,\n harness,\n ...(execution === undefined ? {} : { execution }),\n }) as AgentSpec\n}\n","import { randomUUID } from 'node:crypto'\nimport {\n agentProfileSchema,\n canonicalAgentProfileDigest,\n canonicalCandidateDigest,\n type Sha256Digest,\n} from '@tangle-network/agent-interface'\nimport { ValidationError } from '../../errors'\nimport { detachedSnapshot } from './snapshot'\nimport type {\n ExecutionBindingReceipt,\n Executor,\n ExecutorExecutionBinding,\n ExecutorMaterialization,\n ProfileMaterializationReceipt,\n Runtime,\n UnknownMaterializationReason,\n} from './types'\n\ntype RuntimeOwnedExecutorMaterialization =\n | {\n readonly kind: 'known'\n readonly declaration: ExecutorMaterialization\n readonly binding?: ExecutorExecutionBinding\n }\n | {\n /** A Runtime-owned external executor whose exact launch is known, but whose remote\n * materializer has not yet returned its terminal acknowledgement. This private state lets\n * Runtime validate the planned authority before execution without presenting it as proof\n * that the remote process actually used that plan. */\n readonly kind: 'pending'\n readonly runtime: Runtime\n readonly declaration: ExecutorMaterialization\n readonly binding: ExecutorExecutionBinding\n }\n | { readonly kind: 'deferred'; readonly runtime: Runtime }\n\ninterface RuntimeOwnedExecutorMaterializationRef {\n current: RuntimeOwnedExecutorMaterialization\n}\n\nconst runtimeOwnedExecutorMaterializations = new WeakMap<\n object,\n RuntimeOwnedExecutorMaterializationRef\n>()\nconst runtimeOwnedScopeOwners = new WeakMap<object, Runtime>()\n\ninterface KnownReceiptInput {\n readonly authoredProfileDigest: Sha256Digest\n readonly runtime: Runtime\n readonly declaration: ExecutorMaterialization\n}\n\ninterface UnknownReceiptInput {\n readonly authoredProfileDigest?: Sha256Digest\n readonly runtime: Runtime\n readonly reason: UnknownMaterializationReason\n}\n\nconst declarationKeys = new Set([\n 'effectiveProfile',\n 'backend',\n 'model',\n 'execution',\n 'materializer',\n 'plan',\n 'platformAttachments',\n])\n\n/**\n * Bind a declaration to a runtime-owned executor without putting an attestable method on the\n * public Executor interface. This module is not a package export: arbitrary caller executors stay\n * unknown even if they add a lookalike `materialization()` property.\n */\nexport function attestRuntimeOwnedExecutor<Out>(\n executor: Executor<Out>,\n declaration: ExecutorMaterialization,\n binding?: ExecutorExecutionBinding,\n): Executor<Out> {\n runtimeOwnedExecutorMaterializations.set(executor as object, {\n current: Object.freeze({\n kind: 'known',\n declaration: detachedSnapshot(declaration, 'runtime-owned executor materialization'),\n ...(binding === undefined\n ? {}\n : {\n binding: detachedSnapshot(binding, 'runtime-owned executor execution binding'),\n }),\n }),\n })\n return executor\n}\n\n/** Brand an external Runtime executor whose exact remote materialization is provable only after\n * its terminal protocol acknowledgement. The declaration is a planned authority check, never a\n * known receipt; callers must finalize this same object after validating the acknowledgement. */\nexport function attestRuntimeOwnedPendingExecutor<Out>(\n executor: Executor<Out>,\n runtime: Runtime,\n declaration: ExecutorMaterialization,\n binding: ExecutorExecutionBinding,\n): Executor<Out> {\n runtimeOwnedExecutorMaterializations.set(executor as object, {\n current: Object.freeze({\n kind: 'pending',\n runtime,\n declaration: detachedSnapshot(declaration, 'pending executor materialization'),\n binding: detachedSnapshot(binding, 'pending executor execution binding'),\n }),\n })\n return executor\n}\n\n/** Replace a private pending brand with terminally acknowledged evidence. A caller-owned executor\n * cannot enter this path because only this module can create the pending WeakMap entry. */\nexport function finalizeRuntimeOwnedPendingExecutor<Out>(\n executor: Executor<Out>,\n declaration: ExecutorMaterialization,\n binding: ExecutorExecutionBinding,\n): Executor<Out> {\n const ref = runtimeOwnedExecutorMaterializations.get(executor as object)\n if (ref?.current.kind !== 'pending' || ref.current.runtime !== executor.runtime) {\n throw new ValidationError(\n 'executor materialization: terminal acknowledgement has no matching Runtime-owned pending executor',\n )\n }\n ref.current = Object.freeze({\n kind: 'known',\n declaration: detachedSnapshot(declaration, 'runtime-owned executor materialization'),\n binding: detachedSnapshot(binding, 'runtime-owned executor execution binding'),\n })\n return executor\n}\n\n/** Mark a runtime-owned orchestration executor whose exact leaf declaration is published through\n * its private nested Scope before the first backend inference. Arbitrary executors cannot opt in. */\nexport function attestRuntimeOwnedDeferredExecutor<Out>(\n executor: Executor<Out>,\n runtime: Runtime,\n): Executor<Out> {\n runtimeOwnedExecutorMaterializations.set(executor as object, {\n current: Object.freeze({ kind: 'deferred', runtime }),\n })\n return executor\n}\n\n/** Preserve the runtime-owned attestation when a trusted wrapper changes result semantics only. */\nexport function inheritRuntimeOwnedExecutorAttestation<In, Out>(\n source: Executor<In>,\n wrapper: Executor<Out>,\n): Executor<Out> {\n const ref = runtimeOwnedExecutorMaterializations.get(source as object)\n if (ref !== undefined) {\n runtimeOwnedExecutorMaterializations.set(wrapper as object, ref)\n }\n return wrapper\n}\n\n/** Read a declaration only when Runtime itself branded this exact executor object. */\nexport function runtimeOwnedExecutorMaterialization<Out>(\n executor: Executor<Out>,\n): ExecutorMaterialization | undefined {\n const attestation = runtimeOwnedExecutorMaterializations.get(executor as object)?.current\n return attestation?.kind === 'known' ? attestation.declaration : undefined\n}\n\n/** Read one attempt binding only from the private brand on this exact executor object. */\nexport function runtimeOwnedExecutorExecutionBinding<Out>(\n executor: Executor<Out>,\n): ExecutorExecutionBinding | undefined {\n const attestation = runtimeOwnedExecutorMaterializations.get(executor as object)?.current\n return attestation?.kind === 'known' ? attestation.binding : undefined\n}\n\n/** Read a planned external declaration only for Runtime's private pending brand. This is useful for\n * pre-execution authority checks, but must never be turned into a known durable receipt. */\nexport function runtimeOwnedPendingExecutorMaterialization<Out>(executor: Executor<Out>):\n | {\n readonly runtime: Runtime\n readonly declaration: ExecutorMaterialization\n readonly binding: ExecutorExecutionBinding\n }\n | undefined {\n const attestation = runtimeOwnedExecutorMaterializations.get(executor as object)?.current\n return attestation?.kind === 'pending'\n ? {\n runtime: attestation.runtime,\n declaration: attestation.declaration,\n binding: attestation.binding,\n }\n : undefined\n}\n\n/** Read the expected leaf runtime only for a privately branded deferred orchestration executor. */\nexport function runtimeOwnedDeferredExecutorRuntime<Out>(\n executor: Executor<Out>,\n): Runtime | undefined {\n const attestation = runtimeOwnedExecutorMaterializations.get(executor as object)?.current\n return attestation?.kind === 'deferred' ? attestation.runtime : undefined\n}\n\n/** Propagate trust from a built-in driver adapter to the Agent and recursive executor it owns. */\nexport function attestRuntimeOwnedScopeOwner<T extends object>(owner: T, runtime: Runtime): T {\n runtimeOwnedScopeOwners.set(owner, runtime)\n return owner\n}\n\n/** Return a built-in scope owner's expected concrete leaf runtime; caller-owned functions/Agents\n * deliberately have no entry even if they add lookalike fields. */\nexport function runtimeOwnedScopeOwnerRuntime(owner: object): Runtime | undefined {\n return runtimeOwnedScopeOwners.get(owner)\n}\n\n/** Build one kernel-owned known receipt from a data-only executor declaration. */\nexport function knownMaterializationReceipt(\n input: KnownReceiptInput,\n): ProfileMaterializationReceipt {\n const declaration = detachedSnapshot(input.declaration, 'executor materialization')\n assertExactDeclaration(declaration)\n const effectiveProfile = agentProfileSchema.safeParse(declaration.effectiveProfile)\n if (!effectiveProfile.success) {\n throw new ValidationError('executor materialization: effectiveProfile must be an AgentProfile')\n }\n assertNonEmpty(declaration.backend, 'backend')\n assertNonEmpty(declaration.materializer, 'materializer')\n assertNonEmpty(declaration.execution?.kind, 'execution.kind')\n assertNonEmpty(declaration.execution?.id, 'execution.id')\n assertModel(declaration.model)\n\n let effectiveProfileDigest: Sha256Digest\n let materializationPlanDigest: Sha256Digest\n let platformAttachmentsDigest: Sha256Digest | undefined\n try {\n effectiveProfileDigest = canonicalAgentProfileDigest(effectiveProfile.data)\n materializationPlanDigest = canonicalCandidateDigest(jsonWireSnapshot(declaration.plan))\n platformAttachmentsDigest =\n declaration.platformAttachments === undefined\n ? undefined\n : canonicalCandidateDigest(jsonWireSnapshot(declaration.platformAttachments))\n } catch (error) {\n throw new ValidationError(\n 'executor materialization: profile, plan, and attachments must be finite RFC 8785 JSON',\n { cause: error },\n )\n }\n\n return Object.freeze({\n status: 'known' as const,\n authoredProfileDigest: input.authoredProfileDigest,\n effectiveProfileDigest,\n materializationPlanDigest,\n ...(platformAttachmentsDigest === undefined ? {} : { platformAttachmentsDigest }),\n runtime: input.runtime,\n backend: declaration.backend,\n model: declaration.model,\n execution: declaration.execution,\n materializer: declaration.materializer,\n })\n}\n\n/** Build an explicit unknown receipt without fabricating any executor-owned identity. */\nexport function unknownMaterializationReceipt(\n input: UnknownReceiptInput,\n): ProfileMaterializationReceipt {\n return Object.freeze({\n status: 'unknown' as const,\n ...(input.authoredProfileDigest === undefined\n ? {}\n : { authoredProfileDigest: input.authoredProfileDigest }),\n runtime: input.runtime,\n reason: input.reason,\n })\n}\n\n/** Mint a process-unique attempt id before executor construction. */\nexport function newExecutionAttemptId(nodeId: string): string {\n return `${nodeId}:attempt:${randomUUID()}`\n}\n\n/** Build the immutable safe receipt for a full, transient execution binding. */\nexport function knownExecutionBindingReceipt(\n materialization: ProfileMaterializationReceipt,\n bindingInput: ExecutorExecutionBinding,\n): ExecutionBindingReceipt {\n const binding = detachedSnapshot(bindingInput, 'executor execution binding')\n assertNonEmpty(binding.attemptId, 'binding.attemptId')\n assertSafeDescriptor(binding.descriptor)\n let materializationReceiptDigest: Sha256Digest\n let bindingDigest: Sha256Digest\n try {\n materializationReceiptDigest = canonicalCandidateDigest(materialization)\n // Bind the exact JSON document a backend receives. Optional AgentProfile fields are represented\n // as `undefined` in memory but omitted by JSON transport; normalize that one distinction while\n // rejecting every non-finite/non-data value instead of silently coercing it.\n bindingDigest = canonicalCandidateDigest(jsonWireSnapshot(binding.binding))\n } catch (error) {\n throw new ValidationError('executor binding must be finite RFC 8785 JSON', { cause: error })\n }\n return Object.freeze({\n status: 'known' as const,\n attemptId: binding.attemptId,\n materializationReceiptDigest,\n bindingDigest,\n descriptor: binding.descriptor,\n })\n}\n\n/** Preserve an attempt boundary even when its caller-owned transport cannot be attested. */\nexport function unknownExecutionBindingReceipt(\n materialization: ProfileMaterializationReceipt,\n attemptId: string,\n reason: UnknownMaterializationReason,\n): ExecutionBindingReceipt {\n assertNonEmpty(attemptId, 'binding.attemptId')\n return Object.freeze({\n status: 'unknown' as const,\n attemptId,\n materializationReceiptDigest: canonicalCandidateDigest(materialization),\n reason,\n })\n}\n\n/** Derive an authored-profile digest without turning non-canonical input into a fake identity. */\nexport function authoredProfileDigest(profile: unknown): Sha256Digest | undefined {\n try {\n return canonicalAgentProfileDigest(agentProfileSchema.parse(profile))\n } catch {\n return undefined\n }\n}\n\nfunction assertExactDeclaration(value: ExecutorMaterialization): void {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new ValidationError('executor materialization: declaration must be an object')\n }\n const unknown = Object.keys(value).filter((key) => !declarationKeys.has(key))\n if (unknown.length > 0) {\n throw new ValidationError(\n `executor materialization: unknown declaration fields: ${unknown.sort().join(', ')}`,\n )\n }\n if (!Object.hasOwn(value, 'plan')) {\n throw new ValidationError('executor materialization: plan is required')\n }\n}\n\nfunction assertModel(model: ExecutorMaterialization['model']): void {\n if (typeof model !== 'object' || model === null || Array.isArray(model)) {\n throw new ValidationError('executor materialization: model must be a known/unknown identity')\n }\n const keys = Object.keys(model).sort()\n if (model.status === 'known') {\n if (keys.join(',') !== 'id,status') {\n throw new ValidationError('executor materialization: known model accepts only status and id')\n }\n assertNonEmpty(model.id, 'model.id')\n return\n }\n if (model.status === 'unknown') {\n if (keys.join(',') !== 'reason,status') {\n throw new ValidationError(\n 'executor materialization: unknown model accepts only status and reason',\n )\n }\n assertNonEmpty(model.reason, 'model.reason')\n return\n }\n throw new ValidationError('executor materialization: model.status must be known or unknown')\n}\n\nfunction assertNonEmpty(value: unknown, field: string): asserts value is string {\n if (typeof value !== 'string' || value.trim().length === 0) {\n throw new ValidationError(`executor materialization: ${field} must be a non-empty string`)\n }\n}\n\nfunction assertSafeDescriptor(descriptor: ExecutorExecutionBinding['descriptor']): void {\n if (typeof descriptor !== 'object' || descriptor === null || Array.isArray(descriptor)) {\n throw new ValidationError('executor binding: descriptor must be an object')\n }\n for (const [key, value] of Object.entries(descriptor)) {\n if (/(url|uri|token|key|secret|bearer|credential|authorization)/i.test(key)) {\n throw new ValidationError(`executor binding: unsafe descriptor key ${JSON.stringify(key)}`)\n }\n if (\n value !== null &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n ) {\n throw new ValidationError(\n `executor binding: descriptor ${JSON.stringify(key)} must be scalar`,\n )\n }\n if (typeof value === 'string' && (value.includes('://') || value.includes('@'))) {\n throw new ValidationError(\n `executor binding: descriptor ${JSON.stringify(key)} contains transport or credential text`,\n )\n }\n }\n}\n\nfunction jsonWireSnapshot(value: unknown, path = '$'): unknown {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return value\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) {\n throw new ValidationError(`executor binding: ${path} must be finite`)\n }\n return value\n }\n if (Array.isArray(value)) {\n return value.map((item, index) => {\n if (item === undefined) {\n throw new ValidationError(`executor binding: ${path}[${index}] cannot be undefined`)\n }\n return jsonWireSnapshot(item, `${path}[${index}]`)\n })\n }\n if (typeof value !== 'object' || value === null) {\n throw new ValidationError(`executor binding: ${path} must be JSON data`)\n }\n const prototype = Object.getPrototypeOf(value)\n if (prototype !== Object.prototype && prototype !== null) {\n throw new ValidationError(`executor binding: ${path} must be a plain object`)\n }\n const out: Record<string, unknown> = {}\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n if (item === undefined) continue\n out[key] = jsonWireSnapshot(item, `${path}.${key}`)\n }\n return out\n}\n"],"mappings":"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"}
package/dist/mcp/bin.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { i as ConfigError } from "../errors-DEAvWQPy.js";
3
- import { ot as readTraceContextFromEnv } from "../supervisor-D4G47raS.js";
4
- import { C as createMcpServer, Z as DelegationTaskQueue, st as FileDelegationStore } from "../supervise-BVNSL3N0.js";
5
- import { a as supervisorInstructions } from "../authoring-tkyJHE0o.js";
3
+ import { ot as readTraceContextFromEnv } from "../supervisor-C16p9KqO.js";
4
+ import { C as createMcpServer, Z as DelegationTaskQueue, st as FileDelegationStore } from "../supervise-msTRhTN7.js";
5
+ import { a as supervisorInstructions } from "../authoring-DI778qK7.js";
6
6
  //#region src/mcp/delegate-supervisor-provisioning.ts
7
7
  function trimmed(value) {
8
8
  const v = value?.trim();
package/dist/mcp/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { i as ConfigError, u as ValidationError } from "../errors-DEAvWQPy.js";
2
2
  import { l as throwAbort, n as deleteBoxSafe, s as sleep, u as throwIfAborted } from "../util-Bw6srryQ.js";
3
- import { t as assertExecutableAgentProfile } from "../model-policy-CqziaqS1.js";
4
- import { At as removeWorktree, Dt as runWorktreeHarness, Ft as parseCodexTokenUsage, It as CodexExecutionDiagnosticError, Mt as LOCAL_HARNESSES, Nt as harnessSupportsReasoningEffort, Ot as captureWorktreeDiff, Pt as localHarnessExecutable, Q as runAgentRounds, X as createSandboxForSpec, at as mergeTraceEnv, it as createPropagatingTraceEmitter, jt as DEFAULT_LOCAL_HARNESS, kt as createWorktree, ot as readTraceContextFromEnv, st as traceContextToEnv } from "../supervisor-D4G47raS.js";
5
- import { S as runCoderChecks, et as selectValidWinner } from "../runtime-B4z0Z1sM.js";
6
- import { $ as DELEGATION_TRACE_MAX_BYTES, A as DELEGATION_HISTORY_INPUT_SCHEMA, B as DELEGATE_FEEDBACK_INPUT_SCHEMA, C as createMcpServer, D as createDelegationStatusHandler, Dt as createCoordinationTools, E as DELEGATION_STATUS_TOOL_NAME, F as DELEGATE_UI_AUDIT_INPUT_SCHEMA, G as DELEGATE_INPUT_SCHEMA, H as createDelegateFeedbackHandler, I as DELEGATE_UI_AUDIT_TOOL_NAME, J as validateDelegateArgs, K as DELEGATE_TOOL_NAME, L as createDelegateUiAuditHandler, M as createDelegationHistoryHandler, N as validateDelegationHistoryArgs, O as validateDelegationStatusArgs, P as DELEGATE_UI_AUDIT_DESCRIPTION, Q as hashIdempotencyInput, R as validateDelegateUiAuditArgs, S as createInProcessTransport, T as DELEGATION_STATUS_INPUT_SCHEMA, Tt as DEFAULT_AWAIT_EVENT_TIMEOUT_MS, U as validateDelegateFeedbackArgs, V as DELEGATE_FEEDBACK_TOOL_NAME, W as DELEGATE_DESCRIPTION, Z as DelegationTaskQueue, at as DelegationPersistenceError, ct as InMemoryDelegationStore, et as DELEGATION_TRACE_MAX_SPANS, it as createDelegationTraceCollector, j as DELEGATION_HISTORY_TOOL_NAME, k as DELEGATION_HISTORY_DESCRIPTION, lt as InMemoryFeedbackStore, nt as capDelegationTrace, ot as DelegationStateCorruptError, q as createDelegateHandler, rt as composeLoopTraceEmitters, st as FileDelegationStore, tt as buildDelegationTraceSpans, ut as eventToSnapshot, w as DELEGATION_STATUS_DESCRIPTION, z as DELEGATE_FEEDBACK_DESCRIPTION } from "../supervise-BVNSL3N0.js";
3
+ import { t as assertExecutableAgentProfile } from "../model-policy-mWSoToiQ.js";
4
+ import { At as removeWorktree, Dt as runWorktreeHarness, Ft as parseCodexTokenUsage, It as CodexExecutionDiagnosticError, Mt as LOCAL_HARNESSES, Nt as harnessSupportsReasoningEffort, Ot as captureWorktreeDiff, Pt as localHarnessExecutable, Q as runAgentRounds, X as createSandboxForSpec, at as mergeTraceEnv, it as createPropagatingTraceEmitter, jt as DEFAULT_LOCAL_HARNESS, kt as createWorktree, ot as readTraceContextFromEnv, st as traceContextToEnv } from "../supervisor-C16p9KqO.js";
5
+ import { S as runCoderChecks, et as selectValidWinner } from "../runtime-ZNVnT8h1.js";
6
+ import { $ as DELEGATION_TRACE_MAX_BYTES, A as DELEGATION_HISTORY_INPUT_SCHEMA, B as DELEGATE_FEEDBACK_INPUT_SCHEMA, C as createMcpServer, D as createDelegationStatusHandler, Dt as createCoordinationTools, E as DELEGATION_STATUS_TOOL_NAME, F as DELEGATE_UI_AUDIT_INPUT_SCHEMA, G as DELEGATE_INPUT_SCHEMA, H as createDelegateFeedbackHandler, I as DELEGATE_UI_AUDIT_TOOL_NAME, J as validateDelegateArgs, K as DELEGATE_TOOL_NAME, L as createDelegateUiAuditHandler, M as createDelegationHistoryHandler, N as validateDelegationHistoryArgs, O as validateDelegationStatusArgs, P as DELEGATE_UI_AUDIT_DESCRIPTION, Q as hashIdempotencyInput, R as validateDelegateUiAuditArgs, S as createInProcessTransport, T as DELEGATION_STATUS_INPUT_SCHEMA, Tt as DEFAULT_AWAIT_EVENT_TIMEOUT_MS, U as validateDelegateFeedbackArgs, V as DELEGATE_FEEDBACK_TOOL_NAME, W as DELEGATE_DESCRIPTION, Z as DelegationTaskQueue, at as DelegationPersistenceError, ct as InMemoryDelegationStore, et as DELEGATION_TRACE_MAX_SPANS, it as createDelegationTraceCollector, j as DELEGATION_HISTORY_TOOL_NAME, k as DELEGATION_HISTORY_DESCRIPTION, lt as InMemoryFeedbackStore, nt as capDelegationTrace, ot as DelegationStateCorruptError, q as createDelegateHandler, rt as composeLoopTraceEmitters, st as FileDelegationStore, tt as buildDelegationTraceSpans, ut as eventToSnapshot, w as DELEGATION_STATUS_DESCRIPTION, z as DELEGATE_FEEDBACK_DESCRIPTION } from "../supervise-msTRhTN7.js";
7
7
  import { t as createStdioToolServer } from "../tool-server-Gs3VvfSK.js";
8
8
  import { t as createKbGate } from "../kb-gate-DpaSwXVx.js";
9
- import { n as mcpToolsForRuntimeMcpSubset, t as mcpToolsForRuntimeMcp } from "../openai-tools-CPhN7uKC.js";
9
+ import { n as mcpToolsForRuntimeMcpSubset, t as mcpToolsForRuntimeMcp } from "../openai-tools-CupeHJEv.js";
10
10
  import { t as coderTaskToPrompt } from "../coder-yhVWbdWc.js";
11
11
  import { a as createMemoryToolServer, c as resolveMemoryFromEnv, i as MEMORY_NAME_ENV, n as MEMORY_ITEMS_ENV, o as parseMemoryItems, r as MEMORY_LOG_ENV, s as readMemoryItemsFile, t as MEMORY_FILE_ENV } from "../memory-server-eD2baiRO.js";
12
12
  import { agentProfileSchema } from "@tangle-network/agent-interface";
@@ -126,8 +126,9 @@ function profileProviderModel(profile) {
126
126
  function profileBridgeWireModel(profile) {
127
127
  const model = concreteProfileModel(profile);
128
128
  const provider = profile.model?.provider;
129
- const providerModel = model ? provider && !model.includes("/") ? `${provider}/${model}` : model : void 0;
130
129
  const harness = agentHarness(profile.harness);
130
+ const modelWithoutHarness = model && harness && model.startsWith(`${harness}/`) ? model.slice(harness.length + 1) : model;
131
+ const providerModel = modelWithoutHarness ? provider && !modelWithoutHarness.startsWith(`${provider}/`) ? `${provider}/${modelWithoutHarness}` : modelWithoutHarness : void 0;
131
132
  if (!harness) return providerModel;
132
133
  if (!providerModel) return harness;
133
134
  return providerModel.startsWith(`${harness}/`) ? providerModel : `${harness}/${providerModel}`;
@@ -229,4 +230,4 @@ function assertProfileModelsAllowed(profile, allowed) {
229
230
  //#endregion
230
231
  export { concreteProfileModel as a, profileProviderModel as c, harnessRunsAgent as d, concreteModelId as i, resolveRouterRetryPolicy as l, assertModelAllowed as n, profileBridgeWireModel as o, assertProfileModelsAllowed as r, profileModelExecutionSettings as s, assertExecutableAgentProfile as t, agentHarness as u };
231
232
 
232
- //# sourceMappingURL=model-policy-CqziaqS1.js.map
233
+ //# sourceMappingURL=model-policy-mWSoToiQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-policy-mWSoToiQ.js","names":["positiveInteger"],"sources":["../src/runtime/harness-role.ts","../src/runtime/router-retry-policy.ts","../src/runtime/supervise/model-policy.ts"],"sourcesContent":["/**\n * Which `HarnessType` values name a real coding-agent runtime, and which name a MODE that has no\n * agent behind it.\n *\n * `cli-base` is the router-backed mode — a plain multi-turn router call with no coding-agent\n * harness (`@tangle-network/agent-interface`'s `HarnessType` doc, and the same table's\n * `harnessReasoningCeiling['cli-base'] = 'none'` commented \"cli-base has no agent\"). The\n * distinction is REAL; what was accidental is that three call sites each spelled the test\n * themselves, so a second no-agent mode would have to be remembered in three places.\n *\n * SHOULD UPSTREAM: this belongs next to `harnessHonorsEffort` in agent-interface's\n * `harness-capabilities.ts`, which already encodes the fact but exports no predicate for it.\n * Until it does, this is the one local copy — extend the set here, never re-test the name.\n */\n\nimport type { HarnessType } from '@tangle-network/agent-interface'\n\n/**\n * Harness ids that select a router/no-agent mode rather than a coding-agent runtime.\n *\n * `nanoclaw` is deliberately ABSENT: the shared capability table clamps its reasoning ceiling the\n * same way it clamps `cli-base`, but nanoclaw does run an agent (a socket-bridge runner to the\n * NanoClaw daemon) and every caller here treats it as a full harness. Add a row only with the\n * behavior change stated, never to make the two clamps look symmetric.\n */\nconst NO_AGENT_HARNESSES: ReadonlySet<string> = new Set<string>(['cli-base' satisfies HarnessType])\n\n/** Whether this profile harness selects a real coding-agent runtime (vs. the router/no-agent mode\n * or no preference at all). Accepts the looser `string` some local profile shapes declare, and\n * preserves the caller's own harness type when it is narrower. */\nexport function harnessRunsAgent<T extends string>(harness: T | null | undefined): harness is T {\n return harness != null && !NO_AGENT_HARNESSES.has(harness)\n}\n\n/** The coding-agent harness this profile selects, or `undefined` when it selects none — the shape\n * callers want when a no-agent mode must fall through to the router arm. */\nexport function agentHarness<T extends string>(harness: T | null | undefined): T | undefined {\n return harnessRunsAgent(harness) ? harness : undefined\n}\n","import { ValidationError } from '../errors'\n\n/** Exact retry controls accepted at `AgentProfile.model.metadata.retry`. */\nexport interface RouterRetryPolicy {\n /** Total attempts, including the first request. */\n readonly maxAttempts?: number\n /** Delay before the second attempt. Later delays grow exponentially. */\n readonly initialBackoffMs?: number\n /** Maximum delay between attempts. */\n readonly maxBackoffMs?: number\n /** Symmetric random variation around each delay, from 0 through 1. */\n readonly jitter?: number\n /** HTTP statuses that may be retried. */\n readonly retryStatuses?: ReadonlyArray<number>\n /** Deadline for receiving one attempt's response headers. Zero disables it. */\n readonly requestTimeoutMs?: number\n}\n\nexport interface ResolvedRouterRetryPolicy {\n readonly maxAttempts: number\n readonly initialBackoffMs: number\n readonly maxBackoffMs: number\n readonly jitter: number\n readonly retryStatuses: ReadonlyArray<number>\n readonly requestTimeoutMs: number\n}\n\nconst maximumTimerMs = 2_147_483_647\nconst defaultRetryStatuses = Object.freeze([408, 425, 429, 500, 502, 503, 504, 520, 522, 524])\nconst retryPolicyKeys = new Set([\n 'initialBackoffMs',\n 'jitter',\n 'maxAttempts',\n 'maxBackoffMs',\n 'requestTimeoutMs',\n 'retryStatuses',\n])\n\n/** Parse untrusted profile/config data once and return an immutable complete policy. */\nexport function resolveRouterRetryPolicy(\n input: unknown,\n context: string,\n): ResolvedRouterRetryPolicy {\n if (\n input !== undefined &&\n (typeof input !== 'object' || input === null || Array.isArray(input))\n ) {\n throw new ValidationError(`${context} must be an object`)\n }\n const policy = input === undefined ? {} : Object.fromEntries(Object.entries(input))\n const unknown = Object.keys(policy).filter((key) => !retryPolicyKeys.has(key))\n if (unknown.length > 0) {\n throw new ValidationError(`${context} has unsupported fields: ${unknown.join(', ')}`)\n }\n const maxAttempts = positiveInteger(policy.maxAttempts, 5, `${context}.maxAttempts`)\n const initialBackoffMs = timerInteger(\n policy.initialBackoffMs,\n 1_000,\n `${context}.initialBackoffMs`,\n )\n const maxBackoffMs = timerInteger(policy.maxBackoffMs, 30_000, `${context}.maxBackoffMs`)\n const requestTimeoutMs = timerInteger(policy.requestTimeoutMs, 0, `${context}.requestTimeoutMs`)\n const jitter = policy.jitter ?? 0.25\n if (typeof jitter !== 'number' || !Number.isFinite(jitter) || jitter < 0 || jitter > 1) {\n throw new ValidationError(`${context}.jitter must be a finite number from 0 through 1`)\n }\n const retryStatuses = parseRetryStatuses(policy.retryStatuses, context)\n return Object.freeze({\n maxAttempts,\n initialBackoffMs,\n maxBackoffMs,\n jitter,\n retryStatuses,\n requestTimeoutMs,\n })\n}\n\nfunction parseRetryStatuses(value: unknown, context: string): ReadonlyArray<number> {\n if (value === undefined) return defaultRetryStatuses\n if (!Array.isArray(value)) {\n throw new ValidationError(`${context}.retryStatuses must be an array of HTTP statuses`)\n }\n const statuses: number[] = []\n const seen = new Set<number>()\n for (const status of value) {\n if (!Number.isSafeInteger(status) || status < 100 || status > 599) {\n throw new ValidationError(\n `${context}.retryStatuses must contain integer HTTP statuses from 100 through 599`,\n )\n }\n if (seen.has(status)) {\n throw new ValidationError(`${context}.retryStatuses must not contain duplicates`)\n }\n seen.add(status)\n statuses.push(status)\n }\n return Object.freeze(statuses)\n}\n\nfunction positiveInteger(value: unknown, fallback: number, context: string): number {\n const parsed = value ?? fallback\n if (typeof parsed !== 'number' || !Number.isSafeInteger(parsed) || parsed < 1) {\n throw new ValidationError(`${context} must be a positive safe integer`)\n }\n return parsed\n}\n\nfunction timerInteger(value: unknown, fallback: number, context: string): number {\n const parsed = value ?? fallback\n if (\n typeof parsed !== 'number' ||\n !Number.isSafeInteger(parsed) ||\n parsed < 0 ||\n parsed > maximumTimerMs\n ) {\n throw new ValidationError(\n `${context} must be a nonnegative safe integer no greater than ${maximumTimerMs}`,\n )\n }\n return parsed\n}\n","/**\n * `assertModelAllowed` — a fail-loud guard that restricts a run to a chosen subset of\n * models. The two front doors (`supervise()` / `improve()`) call it once per configured\n * model at resolve time, so a run that names a model outside the allowed set throws before\n * any compute is spent — never silently swapped or silently allowed.\n */\nimport { HARNESS_NATIVE_MODEL } from '@tangle-network/agent-eval'\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport { ConfigError } from '../../errors'\nimport { agentHarness } from '../harness-role'\nimport { type ResolvedRouterRetryPolicy, resolveRouterRetryPolicy } from '../router-retry-policy'\n\n/**\n * Return the model id an executor may send to a provider.\n *\n * Eval stamps {@link HARNESS_NATIVE_MODEL} into a profile when model selection is deliberately\n * delegated to the configured runtime. That marker belongs in experiment identity and cost\n * admission; it is not a provider model id.\n */\nexport function concreteModelId(model: string | undefined): string | undefined {\n if (model === undefined) return undefined\n const id = model.trim()\n return id.length > 0 && !isHarnessNativeModel(id) ? id : undefined\n}\n\n/** Whether a model value delegates selection to the chosen execution system. */\nexport function isHarnessNativeModel(model: string | undefined): boolean {\n return model?.trim() === HARNESS_NATIVE_MODEL\n}\n\n/** Return a profile's explicitly selected provider model, if it has one. */\nexport function concreteProfileModel(profile: Pick<AgentProfile, 'model'>): string | undefined {\n return concreteModelId(profile.model?.default)\n}\n\n/** The provider-facing model id declared by a profile. Direct Router execution uses this form:\n * the endpoint already selects the provider, so the model id itself is not harness-prefixed. */\nexport function profileProviderModel(profile: Pick<AgentProfile, 'model'>): string | undefined {\n return concreteProfileModel(profile)\n}\n\n/** The full cli-bridge wire id declared by a profile: harness/provider/model. */\nexport function profileBridgeWireModel(\n profile: Pick<AgentProfile, 'harness' | 'model'>,\n): string | undefined {\n const model = concreteProfileModel(profile)\n const provider = profile.model?.provider\n const harness = agentHarness(profile.harness)\n const modelWithoutHarness =\n model && harness && model.startsWith(`${harness}/`) ? model.slice(harness.length + 1) : model\n const providerModel = modelWithoutHarness\n ? provider && !modelWithoutHarness.startsWith(`${provider}/`)\n ? `${provider}/${modelWithoutHarness}`\n : modelWithoutHarness\n : undefined\n if (!harness) return providerModel\n if (!providerModel) return harness\n return providerModel.startsWith(`${harness}/`) ? providerModel : `${harness}/${providerModel}`\n}\n\n/**\n * Refuse an incomplete execution identity before any backend may fill it from ambient config.\n * `AgentProfile` is the sole behavioral authority: harness, provider, and concrete model all\n * participate in its digest. Eval's runtime-selected marker is a matrix-planning value, never an\n * executable model.\n */\nexport function assertExecutableAgentProfile(profile: AgentProfile, context: string): void {\n if (profile.harness === undefined) {\n throw new ConfigError(`${context}: AgentProfile.harness must be explicit before execution`)\n }\n const declared = profile.model?.default\n const model = concreteModelId(declared)\n if (!model) {\n const reason = isHarnessNativeModel(declared) ? 'runtime-selected' : 'missing'\n throw new ConfigError(\n `${context}: AgentProfile.model.default is ${reason}; execution requires a concrete model`,\n )\n }\n if (!profile.model?.provider?.trim()) {\n throw new ConfigError(\n `${context}: AgentProfile.model.provider must be explicit before execution`,\n )\n }\n}\n\n/** Generation and loop controls that may affect one model execution. */\nexport interface ProfileModelExecutionSettings {\n readonly temperature?: number\n readonly maxTokens?: number\n readonly retry?: ResolvedRouterRetryPolicy\n readonly seed?: number\n readonly toolChoice?: 'auto' | 'required' | 'none'\n readonly extraBody?: Readonly<Record<string, unknown>>\n /** Zero means no turn-count cap; conserved budgets and deadlines still apply. */\n readonly maxTurns?: number\n readonly stream?: boolean\n}\n\nconst PROFILE_MODEL_METADATA_KEYS = new Set([\n 'extraBody',\n 'maxTokens',\n 'maxTurns',\n 'retry',\n 'seed',\n 'stream',\n 'temperature',\n 'toolChoice',\n])\n\n/**\n * Read every Router-affecting control from the exact profile and reject unknown controls.\n * Backends receive endpoint/auth and executable ports only; they cannot silently alter behavior.\n */\nexport function profileModelExecutionSettings(\n profile: Pick<AgentProfile, 'model'>,\n context: string,\n): ProfileModelExecutionSettings {\n const metadata = profile.model?.metadata ?? {}\n const unknown = Object.keys(metadata).filter((key) => !PROFILE_MODEL_METADATA_KEYS.has(key))\n if (unknown.length > 0) {\n throw new ConfigError(\n `${context}: unsupported AgentProfile.model.metadata fields: ${unknown.join(', ')}`,\n )\n }\n const temperature = finiteNumber(metadata.temperature, `${context}: temperature`)\n const maxTokens = positiveInteger(metadata.maxTokens, `${context}: maxTokens`)\n const retryInput = metadata.retry\n const retry =\n retryInput === undefined\n ? undefined\n : resolveRouterRetryPolicy(retryInput, `${context}: AgentProfile.model.metadata.retry`)\n const seed = safeInteger(metadata.seed, `${context}: seed`)\n const maxTurns = nonnegativeInteger(metadata.maxTurns, `${context}: maxTurns`)\n const stream = optionalBoolean(metadata.stream, `${context}: stream`)\n const toolChoice = metadata.toolChoice\n if (\n toolChoice !== undefined &&\n toolChoice !== 'auto' &&\n toolChoice !== 'required' &&\n toolChoice !== 'none'\n ) {\n throw new ConfigError(`${context}: toolChoice must be auto, required, or none`)\n }\n const extraBody = metadata.extraBody\n if (\n extraBody !== undefined &&\n (typeof extraBody !== 'object' || extraBody === null || Array.isArray(extraBody))\n ) {\n throw new ConfigError(`${context}: extraBody must be an object`)\n }\n return {\n ...(temperature !== undefined ? { temperature } : {}),\n ...(maxTokens !== undefined ? { maxTokens } : {}),\n ...(retry !== undefined ? { retry } : {}),\n ...(seed !== undefined ? { seed } : {}),\n ...(toolChoice !== undefined ? { toolChoice } : {}),\n ...(extraBody !== undefined\n ? { extraBody: Object.freeze({ ...(extraBody as Record<string, unknown>) }) }\n : {}),\n ...(maxTurns !== undefined ? { maxTurns } : {}),\n ...(stream !== undefined ? { stream } : {}),\n }\n}\n\nfunction finiteNumber(value: unknown, context: string): number | undefined {\n if (value === undefined) return undefined\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n throw new ConfigError(`${context} must be a finite number`)\n }\n return value\n}\n\nfunction safeInteger(value: unknown, context: string): number | undefined {\n if (value === undefined) return undefined\n if (!Number.isSafeInteger(value)) throw new ConfigError(`${context} must be a safe integer`)\n return value as number\n}\n\nfunction positiveInteger(value: unknown, context: string): number | undefined {\n const parsed = safeInteger(value, context)\n if (parsed !== undefined && parsed < 1) {\n throw new ConfigError(`${context} must be positive`)\n }\n return parsed\n}\n\nfunction nonnegativeInteger(value: unknown, context: string): number | undefined {\n const parsed = safeInteger(value, context)\n if (parsed !== undefined && parsed < 0) {\n throw new ConfigError(`${context} must be nonnegative`)\n }\n return parsed\n}\n\nfunction optionalBoolean(value: unknown, context: string): boolean | undefined {\n if (value === undefined) return undefined\n if (typeof value !== 'boolean') throw new ConfigError(`${context} must be boolean`)\n return value\n}\n\n/**\n * Throw a `ConfigError` when `allowed` is set, `model` is defined, and `model` is not a\n * member of `allowed`. No-op when `allowed` is unset (the unrestricted default) or when\n * `model` is undefined (nothing was configured to check).\n */\nexport function assertModelAllowed(\n model: string | undefined,\n allowed: readonly string[] | undefined,\n): void {\n if (!allowed || model === undefined) return\n if (!allowed.includes(model)) {\n throw new ConfigError(\n `model ${JSON.stringify(model)} is not in the allowed set ${JSON.stringify([...allowed])}`,\n )\n }\n}\n\n/** Check every canonical model-bearing field in a complete profile, including the models a\n * backend may select for cheap work, named subagents, or modes. */\nexport function assertProfileModelsAllowed(\n profile: AgentProfile,\n allowed: readonly string[] | undefined,\n): void {\n assertModelAllowed(profile.model?.default, allowed)\n assertModelAllowed(profile.model?.small, allowed)\n for (const subagent of Object.values(profile.subagents ?? {})) {\n assertModelAllowed(subagent.model, allowed)\n }\n for (const mode of Object.values(profile.modes ?? {})) {\n assertModelAllowed(mode.model, allowed)\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { A as DELEGATION_HISTORY_INPUT_SCHEMA, B as DELEGATE_FEEDBACK_INPUT_SCHEMA, E as DELEGATION_STATUS_TOOL_NAME, T as DELEGATION_STATUS_INPUT_SCHEMA, V as DELEGATE_FEEDBACK_TOOL_NAME, j as DELEGATION_HISTORY_TOOL_NAME, k as DELEGATION_HISTORY_DESCRIPTION, w as DELEGATION_STATUS_DESCRIPTION, z as DELEGATE_FEEDBACK_DESCRIPTION } from "./supervise-BVNSL3N0.js";
1
+ import { A as DELEGATION_HISTORY_INPUT_SCHEMA, B as DELEGATE_FEEDBACK_INPUT_SCHEMA, E as DELEGATION_STATUS_TOOL_NAME, T as DELEGATION_STATUS_INPUT_SCHEMA, V as DELEGATE_FEEDBACK_TOOL_NAME, j as DELEGATION_HISTORY_TOOL_NAME, k as DELEGATION_HISTORY_DESCRIPTION, w as DELEGATION_STATUS_DESCRIPTION, z as DELEGATE_FEEDBACK_DESCRIPTION } from "./supervise-msTRhTN7.js";
2
2
  //#region src/mcp/openai-tools.ts
3
3
  function buildTool(name, description, parameters) {
4
4
  return {
@@ -41,4 +41,4 @@ function mcpToolsForRuntimeMcpSubset(names) {
41
41
  //#endregion
42
42
  export { mcpToolsForRuntimeMcpSubset as n, mcpToolsForRuntimeMcp as t };
43
43
 
44
- //# sourceMappingURL=openai-tools-CPhN7uKC.js.map
44
+ //# sourceMappingURL=openai-tools-CupeHJEv.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"openai-tools-CPhN7uKC.js","names":[],"sources":["../src/mcp/openai-tools.ts"],"sourcesContent":["/**\n *\n * OpenAI Chat Completions `tools[]` projection of the queue-bound agent-runtime\n * MCP delegation tools.\n *\n * Use when a caller-owned OpenAI-compatible transport needs the model to call\n * `delegate_feedback`, `delegation_status`, and `delegation_history`. Execution\n * is the caller's responsibility (typically the parent sandbox runtime's MCP\n * mount); Runtime's profile-bound model path materializes profile tools through\n * its executor instead.\n *\n * Sandbox-SDK callers do NOT need this helper: the sandbox runtime mounts\n * MCP servers natively and the in-sandbox harness discovers tools via the\n * runtime, not via an OpenAI tools array.\n *\n * Tool name + description + JSON-schema are pulled from the canonical\n * `DELEGATE_*` constants exported by `./tools/*` so the projection cannot\n * drift from the server's own validators.\n *\n * @experimental\n */\n\nimport type { OpenAIChatTool } from '../types'\nimport {\n DELEGATE_FEEDBACK_DESCRIPTION,\n DELEGATE_FEEDBACK_INPUT_SCHEMA,\n DELEGATE_FEEDBACK_TOOL_NAME,\n} from './tools/delegate-feedback'\nimport {\n DELEGATION_HISTORY_DESCRIPTION,\n DELEGATION_HISTORY_INPUT_SCHEMA,\n DELEGATION_HISTORY_TOOL_NAME,\n} from './tools/delegation-history'\nimport {\n DELEGATION_STATUS_DESCRIPTION,\n DELEGATION_STATUS_INPUT_SCHEMA,\n DELEGATION_STATUS_TOOL_NAME,\n} from './tools/delegation-status'\n\nfunction buildTool(\n name: string,\n description: string,\n parameters: Readonly<Record<string, unknown>>,\n): OpenAIChatTool {\n // `parameters` arrives as a deeply-readonly `as const` literal. The\n // OpenAI-compatible transports JSON-serialize the body, so a shallow copy\n // into a plain object is sufficient and shields callers that mutate\n // the returned descriptor from corrupting the source constant.\n return {\n type: 'function',\n function: { name, description, parameters: { ...parameters } },\n }\n}\n\n/**\n *\n * Returns the queue-bound delegation tools projected into OpenAI Chat\n * Completions `tools[]` shape. The order is stable: `delegate_feedback`,\n * `delegation_status`, `delegation_history`.\n *\n * @experimental\n */\nexport function mcpToolsForRuntimeMcp(): OpenAIChatTool[] {\n return [\n buildTool(\n DELEGATE_FEEDBACK_TOOL_NAME,\n DELEGATE_FEEDBACK_DESCRIPTION,\n DELEGATE_FEEDBACK_INPUT_SCHEMA as Readonly<Record<string, unknown>>,\n ),\n buildTool(\n DELEGATION_STATUS_TOOL_NAME,\n DELEGATION_STATUS_DESCRIPTION,\n DELEGATION_STATUS_INPUT_SCHEMA as Readonly<Record<string, unknown>>,\n ),\n buildTool(\n DELEGATION_HISTORY_TOOL_NAME,\n DELEGATION_HISTORY_DESCRIPTION,\n DELEGATION_HISTORY_INPUT_SCHEMA as Readonly<Record<string, unknown>>,\n ),\n ]\n}\n\n/**\n *\n * Subset filter — return only the projected tools whose `function.name`\n * appears in `names`. Useful for curated mounts (e.g. only the queue-bound\n * delegation tools, omitting `delegate_feedback`). Unknown names are\n * silently ignored; pass an empty array to get an empty result.\n *\n * @experimental\n */\nexport function mcpToolsForRuntimeMcpSubset(names: ReadonlyArray<string>): OpenAIChatTool[] {\n const allowed = new Set(names)\n return mcpToolsForRuntimeMcp().filter((tool) => allowed.has(tool.function.name))\n}\n"],"mappings":";;AAuCA,SAAS,UACP,MACA,aACA,YACgB;CAKhB,OAAO;EACL,MAAM;EACN,UAAU;GAAE;GAAM;GAAa,YAAY,EAAE,GAAG,WAAW;EAAE;CAC/D;AACF;;;;;;;;;AAUA,SAAgB,wBAA0C;CACxD,OAAO;EACL,UACE,6BACA,+BACA,8BACF;EACA,UACE,6BACA,+BACA,8BACF;EACA,UACE,8BACA,gCACA,+BACF;CACF;AACF;;;;;;;;;;AAWA,SAAgB,4BAA4B,OAAgD;CAC1F,MAAM,UAAU,IAAI,IAAI,KAAK;CAC7B,OAAO,sBAAsB,CAAC,CAAC,QAAQ,SAAS,QAAQ,IAAI,KAAK,SAAS,IAAI,CAAC;AACjF"}
1
+ {"version":3,"file":"openai-tools-CupeHJEv.js","names":[],"sources":["../src/mcp/openai-tools.ts"],"sourcesContent":["/**\n *\n * OpenAI Chat Completions `tools[]` projection of the queue-bound agent-runtime\n * MCP delegation tools.\n *\n * Use when a caller-owned OpenAI-compatible transport needs the model to call\n * `delegate_feedback`, `delegation_status`, and `delegation_history`. Execution\n * is the caller's responsibility (typically the parent sandbox runtime's MCP\n * mount); Runtime's profile-bound model path materializes profile tools through\n * its executor instead.\n *\n * Sandbox-SDK callers do NOT need this helper: the sandbox runtime mounts\n * MCP servers natively and the in-sandbox harness discovers tools via the\n * runtime, not via an OpenAI tools array.\n *\n * Tool name + description + JSON-schema are pulled from the canonical\n * `DELEGATE_*` constants exported by `./tools/*` so the projection cannot\n * drift from the server's own validators.\n *\n * @experimental\n */\n\nimport type { OpenAIChatTool } from '../types'\nimport {\n DELEGATE_FEEDBACK_DESCRIPTION,\n DELEGATE_FEEDBACK_INPUT_SCHEMA,\n DELEGATE_FEEDBACK_TOOL_NAME,\n} from './tools/delegate-feedback'\nimport {\n DELEGATION_HISTORY_DESCRIPTION,\n DELEGATION_HISTORY_INPUT_SCHEMA,\n DELEGATION_HISTORY_TOOL_NAME,\n} from './tools/delegation-history'\nimport {\n DELEGATION_STATUS_DESCRIPTION,\n DELEGATION_STATUS_INPUT_SCHEMA,\n DELEGATION_STATUS_TOOL_NAME,\n} from './tools/delegation-status'\n\nfunction buildTool(\n name: string,\n description: string,\n parameters: Readonly<Record<string, unknown>>,\n): OpenAIChatTool {\n // `parameters` arrives as a deeply-readonly `as const` literal. The\n // OpenAI-compatible transports JSON-serialize the body, so a shallow copy\n // into a plain object is sufficient and shields callers that mutate\n // the returned descriptor from corrupting the source constant.\n return {\n type: 'function',\n function: { name, description, parameters: { ...parameters } },\n }\n}\n\n/**\n *\n * Returns the queue-bound delegation tools projected into OpenAI Chat\n * Completions `tools[]` shape. The order is stable: `delegate_feedback`,\n * `delegation_status`, `delegation_history`.\n *\n * @experimental\n */\nexport function mcpToolsForRuntimeMcp(): OpenAIChatTool[] {\n return [\n buildTool(\n DELEGATE_FEEDBACK_TOOL_NAME,\n DELEGATE_FEEDBACK_DESCRIPTION,\n DELEGATE_FEEDBACK_INPUT_SCHEMA as Readonly<Record<string, unknown>>,\n ),\n buildTool(\n DELEGATION_STATUS_TOOL_NAME,\n DELEGATION_STATUS_DESCRIPTION,\n DELEGATION_STATUS_INPUT_SCHEMA as Readonly<Record<string, unknown>>,\n ),\n buildTool(\n DELEGATION_HISTORY_TOOL_NAME,\n DELEGATION_HISTORY_DESCRIPTION,\n DELEGATION_HISTORY_INPUT_SCHEMA as Readonly<Record<string, unknown>>,\n ),\n ]\n}\n\n/**\n *\n * Subset filter — return only the projected tools whose `function.name`\n * appears in `names`. Useful for curated mounts (e.g. only the queue-bound\n * delegation tools, omitting `delegate_feedback`). Unknown names are\n * silently ignored; pass an empty array to get an empty result.\n *\n * @experimental\n */\nexport function mcpToolsForRuntimeMcpSubset(names: ReadonlyArray<string>): OpenAIChatTool[] {\n const allowed = new Set(names)\n return mcpToolsForRuntimeMcp().filter((tool) => allowed.has(tool.function.name))\n}\n"],"mappings":";;AAuCA,SAAS,UACP,MACA,aACA,YACgB;CAKhB,OAAO;EACL,MAAM;EACN,UAAU;GAAE;GAAM;GAAa,YAAY,EAAE,GAAG,WAAW;EAAE;CAC/D;AACF;;;;;;;;;AAUA,SAAgB,wBAA0C;CACxD,OAAO;EACL,UACE,6BACA,+BACA,8BACF;EACA,UACE,6BACA,+BACA,8BACF;EACA,UACE,8BACA,gCACA,+BACF;CACF;AACF;;;;;;;;;;AAWA,SAAgB,4BAA4B,OAAgD;CAC1F,MAAM,UAAU,IAAI,IAAI,KAAK;CAC7B,OAAO,sBAAsB,CAAC,CAAC,QAAQ,SAAS,QAAQ,IAAI,KAAK,SAAS,IAAI,CAAC;AACjF"}
package/dist/profiles.js CHANGED
@@ -1,4 +1,4 @@
1
- import { i as researcherProfile, n as createResearcherValidator, r as multiHarnessResearcherFanout } from "./researcher-Skz5-Uc8.js";
1
+ import { i as researcherProfile, n as createResearcherValidator, r as multiHarnessResearcherFanout } from "./researcher-CYmr4VJy.js";
2
2
  import { n as UI_LENSES, t as UI_FINDING_SEVERITIES } from "./substrate-B0TYNrXn.js";
3
3
  import { t as coderTaskToPrompt } from "./coder-yhVWbdWc.js";
4
4
  import path from "node:path";
@@ -1,5 +1,5 @@
1
1
  import { i as ConfigError } from "./errors-DEAvWQPy.js";
2
- import { t as assertExecutableAgentProfile } from "./model-policy-CqziaqS1.js";
2
+ import { t as assertExecutableAgentProfile } from "./model-policy-mWSoToiQ.js";
3
3
  import { agentProfileSchema } from "@tangle-network/agent-interface";
4
4
  //#region src/profiles/researcher.ts
5
5
  /**
@@ -454,4 +454,4 @@ function clamp01(value) {
454
454
  //#endregion
455
455
  export { researcherProfile as i, createResearcherValidator as n, multiHarnessResearcherFanout as r, RESEARCHER_SYSTEM_PROMPT as t };
456
456
 
457
- //# sourceMappingURL=researcher-Skz5-Uc8.js.map
457
+ //# sourceMappingURL=researcher-CYmr4VJy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"researcher-Skz5-Uc8.js","names":[],"sources":["../src/profiles/researcher.ts"],"sourcesContent":["/**\n * Opinionated preset for source-grounded research\n * tasks. The agent is told to:\n * - bound its work to a single `knowledgeNamespace`\n * - emit `items[]` carrying provenance + confidence\n * - emit `citations[]` linking quotes back to source urls\n * - emit `proposedWrites[]` — never call materialize itself\n * - describe `gaps` it could not answer\n *\n * The profile is stateless and agent-agnostic. The caller supplies the exact execution profile;\n * this preset adds only the researcher prompt, tools, parser, and validator.\n *\n * Propose-don't-apply: the profile NEVER writes to the knowledge base.\n * It produces `proposedWrites: KnowledgeUpdate[]` in the output. The\n * caller (gtm-agent, journey-eval, user) decides whether to feed those\n * updates through `applyKnowledgeWriteBlocks` / a KbStore put.\n *\n * Namespace isolation: every `KnowledgeItem` + `KnowledgeUpdate` in the\n * output carries `namespace`. The validator hard-fails when any item\n * touches a namespace other than `task.knowledgeNamespace`.\n *\n * @experimental\n */\n\nimport { type AgentProfile, agentProfileSchema } from '@tangle-network/agent-interface'\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport { ConfigError } from '../errors'\nimport { assertExecutableAgentProfile } from '../runtime/supervise/model-policy'\nimport type {\n AgentRunSpec,\n DefaultVerdict,\n Driver,\n OutputAdapter,\n Validator,\n} from '../runtime/types'\n\n/** Source families a researcher profile may prefer for a task. @experimental */\nexport type ResearchSource = 'web' | 'corpus' | 'twitter' | 'github' | 'docs'\n\n/** Task contract for a source-grounded research agent. @experimental */\nexport interface ResearchTask {\n /** The research question to answer. */\n question: string\n /** Bound: e.g. \"audience for cpg-founder ICP\". */\n scope?: string\n /** Multi-tenant scope (customer-id, workspace-id). Validator enforces. */\n knowledgeNamespace: string\n sources?: ResearchSource[]\n recencyWindow?: { since?: Date; until?: Date }\n maxItems?: number\n /** Per-item minimum confidence in [0, 1]. Validator scores recall vs this. */\n minConfidence?: number\n}\n\n/**\n * Knowledge item emitted by the researcher.\n *\n * Profile-local type. When agent-knowledge promotes `KnowledgeClaim` →\n * top-level `KnowledgeItem` substrate-wide, these fields collapse 1:1.\n *\n * @experimental\n */\nexport interface KnowledgeItem {\n id: string\n /** Multi-tenant scope. MUST equal `task.knowledgeNamespace`. */\n namespace: string\n /** The factual claim, in the researcher's words. */\n claim: string\n /** Provenance — at least one entry required. */\n evidence: Array<{ source: string; quote?: string; url?: string; capturedAt: number }>\n /** Researcher's self-reported confidence in [0, 1]. */\n confidence: number\n /** Prior item ids this supersedes (chain). */\n supersedes?: string[]\n /** Set if the agent is retracting an earlier item. Unix ms. */\n retractedAt?: number\n authoredBy: { kind: 'human' | 'agent'; id: string }\n}\n\n/**\n * A proposed write to the knowledge base. The profile does NOT apply\n * these — the caller decides.\n *\n * @experimental\n */\nexport type KnowledgeUpdate =\n | { kind: 'insert'; namespace: string; item: KnowledgeItem }\n | { kind: 'supersede'; namespace: string; previousId: string; item: KnowledgeItem }\n | { kind: 'retract'; namespace: string; itemId: string; reason: string }\n\n/**\n * Researcher output. Required fields are typed; optional fields preserve\n * the agent's free-form intelligence (`notes`, `raw`). The validator\n * enforces the typed minimum.\n *\n * @experimental\n */\nexport interface ResearchOutput {\n items: KnowledgeItem[]\n citations: Array<{ url: string; quote: string; confidence: number }>\n proposedWrites: KnowledgeUpdate[]\n gaps?: string[]\n notes?: string\n /** Anything the agent emitted beyond the typed fields. */\n raw?: unknown\n}\n\n/** Options for the source-grounded researcher profile preset. @experimental */\nexport interface ResearcherProfileOptions {\n /** Caller-owned exact harness/provider/model identity. */\n profile: AgentProfile\n /** Custom system prompt replacement. Default = built-in researcher preset. */\n systemPrompt?: string\n /** Stable name for `AgentRunSpec.name`. Default = `profile.name`. */\n name?: string\n /**\n * Default 0.7. Minimum (citations with quote) / items ratio for `valid=true`.\n * Below this floor, citation_density scores < 1 and the item set is gated.\n */\n citationDensityMin?: number\n}\n\nconst DEFAULT_CITATION_DENSITY_MIN = 0.7\n\n/** Build a source-grounded researcher profile with output parsing and validation. @experimental */\nexport function researcherProfile(options: ResearcherProfileOptions & { task?: ResearchTask }): {\n profile: AgentProfile\n taskToPrompt: (task: ResearchTask) => string\n output: OutputAdapter<ResearchOutput>\n validator: Validator<ResearchOutput>\n agentRunSpec: AgentRunSpec<ResearchTask>\n} {\n const base = agentProfileSchema.parse(options.profile) as AgentProfile\n assertExecutableAgentProfile(base, 'researcherProfile')\n const name = options.name ?? base.name\n const systemPrompt = options.systemPrompt ?? RESEARCHER_SYSTEM_PROMPT\n const citationDensityMin = options.citationDensityMin ?? DEFAULT_CITATION_DENSITY_MIN\n const profile: AgentProfile = {\n ...base,\n name,\n description: base.description ?? \"Source-grounded research agent. Propose-don't-apply.\",\n prompt: { ...base.prompt, systemPrompt },\n tools: { web_search: true, fs: true, shell: true, ...base.tools },\n metadata: { ...base.metadata, role: 'researcher' },\n }\n const output: OutputAdapter<ResearchOutput> = { parse: parseResearcherEvents }\n const validator: Validator<ResearchOutput> = options.task\n ? createResearcherValidator(options.task, { citationDensityMin })\n : createResearcherValidator(\n { question: '', knowledgeNamespace: '' },\n { citationDensityMin, namespaceCheck: false },\n )\n const agentRunSpec: AgentRunSpec<ResearchTask> = {\n name,\n profile,\n taskToPrompt: formatResearcherPrompt,\n }\n return { profile, taskToPrompt: formatResearcherPrompt, output, validator, agentRunSpec }\n}\n\n/** @experimental */\nexport interface MultiHarnessResearcherFanoutOptions {\n /** Exact execution profiles, one per parallel researcher. */\n profiles: ReadonlyArray<AgentProfile>\n /** Default citation density floor for the shared validator. */\n citationDensityMin?: number\n /** Optional task — narrows the validator's namespace check. */\n task?: ResearchTask\n}\n\n/**\n * Build a fanout topology over multiple harnesses. The kernel round-robins\n * `agentRuns` across the N parallel iterations and the `FanoutVote` driver\n * picks the highest-scoring valid output.\n *\n * @experimental\n */\nexport function multiHarnessResearcherFanout(options: MultiHarnessResearcherFanoutOptions): {\n agentRuns: AgentRunSpec<ResearchTask>[]\n output: OutputAdapter<ResearchOutput>\n validator: Validator<ResearchOutput>\n driver: Driver<ResearchTask, ResearchOutput, 'done'>\n} {\n if (options.profiles.length === 0) {\n throw new ConfigError('multiHarnessResearcherFanout: at least one exact profile is required')\n }\n const agentRuns = options.profiles.map((profile) => {\n const { agentRunSpec } = researcherProfile({ profile })\n return agentRunSpec\n })\n const { output, validator } = researcherProfile({\n profile: options.profiles[0]!,\n citationDensityMin: options.citationDensityMin,\n task: options.task,\n })\n // Single fanout round across the N harnesses, then stop: the kernel\n // round-robins `agentRuns` over the N branches and selects the winner\n // (best valid score) across all iterations via `defaultSelectWinner`.\n const driver: Driver<ResearchTask, ResearchOutput, 'done'> = {\n name: 'researcher-fanout',\n async plan(task, history) {\n return history.length === 0 ? Array.from({ length: agentRuns.length }, () => task) : []\n },\n // 'done' is a terminal decision in the kernel; the loop finalizes after\n // the single fanout round and selects the winner via `defaultSelectWinner`.\n decide() {\n return 'done'\n },\n describePlan() {\n return { kind: 'fanout' }\n },\n }\n return { agentRuns, output, validator, driver }\n}\n\n/**\n * Build a validator that closes over a specific `ResearchTask`'s constraints.\n *\n * Checks in order:\n * 1. Items must be non-empty.\n * 2. Every item carries `evidence.length >= 1`.\n * 3. Every item + proposedWrite is scoped to `task.knowledgeNamespace`\n * (hard-fail on any namespace mismatch — defence in depth for the\n * multi-tenant invariant).\n * 4. Citation density (citations with quote / items) >= floor.\n *\n * Aggregate score:\n * 0.4 · citation_density\n * + 0.2 · source_diversity (distinct sources / max(items, 1))\n * + 0.2 · recency_match (mean fraction within `recencyWindow`)\n * + 0.2 · (1 − gaps/maxGaps), maxGaps = max(items, 1)\n *\n * @experimental\n */\nexport function createResearcherValidator(\n task: ResearchTask,\n config: { citationDensityMin?: number; namespaceCheck?: boolean } = {},\n): Validator<ResearchOutput> {\n const citationDensityMin = config.citationDensityMin ?? DEFAULT_CITATION_DENSITY_MIN\n const namespaceCheck = config.namespaceCheck ?? true\n return {\n async validate(output) {\n const notes: string[] = []\n const scores: Record<string, number> = {}\n let pass = true\n\n if (!Array.isArray(output.items) || output.items.length === 0) {\n pass = false\n notes.push('no items')\n scores.items = 0\n } else {\n scores.items = 1\n }\n\n const missingEvidence = (output.items ?? []).filter(\n (item) => !Array.isArray(item.evidence) || item.evidence.length === 0,\n )\n if (missingEvidence.length > 0) {\n pass = false\n notes.push(`${missingEvidence.length} item(s) without evidence`)\n scores.provenance = 0\n } else {\n scores.provenance = 1\n }\n\n if (namespaceCheck) {\n const foreignItems = (output.items ?? []).filter(\n (item) => item.namespace !== task.knowledgeNamespace,\n )\n const foreignWrites = (output.proposedWrites ?? []).filter(\n (write) => write.namespace !== task.knowledgeNamespace,\n )\n if (foreignItems.length > 0 || foreignWrites.length > 0) {\n pass = false\n notes.push(\n `namespace violation: ${foreignItems.length} item(s) + ${foreignWrites.length} write(s) ` +\n `outside ${task.knowledgeNamespace}`,\n )\n scores.namespace = 0\n } else {\n scores.namespace = 1\n }\n }\n\n const itemCount = Math.max(output.items?.length ?? 0, 1)\n const citationsWithQuote = (output.citations ?? []).filter(\n (citation) => typeof citation.quote === 'string' && citation.quote.length > 0,\n ).length\n const citationDensity = Math.min(1, citationsWithQuote / itemCount)\n if (citationDensity < citationDensityMin) {\n pass = false\n notes.push(\n `citation density ${citationDensity.toFixed(2)} below floor ${citationDensityMin.toFixed(2)}`,\n )\n }\n scores.citation_density = citationDensity\n\n const sourceSet = new Set<string>()\n for (const item of output.items ?? []) {\n for (const evidence of item.evidence ?? []) {\n if (evidence.source) sourceSet.add(evidence.source)\n }\n }\n scores.source_diversity = Math.min(1, sourceSet.size / itemCount)\n\n scores.recency_match = recencyMatchScore(output.items ?? [], task.recencyWindow)\n\n const maxGaps = itemCount\n const gapCount = output.gaps?.length ?? 0\n scores.gap_coverage = Math.max(0, 1 - gapCount / maxGaps)\n\n const score =\n 0.4 * scores.citation_density +\n 0.2 * scores.source_diversity +\n 0.2 * scores.recency_match +\n 0.2 * scores.gap_coverage\n\n const verdict: DefaultVerdict = {\n valid: pass,\n score: Number.isFinite(score) ? score : 0,\n scores,\n }\n if (notes.length > 0) verdict.notes = notes.join('; ')\n return verdict\n },\n }\n}\n\nfunction recencyMatchScore(items: KnowledgeItem[], window: ResearchTask['recencyWindow']): number {\n if (!window || (window.since === undefined && window.until === undefined)) return 1\n if (items.length === 0) return 0\n const sinceMs = window.since?.getTime() ?? Number.NEGATIVE_INFINITY\n const untilMs = window.until?.getTime() ?? Number.POSITIVE_INFINITY\n let hits = 0\n let total = 0\n for (const item of items) {\n for (const evidence of item.evidence ?? []) {\n if (typeof evidence.capturedAt !== 'number') continue\n total += 1\n if (evidence.capturedAt >= sinceMs && evidence.capturedAt <= untilMs) hits += 1\n }\n }\n return total === 0 ? 0 : hits / total\n}\n\n/** Built-in source-grounded research contract added to a caller-owned exact profile. */\nexport const RESEARCHER_SYSTEM_PROMPT = [\n 'You are a research agent. Your job is to answer a research question with',\n 'source-grounded knowledge items that the caller will choose whether to',\n 'persist to a multi-tenant knowledge base.',\n '',\n 'Hard rules:',\n \" 1. Every item you emit MUST carry the task's knowledgeNamespace exactly.\",\n ' Never write to a different namespace.',\n ' 2. Every item MUST carry at least one evidence entry with a source.',\n ' A quote + url is strongly preferred; capturedAt is unix ms.',\n ' 3. You propose writes — you do NOT apply them. The caller decides.',\n ' 4. Self-report confidence honestly in [0, 1]. Do not inflate.',\n ' 5. List what you could not answer in `gaps`. Better to admit a gap',\n ' than fabricate.',\n '',\n 'When you finish, emit a single final structured message of the shape:',\n ' ```json',\n ' { \"items\": [{ \"id\": \"...\", \"namespace\": \"...\", \"claim\": \"...\",',\n ' \"evidence\": [{ \"source\": \"...\", \"quote\": \"...\",',\n ' \"url\": \"...\", \"capturedAt\": 0 }],',\n ' \"confidence\": 0.0,',\n ' \"authoredBy\": { \"kind\": \"agent\", \"id\": \"...\" } }],',\n ' \"citations\": [{ \"url\": \"...\", \"quote\": \"...\", \"confidence\": 0.0 }],',\n ' \"proposedWrites\": [{ \"kind\": \"insert\", \"namespace\": \"...\",',\n ' \"item\": { /* same shape as items[] */ } }],',\n ' \"gaps\": [\"...\"],',\n ' \"notes\": \"free-form commentary\" }',\n ' ```',\n].join('\\n')\n\nfunction formatResearcherPrompt(task: ResearchTask): string {\n const sources = task.sources?.length ? task.sources.join(', ') : '(no preference)'\n const window = formatRecencyWindow(task.recencyWindow)\n return [\n `Question: ${task.question}`,\n `Knowledge namespace (DO NOT cross): ${task.knowledgeNamespace}`,\n `Scope: ${task.scope ?? '(unspecified)'}`,\n `Preferred sources: ${sources}`,\n `Recency window: ${window}`,\n `Max items: ${task.maxItems ?? '(no cap)'}`,\n `Per-item minimum confidence: ${task.minConfidence ?? '(no floor)'}`,\n '',\n 'Produce knowledge items with provenance + citations + proposed writes.',\n 'List gaps for anything you could not answer. Emit the final JSON',\n 'result block exactly as instructed.',\n ].join('\\n')\n}\n\nfunction formatRecencyWindow(window: ResearchTask['recencyWindow']): string {\n if (!window) return '(none)'\n const since = window.since ? window.since.toISOString() : '-∞'\n const until = window.until ? window.until.toISOString() : 'now'\n return `${since} .. ${until}`\n}\n\n/**\n * Walk the event stream and return the last structured `research.result`\n * payload. Falls back to scanning text deltas for a fenced JSON block.\n */\nfunction parseResearcherEvents(events: SandboxEvent[]): ResearchOutput {\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]\n if (!event) continue\n const type = String(event.type ?? '')\n const data = isRecord(event.data) ? event.data : {}\n if (type === 'result' || type === 'final' || type === 'research.result') {\n const direct = coerceResearchOutput(data.result ?? data.output ?? data)\n // opencode reports the agent's terminal answer in `finalText` (not result/output).\n // Parse it too, and prefer it when `direct` is an all-empty shape — otherwise an\n // event carrying both `{items:[],citations:[],proposedWrites:[]}` and a rich\n // finalText would silently drop the real answer.\n const finalText = pickString(data.finalText)\n const fenced = finalText ? extractFencedJson(finalText) : undefined\n const fromFinalText = fenced ? coerceResearchOutput(fenced) : undefined\n if (direct && !isEmptyOutput(direct)) return direct\n if (fromFinalText) return fromFinalText\n if (direct) return direct\n }\n }\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]\n if (!event) continue\n const data = isRecord(event.data) ? event.data : {}\n const text = pickString(data.text) ?? pickString(data.delta) ?? pickString(data.finalText)\n if (!text) continue\n const fenced = extractFencedJson(text)\n if (!fenced) continue\n const coerced = coerceResearchOutput(fenced)\n if (coerced) return coerced\n }\n return { items: [], citations: [], proposedWrites: [] }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\n/** A coerced output that carries no items, citations, or proposed writes. */\nfunction isEmptyOutput(o: ResearchOutput): boolean {\n return o.items.length === 0 && o.citations.length === 0 && o.proposedWrites.length === 0\n}\n\nfunction pickString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction extractFencedJson(text: string): unknown | undefined {\n const match = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/i)\n if (!match) return undefined\n const body = (match[1] ?? '').trim()\n if (!body) return undefined\n try {\n return JSON.parse(body)\n } catch {\n return undefined\n }\n}\n\nfunction coerceResearchOutput(value: unknown): ResearchOutput | undefined {\n if (!isRecord(value)) return undefined\n const items = coerceItems(value.items)\n const citations = coerceCitations(value.citations)\n const proposedWrites = coerceProposedWrites(value.proposedWrites)\n // Reject completely empty payloads — those signal \"no result block\",\n // not \"a valid empty result\".\n if (items === undefined && citations === undefined && proposedWrites === undefined) {\n return undefined\n }\n const output: ResearchOutput = {\n items: items ?? [],\n citations: citations ?? [],\n proposedWrites: proposedWrites ?? [],\n }\n if (Array.isArray(value.gaps)) {\n output.gaps = value.gaps.filter((entry): entry is string => typeof entry === 'string')\n }\n const notes = pickString(value.notes)\n if (notes) output.notes = notes\n // Preserve any extra fields the agent emitted that don't fit the typed\n // surface — callers can inspect `raw` without forcing them through the\n // typed coercion. We only include `raw` when the agent emitted fields\n // beyond the known set.\n const known = new Set(['items', 'citations', 'proposedWrites', 'gaps', 'notes'])\n const extras: Record<string, unknown> = {}\n let extrasCount = 0\n for (const [key, val] of Object.entries(value)) {\n if (known.has(key)) continue\n extras[key] = val\n extrasCount += 1\n }\n if (extrasCount > 0) output.raw = extras\n return output\n}\n\nfunction coerceItems(value: unknown): KnowledgeItem[] | undefined {\n if (!Array.isArray(value)) return undefined\n const out: KnowledgeItem[] = []\n for (const entry of value) {\n if (!isRecord(entry)) continue\n const id = pickString(entry.id)\n const namespace = pickString(entry.namespace)\n const claim = pickString(entry.claim)\n const evidence = coerceEvidence(entry.evidence)\n const confidence = toFiniteNumber(entry.confidence)\n const authoredBy = coerceAuthoredBy(entry.authoredBy)\n if (!id || !namespace || !claim || !authoredBy) continue\n const item: KnowledgeItem = {\n id,\n namespace,\n claim,\n evidence,\n confidence: clamp01(confidence),\n authoredBy,\n }\n if (Array.isArray(entry.supersedes)) {\n item.supersedes = entry.supersedes.filter((s): s is string => typeof s === 'string')\n }\n const retractedAt = toFiniteNumber(entry.retractedAt)\n if (retractedAt > 0) item.retractedAt = retractedAt\n out.push(item)\n }\n return out\n}\n\nfunction coerceEvidence(value: unknown): KnowledgeItem['evidence'] {\n if (!Array.isArray(value)) return []\n const out: KnowledgeItem['evidence'] = []\n for (const entry of value) {\n if (!isRecord(entry)) continue\n const source = pickString(entry.source)\n if (!source) continue\n const item: KnowledgeItem['evidence'][number] = {\n source,\n capturedAt: toFiniteNumber(entry.capturedAt),\n }\n const quote = pickString(entry.quote)\n if (quote) item.quote = quote\n const url = pickString(entry.url)\n if (url) item.url = url\n out.push(item)\n }\n return out\n}\n\nfunction coerceAuthoredBy(value: unknown): KnowledgeItem['authoredBy'] | undefined {\n if (!isRecord(value)) return undefined\n const kind = value.kind === 'human' || value.kind === 'agent' ? value.kind : undefined\n const id = pickString(value.id)\n if (!kind || !id) return undefined\n return { kind, id }\n}\n\nfunction coerceCitations(value: unknown): ResearchOutput['citations'] | undefined {\n if (!Array.isArray(value)) return undefined\n const out: ResearchOutput['citations'] = []\n for (const entry of value) {\n if (!isRecord(entry)) continue\n const url = pickString(entry.url)\n const quote = pickString(entry.quote)\n if (!url || !quote) continue\n out.push({ url, quote, confidence: clamp01(toFiniteNumber(entry.confidence)) })\n }\n return out\n}\n\nfunction coerceProposedWrites(value: unknown): KnowledgeUpdate[] | undefined {\n if (!Array.isArray(value)) return undefined\n const out: KnowledgeUpdate[] = []\n for (const entry of value) {\n if (!isRecord(entry)) continue\n const namespace = pickString(entry.namespace)\n if (!namespace) continue\n if (entry.kind === 'insert') {\n const items = coerceItems([entry.item])\n const item = items?.[0]\n if (!item) continue\n out.push({ kind: 'insert', namespace, item })\n } else if (entry.kind === 'supersede') {\n const previousId = pickString(entry.previousId)\n const items = coerceItems([entry.item])\n const item = items?.[0]\n if (!previousId || !item) continue\n out.push({ kind: 'supersede', namespace, previousId, item })\n } else if (entry.kind === 'retract') {\n const itemId = pickString(entry.itemId)\n const reason = pickString(entry.reason)\n if (!itemId || !reason) continue\n out.push({ kind: 'retract', namespace, itemId, reason })\n }\n }\n return out\n}\n\nfunction toFiniteNumber(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : 0\n}\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0\n if (value < 0) return 0\n if (value > 1) return 1\n return value\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"researcher-CYmr4VJy.js","names":[],"sources":["../src/profiles/researcher.ts"],"sourcesContent":["/**\n * Opinionated preset for source-grounded research\n * tasks. The agent is told to:\n * - bound its work to a single `knowledgeNamespace`\n * - emit `items[]` carrying provenance + confidence\n * - emit `citations[]` linking quotes back to source urls\n * - emit `proposedWrites[]` — never call materialize itself\n * - describe `gaps` it could not answer\n *\n * The profile is stateless and agent-agnostic. The caller supplies the exact execution profile;\n * this preset adds only the researcher prompt, tools, parser, and validator.\n *\n * Propose-don't-apply: the profile NEVER writes to the knowledge base.\n * It produces `proposedWrites: KnowledgeUpdate[]` in the output. The\n * caller (gtm-agent, journey-eval, user) decides whether to feed those\n * updates through `applyKnowledgeWriteBlocks` / a KbStore put.\n *\n * Namespace isolation: every `KnowledgeItem` + `KnowledgeUpdate` in the\n * output carries `namespace`. The validator hard-fails when any item\n * touches a namespace other than `task.knowledgeNamespace`.\n *\n * @experimental\n */\n\nimport { type AgentProfile, agentProfileSchema } from '@tangle-network/agent-interface'\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport { ConfigError } from '../errors'\nimport { assertExecutableAgentProfile } from '../runtime/supervise/model-policy'\nimport type {\n AgentRunSpec,\n DefaultVerdict,\n Driver,\n OutputAdapter,\n Validator,\n} from '../runtime/types'\n\n/** Source families a researcher profile may prefer for a task. @experimental */\nexport type ResearchSource = 'web' | 'corpus' | 'twitter' | 'github' | 'docs'\n\n/** Task contract for a source-grounded research agent. @experimental */\nexport interface ResearchTask {\n /** The research question to answer. */\n question: string\n /** Bound: e.g. \"audience for cpg-founder ICP\". */\n scope?: string\n /** Multi-tenant scope (customer-id, workspace-id). Validator enforces. */\n knowledgeNamespace: string\n sources?: ResearchSource[]\n recencyWindow?: { since?: Date; until?: Date }\n maxItems?: number\n /** Per-item minimum confidence in [0, 1]. Validator scores recall vs this. */\n minConfidence?: number\n}\n\n/**\n * Knowledge item emitted by the researcher.\n *\n * Profile-local type. When agent-knowledge promotes `KnowledgeClaim` →\n * top-level `KnowledgeItem` substrate-wide, these fields collapse 1:1.\n *\n * @experimental\n */\nexport interface KnowledgeItem {\n id: string\n /** Multi-tenant scope. MUST equal `task.knowledgeNamespace`. */\n namespace: string\n /** The factual claim, in the researcher's words. */\n claim: string\n /** Provenance — at least one entry required. */\n evidence: Array<{ source: string; quote?: string; url?: string; capturedAt: number }>\n /** Researcher's self-reported confidence in [0, 1]. */\n confidence: number\n /** Prior item ids this supersedes (chain). */\n supersedes?: string[]\n /** Set if the agent is retracting an earlier item. Unix ms. */\n retractedAt?: number\n authoredBy: { kind: 'human' | 'agent'; id: string }\n}\n\n/**\n * A proposed write to the knowledge base. The profile does NOT apply\n * these — the caller decides.\n *\n * @experimental\n */\nexport type KnowledgeUpdate =\n | { kind: 'insert'; namespace: string; item: KnowledgeItem }\n | { kind: 'supersede'; namespace: string; previousId: string; item: KnowledgeItem }\n | { kind: 'retract'; namespace: string; itemId: string; reason: string }\n\n/**\n * Researcher output. Required fields are typed; optional fields preserve\n * the agent's free-form intelligence (`notes`, `raw`). The validator\n * enforces the typed minimum.\n *\n * @experimental\n */\nexport interface ResearchOutput {\n items: KnowledgeItem[]\n citations: Array<{ url: string; quote: string; confidence: number }>\n proposedWrites: KnowledgeUpdate[]\n gaps?: string[]\n notes?: string\n /** Anything the agent emitted beyond the typed fields. */\n raw?: unknown\n}\n\n/** Options for the source-grounded researcher profile preset. @experimental */\nexport interface ResearcherProfileOptions {\n /** Caller-owned exact harness/provider/model identity. */\n profile: AgentProfile\n /** Custom system prompt replacement. Default = built-in researcher preset. */\n systemPrompt?: string\n /** Stable name for `AgentRunSpec.name`. Default = `profile.name`. */\n name?: string\n /**\n * Default 0.7. Minimum (citations with quote) / items ratio for `valid=true`.\n * Below this floor, citation_density scores < 1 and the item set is gated.\n */\n citationDensityMin?: number\n}\n\nconst DEFAULT_CITATION_DENSITY_MIN = 0.7\n\n/** Build a source-grounded researcher profile with output parsing and validation. @experimental */\nexport function researcherProfile(options: ResearcherProfileOptions & { task?: ResearchTask }): {\n profile: AgentProfile\n taskToPrompt: (task: ResearchTask) => string\n output: OutputAdapter<ResearchOutput>\n validator: Validator<ResearchOutput>\n agentRunSpec: AgentRunSpec<ResearchTask>\n} {\n const base = agentProfileSchema.parse(options.profile) as AgentProfile\n assertExecutableAgentProfile(base, 'researcherProfile')\n const name = options.name ?? base.name\n const systemPrompt = options.systemPrompt ?? RESEARCHER_SYSTEM_PROMPT\n const citationDensityMin = options.citationDensityMin ?? DEFAULT_CITATION_DENSITY_MIN\n const profile: AgentProfile = {\n ...base,\n name,\n description: base.description ?? \"Source-grounded research agent. Propose-don't-apply.\",\n prompt: { ...base.prompt, systemPrompt },\n tools: { web_search: true, fs: true, shell: true, ...base.tools },\n metadata: { ...base.metadata, role: 'researcher' },\n }\n const output: OutputAdapter<ResearchOutput> = { parse: parseResearcherEvents }\n const validator: Validator<ResearchOutput> = options.task\n ? createResearcherValidator(options.task, { citationDensityMin })\n : createResearcherValidator(\n { question: '', knowledgeNamespace: '' },\n { citationDensityMin, namespaceCheck: false },\n )\n const agentRunSpec: AgentRunSpec<ResearchTask> = {\n name,\n profile,\n taskToPrompt: formatResearcherPrompt,\n }\n return { profile, taskToPrompt: formatResearcherPrompt, output, validator, agentRunSpec }\n}\n\n/** @experimental */\nexport interface MultiHarnessResearcherFanoutOptions {\n /** Exact execution profiles, one per parallel researcher. */\n profiles: ReadonlyArray<AgentProfile>\n /** Default citation density floor for the shared validator. */\n citationDensityMin?: number\n /** Optional task — narrows the validator's namespace check. */\n task?: ResearchTask\n}\n\n/**\n * Build a fanout topology over multiple harnesses. The kernel round-robins\n * `agentRuns` across the N parallel iterations and the `FanoutVote` driver\n * picks the highest-scoring valid output.\n *\n * @experimental\n */\nexport function multiHarnessResearcherFanout(options: MultiHarnessResearcherFanoutOptions): {\n agentRuns: AgentRunSpec<ResearchTask>[]\n output: OutputAdapter<ResearchOutput>\n validator: Validator<ResearchOutput>\n driver: Driver<ResearchTask, ResearchOutput, 'done'>\n} {\n if (options.profiles.length === 0) {\n throw new ConfigError('multiHarnessResearcherFanout: at least one exact profile is required')\n }\n const agentRuns = options.profiles.map((profile) => {\n const { agentRunSpec } = researcherProfile({ profile })\n return agentRunSpec\n })\n const { output, validator } = researcherProfile({\n profile: options.profiles[0]!,\n citationDensityMin: options.citationDensityMin,\n task: options.task,\n })\n // Single fanout round across the N harnesses, then stop: the kernel\n // round-robins `agentRuns` over the N branches and selects the winner\n // (best valid score) across all iterations via `defaultSelectWinner`.\n const driver: Driver<ResearchTask, ResearchOutput, 'done'> = {\n name: 'researcher-fanout',\n async plan(task, history) {\n return history.length === 0 ? Array.from({ length: agentRuns.length }, () => task) : []\n },\n // 'done' is a terminal decision in the kernel; the loop finalizes after\n // the single fanout round and selects the winner via `defaultSelectWinner`.\n decide() {\n return 'done'\n },\n describePlan() {\n return { kind: 'fanout' }\n },\n }\n return { agentRuns, output, validator, driver }\n}\n\n/**\n * Build a validator that closes over a specific `ResearchTask`'s constraints.\n *\n * Checks in order:\n * 1. Items must be non-empty.\n * 2. Every item carries `evidence.length >= 1`.\n * 3. Every item + proposedWrite is scoped to `task.knowledgeNamespace`\n * (hard-fail on any namespace mismatch — defence in depth for the\n * multi-tenant invariant).\n * 4. Citation density (citations with quote / items) >= floor.\n *\n * Aggregate score:\n * 0.4 · citation_density\n * + 0.2 · source_diversity (distinct sources / max(items, 1))\n * + 0.2 · recency_match (mean fraction within `recencyWindow`)\n * + 0.2 · (1 − gaps/maxGaps), maxGaps = max(items, 1)\n *\n * @experimental\n */\nexport function createResearcherValidator(\n task: ResearchTask,\n config: { citationDensityMin?: number; namespaceCheck?: boolean } = {},\n): Validator<ResearchOutput> {\n const citationDensityMin = config.citationDensityMin ?? DEFAULT_CITATION_DENSITY_MIN\n const namespaceCheck = config.namespaceCheck ?? true\n return {\n async validate(output) {\n const notes: string[] = []\n const scores: Record<string, number> = {}\n let pass = true\n\n if (!Array.isArray(output.items) || output.items.length === 0) {\n pass = false\n notes.push('no items')\n scores.items = 0\n } else {\n scores.items = 1\n }\n\n const missingEvidence = (output.items ?? []).filter(\n (item) => !Array.isArray(item.evidence) || item.evidence.length === 0,\n )\n if (missingEvidence.length > 0) {\n pass = false\n notes.push(`${missingEvidence.length} item(s) without evidence`)\n scores.provenance = 0\n } else {\n scores.provenance = 1\n }\n\n if (namespaceCheck) {\n const foreignItems = (output.items ?? []).filter(\n (item) => item.namespace !== task.knowledgeNamespace,\n )\n const foreignWrites = (output.proposedWrites ?? []).filter(\n (write) => write.namespace !== task.knowledgeNamespace,\n )\n if (foreignItems.length > 0 || foreignWrites.length > 0) {\n pass = false\n notes.push(\n `namespace violation: ${foreignItems.length} item(s) + ${foreignWrites.length} write(s) ` +\n `outside ${task.knowledgeNamespace}`,\n )\n scores.namespace = 0\n } else {\n scores.namespace = 1\n }\n }\n\n const itemCount = Math.max(output.items?.length ?? 0, 1)\n const citationsWithQuote = (output.citations ?? []).filter(\n (citation) => typeof citation.quote === 'string' && citation.quote.length > 0,\n ).length\n const citationDensity = Math.min(1, citationsWithQuote / itemCount)\n if (citationDensity < citationDensityMin) {\n pass = false\n notes.push(\n `citation density ${citationDensity.toFixed(2)} below floor ${citationDensityMin.toFixed(2)}`,\n )\n }\n scores.citation_density = citationDensity\n\n const sourceSet = new Set<string>()\n for (const item of output.items ?? []) {\n for (const evidence of item.evidence ?? []) {\n if (evidence.source) sourceSet.add(evidence.source)\n }\n }\n scores.source_diversity = Math.min(1, sourceSet.size / itemCount)\n\n scores.recency_match = recencyMatchScore(output.items ?? [], task.recencyWindow)\n\n const maxGaps = itemCount\n const gapCount = output.gaps?.length ?? 0\n scores.gap_coverage = Math.max(0, 1 - gapCount / maxGaps)\n\n const score =\n 0.4 * scores.citation_density +\n 0.2 * scores.source_diversity +\n 0.2 * scores.recency_match +\n 0.2 * scores.gap_coverage\n\n const verdict: DefaultVerdict = {\n valid: pass,\n score: Number.isFinite(score) ? score : 0,\n scores,\n }\n if (notes.length > 0) verdict.notes = notes.join('; ')\n return verdict\n },\n }\n}\n\nfunction recencyMatchScore(items: KnowledgeItem[], window: ResearchTask['recencyWindow']): number {\n if (!window || (window.since === undefined && window.until === undefined)) return 1\n if (items.length === 0) return 0\n const sinceMs = window.since?.getTime() ?? Number.NEGATIVE_INFINITY\n const untilMs = window.until?.getTime() ?? Number.POSITIVE_INFINITY\n let hits = 0\n let total = 0\n for (const item of items) {\n for (const evidence of item.evidence ?? []) {\n if (typeof evidence.capturedAt !== 'number') continue\n total += 1\n if (evidence.capturedAt >= sinceMs && evidence.capturedAt <= untilMs) hits += 1\n }\n }\n return total === 0 ? 0 : hits / total\n}\n\n/** Built-in source-grounded research contract added to a caller-owned exact profile. */\nexport const RESEARCHER_SYSTEM_PROMPT = [\n 'You are a research agent. Your job is to answer a research question with',\n 'source-grounded knowledge items that the caller will choose whether to',\n 'persist to a multi-tenant knowledge base.',\n '',\n 'Hard rules:',\n \" 1. Every item you emit MUST carry the task's knowledgeNamespace exactly.\",\n ' Never write to a different namespace.',\n ' 2. Every item MUST carry at least one evidence entry with a source.',\n ' A quote + url is strongly preferred; capturedAt is unix ms.',\n ' 3. You propose writes — you do NOT apply them. The caller decides.',\n ' 4. Self-report confidence honestly in [0, 1]. Do not inflate.',\n ' 5. List what you could not answer in `gaps`. Better to admit a gap',\n ' than fabricate.',\n '',\n 'When you finish, emit a single final structured message of the shape:',\n ' ```json',\n ' { \"items\": [{ \"id\": \"...\", \"namespace\": \"...\", \"claim\": \"...\",',\n ' \"evidence\": [{ \"source\": \"...\", \"quote\": \"...\",',\n ' \"url\": \"...\", \"capturedAt\": 0 }],',\n ' \"confidence\": 0.0,',\n ' \"authoredBy\": { \"kind\": \"agent\", \"id\": \"...\" } }],',\n ' \"citations\": [{ \"url\": \"...\", \"quote\": \"...\", \"confidence\": 0.0 }],',\n ' \"proposedWrites\": [{ \"kind\": \"insert\", \"namespace\": \"...\",',\n ' \"item\": { /* same shape as items[] */ } }],',\n ' \"gaps\": [\"...\"],',\n ' \"notes\": \"free-form commentary\" }',\n ' ```',\n].join('\\n')\n\nfunction formatResearcherPrompt(task: ResearchTask): string {\n const sources = task.sources?.length ? task.sources.join(', ') : '(no preference)'\n const window = formatRecencyWindow(task.recencyWindow)\n return [\n `Question: ${task.question}`,\n `Knowledge namespace (DO NOT cross): ${task.knowledgeNamespace}`,\n `Scope: ${task.scope ?? '(unspecified)'}`,\n `Preferred sources: ${sources}`,\n `Recency window: ${window}`,\n `Max items: ${task.maxItems ?? '(no cap)'}`,\n `Per-item minimum confidence: ${task.minConfidence ?? '(no floor)'}`,\n '',\n 'Produce knowledge items with provenance + citations + proposed writes.',\n 'List gaps for anything you could not answer. Emit the final JSON',\n 'result block exactly as instructed.',\n ].join('\\n')\n}\n\nfunction formatRecencyWindow(window: ResearchTask['recencyWindow']): string {\n if (!window) return '(none)'\n const since = window.since ? window.since.toISOString() : '-∞'\n const until = window.until ? window.until.toISOString() : 'now'\n return `${since} .. ${until}`\n}\n\n/**\n * Walk the event stream and return the last structured `research.result`\n * payload. Falls back to scanning text deltas for a fenced JSON block.\n */\nfunction parseResearcherEvents(events: SandboxEvent[]): ResearchOutput {\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]\n if (!event) continue\n const type = String(event.type ?? '')\n const data = isRecord(event.data) ? event.data : {}\n if (type === 'result' || type === 'final' || type === 'research.result') {\n const direct = coerceResearchOutput(data.result ?? data.output ?? data)\n // opencode reports the agent's terminal answer in `finalText` (not result/output).\n // Parse it too, and prefer it when `direct` is an all-empty shape — otherwise an\n // event carrying both `{items:[],citations:[],proposedWrites:[]}` and a rich\n // finalText would silently drop the real answer.\n const finalText = pickString(data.finalText)\n const fenced = finalText ? extractFencedJson(finalText) : undefined\n const fromFinalText = fenced ? coerceResearchOutput(fenced) : undefined\n if (direct && !isEmptyOutput(direct)) return direct\n if (fromFinalText) return fromFinalText\n if (direct) return direct\n }\n }\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]\n if (!event) continue\n const data = isRecord(event.data) ? event.data : {}\n const text = pickString(data.text) ?? pickString(data.delta) ?? pickString(data.finalText)\n if (!text) continue\n const fenced = extractFencedJson(text)\n if (!fenced) continue\n const coerced = coerceResearchOutput(fenced)\n if (coerced) return coerced\n }\n return { items: [], citations: [], proposedWrites: [] }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\n/** A coerced output that carries no items, citations, or proposed writes. */\nfunction isEmptyOutput(o: ResearchOutput): boolean {\n return o.items.length === 0 && o.citations.length === 0 && o.proposedWrites.length === 0\n}\n\nfunction pickString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction extractFencedJson(text: string): unknown | undefined {\n const match = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/i)\n if (!match) return undefined\n const body = (match[1] ?? '').trim()\n if (!body) return undefined\n try {\n return JSON.parse(body)\n } catch {\n return undefined\n }\n}\n\nfunction coerceResearchOutput(value: unknown): ResearchOutput | undefined {\n if (!isRecord(value)) return undefined\n const items = coerceItems(value.items)\n const citations = coerceCitations(value.citations)\n const proposedWrites = coerceProposedWrites(value.proposedWrites)\n // Reject completely empty payloads — those signal \"no result block\",\n // not \"a valid empty result\".\n if (items === undefined && citations === undefined && proposedWrites === undefined) {\n return undefined\n }\n const output: ResearchOutput = {\n items: items ?? [],\n citations: citations ?? [],\n proposedWrites: proposedWrites ?? [],\n }\n if (Array.isArray(value.gaps)) {\n output.gaps = value.gaps.filter((entry): entry is string => typeof entry === 'string')\n }\n const notes = pickString(value.notes)\n if (notes) output.notes = notes\n // Preserve any extra fields the agent emitted that don't fit the typed\n // surface — callers can inspect `raw` without forcing them through the\n // typed coercion. We only include `raw` when the agent emitted fields\n // beyond the known set.\n const known = new Set(['items', 'citations', 'proposedWrites', 'gaps', 'notes'])\n const extras: Record<string, unknown> = {}\n let extrasCount = 0\n for (const [key, val] of Object.entries(value)) {\n if (known.has(key)) continue\n extras[key] = val\n extrasCount += 1\n }\n if (extrasCount > 0) output.raw = extras\n return output\n}\n\nfunction coerceItems(value: unknown): KnowledgeItem[] | undefined {\n if (!Array.isArray(value)) return undefined\n const out: KnowledgeItem[] = []\n for (const entry of value) {\n if (!isRecord(entry)) continue\n const id = pickString(entry.id)\n const namespace = pickString(entry.namespace)\n const claim = pickString(entry.claim)\n const evidence = coerceEvidence(entry.evidence)\n const confidence = toFiniteNumber(entry.confidence)\n const authoredBy = coerceAuthoredBy(entry.authoredBy)\n if (!id || !namespace || !claim || !authoredBy) continue\n const item: KnowledgeItem = {\n id,\n namespace,\n claim,\n evidence,\n confidence: clamp01(confidence),\n authoredBy,\n }\n if (Array.isArray(entry.supersedes)) {\n item.supersedes = entry.supersedes.filter((s): s is string => typeof s === 'string')\n }\n const retractedAt = toFiniteNumber(entry.retractedAt)\n if (retractedAt > 0) item.retractedAt = retractedAt\n out.push(item)\n }\n return out\n}\n\nfunction coerceEvidence(value: unknown): KnowledgeItem['evidence'] {\n if (!Array.isArray(value)) return []\n const out: KnowledgeItem['evidence'] = []\n for (const entry of value) {\n if (!isRecord(entry)) continue\n const source = pickString(entry.source)\n if (!source) continue\n const item: KnowledgeItem['evidence'][number] = {\n source,\n capturedAt: toFiniteNumber(entry.capturedAt),\n }\n const quote = pickString(entry.quote)\n if (quote) item.quote = quote\n const url = pickString(entry.url)\n if (url) item.url = url\n out.push(item)\n }\n return out\n}\n\nfunction coerceAuthoredBy(value: unknown): KnowledgeItem['authoredBy'] | undefined {\n if (!isRecord(value)) return undefined\n const kind = value.kind === 'human' || value.kind === 'agent' ? value.kind : undefined\n const id = pickString(value.id)\n if (!kind || !id) return undefined\n return { kind, id }\n}\n\nfunction coerceCitations(value: unknown): ResearchOutput['citations'] | undefined {\n if (!Array.isArray(value)) return undefined\n const out: ResearchOutput['citations'] = []\n for (const entry of value) {\n if (!isRecord(entry)) continue\n const url = pickString(entry.url)\n const quote = pickString(entry.quote)\n if (!url || !quote) continue\n out.push({ url, quote, confidence: clamp01(toFiniteNumber(entry.confidence)) })\n }\n return out\n}\n\nfunction coerceProposedWrites(value: unknown): KnowledgeUpdate[] | undefined {\n if (!Array.isArray(value)) return undefined\n const out: KnowledgeUpdate[] = []\n for (const entry of value) {\n if (!isRecord(entry)) continue\n const namespace = pickString(entry.namespace)\n if (!namespace) continue\n if (entry.kind === 'insert') {\n const items = coerceItems([entry.item])\n const item = items?.[0]\n if (!item) continue\n out.push({ kind: 'insert', namespace, item })\n } else if (entry.kind === 'supersede') {\n const previousId = pickString(entry.previousId)\n const items = coerceItems([entry.item])\n const item = items?.[0]\n if (!previousId || !item) continue\n out.push({ kind: 'supersede', namespace, previousId, item })\n } else if (entry.kind === 'retract') {\n const itemId = pickString(entry.itemId)\n const reason = pickString(entry.reason)\n if (!itemId || !reason) continue\n out.push({ kind: 'retract', namespace, itemId, reason })\n }\n }\n return out\n}\n\nfunction toFiniteNumber(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : 0\n}\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0\n if (value < 0) return 0\n if (value > 1) return 1\n return value\n}\n"],"mappings":"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"}
@@ -1,18 +1,18 @@
1
1
  import { n as AnalystError, s as PlannerError, u as ValidationError } from "./errors-DEAvWQPy.js";
2
- import "./stream-agent-turn-rYgaOLO0.js";
2
+ import "./stream-agent-turn-DE8_alvm.js";
3
3
  import { i as InMemorySpawnJournal, r as InMemoryResultBlobStore, v as isTraceAnalysisStore, x as contentAddress } from "./spawn-journal-saHQzqYi.js";
4
4
  import { a as randomSuffix, c as stringifySafe, f as zeroTokenUsage, r as isAbortError, s as sleep, t as addTokenUsage } from "./util-Bw6srryQ.js";
5
5
  import { i as redactProtectedValue, r as redactProtectedReason } from "./protected-redaction--F3v1oo8.js";
6
6
  import { a as notifySandboxEventObserver } from "./sandbox-events-CRDwc5WN.js";
7
- import { c as profileProviderModel, i as concreteModelId, s as profileModelExecutionSettings, t as assertExecutableAgentProfile } from "./model-policy-CqziaqS1.js";
8
- import { v as executableAgentProfileSnapshot, y as executableAgentSpecSnapshot } from "./materialization-COJ1UYQ-.js";
9
- import { $ as createSandboxLineage, I as createWorktreeCliExecutor, N as createExecutor, P as createExecutorRegistry, Q as runAgentRounds, U as createPushTraceSource, Z as defaultSelectWinner, et as probeSandboxCapabilities, l as withDriverExecutor, m as settledToIteration, n as createSupervisor, nt as routerBrain, rt as runBrainLoop, w as rollingDispatch } from "./supervisor-D4G47raS.js";
7
+ import { c as profileProviderModel, i as concreteModelId, s as profileModelExecutionSettings, t as assertExecutableAgentProfile } from "./model-policy-mWSoToiQ.js";
8
+ import { v as executableAgentProfileSnapshot, y as executableAgentSpecSnapshot } from "./materialization-DBXuH34A.js";
9
+ import { $ as createSandboxLineage, I as createWorktreeCliExecutor, N as createExecutor, P as createExecutorRegistry, Q as runAgentRounds, U as createPushTraceSource, Z as defaultSelectWinner, et as probeSandboxCapabilities, l as withDriverExecutor, m as settledToIteration, n as createSupervisor, nt as routerBrain, rt as runBrainLoop, w as rollingDispatch } from "./supervisor-C16p9KqO.js";
10
10
  import "./environment-provider-Dyg8DtLK.js";
11
11
  import { i as notifyRuntimeHookEvent } from "./runtime-hooks-C7iJOWm3.js";
12
- import { C as observe, O as strategyAuthorMethod, T as profileChatClient, b as sample, v as refine, x as sampleThenRefine, y as runAgentic } from "./structural-rollout-UO3ue9OI.js";
13
- import { It as gateOnDeliverable, Lt as mapExecutorResult, n as supervise } from "./supervise-BVNSL3N0.js";
14
- import "./authoring-tkyJHE0o.js";
15
- import "./graph-RVorX4TM.js";
12
+ import { C as observe, O as strategyAuthorMethod, T as profileChatClient, b as sample, v as refine, x as sampleThenRefine, y as runAgentic } from "./structural-rollout-n089ZP33.js";
13
+ import { It as gateOnDeliverable, Lt as mapExecutorResult, n as supervise } from "./supervise-msTRhTN7.js";
14
+ import "./authoring-DI778qK7.js";
15
+ import "./graph-CoN60QtH.js";
16
16
  import { CODING_HARNESSES, InMemoryTraceStore, OUTPUT_VALUE, benjaminiHochberg, buildTrajectory, computeFindingId as computeFindingId$1, confidenceInterval, expandProfileAxes, makeFinding as makeFinding$1, pairedBootstrap, paretoFrontier, wilcoxonSignedRank, wilson } from "@tangle-network/agent-eval";
17
17
  import { heldoutSignificance, runProfileMatrix } from "@tangle-network/agent-eval/campaign";
18
18
  import { agentProfileSchema, canonicalAgentProfileDigest, validateAgentProfileSecurity } from "@tangle-network/agent-interface";
@@ -5627,4 +5627,4 @@ function tail(s) {
5627
5627
  //#endregion
5628
5628
  export { pipeline as $, assertStrategyContract as A, createMcpEnvironment as At, trajectoryReport as B, chatTransportExecutor as C, renderLeaderboardSvg as Ct, pickChampion as D, McpSpawnFault as Dt, discriminatingMeans as E, defaultAuditorInstruction as Et, openSandboxRun as F, resolveSecretEnv as Ft, registerShape as G, runPersonified as H, printBenchmarkReport as I, secretEnvOfMcpServer as It, renderCorpusToInstructions as J, FileCorpus as K, runBenchmark as L, strategyAuthorContract as M, envKeyProvider as Mt, strategyAuthorSystemPrompt as N, mcpSecretEnvMetadataKey as Nt, runStrategyEvolution as O, connectStdioMcp as Ot, SandboxRunAbortError as P, resolveMcpServerLaunch as Pt, panel as Q, promotionGate as R, runCoderChecks as S, renderLeaderboardMarkdown as St, createChatSessionStore as T, auditIntent as Tt, builtinShapes as U, definePersona as V, createShapeRegistry as W, flatWidenGate as X, fanout as Y, loopUntil as Z, settledWorkerOut as _, sentinelCompletion as _t, localShell as a, createScopeAnalyst as at, analyzeTrace as b, pairwiseSignificance as bt, createVerifierEnvironment as c, harvestCorpus as ct, worktreeFanout as d, localSandboxClient as dt, selectValidWinner as et, EVIDENCE_MAX_CHARS as f, inlineSandboxClient as ft, composeWorkerEvidence as g, deterministicCompletion as gt, closingWorkerNote as h, completionAuthorizes as ht, jjWorkspace as i, buildSteerContext as it, authorStrategy as j, sanitizeMcpToolSchema as jt, selectChampion as k, materializeLocalMcp as kt, failuresAnalyst as l, defineLeaderboard as lt, VERIFY_TAIL_CHARS as m, loopDispatch as mt, makeFinding$1 as n, widen as nt, runInWorkspace as o, registryScopeAnalyst as ot, NOTE_MAX_CHARS as p, loopCampaignDispatch as pt, InMemoryCorpus as q, gitWorkspace as r, assertTraceDerivedFindings as rt, createWaterfallCollector as s, inProcessSandboxClient as st, computeFindingId$1 as t, verify as tt, superviseSurface as u, resolveSandboxClient as ut, copyUntrackedIntoClone as v, stopSentinel as vt, chatWorkerSeam as w, renderPairwiseMarkdown as wt, patchDelivered as x, renderLeaderboardHtml as xt, withUntrackedArtifacts as y, leaderboard as yt, equalKOnCost as z };
5629
5629
 
5630
- //# sourceMappingURL=runtime-B4z0Z1sM.js.map
5630
+ //# sourceMappingURL=runtime-ZNVnT8h1.js.map