@full-self-browsing/lattice 1.4.0 → 1.5.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.
Files changed (108) hide show
  1. package/dist/agent-run-C6miAzwI.d.ts +45 -0
  2. package/dist/agent-run-C6miAzwI.d.ts.map +1 -0
  3. package/dist/agent-run-CgPVFl0Z.js +47 -0
  4. package/dist/agent-run-CgPVFl0Z.js.map +1 -0
  5. package/dist/agents.d.ts +5 -0
  6. package/dist/agents.js +6 -0
  7. package/dist/artifact-Bg6mJGnm.d.ts +125 -0
  8. package/dist/artifact-Bg6mJGnm.d.ts.map +1 -0
  9. package/dist/artifact-DOfpeXLb.js +140 -0
  10. package/dist/artifact-DOfpeXLb.js.map +1 -0
  11. package/dist/artifacts.d.ts +2 -0
  12. package/dist/artifacts.js +2 -0
  13. package/dist/audit.d.ts +3 -0
  14. package/dist/audit.js +4 -0
  15. package/dist/catalog-CAfYwB_-.js +91 -0
  16. package/dist/catalog-CAfYwB_-.js.map +1 -0
  17. package/dist/context-pack-Bz3GXmjv.js +99 -0
  18. package/dist/context-pack-Bz3GXmjv.js.map +1 -0
  19. package/dist/context.d.ts +2 -0
  20. package/dist/context.js +2 -0
  21. package/dist/contract-S3oJGlc9.d.ts +74 -0
  22. package/dist/contract-S3oJGlc9.d.ts.map +1 -0
  23. package/dist/core.d.ts +48 -0
  24. package/dist/core.d.ts.map +1 -0
  25. package/dist/core.js +95 -0
  26. package/dist/core.js.map +1 -0
  27. package/dist/errors-eEuEIx6X.js +407 -0
  28. package/dist/errors-eEuEIx6X.js.map +1 -0
  29. package/dist/eval.d.ts +2 -0
  30. package/dist/eval.js +2 -0
  31. package/dist/fingerprint-DodDbQKN.js +34 -0
  32. package/dist/fingerprint-DodDbQKN.js.map +1 -0
  33. package/dist/index-DpnHGHVL.d.ts +53 -0
  34. package/dist/index-DpnHGHVL.d.ts.map +1 -0
  35. package/dist/index.d.ts +90 -3533
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +26 -15968
  38. package/dist/index.js.map +1 -1
  39. package/dist/infer-DLqp5QIM.d.ts +96 -0
  40. package/dist/infer-DLqp5QIM.d.ts.map +1 -0
  41. package/dist/lineage-DBgoPWAZ.js +137 -0
  42. package/dist/lineage-DBgoPWAZ.js.map +1 -0
  43. package/dist/local-CXOGPJ1f.js +139 -0
  44. package/dist/local-CXOGPJ1f.js.map +1 -0
  45. package/dist/local-Dy--7peL.d.ts +10 -0
  46. package/dist/local-Dy--7peL.d.ts.map +1 -0
  47. package/dist/memory-CkQEW6m5.js +62 -0
  48. package/dist/memory-CkQEW6m5.js.map +1 -0
  49. package/dist/memory-DRig5EHV.d.ts +10 -0
  50. package/dist/memory-DRig5EHV.d.ts.map +1 -0
  51. package/dist/negotiate-ClD88hkc.js +10967 -0
  52. package/dist/negotiate-ClD88hkc.js.map +1 -0
  53. package/dist/otel-BgM4e55_.d.ts +421 -0
  54. package/dist/otel-BgM4e55_.d.ts.map +1 -0
  55. package/dist/permission-context-CUKMo79F.js +134 -0
  56. package/dist/permission-context-CUKMo79F.js.map +1 -0
  57. package/dist/plan-DFm8Llep.js +125 -0
  58. package/dist/plan-DFm8Llep.js.map +1 -0
  59. package/dist/preflight-DNHWuJ46.d.ts +64 -0
  60. package/dist/preflight-DNHWuJ46.d.ts.map +1 -0
  61. package/dist/provider-C2IfKsvz.d.ts +1178 -0
  62. package/dist/provider-C2IfKsvz.d.ts.map +1 -0
  63. package/dist/providers.d.ts +4 -0
  64. package/dist/providers.js +4 -0
  65. package/dist/rate-limit-group-nDsBJqSu.d.ts +235 -0
  66. package/dist/rate-limit-group-nDsBJqSu.d.ts.map +1 -0
  67. package/dist/receipt-FYouoPHv.js +205 -0
  68. package/dist/receipt-FYouoPHv.js.map +1 -0
  69. package/dist/replay-CtIhpLek.js +964 -0
  70. package/dist/replay-CtIhpLek.js.map +1 -0
  71. package/dist/result-DLEx2WvU.d.ts +38 -0
  72. package/dist/result-DLEx2WvU.d.ts.map +1 -0
  73. package/dist/router-DU4Z3pTd.js +314 -0
  74. package/dist/router-DU4Z3pTd.js.map +1 -0
  75. package/dist/router-Yo1-aDOv.d.ts +42 -0
  76. package/dist/router-Yo1-aDOv.d.ts.map +1 -0
  77. package/dist/routing.d.ts +6 -0
  78. package/dist/routing.js +4 -0
  79. package/dist/{run-crew-CKdBjh5P.js → run-crew-B2fQLmgB.js} +7 -136
  80. package/dist/run-crew-B2fQLmgB.js.map +1 -0
  81. package/dist/run-crew-Bnve5dyI.d.ts +721 -0
  82. package/dist/run-crew-Bnve5dyI.d.ts.map +1 -0
  83. package/dist/{runtime-D25ehzCj.js → runtime-Dxiet5YS.js} +98 -641
  84. package/dist/runtime-Dxiet5YS.js.map +1 -0
  85. package/dist/scaffolds-DKQrCRqh.d.ts +535 -0
  86. package/dist/scaffolds-DKQrCRqh.d.ts.map +1 -0
  87. package/dist/scaffolds-ekPIlBeU.js +3139 -0
  88. package/dist/scaffolds-ekPIlBeU.js.map +1 -0
  89. package/dist/schema-CNfa_VEy.d.ts +15 -0
  90. package/dist/schema-CNfa_VEy.d.ts.map +1 -0
  91. package/dist/storage-DJKmsaEI.d.ts +26 -0
  92. package/dist/storage-DJKmsaEI.d.ts.map +1 -0
  93. package/dist/storage.d.ts +10 -0
  94. package/dist/storage.d.ts.map +1 -0
  95. package/dist/storage.js +4 -0
  96. package/dist/tool-call-validation-BFoXkwbf.js +107 -0
  97. package/dist/tool-call-validation-BFoXkwbf.js.map +1 -0
  98. package/dist/tools-C4wHgGKQ.js +49 -0
  99. package/dist/tools-C4wHgGKQ.js.map +1 -0
  100. package/dist/tools.d.ts +46 -0
  101. package/dist/tools.d.ts.map +1 -0
  102. package/dist/tools.js +106 -0
  103. package/dist/tools.js.map +1 -0
  104. package/dist/validate-c7EL5uuH.js +224 -0
  105. package/dist/validate-c7EL5uuH.js.map +1 -0
  106. package/package.json +99 -2
  107. package/dist/run-crew-CKdBjh5P.js.map +0 -1
  108. package/dist/runtime-D25ehzCj.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"runtime-D25ehzCj.js","names":["textEncoder"],"sources":["../src/artifacts/metadata.ts","../src/artifacts/artifact.ts","../src/contract/bands.ts","../src/receipts/canonical.ts","../src/receipts/envelope.ts","../src/receipts/redact.ts","../src/receipts/receipt.ts","../src/contract/checkpoint.ts","../src/agent/format-tools.ts","../src/outputs/validate.ts","../src/runtime/survivability.ts","../src/tools/tools.ts","../src/agent/host.ts","../src/agent/types.ts","../src/agent/runtime.ts"],"sourcesContent":["import mime from \"mime\";\n\nimport type { ArtifactKind, ArtifactOptions, ArtifactSize } from \"./artifact.js\";\n\nexport interface InferMediaTypeOptions\n extends Pick<ArtifactOptions, \"mediaType\"> {\n readonly kind: ArtifactKind;\n readonly defaultMediaType?: string;\n}\n\nconst textEncoder = new TextEncoder();\n\nexport function inferMediaType(\n value: unknown,\n options: InferMediaTypeOptions,\n): string | undefined {\n if (options.mediaType !== undefined) {\n return options.mediaType;\n }\n\n if (isBlobLike(value) && value.type !== \"\") {\n return value.type;\n }\n\n if (typeof value === \"string\") {\n return mime.getType(value) ?? options.defaultMediaType;\n }\n\n return options.defaultMediaType;\n}\n\nexport function measureArtifactValue(\n value: unknown,\n kind: ArtifactKind,\n): ArtifactSize | undefined {\n if (kind === \"text\" && typeof value === \"string\") {\n return measureString(value);\n }\n\n if (kind === \"json\") {\n const serialized = JSON.stringify(value);\n\n return serialized === undefined ? undefined : measureString(serialized);\n }\n\n if (isBlobLike(value)) {\n return {\n bytes: value.size,\n };\n }\n\n return undefined;\n}\n\nfunction measureString(value: string): ArtifactSize {\n return {\n characters: value.length,\n bytes: textEncoder.encode(value).byteLength,\n };\n}\n\nfunction isBlobLike(value: unknown): value is Blob {\n return typeof Blob !== \"undefined\" && value instanceof Blob;\n}\n","import type { PolicySpec } from \"../policy/policy.js\";\nimport type {\n ArtifactLineage,\n ArtifactTransformDescriptor,\n} from \"./lineage.js\";\nimport { inferMediaType, measureArtifactValue } from \"./metadata.js\";\n\nexport type ArtifactKind =\n | \"text\"\n | \"json\"\n | \"file\"\n | \"image\"\n | \"audio\"\n | \"video\"\n | \"document\"\n | \"url\"\n | \"tool-result\";\n\ntype ProviderUploadArtifactSource = `provider-${\"up\"}${\"load\"}`;\n\nexport type ArtifactSource =\n | \"inline\"\n | \"file\"\n | \"url\"\n | \"generated\"\n | ProviderUploadArtifactSource\n | \"tool\";\n\nexport type ArtifactPrivacy = NonNullable<PolicySpec[\"privacy\"]>;\n\nexport interface ArtifactSize {\n readonly bytes?: number;\n readonly characters?: number;\n readonly pages?: number;\n readonly width?: number;\n readonly height?: number;\n readonly durationMs?: number;\n}\n\nexport interface ArtifactFingerprint {\n readonly algorithm: \"sha256\";\n readonly value: string;\n}\n\nexport interface ArtifactStorageRef {\n readonly storeId: string;\n readonly key: string;\n}\n\nexport interface ArtifactOptions {\n readonly id?: string;\n readonly mediaType?: string;\n readonly label?: string;\n readonly metadata?: Record<string, unknown>;\n readonly privacy?: ArtifactPrivacy;\n readonly size?: ArtifactSize;\n readonly fingerprint?: ArtifactFingerprint;\n readonly storage?: ArtifactStorageRef;\n readonly lineage?: ArtifactLineage;\n}\n\nexport interface ArtifactToolResultOptions extends ArtifactOptions {\n readonly toolName: string;\n readonly callId?: string;\n}\n\nexport interface ArtifactDerivedOptions extends ArtifactOptions {\n readonly kind: ArtifactKind;\n readonly source?: ArtifactSource;\n readonly value?: unknown;\n readonly parents: readonly ArtifactRef[];\n readonly transform: ArtifactTransformDescriptor;\n}\n\nexport interface ArtifactRef {\n readonly id: string;\n readonly kind: ArtifactKind;\n readonly mediaType?: string;\n readonly source: ArtifactSource;\n readonly label?: string;\n readonly metadata?: Record<string, unknown>;\n readonly privacy: ArtifactPrivacy;\n readonly size?: ArtifactSize;\n readonly fingerprint?: ArtifactFingerprint;\n readonly storage?: ArtifactStorageRef;\n readonly lineage?: ArtifactLineage;\n}\n\nexport type ArtifactInput = ArtifactRef & {\n readonly value?: unknown;\n};\n\nexport const artifact = {\n text(value: string, options: ArtifactOptions = {}): ArtifactInput {\n return createArtifact(\"text\", \"inline\", value, options, \"text/plain\");\n },\n\n json(value: unknown, options: ArtifactOptions = {}): ArtifactInput {\n return createArtifact(\"json\", \"inline\", value, options, \"application/json\");\n },\n\n file(value: Blob | File | string, options: ArtifactOptions = {}): ArtifactInput {\n return createArtifact(\"file\", \"file\", value, options);\n },\n\n image(value: Blob | File | string, options: ArtifactOptions = {}): ArtifactInput {\n return createArtifact(\"image\", \"file\", value, options);\n },\n\n audio(value: Blob | File | string, options: ArtifactOptions = {}): ArtifactInput {\n return createArtifact(\"audio\", \"file\", value, options);\n },\n\n document(value: Blob | File | string, options: ArtifactOptions = {}): ArtifactInput {\n return createArtifact(\"document\", \"file\", value, options);\n },\n\n url(value: string | URL, options: ArtifactOptions = {}): ArtifactInput {\n return createArtifact(\"url\", \"url\", value.toString(), options);\n },\n\n toolResult(value: unknown, options: ArtifactToolResultOptions): ArtifactInput {\n return createArtifact(\n \"tool-result\",\n \"tool\",\n value,\n {\n ...options,\n metadata: {\n ...options.metadata,\n toolName: options.toolName,\n ...(options.callId !== undefined ? { callId: options.callId } : {}),\n },\n },\n \"application/json\",\n );\n },\n\n derive(input: ArtifactDerivedOptions): ArtifactInput {\n const {\n kind,\n source = \"generated\",\n value,\n parents,\n transform,\n ...options\n } = input;\n\n return createArtifact(kind, source, value, {\n ...options,\n lineage: {\n parents: parents.map(toArtifactRef),\n transform,\n },\n }, defaultMediaTypeForKind(kind));\n },\n};\n\nexport function toArtifactRef(input: ArtifactInput | ArtifactRef): ArtifactRef {\n return {\n id: input.id,\n kind: input.kind,\n source: input.source,\n privacy: input.privacy,\n ...(input.mediaType !== undefined ? { mediaType: input.mediaType } : {}),\n ...(input.label !== undefined ? { label: input.label } : {}),\n ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n ...(input.size !== undefined ? { size: input.size } : {}),\n ...(input.fingerprint !== undefined ? { fingerprint: input.fingerprint } : {}),\n ...(input.storage !== undefined ? { storage: input.storage } : {}),\n ...(input.lineage !== undefined ? { lineage: input.lineage } : {}),\n };\n}\n\nexport function isArtifactRef(value: unknown): value is ArtifactRef {\n if (!isRecord(value)) {\n return false;\n }\n\n return (\n typeof value.id === \"string\" &&\n isArtifactKind(value.kind) &&\n isArtifactSource(value.source) &&\n isArtifactPrivacy(value.privacy)\n );\n}\n\nfunction createArtifact(\n kind: ArtifactKind,\n source: ArtifactSource,\n value: unknown,\n options: ArtifactOptions,\n defaultMediaType?: string,\n): ArtifactInput {\n const mediaType = inferMediaType(value, {\n kind,\n ...(options.mediaType !== undefined ? { mediaType: options.mediaType } : {}),\n ...(defaultMediaType !== undefined ? { defaultMediaType } : {}),\n });\n const size = options.size ?? measureArtifactValue(value, kind);\n\n return {\n id: options.id ?? createArtifactId(kind),\n kind,\n source,\n value,\n privacy: options.privacy ?? \"standard\",\n ...(mediaType !== undefined ? { mediaType } : {}),\n ...(options.label !== undefined ? { label: options.label } : {}),\n ...(options.metadata !== undefined ? { metadata: options.metadata } : {}),\n ...(size !== undefined ? { size } : {}),\n ...(options.fingerprint !== undefined ? { fingerprint: options.fingerprint } : {}),\n ...(options.storage !== undefined ? { storage: options.storage } : {}),\n ...(options.lineage !== undefined ? { lineage: options.lineage } : {}),\n };\n}\n\nfunction defaultMediaTypeForKind(kind: ArtifactKind): string | undefined {\n switch (kind) {\n case \"text\":\n return \"text/plain\";\n case \"json\":\n case \"tool-result\":\n return \"application/json\";\n default:\n return undefined;\n }\n}\n\nfunction isArtifactKind(value: unknown): value is ArtifactKind {\n return (\n value === \"text\" ||\n value === \"json\" ||\n value === \"file\" ||\n value === \"image\" ||\n value === \"audio\" ||\n value === \"video\" ||\n value === \"document\" ||\n value === \"url\" ||\n value === \"tool-result\"\n );\n}\n\nfunction isArtifactSource(value: unknown): value is ArtifactSource {\n return (\n value === \"inline\" ||\n value === \"file\" ||\n value === \"url\" ||\n value === \"generated\" ||\n value === `provider-${\"up\"}${\"load\"}` ||\n value === \"tool\"\n );\n}\n\nfunction isArtifactPrivacy(value: unknown): value is ArtifactPrivacy {\n return value === \"standard\" || value === \"sensitive\" || value === \"restricted\";\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction createArtifactId(kind: ArtifactKind): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return `artifact:${kind}:${crypto.randomUUID()}`;\n }\n\n return `artifact:${kind}:${Date.now()}:${Math.random().toString(16).slice(2)}`;\n}\n","/**\n * Tripwire band pipeline -- Lattice's primitive for ordered, budgeted hook\n * execution around provider + tool boundaries.\n *\n * This module is a SIBLING of tripwire.ts (the pure invariant evaluator) --\n * the two have no callsite coupling. evaluateTripwires stays pure; the\n * band pipeline owns side effects (tracer emit, timing, mutation isolation).\n *\n * Phase 2 (FSB v0.10.0-attempt-2) -- ships:\n * - Priority bands: SAFETY (0) > OBSERVABILITY (1) > EXTENSION (2)\n * - Per-handler regex matcher (opt-in)\n * - Per-handler race-with-log budget (default 100ms; HOOK_TIMEOUT via TracerLike)\n * - structuredClone + Object.freeze context per handler (mutations don't leak)\n * - Irreversible freeze() blocking late register()\n * - HookLifecycleEvent union: BEFORE_PROVIDER, AFTER_PROVIDER, BEFORE_TOOL, AFTER_TOOL\n *\n * Lifecycle event vocabulary is intentionally SEPARATE from tracing.ts's\n * RunEventKind. Run events (\"run.start\", \"provider.attempt\", ...) describe\n * Lattice runtime stages; lifecycle events describe pluggable hook\n * attach-points. Phase 3 may add observability event kinds; Phase 2 ships\n * only the four lifecycle events listed.\n *\n * Race-with-log uses no-abort Promise.race: the handler keeps running\n * in the background after a timeout (CPU-leak risk is acceptable; see\n * 02-CONTEXT.md D-09 and 02-RESEARCH.md CD-01 Resolution).\n */\n\nimport type { TracerLike } from \"../tracing/tracing.js\";\n\n/**\n * Hook lifecycle event vocabulary -- separate from RunEventKind by design.\n *\n * Phase 19 (v1.2) additively extends with BEFORE_AGENT_ITERATION and\n * AFTER_AGENT_ITERATION — emitted by `runAgent` around each iteration's\n * provider call. Existing four events continue to fire inside each\n * iteration (BEFORE/AFTER_PROVIDER per native call; BEFORE/AFTER_TOOL\n * per dispatched tool).\n */\nexport type HookLifecycleEvent =\n | \"BEFORE_PROVIDER\"\n | \"AFTER_PROVIDER\"\n | \"BEFORE_TOOL\"\n | \"AFTER_TOOL\"\n | \"BEFORE_AGENT_ITERATION\"\n | \"AFTER_AGENT_ITERATION\";\n\n/**\n * SAFETY-band veto mechanism — Phase 19.\n *\n * Handlers can deny an iteration by calling `controls.deny(reason)`. The\n * pipeline records the latest reason and exposes it via `lastDenialReason()`.\n * The reason resets at the start of each `run()` call.\n *\n * Composition convention: the agent runtime invokes BEFORE_AGENT_ITERATION\n * before provider call, then checks `pipeline.lastDenialReason()`. If set,\n * the iteration aborts with `agent-iteration-denied` failure.\n */\nexport interface HookDenyDirective {\n readonly reason: string;\n}\n\n/**\n * Controls passed to each handler as an optional second argument.\n *\n * Backward compat: existing single-argument handlers (Phase 15 + Phase 16)\n * ignore this and continue to work unchanged.\n */\nexport interface HookControls {\n /** Set a denial reason; the latest call wins per `run()`. */\n readonly deny: (reason: string) => void;\n}\n\n/**\n * Priority bands. Lower number = higher priority (runs first).\n *\n * SAFETY (0) -- safety / breaker hooks; cannot be overridden by lower bands\n * OBSERVABILITY (1) -- logging, metrics, audit; runs after safety, before extension\n * EXTENSION (2) -- user-supplied hooks; runs last\n *\n * Within a band, handlers run in registration order.\n */\nexport const BAND = {\n SAFETY: 0,\n OBSERVABILITY: 1,\n EXTENSION: 2,\n} as const;\n\nexport type Band = typeof BAND[keyof typeof BAND];\n\nconst BAND_ORDER: readonly Band[] = [BAND.SAFETY, BAND.OBSERVABILITY, BAND.EXTENSION];\n\n/**\n * Handler input -- frozen snapshot of the caller's context at run() time.\n *\n * structuredClone-then-Object.freeze: handlers receive a deep-cloned,\n * surface-frozen view. Mutations on the handler side do NOT leak back to\n * the calling site.\n *\n * The handler's return value is currently ignored; future revisions may\n * add a typed return that downstream bands consume.\n */\nexport interface HookHandler<TContext = unknown> {\n (context: Readonly<TContext>, controls?: HookControls): void | Promise<void>;\n}\n\nexport interface RegisterOptions {\n readonly band: Band;\n readonly matcher?: RegExp;\n readonly budgetMs?: number;\n}\n\n/**\n * The HookPipeline interface returned by createHookPipeline().\n *\n * IMMUTABILITY: once freeze() is called, register() throws an Error whose\n * .name === \"PIPELINE_FROZEN\". freeze() is irreversible by design --\n * protects against late-binding hook injection mid-session.\n */\nexport interface HookPipeline {\n readonly kind: \"hook-pipeline\";\n register<TContext = unknown>(\n event: HookLifecycleEvent,\n handler: HookHandler<TContext>,\n options: RegisterOptions,\n ): void;\n freeze(): void;\n isFrozen(): boolean;\n run<TContext = unknown>(\n event: HookLifecycleEvent,\n context: TContext,\n ): Promise<void>;\n /**\n * Phase 19: returns the latest denial reason set by any handler during\n * the most recent `run()` call. Resets to `null` at the start of each run.\n * Read by the agent runtime to detect SAFETY-band veto.\n */\n lastDenialReason(): string | null;\n}\n\nexport interface CreateHookPipelineOptions {\n readonly tracer?: TracerLike;\n readonly sessionId?: string;\n readonly defaultBudgetMs?: number;\n}\n\nexport const HOOK_DEFAULT_BUDGET_MS = 100;\nexport const PIPELINE_FROZEN_ERROR_NAME = \"PIPELINE_FROZEN\";\nexport const HOOK_TIMEOUT_EVENT_NAME = \"HOOK_TIMEOUT\";\n\ninterface HandlerRecord {\n readonly handler: HookHandler<unknown>;\n readonly matcher?: RegExp;\n readonly budgetMs: number;\n readonly band: Band;\n readonly registrationIndex: number;\n}\n\nfunction freezeContext<T>(ctx: T): Readonly<T> {\n let cloned: T;\n try {\n cloned = structuredClone(ctx);\n } catch {\n cloned = ctx;\n }\n if (typeof cloned === \"object\" && cloned !== null) {\n Object.freeze(cloned);\n }\n return cloned as Readonly<T>;\n}\n\nasync function runHandlerWithBudget(\n record: HandlerRecord,\n ctx: Readonly<unknown>,\n controls: HookControls,\n emit: ((kind: string, payload: Record<string, unknown>) => void) | undefined,\n event: HookLifecycleEvent,\n sessionId: string | undefined,\n): Promise<void> {\n const startedAt = performance.now();\n let timeoutFired = false;\n const budgetMs = record.budgetMs;\n const budgetPromise = new Promise<\"__timeout__\">((resolve) => {\n setTimeout(() => {\n timeoutFired = true;\n resolve(\"__timeout__\");\n }, budgetMs);\n });\n const handlerPromise = (async () => {\n try {\n await record.handler(ctx, controls);\n } catch {\n // handler errors are absorbed (pipeline does not propagate)\n }\n return \"__done__\" as const;\n })();\n const result = await Promise.race([handlerPromise, budgetPromise]);\n if (result === \"__timeout__\" && timeoutFired) {\n const elapsedMs = Math.round(performance.now() - startedAt);\n if (emit !== undefined) {\n emit(HOOK_TIMEOUT_EVENT_NAME, {\n event,\n band: record.band,\n budgetMs,\n ...(sessionId !== undefined ? { sessionId } : {}),\n handlerIndex: record.registrationIndex,\n elapsedMs,\n });\n }\n }\n}\n\n/**\n * Factory: build a fresh hook pipeline.\n */\nexport function createHookPipeline(\n options?: CreateHookPipelineOptions,\n): HookPipeline {\n const tracer = options?.tracer;\n const sessionId = options?.sessionId;\n const defaultBudgetMs = options?.defaultBudgetMs ?? HOOK_DEFAULT_BUDGET_MS;\n const registry: Map<HookLifecycleEvent, Map<Band, HandlerRecord[]>> = new Map();\n let frozen = false;\n let globalRegistrationCounter = 0;\n let currentDenialReason: string | null = null;\n\n // TracerLike.event is optional on the interface; the emit factory bridges\n // through optional-chain so a tracer without an event method (or no tracer\n // at all) becomes a no-op rather than a TypeError. Mirrors the pattern at\n // runtime/create-ai.ts:862 (normalized.tracing?.event?.(...)).\n const emit: ((kind: string, payload: Record<string, unknown>) => void) | undefined =\n tracer !== undefined\n ? (kind, payload) => {\n tracer.event?.(kind, payload);\n }\n : undefined;\n\n function register<TContext = unknown>(\n event: HookLifecycleEvent,\n handler: HookHandler<TContext>,\n opts: RegisterOptions,\n ): void {\n if (frozen) {\n const err = new Error(\"HookPipeline.register() called after freeze()\");\n err.name = PIPELINE_FROZEN_ERROR_NAME;\n throw err;\n }\n let perEventBands = registry.get(event);\n if (perEventBands === undefined) {\n perEventBands = new Map();\n registry.set(event, perEventBands);\n }\n let arr = perEventBands.get(opts.band);\n if (arr === undefined) {\n arr = [];\n perEventBands.set(opts.band, arr);\n }\n const record: HandlerRecord = {\n handler: handler as HookHandler<unknown>,\n ...(opts.matcher !== undefined ? { matcher: opts.matcher } : {}),\n budgetMs: opts.budgetMs ?? defaultBudgetMs,\n band: opts.band,\n registrationIndex: globalRegistrationCounter,\n };\n globalRegistrationCounter += 1;\n arr.push(record);\n }\n\n function freezePipeline(): void {\n frozen = true;\n }\n\n function isFrozen(): boolean {\n return frozen;\n }\n\n async function run<TContext = unknown>(\n event: HookLifecycleEvent,\n context: TContext,\n ): Promise<void> {\n currentDenialReason = null;\n const perEventBands = registry.get(event);\n if (perEventBands === undefined) return;\n const controls: HookControls = {\n deny: (reason: string) => {\n currentDenialReason = reason;\n },\n };\n for (const band of BAND_ORDER) {\n const arr = perEventBands.get(band);\n if (arr === undefined || arr.length === 0) continue;\n for (const record of arr) {\n if (record.matcher !== undefined && !record.matcher.test(event)) {\n continue;\n }\n const ctx = freezeContext(context);\n await runHandlerWithBudget(record, ctx, controls, emit, event, sessionId);\n }\n }\n }\n\n function lastDenialReason(): string | null {\n return currentDenialReason;\n }\n\n const pipeline: HookPipeline = {\n kind: \"hook-pipeline\",\n register,\n freeze: freezePipeline,\n isFrozen,\n run,\n lastDenialReason,\n };\n return pipeline;\n}\n","import canonicalize from \"canonicalize\";\n\nimport type { Usage } from \"../providers/provider.js\";\nimport type {\n CapabilityReceiptBody,\n ReceiptUsageCanonical,\n} from \"./types.js\";\n\nconst encoder = new TextEncoder();\n\n/**\n * Convert costUsd (number | null) to its canonical string form.\n * RFC 8785 requires deterministic float-to-string; using JS Number→string\n * directly is unsafe across V8 versions (Grisu3 vs Dragonbox). We pin the\n * format by routing through Number.prototype.toString() for FINITE numbers\n * only, and treat NaN/Infinity as null. This matches \"I-JSON only\" from\n * 09-CONTEXT.md — receipts NEVER carry non-finite floats.\n */\nexport function stringifyCostUsd(costUsd: number | null): string | null {\n if (costUsd === null) return null;\n if (!Number.isFinite(costUsd)) return null;\n return costUsd.toString();\n}\n\n/**\n * Convert a runtime Usage (number costUsd) to its canonical receipt form\n * (string costUsd). This is the single conversion site — canonical bytes\n * NEVER see a raw float in the cost field.\n */\nexport function usageToCanonical(usage: Usage): ReceiptUsageCanonical {\n return {\n promptTokens: usage.promptTokens,\n completionTokens: usage.completionTokens,\n costUsd: stringifyCostUsd(usage.costUsd),\n };\n}\n\n/**\n * Canonicalize a receipt body to JCS bytes (RFC 8785).\n *\n * INVARIANT: callers MUST pass an already-redacted body. The redactor in\n * redact.ts produces the input to this function — never the cleartext.\n * See 09-CONTEXT.md \"Redact-Then-Sign Ordering (UNRETROFITTABLE)\".\n *\n * Throws if canonicalize returns undefined (impossible for valid bodies\n * — surfaces a programmer error rather than silently producing zero\n * bytes that would later fail signature verification).\n */\nexport function canonicalizeReceiptBody(\n body: CapabilityReceiptBody,\n): Uint8Array {\n const json = canonicalize(body);\n if (json === undefined) {\n throw new Error(\n \"canonicalizeReceiptBody: canonicalize returned undefined; receipt body contained a non-canonicalizable value (function/symbol/undefined).\",\n );\n }\n return encoder.encode(json);\n}\n","/**\n * DSSE-shaped envelope encoder/decoder + Pre-Authentication Encoding (PAE).\n *\n * This module is the single source of truth for:\n * - PAYLOAD_TYPE constant (the receipt media type)\n * - base64 (standard, NOT base64url) encoding helpers\n * - DSSE v1.0 PAE construction: signatures MUST be computed over the bytes\n * returned by buildPae(...), never over raw canonical JSON bytes.\n *\n * Reference: https://github.com/secure-systems-lab/dsse/blob/v1.0.0/protocol.md\n *\n * Reconciled in plan 09-03 to import canonical types from ./types.js (plan\n * 09-01 lands the spine). `_Local` aliases are retained as deprecated type\n * exports for backward compatibility with the Wave 1 sibling imports.\n */\n\nimport type { ReceiptEnvelope, ReceiptSignature } from \"./types.js\";\n\n/**\n * @deprecated Use ReceiptSignature from \"./types.js\". Retained as an alias\n * during the Wave 1 -> Wave 2 reconciliation.\n */\nexport type ReceiptSignature_Local = ReceiptSignature;\n\n/**\n * @deprecated Use ReceiptEnvelope from \"./types.js\". Retained as an alias\n * during the Wave 1 -> Wave 2 reconciliation.\n */\nexport type ReceiptEnvelope_Local = ReceiptEnvelope;\n\nexport const PAYLOAD_TYPE = \"application/vnd.lattice.receipt+json\" as const;\n\nconst textEncoder = new TextEncoder();\n\nexport function base64Encode(bytes: Uint8Array): string {\n return Buffer.from(bytes).toString(\"base64\");\n}\n\nexport function base64Decode(value: string): Uint8Array {\n return new Uint8Array(Buffer.from(value, \"base64\"));\n}\n\n/**\n * DSSE v1.0 Pre-Authentication Encoding.\n *\n * Reference: https://github.com/secure-systems-lab/dsse/blob/v1.0.0/protocol.md\n *\n * PAE = UTF-8(\"DSSEv1 \" + len(payloadType) + \" \" + payloadType\n * + \" \" + len(payload) + \" \" + payload)\n *\n * `payload` here is the BASE64-encoded string per DSSE v1.0 spec (NOT raw\n * canonical bytes). Both signing and verification MUST construct PAE the\n * same way; this module is the single source of truth.\n *\n * ASCII length is decimal (no zero-padding). e.g. length 1000 → \"1000\".\n */\nexport function buildPae(\n payloadType: string,\n payloadBase64: string,\n): Uint8Array {\n const ascii =\n \"DSSEv1 \" +\n payloadType.length.toString() +\n \" \" +\n payloadType +\n \" \" +\n payloadBase64.length.toString() +\n \" \" +\n payloadBase64;\n return textEncoder.encode(ascii);\n}\n\nexport interface EncodeEnvelopeInput {\n readonly payloadBytes: Uint8Array;\n readonly signatures: readonly {\n readonly keyid: string;\n readonly sig: Uint8Array;\n }[];\n}\n\nexport function encodeEnvelope(\n input: EncodeEnvelopeInput,\n): ReceiptEnvelope {\n const payload = base64Encode(input.payloadBytes);\n const signatures: ReceiptSignature[] = input.signatures.map((entry) => ({\n keyid: entry.keyid,\n sig: base64Encode(entry.sig),\n }));\n return {\n payloadType: PAYLOAD_TYPE,\n payload,\n signatures,\n };\n}\n\nexport interface DecodedEnvelope {\n readonly payloadType: string;\n readonly payloadBytes: Uint8Array;\n readonly signatures: readonly {\n readonly keyid: string;\n readonly sig: Uint8Array;\n }[];\n}\n\nexport function decodeEnvelope(\n envelope: ReceiptEnvelope,\n): DecodedEnvelope {\n if (envelope.payloadType !== PAYLOAD_TYPE) {\n throw new Error(\n `envelope payloadType mismatch: expected \"${PAYLOAD_TYPE}\" got \"${envelope.payloadType}\"`,\n );\n }\n return {\n payloadType: envelope.payloadType,\n payloadBytes: base64Decode(envelope.payload),\n signatures: envelope.signatures.map((entry) => ({\n keyid: entry.keyid,\n sig: base64Decode(entry.sig),\n })),\n };\n}\n","import type {\n CapabilityReceiptBody,\n ReceiptRedaction,\n} from \"./types.js\";\n\n/**\n * Default redaction policy id for v1.1. Free-form string per\n * 09-CONTEXT.md — registry enforcement deferred to v1.2.\n */\nexport const DEFAULT_REDACTION_POLICY_ID = \"lattice.default.v1\";\n\nexport interface RedactionResult {\n readonly body: CapabilityReceiptBody;\n readonly redactions: readonly ReceiptRedaction[];\n}\n\n/**\n * Redact a receipt body BEFORE canonicalization (and BEFORE signing).\n *\n * The signed digest commits to canonicalize(redact(body)). NEVER the\n * other way around. See 09-CONTEXT.md \"Redact-Then-Sign Ordering\n * (UNRETROFITTABLE)\" and PITFALLS.md Pitfall #1.\n *\n * For v1.1 the default policy is minimal — the heavy lifting already\n * happened upstream:\n * - Tripwire evaluator emits {detector, substring} for no-pii (T-08-01).\n * - Provider responses are hashed into inputHashes/outputHash, never\n * embedded raw.\n * - Router reject messages do not contain PII by construction.\n *\n * This function therefore primarily:\n * 1. Materializes the redactions[] manifest declaring what WAS elided\n * upstream (so receipts are self-describing).\n * 2. Provides the extension point future policies will use.\n *\n * Returns a NEW body — never mutates the input.\n */\nexport function redactReceiptBody(\n body: CapabilityReceiptBody,\n policyId: string = DEFAULT_REDACTION_POLICY_ID,\n): RedactionResult {\n const redactions: ReceiptRedaction[] = [];\n\n // Record the no-pii redaction as a declared manifest entry.\n // The tripwire kernel ALREADY redacted to {detector, substring};\n // this only declares that the redaction happened so verifiers can\n // see it in the signed body.\n if (\n body.tripwireEvidence !== undefined &&\n body.tripwireEvidence.kind === \"no-pii\"\n ) {\n redactions.push({\n path: \"tripwireEvidence.observed\",\n reason: \"no-pii-detector-substring-only\",\n });\n }\n\n // Sort redactions by path for canonical-form stability (sorted arrays\n // canonicalize identically regardless of insertion order).\n const sorted = [...redactions].sort((a, b) =>\n a.path < b.path ? -1 : a.path > b.path ? 1 : 0,\n );\n\n return {\n body: {\n ...body,\n redactionPolicyId: policyId,\n redactions: sorted,\n },\n redactions: sorted,\n };\n}\n","import type { TrainingClass } from \"../capabilities/profile.js\";\nimport type { TripwireEvidence } from \"../contract/tripwire.js\";\nimport type { RouteRejectReason } from \"../plan/plan.js\";\nimport type { Usage } from \"../providers/provider.js\";\n\nimport { canonicalizeReceiptBody, usageToCanonical } from \"./canonical.js\";\nimport {\n PAYLOAD_TYPE,\n base64Encode,\n buildPae,\n encodeEnvelope,\n} from \"./envelope.js\";\nimport { DEFAULT_REDACTION_POLICY_ID, redactReceiptBody } from \"./redact.js\";\nimport type {\n CapabilityReceiptBody,\n ContractVerdict,\n ReceiptEnvelope,\n ReceiptModel,\n ReceiptRoute,\n ReceiptSigner,\n} from \"./types.js\";\n\n/**\n * Public input to createReceipt. Mirrors CapabilityReceiptBody minus:\n * - `version` (forced to \"lattice-receipt/v1.3\" per Phase 46)\n * - `kid` (forced from signer.kid — caller cannot mismatch)\n * - `redactions[]` (populated by redactReceiptBody)\n * - `usage.costUsd` (converted to canonical string by usageToCanonical)\n *\n * receiptId and issuedAt default to runtime-generated values when omitted.\n * redactionPolicyId defaults to DEFAULT_REDACTION_POLICY_ID.\n */\nexport interface CreateReceiptInput {\n readonly runId: string;\n readonly issuedAt?: string;\n readonly receiptId?: string;\n readonly model: ReceiptModel;\n readonly route: ReceiptRoute;\n readonly modelClass?: TrainingClass;\n // Phase 39 (DELEG-06): chain-link to the parent receipt's CID\n // (`sha256:<hex>` of the parent envelope's canonical payload bytes,\n // derived via receipts/cid.ts receiptCid). Omit for root/non-crew receipts.\n readonly parentReceiptCid?: string;\n readonly lineageMerkleRoot?: string;\n readonly usage: Usage;\n readonly contractVerdict: ContractVerdict;\n readonly contractHash: string | null;\n readonly inputHashes: readonly string[];\n readonly outputHash: string | null;\n readonly redactionPolicyId?: string;\n readonly noRouteReasons?: readonly RouteRejectReason[];\n readonly tripwireEvidence?: TripwireEvidence;\n // Phase 2 v1.1 step-marker fields. All optional; populated when a step\n // transition emits a receipt. Phase 26 (CRYPTO-01) collapsed the v1/v1.1\n // version-bump heuristic to ALWAYS emit \"lattice-receipt/v1.1\" since v1\n // receipts can no longer pass verifyReceipt (receipt-downgrade defense).\n readonly stepName?: string;\n readonly stepIndex?: number;\n readonly parentStepName?: string;\n readonly previousStepName?: string;\n readonly sessionId?: string;\n readonly timestamp?: string;\n}\n\n/**\n * Build, redact, canonicalize, sign, and envelope a CapabilityReceipt.\n *\n * Ordering INVARIANT (09-CONTEXT.md, PITFALLS.md Pitfall #1):\n * redact -> canonicalize -> PAE -> sign -> encode\n *\n * The signed digest commits to canonicalize(redact(body)). The function\n * structure makes any other ordering impossible to write by accident —\n * canonicalizeReceiptBody is ONLY called on the output of redactReceiptBody.\n *\n * Defense in depth:\n * - body.kid is assigned from signer.kid, never from input (input has no\n * kid field). The signed body and the envelope keyid CANNOT disagree by\n * construction.\n * - signer.kid is also written to envelope.signatures[0].keyid, so the\n * verifier can cross-check (Step 7 of verifyReceipt).\n *\n * I-JSON guarantees: usage.costUsd is converted to string (or null) via\n * usageToCanonical. Receipts NEVER carry raw floats in the canonical form.\n */\nexport async function createReceipt(\n input: CreateReceiptInput,\n signer: ReceiptSigner,\n): Promise<ReceiptEnvelope> {\n const policyId = input.redactionPolicyId ?? DEFAULT_REDACTION_POLICY_ID;\n const receiptId = input.receiptId ?? crypto.randomUUID();\n const issuedAt = input.issuedAt ?? new Date().toISOString();\n\n // Phase 46: always emit v1.3. v1.1/v1.2 remain verifier-compatible, but\n // new receipts can carry the optional lineageMerkleRoot provenance field.\n const version: CapabilityReceiptBody[\"version\"] = \"lattice-receipt/v1.3\";\n\n // Step 1: assemble the raw body. `kid` comes from the signer — caller\n // cannot mismatch it. `usage.costUsd` is converted to string (I-JSON).\n const body0: CapabilityReceiptBody = {\n version,\n receiptId,\n runId: input.runId,\n issuedAt,\n kid: signer.kid,\n model: input.model,\n route: input.route,\n ...(input.modelClass !== undefined ? { modelClass: input.modelClass } : {}),\n ...(input.parentReceiptCid !== undefined ? { parentReceiptCid: input.parentReceiptCid } : {}),\n ...(input.lineageMerkleRoot !== undefined ? { lineageMerkleRoot: input.lineageMerkleRoot } : {}),\n usage: usageToCanonical(input.usage),\n contractVerdict: input.contractVerdict,\n contractHash: input.contractHash,\n inputHashes: input.inputHashes,\n outputHash: input.outputHash,\n redactionPolicyId: policyId,\n redactions: [],\n ...(input.noRouteReasons !== undefined\n ? { noRouteReasons: input.noRouteReasons }\n : {}),\n ...(input.tripwireEvidence !== undefined\n ? { tripwireEvidence: input.tripwireEvidence }\n : {}),\n // v1.1 step-marker fields (conditional-spread to honor exactOptionalPropertyTypes)\n ...(input.stepName !== undefined ? { stepName: input.stepName } : {}),\n ...(input.stepIndex !== undefined ? { stepIndex: input.stepIndex } : {}),\n ...(input.parentStepName !== undefined ? { parentStepName: input.parentStepName } : {}),\n ...(input.previousStepName !== undefined ? { previousStepName: input.previousStepName } : {}),\n ...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),\n ...(input.timestamp !== undefined ? { timestamp: input.timestamp } : {}),\n };\n\n // Step 2: redact BEFORE canonicalize. body now carries the redactions[]\n // manifest declaring what was elided.\n const { body } = redactReceiptBody(body0, policyId);\n\n // Step 3: canonicalize the redacted body (RFC 8785 JCS).\n const payloadBytes = canonicalizeReceiptBody(body);\n\n // Step 4: base64-encode for the envelope (DSSE wire format).\n const payload = base64Encode(payloadBytes);\n\n // Step 5: build PAE — Pre-Authentication Encoding per DSSE v1.0.\n const pae = buildPae(PAYLOAD_TYPE, payload);\n\n // Step 6: sign the PAE bytes.\n const sig = await signer.sign(pae);\n\n // Step 7: assemble the envelope. signer.kid duplicated in signatures[]\n // even though it is ALSO inside the signed body (defense in depth).\n return encodeEnvelope({\n payloadBytes,\n signatures: [{ keyid: signer.kid, sig }],\n });\n}\n","/**\n * Checkpoint hook -- Lattice's per-step receipt + tracer-event primitive.\n *\n * This module is a SIBLING of bands.ts (the hook pipeline factory) and\n * receipt.ts (the Capability Receipt mint). It does NOT modify either; the\n * checkpoint hook is composed from both surfaces.\n *\n * Phase 3 (FSB v0.10.0-attempt-2) -- ships:\n * - createCheckpointHook(options) factory returning a HookHandler\n * - One signed v1.2 Capability Receipt minted per handler invocation\n * (when a signer is configured); body carries step-marker fields\n * - Exactly one \"step.transition\" tracer event emitted per invocation\n * (when a tracer is configured); metadata carries the same step\n * fields plus runId and either receiptId (mint success) or mintError\n * (mint failed)\n *\n * Registration convention (D-06): the caller registers the returned\n * handler on a HookPipeline at BAND.OBSERVABILITY -- between SAFETY\n * (must run first) and EXTENSION (user-supplied; runs last). The factory\n * exposes DEFAULT_CHECKPOINT_BAND as a re-export of BAND.OBSERVABILITY\n * for clarity at the registration site. The factory does NOT auto-\n * register -- the caller owns lifecycle.\n *\n * Best-effort mint contract (D-07): signer.sign() failures are caught\n * by an internal try/catch; the handler emits a tracer event with\n * mintError (no throw upstream). Mirrors maybeIssueReceipt at\n * create-ai.ts:956-992. Callers cannot rely on receipt minting; if\n * minting is required for correctness, the caller must inspect the\n * envelope returned via the tracer event (event.metadata.envelope) AND\n * check mintError absence.\n *\n * Step-marker field contract (carries forward Phase 2 D-04):\n * - stepName, parentStepName, previousStepName, sessionId are STABLE\n * IDENTIFIERS, NOT user content. Callers MUST NOT populate them\n * with free-form user input -- those fields appear cleartext in\n * the signed receipt (the redaction manifest at redact.ts\n * intentionally does NOT cover them per Phase 2 D-04).\n * - timestamp is ISO-8601 RFC 3339 (e.g., \"2026-05-24T18:00:00.000Z\").\n * - stepIndex is a monotonically increasing ordinal supplied by the\n * caller. The handler does NOT auto-increment -- the caller owns\n * ordering (typically via session state).\n *\n * Tracer event vocabulary (D-01):\n * - Event name: \"step.transition\" (added to RunEventKind in the\n * preceding tracing.ts commit; namespace-sibling of run.start /\n * stage.start / provider.attempt / tool.call).\n * - Metadata keys (flat -- CD-01 resolved to flat per existing\n * emitEvent at create-ai.ts:862-868):\n * { stepName, stepIndex, parentStepName?, previousStepName?,\n * sessionId?, timestamp, runId,\n * receiptId? | mintError?, envelope? }\n * - envelope (the minted ReceiptEnvelope) is included on success so\n * downstream subscribers can persist or display the signed receipt\n * without re-minting.\n *\n * Vocabulary separation (D-02): HookLifecycleEvent (bands.ts) and\n * RunEventKind (tracing.ts) remain SEPARATE unions. This module\n * subscribes to HookLifecycleEvent (the caller registers on BEFORE_TOOL\n * or AFTER_TOOL or wherever) and emits a RunEventKind tracer event.\n * The two vocabularies meet only at the checkpoint hook boundary.\n */\n\nimport type { ReceiptEnvelope, ReceiptModel, ReceiptRoute, ReceiptSigner } from \"../receipts/types.js\";\nimport { createReceipt, type CreateReceiptInput } from \"../receipts/receipt.js\";\nimport type { TracerLike } from \"../tracing/tracing.js\";\n\nimport { BAND, type Band, type HookHandler } from \"./bands.js\";\n\n/**\n * The tracer event name Lattice's checkpoint hook emits per step transition.\n * Identical to the literal added to RunEventKind in tracing.ts.\n */\nexport const STEP_TRANSITION_EVENT_NAME = \"step.transition\" as const;\n\n/**\n * Default band convention for the checkpoint hook (D-06). The caller is\n * free to register in a different band but the documented convention is\n * OBSERVABILITY -- between SAFETY (runs first) and EXTENSION (runs last).\n */\nexport const DEFAULT_CHECKPOINT_BAND: Band = BAND.OBSERVABILITY;\n\n/**\n * Per-step context the caller passes through the hook pipeline.\n *\n * Fields are stable identifiers (D-04 carryforward); do NOT populate with\n * user content -- they appear cleartext in the signed receipt body.\n *\n * - stepName: required. Stable identifier for this step.\n * - stepIndex: required. Monotonically increasing ordinal; caller-owned.\n * - parentStepName: optional. Names the enclosing step when nested.\n * - previousStepName: optional. Names the immediately-prior step in the\n * linked-list timeline (D-09 linked-list threading).\n * - timestamp: required. ISO-8601 RFC 3339.\n */\nexport interface CheckpointHookContext {\n readonly stepName: string;\n readonly stepIndex: number;\n readonly parentStepName?: string;\n readonly previousStepName?: string;\n readonly timestamp: string;\n}\n\n/**\n * The factory's options.\n *\n * - runId: required. Threaded into every receipt body + every tracer event.\n * - tracer: optional. When omitted, the handler still mints (when signer\n * present) but does NOT emit a tracer event. When provided, the handler\n * ALWAYS emits exactly one event per invocation (independent of mint\n * success/failure per D-10).\n * - signer: optional. When omitted, the handler emits a tracer event only\n * (no mint attempted). When provided, the handler attempts to mint via\n * createReceipt(...) inside a try/catch (D-07 best-effort).\n * - sessionId: optional. Threaded into receipt body and event metadata.\n * - model: optional. ReceiptModel descriptor for the receipt body; the\n * factory provides a sensible \"step\" default when omitted.\n * - route: optional. ReceiptRoute descriptor for the receipt body; the\n * factory provides a sensible \"step\" default when omitted.\n * - contractVerdict: optional. Defaults to \"success\" -- step transitions\n * are observability events, not contract evaluations.\n */\nexport interface CheckpointHookOptions {\n readonly runId: string;\n readonly tracer?: TracerLike;\n readonly signer?: ReceiptSigner;\n readonly sessionId?: string;\n readonly model?: ReceiptModel;\n readonly route?: ReceiptRoute;\n readonly contractVerdict?: CreateReceiptInput[\"contractVerdict\"];\n}\n\nconst DEFAULT_MODEL: ReceiptModel = {\n requested: \"lattice-checkpoint/observability\",\n observed: null,\n};\n\nconst DEFAULT_ROUTE: ReceiptRoute = {\n providerId: \"lattice-checkpoint\",\n capabilityId: \"lattice-checkpoint/step-transition\",\n attemptNumber: 1,\n};\n\nconst DEFAULT_USAGE = {\n promptTokens: 0,\n completionTokens: 0,\n costUsd: null as null,\n};\n\n/**\n * Build a checkpoint hook handler.\n *\n * The returned handler is suitable for registration on a HookPipeline\n * created via createHookPipeline (see ./bands.ts). The handler does not\n * auto-register; the caller passes it to pipeline.register(...) with the\n * desired lifecycle event (typically AFTER_TOOL or BEFORE_TOOL) and band\n * (typically BAND.OBSERVABILITY, exported as DEFAULT_CHECKPOINT_BAND).\n *\n * Per-invocation behavior:\n * 1. Build event metadata from options + per-call context.\n * 2. If signer is configured, attempt createReceipt(...) inside a\n * try/catch. On success, set metadata.receiptId + metadata.envelope.\n * On failure, set metadata.mintError (string from caught error).\n * 3. If tracer is configured, emit exactly one tracer.event?.(\n * STEP_TRANSITION_EVENT_NAME, metadata) call.\n * 4. Return void.\n *\n * NO upstream throw (D-07). NO global mutation (D-05).\n */\nexport function createCheckpointHook(\n options: CheckpointHookOptions,\n): HookHandler<CheckpointHookContext> {\n const runId = options.runId;\n const tracer = options.tracer;\n const signer = options.signer;\n const sessionId = options.sessionId;\n const model = options.model ?? DEFAULT_MODEL;\n const route = options.route ?? DEFAULT_ROUTE;\n const contractVerdict = options.contractVerdict ?? \"success\";\n\n return async function checkpointHookHandler(\n ctx: Readonly<CheckpointHookContext>,\n ): Promise<void> {\n // Step 1: assemble event metadata. Optional context fields are spread\n // conditionally to honor exactOptionalPropertyTypes (mirrors the\n // conditional-spread pattern in receipt.ts createReceipt).\n const baseMetadata: Record<string, unknown> = {\n runId,\n stepName: ctx.stepName,\n stepIndex: ctx.stepIndex,\n timestamp: ctx.timestamp,\n ...(ctx.parentStepName !== undefined ? { parentStepName: ctx.parentStepName } : {}),\n ...(ctx.previousStepName !== undefined ? { previousStepName: ctx.previousStepName } : {}),\n ...(sessionId !== undefined ? { sessionId } : {}),\n };\n\n // Step 2: best-effort receipt mint (D-07). The try/catch absorbs\n // signer.sign() failures so the handler never throws upstream.\n let envelope: ReceiptEnvelope | undefined;\n let receiptId: string | undefined;\n let mintError: string | undefined;\n if (signer !== undefined) {\n try {\n const input: CreateReceiptInput = {\n runId,\n model,\n route,\n usage: DEFAULT_USAGE,\n contractVerdict,\n contractHash: null,\n inputHashes: [],\n outputHash: null,\n stepName: ctx.stepName,\n stepIndex: ctx.stepIndex,\n timestamp: ctx.timestamp,\n ...(ctx.parentStepName !== undefined ? { parentStepName: ctx.parentStepName } : {}),\n ...(ctx.previousStepName !== undefined ? { previousStepName: ctx.previousStepName } : {}),\n ...(sessionId !== undefined ? { sessionId } : {}),\n };\n envelope = await createReceipt(input, signer);\n // Re-derive receiptId from the envelope by decoding the canonical\n // payload bytes. createReceipt does not return the body directly;\n // the receiptId lives inside the payload. We pull it back so\n // subscribers can correlate the tracer event to the receipt\n // without re-decoding the envelope themselves.\n receiptId = extractReceiptId(envelope);\n } catch (err) {\n mintError = err instanceof Error ? err.message : String(err);\n }\n }\n\n // Step 3: assemble the final metadata + emit. tracer.event?.() is\n // optional-chained per the established pattern (create-ai.ts:862).\n const metadata: Record<string, unknown> = {\n ...baseMetadata,\n ...(receiptId !== undefined ? { receiptId } : {}),\n ...(envelope !== undefined ? { envelope } : {}),\n ...(mintError !== undefined ? { mintError } : {}),\n };\n tracer?.event?.(STEP_TRANSITION_EVENT_NAME, metadata);\n };\n}\n\n/**\n * Decode the canonical payload of a freshly-minted envelope and return\n * its receiptId. The envelope's payload is base64-encoded JSON of the\n * signed body (DSSE v1.0 form); receiptId is a top-level field.\n *\n * Returns undefined if decoding fails (defensive -- the handler still\n * emits the tracer event with the envelope itself so subscribers can\n * re-derive the id if they want).\n */\nfunction extractReceiptId(envelope: ReceiptEnvelope): string | undefined {\n try {\n // base64 decode without depending on Node-only Buffer.\n const bytes = Uint8Array.from(atob(envelope.payload), (c) => c.charCodeAt(0));\n const body = JSON.parse(new TextDecoder().decode(bytes)) as { receiptId?: unknown };\n return typeof body.receiptId === \"string\" ? body.receiptId : undefined;\n } catch {\n return undefined;\n }\n}\n","/**\n * formatToolsForProvider — Phase 19 (v1.2).\n *\n * The agent loop runs over the existing v1.1 + v1.2 `ProviderAdapter`\n * interface unchanged (CONTEXT.md Q2). Adapters accept only a single\n * `task: string` plus `outputs[]` — they have no native multi-turn or\n * tool-use surface.\n *\n * This helper bridges that gap by encoding the running conversation +\n * tool descriptions + a structured \"respond with this envelope\" instruction\n * into the `task` string. The model is asked to either answer directly or\n * emit a JSON envelope on a line by itself. `parseToolUse` extracts the\n * envelope.\n *\n * The implementation works ACROSS all 7 logical providers (openai,\n * openai-compat, anthropic, gemini, xai, openrouter, lm-studio) by virtue\n * of being provider-agnostic: it uses the adapter's normalized text\n * response (`ProviderRunResponse.rawOutputs`) and never touches the\n * provider-specific request shape. Native tool_use (Anthropic Messages-API\n * `tools[]`, OpenAI Chat-Completions `tools[]`, Gemini `function_declarations`)\n * is DEFERRED to a follow-on milestone where the `ProviderAdapter` interface\n * can be additively extended without breaking the INV-03 parity contract\n * shipped in v1.2 Phase 17.\n *\n * Returned closure shape:\n * {\n * buildTask(conversation, system?) — encodes turns + tools + envelope\n * instructions into a single string;\n * parseToolUse(text) — extracts JSON tool-call envelopes\n * from the response, returns null\n * when the response is a final answer;\n * describeForSystem() — returns the static tool-description\n * block (for tracing / logging);\n * }\n */\n\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\nimport type { ToolDefinition } from \"../tools/tools.js\";\nimport type { ToolUseRequest } from \"./types.js\";\n\n/**\n * One turn in the running conversation.\n *\n * `role: \"tool\"` is used for tool-result turns; `toolCallId` and `toolName`\n * are populated so the model can correlate the result with its prior\n * `tool_call` envelope.\n */\nexport interface ConversationTurn {\n readonly role: \"user\" | \"assistant\" | \"tool\";\n readonly content: string;\n readonly toolCallId?: string;\n readonly toolName?: string;\n}\n\nexport type FormatToolsMode = \"native\" | \"prompt-reencoded\" | \"auto\";\n\nexport interface FormatToolsOptions {\n /**\n * Tool-use protocol mode. Defaults to `\"auto\"`, which currently resolves\n * to `\"prompt-reencoded\"` for ALL 7 providers (Phase 19 simplification —\n * native tool_use deferred to a follow-on milestone). Reserved for\n * forward compatibility.\n */\n readonly mode?: FormatToolsMode;\n /**\n * Optional system prompt to prepend. Useful for setting persona /\n * domain-specific instructions on top of the tool-use envelope.\n */\n readonly system?: string;\n}\n\nexport interface FormattedToolsHandle {\n /**\n * Builds the single `task` string passed to `ProviderAdapter.execute()`.\n * Encodes the conversation, available tools, and response-envelope\n * instructions.\n */\n readonly buildTask: (conversation: readonly ConversationTurn[]) => string;\n /**\n * Phase 39 (v1.3): body-only sibling of `buildTask` — identical turn\n * rendering minus the leading system block, so the byte-stable\n * `describeForSystem()` prefix can be hoisted once per crew for\n * prompt-cache sharing without duplication (39-05).\n *\n * Invariant: `describeForSystem() + \"\\n\" + buildTaskBody(conversation)`\n * reconstructs `buildTask(conversation)` byte-for-byte.\n */\n readonly buildTaskBody: (conversation: readonly ConversationTurn[]) => string;\n /**\n * Parses the assistant's response text. Returns:\n * - `ToolUseRequest[]` when the response contains one or more tool-call\n * envelopes (parsed in declaration order).\n * - `null` when the response is a final answer (no tool-call envelopes\n * detected).\n *\n * The parser is forgiving: it tolerates extra prose around the JSON\n * envelope (markdown fences, leading explanations) and the model\n * occasionally drifting on whitespace.\n */\n readonly parseToolUse: (responseText: string) => ReadonlyArray<ToolUseRequest> | null;\n /**\n * Returns the static system block describing available tools. Useful for\n * tracing / logging the exact tool-description text fed to the model.\n */\n readonly describeForSystem: () => string;\n /**\n * Effective mode this handle resolved to (`\"prompt-reencoded\"` for all\n * v1.2 providers). Exposed for inspectability.\n */\n readonly mode: \"prompt-reencoded\";\n}\n\n/**\n * Convert a Standard Schema to a JSON Schema-shaped descriptor suitable for\n * inclusion in an LLM tool description. Standard Schema vendors can\n * optionally expose `toJSONSchema` on their schema objects; when absent,\n * we fall back to a minimal structural description that lists the schema\n * vendor + version + a placeholder. Models tolerate placeholder schemas in\n * practice because the tool description is supplementary — what matters\n * is the envelope contract (`{tool_call: {name, args}}`).\n */\nexport function toolSchemaToJsonSchema(schema: StandardSchemaV1): unknown {\n const standardSchema = (schema as unknown as { readonly \"~standard\"?: unknown })[\"~standard\"];\n if (\n typeof standardSchema === \"object\" &&\n standardSchema !== null &&\n \"vendor\" in standardSchema\n ) {\n const vendor = standardSchema as { readonly vendor: string };\n const maybeToJson = (schema as unknown as { readonly toJSONSchema?: () => unknown })\n .toJSONSchema;\n if (typeof maybeToJson === \"function\") {\n try {\n return maybeToJson();\n } catch {\n // fall through to placeholder\n }\n }\n return {\n $comment: `standard-schema vendor: ${vendor.vendor}; toJSONSchema not available`,\n type: \"object\",\n };\n }\n return { $comment: \"non-standard-schema input\", type: \"object\" };\n}\n\n/**\n * Builds the prompt-reencoded tool-use protocol handle for any provider.\n *\n * Phase 19 ships a uniform implementation across all 7 logical providers\n * (openai, openai-compat, anthropic, gemini, xai, openrouter, lm-studio).\n * The `providerName` argument is accepted for forward compatibility but\n * does not branch the implementation in v1.2.\n */\nexport function formatToolsForProvider(\n providerName: string,\n tools: ReadonlyArray<ToolDefinition<StandardSchemaV1>>,\n options: FormatToolsOptions = {},\n): FormattedToolsHandle {\n // mode is currently a forward-compat field — v1.2 resolves all modes to\n // prompt-reencoded.\n void providerName;\n void options.mode;\n\n const system = options.system?.trim() ?? \"\";\n const toolDescriptions = tools\n .map((tool) => {\n const schemaDescriptor = toolSchemaToJsonSchema(tool.inputSchema);\n const schemaJson = JSON.stringify(schemaDescriptor, null, 2);\n const desc = tool.description?.trim() ?? \"(no description)\";\n return `- name: ${tool.name}\\n description: ${desc}\\n args_schema: ${schemaJson}`;\n })\n .join(\"\\n\");\n\n const envelopeInstructions = [\n \"You are a single-agent loop. You can either:\",\n \" (a) answer the user directly with a final response, OR\",\n \" (b) request one or more tool calls.\",\n \"\",\n \"To request tool calls, respond with ONE JSON object on a line by itself:\",\n ' {\"tool_calls\": [{\"id\": \"...\", \"name\": \"tool_name\", \"args\": {...}}]}',\n \"Each tool_call needs a unique id (any string). The args MUST match the tool's args_schema.\",\n \"\",\n \"To answer directly, respond with a final answer in natural language with NO JSON envelope.\",\n \"Do not mix a final answer and a tool_calls envelope in the same response.\",\n ].join(\"\\n\");\n\n const systemBlock = [\n system,\n \"\",\n \"Available tools:\",\n toolDescriptions || \"(none)\",\n \"\",\n envelopeInstructions,\n ]\n .filter((s) => s !== \"\" || true)\n .join(\"\\n\")\n .replace(/^\\n+/, \"\")\n .trimEnd();\n\n function assembleTask(\n conversation: readonly ConversationTurn[],\n includeSystemBlock: boolean,\n ): string {\n const lines: string[] = [];\n if (includeSystemBlock) {\n lines.push(systemBlock);\n }\n lines.push(\"\");\n lines.push(\"---\");\n lines.push(\"\");\n for (const turn of conversation) {\n if (turn.role === \"user\") {\n lines.push(`USER:\\n${turn.content}`);\n } else if (turn.role === \"assistant\") {\n lines.push(`ASSISTANT:\\n${turn.content}`);\n } else {\n const idHint = turn.toolCallId !== undefined ? ` id=${turn.toolCallId}` : \"\";\n const nameHint = turn.toolName !== undefined ? ` name=${turn.toolName}` : \"\";\n lines.push(`TOOL_RESULT (${nameHint.trim() || \"tool\"}${idHint}):\\n${turn.content}`);\n }\n lines.push(\"\");\n }\n lines.push(\"ASSISTANT:\");\n return lines.join(\"\\n\");\n }\n\n function buildTask(conversation: readonly ConversationTurn[]): string {\n return assembleTask(conversation, true);\n }\n\n function buildTaskBody(conversation: readonly ConversationTurn[]): string {\n return assembleTask(conversation, false);\n }\n\n function describeForSystem(): string {\n return systemBlock;\n }\n\n return {\n buildTask,\n buildTaskBody,\n parseToolUse: parseToolUseEnvelope,\n describeForSystem,\n mode: \"prompt-reencoded\",\n };\n}\n\nexport function parseToolUseEnvelope(responseText: string): ReadonlyArray<ToolUseRequest> | null {\n if (typeof responseText !== \"string\" || responseText.length === 0) {\n return null;\n }\n const candidates = extractJsonCandidates(responseText);\n for (const candidate of candidates) {\n const parsed = tryParseEnvelope(candidate);\n if (parsed !== null) {\n return parsed;\n }\n }\n return null;\n}\n\n/**\n * Extracts JSON-looking candidate substrings from a response text.\n *\n * Models routinely wrap JSON in markdown code fences (```json ... ```),\n * prepend explanatory prose (\"I'll call the search tool: { ... }\"), or\n * produce multiple JSON-shaped blobs. This extractor scans for plausible\n * candidates ordered by likelihood.\n */\nfunction extractJsonCandidates(text: string): readonly string[] {\n const candidates: string[] = [];\n // 1) Fenced code blocks (most common formatting).\n const fenceRegex = /```(?:json)?\\s*([\\s\\S]*?)```/g;\n let fenceMatch: RegExpExecArray | null;\n while ((fenceMatch = fenceRegex.exec(text)) !== null) {\n const inner = fenceMatch[1];\n if (inner !== undefined) {\n candidates.push(inner.trim());\n }\n }\n // 2) Top-level braced blobs (greedy match from first '{' to last '}').\n const braceStart = text.indexOf(\"{\");\n const braceEnd = text.lastIndexOf(\"}\");\n if (braceStart !== -1 && braceEnd > braceStart) {\n candidates.push(text.slice(braceStart, braceEnd + 1));\n }\n // 3) Whole text as a candidate (envelope-only response).\n candidates.push(text.trim());\n return candidates;\n}\n\nfunction tryParseEnvelope(jsonLike: string): ReadonlyArray<ToolUseRequest> | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(jsonLike);\n } catch {\n return null;\n }\n if (typeof parsed !== \"object\" || parsed === null) {\n return null;\n }\n const envelope = parsed as Record<string, unknown>;\n const toolCalls = envelope[\"tool_calls\"];\n if (!Array.isArray(toolCalls) || toolCalls.length === 0) {\n return null;\n }\n const requests: ToolUseRequest[] = [];\n for (const call of toolCalls) {\n if (typeof call !== \"object\" || call === null) {\n return null;\n }\n const callRecord = call as Record<string, unknown>;\n const id = callRecord[\"id\"];\n const name = callRecord[\"name\"];\n const args = callRecord[\"args\"];\n if (typeof id !== \"string\" || typeof name !== \"string\") {\n return null;\n }\n requests.push({ id, name, args });\n }\n return requests;\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\nimport { isArtifactRef, toArtifactRef } from \"../artifacts/artifact.js\";\nimport type { ResultPlan } from \"../plan/plan.js\";\nimport type { ValidationIssue } from \"../results/errors.js\";\nimport type { RunResult } from \"../results/result.js\";\nimport type { OutputContract, OutputContractMap } from \"./contracts.js\";\nimport type { InferOutputMap } from \"./infer.js\";\n\nexport async function validateSchemaOutput<S extends StandardSchemaV1>(\n name: string,\n schema: S,\n value: unknown,\n): Promise<\n | { readonly ok: true; readonly value: StandardSchemaV1.InferOutput<S> }\n | {\n readonly ok: false;\n readonly issue: {\n readonly [\"output\"]: string;\n readonly issues: readonly ValidationIssue[];\n };\n }\n> {\n const result = schema[\"~standard\"].validate(value);\n const validation = result instanceof Promise ? await result : result;\n\n if (validation.issues) {\n return {\n ok: false,\n issue: {\n [\"output\"]: name,\n issues: validation.issues.map(normalizeIssue),\n },\n };\n }\n\n return {\n ok: true,\n value: validation.value,\n };\n}\n\nexport async function validateOutputMap<TOutputs extends OutputContractMap>(\n contracts: TOutputs,\n rawOutputs: Record<string, unknown>,\n plan: ResultPlan,\n): Promise<RunResult<TOutputs>> {\n const outputs: Record<string, unknown> = {};\n\n for (const [name, contract] of Object.entries(contracts)) {\n const value = rawOutputs[name];\n const issue = await validateOutput(name, contract, value);\n\n if (!issue.ok) {\n return {\n ok: false,\n error: {\n kind: \"validation\",\n message: `Invalid output \"${name}\".`,\n [\"output\"]: name,\n issues: issue.issues,\n },\n usage: { promptTokens: 0, completionTokens: 0, costUsd: null },\n raw: rawOutputs,\n partialOutputs: outputs,\n plan,\n };\n }\n\n outputs[name] = issue.value;\n }\n\n return {\n ok: true,\n outputs: outputs as InferOutputMap<TOutputs>,\n artifacts: [],\n usage: { promptTokens: 0, completionTokens: 0, costUsd: null },\n plan,\n };\n}\n\nasync function validateOutput(\n name: string,\n contract: OutputContract,\n value: unknown,\n): Promise<\n | { readonly ok: true; readonly value: unknown }\n | { readonly ok: false; readonly issues: readonly ValidationIssue[] }\n> {\n if (contract === \"text\") {\n if (typeof value !== \"string\") {\n return {\n ok: false,\n issues: [{ message: \"Expected text output to be a string.\" }],\n };\n }\n\n return { ok: true, value };\n }\n\n if (isStandardSchema(contract)) {\n const result = await validateSchemaOutput(name, contract, value);\n\n if (!result.ok) {\n return {\n ok: false,\n issues: result.issue.issues,\n };\n }\n\n return { ok: true, value: result.value };\n }\n\n if (contract.kind === \"citations\") {\n if (!Array.isArray(value)) {\n return {\n ok: false,\n issues: [{ message: \"Expected citations output to be an array.\" }],\n };\n }\n\n return { ok: true, value };\n }\n\n if (contract.kind === \"artifacts\") {\n if (!Array.isArray(value)) {\n return {\n ok: false,\n issues: [{ message: \"Expected artifacts output to be an array.\" }],\n };\n }\n\n for (const item of value) {\n if (!isArtifactRef(item)) {\n return {\n ok: false,\n issues: [{ message: \"Expected artifacts output item to be an artifact ref.\" }],\n };\n }\n\n if (contract.artifactKind !== undefined && item.kind !== contract.artifactKind) {\n return {\n ok: false,\n issues: [\n {\n message: `Expected artifacts output item kind to be \"${contract.artifactKind}\".`,\n },\n ],\n };\n }\n }\n\n return { ok: true, value: value.map(toArtifactRef) };\n }\n\n return {\n ok: false,\n issues: [{ message: \"Unsupported output contract.\" }],\n };\n}\n\nfunction isStandardSchema(contract: OutputContract): contract is StandardSchemaV1 {\n if (typeof contract !== \"object\" || contract === null) {\n return false;\n }\n\n const standard = (contract as { readonly \"~standard\"?: { readonly validate?: unknown } })[\n \"~standard\"\n ];\n\n return typeof standard?.validate === \"function\";\n}\n\nfunction normalizeIssue(issue: StandardSchemaV1.Issue): ValidationIssue {\n const path = issue.path\n ?.map(normalizePathSegment)\n .filter((segment): segment is string | number | symbol => segment !== undefined);\n\n return {\n message: issue.message,\n ...(path !== undefined && path.length > 0 ? { path } : {}),\n };\n}\n\nfunction normalizePathSegment(\n segment: PropertyKey | StandardSchemaV1.PathSegment,\n): string | number | symbol | undefined {\n if (\n typeof segment === \"string\" ||\n typeof segment === \"number\" ||\n typeof segment === \"symbol\"\n ) {\n return segment;\n }\n\n return normalizePathKey(segment.key);\n}\n\nfunction normalizePathKey(key: PropertyKey): string | number | symbol {\n return key;\n}\n","/**\n * MV3-survivability adapter contract -- Phase 5 (FSB v0.10.0-attempt-2).\n *\n * This module is a SIBLING of create-ai.ts (the Lattice runtime facade) and\n * a SIBLING of contract/bands.ts (the hook pipeline factory) and\n * contract/checkpoint.ts (the per-step receipt hook). It does NOT modify\n * any of them; the SurvivabilityAdapter contract is composed from those\n * surfaces by the consumer (FSB's lattice-runtime-adapter.js in Plan 05-05).\n *\n * What is the survivability problem?\n * Some host runtimes can evict the execution context mid-flow with no\n * synchronous shutdown signal:\n * - Chrome MV3 service workers: evicted after 30s silence OR 5min idle.\n * - Cloudflare Workers: evicted at end of each request unless waitUntil.\n * - AWS Lambda: process freeze + thaw across invocations.\n * Lattice's existing runtime (create-ai.ts) assumes the process stays\n * live for the duration of a run. The SurvivabilityAdapter contract is\n * the seam where a host runtime tells Lattice \"here is how to serialize\n * my state, here is how to deserialize it back, here is how to resume\n * work after I get evicted and recreated.\"\n *\n * What this module SHIPS:\n * - SurvivabilityAdapter<TState> interface (4 methods)\n * - SerializedSnapshot type (string-encodable opaque envelope)\n * - EvictionHook<TState> type (pre-eviction callback signature)\n * - ResumePolicy literal-union (post-restore reconstruction verdict)\n * - UnsubscribeFn type\n * - createNoopSurvivabilityAdapter() reference implementation\n *\n * What this module DOES NOT ship:\n * - chrome.storage.session integration (FSB-side; Plan 05-05).\n * - offscreen-document message bus (FSB-side; Plan 05-04).\n * - Auto-wiring into create-ai.ts runtime (deferred indefinitely; the\n * contract is consumer-controlled).\n * - Mid-API-request / mid-tool-dispatch recovery dispatcher (CONSERVATIVE\n * recovery wiring is deferred to a follow-on FSB milestone per\n * CONTEXT.md D-22; only the ResumePolicy taxonomy lands here).\n *\n * Composition conventions (NOT enforced; documented for callers):\n * D-09: onEviction hooks SHOULD register in BAND.SAFETY band on the\n * caller's HookPipeline so they run FIRST per Phase 2 priority\n * ordering. This module does NOT auto-register; it ships the\n * contract only.\n * D-10: serialize(state) MAY include the latest checkpoint receipt\n * envelope (Phase 3 createCheckpointHook output) inside the\n * SerializedSnapshot.payload; deserialize() reconstructs session\n * identifiers from the v1.1 receipt body's step-marker fields\n * (stepName, stepIndex, parentStepName, previousStepName,\n * sessionId, timestamp). The payload is opaque to Lattice -- the\n * host runtime defines the shape.\n *\n * ResumePolicy taxonomy (CD-E resolution per attempt-1 02-04-PLAN.md):\n * - SAFE: the snapshot was captured at a safe boundary (BEFORE_ITERATION\n * or BEFORE_NEXT_ITERATION_SCHEDULE step markers) and can be replayed\n * deterministically. The host runtime may re-arm the loop.\n * - RECOVERY_AMBIGUOUS: the snapshot was captured during a tool dispatch\n * where re-execution risk is non-zero (file write, network POST without\n * Idempotency-Key, side-effecting browser action). Host should escalate\n * to the user before deciding.\n * - ON_ERROR_SW_EVICTION_MID_REQUEST: the eviction happened mid-API-call\n * (the provider request was in flight). 6 of 7 FSB providers do NOT\n * document Idempotency-Key headers; replay risks duplicate charges +\n * duplicate responses. Host should treat the run as failed and surface\n * the error to the user.\n * - ON_ERROR_SW_EVICTION_MID_TOOL_DISPATCH: the eviction happened mid-\n * tool-dispatch (a browser action was in progress). Re-execution risk\n * is similar to mid-API-call but lands in a different recovery branch\n * (the host may inspect the page state before deciding).\n *\n * SerializedSnapshot is intentionally opaque + string-encodable. The\n * host runtime defines the payload shape; Lattice's only requirement\n * is that serialize() followed by deserialize() round-trips the state.\n *\n * Ed25519 receipt envelope contract (carries forward from Phase 1-3):\n * Callers MAY embed a v1.1 ReceiptEnvelope inside SerializedSnapshot.payload\n * for signed checkpoint round-trip. verifyReceipt against the embedded\n * envelope MUST return result.ok === true after a serialize -> deserialize\n * cycle (Test 12). This validates that JSON.stringify + JSON.parse over\n * the envelope preserves the JCS-canonical body bytes used by DSSE PAE.\n *\n * Threat model (Phase 5 CONTEXT.md security block):\n * - PII via serialized state: callers MUST ensure SerializedSnapshot.payload\n * contains only stable identifiers + user-controlled state the user has\n * already consented to persist. Mirrors Phase 2 D-04 receipt-body contract\n * (step-marker fields are stable identifiers, not free-form user input).\n * - Snapshot tampering: the noop adapter does NOT sign the snapshot.\n * Callers that need cryptographic integrity SHOULD embed a signed\n * ReceiptEnvelope inside the payload + verify it on deserialize.\n * Phase 5 ships the contract; signature wrapping is a follow-on.\n *\n * Vocabulary separation (carries forward Phase 2 D-12 + Phase 3 D-02):\n * ResumePolicy is the survivability vocabulary -- separate from\n * RunEventKind (tracing) AND separate from HookLifecycleEvent (bands).\n * The three vocabularies meet only when a host runtime composes them.\n */\n\n/**\n * String-encodable opaque snapshot. The host runtime defines the payload\n * shape; Lattice's only requirement is that serialize() followed by\n * deserialize() round-trips the original state object.\n *\n * Why string-encodable? MV3's chrome.storage.session and most cross-process\n * storage layers accept structured-clone-safe values. JSON-string payloads\n * are the lowest-common-denominator that survives MV3 SW eviction +\n * Cloudflare Worker freeze + Lambda thaw. Callers MAY use a richer payload\n * shape (Uint8Array, Blob) IF the host runtime supports it; the contract\n * does not constrain payload format beyond \"deserialize round-trips it\".\n */\nexport interface SerializedSnapshot {\n readonly kind: \"survivability-snapshot\";\n readonly version: \"lattice-survivability/v1\";\n readonly payload: string;\n readonly capturedAt: string;\n}\n\n/**\n * Pre-eviction callback. The host runtime CAN attempt to call this hook\n * before the execution context is evicted, but MAY NOT be able to in\n * every case (MV3 eviction has no synchronous signal -- the SW just\n * stops). Callers should treat onEviction as best-effort: useful for\n * gathering final state when the eviction is announced (e.g., user-\n * initiated stop) but not load-bearing for involuntary eviction.\n *\n * The hook receives the current TState by reference. Mutations on the\n * hook side leak to the caller's state -- this is deliberate (the hook\n * is the LAST chance to update state before eviction). Callers who want\n * structuredClone semantics SHOULD wrap state in their own freeze layer.\n */\nexport type EvictionHook<TState> = (state: TState) => void | Promise<void>;\n\n/**\n * Return value of onEviction(); calling unsubscribes the hook.\n *\n * Idempotent -- calling twice has the same effect as calling once.\n */\nexport type UnsubscribeFn = () => void;\n\n/**\n * Resume policy taxonomy. The host runtime calls adapter.resume(snapshot)\n * after eviction + restore; the returned policy tells the host runtime\n * how to react.\n *\n * The 4 literal members carry forward from FSB v0.10.0-attempt-1's\n * 02-04-PLAN.md CONSERVATIVE recovery dispatch (preserved at\n * .planning/milestones/v0.10.0-attempt-1-pre-pivot/02-state-inspectability-\n * carve-out/02-04-PLAN.md). Per CONTEXT.md CD-E this is the locked union.\n */\nexport type ResumePolicy =\n | \"SAFE\"\n | \"RECOVERY_AMBIGUOUS\"\n | \"ON_ERROR_SW_EVICTION_MID_REQUEST\"\n | \"ON_ERROR_SW_EVICTION_MID_TOOL_DISPATCH\";\n\n/**\n * The SurvivabilityAdapter contract. Host runtimes implement this; Lattice\n * runs against the interface.\n *\n * 4 methods (D-08 locked):\n * - serialize(state): convert in-memory state to SerializedSnapshot\n * - deserialize(snapshot): inverse of serialize\n * - onEviction(hook): register a best-effort pre-eviction callback\n * - resume(snapshot): return ResumePolicy verdict for the post-restore\n * reconstruction. The host runtime acts on the policy.\n *\n * Adapters are POLYMORPHIC over TState -- the host runtime parameterizes\n * the type. Lattice's vitest covers the contract surface with a noop\n * adapter where TState = Record<string, unknown> for ergonomics.\n */\nexport interface SurvivabilityAdapter<TState> {\n readonly kind: \"survivability-adapter\";\n readonly id: string;\n serialize(state: TState): SerializedSnapshot;\n deserialize(snapshot: SerializedSnapshot): TState;\n onEviction(hook: EvictionHook<TState>): UnsubscribeFn;\n resume(snapshot: SerializedSnapshot): Promise<ResumePolicy>;\n}\n\n/**\n * Factory options for the reference noop adapter.\n *\n * - id: optional. Defaults to \"noop-survivability\". Useful when callers\n * want to distinguish multiple adapter instances in test fixtures.\n * - policy: optional. Sets the default ResumePolicy returned by resume().\n * Defaults to \"SAFE\" (matches noop adapter semantics: no recovery\n * ambiguity if nothing was ever persisted).\n */\nexport interface NoopSurvivabilityAdapterOptions {\n readonly id?: string;\n readonly policy?: ResumePolicy;\n}\n\n/**\n * Reference implementation of SurvivabilityAdapter<TState>. Records\n * eviction events but does NOT persist; serialize / deserialize round-\n * trip via JSON.stringify / JSON.parse. Analog to createFakeProvider\n * in the providers/ module -- gives Lattice's vitest a complete shape-\n * conformance target before the real (FSB-side) adapter ships in\n * Plan 05-05.\n *\n * Per CONTEXT.md D-11 the noop adapter ships in Lattice (not FSB)\n * because it covers the contract surface in Lattice's own test suite;\n * FSB's real chrome.storage.session-backed adapter is glue layer.\n */\nexport function createNoopSurvivabilityAdapter<TState = Record<string, unknown>>(\n options: NoopSurvivabilityAdapterOptions = {},\n): SurvivabilityAdapter<TState> {\n const id = options.id ?? \"noop-survivability\";\n const defaultPolicy: ResumePolicy = options.policy ?? \"SAFE\";\n const hooks = new Set<EvictionHook<TState>>();\n\n return {\n kind: \"survivability-adapter\" as const,\n id,\n serialize(state: TState): SerializedSnapshot {\n return {\n kind: \"survivability-snapshot\" as const,\n version: \"lattice-survivability/v1\" as const,\n payload: JSON.stringify(state ?? null),\n capturedAt: new Date().toISOString(),\n };\n },\n deserialize(snapshot: SerializedSnapshot): TState {\n // Trust the contract: callers are responsible for matching the\n // payload shape to TState (noop adapter does not validate).\n return JSON.parse(snapshot.payload) as TState;\n },\n onEviction(hook: EvictionHook<TState>): UnsubscribeFn {\n hooks.add(hook);\n let unsubscribed = false;\n return () => {\n if (unsubscribed) return;\n unsubscribed = true;\n hooks.delete(hook);\n };\n },\n async resume(_snapshot: SerializedSnapshot): Promise<ResumePolicy> {\n // The noop adapter has no persisted state to inspect; it always\n // returns the default policy. Real adapters (Plan 05-05) inspect\n // the snapshot's payload to determine which CONSERVATIVE branch\n // applies.\n return defaultPolicy;\n },\n };\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\nimport { artifact, type ArtifactInput, type ArtifactRef } from \"../artifacts/artifact.js\";\nimport { validateSchemaOutput } from \"../outputs/validate.js\";\nimport type { RunEventSink } from \"../tracing/tracing.js\";\n\nexport interface ToolExecutionContext {\n readonly signal?: AbortSignal;\n readonly emit?: RunEventSink;\n}\n\nexport interface ToolDefinition<TSchema extends StandardSchemaV1 = StandardSchemaV1> {\n readonly kind: \"tool\";\n readonly name: string;\n readonly description?: string;\n readonly inputSchema: TSchema;\n readonly execute: (\n input: StandardSchemaV1.InferOutput<TSchema>,\n context: ToolExecutionContext,\n ) => Promise<unknown> | unknown;\n}\n\nexport interface ToolCallResult {\n readonly callId: string;\n readonly toolName: string;\n readonly artifact: ArtifactInput;\n}\n\nexport function defineTool<TSchema extends StandardSchemaV1>(\n definition: Omit<ToolDefinition<TSchema>, \"kind\">,\n): ToolDefinition<TSchema> {\n return {\n kind: \"tool\",\n ...definition,\n };\n}\n\nexport async function runTool<TSchema extends StandardSchemaV1>(\n tool: ToolDefinition<TSchema>,\n input: unknown,\n context: ToolExecutionContext = {},\n): Promise<ToolCallResult> {\n const validation = await validateSchemaOutput(tool.name, tool.inputSchema, input);\n\n if (!validation.ok) {\n throw new Error(`Invalid input for tool \"${tool.name}\".`);\n }\n\n const callId = createToolCallId();\n const output = await tool.execute(validation.value, context);\n\n return {\n callId,\n toolName: tool.name,\n artifact: artifact.toolResult(output, {\n id: `artifact:tool-result:${tool.name}:${callId}`,\n toolName: tool.name,\n callId,\n }),\n };\n}\n\nexport interface McpLikeClient {\n readonly listTools?: () => Promise<readonly McpToolDescriptor[]> | readonly McpToolDescriptor[];\n readonly callTool: (input: {\n readonly name: string;\n readonly arguments: unknown;\n }) => Promise<unknown> | unknown;\n}\n\nexport interface McpToolDescriptor {\n readonly name: string;\n readonly description?: string;\n readonly inputSchema: StandardSchemaV1;\n}\n\nexport async function importMcpTools(\n client: McpLikeClient,\n toolNames?: readonly string[],\n): Promise<readonly ToolDefinition[]> {\n const descriptors = await Promise.resolve(client.listTools?.() ?? []);\n const allowed = toolNames === undefined ? undefined : new Set(toolNames);\n\n return descriptors\n .filter((descriptor) => allowed === undefined || allowed.has(descriptor.name))\n .map((descriptor) =>\n defineTool({\n name: descriptor.name,\n ...(descriptor.description !== undefined\n ? { description: descriptor.description }\n : {}),\n inputSchema: descriptor.inputSchema,\n execute: async (input) =>\n client.callTool({\n name: descriptor.name,\n arguments: input,\n }),\n }),\n );\n}\n\nexport function toolArtifactRef(result: ToolCallResult): ArtifactRef {\n const { value: _value, ...ref } = result.artifact;\n\n return ref;\n}\n\nfunction createToolCallId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n\n return `${Date.now()}:${Math.random().toString(16).slice(2)}`;\n}\n","/**\n * AgentHost — Phase 20 (v1.2).\n *\n * The pluggable host adapter for `runAgent`. Promotes the Phase 19\n * forward-declared `AgentHost` to a full interface with three optional\n * seams: scheduler (how iterations yield between provider calls),\n * transport (how provider calls are dispatched), and storage (how the\n * agent state persists for resume after eviction).\n *\n * Composition surfaces:\n * - SurvivabilityAdapter (Phase 18) handles serialize/deserialize/resume\n * against the host's storage payload. The agent loop wires storage +\n * SurvivabilityAdapter together to deliver the eviction-resume\n * contract.\n * - createCheckpointHook (Phase 16) continues to mint per-iteration\n * receipts via the OBSERVABILITY band; receipts can be embedded inside\n * the `AgentSnapshot.lastReceiptId` (when callers want auditable\n * resume).\n *\n * Phase 20 ships:\n * - The full `AgentHost` interface (3 seams: scheduler / transport / storage).\n * - `AgentSnapshot` interface — the agent-state shape that gets serialized.\n * - `createNoopAgentHost()` reference implementation suitable for Node tests\n * and the Phase 19 default behavior (no scheduling delay, direct provider\n * transport, no persistence).\n *\n * Concrete MV3 SW / Cloudflare Worker / Lambda hosts are out of scope —\n * they live in consumer codebases (FSB, etc.).\n */\n\nimport type { SerializedSnapshot } from \"../runtime/survivability.js\";\nimport type {\n ProviderAdapter,\n ProviderRunRequest,\n ProviderRunResponse,\n Usage,\n} from \"../providers/provider.js\";\n\nimport type { ConversationTurn } from \"./format-tools.js\";\n\n/**\n * Snapshot shape the agent loop serializes between iterations. The full\n * shape is opaque to callers (they only see it through SerializedSnapshot\n * via the configured SurvivabilityAdapter) but it's exported so reference\n * implementations and tests can inspect the round-trip.\n */\nexport interface AgentSnapshot {\n readonly version: \"agent-snapshot/v1\";\n readonly iterationIndex: number;\n readonly conversation: readonly ConversationTurn[];\n readonly cumulativeUsage: Usage;\n readonly providerName: string;\n readonly capturedAt: string;\n /**\n * Phase 39 (v1.3): dispatch ancestry chain of crew `AgentSpec` ids\n * (root-first). Absent = root agent (single-agent runs never set it).\n * Optional so existing serialized `agent-snapshot/v1` snapshots\n * deserialize unchanged — the version literal stays `\"agent-snapshot/v1\"`\n * (D-05; Pitfall 8). The crew dispatcher threads the chain through\n * dispatch context in 39-05; cycle prevention rejects any dispatch whose\n * target id already appears in the chain.\n */\n readonly ancestry?: readonly string[];\n}\n\n/**\n * Scheduler seam — controls how the agent loop yields between iterations.\n *\n * `scheduleNext(iterationIndex)` is called AFTER an AFTER_AGENT_ITERATION\n * emission and BEFORE the next iteration's BEFORE_AGENT_ITERATION. The\n * scheduler decides when to resume — synchronously (sync loop), on next\n * tick (setTimeout/queueMicrotask), via a queue (Durable Object), or any\n * other strategy.\n *\n * Default (noop): resolves immediately.\n */\nexport interface AgentScheduler {\n scheduleNext(iterationIndex: number): Promise<void>;\n}\n\n/**\n * Transport seam — controls how a provider call is dispatched.\n *\n * `call(provider, request)` wraps the provider's `execute()` invocation.\n * Default (noop): pass-through (`provider.execute!(request)`). Cross-process\n * bridges (FSB's offscreen-document host) override to dispatch via\n * `chrome.runtime.sendMessage`.\n *\n * Per the Phase 19 INV-03 parity invariant, the transport seam does NOT\n * modify the `ProviderAdapter` interface — it operates on top of the\n * existing `execute()` method.\n */\nexport interface AgentTransport {\n call(\n provider: ProviderAdapter,\n request: ProviderRunRequest,\n ): Promise<ProviderRunResponse>;\n}\n\n/**\n * Storage seam — controls how agent state persists between iterations for\n * resume after host eviction.\n *\n * Phase 20 composes this with the Phase 18 `SurvivabilityAdapter`:\n * - The adapter serializes `AgentSnapshot` to `SerializedSnapshot` on\n * each AFTER_AGENT_ITERATION; storage.save() persists the snapshot.\n * - On run start, the agent loop calls storage.load(). If a non-null\n * snapshot is returned, the adapter deserializes it; the loop resumes\n * at the recorded iteration index.\n * - On success, the loop calls storage.clear() so the next run starts\n * fresh.\n *\n * Default (noop): save() is a no-op, load() returns null, clear() is a\n * no-op. Suitable for Node tests where eviction never occurs.\n */\nexport interface AgentStorage {\n save(snapshot: SerializedSnapshot): Promise<void>;\n load(): Promise<SerializedSnapshot | null>;\n clear(): Promise<void>;\n}\n\n/**\n * The host adapter — three optional seams, all swappable independently.\n *\n * Callers pass `host` on `AgentIntent`. The agent runtime falls back to\n * `createNoopAgentHost()` when `intent.host` is absent (so Phase 19\n * single-shot Node usage continues to work without explicit configuration).\n */\nexport interface AgentHost {\n readonly kind: \"agent-host\";\n readonly scheduler?: AgentScheduler;\n readonly transport?: AgentTransport;\n readonly storage?: AgentStorage;\n}\n\n/**\n * Reference implementation suitable for Node tests + the Phase 19 default\n * behavior.\n *\n * - scheduler: resolves immediately (no yield between iterations).\n * - transport: pass-through to provider.execute().\n * - storage: save() / clear() are no-ops; load() always returns null.\n *\n * Equivalent to passing no host at all.\n */\nexport function createNoopAgentHost(): AgentHost {\n return {\n kind: \"agent-host\",\n scheduler: {\n async scheduleNext(_iterationIndex: number): Promise<void> {\n void _iterationIndex;\n },\n },\n transport: {\n async call(\n provider: ProviderAdapter,\n request: ProviderRunRequest,\n ): Promise<ProviderRunResponse> {\n if (provider.execute === undefined) {\n throw new Error(\n `AgentTransport: provider ${provider.id} has no execute() method.`,\n );\n }\n return provider.execute(request);\n },\n },\n storage: {\n async save(_snapshot: SerializedSnapshot): Promise<void> {\n void _snapshot;\n },\n async load(): Promise<SerializedSnapshot | null> {\n return null;\n },\n async clear(): Promise<void> {\n // no-op\n },\n },\n };\n}\n","/**\n * Agent runtime type definitions — Phase 19 (v1.2).\n *\n * The agent surface is intentionally distinct from the v1.0 single-shot\n * runtime (`RunIntent` / `RunResult`). The agent loop wraps multiple\n * provider iterations, dispatches tool calls between them, and threads\n * v1.1 capability receipts through Phase 16's `createCheckpointHook` when\n * a signer is configured.\n *\n * Composition surfaces (all optional on `AgentIntent`):\n * - `pipeline?` — Phase 15 `HookPipeline`; if absent, runtime creates a default.\n * - `signer?` — Phase 9 `ReceiptSigner`; if present, auto-registers Phase 16\n * checkpoint hook on `BAND.OBSERVABILITY`.\n * - `tracer?` — Phase 5 `TracerLike`; flows through pipeline + provider calls.\n * - `host?` — Phase 20 `AgentHost` pluggable adapter (forward-declared here;\n * default in-process implementation lives in `runtime.ts`).\n * - `contract?` — Phase 7 `CapabilityContract`; budget.maxIterations + .maxWallTimeMs\n * enforced by the loop.\n */\n\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\nimport type { ArtifactRef } from \"../artifacts/artifact.js\";\nimport type { HookPipeline } from \"../contract/bands.js\";\nimport type { CapabilityContract } from \"../contract/contract.js\";\nimport type { OutputContractMap } from \"../outputs/contracts.js\";\nimport type { InferOutputMap } from \"../outputs/infer.js\";\nimport type { PolicySpec } from \"../policy/policy.js\";\nimport type { Usage } from \"../providers/provider.js\";\nimport type { LatticeRunError } from \"../results/errors.js\";\nimport type { ReceiptEnvelope, ReceiptSigner } from \"../receipts/types.js\";\nimport type { SurvivabilityAdapter } from \"../runtime/survivability.js\";\nimport type { ToolDefinition } from \"../tools/tools.js\";\nimport type { TracerLike } from \"../tracing/tracing.js\";\n\n// Phase 20 (v1.2): the AgentHost forward-decl that shipped in Phase 19 is\n// replaced by the full interface in host.ts. Existing imports of AgentHost\n// from \"./types.js\" continue to resolve via this re-export.\nexport type {\n AgentHost,\n AgentScheduler,\n AgentSnapshot,\n AgentStorage,\n AgentTransport,\n} from \"./host.js\";\nimport type { AgentHost as _AgentHost } from \"./host.js\";\n\n/**\n * Per-iteration record stored on `AgentSuccess.iterations` for inspectability.\n *\n * `toolCalls` carries content-addressed args/result hashes (sha256) so\n * downstream receipts can reference them without inlining the bodies.\n *\n * `deniedReason` is populated on iterations whose `BEFORE_AGENT_ITERATION`\n * SAFETY-band handler set `controls.deny(...)`.\n */\nexport interface IterationRecord {\n readonly index: number;\n readonly provider: string;\n readonly promptTokens: number;\n readonly completionTokens: number;\n readonly costUsd: number | null;\n readonly durationMs: number;\n readonly toolCalls: ReadonlyArray<{\n readonly id: string;\n readonly name: string;\n readonly argsHash: string;\n readonly resultHash: string;\n }>;\n readonly deniedReason?: string;\n readonly receipt?: ReceiptEnvelope;\n}\n\n/**\n * Input shape accepted by `ai.runAgent(intent)`.\n *\n * All fields except `task` and `tools` are optional. The runtime supplies\n * sensible defaults (in-process host, fresh pipeline, no signer, no tracer).\n *\n * `TOutputs` parameterizes the final-answer schema map; defaults to a free-form\n * `{ answer: \"text\" }` shape when the field is omitted. Validation runs once\n * against the final assistant message (no intermediate iteration validation).\n */\nexport interface AgentIntent<TOutputs extends OutputContractMap = OutputContractMap> {\n readonly task: string;\n readonly tools: ReadonlyArray<ToolDefinition<StandardSchemaV1>>;\n readonly host?: _AgentHost;\n /**\n * Phase 20 (v1.2): when the agent loop resumes from a host.storage snapshot,\n * the configured SurvivabilityAdapter handles the serialize/deserialize\n * round-trip. When absent, runtime defaults to\n * `createNoopSurvivabilityAdapter<AgentSnapshot>()`.\n */\n readonly survivabilityAdapter?: SurvivabilityAdapter<\n import(\"./host.js\").AgentSnapshot\n >;\n readonly contract?: CapabilityContract;\n readonly policy?: PolicySpec;\n readonly outputs?: TOutputs;\n readonly pipeline?: HookPipeline;\n readonly signer?: ReceiptSigner;\n readonly tracer?: TracerLike;\n /**\n * When `false`, the runtime will NOT auto-register `createCheckpointHook`\n * even if `signer` is provided. Callers who want full manual control over\n * receipt minting set this to `false` and register their own hook.\n * Defaults to `true` (auto-register when signer present).\n */\n readonly autoRegisterCheckpoint?: boolean;\n}\n\n/**\n * Success result returned by `ai.runAgent` when the loop reaches a final\n * answer and (when `outputs` is declared) the final answer validates.\n *\n * `iterations[]` records every iteration that ran — including the one that\n * produced the final answer. `receipt` is the outermost receipt minted at\n * loop close when `signer` is configured (separate from per-iteration\n * receipts on `iterations[i].receipt`).\n */\nexport interface AgentSuccess<TOutputs extends OutputContractMap = OutputContractMap> {\n readonly kind: \"success\";\n readonly output: InferOutputMap<TOutputs>;\n readonly artifacts?: readonly ArtifactRef[];\n readonly usage: Usage;\n readonly iterations: ReadonlyArray<IterationRecord>;\n readonly receipt?: ReceiptEnvelope;\n}\n\n/**\n * Failure kinds specific to the agent loop. v1.1 `LatticeRunError.kind`\n * values remain valid (provider errors, no-contract-match, validation-failed,\n * tripwire-violated) and are reused verbatim. Phase 19 adds three\n * agent-specific kinds. Phase 39 (v1.3) adds `crew-budget-exceeded` —\n * crew-level shared-pool exhaustion, terminal across the parent/child\n * boundary (D-10).\n */\nexport type AgentFailureKind =\n | LatticeRunError[\"kind\"]\n | \"agent-iteration-denied\"\n | \"agent-max-iterations\"\n | \"agent-wall-time-exceeded\"\n | \"crew-budget-exceeded\";\n\n/**\n * Failure result returned by `ai.runAgent`. Discriminates via `kind`.\n *\n * `iterations[]` carries any iterations that completed before the failure\n * (empty if the failure occurred pre-iteration). For `agent-iteration-denied`,\n * the failing iteration is the LAST entry and carries `deniedReason`.\n */\nexport interface AgentFailure {\n readonly kind: AgentFailureKind;\n readonly usage: Usage;\n readonly iterations: ReadonlyArray<IterationRecord>;\n readonly reason?: string;\n readonly cause?: unknown;\n readonly receipt?: ReceiptEnvelope;\n}\n\n/**\n * Discriminated union returned by `ai.runAgent`.\n */\nexport type AgentResult<TOutputs extends OutputContractMap = OutputContractMap> =\n | AgentSuccess<TOutputs>\n | AgentFailure;\n\n/**\n * Typed error raised when a SAFETY-band handler sets `controls.deny(reason)`\n * during `BEFORE_AGENT_ITERATION`. Carries `terminal: true` semantics to\n * align with v1.1 `TripwireViolationError`: the failure is NOT retried by\n * the fallback chain.\n *\n * Surfaced via `AgentFailure { kind: \"agent-iteration-denied\", reason, ... }`\n * — callers can also catch the typed error if they prefer.\n */\nexport class AgentDeniedError extends Error {\n readonly kind = \"agent-iteration-denied\" as const;\n readonly terminal = true as const;\n readonly reason: string;\n readonly iterationIndex: number;\n\n constructor(reason: string, iterationIndex: number) {\n super(`Agent iteration ${iterationIndex} denied: ${reason}`);\n this.name = \"AgentDeniedError\";\n this.reason = reason;\n this.iterationIndex = iterationIndex;\n }\n}\n\n/**\n * Returned by `formatToolsForProvider` (Phase 19 Plan 19-03). Re-exported\n * here for convenience; the canonical declaration lives in format-tools.ts.\n */\nexport interface ToolUseRequest {\n readonly id: string;\n readonly name: string;\n readonly args: unknown;\n}\n","/**\n * runAgent — Phase 19 (v1.2).\n *\n * The agent-loop orchestrator. Wraps multiple provider iterations under one\n * `ai.runAgent(intent)` call. Each iteration:\n *\n * 1. Budget pre-check (maxIterations, maxWallTimeMs, maxCostUsd).\n * 2. Emit BEFORE_AGENT_ITERATION through the hook pipeline; check\n * `pipeline.lastDenialReason()` for SAFETY-band veto.\n * 3. Build the provider request via formatToolsForProvider.buildTask().\n * 4. Call the sticky provider's `execute()` (or pick first provider on\n * iteration 0).\n * 5. Parse tool-use envelopes from the response. If absent, the response\n * is a final answer: validate against `intent.outputs` (if declared)\n * and exit with AgentSuccess.\n * 6. If tool-use envelopes are present: dispatch each via `runTool`,\n * append assistant + tool-result turns to the conversation, record an\n * IterationRecord, emit AFTER_AGENT_ITERATION, continue.\n *\n * Composition surfaces (all optional on AgentIntent):\n *\n * - `pipeline?` — Phase 15 HookPipeline; runtime creates one if absent.\n * - `signer?` — Phase 9 ReceiptSigner; when present AND\n * `autoRegisterCheckpoint !== false`, the runtime\n * auto-registers `createCheckpointHook` on\n * BAND.OBSERVABILITY for per-iteration receipts.\n * - `tracer?` — Phase 5 TracerLike; flows through pipeline.\n * - `outputs?` — final-answer schema map; validated only on the final\n * assistant message (no intermediate validation).\n * - `contract?` — Phase 7 CapabilityContract; budget invariants are\n * enforced pre-iteration.\n */\n\nimport type { ArtifactRef } from \"../artifacts/artifact.js\";\nimport { toArtifactRef } from \"../artifacts/artifact.js\";\nimport { BAND, type HookPipeline, createHookPipeline } from \"../contract/bands.js\";\nimport { createCheckpointHook } from \"../contract/checkpoint.js\";\nimport type { LatticeConfig } from \"./../runtime/config.js\";\nimport type { OutputContractMap } from \"../outputs/contracts.js\";\nimport type { ProviderAdapter, ProviderRunResponse, Usage } from \"../providers/provider.js\";\nimport { createNoopSurvivabilityAdapter, type SurvivabilityAdapter } from \"../runtime/survivability.js\";\nimport { runTool, type ToolCallResult } from \"../tools/tools.js\";\n\nimport { formatToolsForProvider, type ConversationTurn } from \"./format-tools.js\";\nimport {\n createNoopAgentHost,\n type AgentHost,\n type AgentSnapshot,\n} from \"./host.js\";\nimport {\n AgentDeniedError,\n type AgentFailure,\n type AgentIntent,\n type AgentResult,\n type IterationRecord,\n type ToolUseRequest,\n} from \"./types.js\";\n\nconst ZERO_USAGE: Usage = { promptTokens: 0, completionTokens: 0, costUsd: null };\n\n/**\n * Context handed to an injected `dispatchToolUse` seam (Phase 39, internal).\n * Carries the loop position plus read-only views of the live conversation\n * and the hook pipeline so a crew dispatcher can run its own pipeline\n * events around child execution.\n */\nexport interface DispatchToolUseContext {\n readonly iterationIndex: number;\n readonly conversation: readonly ConversationTurn[];\n readonly pipeline: HookPipeline;\n}\n\n/**\n * Internal (in-package only — NOT re-exported from src/index.ts) options\n * for `runAgentInternal`. Phase 39 (v1.3) adds the injectable tool-use\n * dispatch seam the CrewDispatcher (39-05) routes child-agent calls\n * through.\n *\n * Semantics: for each `ToolUseRequest` in step 4g, when `dispatchToolUse`\n * is present it is consulted FIRST. If it resolves `{ content }`, that\n * content is pushed as the `role: \"tool\"` turn (same toolCallId/toolName\n * as the default path) and recorded in `toolCallRecords`; the default\n * lookup/`runTool` path — including its BEFORE_TOOL/AFTER_TOOL hook band\n * semantics — is bypassed for that request (the dispatcher owns its own\n * pipeline events). If it resolves `undefined`, the existing\n * lookup/`runTool` path executes verbatim (fall-through).\n */\nexport interface RunAgentInternalOptions {\n readonly dispatchToolUse?: (\n req: ToolUseRequest,\n ctx: DispatchToolUseContext,\n ) => Promise<{ readonly content: string } | undefined>;\n}\n\n/**\n * Resolves the runtime's behaviour for a single `ai.runAgent(intent)` call.\n *\n * Phase 19 ships an in-process default scheduler (the loop runs in the\n * calling Promise), direct transport (provider.execute()), and in-memory\n * transcript (the `conversation` array). Phase 20 promotes scheduler /\n * transport / storage to the pluggable `AgentHost` adapter.\n *\n * Phase 39: `runAgent` is a thin public wrapper over `runAgentInternal`\n * with no internal options — the public signature and behavior are\n * unchanged.\n */\nexport async function runAgent<TOutputs extends OutputContractMap = OutputContractMap>(\n intent: AgentIntent<TOutputs>,\n config: LatticeConfig = {},\n): Promise<AgentResult<TOutputs>> {\n return runAgentInternal(intent, config);\n}\n\n/**\n * The agent-loop implementation with the internal dispatch seam (Phase 39).\n * In-package consumers (agent/crew/, 39-05) call this directly; it is NOT\n * part of the public package surface.\n */\nexport async function runAgentInternal<TOutputs extends OutputContractMap = OutputContractMap>(\n intent: AgentIntent<TOutputs>,\n config: LatticeConfig = {},\n internalOptions: RunAgentInternalOptions = {},\n): Promise<AgentResult<TOutputs>> {\n const startedAt = Date.now();\n const cumulativeUsage = { promptTokens: 0, completionTokens: 0, costUsd: null as number | null };\n const iterations: IterationRecord[] = [];\n\n // 0. Host adapter + survivability defaults.\n const host: AgentHost = intent.host ?? createNoopAgentHost();\n const survivabilityAdapter: SurvivabilityAdapter<AgentSnapshot> =\n intent.survivabilityAdapter ?? createNoopSurvivabilityAdapter<AgentSnapshot>();\n\n // 1. Hook pipeline + auto-checkpoint registration.\n const pipeline = ensurePipeline(intent);\n maybeAutoRegisterCheckpoint(pipeline, intent);\n\n // 2. Provider selection — pick the first adapter with execute().\n const provider = pickFirstExecutableProvider(config);\n if (provider === null) {\n return buildFailure({\n kind: \"execution_unavailable\",\n reason: \"No provider adapter with execute() is configured.\",\n iterations,\n usage: cumulativeUsage,\n });\n }\n let providerName = provider.id;\n\n // 3. Initialize conversation + tools handle.\n let conversation: ConversationTurn[] = [{ role: \"user\", content: intent.task }];\n const handle = formatToolsForProvider(providerName, intent.tools);\n\n const budget = intent.contract?.budget;\n const maxIterations = budget?.maxIterations ?? Number.POSITIVE_INFINITY;\n const maxWallTimeMs = budget?.maxWallTimeMs ?? Number.POSITIVE_INFINITY;\n const maxCostUsd = budget?.maxCostUsd ?? Number.POSITIVE_INFINITY;\n\n let iterationIndex = 0;\n\n // 3.5. Resume path (Phase 20): attempt to load a snapshot from host.storage.\n // On success, deserialize via the survivability adapter and re-enter at the\n // recorded iteration index. Emits recovery.start / recovery.complete /\n // recovery.failed events on the configured tracer (TRACE-EXT-01).\n const existingSnapshot = await host.storage?.load();\n if (existingSnapshot !== null && existingSnapshot !== undefined) {\n intent.tracer?.event?.(\"recovery.start\", {\n snapshotVersion: existingSnapshot.version,\n capturedAt: existingSnapshot.capturedAt,\n });\n try {\n const restored = survivabilityAdapter.deserialize(existingSnapshot);\n iterationIndex = restored.iterationIndex;\n conversation = [...restored.conversation];\n cumulativeUsage.promptTokens = restored.cumulativeUsage.promptTokens;\n cumulativeUsage.completionTokens = restored.cumulativeUsage.completionTokens;\n cumulativeUsage.costUsd = restored.cumulativeUsage.costUsd;\n providerName = restored.providerName;\n intent.tracer?.event?.(\"recovery.complete\", {\n iterationIndex,\n providerName,\n });\n } catch (error) {\n intent.tracer?.event?.(\"recovery.failed\", {\n reason: error instanceof Error ? error.message : \"deserialize failed\",\n });\n await host.storage?.clear();\n // Fall through to fresh start (iterationIndex stays 0).\n }\n }\n\n while (iterationIndex < maxIterations) {\n // 4a. Budget pre-checks.\n const elapsedMs = Date.now() - startedAt;\n if (elapsedMs >= maxWallTimeMs) {\n return buildFailure({\n kind: \"agent-wall-time-exceeded\",\n reason: `Wall-time budget ${maxWallTimeMs}ms exceeded after ${elapsedMs}ms`,\n iterations,\n usage: cumulativeUsage,\n });\n }\n if (\n cumulativeUsage.costUsd !== null &&\n cumulativeUsage.costUsd >= maxCostUsd\n ) {\n // Reuses v1.1 \"no-contract-match\" kind for contract-budget-exceeded\n // (per LatticeRunError taxonomy); agent-specific cost-budget exhaustion\n // surfaces with this kind and a descriptive `reason`.\n return buildFailure({\n kind: \"no-contract-match\",\n reason: `Cost budget $${maxCostUsd} exceeded at $${cumulativeUsage.costUsd}`,\n iterations,\n usage: cumulativeUsage,\n });\n }\n\n // 4b. BEFORE_AGENT_ITERATION + deny check.\n await pipeline.run(\"BEFORE_AGENT_ITERATION\", {\n iterationIndex,\n intent,\n conversation: conversation.map((t) => ({ ...t })),\n // CheckpointHookContext fields — the auto-registered checkpoint hook\n // reads these to assemble its receipt + tracer event metadata.\n stepName: `agent-iteration-${iterationIndex}-before`,\n stepIndex: iterationIndex,\n timestamp: new Date().toISOString(),\n ...(iterationIndex > 0\n ? { previousStepName: `agent-iteration-${iterationIndex - 1}-after` }\n : {}),\n });\n const denial = pipeline.lastDenialReason();\n if (denial !== null) {\n const failedRecord: IterationRecord = {\n index: iterationIndex,\n provider: providerName,\n promptTokens: 0,\n completionTokens: 0,\n costUsd: null,\n durationMs: 0,\n toolCalls: [],\n deniedReason: denial,\n };\n iterations.push(failedRecord);\n await pipeline.run(\"AFTER_AGENT_ITERATION\", {\n iterationIndex,\n intent,\n record: failedRecord,\n stepName: `agent-iteration-${iterationIndex}-after`,\n stepIndex: iterationIndex,\n timestamp: new Date().toISOString(),\n previousStepName: `agent-iteration-${iterationIndex}-before`,\n });\n return buildFailure({\n kind: \"agent-iteration-denied\",\n reason: denial,\n iterations,\n usage: cumulativeUsage,\n });\n }\n\n // 4c. Build task + dispatch via host transport seam.\n const task = handle.buildTask(conversation);\n const iterStart = Date.now();\n let response: ProviderRunResponse;\n try {\n if (provider.execute === undefined) {\n return buildFailure({\n kind: \"execution_unavailable\",\n reason: \"Selected provider has no execute() method.\",\n iterations,\n usage: cumulativeUsage,\n });\n }\n const providerRequest = {\n task,\n artifacts: [],\n outputs: [\"answer\"],\n ...(intent.policy !== undefined ? { policy: intent.policy } : {}),\n };\n response = host.transport !== undefined\n ? await host.transport.call(provider, providerRequest)\n : await provider.execute(providerRequest);\n } catch (error) {\n return buildFailure({\n kind: \"provider_execution\",\n reason: error instanceof Error ? error.message : \"Provider execution failed\",\n cause: error,\n iterations,\n usage: cumulativeUsage,\n });\n }\n const iterDuration = Date.now() - iterStart;\n const iterUsage = response.normalizedUsage ?? ZERO_USAGE;\n accumulateUsage(cumulativeUsage, iterUsage);\n\n // 4d. Extract response text + parse tool-use envelope.\n const responseText = extractResponseText(response);\n const toolUseRequests = response.toolCalls !== undefined\n ? response.toolCalls.map((toolCall) => ({\n id: toolCall.id,\n name: toolCall.name,\n args: toolCall.args,\n }))\n : handle.parseToolUse(responseText);\n\n if (toolUseRequests === null || toolUseRequests.length === 0) {\n // 4e. Final answer path.\n const finalRecord: IterationRecord = {\n index: iterationIndex,\n provider: providerName,\n promptTokens: iterUsage.promptTokens,\n completionTokens: iterUsage.completionTokens,\n costUsd: iterUsage.costUsd,\n durationMs: iterDuration,\n toolCalls: [],\n };\n iterations.push(finalRecord);\n conversation.push({ role: \"assistant\", content: responseText });\n\n await pipeline.run(\"AFTER_AGENT_ITERATION\", {\n iterationIndex,\n intent,\n record: finalRecord,\n stepName: `agent-iteration-${iterationIndex}-after`,\n stepIndex: iterationIndex,\n timestamp: new Date().toISOString(),\n previousStepName: `agent-iteration-${iterationIndex}-before`,\n });\n\n // 4e.1. Clear persistent storage on final-answer success so the next\n // run starts fresh (Phase 20).\n await host.storage?.clear();\n\n // 4f. Output materialization. Phase 19 produces a flat\n // `{ answer: string }` output by default. When `intent.outputs` is\n // declared, the runtime still surfaces the same flat shape — full\n // OutputContractMap-aware materialization (Standard Schema\n // round-trip, structured output fields) lives in a follow-on phase\n // alongside the agent showcase (Phase 22).\n const artifactRefs =\n response.artifactRefs !== undefined\n ? response.artifactRefs.map(toArtifactRef)\n : [];\n return {\n kind: \"success\",\n output: { answer: responseText } as never,\n ...(artifactRefs.length > 0 ? { artifacts: artifactRefs } : {}),\n usage: snapshotUsage(cumulativeUsage),\n iterations: Object.freeze([...iterations]),\n };\n }\n\n // 4g. Tool dispatch path.\n conversation.push({ role: \"assistant\", content: responseText });\n const toolCallRecords: Array<{\n readonly id: string;\n readonly name: string;\n readonly argsHash: string;\n readonly resultHash: string;\n }> = [];\n for (const req of toolUseRequests) {\n let resultContent: string | null = null;\n let resultHash = \"tool-not-found\";\n\n // Phase 39 internal dispatch seam: consult the injected dispatcher\n // first. `{ content }` short-circuits the default path; `undefined`\n // falls through to the existing lookup/runTool path verbatim.\n if (internalOptions.dispatchToolUse !== undefined) {\n const dispatched = await internalOptions.dispatchToolUse(req, {\n iterationIndex,\n conversation,\n pipeline,\n });\n if (dispatched !== undefined) {\n resultContent = dispatched.content;\n resultHash = stableHash(dispatched.content);\n }\n }\n\n if (resultContent === null) {\n const tool = intent.tools.find((t) => t.name === req.name);\n let toolResult: ToolCallResult | null = null;\n if (tool === undefined) {\n resultContent = JSON.stringify({\n error: `Unknown tool: ${req.name}`,\n });\n } else {\n try {\n await pipeline.run(\"BEFORE_TOOL\", {\n iterationIndex,\n toolName: req.name,\n args: req.args,\n });\n toolResult = await runTool(tool, req.args);\n resultContent = stringifyArtifactValue(toolResult.artifact.value);\n resultHash = toolResult.callId;\n await pipeline.run(\"AFTER_TOOL\", {\n iterationIndex,\n toolName: req.name,\n args: req.args,\n result: toolResult.artifact.value,\n });\n } catch (error) {\n resultContent = JSON.stringify({\n error: error instanceof Error ? error.message : \"Tool execution failed\",\n });\n }\n }\n }\n conversation.push({\n role: \"tool\",\n content: resultContent,\n toolCallId: req.id,\n toolName: req.name,\n });\n toolCallRecords.push({\n id: req.id,\n name: req.name,\n argsHash: stableHash(req.args),\n resultHash,\n });\n }\n\n const record: IterationRecord = {\n index: iterationIndex,\n provider: providerName,\n promptTokens: iterUsage.promptTokens,\n completionTokens: iterUsage.completionTokens,\n costUsd: iterUsage.costUsd,\n durationMs: iterDuration,\n toolCalls: Object.freeze([...toolCallRecords]),\n };\n iterations.push(record);\n\n await pipeline.run(\"AFTER_AGENT_ITERATION\", {\n iterationIndex,\n intent,\n record,\n stepName: `agent-iteration-${iterationIndex}-after`,\n stepIndex: iterationIndex,\n timestamp: new Date().toISOString(),\n previousStepName: `agent-iteration-${iterationIndex}-before`,\n });\n\n // 4h. Persist agent state via host.storage so the loop can resume\n // after eviction (Phase 20). The survivability adapter handles\n // serialization (default: createNoopSurvivabilityAdapter which\n // JSON.stringifies the state).\n if (host.storage !== undefined) {\n const snapshot = survivabilityAdapter.serialize({\n version: \"agent-snapshot/v1\",\n iterationIndex: iterationIndex + 1,\n conversation: [...conversation],\n cumulativeUsage: snapshotUsage(cumulativeUsage),\n providerName,\n capturedAt: new Date().toISOString(),\n });\n await host.storage.save(snapshot);\n }\n\n // 4i. Yield to the host scheduler between iterations.\n if (host.scheduler !== undefined) {\n await host.scheduler.scheduleNext(iterationIndex);\n }\n\n iterationIndex += 1;\n }\n\n return buildFailure({\n kind: \"agent-max-iterations\",\n reason: `Iteration budget ${maxIterations} reached without a final answer`,\n iterations,\n usage: cumulativeUsage,\n });\n}\n\nfunction ensurePipeline<T extends AgentIntent>(intent: T): HookPipeline {\n if (intent.pipeline !== undefined) return intent.pipeline;\n const options: Parameters<typeof createHookPipeline>[0] =\n intent.tracer !== undefined ? { tracer: intent.tracer } : {};\n return createHookPipeline(options);\n}\n\nfunction maybeAutoRegisterCheckpoint<T extends AgentIntent>(\n pipeline: HookPipeline,\n intent: T,\n): void {\n if (intent.signer === undefined) return;\n if (intent.autoRegisterCheckpoint === false) return;\n if (pipeline.isFrozen()) return;\n const handler = createCheckpointHook({\n runId: `runAgent-${Date.now()}-${Math.random().toString(16).slice(2)}`,\n signer: intent.signer,\n ...(intent.tracer !== undefined ? { tracer: intent.tracer } : {}),\n });\n pipeline.register(\"AFTER_AGENT_ITERATION\", handler, { band: BAND.OBSERVABILITY });\n}\n\nfunction pickFirstExecutableProvider(config: LatticeConfig): ProviderAdapter | null {\n const providers = config.providers ?? [];\n for (const entry of providers) {\n if (typeof entry === \"string\") continue;\n if (\"kind\" in entry && entry.kind === \"provider-adapter\" && entry.execute !== undefined) {\n return entry;\n }\n }\n return null;\n}\n\nfunction extractResponseText(response: ProviderRunResponse): string {\n const raw = response.rawOutputs ?? {};\n const text = raw[\"answer\"];\n if (typeof text === \"string\") return text;\n // Fallback: any string value in rawOutputs.\n for (const value of Object.values(raw)) {\n if (typeof value === \"string\") return value;\n }\n return \"\";\n}\n\nfunction accumulateUsage(\n cumulative: { promptTokens: number; completionTokens: number; costUsd: number | null },\n iter: Usage,\n): void {\n cumulative.promptTokens += iter.promptTokens;\n cumulative.completionTokens += iter.completionTokens;\n if (iter.costUsd !== null) {\n cumulative.costUsd = (cumulative.costUsd ?? 0) + iter.costUsd;\n }\n}\n\nfunction snapshotUsage(c: {\n promptTokens: number;\n completionTokens: number;\n costUsd: number | null;\n}): Usage {\n return {\n promptTokens: c.promptTokens,\n completionTokens: c.completionTokens,\n costUsd: c.costUsd,\n };\n}\n\nfunction buildFailure(input: {\n kind: AgentFailure[\"kind\"];\n reason?: string;\n cause?: unknown;\n iterations: readonly IterationRecord[];\n usage: { promptTokens: number; completionTokens: number; costUsd: number | null };\n}): AgentFailure {\n return {\n kind: input.kind,\n usage: snapshotUsage(input.usage),\n iterations: Object.freeze([...input.iterations]),\n ...(input.reason !== undefined ? { reason: input.reason } : {}),\n ...(input.cause !== undefined ? { cause: input.cause } : {}),\n };\n}\n\nfunction stringifyArtifactValue(value: unknown): string {\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction stableHash(input: unknown): string {\n try {\n const json = JSON.stringify(input);\n let hash = 5381;\n for (let i = 0; i < json.length; i += 1) {\n hash = (hash * 33) ^ json.charCodeAt(i);\n }\n return `djb2:${(hash >>> 0).toString(16)}`;\n } catch {\n return \"djb2:0\";\n }\n}\n\n// Forward-compat re-export: AgentDeniedError is the typed error class\n// callers can catch (vs reading `result.kind === \"agent-iteration-denied\"`).\nvoid AgentDeniedError;\n"],"mappings":";;;;AAUA,MAAMA,gBAAc,IAAI,aAAa;AAErC,SAAgB,eACd,OACA,SACoB;AACpB,KAAI,QAAQ,cAAc,KAAA,EACxB,QAAO,QAAQ;AAGjB,KAAI,WAAW,MAAM,IAAI,MAAM,SAAS,GACtC,QAAO,MAAM;AAGf,KAAI,OAAO,UAAU,SACnB,QAAO,KAAK,QAAQ,MAAM,IAAI,QAAQ;AAGxC,QAAO,QAAQ;;AAGjB,SAAgB,qBACd,OACA,MAC0B;AAC1B,KAAI,SAAS,UAAU,OAAO,UAAU,SACtC,QAAO,cAAc,MAAM;AAG7B,KAAI,SAAS,QAAQ;EACnB,MAAM,aAAa,KAAK,UAAU,MAAM;AAExC,SAAO,eAAe,KAAA,IAAY,KAAA,IAAY,cAAc,WAAW;;AAGzE,KAAI,WAAW,MAAM,CACnB,QAAO,EACL,OAAO,MAAM,MACd;;AAML,SAAS,cAAc,OAA6B;AAClD,QAAO;EACL,YAAY,MAAM;EAClB,OAAOA,cAAY,OAAO,MAAM,CAAC;EAClC;;AAGH,SAAS,WAAW,OAA+B;AACjD,QAAO,OAAO,SAAS,eAAe,iBAAiB;;;;AC8BzD,MAAa,WAAW;CACtB,KAAK,OAAe,UAA2B,EAAE,EAAiB;AAChE,SAAO,eAAe,QAAQ,UAAU,OAAO,SAAS,aAAa;;CAGvE,KAAK,OAAgB,UAA2B,EAAE,EAAiB;AACjE,SAAO,eAAe,QAAQ,UAAU,OAAO,SAAS,mBAAmB;;CAG7E,KAAK,OAA6B,UAA2B,EAAE,EAAiB;AAC9E,SAAO,eAAe,QAAQ,QAAQ,OAAO,QAAQ;;CAGvD,MAAM,OAA6B,UAA2B,EAAE,EAAiB;AAC/E,SAAO,eAAe,SAAS,QAAQ,OAAO,QAAQ;;CAGxD,MAAM,OAA6B,UAA2B,EAAE,EAAiB;AAC/E,SAAO,eAAe,SAAS,QAAQ,OAAO,QAAQ;;CAGxD,SAAS,OAA6B,UAA2B,EAAE,EAAiB;AAClF,SAAO,eAAe,YAAY,QAAQ,OAAO,QAAQ;;CAG3D,IAAI,OAAqB,UAA2B,EAAE,EAAiB;AACrE,SAAO,eAAe,OAAO,OAAO,MAAM,UAAU,EAAE,QAAQ;;CAGhE,WAAW,OAAgB,SAAmD;AAC5E,SAAO,eACL,eACA,QACA,OACA;GACE,GAAG;GACH,UAAU;IACR,GAAG,QAAQ;IACX,UAAU,QAAQ;IAClB,GAAI,QAAQ,WAAW,KAAA,IAAY,EAAE,QAAQ,QAAQ,QAAQ,GAAG,EAAE;IACnE;GACF,EACD,mBACD;;CAGH,OAAO,OAA8C;EACnD,MAAM,EACJ,MACA,SAAS,aACT,OACA,SACA,WACA,GAAG,YACD;AAEJ,SAAO,eAAe,MAAM,QAAQ,OAAO;GACzC,GAAG;GACH,SAAS;IACP,SAAS,QAAQ,IAAI,cAAc;IACnC;IACD;GACF,EAAE,wBAAwB,KAAK,CAAC;;CAEpC;AAED,SAAgB,cAAc,OAAiD;AAC7E,QAAO;EACL,IAAI,MAAM;EACV,MAAM,MAAM;EACZ,QAAQ,MAAM;EACd,SAAS,MAAM;EACf,GAAI,MAAM,cAAc,KAAA,IAAY,EAAE,WAAW,MAAM,WAAW,GAAG,EAAE;EACvE,GAAI,MAAM,UAAU,KAAA,IAAY,EAAE,OAAO,MAAM,OAAO,GAAG,EAAE;EAC3D,GAAI,MAAM,aAAa,KAAA,IAAY,EAAE,UAAU,MAAM,UAAU,GAAG,EAAE;EACpE,GAAI,MAAM,SAAS,KAAA,IAAY,EAAE,MAAM,MAAM,MAAM,GAAG,EAAE;EACxD,GAAI,MAAM,gBAAgB,KAAA,IAAY,EAAE,aAAa,MAAM,aAAa,GAAG,EAAE;EAC7E,GAAI,MAAM,YAAY,KAAA,IAAY,EAAE,SAAS,MAAM,SAAS,GAAG,EAAE;EACjE,GAAI,MAAM,YAAY,KAAA,IAAY,EAAE,SAAS,MAAM,SAAS,GAAG,EAAE;EAClE;;AAGH,SAAgB,cAAc,OAAsC;AAClE,KAAI,CAAC,SAAS,MAAM,CAClB,QAAO;AAGT,QACE,OAAO,MAAM,OAAO,YACpB,eAAe,MAAM,KAAK,IAC1B,iBAAiB,MAAM,OAAO,IAC9B,kBAAkB,MAAM,QAAQ;;AAIpC,SAAS,eACP,MACA,QACA,OACA,SACA,kBACe;CACf,MAAM,YAAY,eAAe,OAAO;EACtC;EACA,GAAI,QAAQ,cAAc,KAAA,IAAY,EAAE,WAAW,QAAQ,WAAW,GAAG,EAAE;EAC3E,GAAI,qBAAqB,KAAA,IAAY,EAAE,kBAAkB,GAAG,EAAE;EAC/D,CAAC;CACF,MAAM,OAAO,QAAQ,QAAQ,qBAAqB,OAAO,KAAK;AAE9D,QAAO;EACL,IAAI,QAAQ,MAAM,iBAAiB,KAAK;EACxC;EACA;EACA;EACA,SAAS,QAAQ,WAAW;EAC5B,GAAI,cAAc,KAAA,IAAY,EAAE,WAAW,GAAG,EAAE;EAChD,GAAI,QAAQ,UAAU,KAAA,IAAY,EAAE,OAAO,QAAQ,OAAO,GAAG,EAAE;EAC/D,GAAI,QAAQ,aAAa,KAAA,IAAY,EAAE,UAAU,QAAQ,UAAU,GAAG,EAAE;EACxE,GAAI,SAAS,KAAA,IAAY,EAAE,MAAM,GAAG,EAAE;EACtC,GAAI,QAAQ,gBAAgB,KAAA,IAAY,EAAE,aAAa,QAAQ,aAAa,GAAG,EAAE;EACjF,GAAI,QAAQ,YAAY,KAAA,IAAY,EAAE,SAAS,QAAQ,SAAS,GAAG,EAAE;EACrE,GAAI,QAAQ,YAAY,KAAA,IAAY,EAAE,SAAS,QAAQ,SAAS,GAAG,EAAE;EACtE;;AAGH,SAAS,wBAAwB,MAAwC;AACvE,SAAQ,MAAR;EACE,KAAK,OACH,QAAO;EACT,KAAK;EACL,KAAK,cACH,QAAO;EACT,QACE;;;AAIN,SAAS,eAAe,OAAuC;AAC7D,QACE,UAAU,UACV,UAAU,UACV,UAAU,UACV,UAAU,WACV,UAAU,WACV,UAAU,WACV,UAAU,cACV,UAAU,SACV,UAAU;;AAId,SAAS,iBAAiB,OAAyC;AACjE,QACE,UAAU,YACV,UAAU,UACV,UAAU,SACV,UAAU,eACV,UAAU,qBACV,UAAU;;AAId,SAAS,kBAAkB,OAA0C;AACnE,QAAO,UAAU,cAAc,UAAU,eAAe,UAAU;;AAGpE,SAAS,SAAS,OAAkD;AAClE,QAAO,OAAO,UAAU,YAAY,UAAU;;AAGhD,SAAS,iBAAiB,MAA4B;AACpD,KAAI,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,WAChE,QAAO,YAAY,KAAK,GAAG,OAAO,YAAY;AAGhD,QAAO,YAAY,KAAK,GAAG,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE;;;;;;;;;;;;;AC1L9E,MAAa,OAAO;CAClB,QAAQ;CACR,eAAe;CACf,WAAW;CACZ;AAID,MAAM,aAA8B;CAAC,KAAK;CAAQ,KAAK;CAAe,KAAK;CAAU;AAyDrF,MAAa,6BAA6B;AAC1C,MAAa,0BAA0B;AAUvC,SAAS,cAAiB,KAAqB;CAC7C,IAAI;AACJ,KAAI;AACF,WAAS,gBAAgB,IAAI;SACvB;AACN,WAAS;;AAEX,KAAI,OAAO,WAAW,YAAY,WAAW,KAC3C,QAAO,OAAO,OAAO;AAEvB,QAAO;;AAGT,eAAe,qBACb,QACA,KACA,UACA,MACA,OACA,WACe;CACf,MAAM,YAAY,YAAY,KAAK;CACnC,IAAI,eAAe;CACnB,MAAM,WAAW,OAAO;CACxB,MAAM,gBAAgB,IAAI,SAAwB,YAAY;AAC5D,mBAAiB;AACf,kBAAe;AACf,WAAQ,cAAc;KACrB,SAAS;GACZ;CACF,MAAM,kBAAkB,YAAY;AAClC,MAAI;AACF,SAAM,OAAO,QAAQ,KAAK,SAAS;UAC7B;AAGR,SAAO;KACL;AAEJ,KADe,MAAM,QAAQ,KAAK,CAAC,gBAAgB,cAAc,CAAC,KACnD,iBAAiB,cAAc;EAC5C,MAAM,YAAY,KAAK,MAAM,YAAY,KAAK,GAAG,UAAU;AAC3D,MAAI,SAAS,KAAA,EACX,MAAK,yBAAyB;GAC5B;GACA,MAAM,OAAO;GACb;GACA,GAAI,cAAc,KAAA,IAAY,EAAE,WAAW,GAAG,EAAE;GAChD,cAAc,OAAO;GACrB;GACD,CAAC;;;;;;AAQR,SAAgB,mBACd,SACc;CACd,MAAM,SAAS,SAAS;CACxB,MAAM,YAAY,SAAS;CAC3B,MAAM,kBAAkB,SAAS,mBAAA;CACjC,MAAM,2BAAgE,IAAI,KAAK;CAC/E,IAAI,SAAS;CACb,IAAI,4BAA4B;CAChC,IAAI,sBAAqC;CAMzC,MAAM,OACJ,WAAW,KAAA,KACN,MAAM,YAAY;AACjB,SAAO,QAAQ,MAAM,QAAQ;KAE/B,KAAA;CAEN,SAAS,SACP,OACA,SACA,MACM;AACN,MAAI,QAAQ;GACV,MAAM,sBAAM,IAAI,MAAM,gDAAgD;AACtE,OAAI,OAAO;AACX,SAAM;;EAER,IAAI,gBAAgB,SAAS,IAAI,MAAM;AACvC,MAAI,kBAAkB,KAAA,GAAW;AAC/B,mCAAgB,IAAI,KAAK;AACzB,YAAS,IAAI,OAAO,cAAc;;EAEpC,IAAI,MAAM,cAAc,IAAI,KAAK,KAAK;AACtC,MAAI,QAAQ,KAAA,GAAW;AACrB,SAAM,EAAE;AACR,iBAAc,IAAI,KAAK,MAAM,IAAI;;EAEnC,MAAM,SAAwB;GACnB;GACT,GAAI,KAAK,YAAY,KAAA,IAAY,EAAE,SAAS,KAAK,SAAS,GAAG,EAAE;GAC/D,UAAU,KAAK,YAAY;GAC3B,MAAM,KAAK;GACX,mBAAmB;GACpB;AACD,+BAA6B;AAC7B,MAAI,KAAK,OAAO;;CAGlB,SAAS,iBAAuB;AAC9B,WAAS;;CAGX,SAAS,WAAoB;AAC3B,SAAO;;CAGT,eAAe,IACb,OACA,SACe;AACf,wBAAsB;EACtB,MAAM,gBAAgB,SAAS,IAAI,MAAM;AACzC,MAAI,kBAAkB,KAAA,EAAW;EACjC,MAAM,WAAyB,EAC7B,OAAO,WAAmB;AACxB,yBAAsB;KAEzB;AACD,OAAK,MAAM,QAAQ,YAAY;GAC7B,MAAM,MAAM,cAAc,IAAI,KAAK;AACnC,OAAI,QAAQ,KAAA,KAAa,IAAI,WAAW,EAAG;AAC3C,QAAK,MAAM,UAAU,KAAK;AACxB,QAAI,OAAO,YAAY,KAAA,KAAa,CAAC,OAAO,QAAQ,KAAK,MAAM,CAC7D;AAGF,UAAM,qBAAqB,QADf,cAAc,QAAQ,EACM,UAAU,MAAM,OAAO,UAAU;;;;CAK/E,SAAS,mBAAkC;AACzC,SAAO;;AAWT,QAR+B;EAC7B,MAAM;EACN;EACA,QAAQ;EACR;EACA;EACA;EACD;;;;AC/SH,MAAM,UAAU,IAAI,aAAa;;;;;;;;;AAUjC,SAAgB,iBAAiB,SAAuC;AACtE,KAAI,YAAY,KAAM,QAAO;AAC7B,KAAI,CAAC,OAAO,SAAS,QAAQ,CAAE,QAAO;AACtC,QAAO,QAAQ,UAAU;;;;;;;AAQ3B,SAAgB,iBAAiB,OAAqC;AACpE,QAAO;EACL,cAAc,MAAM;EACpB,kBAAkB,MAAM;EACxB,SAAS,iBAAiB,MAAM,QAAQ;EACzC;;;;;;;;;;;;;AAcH,SAAgB,wBACd,MACY;CACZ,MAAM,OAAO,aAAa,KAAK;AAC/B,KAAI,SAAS,KAAA,EACX,OAAM,IAAI,MACR,4IACD;AAEH,QAAO,QAAQ,OAAO,KAAK;;;;AC3B7B,MAAa,eAAe;AAE5B,MAAM,cAAc,IAAI,aAAa;AAErC,SAAgB,aAAa,OAA2B;AACtD,QAAO,OAAO,KAAK,MAAM,CAAC,SAAS,SAAS;;AAG9C,SAAgB,aAAa,OAA2B;AACtD,QAAO,IAAI,WAAW,OAAO,KAAK,OAAO,SAAS,CAAC;;;;;;;;;;;;;;;;AAiBrD,SAAgB,SACd,aACA,eACY;CACZ,MAAM,QACJ,YACA,YAAY,OAAO,UAAU,GAC7B,MACA,cACA,MACA,cAAc,OAAO,UAAU,GAC/B,MACA;AACF,QAAO,YAAY,OAAO,MAAM;;AAWlC,SAAgB,eACd,OACiB;AAMjB,QAAO;EACL,aAAa;EACb,SAPc,aAAa,MAAM,aAAa;EAQ9C,YAPqC,MAAM,WAAW,KAAK,WAAW;GACtE,OAAO,MAAM;GACb,KAAK,aAAa,MAAM,IAAI;GAC7B,EAAE;EAKF;;AAYH,SAAgB,eACd,UACiB;AACjB,KAAI,SAAS,gBAAA,uCACX,OAAM,IAAI,MACR,4CAA4C,aAAa,SAAS,SAAS,YAAY,GACxF;AAEH,QAAO;EACL,aAAa,SAAS;EACtB,cAAc,aAAa,SAAS,QAAQ;EAC5C,YAAY,SAAS,WAAW,KAAK,WAAW;GAC9C,OAAO,MAAM;GACb,KAAK,aAAa,MAAM,IAAI;GAC7B,EAAE;EACJ;;;;;;;;AC9GH,MAAa,8BAA8B;;;;;;;;;;;;;;;;;;;;;;AA4B3C,SAAgB,kBACd,MACA,WAAmB,6BACF;CACjB,MAAM,aAAiC,EAAE;AAMzC,KACE,KAAK,qBAAqB,KAAA,KAC1B,KAAK,iBAAiB,SAAS,SAE/B,YAAW,KAAK;EACd,MAAM;EACN,QAAQ;EACT,CAAC;CAKJ,MAAM,SAAS,CAAC,GAAG,WAAW,CAAC,MAAM,GAAG,MACtC,EAAE,OAAO,EAAE,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,IAAI,EAC9C;AAED,QAAO;EACL,MAAM;GACJ,GAAG;GACH,mBAAmB;GACnB,YAAY;GACb;EACD,YAAY;EACb;;;;;;;;;;;;;;;;;;;;;;;;ACcH,eAAsB,cACpB,OACA,QAC0B;CAC1B,MAAM,WAAW,MAAM,qBAAA;CACvB,MAAM,YAAY,MAAM,aAAa,OAAO,YAAY;CACxD,MAAM,WAAW,MAAM,6BAAY,IAAI,MAAM,EAAC,aAAa;CA2C3D,MAAM,EAAE,SAAS,kBAnCoB;EACnC,SALgD;EAMhD;EACA,OAAO,MAAM;EACb;EACA,KAAK,OAAO;EACZ,OAAO,MAAM;EACb,OAAO,MAAM;EACb,GAAI,MAAM,eAAe,KAAA,IAAY,EAAE,YAAY,MAAM,YAAY,GAAG,EAAE;EAC1E,GAAI,MAAM,qBAAqB,KAAA,IAAY,EAAE,kBAAkB,MAAM,kBAAkB,GAAG,EAAE;EAC5F,GAAI,MAAM,sBAAsB,KAAA,IAAY,EAAE,mBAAmB,MAAM,mBAAmB,GAAG,EAAE;EAC/F,OAAO,iBAAiB,MAAM,MAAM;EACpC,iBAAiB,MAAM;EACvB,cAAc,MAAM;EACpB,aAAa,MAAM;EACnB,YAAY,MAAM;EAClB,mBAAmB;EACnB,YAAY,EAAE;EACd,GAAI,MAAM,mBAAmB,KAAA,IACzB,EAAE,gBAAgB,MAAM,gBAAgB,GACxC,EAAE;EACN,GAAI,MAAM,qBAAqB,KAAA,IAC3B,EAAE,kBAAkB,MAAM,kBAAkB,GAC5C,EAAE;EAEN,GAAI,MAAM,aAAa,KAAA,IAAY,EAAE,UAAU,MAAM,UAAU,GAAG,EAAE;EACpE,GAAI,MAAM,cAAc,KAAA,IAAY,EAAE,WAAW,MAAM,WAAW,GAAG,EAAE;EACvE,GAAI,MAAM,mBAAmB,KAAA,IAAY,EAAE,gBAAgB,MAAM,gBAAgB,GAAG,EAAE;EACtF,GAAI,MAAM,qBAAqB,KAAA,IAAY,EAAE,kBAAkB,MAAM,kBAAkB,GAAG,EAAE;EAC5F,GAAI,MAAM,cAAc,KAAA,IAAY,EAAE,WAAW,MAAM,WAAW,GAAG,EAAE;EACvE,GAAI,MAAM,cAAc,KAAA,IAAY,EAAE,WAAW,MAAM,WAAW,GAAG,EAAE;EACxE,EAIyC,SAAS;CAGnD,MAAM,eAAe,wBAAwB,KAAK;CAMlD,MAAM,MAAM,SAAS,cAHL,aAAa,aAAa,CAGC;CAG3C,MAAM,MAAM,MAAM,OAAO,KAAK,IAAI;AAIlC,QAAO,eAAe;EACpB;EACA,YAAY,CAAC;GAAE,OAAO,OAAO;GAAK;GAAK,CAAC;EACzC,CAAC;;;;;;;;AChFJ,MAAa,6BAA6B;;;;;;AAO1C,MAAa,0BAAgC,KAAK;AAoDlD,MAAM,gBAA8B;CAClC,WAAW;CACX,UAAU;CACX;AAED,MAAM,gBAA8B;CAClC,YAAY;CACZ,cAAc;CACd,eAAe;CAChB;AAED,MAAM,gBAAgB;CACpB,cAAc;CACd,kBAAkB;CAClB,SAAS;CACV;;;;;;;;;;;;;;;;;;;;;AAsBD,SAAgB,qBACd,SACoC;CACpC,MAAM,QAAQ,QAAQ;CACtB,MAAM,SAAS,QAAQ;CACvB,MAAM,SAAS,QAAQ;CACvB,MAAM,YAAY,QAAQ;CAC1B,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,kBAAkB,QAAQ,mBAAmB;AAEnD,QAAO,eAAe,sBACpB,KACe;EAIf,MAAM,eAAwC;GAC5C;GACA,UAAU,IAAI;GACd,WAAW,IAAI;GACf,WAAW,IAAI;GACf,GAAI,IAAI,mBAAmB,KAAA,IAAY,EAAE,gBAAgB,IAAI,gBAAgB,GAAG,EAAE;GAClF,GAAI,IAAI,qBAAqB,KAAA,IAAY,EAAE,kBAAkB,IAAI,kBAAkB,GAAG,EAAE;GACxF,GAAI,cAAc,KAAA,IAAY,EAAE,WAAW,GAAG,EAAE;GACjD;EAID,IAAI;EACJ,IAAI;EACJ,IAAI;AACJ,MAAI,WAAW,KAAA,EACb,KAAI;AAiBF,cAAW,MAAM,cAhBiB;IAChC;IACA;IACA;IACA,OAAO;IACP;IACA,cAAc;IACd,aAAa,EAAE;IACf,YAAY;IACZ,UAAU,IAAI;IACd,WAAW,IAAI;IACf,WAAW,IAAI;IACf,GAAI,IAAI,mBAAmB,KAAA,IAAY,EAAE,gBAAgB,IAAI,gBAAgB,GAAG,EAAE;IAClF,GAAI,IAAI,qBAAqB,KAAA,IAAY,EAAE,kBAAkB,IAAI,kBAAkB,GAAG,EAAE;IACxF,GAAI,cAAc,KAAA,IAAY,EAAE,WAAW,GAAG,EAAE;IACjD,EACqC,OAAO;AAM7C,eAAY,iBAAiB,SAAS;WAC/B,KAAK;AACZ,eAAY,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;;EAMhE,MAAM,WAAoC;GACxC,GAAG;GACH,GAAI,cAAc,KAAA,IAAY,EAAE,WAAW,GAAG,EAAE;GAChD,GAAI,aAAa,KAAA,IAAY,EAAE,UAAU,GAAG,EAAE;GAC9C,GAAI,cAAc,KAAA,IAAY,EAAE,WAAW,GAAG,EAAE;GACjD;AACD,UAAQ,QAAQ,4BAA4B,SAAS;;;;;;;;;;;;AAazD,SAAS,iBAAiB,UAA+C;AACvE,KAAI;EAEF,MAAM,QAAQ,WAAW,KAAK,KAAK,SAAS,QAAQ,GAAG,MAAM,EAAE,WAAW,EAAE,CAAC;EAC7E,MAAM,OAAO,KAAK,MAAM,IAAI,aAAa,CAAC,OAAO,MAAM,CAAC;AACxD,SAAO,OAAO,KAAK,cAAc,WAAW,KAAK,YAAY,KAAA;SACvD;AACN;;;;;;;;;;;;;;ACxIJ,SAAgB,uBAAuB,QAAmC;CACxE,MAAM,iBAAkB,OAAyD;AACjF,KACE,OAAO,mBAAmB,YAC1B,mBAAmB,QACnB,YAAY,gBACZ;EACA,MAAM,SAAS;EACf,MAAM,cAAe,OAClB;AACH,MAAI,OAAO,gBAAgB,WACzB,KAAI;AACF,UAAO,aAAa;UACd;AAIV,SAAO;GACL,UAAU,2BAA2B,OAAO,OAAO;GACnD,MAAM;GACP;;AAEH,QAAO;EAAE,UAAU;EAA6B,MAAM;EAAU;;;;;;;;;;AAWlE,SAAgB,uBACd,cACA,OACA,UAA8B,EAAE,EACV;AAIjB,SAAQ;CAEb,MAAM,SAAS,QAAQ,QAAQ,MAAM,IAAI;CACzC,MAAM,mBAAmB,MACtB,KAAK,SAAS;EACb,MAAM,mBAAmB,uBAAuB,KAAK,YAAY;EACjE,MAAM,aAAa,KAAK,UAAU,kBAAkB,MAAM,EAAE;EAC5D,MAAM,OAAO,KAAK,aAAa,MAAM,IAAI;AACzC,SAAO,WAAW,KAAK,KAAK,mBAAmB,KAAK,mBAAmB;GACvE,CACD,KAAK,KAAK;CAEb,MAAM,uBAAuB;EAC3B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;CAEZ,MAAM,cAAc;EAClB;EACA;EACA;EACA,oBAAoB;EACpB;EACA;EACD,CACE,QAAQ,MAAM,MAAM,MAAM,KAAK,CAC/B,KAAK,KAAK,CACV,QAAQ,QAAQ,GAAG,CACnB,SAAS;CAEZ,SAAS,aACP,cACA,oBACQ;EACR,MAAM,QAAkB,EAAE;AAC1B,MAAI,mBACF,OAAM,KAAK,YAAY;AAEzB,QAAM,KAAK,GAAG;AACd,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,GAAG;AACd,OAAK,MAAM,QAAQ,cAAc;AAC/B,OAAI,KAAK,SAAS,OAChB,OAAM,KAAK,UAAU,KAAK,UAAU;YAC3B,KAAK,SAAS,YACvB,OAAM,KAAK,eAAe,KAAK,UAAU;QACpC;IACL,MAAM,SAAS,KAAK,eAAe,KAAA,IAAY,OAAO,KAAK,eAAe;IAC1E,MAAM,WAAW,KAAK,aAAa,KAAA,IAAY,SAAS,KAAK,aAAa;AAC1E,UAAM,KAAK,gBAAgB,SAAS,MAAM,IAAI,SAAS,OAAO,MAAM,KAAK,UAAU;;AAErF,SAAM,KAAK,GAAG;;AAEhB,QAAM,KAAK,aAAa;AACxB,SAAO,MAAM,KAAK,KAAK;;CAGzB,SAAS,UAAU,cAAmD;AACpE,SAAO,aAAa,cAAc,KAAK;;CAGzC,SAAS,cAAc,cAAmD;AACxE,SAAO,aAAa,cAAc,MAAM;;CAG1C,SAAS,oBAA4B;AACnC,SAAO;;AAGT,QAAO;EACL;EACA;EACA,cAAc;EACd;EACA,MAAM;EACP;;AAGH,SAAgB,qBAAqB,cAA4D;AAC/F,KAAI,OAAO,iBAAiB,YAAY,aAAa,WAAW,EAC9D,QAAO;CAET,MAAM,aAAa,sBAAsB,aAAa;AACtD,MAAK,MAAM,aAAa,YAAY;EAClC,MAAM,SAAS,iBAAiB,UAAU;AAC1C,MAAI,WAAW,KACb,QAAO;;AAGX,QAAO;;;;;;;;;;AAWT,SAAS,sBAAsB,MAAiC;CAC9D,MAAM,aAAuB,EAAE;CAE/B,MAAM,aAAa;CACnB,IAAI;AACJ,SAAQ,aAAa,WAAW,KAAK,KAAK,MAAM,MAAM;EACpD,MAAM,QAAQ,WAAW;AACzB,MAAI,UAAU,KAAA,EACZ,YAAW,KAAK,MAAM,MAAM,CAAC;;CAIjC,MAAM,aAAa,KAAK,QAAQ,IAAI;CACpC,MAAM,WAAW,KAAK,YAAY,IAAI;AACtC,KAAI,eAAe,MAAM,WAAW,WAClC,YAAW,KAAK,KAAK,MAAM,YAAY,WAAW,EAAE,CAAC;AAGvD,YAAW,KAAK,KAAK,MAAM,CAAC;AAC5B,QAAO;;AAGT,SAAS,iBAAiB,UAAwD;CAChF,IAAI;AACJ,KAAI;AACF,WAAS,KAAK,MAAM,SAAS;SACvB;AACN,SAAO;;AAET,KAAI,OAAO,WAAW,YAAY,WAAW,KAC3C,QAAO;CAGT,MAAM,YADW,OACU;AAC3B,KAAI,CAAC,MAAM,QAAQ,UAAU,IAAI,UAAU,WAAW,EACpD,QAAO;CAET,MAAM,WAA6B,EAAE;AACrC,MAAK,MAAM,QAAQ,WAAW;AAC5B,MAAI,OAAO,SAAS,YAAY,SAAS,KACvC,QAAO;EAET,MAAM,aAAa;EACnB,MAAM,KAAK,WAAW;EACtB,MAAM,OAAO,WAAW;EACxB,MAAM,OAAO,WAAW;AACxB,MAAI,OAAO,OAAO,YAAY,OAAO,SAAS,SAC5C,QAAO;AAET,WAAS,KAAK;GAAE;GAAI;GAAM;GAAM,CAAC;;AAEnC,QAAO;;;;ACzTT,eAAsB,qBACpB,MACA,QACA,OAUA;CACA,MAAM,SAAS,OAAO,aAAa,SAAS,MAAM;CAClD,MAAM,aAAa,kBAAkB,UAAU,MAAM,SAAS;AAE9D,KAAI,WAAW,OACb,QAAO;EACL,IAAI;EACJ,OAAO;IACJ,WAAW;GACZ,QAAQ,WAAW,OAAO,IAAI,eAAe;GAC9C;EACF;AAGH,QAAO;EACL,IAAI;EACJ,OAAO,WAAW;EACnB;;AAGH,eAAsB,kBACpB,WACA,YACA,MAC8B;CAC9B,MAAM,UAAmC,EAAE;AAE3C,MAAK,MAAM,CAAC,MAAM,aAAa,OAAO,QAAQ,UAAU,EAAE;EACxD,MAAM,QAAQ,WAAW;EACzB,MAAM,QAAQ,MAAM,eAAe,MAAM,UAAU,MAAM;AAEzD,MAAI,CAAC,MAAM,GACT,QAAO;GACL,IAAI;GACJ,OAAO;IACL,MAAM;IACN,SAAS,mBAAmB,KAAK;KAChC,WAAW;IACZ,QAAQ,MAAM;IACf;GACD,OAAO;IAAE,cAAc;IAAG,kBAAkB;IAAG,SAAS;IAAM;GAC9D,KAAK;GACL,gBAAgB;GAChB;GACD;AAGH,UAAQ,QAAQ,MAAM;;AAGxB,QAAO;EACL,IAAI;EACK;EACT,WAAW,EAAE;EACb,OAAO;GAAE,cAAc;GAAG,kBAAkB;GAAG,SAAS;GAAM;EAC9D;EACD;;AAGH,eAAe,eACb,MACA,UACA,OAIA;AACA,KAAI,aAAa,QAAQ;AACvB,MAAI,OAAO,UAAU,SACnB,QAAO;GACL,IAAI;GACJ,QAAQ,CAAC,EAAE,SAAS,wCAAwC,CAAC;GAC9D;AAGH,SAAO;GAAE,IAAI;GAAM;GAAO;;AAG5B,KAAI,iBAAiB,SAAS,EAAE;EAC9B,MAAM,SAAS,MAAM,qBAAqB,MAAM,UAAU,MAAM;AAEhE,MAAI,CAAC,OAAO,GACV,QAAO;GACL,IAAI;GACJ,QAAQ,OAAO,MAAM;GACtB;AAGH,SAAO;GAAE,IAAI;GAAM,OAAO,OAAO;GAAO;;AAG1C,KAAI,SAAS,SAAS,aAAa;AACjC,MAAI,CAAC,MAAM,QAAQ,MAAM,CACvB,QAAO;GACL,IAAI;GACJ,QAAQ,CAAC,EAAE,SAAS,6CAA6C,CAAC;GACnE;AAGH,SAAO;GAAE,IAAI;GAAM;GAAO;;AAG5B,KAAI,SAAS,SAAS,aAAa;AACjC,MAAI,CAAC,MAAM,QAAQ,MAAM,CACvB,QAAO;GACL,IAAI;GACJ,QAAQ,CAAC,EAAE,SAAS,6CAA6C,CAAC;GACnE;AAGH,OAAK,MAAM,QAAQ,OAAO;AACxB,OAAI,CAAC,cAAc,KAAK,CACtB,QAAO;IACL,IAAI;IACJ,QAAQ,CAAC,EAAE,SAAS,yDAAyD,CAAC;IAC/E;AAGH,OAAI,SAAS,iBAAiB,KAAA,KAAa,KAAK,SAAS,SAAS,aAChE,QAAO;IACL,IAAI;IACJ,QAAQ,CACN,EACE,SAAS,8CAA8C,SAAS,aAAa,KAC9E,CACF;IACF;;AAIL,SAAO;GAAE,IAAI;GAAM,OAAO,MAAM,IAAI,cAAc;GAAE;;AAGtD,QAAO;EACL,IAAI;EACJ,QAAQ,CAAC,EAAE,SAAS,gCAAgC,CAAC;EACtD;;AAGH,SAAS,iBAAiB,UAAwD;AAChF,KAAI,OAAO,aAAa,YAAY,aAAa,KAC/C,QAAO;AAOT,QAAO,OAJW,SAChB,cAGsB,aAAa;;AAGvC,SAAS,eAAe,OAAgD;CACtE,MAAM,OAAO,MAAM,MACf,IAAI,qBAAqB,CAC1B,QAAQ,YAAiD,YAAY,KAAA,EAAU;AAElF,QAAO;EACL,SAAS,MAAM;EACf,GAAI,SAAS,KAAA,KAAa,KAAK,SAAS,IAAI,EAAE,MAAM,GAAG,EAAE;EAC1D;;AAGH,SAAS,qBACP,SACsC;AACtC,KACE,OAAO,YAAY,YACnB,OAAO,YAAY,YACnB,OAAO,YAAY,SAEnB,QAAO;AAGT,QAAO,iBAAiB,QAAQ,IAAI;;AAGtC,SAAS,iBAAiB,KAA4C;AACpE,QAAO;;;;;;;;;;;;;;;;ACIT,SAAgB,+BACd,UAA2C,EAAE,EACf;CAC9B,MAAM,KAAK,QAAQ,MAAM;CACzB,MAAM,gBAA8B,QAAQ,UAAU;CACtD,MAAM,wBAAQ,IAAI,KAA2B;AAE7C,QAAO;EACL,MAAM;EACN;EACA,UAAU,OAAmC;AAC3C,UAAO;IACL,MAAM;IACN,SAAS;IACT,SAAS,KAAK,UAAU,SAAS,KAAK;IACtC,6BAAY,IAAI,MAAM,EAAC,aAAa;IACrC;;EAEH,YAAY,UAAsC;AAGhD,UAAO,KAAK,MAAM,SAAS,QAAQ;;EAErC,WAAW,MAA2C;AACpD,SAAM,IAAI,KAAK;GACf,IAAI,eAAe;AACnB,gBAAa;AACX,QAAI,aAAc;AAClB,mBAAe;AACf,UAAM,OAAO,KAAK;;;EAGtB,MAAM,OAAO,WAAsD;AAKjE,UAAO;;EAEV;;;;ACtNH,SAAgB,WACd,YACyB;AACzB,QAAO;EACL,MAAM;EACN,GAAG;EACJ;;AAGH,eAAsB,QACpB,MACA,OACA,UAAgC,EAAE,EACT;CACzB,MAAM,aAAa,MAAM,qBAAqB,KAAK,MAAM,KAAK,aAAa,MAAM;AAEjF,KAAI,CAAC,WAAW,GACd,OAAM,IAAI,MAAM,2BAA2B,KAAK,KAAK,IAAI;CAG3D,MAAM,SAAS,kBAAkB;CACjC,MAAM,SAAS,MAAM,KAAK,QAAQ,WAAW,OAAO,QAAQ;AAE5D,QAAO;EACL;EACA,UAAU,KAAK;EACf,UAAU,SAAS,WAAW,QAAQ;GACpC,IAAI,wBAAwB,KAAK,KAAK,GAAG;GACzC,UAAU,KAAK;GACf;GACD,CAAC;EACH;;AAiBH,eAAsB,eACpB,QACA,WACoC;CACpC,MAAM,cAAc,MAAM,QAAQ,QAAQ,OAAO,aAAa,IAAI,EAAE,CAAC;CACrE,MAAM,UAAU,cAAc,KAAA,IAAY,KAAA,IAAY,IAAI,IAAI,UAAU;AAExE,QAAO,YACJ,QAAQ,eAAe,YAAY,KAAA,KAAa,QAAQ,IAAI,WAAW,KAAK,CAAC,CAC7E,KAAK,eACJ,WAAW;EACT,MAAM,WAAW;EACjB,GAAI,WAAW,gBAAgB,KAAA,IAC3B,EAAE,aAAa,WAAW,aAAa,GACvC,EAAE;EACN,aAAa,WAAW;EACxB,SAAS,OAAO,UACd,OAAO,SAAS;GACd,MAAM,WAAW;GACjB,WAAW;GACZ,CAAC;EACL,CAAC,CACH;;AAGL,SAAgB,gBAAgB,QAAqC;CACnE,MAAM,EAAE,OAAO,QAAQ,GAAG,QAAQ,OAAO;AAEzC,QAAO;;AAGT,SAAS,mBAA2B;AAClC,KAAI,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,WAChE,QAAO,OAAO,YAAY;AAG5B,QAAO,GAAG,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE;;;;;;;;;;;;;;ACiC7D,SAAgB,sBAAiC;AAC/C,QAAO;EACL,MAAM;EACN,WAAW,EACT,MAAM,aAAa,iBAAwC,IAG5D;EACD,WAAW,EACT,MAAM,KACJ,UACA,SAC8B;AAC9B,OAAI,SAAS,YAAY,KAAA,EACvB,OAAM,IAAI,MACR,4BAA4B,SAAS,GAAG,2BACzC;AAEH,UAAO,SAAS,QAAQ,QAAQ;KAEnC;EACD,SAAS;GACP,MAAM,KAAK,WAA8C;GAGzD,MAAM,OAA2C;AAC/C,WAAO;;GAET,MAAM,QAAuB;GAG9B;EACF;;;;;;;;;;;;;ACDH,IAAa,mBAAb,cAAsC,MAAM;CAC1C,OAAgB;CAChB,WAAoB;CACpB;CACA;CAEA,YAAY,QAAgB,gBAAwB;AAClD,QAAM,mBAAmB,eAAe,WAAW,SAAS;AAC5D,OAAK,OAAO;AACZ,OAAK,SAAS;AACd,OAAK,iBAAiB;;;;;;;;;AChI1B,MAAM,aAAoB;CAAE,cAAc;CAAG,kBAAkB;CAAG,SAAS;CAAM;;;;;;;;;;;;;AAgDjF,eAAsB,SACpB,QACA,SAAwB,EAAE,EACM;AAChC,QAAO,iBAAiB,QAAQ,OAAO;;;;;;;AAQzC,eAAsB,iBACpB,QACA,SAAwB,EAAE,EAC1B,kBAA2C,EAAE,EACb;CAChC,MAAM,YAAY,KAAK,KAAK;CAC5B,MAAM,kBAAkB;EAAE,cAAc;EAAG,kBAAkB;EAAG,SAAS;EAAuB;CAChG,MAAM,aAAgC,EAAE;CAGxC,MAAM,OAAkB,OAAO,QAAQ,qBAAqB;CAC5D,MAAM,uBACJ,OAAO,wBAAwB,gCAA+C;CAGhF,MAAM,WAAW,eAAe,OAAO;AACvC,6BAA4B,UAAU,OAAO;CAG7C,MAAM,WAAW,4BAA4B,OAAO;AACpD,KAAI,aAAa,KACf,QAAO,aAAa;EAClB,MAAM;EACN,QAAQ;EACR;EACA,OAAO;EACR,CAAC;CAEJ,IAAI,eAAe,SAAS;CAG5B,IAAI,eAAmC,CAAC;EAAE,MAAM;EAAQ,SAAS,OAAO;EAAM,CAAC;CAC/E,MAAM,SAAS,uBAAuB,cAAc,OAAO,MAAM;CAEjE,MAAM,SAAS,OAAO,UAAU;CAChC,MAAM,gBAAgB,QAAQ,iBAAiB,OAAO;CACtD,MAAM,gBAAgB,QAAQ,iBAAiB,OAAO;CACtD,MAAM,aAAa,QAAQ,cAAc,OAAO;CAEhD,IAAI,iBAAiB;CAMrB,MAAM,mBAAmB,MAAM,KAAK,SAAS,MAAM;AACnD,KAAI,qBAAqB,QAAQ,qBAAqB,KAAA,GAAW;AAC/D,SAAO,QAAQ,QAAQ,kBAAkB;GACvC,iBAAiB,iBAAiB;GAClC,YAAY,iBAAiB;GAC9B,CAAC;AACF,MAAI;GACF,MAAM,WAAW,qBAAqB,YAAY,iBAAiB;AACnE,oBAAiB,SAAS;AAC1B,kBAAe,CAAC,GAAG,SAAS,aAAa;AACzC,mBAAgB,eAAe,SAAS,gBAAgB;AACxD,mBAAgB,mBAAmB,SAAS,gBAAgB;AAC5D,mBAAgB,UAAU,SAAS,gBAAgB;AACnD,kBAAe,SAAS;AACxB,UAAO,QAAQ,QAAQ,qBAAqB;IAC1C;IACA;IACD,CAAC;WACK,OAAO;AACd,UAAO,QAAQ,QAAQ,mBAAmB,EACxC,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,sBAClD,CAAC;AACF,SAAM,KAAK,SAAS,OAAO;;;AAK/B,QAAO,iBAAiB,eAAe;EAErC,MAAM,YAAY,KAAK,KAAK,GAAG;AAC/B,MAAI,aAAa,cACf,QAAO,aAAa;GAClB,MAAM;GACN,QAAQ,oBAAoB,cAAc,oBAAoB,UAAU;GACxE;GACA,OAAO;GACR,CAAC;AAEJ,MACE,gBAAgB,YAAY,QAC5B,gBAAgB,WAAW,WAK3B,QAAO,aAAa;GAClB,MAAM;GACN,QAAQ,gBAAgB,WAAW,gBAAgB,gBAAgB;GACnE;GACA,OAAO;GACR,CAAC;AAIJ,QAAM,SAAS,IAAI,0BAA0B;GAC3C;GACA;GACA,cAAc,aAAa,KAAK,OAAO,EAAE,GAAG,GAAG,EAAE;GAGjD,UAAU,mBAAmB,eAAe;GAC5C,WAAW;GACX,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC,GAAI,iBAAiB,IACjB,EAAE,kBAAkB,mBAAmB,iBAAiB,EAAE,SAAS,GACnE,EAAE;GACP,CAAC;EACF,MAAM,SAAS,SAAS,kBAAkB;AAC1C,MAAI,WAAW,MAAM;GACnB,MAAM,eAAgC;IACpC,OAAO;IACP,UAAU;IACV,cAAc;IACd,kBAAkB;IAClB,SAAS;IACT,YAAY;IACZ,WAAW,EAAE;IACb,cAAc;IACf;AACD,cAAW,KAAK,aAAa;AAC7B,SAAM,SAAS,IAAI,yBAAyB;IAC1C;IACA;IACA,QAAQ;IACR,UAAU,mBAAmB,eAAe;IAC5C,WAAW;IACX,4BAAW,IAAI,MAAM,EAAC,aAAa;IACnC,kBAAkB,mBAAmB,eAAe;IACrD,CAAC;AACF,UAAO,aAAa;IAClB,MAAM;IACN,QAAQ;IACR;IACA,OAAO;IACR,CAAC;;EAIJ,MAAM,OAAO,OAAO,UAAU,aAAa;EAC3C,MAAM,YAAY,KAAK,KAAK;EAC5B,IAAI;AACJ,MAAI;AACF,OAAI,SAAS,YAAY,KAAA,EACvB,QAAO,aAAa;IAClB,MAAM;IACN,QAAQ;IACR;IACA,OAAO;IACR,CAAC;GAEJ,MAAM,kBAAkB;IACtB;IACA,WAAW,EAAE;IACb,SAAS,CAAC,SAAS;IACnB,GAAI,OAAO,WAAW,KAAA,IAAY,EAAE,QAAQ,OAAO,QAAQ,GAAG,EAAE;IACjE;AACD,cAAW,KAAK,cAAc,KAAA,IAC1B,MAAM,KAAK,UAAU,KAAK,UAAU,gBAAgB,GACpD,MAAM,SAAS,QAAQ,gBAAgB;WACpC,OAAO;AACd,UAAO,aAAa;IAClB,MAAM;IACN,QAAQ,iBAAiB,QAAQ,MAAM,UAAU;IACjD,OAAO;IACP;IACA,OAAO;IACR,CAAC;;EAEJ,MAAM,eAAe,KAAK,KAAK,GAAG;EAClC,MAAM,YAAY,SAAS,mBAAmB;AAC9C,kBAAgB,iBAAiB,UAAU;EAG3C,MAAM,eAAe,oBAAoB,SAAS;EAClD,MAAM,kBAAkB,SAAS,cAAc,KAAA,IAC3C,SAAS,UAAU,KAAK,cAAc;GACpC,IAAI,SAAS;GACb,MAAM,SAAS;GACf,MAAM,SAAS;GAChB,EAAE,GACH,OAAO,aAAa,aAAa;AAErC,MAAI,oBAAoB,QAAQ,gBAAgB,WAAW,GAAG;GAE5D,MAAM,cAA+B;IACnC,OAAO;IACP,UAAU;IACV,cAAc,UAAU;IACxB,kBAAkB,UAAU;IAC5B,SAAS,UAAU;IACnB,YAAY;IACZ,WAAW,EAAE;IACd;AACD,cAAW,KAAK,YAAY;AAC5B,gBAAa,KAAK;IAAE,MAAM;IAAa,SAAS;IAAc,CAAC;AAE/D,SAAM,SAAS,IAAI,yBAAyB;IAC1C;IACA;IACA,QAAQ;IACR,UAAU,mBAAmB,eAAe;IAC5C,WAAW;IACX,4BAAW,IAAI,MAAM,EAAC,aAAa;IACnC,kBAAkB,mBAAmB,eAAe;IACrD,CAAC;AAIF,SAAM,KAAK,SAAS,OAAO;GAQ3B,MAAM,eACJ,SAAS,iBAAiB,KAAA,IACtB,SAAS,aAAa,IAAI,cAAc,GACxC,EAAE;AACR,UAAO;IACL,MAAM;IACN,QAAQ,EAAE,QAAQ,cAAc;IAChC,GAAI,aAAa,SAAS,IAAI,EAAE,WAAW,cAAc,GAAG,EAAE;IAC9D,OAAO,cAAc,gBAAgB;IACrC,YAAY,OAAO,OAAO,CAAC,GAAG,WAAW,CAAC;IAC3C;;AAIH,eAAa,KAAK;GAAE,MAAM;GAAa,SAAS;GAAc,CAAC;EAC/D,MAAM,kBAKD,EAAE;AACP,OAAK,MAAM,OAAO,iBAAiB;GACjC,IAAI,gBAA+B;GACnC,IAAI,aAAa;AAKjB,OAAI,gBAAgB,oBAAoB,KAAA,GAAW;IACjD,MAAM,aAAa,MAAM,gBAAgB,gBAAgB,KAAK;KAC5D;KACA;KACA;KACD,CAAC;AACF,QAAI,eAAe,KAAA,GAAW;AAC5B,qBAAgB,WAAW;AAC3B,kBAAa,WAAW,WAAW,QAAQ;;;AAI/C,OAAI,kBAAkB,MAAM;IAC1B,MAAM,OAAO,OAAO,MAAM,MAAM,MAAM,EAAE,SAAS,IAAI,KAAK;IAC1D,IAAI,aAAoC;AACxC,QAAI,SAAS,KAAA,EACX,iBAAgB,KAAK,UAAU,EAC7B,OAAO,iBAAiB,IAAI,QAC7B,CAAC;QAEF,KAAI;AACF,WAAM,SAAS,IAAI,eAAe;MAChC;MACA,UAAU,IAAI;MACd,MAAM,IAAI;MACX,CAAC;AACF,kBAAa,MAAM,QAAQ,MAAM,IAAI,KAAK;AAC1C,qBAAgB,uBAAuB,WAAW,SAAS,MAAM;AACjE,kBAAa,WAAW;AACxB,WAAM,SAAS,IAAI,cAAc;MAC/B;MACA,UAAU,IAAI;MACd,MAAM,IAAI;MACV,QAAQ,WAAW,SAAS;MAC7B,CAAC;aACK,OAAO;AACd,qBAAgB,KAAK,UAAU,EAC7B,OAAO,iBAAiB,QAAQ,MAAM,UAAU,yBACjD,CAAC;;;AAIR,gBAAa,KAAK;IAChB,MAAM;IACN,SAAS;IACT,YAAY,IAAI;IAChB,UAAU,IAAI;IACf,CAAC;AACF,mBAAgB,KAAK;IACnB,IAAI,IAAI;IACR,MAAM,IAAI;IACV,UAAU,WAAW,IAAI,KAAK;IAC9B;IACD,CAAC;;EAGJ,MAAM,SAA0B;GAC9B,OAAO;GACP,UAAU;GACV,cAAc,UAAU;GACxB,kBAAkB,UAAU;GAC5B,SAAS,UAAU;GACnB,YAAY;GACZ,WAAW,OAAO,OAAO,CAAC,GAAG,gBAAgB,CAAC;GAC/C;AACD,aAAW,KAAK,OAAO;AAEvB,QAAM,SAAS,IAAI,yBAAyB;GAC1C;GACA;GACA;GACA,UAAU,mBAAmB,eAAe;GAC5C,WAAW;GACX,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC,kBAAkB,mBAAmB,eAAe;GACrD,CAAC;AAMF,MAAI,KAAK,YAAY,KAAA,GAAW;GAC9B,MAAM,WAAW,qBAAqB,UAAU;IAC9C,SAAS;IACT,gBAAgB,iBAAiB;IACjC,cAAc,CAAC,GAAG,aAAa;IAC/B,iBAAiB,cAAc,gBAAgB;IAC/C;IACA,6BAAY,IAAI,MAAM,EAAC,aAAa;IACrC,CAAC;AACF,SAAM,KAAK,QAAQ,KAAK,SAAS;;AAInC,MAAI,KAAK,cAAc,KAAA,EACrB,OAAM,KAAK,UAAU,aAAa,eAAe;AAGnD,oBAAkB;;AAGpB,QAAO,aAAa;EAClB,MAAM;EACN,QAAQ,oBAAoB,cAAc;EAC1C;EACA,OAAO;EACR,CAAC;;AAGJ,SAAS,eAAsC,QAAyB;AACtE,KAAI,OAAO,aAAa,KAAA,EAAW,QAAO,OAAO;AAGjD,QAAO,mBADL,OAAO,WAAW,KAAA,IAAY,EAAE,QAAQ,OAAO,QAAQ,GAAG,EAAE,CAC5B;;AAGpC,SAAS,4BACP,UACA,QACM;AACN,KAAI,OAAO,WAAW,KAAA,EAAW;AACjC,KAAI,OAAO,2BAA2B,MAAO;AAC7C,KAAI,SAAS,UAAU,CAAE;CACzB,MAAM,UAAU,qBAAqB;EACnC,OAAO,YAAY,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE;EACpE,QAAQ,OAAO;EACf,GAAI,OAAO,WAAW,KAAA,IAAY,EAAE,QAAQ,OAAO,QAAQ,GAAG,EAAE;EACjE,CAAC;AACF,UAAS,SAAS,yBAAyB,SAAS,EAAE,MAAM,KAAK,eAAe,CAAC;;AAGnF,SAAS,4BAA4B,QAA+C;CAClF,MAAM,YAAY,OAAO,aAAa,EAAE;AACxC,MAAK,MAAM,SAAS,WAAW;AAC7B,MAAI,OAAO,UAAU,SAAU;AAC/B,MAAI,UAAU,SAAS,MAAM,SAAS,sBAAsB,MAAM,YAAY,KAAA,EAC5E,QAAO;;AAGX,QAAO;;AAGT,SAAS,oBAAoB,UAAuC;CAClE,MAAM,MAAM,SAAS,cAAc,EAAE;CACrC,MAAM,OAAO,IAAI;AACjB,KAAI,OAAO,SAAS,SAAU,QAAO;AAErC,MAAK,MAAM,SAAS,OAAO,OAAO,IAAI,CACpC,KAAI,OAAO,UAAU,SAAU,QAAO;AAExC,QAAO;;AAGT,SAAS,gBACP,YACA,MACM;AACN,YAAW,gBAAgB,KAAK;AAChC,YAAW,oBAAoB,KAAK;AACpC,KAAI,KAAK,YAAY,KACnB,YAAW,WAAW,WAAW,WAAW,KAAK,KAAK;;AAI1D,SAAS,cAAc,GAIb;AACR,QAAO;EACL,cAAc,EAAE;EAChB,kBAAkB,EAAE;EACpB,SAAS,EAAE;EACZ;;AAGH,SAAS,aAAa,OAML;AACf,QAAO;EACL,MAAM,MAAM;EACZ,OAAO,cAAc,MAAM,MAAM;EACjC,YAAY,OAAO,OAAO,CAAC,GAAG,MAAM,WAAW,CAAC;EAChD,GAAI,MAAM,WAAW,KAAA,IAAY,EAAE,QAAQ,MAAM,QAAQ,GAAG,EAAE;EAC9D,GAAI,MAAM,UAAU,KAAA,IAAY,EAAE,OAAO,MAAM,OAAO,GAAG,EAAE;EAC5D;;AAGH,SAAS,uBAAuB,OAAwB;AACtD,KAAI,OAAO,UAAU,SAAU,QAAO;AACtC,KAAI;AACF,SAAO,KAAK,UAAU,MAAM;SACtB;AACN,SAAO,OAAO,MAAM;;;AAIxB,SAAS,WAAW,OAAwB;AAC1C,KAAI;EACF,MAAM,OAAO,KAAK,UAAU,MAAM;EAClC,IAAI,OAAO;AACX,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,EACpC,QAAQ,OAAO,KAAM,KAAK,WAAW,EAAE;AAEzC,SAAO,SAAS,SAAS,GAAG,SAAS,GAAG;SAClC;AACN,SAAO"}