@tangle-network/agent-runtime 0.168.0 → 0.170.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import { at as canonicalCandidateDocument, ct as immutableCandidateValue, dt as verifyCanonicalCandidateDocument, it as canonicalCandidateDigest$1 } from "./prepare-BAyaNoZu.js";
2
- import { A as agentImprovementTargetInput, M as agentProfileImprovementStateDigest, c as requireSealedCandidateExperiment, d as verifyAgentImprovementActivation, f as verifyAgentImprovementProposal, k as agentImprovementTargetDigest } from "./improvement-cycle-BAKN_f4x.js";
2
+ import { A as agentImprovementTargetInput, M as agentProfileImprovementStateDigest, c as requireSealedCandidateExperiment, d as verifyAgentImprovementActivation, f as verifyAgentImprovementProposal, k as agentImprovementTargetDigest } from "./improvement-cycle-BYCnKZ_G.js";
3
3
  import { agentImprovementActivationResultSchema, agentImprovementActivationSchema, agentProfileImprovementExperimentSchema } from "@tangle-network/agent-interface";
4
4
  //#region src/intelligence/activation.ts
5
5
  /** Create the exact result a product stores in the same transaction as its target write. */
@@ -201,4 +201,4 @@ function targetIdentity(target) {
201
201
  //#endregion
202
202
  export { executeAgentImprovementActivation as n, verifyAgentImprovementActivationResult as r, createAgentImprovementActivationResult as t };
203
203
 
204
- //# sourceMappingURL=activation-CIwer0zU.js.map
204
+ //# sourceMappingURL=activation-8RxHIo02.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"activation-CIwer0zU.js","names":["canonicalCandidateDigest"],"sources":["../src/intelligence/activation.ts"],"sourcesContent":["import type {\n AgentCandidateBundle,\n AgentCandidateExperiment,\n AgentImprovementActivation,\n AgentImprovementActivationOutcome,\n AgentImprovementActivationResult,\n AgentImprovementActivationTarget,\n AgentImprovementProposal,\n AgentImprovementReview,\n AgentImprovementSurface,\n AgentProfileImprovementChange,\n AgentProfileImprovementExperiment,\n Sha256Digest,\n} from '@tangle-network/agent-interface'\nimport {\n agentImprovementActivationResultSchema,\n agentImprovementActivationSchema,\n agentProfileImprovementExperimentSchema,\n} from '@tangle-network/agent-interface'\n\nimport {\n canonicalCandidateDigest,\n canonicalCandidateDocument,\n immutableCandidateValue,\n verifyCanonicalCandidateDocument,\n} from '../candidate-execution/digest'\nimport {\n requireSealedCandidateExperiment,\n verifyAgentImprovementActivation,\n verifyAgentImprovementProposal,\n} from './improvement-cycle'\nimport {\n agentImprovementTargetDigest,\n agentImprovementTargetInput,\n agentProfileImprovementStateDigest,\n} from './improvement-surfaces'\n\nexport interface CreateAgentImprovementActivationResultOptions {\n completedAt: string\n outcome: AgentImprovementActivationOutcome\n}\n\nexport interface AgentImprovementActivationTargetPlan extends AgentImprovementActivationTarget {\n desiredDigest: Sha256Digest\n /**\n * Exact measured input the product must apply to reach `desiredDigest`.\n * Transition surfaces such as code and knowledge are applied operations, so\n * their resulting state digest is not the digest of this input document.\n */\n desiredInput: unknown\n}\n\nexport type AgentProfileImprovementActivationOperation =\n | {\n kind: 'apply-change'\n changes: AgentProfileImprovementChange\n }\n | {\n /** The product must load its own saved state at `desiredStateDigest`. */\n kind: 'restore-state'\n }\n\nexport interface AgentProfileImprovementActivationTargetPlan\n extends AgentImprovementActivationTarget {\n desiredDigest: Sha256Digest\n desiredInput: AgentProfileImprovementActivationOperation\n}\n\nexport interface SealedCandidateActivationTransitionInput {\n kind: 'sealed-candidate'\n activation: AgentImprovementActivation\n candidateBundle: AgentCandidateBundle\n bundle: AgentCandidateBundle\n targets: [AgentImprovementActivationTargetPlan, ...AgentImprovementActivationTargetPlan[]]\n attemptedAt: string\n expired: boolean\n}\n\n/**\n * A measured profile change without raw profile bytes.\n * The product owns the private state lookup and atomic write.\n */\nexport interface ProfileImprovementActivationTransitionInput {\n kind: 'profile-improvement'\n activation: AgentImprovementActivation\n experiment: AgentProfileImprovementExperiment\n sourceStateDigest: Sha256Digest\n desiredStateDigest: Sha256Digest\n operation: AgentProfileImprovementActivationOperation\n targets: [\n AgentProfileImprovementActivationTargetPlan,\n ...AgentProfileImprovementActivationTargetPlan[],\n ]\n attemptedAt: string\n expired: boolean\n}\n\nexport type AgentImprovementActivationTransitionInput =\n | SealedCandidateActivationTransitionInput\n | ProfileImprovementActivationTransitionInput\n\nexport interface AgentImprovementActivationResultStore {\n load(idempotencyKey: Sha256Digest): Promise<unknown | undefined>\n putIfAbsent(result: AgentImprovementActivationResult): Promise<unknown>\n}\n\n/**\n * Product-owned or Runtime-composed transition.\n *\n * Implementations resolve a stored result for `activation.digest`, compare\n * every target, and make the write durably idempotent. Co-located targets store\n * the all-or-none write with its result. Other targets throw when result\n * storage fails so a retry can reconcile it. Runtime never invokes this write\n * function after authorization expires.\n */\nexport type AgentImprovementActivationTransition = (\n input: AgentImprovementActivationTransitionInput,\n) => Promise<unknown>\n\n/**\n * Target-read-only check for a prior exact write.\n * It may persist recovered result metadata, but must not change an activation target.\n * Return undefined only when no target write can have committed.\n */\nexport type AgentImprovementActivationReconciliation = (\n input: AgentImprovementActivationTransitionInput,\n) => Promise<unknown | undefined>\n\nexport interface ExecuteAgentImprovementActivationInput {\n proposal: AgentImprovementProposal\n review: AgentImprovementReview\n activation: AgentImprovementActivation\n}\n\nexport interface ExecuteAgentImprovementActivationOptions {\n transition: AgentImprovementActivationTransition\n reconcile?: AgentImprovementActivationReconciliation\n now?: () => Date\n}\n\n/** Create the exact result a product stores in the same transaction as its target write. */\nexport function createAgentImprovementActivationResult(\n transition: AgentImprovementActivationTransitionInput,\n options: CreateAgentImprovementActivationResultOptions,\n): AgentImprovementActivationResult {\n const activation = verifyCanonicalCandidateDocument(\n agentImprovementActivationSchema.parse(transition.activation),\n 'agent improvement activation',\n )\n assertTransitionInput(activation, transition)\n const result = agentImprovementActivationResultSchema.parse(\n canonicalCandidateDocument<AgentImprovementActivationResult>({\n kind: 'agent-improvement-activation-result',\n idempotencyKey: activation.digest,\n attemptedAt: transition.attemptedAt,\n completedAt: options.completedAt,\n outcome: options.outcome,\n }).value,\n )\n assertResultAgainstActivation(activation, result)\n assertOutcomeDesiredState(\n activation,\n result,\n new Map(transition.targets.map((target) => [targetIdentity(target), target.desiredDigest])),\n )\n return immutableCandidateValue(result)\n}\n\n/**\n * Recompute one historical activation result against the exact measured proposal and authority.\n * The result records that attempt; it is not a query of the target's current state.\n */\nexport function verifyAgentImprovementActivationResult(input: {\n proposal: unknown\n review: unknown\n activation: unknown\n result: unknown\n}): AgentImprovementActivationResult {\n const proposal = verifyAgentImprovementProposal(input.proposal)\n const activation = verifyAgentImprovementActivation(input)\n const result = verifyCanonicalCandidateDocument(\n agentImprovementActivationResultSchema.parse(input.result),\n 'agent improvement activation result',\n )\n assertResultAgainstActivation(activation, result)\n assertResultDesiredState(proposal, activation, result)\n return result\n}\n\n/** Validate and execute one product-owned activation transition. */\nexport async function executeAgentImprovementActivation(\n input: ExecuteAgentImprovementActivationInput,\n options: ExecuteAgentImprovementActivationOptions,\n): Promise<AgentImprovementActivationResult> {\n const proposal = verifyAgentImprovementProposal(input.proposal)\n const activation = verifyAgentImprovementActivation(input)\n const observedAt = (options.now ?? (() => new Date()))().toISOString()\n const attemptedAt =\n Date.parse(observedAt) < Date.parse(activation.authorizedAt)\n ? activation.authorizedAt\n : observedAt\n const expired = Date.parse(attemptedAt) >= Date.parse(activation.expiresAt)\n const transition = immutableCandidateValue<AgentImprovementActivationTransitionInput>(\n proposal.evaluation.kind === 'agent-improvement-measured-comparison'\n ? sealedCandidateTransition(proposal.evaluation.experiment, activation, attemptedAt, expired)\n : profileImprovementTransition(\n proposal.evaluation.experiment,\n activation,\n attemptedAt,\n expired,\n ),\n )\n\n if (transition.expired) {\n if (!options.reconcile) {\n return uncertainActivationResult(transition, 'RECONCILIATION_UNAVAILABLE')\n }\n let reconciled: unknown\n try {\n reconciled = await options.reconcile(transition)\n } catch {\n return uncertainActivationResult(transition, 'RECONCILIATION_THROW')\n }\n if (reconciled === undefined) {\n return createAgentImprovementActivationResult(transition, {\n completedAt: transition.attemptedAt,\n outcome: { status: 'expired' },\n })\n }\n try {\n return verifyAgentImprovementActivationResult({ ...input, result: reconciled })\n } catch {\n return uncertainActivationResult(transition, 'INVALID_RECONCILIATION')\n }\n }\n\n let rawResult: unknown\n try {\n rawResult = await options.transition(transition)\n } catch {\n return uncertainActivationResult(transition, 'TRANSITION_THROW')\n }\n try {\n return verifyAgentImprovementActivationResult({ ...input, result: rawResult })\n } catch {\n return uncertainActivationResult(transition, 'INVALID_RESULT')\n }\n}\n\nfunction sealedCandidateTransition(\n experiment: AgentCandidateExperiment,\n activation: AgentImprovementActivation,\n attemptedAt: string,\n expired: boolean,\n): SealedCandidateActivationTransitionInput {\n const targetArm = activation.intent === 'activate-candidate' ? 'candidate' : 'baseline'\n return {\n kind: 'sealed-candidate',\n activation,\n candidateBundle: experiment.candidate,\n bundle: experiment[targetArm],\n targets: activation.targets.map((target) => ({\n ...target,\n desiredDigest: agentImprovementTargetDigest(experiment, targetArm, target.surface),\n desiredInput: agentImprovementTargetInput(experiment[targetArm], target.surface),\n })) as SealedCandidateActivationTransitionInput['targets'],\n attemptedAt,\n expired,\n }\n}\n\nfunction profileImprovementTransition(\n experiment: AgentProfileImprovementExperiment,\n activation: AgentImprovementActivation,\n attemptedAt: string,\n expired: boolean,\n): ProfileImprovementActivationTransitionInput {\n const sourceArm = activation.intent === 'activate-candidate' ? 'baseline' : 'candidate'\n const targetArm = activation.intent === 'activate-candidate' ? 'candidate' : 'baseline'\n const operation = profileImprovementOperation(experiment, activation.intent)\n return {\n kind: 'profile-improvement',\n activation,\n experiment,\n sourceStateDigest: agentProfileImprovementStateDigest(experiment, sourceArm),\n desiredStateDigest: agentProfileImprovementStateDigest(experiment, targetArm),\n operation,\n targets: activation.targets.map((target) => ({\n ...target,\n desiredDigest: agentProfileImprovementStateDigest(experiment, targetArm),\n desiredInput: operation,\n })) as ProfileImprovementActivationTransitionInput['targets'],\n attemptedAt,\n expired,\n }\n}\n\nfunction profileImprovementOperation(\n experiment: AgentProfileImprovementExperiment,\n intent: AgentImprovementActivation['intent'],\n): AgentProfileImprovementActivationOperation {\n return intent === 'activate-candidate'\n ? { kind: 'apply-change', changes: experiment.change }\n : { kind: 'restore-state' }\n}\n\nfunction uncertainActivationResult(\n transition: AgentImprovementActivationTransitionInput,\n code: string,\n): AgentImprovementActivationResult {\n return createAgentImprovementActivationResult(transition, {\n completedAt: transition.attemptedAt,\n outcome: {\n status: 'indeterminate',\n code,\n message: 'The product transition did not return a trustworthy commit result.',\n },\n })\n}\n\nfunction assertTransitionInput(\n activation: AgentImprovementActivation,\n transition: AgentImprovementActivationTransitionInput,\n): void {\n if (transition.kind === 'sealed-candidate') {\n assertSealedCandidateTransitionInput(activation, transition)\n return\n }\n assertProfileImprovementTransitionInput(activation, transition)\n}\n\nfunction assertSealedCandidateTransitionInput(\n activation: AgentImprovementActivation,\n transition: SealedCandidateActivationTransitionInput,\n): void {\n assertAuthorizedTransitionTargets(activation, transition.targets)\n const desiredInputsMatch = transition.targets.every(\n (target) =>\n canonicalCandidateDigest(target.desiredInput) ===\n canonicalCandidateDigest(agentImprovementTargetInput(transition.bundle, target.surface)),\n )\n if (\n transition.expired !== Date.parse(transition.attemptedAt) >= Date.parse(activation.expiresAt) ||\n transition.candidateBundle.digest !== activation.candidateDigest ||\n !desiredInputsMatch ||\n (activation.intent === 'activate-candidate' &&\n transition.bundle.digest !== transition.candidateBundle.digest)\n ) {\n throw new Error('activation transition does not match its authorization')\n }\n}\n\nfunction assertProfileImprovementTransitionInput(\n activation: AgentImprovementActivation,\n transition: ProfileImprovementActivationTransitionInput,\n): void {\n assertAuthorizedTransitionTargets(activation, transition.targets)\n const targetsAgentProfile = activation.targets.some(\n (target) => target.surface === 'agent-profile',\n )\n const experiment = agentProfileImprovementExperimentSchema.parse(transition.experiment)\n const sourceArm = activation.intent === 'activate-candidate' ? 'baseline' : 'candidate'\n const targetArm = activation.intent === 'activate-candidate' ? 'candidate' : 'baseline'\n const sourceStateDigest = agentProfileImprovementStateDigest(experiment, sourceArm)\n const desiredStateDigest = agentProfileImprovementStateDigest(experiment, targetArm)\n const operation = profileImprovementOperation(experiment, activation.intent)\n const targetsMatch = transition.targets.every(\n (target) =>\n target.expectedBaseDigest === sourceStateDigest &&\n target.desiredDigest === desiredStateDigest &&\n canonicalCandidateDigest(target.desiredInput) === canonicalCandidateDigest(operation),\n )\n if (\n transition.expired !== Date.parse(transition.attemptedAt) >= Date.parse(activation.expiresAt) ||\n experiment.digest !== activation.experimentDigest ||\n experiment.candidate.stateDigest !== activation.candidateDigest ||\n (targetsAgentProfile &&\n (activation.executionRef === undefined ||\n canonicalCandidateDigest(activation.executionRef) !==\n canonicalCandidateDigest(experiment.executionRef))) ||\n transition.sourceStateDigest !== sourceStateDigest ||\n transition.desiredStateDigest !== desiredStateDigest ||\n canonicalCandidateDigest(transition.operation) !== canonicalCandidateDigest(operation) ||\n !targetsMatch\n ) {\n throw new Error('activation transition does not match its authorization')\n }\n}\n\nfunction assertAuthorizedTransitionTargets(\n activation: AgentImprovementActivation,\n targets: readonly AgentImprovementActivationTargetPlan[],\n): void {\n const authorized = targetMap(activation.targets)\n const planned = targetMap(targets)\n if (\n authorized.size !== planned.size ||\n [...authorized.entries()].some(\n ([identity, target]) =>\n planned.get(identity)?.expectedBaseDigest !== target.expectedBaseDigest,\n )\n ) {\n throw new Error('activation transition does not match its authorization')\n }\n}\n\nfunction assertResultAgainstActivation(\n activation: AgentImprovementActivation,\n result: AgentImprovementActivationResult,\n): void {\n const attemptedAt = Date.parse(result.attemptedAt)\n const completedAt = Date.parse(result.completedAt)\n const expiresAt = Date.parse(activation.expiresAt)\n if (\n result.idempotencyKey !== activation.digest ||\n attemptedAt < Date.parse(activation.authorizedAt) ||\n completedAt < attemptedAt\n ) {\n throw new Error('activation result does not bind its authorization')\n }\n const expired = attemptedAt >= expiresAt\n if (\n (result.outcome.status === 'expired' && !expired) ||\n (expired && !['expired', 'indeterminate', 'already-applied'].includes(result.outcome.status))\n ) {\n throw new Error('activation result does not honor its authorization expiry')\n }\n if (!('targets' in result.outcome)) return\n const authorized = targetMap(activation.targets)\n const observed = new Set(result.outcome.targets.map(targetIdentity))\n if (\n authorized.size !== observed.size ||\n [...authorized.keys()].some((identity) => !observed.has(identity))\n ) {\n throw new Error('activation result must cover every authorized target exactly once')\n }\n if (\n result.outcome.status === 'applied' &&\n result.outcome.targets.some(\n (target) =>\n target.beforeDigest !== authorized.get(targetIdentity(target))?.expectedBaseDigest,\n )\n ) {\n throw new Error('applied activation did not start from its authorized base state')\n }\n}\n\nfunction assertResultDesiredState(\n proposal: AgentImprovementProposal,\n activation: AgentImprovementActivation,\n result: AgentImprovementActivationResult,\n): void {\n if (!('targets' in result.outcome)) return\n const targetArm = activation.intent === 'activate-candidate' ? 'candidate' : 'baseline'\n const desiredStateDigest =\n proposal.evaluation.kind === 'agent-profile-improvement-measured-comparison'\n ? agentProfileImprovementStateDigest(proposal.evaluation.experiment, targetArm)\n : undefined\n const desired = new Map(\n activation.targets.map((target) => [\n targetIdentity(target),\n desiredStateDigest ??\n agentImprovementTargetDigest(\n requireSealedCandidateExperiment(proposal),\n targetArm,\n target.surface,\n ),\n ]),\n )\n assertOutcomeDesiredState(activation, result, desired)\n}\n\nfunction assertOutcomeDesiredState(\n activation: AgentImprovementActivation,\n result: AgentImprovementActivationResult,\n desired: ReadonlyMap<string, Sha256Digest>,\n): void {\n if (!('targets' in result.outcome)) return\n if (result.outcome.status === 'applied') {\n if (\n result.outcome.targets.some(\n (target) => target.afterDigest !== desired.get(targetIdentity(target)),\n )\n ) {\n throw new Error('applied activation does not match the requested bundle')\n }\n return\n }\n const allDesired = result.outcome.targets.every(\n (target) => target.currentDigest === desired.get(targetIdentity(target)),\n )\n if (result.outcome.status === 'already-applied') {\n if (!allDesired) throw new Error('already-applied activation is not at the requested state')\n return\n }\n const authorized = targetMap(activation.targets)\n const hasStaleTarget = result.outcome.targets.some(\n (target) => target.currentDigest !== authorized.get(targetIdentity(target))?.expectedBaseDigest,\n )\n if (allDesired || !hasStaleTarget) {\n throw new Error('activation conflict does not identify stale target state')\n }\n}\n\nfunction targetMap<T extends { surface: AgentImprovementSurface; identity: string }>(\n targets: readonly T[],\n): Map<string, T> {\n return new Map(targets.map((target) => [targetIdentity(target), target]))\n}\n\nfunction targetIdentity(target: { surface: AgentImprovementSurface; identity: string }): string {\n return `${target.surface}\\u0000${target.identity}`\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"activation-8RxHIo02.js","names":["canonicalCandidateDigest"],"sources":["../src/intelligence/activation.ts"],"sourcesContent":["import type {\n AgentCandidateBundle,\n AgentCandidateExperiment,\n AgentImprovementActivation,\n AgentImprovementActivationOutcome,\n AgentImprovementActivationResult,\n AgentImprovementActivationTarget,\n AgentImprovementProposal,\n AgentImprovementReview,\n AgentImprovementSurface,\n AgentProfileImprovementChange,\n AgentProfileImprovementExperiment,\n Sha256Digest,\n} from '@tangle-network/agent-interface'\nimport {\n agentImprovementActivationResultSchema,\n agentImprovementActivationSchema,\n agentProfileImprovementExperimentSchema,\n} from '@tangle-network/agent-interface'\n\nimport {\n canonicalCandidateDigest,\n canonicalCandidateDocument,\n immutableCandidateValue,\n verifyCanonicalCandidateDocument,\n} from '../candidate-execution/digest'\nimport {\n requireSealedCandidateExperiment,\n verifyAgentImprovementActivation,\n verifyAgentImprovementProposal,\n} from './improvement-cycle'\nimport {\n agentImprovementTargetDigest,\n agentImprovementTargetInput,\n agentProfileImprovementStateDigest,\n} from './improvement-surfaces'\n\nexport interface CreateAgentImprovementActivationResultOptions {\n completedAt: string\n outcome: AgentImprovementActivationOutcome\n}\n\nexport interface AgentImprovementActivationTargetPlan extends AgentImprovementActivationTarget {\n desiredDigest: Sha256Digest\n /**\n * Exact measured input the product must apply to reach `desiredDigest`.\n * Transition surfaces such as code and knowledge are applied operations, so\n * their resulting state digest is not the digest of this input document.\n */\n desiredInput: unknown\n}\n\nexport type AgentProfileImprovementActivationOperation =\n | {\n kind: 'apply-change'\n changes: AgentProfileImprovementChange\n }\n | {\n /** The product must load its own saved state at `desiredStateDigest`. */\n kind: 'restore-state'\n }\n\nexport interface AgentProfileImprovementActivationTargetPlan\n extends AgentImprovementActivationTarget {\n desiredDigest: Sha256Digest\n desiredInput: AgentProfileImprovementActivationOperation\n}\n\nexport interface SealedCandidateActivationTransitionInput {\n kind: 'sealed-candidate'\n activation: AgentImprovementActivation\n candidateBundle: AgentCandidateBundle\n bundle: AgentCandidateBundle\n targets: [AgentImprovementActivationTargetPlan, ...AgentImprovementActivationTargetPlan[]]\n attemptedAt: string\n expired: boolean\n}\n\n/**\n * A measured profile change without raw profile bytes.\n * The product owns the private state lookup and atomic write.\n */\nexport interface ProfileImprovementActivationTransitionInput {\n kind: 'profile-improvement'\n activation: AgentImprovementActivation\n experiment: AgentProfileImprovementExperiment\n sourceStateDigest: Sha256Digest\n desiredStateDigest: Sha256Digest\n operation: AgentProfileImprovementActivationOperation\n targets: [\n AgentProfileImprovementActivationTargetPlan,\n ...AgentProfileImprovementActivationTargetPlan[],\n ]\n attemptedAt: string\n expired: boolean\n}\n\nexport type AgentImprovementActivationTransitionInput =\n | SealedCandidateActivationTransitionInput\n | ProfileImprovementActivationTransitionInput\n\nexport interface AgentImprovementActivationResultStore {\n load(idempotencyKey: Sha256Digest): Promise<unknown | undefined>\n putIfAbsent(result: AgentImprovementActivationResult): Promise<unknown>\n}\n\n/**\n * Product-owned or Runtime-composed transition.\n *\n * Implementations resolve a stored result for `activation.digest`, compare\n * every target, and make the write durably idempotent. Co-located targets store\n * the all-or-none write with its result. Other targets throw when result\n * storage fails so a retry can reconcile it. Runtime never invokes this write\n * function after authorization expires.\n */\nexport type AgentImprovementActivationTransition = (\n input: AgentImprovementActivationTransitionInput,\n) => Promise<unknown>\n\n/**\n * Target-read-only check for a prior exact write.\n * It may persist recovered result metadata, but must not change an activation target.\n * Return undefined only when no target write can have committed.\n */\nexport type AgentImprovementActivationReconciliation = (\n input: AgentImprovementActivationTransitionInput,\n) => Promise<unknown | undefined>\n\nexport interface ExecuteAgentImprovementActivationInput {\n proposal: AgentImprovementProposal\n review: AgentImprovementReview\n activation: AgentImprovementActivation\n}\n\nexport interface ExecuteAgentImprovementActivationOptions {\n transition: AgentImprovementActivationTransition\n reconcile?: AgentImprovementActivationReconciliation\n now?: () => Date\n}\n\n/** Create the exact result a product stores in the same transaction as its target write. */\nexport function createAgentImprovementActivationResult(\n transition: AgentImprovementActivationTransitionInput,\n options: CreateAgentImprovementActivationResultOptions,\n): AgentImprovementActivationResult {\n const activation = verifyCanonicalCandidateDocument(\n agentImprovementActivationSchema.parse(transition.activation),\n 'agent improvement activation',\n )\n assertTransitionInput(activation, transition)\n const result = agentImprovementActivationResultSchema.parse(\n canonicalCandidateDocument<AgentImprovementActivationResult>({\n kind: 'agent-improvement-activation-result',\n idempotencyKey: activation.digest,\n attemptedAt: transition.attemptedAt,\n completedAt: options.completedAt,\n outcome: options.outcome,\n }).value,\n )\n assertResultAgainstActivation(activation, result)\n assertOutcomeDesiredState(\n activation,\n result,\n new Map(transition.targets.map((target) => [targetIdentity(target), target.desiredDigest])),\n )\n return immutableCandidateValue(result)\n}\n\n/**\n * Recompute one historical activation result against the exact measured proposal and authority.\n * The result records that attempt; it is not a query of the target's current state.\n */\nexport function verifyAgentImprovementActivationResult(input: {\n proposal: unknown\n review: unknown\n activation: unknown\n result: unknown\n}): AgentImprovementActivationResult {\n const proposal = verifyAgentImprovementProposal(input.proposal)\n const activation = verifyAgentImprovementActivation(input)\n const result = verifyCanonicalCandidateDocument(\n agentImprovementActivationResultSchema.parse(input.result),\n 'agent improvement activation result',\n )\n assertResultAgainstActivation(activation, result)\n assertResultDesiredState(proposal, activation, result)\n return result\n}\n\n/** Validate and execute one product-owned activation transition. */\nexport async function executeAgentImprovementActivation(\n input: ExecuteAgentImprovementActivationInput,\n options: ExecuteAgentImprovementActivationOptions,\n): Promise<AgentImprovementActivationResult> {\n const proposal = verifyAgentImprovementProposal(input.proposal)\n const activation = verifyAgentImprovementActivation(input)\n const observedAt = (options.now ?? (() => new Date()))().toISOString()\n const attemptedAt =\n Date.parse(observedAt) < Date.parse(activation.authorizedAt)\n ? activation.authorizedAt\n : observedAt\n const expired = Date.parse(attemptedAt) >= Date.parse(activation.expiresAt)\n const transition = immutableCandidateValue<AgentImprovementActivationTransitionInput>(\n proposal.evaluation.kind === 'agent-improvement-measured-comparison'\n ? sealedCandidateTransition(proposal.evaluation.experiment, activation, attemptedAt, expired)\n : profileImprovementTransition(\n proposal.evaluation.experiment,\n activation,\n attemptedAt,\n expired,\n ),\n )\n\n if (transition.expired) {\n if (!options.reconcile) {\n return uncertainActivationResult(transition, 'RECONCILIATION_UNAVAILABLE')\n }\n let reconciled: unknown\n try {\n reconciled = await options.reconcile(transition)\n } catch {\n return uncertainActivationResult(transition, 'RECONCILIATION_THROW')\n }\n if (reconciled === undefined) {\n return createAgentImprovementActivationResult(transition, {\n completedAt: transition.attemptedAt,\n outcome: { status: 'expired' },\n })\n }\n try {\n return verifyAgentImprovementActivationResult({ ...input, result: reconciled })\n } catch {\n return uncertainActivationResult(transition, 'INVALID_RECONCILIATION')\n }\n }\n\n let rawResult: unknown\n try {\n rawResult = await options.transition(transition)\n } catch {\n return uncertainActivationResult(transition, 'TRANSITION_THROW')\n }\n try {\n return verifyAgentImprovementActivationResult({ ...input, result: rawResult })\n } catch {\n return uncertainActivationResult(transition, 'INVALID_RESULT')\n }\n}\n\nfunction sealedCandidateTransition(\n experiment: AgentCandidateExperiment,\n activation: AgentImprovementActivation,\n attemptedAt: string,\n expired: boolean,\n): SealedCandidateActivationTransitionInput {\n const targetArm = activation.intent === 'activate-candidate' ? 'candidate' : 'baseline'\n return {\n kind: 'sealed-candidate',\n activation,\n candidateBundle: experiment.candidate,\n bundle: experiment[targetArm],\n targets: activation.targets.map((target) => ({\n ...target,\n desiredDigest: agentImprovementTargetDigest(experiment, targetArm, target.surface),\n desiredInput: agentImprovementTargetInput(experiment[targetArm], target.surface),\n })) as SealedCandidateActivationTransitionInput['targets'],\n attemptedAt,\n expired,\n }\n}\n\nfunction profileImprovementTransition(\n experiment: AgentProfileImprovementExperiment,\n activation: AgentImprovementActivation,\n attemptedAt: string,\n expired: boolean,\n): ProfileImprovementActivationTransitionInput {\n const sourceArm = activation.intent === 'activate-candidate' ? 'baseline' : 'candidate'\n const targetArm = activation.intent === 'activate-candidate' ? 'candidate' : 'baseline'\n const operation = profileImprovementOperation(experiment, activation.intent)\n return {\n kind: 'profile-improvement',\n activation,\n experiment,\n sourceStateDigest: agentProfileImprovementStateDigest(experiment, sourceArm),\n desiredStateDigest: agentProfileImprovementStateDigest(experiment, targetArm),\n operation,\n targets: activation.targets.map((target) => ({\n ...target,\n desiredDigest: agentProfileImprovementStateDigest(experiment, targetArm),\n desiredInput: operation,\n })) as ProfileImprovementActivationTransitionInput['targets'],\n attemptedAt,\n expired,\n }\n}\n\nfunction profileImprovementOperation(\n experiment: AgentProfileImprovementExperiment,\n intent: AgentImprovementActivation['intent'],\n): AgentProfileImprovementActivationOperation {\n return intent === 'activate-candidate'\n ? { kind: 'apply-change', changes: experiment.change }\n : { kind: 'restore-state' }\n}\n\nfunction uncertainActivationResult(\n transition: AgentImprovementActivationTransitionInput,\n code: string,\n): AgentImprovementActivationResult {\n return createAgentImprovementActivationResult(transition, {\n completedAt: transition.attemptedAt,\n outcome: {\n status: 'indeterminate',\n code,\n message: 'The product transition did not return a trustworthy commit result.',\n },\n })\n}\n\nfunction assertTransitionInput(\n activation: AgentImprovementActivation,\n transition: AgentImprovementActivationTransitionInput,\n): void {\n if (transition.kind === 'sealed-candidate') {\n assertSealedCandidateTransitionInput(activation, transition)\n return\n }\n assertProfileImprovementTransitionInput(activation, transition)\n}\n\nfunction assertSealedCandidateTransitionInput(\n activation: AgentImprovementActivation,\n transition: SealedCandidateActivationTransitionInput,\n): void {\n assertAuthorizedTransitionTargets(activation, transition.targets)\n const desiredInputsMatch = transition.targets.every(\n (target) =>\n canonicalCandidateDigest(target.desiredInput) ===\n canonicalCandidateDigest(agentImprovementTargetInput(transition.bundle, target.surface)),\n )\n if (\n transition.expired !== Date.parse(transition.attemptedAt) >= Date.parse(activation.expiresAt) ||\n transition.candidateBundle.digest !== activation.candidateDigest ||\n !desiredInputsMatch ||\n (activation.intent === 'activate-candidate' &&\n transition.bundle.digest !== transition.candidateBundle.digest)\n ) {\n throw new Error('activation transition does not match its authorization')\n }\n}\n\nfunction assertProfileImprovementTransitionInput(\n activation: AgentImprovementActivation,\n transition: ProfileImprovementActivationTransitionInput,\n): void {\n assertAuthorizedTransitionTargets(activation, transition.targets)\n const targetsAgentProfile = activation.targets.some(\n (target) => target.surface === 'agent-profile',\n )\n const experiment = agentProfileImprovementExperimentSchema.parse(transition.experiment)\n const sourceArm = activation.intent === 'activate-candidate' ? 'baseline' : 'candidate'\n const targetArm = activation.intent === 'activate-candidate' ? 'candidate' : 'baseline'\n const sourceStateDigest = agentProfileImprovementStateDigest(experiment, sourceArm)\n const desiredStateDigest = agentProfileImprovementStateDigest(experiment, targetArm)\n const operation = profileImprovementOperation(experiment, activation.intent)\n const targetsMatch = transition.targets.every(\n (target) =>\n target.expectedBaseDigest === sourceStateDigest &&\n target.desiredDigest === desiredStateDigest &&\n canonicalCandidateDigest(target.desiredInput) === canonicalCandidateDigest(operation),\n )\n if (\n transition.expired !== Date.parse(transition.attemptedAt) >= Date.parse(activation.expiresAt) ||\n experiment.digest !== activation.experimentDigest ||\n experiment.candidate.stateDigest !== activation.candidateDigest ||\n (targetsAgentProfile &&\n (activation.executionRef === undefined ||\n canonicalCandidateDigest(activation.executionRef) !==\n canonicalCandidateDigest(experiment.executionRef))) ||\n transition.sourceStateDigest !== sourceStateDigest ||\n transition.desiredStateDigest !== desiredStateDigest ||\n canonicalCandidateDigest(transition.operation) !== canonicalCandidateDigest(operation) ||\n !targetsMatch\n ) {\n throw new Error('activation transition does not match its authorization')\n }\n}\n\nfunction assertAuthorizedTransitionTargets(\n activation: AgentImprovementActivation,\n targets: readonly AgentImprovementActivationTargetPlan[],\n): void {\n const authorized = targetMap(activation.targets)\n const planned = targetMap(targets)\n if (\n authorized.size !== planned.size ||\n [...authorized.entries()].some(\n ([identity, target]) =>\n planned.get(identity)?.expectedBaseDigest !== target.expectedBaseDigest,\n )\n ) {\n throw new Error('activation transition does not match its authorization')\n }\n}\n\nfunction assertResultAgainstActivation(\n activation: AgentImprovementActivation,\n result: AgentImprovementActivationResult,\n): void {\n const attemptedAt = Date.parse(result.attemptedAt)\n const completedAt = Date.parse(result.completedAt)\n const expiresAt = Date.parse(activation.expiresAt)\n if (\n result.idempotencyKey !== activation.digest ||\n attemptedAt < Date.parse(activation.authorizedAt) ||\n completedAt < attemptedAt\n ) {\n throw new Error('activation result does not bind its authorization')\n }\n const expired = attemptedAt >= expiresAt\n if (\n (result.outcome.status === 'expired' && !expired) ||\n (expired && !['expired', 'indeterminate', 'already-applied'].includes(result.outcome.status))\n ) {\n throw new Error('activation result does not honor its authorization expiry')\n }\n if (!('targets' in result.outcome)) return\n const authorized = targetMap(activation.targets)\n const observed = new Set(result.outcome.targets.map(targetIdentity))\n if (\n authorized.size !== observed.size ||\n [...authorized.keys()].some((identity) => !observed.has(identity))\n ) {\n throw new Error('activation result must cover every authorized target exactly once')\n }\n if (\n result.outcome.status === 'applied' &&\n result.outcome.targets.some(\n (target) =>\n target.beforeDigest !== authorized.get(targetIdentity(target))?.expectedBaseDigest,\n )\n ) {\n throw new Error('applied activation did not start from its authorized base state')\n }\n}\n\nfunction assertResultDesiredState(\n proposal: AgentImprovementProposal,\n activation: AgentImprovementActivation,\n result: AgentImprovementActivationResult,\n): void {\n if (!('targets' in result.outcome)) return\n const targetArm = activation.intent === 'activate-candidate' ? 'candidate' : 'baseline'\n const desiredStateDigest =\n proposal.evaluation.kind === 'agent-profile-improvement-measured-comparison'\n ? agentProfileImprovementStateDigest(proposal.evaluation.experiment, targetArm)\n : undefined\n const desired = new Map(\n activation.targets.map((target) => [\n targetIdentity(target),\n desiredStateDigest ??\n agentImprovementTargetDigest(\n requireSealedCandidateExperiment(proposal),\n targetArm,\n target.surface,\n ),\n ]),\n )\n assertOutcomeDesiredState(activation, result, desired)\n}\n\nfunction assertOutcomeDesiredState(\n activation: AgentImprovementActivation,\n result: AgentImprovementActivationResult,\n desired: ReadonlyMap<string, Sha256Digest>,\n): void {\n if (!('targets' in result.outcome)) return\n if (result.outcome.status === 'applied') {\n if (\n result.outcome.targets.some(\n (target) => target.afterDigest !== desired.get(targetIdentity(target)),\n )\n ) {\n throw new Error('applied activation does not match the requested bundle')\n }\n return\n }\n const allDesired = result.outcome.targets.every(\n (target) => target.currentDigest === desired.get(targetIdentity(target)),\n )\n if (result.outcome.status === 'already-applied') {\n if (!allDesired) throw new Error('already-applied activation is not at the requested state')\n return\n }\n const authorized = targetMap(activation.targets)\n const hasStaleTarget = result.outcome.targets.some(\n (target) => target.currentDigest !== authorized.get(targetIdentity(target))?.expectedBaseDigest,\n )\n if (allDesired || !hasStaleTarget) {\n throw new Error('activation conflict does not identify stale target state')\n }\n}\n\nfunction targetMap<T extends { surface: AgentImprovementSurface; identity: string }>(\n targets: readonly T[],\n): Map<string, T> {\n return new Map(targets.map((target) => [targetIdentity(target), target]))\n}\n\nfunction targetIdentity(target: { surface: AgentImprovementSurface; identity: string }): string {\n return `${target.surface}\\u0000${target.identity}`\n}\n"],"mappings":"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"}
package/dist/agent.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { o as mapSandboxEvent } from "./sandbox-events-BVjstFgb.js";
2
2
  import { Sn as worktreeCliProfileMaterialization, _n as renderProfileMaterializationIssues, _t as createSandboxForSpec, cn as assertProfileMaterialization, dn as fullProfileMaterialization, fn as profileMaterializationAxes, gn as promptResourceProfileMaterialization, hn as promptOnlyProfileMaterialization, ln as controlProfileMaterialization, mn as promptModelProfileMaterialization, pn as promptControlProfileMaterialization, sn as AGENT_PROFILE_MATERIALIZATION_AXES, un as defineProfileMaterializationContract, xn as validateProfileMaterialization, yn as sandboxActProfileMaterialization } from "./supervisor-B-mmmiOU.js";
3
- import "./runtime-D5l-enW9.js";
3
+ import "./runtime-C-7uhhFs.js";
4
4
  import { createHash } from "node:crypto";
5
5
  import { isAbsolute, join, relative, resolve, sep } from "node:path";
6
6
  import { existsSync, readFileSync, statSync } from "node:fs";
@@ -0,0 +1,44 @@
1
+ import { m as ValidationError } from "./errors-CDZ8XsVj.js";
2
+ //#region src/runtime/authored-code.ts
3
+ /**
4
+ * The ONE lint over model-authored source, and the fence extractor beside it.
5
+ *
6
+ * Two features have a model write code the runtime then runs: `authorStrategy` (an authored
7
+ * optimization strategy, since 0.60) and the graph engine's `codemode` node (0.169.0). Both need
8
+ * the same refusals; 0.169.0 shipped them as two byte-near copies that could drift independently,
9
+ * which an audit flagged. This module is the single copy both import.
10
+ *
11
+ * A LINT, NOT A SANDBOX — it reads text and cannot constrain what running code does. Its job is
12
+ * refusing the obvious escapes in the authored source so a bad program is rejected before
13
+ * anything executes. Isolation, where required, is the execution boundary's job (a jailed
14
+ * `codeRunner`, a sandboxed loader), never this check's.
15
+ */
16
+ /** Refuse the obvious escapes in authored source. See the module doc for what this is NOT. */
17
+ function assertAuthoredCode(code, options = {}) {
18
+ const context = options.context ?? "authored code";
19
+ const allowed = options.allowedImports ?? [];
20
+ for (const line of code.split("\n")) {
21
+ if (!/^\s*import\s/.test(line)) continue;
22
+ if (!allowed.some((specifier) => line.includes(`'${specifier}'`) || line.includes(`"${specifier}"`))) throw new ValidationError(`${context} rejected: foreign import — ${line.trim().slice(0, 120)}${allowed.length === 0 ? " (no import is allowed here)" : ` (allowed: ${allowed.join(", ")})`}`);
23
+ }
24
+ for (const [pattern, what] of [
25
+ [/\brequire\s*\(/, "require()"],
26
+ [/\bimport\s*\(/, "dynamic import()"],
27
+ [/\beval\s*\(/, "eval()"],
28
+ [/new\s+Function\s*\(/, "new Function()"],
29
+ [/\bprocess\s*[.[]/, "process access"],
30
+ [/\bglobalThis\s*[.[]/, "globalThis access"],
31
+ [/\bfetch\s*\(/, "network access"],
32
+ [/child_process|node:fs|node:net|node:http|worker_threads/, "node builtin access"]
33
+ ]) if (pattern.test(code)) throw new ValidationError(`${context} rejected: ${what}`);
34
+ }
35
+ /** Pull the first fenced block out of a model reply; the whole reply if it carries no fence. */
36
+ function extractCodeBlock(reply) {
37
+ const code = (/```(?:[a-zA-Z]*)\n([\s\S]*?)```/u.exec(reply)?.[1] ?? reply).trim();
38
+ if (code.length === 0) throw new ValidationError("authored code: the model returned no code");
39
+ return code;
40
+ }
41
+ //#endregion
42
+ export { extractCodeBlock as n, assertAuthoredCode as t };
43
+
44
+ //# sourceMappingURL=authored-code-C2TGxNtf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authored-code-C2TGxNtf.js","names":[],"sources":["../src/runtime/authored-code.ts"],"sourcesContent":["/**\n * The ONE lint over model-authored source, and the fence extractor beside it.\n *\n * Two features have a model write code the runtime then runs: `authorStrategy` (an authored\n * optimization strategy, since 0.60) and the graph engine's `codemode` node (0.169.0). Both need\n * the same refusals; 0.169.0 shipped them as two byte-near copies that could drift independently,\n * which an audit flagged. This module is the single copy both import.\n *\n * A LINT, NOT A SANDBOX — it reads text and cannot constrain what running code does. Its job is\n * refusing the obvious escapes in the authored source so a bad program is rejected before\n * anything executes. Isolation, where required, is the execution boundary's job (a jailed\n * `codeRunner`, a sandboxed loader), never this check's.\n */\nimport { ValidationError } from '../errors'\n\nexport interface AuthoredCodeOptions {\n /** Import specifiers an authored module may name. Empty (the default) bans every import. A\n * specifier admits ANY import form of that module (named, namespace, default) — the lint\n * gates WHICH module, not the syntax used to reach it. */\n readonly allowedImports?: ReadonlyArray<string>\n /** Names the refusal, e.g. `codemode \"planner\"`. Defaults to `authored code`. */\n readonly context?: string\n}\n\n/** Refuse the obvious escapes in authored source. See the module doc for what this is NOT. */\nexport function assertAuthoredCode(code: string, options: AuthoredCodeOptions = {}): void {\n const context = options.context ?? 'authored code'\n const allowed = options.allowedImports ?? []\n for (const line of code.split('\\n')) {\n if (!/^\\s*import\\s/.test(line)) continue\n const named = allowed.some(\n (specifier) => line.includes(`'${specifier}'`) || line.includes(`\"${specifier}\"`),\n )\n if (!named) {\n throw new ValidationError(\n `${context} rejected: foreign import — ${line.trim().slice(0, 120)}${\n allowed.length === 0\n ? ' (no import is allowed here)'\n : ` (allowed: ${allowed.join(', ')})`\n }`,\n )\n }\n }\n const banned: ReadonlyArray<readonly [RegExp, string]> = [\n [/\\brequire\\s*\\(/, 'require()'],\n [/\\bimport\\s*\\(/, 'dynamic import()'],\n [/\\beval\\s*\\(/, 'eval()'],\n [/new\\s+Function\\s*\\(/, 'new Function()'],\n [/\\bprocess\\s*[.[]/, 'process access'],\n [/\\bglobalThis\\s*[.[]/, 'globalThis access'],\n [/\\bfetch\\s*\\(/, 'network access'],\n [/child_process|node:fs|node:net|node:http|worker_threads/, 'node builtin access'],\n ]\n for (const [pattern, what] of banned) {\n if (pattern.test(code)) throw new ValidationError(`${context} rejected: ${what}`)\n }\n}\n\n/** Pull the first fenced block out of a model reply; the whole reply if it carries no fence. */\nexport function extractCodeBlock(reply: string): string {\n const fenced = /```(?:[a-zA-Z]*)\\n([\\s\\S]*?)```/u.exec(reply)\n const code = (fenced?.[1] ?? reply).trim()\n if (code.length === 0) throw new ValidationError('authored code: the model returned no code')\n return code\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAyBA,SAAgB,mBAAmB,MAAc,UAA+B,CAAC,GAAS;CACxF,MAAM,UAAU,QAAQ,WAAW;CACnC,MAAM,UAAU,QAAQ,kBAAkB,CAAC;CAC3C,KAAK,MAAM,QAAQ,KAAK,MAAM,IAAI,GAAG;EACnC,IAAI,CAAC,eAAe,KAAK,IAAI,GAAG;EAIhC,IAAI,CAHU,QAAQ,MACnB,cAAc,KAAK,SAAS,IAAI,UAAU,EAAE,KAAK,KAAK,SAAS,IAAI,UAAU,EAAE,CAEzE,GACP,MAAM,IAAI,gBACR,GAAG,QAAQ,8BAA8B,KAAK,KAAK,CAAC,CAAC,MAAM,GAAG,GAAG,IAC/D,QAAQ,WAAW,IACf,iCACA,cAAc,QAAQ,KAAK,IAAI,EAAE,IAEzC;CAEJ;CAWA,KAAK,MAAM,CAAC,SAAS,SAAS;EAT5B,CAAC,kBAAkB,WAAW;EAC9B,CAAC,iBAAiB,kBAAkB;EACpC,CAAC,eAAe,QAAQ;EACxB,CAAC,uBAAuB,gBAAgB;EACxC,CAAC,oBAAoB,gBAAgB;EACrC,CAAC,uBAAuB,mBAAmB;EAC3C,CAAC,gBAAgB,gBAAgB;EACjC,CAAC,2DAA2D,qBAAqB;CAEhD,GACjC,IAAI,QAAQ,KAAK,IAAI,GAAG,MAAM,IAAI,gBAAgB,GAAG,QAAQ,aAAa,MAAM;AAEpF;;AAGA,SAAgB,iBAAiB,OAAuB;CAEtD,MAAM,QADS,mCAAmC,KAAK,KACpC,CAAC,GAAG,MAAM,MAAA,CAAO,KAAK;CACzC,IAAI,KAAK,WAAW,GAAG,MAAM,IAAI,gBAAgB,2CAA2C;CAC5F,OAAO;AACT"}
package/dist/graph.d.ts CHANGED
@@ -2,27 +2,19 @@ import { $l as MakeWorkerAgent, Gt as AgentGraph, If as DeliverableSpec, Qt as R
2
2
  import { H as SpawnJournal, K as Spend, V as SpawnEvent, i as Budget, j as ResultBlobStore, t as Agent, z as Scope } from "./types-DjVO-p7R.js";
3
3
  import { o as ExecutorConfig } from "./runtime-B0HZbuEv.js";
4
4
  import { AgentProfile } from "@tangle-network/agent-interface";
5
- //#region src/runtime/graph/condition.d.ts
6
- /** The leaf comparison operators; `exists`/`truthy` are unary, the rest compare against `value`. */
7
- declare const CONDITION_OPS: readonly ["eq", "neq", "gt", "gte", "lt", "lte", "in", "contains", "exists", "truthy"];
8
- type ConditionOp = (typeof CONDITION_OPS)[number];
9
- interface ConditionLeaf {
10
- /** Dotted path with `[N]` indexing into the guard context, e.g. `out.findings[0].severity`. */
11
- readonly path: string;
12
- readonly op: ConditionOp;
13
- readonly value?: unknown;
14
- }
15
- type Condition = ConditionLeaf | {
16
- readonly all: ReadonlyArray<Condition>;
17
- } | {
18
- readonly any: ReadonlyArray<Condition>;
19
- } | {
20
- readonly not: Condition;
21
- };
22
- /** Validate shape, bounds, and per-leaf path/operator rules; returns the input for chaining. */
23
- declare function validateCondition(raw: unknown, context: string): Condition;
24
- /** Walk a validated condition over a context to a boolean. Never throws on data shape. */
25
- declare function evaluateCondition(condition: Condition, context: unknown): boolean;
5
+ //#region src/runtime/authored-code.d.ts
6
+ interface AuthoredCodeOptions {
7
+ /** Import specifiers an authored module may name. Empty (the default) bans every import. A
8
+ * specifier admits ANY import form of that module (named, namespace, default) — the lint
9
+ * gates WHICH module, not the syntax used to reach it. */
10
+ readonly allowedImports?: ReadonlyArray<string>;
11
+ /** Names the refusal, e.g. `codemode "planner"`. Defaults to `authored code`. */
12
+ readonly context?: string;
13
+ }
14
+ /** Refuse the obvious escapes in authored source. See the module doc for what this is NOT. */
15
+ declare function assertAuthoredCode(code: string, options?: AuthoredCodeOptions): void;
16
+ /** Pull the first fenced block out of a model reply; the whole reply if it carries no fence. */
17
+ declare function extractCodeBlock(reply: string): string;
26
18
  //#endregion
27
19
  //#region src/runtime/graph/registry.d.ts
28
20
  /**
@@ -197,6 +189,86 @@ declare function kindHandle(kind: Pick<NodeKind, 'id' | 'version'>): RegistryHan
197
189
  */
198
190
  declare function narrowEffects<Effects extends ReadonlyArray<EffectName>>(declared: Effects, provided: Readonly<Record<string, unknown>>, context: string): EffectContext<Effects>;
199
191
  //#endregion
192
+ //#region src/runtime/graph/codemode.d.ts
193
+ /** One operation the authored program may call, and the line the model is shown about it. */
194
+ interface CodeOperation {
195
+ /** Identifier the program calls, e.g. `search`. Must be a valid JS identifier. */
196
+ readonly name: string;
197
+ /** The signature and meaning, as the model sees it: `search(query: string): Promise<Hit[]>`. */
198
+ readonly signature: string;
199
+ readonly description: string;
200
+ /** What the call actually does. A spend it reports is added to the node's settlement. */
201
+ readonly call: (...args: ReadonlyArray<unknown>) => Promise<CodeOperationResult> | CodeOperationResult;
202
+ }
203
+ /** An operation's answer. `spend` is optional; an operation that costs nothing omits it. */
204
+ interface CodeOperationResult {
205
+ readonly value: unknown;
206
+ readonly spend?: Spend;
207
+ }
208
+ /** What a host's `codeRunner` effect must do: run authored source with `api` in scope, and answer
209
+ * what it returned. The host decides WHERE that happens — in process, or jailed. */
210
+ interface CodeRunner {
211
+ run(args: {
212
+ readonly code: string;
213
+ readonly api: Readonly<Record<string, (...args: ReadonlyArray<unknown>) => Promise<unknown>>>;
214
+ readonly signal: AbortSignal;
215
+ }): Promise<unknown>;
216
+ }
217
+ /** What a host's `model` effect must do: answer one prompt with text. */
218
+ interface CodeAuthor {
219
+ complete(args: {
220
+ readonly prompt: string;
221
+ readonly profile: AgentProfile;
222
+ readonly signal: AbortSignal;
223
+ }): Promise<{
224
+ readonly text: string;
225
+ readonly spend?: Spend;
226
+ }>;
227
+ }
228
+ interface CodeModeConfig {
229
+ readonly operations: ReadonlyArray<CodeOperation>;
230
+ /** What the program must accomplish, in the author's words. Appended to the generated API doc. */
231
+ readonly task: string;
232
+ /** Import specifiers the authored code may name. Empty (the default) bans every import. */
233
+ readonly allowedImports?: ReadonlyArray<string>;
234
+ }
235
+ /** The API doc the model is shown — generated from the grant, so the two cannot disagree. */
236
+ declare function renderCodeApi(config: CodeModeConfig): string;
237
+ /**
238
+ * A node that asks a model for a program and runs it. Declares the two effects it cannot supply
239
+ * itself — `model` (who writes the code) and `codeRunner` (where it runs) — so the host owns both.
240
+ */
241
+ declare function codemodeKind(): NodeKind<CodeModeConfig, readonly ['model', 'codeRunner']>;
242
+ /**
243
+ * An in-process `codeRunner`: builds the authored body as a function with the granted API in
244
+ * scope. **A development convenience, not a security boundary** — `assertAuthoredCode` is a lint,
245
+ * and code running in this process can reach whatever the process can. Supply a jailed runner for
246
+ * code you did not write.
247
+ */
248
+ declare function inlineCodeRunner(): CodeRunner;
249
+ //#endregion
250
+ //#region src/runtime/graph/condition.d.ts
251
+ /** The leaf comparison operators; `exists`/`truthy` are unary, the rest compare against `value`. */
252
+ declare const CONDITION_OPS: readonly ["eq", "neq", "gt", "gte", "lt", "lte", "in", "contains", "exists", "truthy"];
253
+ type ConditionOp = (typeof CONDITION_OPS)[number];
254
+ interface ConditionLeaf {
255
+ /** Dotted path with `[N]` indexing into the guard context, e.g. `out.findings[0].severity`. */
256
+ readonly path: string;
257
+ readonly op: ConditionOp;
258
+ readonly value?: unknown;
259
+ }
260
+ type Condition = ConditionLeaf | {
261
+ readonly all: ReadonlyArray<Condition>;
262
+ } | {
263
+ readonly any: ReadonlyArray<Condition>;
264
+ } | {
265
+ readonly not: Condition;
266
+ };
267
+ /** Validate shape, bounds, and per-leaf path/operator rules; returns the input for chaining. */
268
+ declare function validateCondition(raw: unknown, context: string): Condition;
269
+ /** Walk a validated condition over a context to a boolean. Never throws on data shape. */
270
+ declare function evaluateCondition(condition: Condition, context: unknown): boolean;
271
+ //#endregion
200
272
  //#region src/runtime/graph/projection.d.ts
201
273
  type Projection = {
202
274
  readonly path: string;
@@ -729,5 +801,5 @@ declare function runEngineGraph(engine: GraphEngine, spec: EngineGraphSpec | Com
729
801
  */
730
802
  declare function createGraphRun(engine: GraphEngine, spec: EngineGraphSpec | CompiledGraph, task: string, options: GraphRunOptions): GraphRunHandle;
731
803
  //#endregion
732
- export { type AgentKindConfig, type AnyNodeKind, type BudgetMode, CONDITION_OPS, type CompiledEdge, type CompiledGraph, type CompiledNode, type Condition, type ConditionLeaf, type ConditionOp, DEFAULT_MAX_NODE_VISITS, ENGINE_WOKEN_SEQ_BASE, type EdgeLedger, type EffectContext, type EffectName, type EngineGraphEdge, type EngineGraphNode, type EngineGraphSpec, type FinalizerChoice, type FoldEdge, type FoldEdgeState, type FoldInstance, type FoldInstanceStatus, type FoldNode, type FoldSuspension, type GatingEdge, type GraphEdgeKind, type GraphEdgeTraversal, type GraphEngine, type GraphEngineOptions, type GraphFoldState, type GraphHost, type GraphNodeSettle, type GraphRunContext, type GraphRunHandle, type GraphRunOptions, type GraphRunReason, type GraphRunResult, JOIN_RULES, type JoinDecision, type JoinRule, type JsonSchema, MAX_MAX_NODE_VISITS, type NodeFlags, type NodeKind, type OnCrash, type PortSpec, type Projection, RUN_GRAPH_ROOT_KIND, type Registered, type Registry, type RegistryHandle, type ScriptBody, type ScriptKindConfig, type SubgraphKindConfig, type SupervisorKindConfig, type SuspensionRequest, admitPayload, agentKind, applyGraphFoldEvent, applyProjection, assembleGraphResult, compileGraph, createEdgeLedger, createGraphEngine, createGraphRun, createRegistry, decideJoin, emptyFoldState, evaluateCondition, foldGraphJournal, formatRegistryHandle, graphFromRunGraph, isEngineFired, isSuspensionRequest, kindHandle, materializeSettles, mintSuspensionToken, narrowEffects, openGraphRun, parseRegistryHandle, runEngineGraph, schemaAccepts, scriptKind, subgraphKind, supervisorKind, suspended, suspensionNodeId, tokenFromSuspensionNodeId, validateCondition, validateNodeKind, validateProjection };
804
+ export { type AgentKindConfig, type AnyNodeKind, type AuthoredCodeOptions, type BudgetMode, CONDITION_OPS, type CodeAuthor, type CodeModeConfig, type CodeOperation, type CodeOperationResult, type CodeRunner, type CompiledEdge, type CompiledGraph, type CompiledNode, type Condition, type ConditionLeaf, type ConditionOp, DEFAULT_MAX_NODE_VISITS, ENGINE_WOKEN_SEQ_BASE, type EdgeLedger, type EffectContext, type EffectName, type EngineGraphEdge, type EngineGraphNode, type EngineGraphSpec, type FinalizerChoice, type FoldEdge, type FoldEdgeState, type FoldInstance, type FoldInstanceStatus, type FoldNode, type FoldSuspension, type GatingEdge, type GraphEdgeKind, type GraphEdgeTraversal, type GraphEngine, type GraphEngineOptions, type GraphFoldState, type GraphHost, type GraphNodeSettle, type GraphRunContext, type GraphRunHandle, type GraphRunOptions, type GraphRunReason, type GraphRunResult, JOIN_RULES, type JoinDecision, type JoinRule, type JsonSchema, MAX_MAX_NODE_VISITS, type NodeFlags, type NodeKind, type OnCrash, type PortSpec, type Projection, RUN_GRAPH_ROOT_KIND, type Registered, type Registry, type RegistryHandle, type ScriptBody, type ScriptKindConfig, type SubgraphKindConfig, type SupervisorKindConfig, type SuspensionRequest, admitPayload, agentKind, applyGraphFoldEvent, applyProjection, assembleGraphResult, assertAuthoredCode, codemodeKind, compileGraph, createEdgeLedger, createGraphEngine, createGraphRun, createRegistry, decideJoin, emptyFoldState, evaluateCondition, extractCodeBlock, foldGraphJournal, formatRegistryHandle, graphFromRunGraph, inlineCodeRunner, isEngineFired, isSuspensionRequest, kindHandle, materializeSettles, mintSuspensionToken, narrowEffects, openGraphRun, parseRegistryHandle, renderCodeApi, runEngineGraph, schemaAccepts, scriptKind, subgraphKind, supervisorKind, suspended, suspensionNodeId, tokenFromSuspensionNodeId, validateCondition, validateNodeKind, validateProjection };
733
805
  //# sourceMappingURL=graph.d.ts.map
package/dist/graph.js CHANGED
@@ -3,7 +3,161 @@ import { d as replaySpawnTree, i as InMemorySpawnJournal, l as materializeTreeVi
3
3
  import { t as addSpend } from "./util-D6ZEuBMi.js";
4
4
  import { N as createBudgetPool, U as createExecutorRegistry, a as uncertainSpawnBudgets, i as sumMeasuredSpendFromEvents, l as runFinalizer, o as bestDelivered, p as createScope, r as maxSeqOf, s as collectDelivered } from "./supervisor-B-mmmiOU.js";
5
5
  import { i as workerFromBackend, s as supervisorAgent } from "./supervise-rEE46ruH.js";
6
+ import { n as extractCodeBlock, t as assertAuthoredCode } from "./authored-code-C2TGxNtf.js";
6
7
  import { t as GraphEdgeCapError } from "./graph-ZDMygFIo.js";
8
+ //#region src/runtime/graph/codemode.ts
9
+ const IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/u;
10
+ /** The API doc the model is shown — generated from the grant, so the two cannot disagree. */
11
+ function renderCodeApi(config) {
12
+ return [
13
+ "Write ONE async function body. It may call only these operations:",
14
+ "",
15
+ ...config.operations.map((operation) => ` ${operation.signature}\n // ${operation.description}`),
16
+ "",
17
+ "Return the result as the body's return value. No imports, no require, no process, no fetch.",
18
+ "Reply with a single fenced code block and nothing else.",
19
+ "",
20
+ `TASK: ${config.task}`
21
+ ].join("\n");
22
+ }
23
+ /**
24
+ * A node that asks a model for a program and runs it. Declares the two effects it cannot supply
25
+ * itself — `model` (who writes the code) and `codeRunner` (where it runs) — so the host owns both.
26
+ */
27
+ function codemodeKind() {
28
+ return {
29
+ id: "codemode",
30
+ version: 1,
31
+ description: "Ask a model for a program over a granted API, then run it as one node.",
32
+ validateConfig: (raw, context) => {
33
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) throw new ValidationError(`${context}: codemode config must be an object`);
34
+ const config = raw;
35
+ if (typeof config.task !== "string" || config.task.trim().length === 0) throw new ValidationError(`${context}: codemode config.task must be a non-empty string`);
36
+ if (!Array.isArray(config.operations) || config.operations.length === 0) throw new ValidationError(`${context}: codemode config.operations must grant at least one operation`);
37
+ const seen = /* @__PURE__ */ new Set();
38
+ for (const operation of config.operations) {
39
+ if (!IDENTIFIER.test(operation?.name ?? "")) throw new ValidationError(`${context}: operation name ${JSON.stringify(operation?.name)} is not a JS identifier`);
40
+ if (seen.has(operation.name)) throw new ValidationError(`${context}: duplicate operation ${operation.name}`);
41
+ seen.add(operation.name);
42
+ if (typeof operation.call !== "function") throw new ValidationError(`${context}: operation ${operation.name} has no call`);
43
+ }
44
+ return {
45
+ operations: config.operations,
46
+ task: config.task,
47
+ ...config.allowedImports === void 0 ? {} : { allowedImports: config.allowedImports }
48
+ };
49
+ },
50
+ configSchema: {
51
+ type: "object",
52
+ properties: {
53
+ task: { type: "string" },
54
+ operations: { type: "array" }
55
+ },
56
+ required: ["task", "operations"]
57
+ },
58
+ inputs: [{
59
+ name: "context",
60
+ schema: {}
61
+ }],
62
+ outputs: [],
63
+ effects: ["model", "codeRunner"],
64
+ onCrash: "restart",
65
+ budget: "metered",
66
+ run: ({ config, profile, inputs, effects }) => {
67
+ const author = effects.model;
68
+ const runner = effects.codeRunner;
69
+ let artifact;
70
+ return {
71
+ name: profile.name ?? "codemode",
72
+ act: () => Promise.reject(new ValidationError("codemode: act() is not the execution path")),
73
+ executorSpec: {
74
+ profile,
75
+ harness: null,
76
+ executor: {
77
+ runtime: "inline",
78
+ async execute(task, signal) {
79
+ const spends = [];
80
+ const prompt = [
81
+ renderCodeApi(config),
82
+ inputs.context === void 0 ? "" : `\nCONTEXT: ${JSON.stringify(inputs.context)}`,
83
+ typeof task === "string" && task.length > 0 ? `\n${task}` : ""
84
+ ].filter((part) => part.length > 0).join("\n");
85
+ const authored = await author.complete({
86
+ prompt,
87
+ profile,
88
+ signal
89
+ });
90
+ if (authored.spend) spends.push(authored.spend);
91
+ const code = extractCodeBlock(authored.text);
92
+ assertAuthoredCode(code, {
93
+ ...config.allowedImports === void 0 ? {} : { allowedImports: config.allowedImports },
94
+ context: `codemode ${JSON.stringify(profile.name ?? "node")}`
95
+ });
96
+ const api = {};
97
+ for (const operation of config.operations) api[operation.name] = async (...args) => {
98
+ const result = await operation.call(...args);
99
+ if (result?.spend) spends.push(result.spend);
100
+ return result?.value;
101
+ };
102
+ const out = await runner.run({
103
+ code,
104
+ api: Object.freeze(api),
105
+ signal
106
+ });
107
+ artifact = {
108
+ outRef: contentAddress({ codemode: out }),
109
+ out,
110
+ spent: totalSpend(spends)
111
+ };
112
+ return artifact;
113
+ },
114
+ teardown: () => Promise.resolve({ destroyed: true }),
115
+ resultArtifact: () => {
116
+ if (!artifact) throw new ValidationError("codemode: resultArtifact() read before execute()");
117
+ return artifact;
118
+ }
119
+ }
120
+ }
121
+ };
122
+ }
123
+ };
124
+ }
125
+ /** The node's spend is the model call plus every operation that reported one. An operation that
126
+ * reports nothing is not assumed free — it contributes an UNKNOWN mark, like the kernel's own. */
127
+ function totalSpend(parts) {
128
+ return parts.reduce((total, part) => ({
129
+ iterations: total.iterations + (part.iterations ?? 0),
130
+ tokens: {
131
+ input: total.tokens.input + (part.tokens?.input ?? 0),
132
+ output: total.tokens.output + (part.tokens?.output ?? 0),
133
+ ...part.tokens?.tokensKnown === false ? { tokensKnown: false } : {}
134
+ },
135
+ usd: total.usd + (part.usd ?? 0),
136
+ ...part.usdKnown === false ? { usdKnown: false } : {},
137
+ ms: total.ms + (part.ms ?? 0)
138
+ }), {
139
+ iterations: 1,
140
+ tokens: {
141
+ input: 0,
142
+ output: 0
143
+ },
144
+ usd: 0,
145
+ ms: 0
146
+ });
147
+ }
148
+ /**
149
+ * An in-process `codeRunner`: builds the authored body as a function with the granted API in
150
+ * scope. **A development convenience, not a security boundary** — `assertAuthoredCode` is a lint,
151
+ * and code running in this process can reach whatever the process can. Supply a jailed runner for
152
+ * code you did not write.
153
+ */
154
+ function inlineCodeRunner() {
155
+ return { async run({ code, api }) {
156
+ const names = Object.keys(api);
157
+ return new Function(...names, `"use strict"; return (async () => { ${code} })()`)(...names.map((name) => api[name]));
158
+ } };
159
+ }
160
+ //#endregion
7
161
  //#region src/runtime/graph/condition.ts
8
162
  /**
9
163
  * The ONE predicate tree: every guard in a graph — an edge `guard`, a filter projection's
@@ -2072,6 +2226,6 @@ async function runGraphLoop(engine, compiled, task, options, wakes, onWakeSignal
2072
2226
  });
2073
2227
  }
2074
2228
  //#endregion
2075
- export { CONDITION_OPS, DEFAULT_MAX_NODE_VISITS, ENGINE_WOKEN_SEQ_BASE, JOIN_RULES, MAX_MAX_NODE_VISITS, RUN_GRAPH_ROOT_KIND, admitPayload, agentKind, applyGraphFoldEvent, applyProjection, assembleGraphResult, compileGraph, createEdgeLedger, createGraphEngine, createGraphRun, createRegistry, decideJoin, emptyFoldState, evaluateCondition, foldGraphJournal, formatRegistryHandle, graphFromRunGraph, isEngineFired, isSuspensionRequest, kindHandle, materializeSettles, mintSuspensionToken, narrowEffects, openGraphRun, parseRegistryHandle, runEngineGraph, schemaAccepts, scriptKind, subgraphKind, supervisorKind, suspended, suspensionNodeId, tokenFromSuspensionNodeId, validateCondition, validateNodeKind, validateProjection };
2229
+ export { CONDITION_OPS, DEFAULT_MAX_NODE_VISITS, ENGINE_WOKEN_SEQ_BASE, JOIN_RULES, MAX_MAX_NODE_VISITS, RUN_GRAPH_ROOT_KIND, admitPayload, agentKind, applyGraphFoldEvent, applyProjection, assembleGraphResult, assertAuthoredCode, codemodeKind, compileGraph, createEdgeLedger, createGraphEngine, createGraphRun, createRegistry, decideJoin, emptyFoldState, evaluateCondition, extractCodeBlock, foldGraphJournal, formatRegistryHandle, graphFromRunGraph, inlineCodeRunner, isEngineFired, isSuspensionRequest, kindHandle, materializeSettles, mintSuspensionToken, narrowEffects, openGraphRun, parseRegistryHandle, renderCodeApi, runEngineGraph, schemaAccepts, scriptKind, subgraphKind, supervisorKind, suspended, suspensionNodeId, tokenFromSuspensionNodeId, validateCondition, validateNodeKind, validateProjection };
2076
2230
 
2077
2231
  //# sourceMappingURL=graph.js.map