@vercel/factory 0.0.15 → 0.0.16
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.
- package/CHANGELOG.md +356 -0
- package/README.md +49 -261
- package/dist/agent-routes.d.mts +47 -3
- package/dist/agent-routes.mjs +28 -1
- package/dist/agent-routes.mjs.map +1 -1
- package/dist/api-contracts.d.mts +20 -1
- package/dist/api-contracts.mjs +2 -1
- package/dist/api-contracts.mjs.map +1 -1
- package/dist/api.d.mts +45 -2
- package/dist/api.mjs +199 -10
- package/dist/api.mjs.map +1 -1
- package/dist/approval-contracts.d.mts +6 -0
- package/dist/blob/index.d.mts +51 -14
- package/dist/blob/index.mjs +26 -10
- package/dist/blob/index.mjs.map +1 -1
- package/dist/budget.d.mts +7 -0
- package/dist/budget.mjs +6 -0
- package/dist/budget.mjs.map +1 -1
- package/dist/build-factory.d.mts +1 -0
- package/dist/change-verification/dispatch.d.mts +16 -3
- package/dist/change-verification/dispatch.mjs +45 -7
- package/dist/change-verification/dispatch.mjs.map +1 -1
- package/dist/change-verification/eve-tool.d.mts +2 -1
- package/dist/change-verification/eve-tool.mjs +35 -47
- package/dist/change-verification/eve-tool.mjs.map +1 -1
- package/dist/change-verification/result.mjs +130 -0
- package/dist/change-verification/result.mjs.map +1 -0
- package/dist/changes/eve-record-change.d.mts +2 -2
- package/dist/changes/eve-record-change.mjs +43 -9
- package/dist/changes/eve-record-change.mjs.map +1 -1
- package/dist/changes.d.mts +4 -3
- package/dist/changes.mjs +2 -2
- package/dist/changes.mjs.map +1 -1
- package/dist/client-events.d.mts +10 -3
- package/dist/client-events.mjs +6 -2
- package/dist/client-events.mjs.map +1 -1
- package/dist/client-stream.mjs +8 -2
- package/dist/client-stream.mjs.map +1 -1
- package/dist/client-transcript.mjs +5 -1
- package/dist/client-transcript.mjs.map +1 -1
- package/dist/client.d.mts +121 -12
- package/dist/client.mjs +117 -9
- package/dist/client.mjs.map +1 -1
- package/dist/code-review/contracts.d.mts +1 -0
- package/dist/code-review/eve-post-review.d.mts +4 -4
- package/dist/code-review/eve-post-review.mjs +29 -17
- package/dist/code-review/eve-post-review.mjs.map +1 -1
- package/dist/code-review/eve-review-comments.d.mts +13 -2
- package/dist/code-review/eve-review-comments.mjs +45 -11
- package/dist/code-review/eve-review-comments.mjs.map +1 -1
- package/dist/code-review/github-reporter.d.mts +2 -0
- package/dist/code-review/github-reporter.mjs +7 -5
- package/dist/code-review/github-reporter.mjs.map +1 -1
- package/dist/code-review.d.mts +3 -2
- package/dist/deepsec/eve-tool.mjs +3 -1
- package/dist/deepsec/eve-tool.mjs.map +1 -1
- package/dist/dispatch.d.mts +79 -8
- package/dist/dispatch.mjs +68 -9
- package/dist/dispatch.mjs.map +1 -1
- package/dist/eve/index.d.mts +70 -10
- package/dist/eve/index.mjs +93 -22
- package/dist/eve/index.mjs.map +1 -1
- package/dist/eve/invoke.mjs +24 -11
- package/dist/eve/invoke.mjs.map +1 -1
- package/dist/eve/session-client.d.mts +122 -4
- package/dist/eve/session-client.mjs +127 -13
- package/dist/eve/session-client.mjs.map +1 -1
- package/dist/eve/task-execution.d.mts +380 -0
- package/dist/eve/task-execution.mjs +57 -2
- package/dist/eve/task-execution.mjs.map +1 -1
- package/dist/eve/task-session.d.mts +44 -2
- package/dist/eve/task-session.mjs +44 -2
- package/dist/eve/task-session.mjs.map +1 -1
- package/dist/eve/transcript.mjs +5 -1
- package/dist/eve/transcript.mjs.map +1 -1
- package/dist/execution.d.mts +117 -9
- package/dist/execution.mjs +76 -6
- package/dist/execution.mjs.map +1 -1
- package/dist/finding-remediation/admission.d.mts +2 -0
- package/dist/finding-remediation/admission.mjs +4 -1
- package/dist/finding-remediation/admission.mjs.map +1 -1
- package/dist/findings.d.mts +1 -0
- package/dist/github-publication.d.mts +1 -0
- package/dist/github-publication.mjs +97 -84
- package/dist/github-publication.mjs.map +1 -1
- package/dist/github-transfer.d.mts +15 -6
- package/dist/github-transfer.mjs +214 -66
- package/dist/github-transfer.mjs.map +1 -1
- package/dist/github.d.mts +51 -11
- package/dist/github.mjs +126 -24
- package/dist/github.mjs.map +1 -1
- package/dist/inbox-activity.d.mts +53 -0
- package/dist/inbox-activity.mjs +41 -0
- package/dist/inbox-activity.mjs.map +1 -0
- package/dist/index.d.mts +3 -1
- package/dist/index.mjs +3 -2
- package/dist/intake-contracts.d.mts +0 -1
- package/dist/integrations/deepsec.d.mts +1 -0
- package/dist/integrations/github.d.mts +2 -2
- package/dist/integrations/github.mjs +2 -2
- package/dist/integrations/slack.d.mts +3 -1
- package/dist/integrations/slack.mjs +3 -1
- package/dist/integrations/vercel.d.mts +4 -2
- package/dist/integrations/vercel.mjs +3 -2
- package/dist/merge-resolution/eve-tools.d.mts +1 -0
- package/dist/merge-resolution/eve-tools.mjs +7 -2
- package/dist/merge-resolution/eve-tools.mjs.map +1 -1
- package/dist/model-settings.d.mts +41 -0
- package/dist/model-settings.mjs +35 -0
- package/dist/model-settings.mjs.map +1 -0
- package/dist/planning/reconcile.mjs +6 -0
- package/dist/planning/reconcile.mjs.map +1 -1
- package/dist/postgres/index.d.mts +43 -2
- package/dist/postgres/index.mjs +40 -2
- package/dist/postgres/index.mjs.map +1 -1
- package/dist/presets/software-development/dispatch.d.mts +4 -1
- package/dist/presets/software-development/dispatch.mjs +2 -1
- package/dist/presets/software-development/dispatch.mjs.map +1 -1
- package/dist/presets/software-development/task-communication.d.mts +1 -0
- package/dist/presets/software-development/task-communication.mjs +48 -11
- package/dist/presets/software-development/task-communication.mjs.map +1 -1
- package/dist/presets/software-development.d.mts +1 -0
- package/dist/pull-requests/github-publisher.d.mts +15 -1
- package/dist/pull-requests/github-publisher.mjs +61 -1
- package/dist/pull-requests/github-publisher.mjs.map +1 -1
- package/dist/pull-requests.d.mts +1 -0
- package/dist/sandbox/index.d.mts +1 -0
- package/dist/schema/agent-route.d.mts +19 -1
- package/dist/schema/agent-route.mjs +19 -1
- package/dist/schema/agent-route.mjs.map +1 -1
- package/dist/schema/factory-config.d.mts +27 -0
- package/dist/schema/factory-config.mjs +33 -3
- package/dist/schema/factory-config.mjs.map +1 -1
- package/dist/schema/repository.d.mts +4 -0
- package/dist/schema/repository.mjs +5 -1
- package/dist/schema/repository.mjs.map +1 -1
- package/dist/schema/session.d.mts +1 -0
- package/dist/schema/session.mjs +1 -0
- package/dist/schema/session.mjs.map +1 -1
- package/dist/schema/slack-pr-notifications.d.mts +12 -0
- package/dist/schema/slack-pr-notifications.mjs +11 -0
- package/dist/schema/slack-pr-notifications.mjs.map +1 -0
- package/dist/schema/task-graph.d.mts +39 -0
- package/dist/schema/task.d.mts +1 -0
- package/dist/schema/task.mjs +2 -1
- package/dist/schema/task.mjs.map +1 -1
- package/dist/schema/transcript.d.mts +6 -0
- package/dist/schema/transcript.mjs +2 -1
- package/dist/schema/transcript.mjs.map +1 -1
- package/dist/schema/work.d.mts +52 -3
- package/dist/schema/work.mjs.map +1 -1
- package/dist/session-previews.d.mts +76 -0
- package/dist/session-previews.mjs +55 -0
- package/dist/session-previews.mjs.map +1 -0
- package/dist/session-review.d.mts +120 -0
- package/dist/session-review.mjs +79 -0
- package/dist/session-review.mjs.map +1 -0
- package/dist/signal-triage.mjs +1 -1
- package/dist/signals.d.mts +1 -0
- package/dist/stall.d.mts +4 -1
- package/dist/stall.mjs +6 -2
- package/dist/stall.mjs.map +1 -1
- package/dist/store/driver.d.mts +1 -1
- package/dist/store/driver.mjs.map +1 -1
- package/dist/store/engine.d.mts +206 -8
- package/dist/store/engine.mjs +147 -13
- package/dist/store/engine.mjs.map +1 -1
- package/dist/store/memory.d.mts +18 -1
- package/dist/store/memory.mjs +18 -1
- package/dist/store/memory.mjs.map +1 -1
- package/dist/store/slack-pr-notifications.d.mts +44 -0
- package/dist/store/slack-pr-notifications.mjs +121 -0
- package/dist/store/slack-pr-notifications.mjs.map +1 -0
- package/dist/store/task-work.d.mts +121 -6
- package/dist/store/task-work.mjs +7 -4
- package/dist/store/task-work.mjs.map +1 -1
- package/dist/sweep.d.mts +28 -6
- package/dist/sweep.mjs +34 -6
- package/dist/sweep.mjs.map +1 -1
- package/dist/task-graph-view.d.mts +3 -0
- package/dist/tasks.d.mts +3 -3
- package/dist/tasks.mjs +3 -3
- package/dist/vercel-git.d.mts +35 -3
- package/dist/vercel-git.mjs +265 -33
- package/dist/vercel-git.mjs.map +1 -1
- package/dist/vercel-github-api.d.mts +103 -0
- package/dist/vercel-github-api.mjs +363 -0
- package/dist/vercel-github-api.mjs.map +1 -0
- package/dist/vercel.d.mts +3 -2
- package/dist/vercel.mjs +3 -2
- package/dist/vercel.mjs.map +1 -1
- package/dist/work-triage.d.mts +1 -0
- package/dist/workflows.d.mts +102 -4
- package/dist/workflows.mjs +55 -2
- package/dist/workflows.mjs.map +1 -1
- package/dist/workspace-files-git.d.mts +15 -0
- package/dist/workspace-files-git.mjs +61 -0
- package/dist/workspace-files-git.mjs.map +1 -0
- package/dist/workspace-files.d.mts +107 -0
- package/dist/workspace-files.mjs +74 -0
- package/dist/workspace-files.mjs.map +1 -0
- package/docs/getting-started.md +104 -0
- package/docs/index.md +100 -0
- package/docs/recipes/cancellation.md +215 -0
- package/docs/recipes/custom-workflow.md +153 -0
- package/docs/recipes/dependent-tasks.md +207 -0
- package/docs/recipes/eve-agent.md +277 -0
- package/docs/recipes/human-input.md +204 -0
- package/docs/recipes/persistence-recovery.md +268 -0
- package/docs/recipes/retry-recovery.md +241 -0
- package/docs/recipes/task-messaging.md +215 -0
- package/docs/recipes/typed-eve-result.md +161 -0
- package/docs/runtime-integration.md +137 -0
- package/package.json +17 -6
package/dist/schema/task.mjs
CHANGED
|
@@ -82,6 +82,7 @@ const taskSchema = z.strictObject({
|
|
|
82
82
|
id: taskIdSchema,
|
|
83
83
|
repositoryIds: repositoryIdsSchema.describe("Repositories the task concerns."),
|
|
84
84
|
kind: taskKindSchema,
|
|
85
|
+
model: z.string().trim().min(1).max(200).optional().describe("Application-selected model pinned for this Task and retained across retries."),
|
|
85
86
|
area: z.string().min(1).optional().describe("Workflow-specific area, e.g. onboarding or security."),
|
|
86
87
|
state: taskStateSchema,
|
|
87
88
|
approval: taskApprovalSchema.optional(),
|
|
@@ -111,7 +112,7 @@ const taskSchema = z.strictObject({
|
|
|
111
112
|
questionTaskId: taskIdSchema.optional().describe("Open QuestionTask blocking this executable task, stored for direct answer routing."),
|
|
112
113
|
answerEventIds: z.array(answerIdSchema).readonly().optional().describe("Immutable answer events projected onto this task for direct replay."),
|
|
113
114
|
changeId: changeIdSchema.optional().describe("Change this executable task concerns or produces."),
|
|
114
|
-
reportRef: z.string().min(1).optional().describe("Reference to the report artifact
|
|
115
|
+
reportRef: z.string().min(1).optional().describe("Reference to the durable report artifact this Task produced."),
|
|
115
116
|
createdAt: isoDateTimeSchema,
|
|
116
117
|
updatedAt: isoDateTimeSchema
|
|
117
118
|
}).superRefine((task, ctx) => {
|
package/dist/schema/task.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task.mjs","names":[],"sources":["../../src/schema/task.ts"],"sourcesContent":["import { z } from \"zod\";\nimport {\n isoDateTimeSchema,\n replyToSchema,\n schemaVersionSchema,\n usdSchema,\n vocabularySchema,\n} from \"./common\";\nimport {\n answerIdSchema,\n changeIdSchema,\n receiptIdSchema,\n repositoryIdSchema,\n repositoryIdsSchema,\n signalIdSchema,\n taskIdSchema,\n} from \"./id\";\nimport { taskWorkResultSchema, taskWorkSchema, workflowBindingSchema } from \"./work\";\n\n/** Descriptive labels used by the reference workflows, not core lifecycle rules. */\nexport const standardTaskKinds = [\n \"coordination\",\n \"code_change\",\n \"verification\",\n \"investigation\",\n \"question\",\n] as const;\n\n/** Standard Task kinds with support for caller-defined vocabulary values. */\nexport type TaskKind = (typeof standardTaskKinds)[number] | (string & Record<never, never>);\n\n/** Validates the descriptive, open-vocabulary label attached to a Task. */\nexport const taskKindSchema = vocabularySchema.describe(\n \"What kind of work this is, e.g. code_change, question, or a registered custom kind.\",\n) as z.ZodType<TaskKind>;\n\n/** Validates the fixed lifecycle state of a Task. */\nexport const taskStateSchema = z\n .enum([\n \"queued\",\n \"running\",\n \"stalled\",\n \"verifying\",\n \"succeeded\",\n \"failed\",\n \"needs_human\",\n \"cancelled\",\n ])\n .describe(\"Lifecycle state. Transitions are fixed; see taskTransitions.\");\n\n/** Validates whether a Task requires, received, or was denied human approval. */\nexport const taskApprovalSchema = z\n .enum([\"required\", \"granted\", \"denied\"])\n .describe(\n \"Human approval status. Absent means no approval is needed. Stamped required at creation by policy; granted or denied by an operator.\",\n );\n\n/** Validates the single-repository scope required by supplied execution adapters. */\nexport const taskExecutionRepositoryIdsSchema = z\n .tuple([repositoryIdSchema])\n .readonly()\n .describe(\"The one repository used to execute a task.\");\n\n/** Validates Task provenance independently from graph parentage. */\nexport const taskOriginSchema = z\n .strictObject({\n signalId: signalIdSchema.optional().describe(\"Signal that led to this task.\"),\n operator: z.string().min(1).optional().describe(\"Human operator who requested it.\"),\n })\n .describe(\"Task provenance; an empty child creation origin inherits its parent's provenance.\");\n\n/** Validates the configured coding-harness identifier retained with an execution. */\nexport const harnessSchema = z\n .string()\n .min(1)\n .describe(\"Coding harness running inside the execution environment, e.g. claude-code or codex.\");\n\n/**\n * The provider's handle on the current attempt's execution. Opaque to the\n * lifecycle: Factory records it so the execution can be inspected or\n * cancelled, never to mirror the provider's own state machine.\n */\nexport const executionReferenceSchema = z.strictObject({\n provider: z.string().min(1).describe(\"Execution provider, e.g. eve.\"),\n sessionId: z.string().min(1).describe(\"Provider-side session running this attempt.\"),\n environmentId: z.string().min(1).optional().describe(\"Provider-side execution environment.\"),\n harness: harnessSchema.optional(),\n traceId: z.string().min(1).optional().describe(\"Provider-side trace for this execution.\"),\n});\n\nconst tokenCountSchema = z.number().int().nonnegative();\n\n/** Validates Task-local measured usage and per-turn step deduplication state. */\nexport const taskUsageSchema = z.strictObject({\n costUsd: usdSchema.describe(\"AI Gateway cost summed over recorded steps.\"),\n inputTokens: tokenCountSchema,\n outputTokens: tokenCountSchema,\n cacheReadTokens: tokenCountSchema,\n cacheWriteTokens: tokenCountSchema,\n steps: z\n .record(z.string().min(1), tokenCountSchema)\n .describe(\"Highest recorded stepIndex per turnId; steps at or below it are already counted.\"),\n});\n\n/** Validates a human question, suggested replies, and any authenticated answer. */\nexport const taskQuestionSchema = z.strictObject({\n text: z\n .string()\n .min(1)\n .describe(\"The input or action requested from a human before work can resume.\"),\n options: z\n .array(z.string().min(1))\n .readonly()\n .describe(\"Suggested replies; free-text is also allowed.\"),\n /**\n * Options (matched case-insensitively, trimmed) whose exact answer means\n * \"this task no longer needs a fresh attempt\": the asker judged that no\n * amount of retrying can succeed once this reply is chosen. Answering with\n * one of these resolves the parent task instead of requeuing it. Answers\n * outside this set keep the existing retry behavior.\n */\n closingOptions: z\n .array(z.string().min(1))\n .max(20)\n .readonly()\n .optional()\n .describe(\n \"Subset of options whose exact answer resolves the task instead of requeuing a fresh attempt.\",\n ),\n answer: z.string().min(1).optional(),\n answeredBy: z.string().min(1).optional().describe(\"Authenticated operator who answered.\"),\n});\n\n/** Validates the canonical durable snapshot of one unit of workflow work. */\nconst taskRecordSchema = z\n .strictObject({\n schemaVersion: schemaVersionSchema,\n id: taskIdSchema,\n repositoryIds: repositoryIdsSchema.describe(\"Repositories the task concerns.\"),\n kind: taskKindSchema,\n area: z\n .string()\n .min(1)\n .optional()\n .describe(\"Workflow-specific area, e.g. onboarding or security.\"),\n state: taskStateSchema,\n approval: taskApprovalSchema.optional(),\n origin: taskOriginSchema,\n work: taskWorkSchema.describe(\"Required versioned workflow contract for this Task.\"),\n workResult: taskWorkResultSchema.optional().describe(\"Validated canonical workflow result.\"),\n waitingForMessages: z\n .boolean()\n .optional()\n .describe(\"Whether work is waiting for messages; true only while running.\"),\n workflowPhase: workflowBindingSchema.shape.id\n .optional()\n .describe(\"Workflow-owned lowercase hyphenated or snake_case phase, at most 64 characters.\"),\n rootTaskId: taskIdSchema.describe(\"Root of the task graph; equal to id for a root task.\"),\n parentTaskId: taskIdSchema\n .optional()\n .describe(\"Single owning parent task; cannot reference the task itself.\"),\n parentTaskAttempt: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\n \"Parent execution attempt that raised this question; a new parent attempt requires a new question.\",\n ),\n replyTo: replyToSchema,\n pendingCommunicationReceiptIds: z\n .array(receiptIdSchema)\n .readonly()\n .optional()\n .describe(\n \"Transition receipts that still need to be projected into the communication outbox.\",\n ),\n failureReceiptId: receiptIdSchema\n .optional()\n .describe(\n \"Committed failure receipt for the current failed attempt; independent of delivery bookkeeping.\",\n ),\n attempt: z.number().int().min(1).describe(\"Execution attempt, starting at 1; bumps on retry.\"),\n execution: executionReferenceSchema\n .optional()\n .describe(\"Execution of the current attempt, recorded at dispatch and replaced on retry.\"),\n lastProgressAt: isoDateTimeSchema\n .optional()\n .describe(\n \"Last time the execution demonstrably advanced: dispatch, or a completed model step.\",\n ),\n stalledAt: isoDateTimeSchema\n .optional()\n .describe(\"When the reconciler marked the task stalled.\"),\n stalledReason: z.string().min(1).optional().describe(\"Why the task was marked stalled.\"),\n needsHumanAction: z\n .string()\n .min(1)\n .optional()\n .describe(\n \"Actionable, human-facing description of what a human must do before this task can proceed. Required exactly while state is needs_human; every needs_human transition must carry one.\",\n ),\n needsHumanNotifiedAt: isoDateTimeSchema\n .optional()\n .describe(\n \"When Slack confirmed delivery of the needs_human notification for the current needs_human episode. Absent while delivery is still retrying.\",\n ),\n reservedUsd: usdSchema.optional().describe(\"Budget reserved before dispatch.\"),\n reservedAt: isoDateTimeSchema\n .optional()\n .describe(\"When the reservation was stamped; attributes spend to a budget month.\"),\n usage: taskUsageSchema\n .optional()\n .describe(\n \"Measured model usage, accumulated per step by recordUsage and settled into settledUsd.\",\n ),\n settledUsd: usdSchema\n .optional()\n .describe(\n \"Measured cost settled after execution. A task settles once and cannot be retried after settlement.\",\n ),\n question: taskQuestionSchema.optional(),\n questionTaskId: taskIdSchema\n .optional()\n .describe(\n \"Open QuestionTask blocking this executable task, stored for direct answer routing.\",\n ),\n answerEventIds: z\n .array(answerIdSchema)\n .readonly()\n .optional()\n .describe(\"Immutable answer events projected onto this task for direct replay.\"),\n changeId: changeIdSchema\n .optional()\n .describe(\"Change this executable task concerns or produces.\"),\n reportRef: z\n .string()\n .min(1)\n .optional()\n .describe(\"Reference to the report artifact an investigation produced.\"),\n createdAt: isoDateTimeSchema,\n updatedAt: isoDateTimeSchema,\n })\n .superRefine((task, ctx) => {\n if (task.failureReceiptId !== undefined && task.state !== \"failed\") {\n ctx.addIssue({\n code: \"custom\",\n path: [\"failureReceiptId\"],\n message: \"failureReceiptId is only valid while the task is failed\",\n });\n }\n if (\n task.state !== \"stalled\" &&\n (task.stalledAt !== undefined || task.stalledReason !== undefined)\n ) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"stalledAt\"],\n message: \"stalledAt and stalledReason are only valid while the task is stalled\",\n });\n }\n if (\n task.state === \"needs_human\" &&\n (task.needsHumanAction === undefined || task.needsHumanAction.trim() === \"\")\n ) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"needsHumanAction\"],\n message: \"needs_human requires a populated, actionable needsHumanAction for a human reader\",\n });\n }\n if (\n task.state !== \"needs_human\" &&\n (task.needsHumanAction !== undefined || task.needsHumanNotifiedAt !== undefined)\n ) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"needsHumanAction\"],\n message:\n \"needsHumanAction and needsHumanNotifiedAt are only valid while the task is needs_human\",\n });\n }\n if (\n task.state === \"needs_human\" &&\n ((task.question === undefined && task.questionTaskId === undefined) ||\n (task.question !== undefined &&\n (task.question.answer !== undefined || task.question.answeredBy !== undefined)))\n ) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"question\"],\n message: \"needs_human requires an unanswered question or a linked open QuestionTask\",\n });\n }\n if (task.question !== undefined && task.questionTaskId !== undefined) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"questionTaskId\"],\n message: \"A task cannot both ask a question and be blocked by another question\",\n });\n }\n if (\n task.parentTaskAttempt !== undefined &&\n (task.parentTaskId === undefined || task.question === undefined)\n ) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"parentTaskAttempt\"],\n message: \"parentTaskAttempt binds a child question to its parent's execution attempt\",\n });\n }\n if (task.parentTaskId === task.id) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"parentTaskId\"],\n message: \"parentTaskId cannot reference the task itself\",\n });\n }\n if (task.parentTaskId === undefined && task.rootTaskId !== task.id) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"rootTaskId\"],\n message: \"Root tasks must use their own id as rootTaskId\",\n });\n }\n if (task.parentTaskId !== undefined && task.rootTaskId === task.id) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"rootTaskId\"],\n message: \"Child tasks cannot use their own id as rootTaskId\",\n });\n }\n if (\n task.parentTaskId === undefined &&\n task.origin.signalId === undefined &&\n task.origin.operator === undefined\n ) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"origin\"],\n message: \"Root task origin requires a signalId or operator\",\n });\n }\n if (task.waitingForMessages === true && task.state !== \"running\") {\n ctx.addIssue({\n code: \"custom\",\n path: [\"waitingForMessages\"],\n message: \"waitingForMessages can only be true while work is running\",\n });\n }\n if (task.state === \"succeeded\" && task.workResult === undefined) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"workResult\"],\n message: \"Succeeded tasks require a validated workflow result\",\n });\n }\n });\n\ntype TaskRecord = z.infer<typeof taskRecordSchema>;\ntype SchemaWithOutput<Schema extends z.ZodType, Output> = Omit<Schema, keyof z.ZodType> &\n z.ZodType<Output, z.input<Schema>>;\ntype TaskStateField =\n | \"state\"\n | \"workResult\"\n | \"waitingForMessages\"\n | \"failureReceiptId\"\n | \"stalledAt\"\n | \"stalledReason\"\n | \"needsHumanAction\"\n | \"needsHumanNotifiedAt\";\ntype TaskQuestionField = \"question\" | \"questionTaskId\" | \"parentTaskAttempt\" | \"parentTaskId\";\ntype TaskCommon = Omit<TaskRecord, TaskStateField | TaskQuestionField>;\ntype TaskIdValue = NonNullable<TaskRecord[\"parentTaskId\"]>;\ntype TaskWorkResult = NonNullable<TaskRecord[\"workResult\"]>;\n\ntype TaskWithoutQuestion = {\n question?: never;\n questionTaskId?: never;\n parentTaskAttempt?: never;\n parentTaskId?: TaskIdValue;\n};\n\ntype TaskWithQuestion<Question extends TaskRecord[\"question\"]> =\n | {\n question: Question;\n questionTaskId?: never;\n parentTaskAttempt?: never;\n parentTaskId?: TaskIdValue;\n }\n | {\n question: Question;\n questionTaskId?: never;\n parentTaskAttempt: number;\n parentTaskId: TaskIdValue;\n };\n\ntype TaskWithLinkedQuestion = {\n question?: never;\n questionTaskId: TaskIdValue;\n parentTaskAttempt?: never;\n parentTaskId?: TaskIdValue;\n};\n\ntype TaskQuestionContext =\n | TaskWithoutQuestion\n | TaskWithQuestion<NonNullable<TaskRecord[\"question\"]>>\n | TaskWithLinkedQuestion;\n\ntype UnansweredTaskQuestion = Omit<NonNullable<TaskRecord[\"question\"]>, \"answer\" | \"answeredBy\"> & {\n answer?: never;\n answeredBy?: never;\n};\n\ntype InactiveStateFields = {\n waitingForMessages?: false;\n needsHumanAction?: never;\n needsHumanNotifiedAt?: never;\n};\n\ntype UnstalledStateFields = {\n stalledAt?: never;\n stalledReason?: never;\n};\n\ntype NonFailedStateFields = {\n failureReceiptId?: never;\n};\n\ntype InactiveOrdinaryTaskState<State extends \"queued\" | \"verifying\" | \"cancelled\"> =\n InactiveStateFields &\n UnstalledStateFields &\n NonFailedStateFields & {\n state: State;\n workResult?: TaskWorkResult;\n };\n\ntype OrdinaryTaskState =\n | InactiveOrdinaryTaskState<\"queued\">\n | InactiveOrdinaryTaskState<\"verifying\">\n | InactiveOrdinaryTaskState<\"cancelled\">\n | (UnstalledStateFields &\n NonFailedStateFields & {\n state: \"running\";\n waitingForMessages?: boolean;\n needsHumanAction?: never;\n needsHumanNotifiedAt?: never;\n workResult?: TaskWorkResult;\n })\n | (InactiveStateFields &\n NonFailedStateFields & {\n state: \"stalled\";\n stalledAt?: string;\n stalledReason?: string;\n workResult?: TaskWorkResult;\n })\n | (InactiveStateFields &\n UnstalledStateFields & {\n state: \"failed\";\n failureReceiptId?: NonNullable<TaskRecord[\"failureReceiptId\"]>;\n workResult?: TaskWorkResult;\n })\n | (InactiveStateFields &\n UnstalledStateFields &\n NonFailedStateFields & {\n state: \"succeeded\";\n workResult: TaskWorkResult;\n });\n\ntype NeedsHumanTaskState = UnstalledStateFields &\n NonFailedStateFields & {\n state: \"needs_human\";\n waitingForMessages?: false;\n needsHumanAction: string;\n needsHumanNotifiedAt?: string;\n workResult?: TaskWorkResult;\n };\n\n/** Canonical durable snapshot of one explicitly versioned unit of workflow work. */\nexport type Task = TaskCommon &\n (\n | (OrdinaryTaskState & TaskQuestionContext)\n | (NeedsHumanTaskState & (TaskWithQuestion<UnansweredTaskQuestion> | TaskWithLinkedQuestion))\n );\n\n/** Validates the canonical durable snapshot of one unit of workflow work. */\nexport const taskSchema = taskRecordSchema as SchemaWithOutput<typeof taskRecordSchema, Task>;\n\n/** Human approval status recorded on a Task when policy requires a decision. */\nexport type TaskApproval = z.infer<typeof taskApprovalSchema>;\n/** Signal or operator provenance retained independently from Task graph parentage. */\nexport type TaskOrigin = z.infer<typeof taskOriginSchema>;\n/** Human question, suggested replies, and optional authenticated answer. */\nexport type TaskQuestion = z.infer<typeof taskQuestionSchema>;\n/** Fixed lifecycle state controlled through the canonical Task transition table. */\nexport type TaskState = z.infer<typeof taskStateSchema>;\n/** Task-local measured model usage with idempotent per-step accounting. */\nexport type TaskUsage = z.infer<typeof taskUsageSchema>;\n/** Opaque provider-owned execution handle for the current Task attempt. */\nexport type ExecutionReference = z.infer<typeof executionReferenceSchema>;\n/** Succeeded Task narrowed to its required validated workflow result. */\nexport type SucceededTask = Extract<Task, { state: \"succeeded\" }>;\n/** Human-blocked Task narrowed to its required actionable description. */\nexport type NeedsHumanTask = Extract<Task, { state: \"needs_human\" }>;\n/** Running Task narrowed to its explicit message-waiting marker. */\nexport type MessageWaitingTask = Extract<Task, { state: \"running\" }> & {\n waitingForMessages: true;\n};\n\n/** Narrows a validated Task after checking its succeeded-state invariant. */\nexport function isSucceededTask(task: Task): task is SucceededTask {\n return task.state === \"succeeded\" && task.workResult !== undefined;\n}\n\n/** Narrows a validated Task after checking its human-action invariant. */\nexport function isNeedsHumanTask(task: Task): task is NeedsHumanTask {\n return task.state === \"needs_human\" && task.needsHumanAction !== undefined;\n}\n\n/** Narrows a validated Task to running work deliberately waiting for messages. */\nexport function isMessageWaitingTask(task: Task): task is MessageWaitingTask {\n return task.state === \"running\" && task.waitingForMessages === true;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"task.mjs","names":[],"sources":["../../src/schema/task.ts"],"sourcesContent":["import { z } from \"zod\";\nimport {\n isoDateTimeSchema,\n replyToSchema,\n schemaVersionSchema,\n usdSchema,\n vocabularySchema,\n} from \"./common\";\nimport {\n answerIdSchema,\n changeIdSchema,\n receiptIdSchema,\n repositoryIdSchema,\n repositoryIdsSchema,\n signalIdSchema,\n taskIdSchema,\n} from \"./id\";\nimport { taskWorkResultSchema, taskWorkSchema, workflowBindingSchema } from \"./work\";\n\n/** Descriptive labels used by the reference workflows, not core lifecycle rules. */\nexport const standardTaskKinds = [\n \"coordination\",\n \"code_change\",\n \"verification\",\n \"investigation\",\n \"question\",\n] as const;\n\n/** Standard Task kinds with support for caller-defined vocabulary values. */\nexport type TaskKind = (typeof standardTaskKinds)[number] | (string & Record<never, never>);\n\n/** Validates the descriptive, open-vocabulary label attached to a Task. */\nexport const taskKindSchema = vocabularySchema.describe(\n \"What kind of work this is, e.g. code_change, question, or a registered custom kind.\",\n) as z.ZodType<TaskKind>;\n\n/** Validates the fixed lifecycle state of a Task. */\nexport const taskStateSchema = z\n .enum([\n \"queued\",\n \"running\",\n \"stalled\",\n \"verifying\",\n \"succeeded\",\n \"failed\",\n \"needs_human\",\n \"cancelled\",\n ])\n .describe(\"Lifecycle state. Transitions are fixed; see taskTransitions.\");\n\n/** Validates whether a Task requires, received, or was denied human approval. */\nexport const taskApprovalSchema = z\n .enum([\"required\", \"granted\", \"denied\"])\n .describe(\n \"Human approval status. Absent means no approval is needed. Stamped required at creation by policy; granted or denied by an operator.\",\n );\n\n/** Validates the single-repository scope required by supplied execution adapters. */\nexport const taskExecutionRepositoryIdsSchema = z\n .tuple([repositoryIdSchema])\n .readonly()\n .describe(\"The one repository used to execute a task.\");\n\n/** Validates Task provenance independently from graph parentage. */\nexport const taskOriginSchema = z\n .strictObject({\n signalId: signalIdSchema.optional().describe(\"Signal that led to this task.\"),\n operator: z.string().min(1).optional().describe(\"Human operator who requested it.\"),\n })\n .describe(\"Task provenance; an empty child creation origin inherits its parent's provenance.\");\n\n/** Validates the configured coding-harness identifier retained with an execution. */\nexport const harnessSchema = z\n .string()\n .min(1)\n .describe(\"Coding harness running inside the execution environment, e.g. claude-code or codex.\");\n\n/**\n * The provider's handle on the current attempt's execution. Opaque to the\n * lifecycle: Factory records it so the execution can be inspected or\n * cancelled, never to mirror the provider's own state machine.\n */\nexport const executionReferenceSchema = z.strictObject({\n provider: z.string().min(1).describe(\"Execution provider, e.g. eve.\"),\n sessionId: z.string().min(1).describe(\"Provider-side session running this attempt.\"),\n environmentId: z.string().min(1).optional().describe(\"Provider-side execution environment.\"),\n harness: harnessSchema.optional(),\n traceId: z.string().min(1).optional().describe(\"Provider-side trace for this execution.\"),\n});\n\nconst tokenCountSchema = z.number().int().nonnegative();\n\n/** Validates Task-local measured usage and per-turn step deduplication state. */\nexport const taskUsageSchema = z.strictObject({\n costUsd: usdSchema.describe(\"AI Gateway cost summed over recorded steps.\"),\n inputTokens: tokenCountSchema,\n outputTokens: tokenCountSchema,\n cacheReadTokens: tokenCountSchema,\n cacheWriteTokens: tokenCountSchema,\n steps: z\n .record(z.string().min(1), tokenCountSchema)\n .describe(\"Highest recorded stepIndex per turnId; steps at or below it are already counted.\"),\n});\n\n/** Validates a human question, suggested replies, and any authenticated answer. */\nexport const taskQuestionSchema = z.strictObject({\n text: z\n .string()\n .min(1)\n .describe(\"The input or action requested from a human before work can resume.\"),\n options: z\n .array(z.string().min(1))\n .readonly()\n .describe(\"Suggested replies; free-text is also allowed.\"),\n /**\n * Options (matched case-insensitively, trimmed) whose exact answer means\n * \"this task no longer needs a fresh attempt\": the asker judged that no\n * amount of retrying can succeed once this reply is chosen. Answering with\n * one of these resolves the parent task instead of requeuing it. Answers\n * outside this set keep the existing retry behavior.\n */\n closingOptions: z\n .array(z.string().min(1))\n .max(20)\n .readonly()\n .optional()\n .describe(\n \"Subset of options whose exact answer resolves the task instead of requeuing a fresh attempt.\",\n ),\n answer: z.string().min(1).optional(),\n answeredBy: z.string().min(1).optional().describe(\"Authenticated operator who answered.\"),\n});\n\n/** Validates the canonical durable snapshot of one unit of workflow work. */\nconst taskRecordSchema = z\n .strictObject({\n schemaVersion: schemaVersionSchema,\n id: taskIdSchema,\n repositoryIds: repositoryIdsSchema.describe(\"Repositories the task concerns.\"),\n kind: taskKindSchema,\n model: z\n .string()\n .trim()\n .min(1)\n .max(200)\n .optional()\n .describe(\"Application-selected model pinned for this Task and retained across retries.\"),\n area: z\n .string()\n .min(1)\n .optional()\n .describe(\"Workflow-specific area, e.g. onboarding or security.\"),\n state: taskStateSchema,\n approval: taskApprovalSchema.optional(),\n origin: taskOriginSchema,\n work: taskWorkSchema.describe(\"Required versioned workflow contract for this Task.\"),\n workResult: taskWorkResultSchema.optional().describe(\"Validated canonical workflow result.\"),\n waitingForMessages: z\n .boolean()\n .optional()\n .describe(\"Whether work is waiting for messages; true only while running.\"),\n workflowPhase: workflowBindingSchema.shape.id\n .optional()\n .describe(\"Workflow-owned lowercase hyphenated or snake_case phase, at most 64 characters.\"),\n rootTaskId: taskIdSchema.describe(\"Root of the task graph; equal to id for a root task.\"),\n parentTaskId: taskIdSchema\n .optional()\n .describe(\"Single owning parent task; cannot reference the task itself.\"),\n parentTaskAttempt: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\n \"Parent execution attempt that raised this question; a new parent attempt requires a new question.\",\n ),\n replyTo: replyToSchema,\n pendingCommunicationReceiptIds: z\n .array(receiptIdSchema)\n .readonly()\n .optional()\n .describe(\n \"Transition receipts that still need to be projected into the communication outbox.\",\n ),\n failureReceiptId: receiptIdSchema\n .optional()\n .describe(\n \"Committed failure receipt for the current failed attempt; independent of delivery bookkeeping.\",\n ),\n attempt: z.number().int().min(1).describe(\"Execution attempt, starting at 1; bumps on retry.\"),\n execution: executionReferenceSchema\n .optional()\n .describe(\"Execution of the current attempt, recorded at dispatch and replaced on retry.\"),\n lastProgressAt: isoDateTimeSchema\n .optional()\n .describe(\n \"Last time the execution demonstrably advanced: dispatch, or a completed model step.\",\n ),\n stalledAt: isoDateTimeSchema\n .optional()\n .describe(\"When the reconciler marked the task stalled.\"),\n stalledReason: z.string().min(1).optional().describe(\"Why the task was marked stalled.\"),\n needsHumanAction: z\n .string()\n .min(1)\n .optional()\n .describe(\n \"Actionable, human-facing description of what a human must do before this task can proceed. Required exactly while state is needs_human; every needs_human transition must carry one.\",\n ),\n needsHumanNotifiedAt: isoDateTimeSchema\n .optional()\n .describe(\n \"When Slack confirmed delivery of the needs_human notification for the current needs_human episode. Absent while delivery is still retrying.\",\n ),\n reservedUsd: usdSchema.optional().describe(\"Budget reserved before dispatch.\"),\n reservedAt: isoDateTimeSchema\n .optional()\n .describe(\"When the reservation was stamped; attributes spend to a budget month.\"),\n usage: taskUsageSchema\n .optional()\n .describe(\n \"Measured model usage, accumulated per step by recordUsage and settled into settledUsd.\",\n ),\n settledUsd: usdSchema\n .optional()\n .describe(\n \"Measured cost settled after execution. A task settles once and cannot be retried after settlement.\",\n ),\n question: taskQuestionSchema.optional(),\n questionTaskId: taskIdSchema\n .optional()\n .describe(\n \"Open QuestionTask blocking this executable task, stored for direct answer routing.\",\n ),\n answerEventIds: z\n .array(answerIdSchema)\n .readonly()\n .optional()\n .describe(\"Immutable answer events projected onto this task for direct replay.\"),\n changeId: changeIdSchema\n .optional()\n .describe(\"Change this executable task concerns or produces.\"),\n reportRef: z\n .string()\n .min(1)\n .optional()\n .describe(\"Reference to the durable report artifact this Task produced.\"),\n createdAt: isoDateTimeSchema,\n updatedAt: isoDateTimeSchema,\n })\n .superRefine((task, ctx) => {\n if (task.failureReceiptId !== undefined && task.state !== \"failed\") {\n ctx.addIssue({\n code: \"custom\",\n path: [\"failureReceiptId\"],\n message: \"failureReceiptId is only valid while the task is failed\",\n });\n }\n if (\n task.state !== \"stalled\" &&\n (task.stalledAt !== undefined || task.stalledReason !== undefined)\n ) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"stalledAt\"],\n message: \"stalledAt and stalledReason are only valid while the task is stalled\",\n });\n }\n if (\n task.state === \"needs_human\" &&\n (task.needsHumanAction === undefined || task.needsHumanAction.trim() === \"\")\n ) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"needsHumanAction\"],\n message: \"needs_human requires a populated, actionable needsHumanAction for a human reader\",\n });\n }\n if (\n task.state !== \"needs_human\" &&\n (task.needsHumanAction !== undefined || task.needsHumanNotifiedAt !== undefined)\n ) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"needsHumanAction\"],\n message:\n \"needsHumanAction and needsHumanNotifiedAt are only valid while the task is needs_human\",\n });\n }\n if (\n task.state === \"needs_human\" &&\n ((task.question === undefined && task.questionTaskId === undefined) ||\n (task.question !== undefined &&\n (task.question.answer !== undefined || task.question.answeredBy !== undefined)))\n ) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"question\"],\n message: \"needs_human requires an unanswered question or a linked open QuestionTask\",\n });\n }\n if (task.question !== undefined && task.questionTaskId !== undefined) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"questionTaskId\"],\n message: \"A task cannot both ask a question and be blocked by another question\",\n });\n }\n if (\n task.parentTaskAttempt !== undefined &&\n (task.parentTaskId === undefined || task.question === undefined)\n ) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"parentTaskAttempt\"],\n message: \"parentTaskAttempt binds a child question to its parent's execution attempt\",\n });\n }\n if (task.parentTaskId === task.id) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"parentTaskId\"],\n message: \"parentTaskId cannot reference the task itself\",\n });\n }\n if (task.parentTaskId === undefined && task.rootTaskId !== task.id) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"rootTaskId\"],\n message: \"Root tasks must use their own id as rootTaskId\",\n });\n }\n if (task.parentTaskId !== undefined && task.rootTaskId === task.id) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"rootTaskId\"],\n message: \"Child tasks cannot use their own id as rootTaskId\",\n });\n }\n if (\n task.parentTaskId === undefined &&\n task.origin.signalId === undefined &&\n task.origin.operator === undefined\n ) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"origin\"],\n message: \"Root task origin requires a signalId or operator\",\n });\n }\n if (task.waitingForMessages === true && task.state !== \"running\") {\n ctx.addIssue({\n code: \"custom\",\n path: [\"waitingForMessages\"],\n message: \"waitingForMessages can only be true while work is running\",\n });\n }\n if (task.state === \"succeeded\" && task.workResult === undefined) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"workResult\"],\n message: \"Succeeded tasks require a validated workflow result\",\n });\n }\n });\n\ntype TaskRecord = z.infer<typeof taskRecordSchema>;\ntype SchemaWithOutput<Schema extends z.ZodType, Output> = Omit<Schema, keyof z.ZodType> &\n z.ZodType<Output, z.input<Schema>>;\ntype TaskStateField =\n | \"state\"\n | \"workResult\"\n | \"waitingForMessages\"\n | \"failureReceiptId\"\n | \"stalledAt\"\n | \"stalledReason\"\n | \"needsHumanAction\"\n | \"needsHumanNotifiedAt\";\ntype TaskQuestionField = \"question\" | \"questionTaskId\" | \"parentTaskAttempt\" | \"parentTaskId\";\ntype TaskCommon = Omit<TaskRecord, TaskStateField | TaskQuestionField>;\ntype TaskIdValue = NonNullable<TaskRecord[\"parentTaskId\"]>;\ntype TaskWorkResult = NonNullable<TaskRecord[\"workResult\"]>;\n\ntype TaskWithoutQuestion = {\n question?: never;\n questionTaskId?: never;\n parentTaskAttempt?: never;\n parentTaskId?: TaskIdValue;\n};\n\ntype TaskWithQuestion<Question extends TaskRecord[\"question\"]> =\n | {\n question: Question;\n questionTaskId?: never;\n parentTaskAttempt?: never;\n parentTaskId?: TaskIdValue;\n }\n | {\n question: Question;\n questionTaskId?: never;\n parentTaskAttempt: number;\n parentTaskId: TaskIdValue;\n };\n\ntype TaskWithLinkedQuestion = {\n question?: never;\n questionTaskId: TaskIdValue;\n parentTaskAttempt?: never;\n parentTaskId?: TaskIdValue;\n};\n\ntype TaskQuestionContext =\n | TaskWithoutQuestion\n | TaskWithQuestion<NonNullable<TaskRecord[\"question\"]>>\n | TaskWithLinkedQuestion;\n\ntype UnansweredTaskQuestion = Omit<NonNullable<TaskRecord[\"question\"]>, \"answer\" | \"answeredBy\"> & {\n answer?: never;\n answeredBy?: never;\n};\n\ntype InactiveStateFields = {\n waitingForMessages?: false;\n needsHumanAction?: never;\n needsHumanNotifiedAt?: never;\n};\n\ntype UnstalledStateFields = {\n stalledAt?: never;\n stalledReason?: never;\n};\n\ntype NonFailedStateFields = {\n failureReceiptId?: never;\n};\n\ntype InactiveOrdinaryTaskState<State extends \"queued\" | \"verifying\" | \"cancelled\"> =\n InactiveStateFields &\n UnstalledStateFields &\n NonFailedStateFields & {\n state: State;\n workResult?: TaskWorkResult;\n };\n\ntype OrdinaryTaskState =\n | InactiveOrdinaryTaskState<\"queued\">\n | InactiveOrdinaryTaskState<\"verifying\">\n | InactiveOrdinaryTaskState<\"cancelled\">\n | (UnstalledStateFields &\n NonFailedStateFields & {\n state: \"running\";\n waitingForMessages?: boolean;\n needsHumanAction?: never;\n needsHumanNotifiedAt?: never;\n workResult?: TaskWorkResult;\n })\n | (InactiveStateFields &\n NonFailedStateFields & {\n state: \"stalled\";\n stalledAt?: string;\n stalledReason?: string;\n workResult?: TaskWorkResult;\n })\n | (InactiveStateFields &\n UnstalledStateFields & {\n state: \"failed\";\n failureReceiptId?: NonNullable<TaskRecord[\"failureReceiptId\"]>;\n workResult?: TaskWorkResult;\n })\n | (InactiveStateFields &\n UnstalledStateFields &\n NonFailedStateFields & {\n state: \"succeeded\";\n workResult: TaskWorkResult;\n });\n\ntype NeedsHumanTaskState = UnstalledStateFields &\n NonFailedStateFields & {\n state: \"needs_human\";\n waitingForMessages?: false;\n needsHumanAction: string;\n needsHumanNotifiedAt?: string;\n workResult?: TaskWorkResult;\n };\n\n/** Canonical durable snapshot of one explicitly versioned unit of workflow work. */\nexport type Task = TaskCommon &\n (\n | (OrdinaryTaskState & TaskQuestionContext)\n | (NeedsHumanTaskState & (TaskWithQuestion<UnansweredTaskQuestion> | TaskWithLinkedQuestion))\n );\n\n/** Validates the canonical durable snapshot of one unit of workflow work. */\nexport const taskSchema = taskRecordSchema as SchemaWithOutput<typeof taskRecordSchema, Task>;\n\n/** Human approval status recorded on a Task when policy requires a decision. */\nexport type TaskApproval = z.infer<typeof taskApprovalSchema>;\n/** Signal or operator provenance retained independently from Task graph parentage. */\nexport type TaskOrigin = z.infer<typeof taskOriginSchema>;\n/** Human question, suggested replies, and optional authenticated answer. */\nexport type TaskQuestion = z.infer<typeof taskQuestionSchema>;\n/** Fixed lifecycle state controlled through the canonical Task transition table. */\nexport type TaskState = z.infer<typeof taskStateSchema>;\n/** Task-local measured model usage with idempotent per-step accounting. */\nexport type TaskUsage = z.infer<typeof taskUsageSchema>;\n/** Opaque provider-owned execution handle for the current Task attempt. */\nexport type ExecutionReference = z.infer<typeof executionReferenceSchema>;\n/** Succeeded Task narrowed to its required validated workflow result. */\nexport type SucceededTask = Extract<Task, { state: \"succeeded\" }>;\n/** Human-blocked Task narrowed to its required actionable description. */\nexport type NeedsHumanTask = Extract<Task, { state: \"needs_human\" }>;\n/** Running Task narrowed to its explicit message-waiting marker. */\nexport type MessageWaitingTask = Extract<Task, { state: \"running\" }> & {\n waitingForMessages: true;\n};\n\n/** Narrows a validated Task after checking its succeeded-state invariant. */\nexport function isSucceededTask(task: Task): task is SucceededTask {\n return task.state === \"succeeded\" && task.workResult !== undefined;\n}\n\n/** Narrows a validated Task after checking its human-action invariant. */\nexport function isNeedsHumanTask(task: Task): task is NeedsHumanTask {\n return task.state === \"needs_human\" && task.needsHumanAction !== undefined;\n}\n\n/** Narrows a validated Task to running work deliberately waiting for messages. */\nexport function isMessageWaitingTask(task: Task): task is MessageWaitingTask {\n return task.state === \"running\" && task.waitingForMessages === true;\n}\n"],"mappings":";;;;;;AAoBA,MAAa,oBAAoB;CAC/B;CACA;CACA;CACA;CACA;AACF;;AAMA,MAAa,iBAAiB,iBAAiB,SAC7C,qFACF;;AAGA,MAAa,kBAAkB,EAC5B,KAAK;CACJ;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,CACD,SAAS,8DAA8D;;AAG1E,MAAa,qBAAqB,EAC/B,KAAK;CAAC;CAAY;CAAW;AAAQ,CAAC,CAAC,CACvC,SACC,sIACF;;AAGF,MAAa,mCAAmC,EAC7C,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAC3B,SAAS,CAAC,CACV,SAAS,4CAA4C;;AAGxD,MAAa,mBAAmB,EAC7B,aAAa;CACZ,UAAU,eAAe,SAAS,CAAC,CAAC,SAAS,+BAA+B;CAC5E,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,kCAAkC;AACpF,CAAC,CAAC,CACD,SAAS,mFAAmF;;AAG/F,MAAa,gBAAgB,EAC1B,OAAO,CAAC,CACR,IAAI,CAAC,CAAC,CACN,SAAS,qFAAqF;;;;;;AAOjG,MAAa,2BAA2B,EAAE,aAAa;CACrD,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,+BAA+B;CACpE,WAAW,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,6CAA6C;CACnF,eAAe,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,sCAAsC;CAC3F,SAAS,cAAc,SAAS;CAChC,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,yCAAyC;AAC1F,CAAC;AAED,MAAM,mBAAmB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY;;AAGtD,MAAa,kBAAkB,EAAE,aAAa;CAC5C,SAAS,UAAU,SAAS,6CAA6C;CACzE,aAAa;CACb,cAAc;CACd,iBAAiB;CACjB,kBAAkB;CAClB,OAAO,EACJ,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAC3C,SAAS,kFAAkF;AAChG,CAAC;;AAGD,MAAa,qBAAqB,EAAE,aAAa;CAC/C,MAAM,EACH,OAAO,CAAC,CACR,IAAI,CAAC,CAAC,CACN,SAAS,oEAAoE;CAChF,SAAS,EACN,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACxB,SAAS,CAAC,CACV,SAAS,+CAA+C;;;;;;;;CAQ3D,gBAAgB,EACb,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACxB,IAAI,EAAE,CAAC,CACP,SAAS,CAAC,CACV,SAAS,CAAC,CACV,SACC,8FACF;CACF,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;CACnC,YAAY,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,sCAAsC;AAC1F,CAAC;;AA0WD,MAAa,aAvWY,EACtB,aAAa;CACZ,eAAe;CACf,IAAI;CACJ,eAAe,oBAAoB,SAAS,iCAAiC;CAC7E,MAAM;CACN,OAAO,EACJ,OAAO,CAAC,CACR,KAAK,CAAC,CACN,IAAI,CAAC,CAAC,CACN,IAAI,GAAG,CAAC,CACR,SAAS,CAAC,CACV,SAAS,8EAA8E;CAC1F,MAAM,EACH,OAAO,CAAC,CACR,IAAI,CAAC,CAAC,CACN,SAAS,CAAC,CACV,SAAS,sDAAsD;CAClE,OAAO;CACP,UAAU,mBAAmB,SAAS;CACtC,QAAQ;CACR,MAAM,eAAe,SAAS,qDAAqD;CACnF,YAAY,qBAAqB,SAAS,CAAC,CAAC,SAAS,sCAAsC;CAC3F,oBAAoB,EACjB,QAAQ,CAAC,CACT,SAAS,CAAC,CACV,SAAS,gEAAgE;CAC5E,eAAe,sBAAsB,MAAM,GACxC,SAAS,CAAC,CACV,SAAS,iFAAiF;CAC7F,YAAY,aAAa,SAAS,sDAAsD;CACxF,cAAc,aACX,SAAS,CAAC,CACV,SAAS,8DAA8D;CAC1E,mBAAmB,EAChB,OAAO,CAAC,CACR,IAAI,CAAC,CACL,SAAS,CAAC,CACV,SAAS,CAAC,CACV,SACC,mGACF;CACF,SAAS;CACT,gCAAgC,EAC7B,MAAM,eAAe,CAAC,CACtB,SAAS,CAAC,CACV,SAAS,CAAC,CACV,SACC,oFACF;CACF,kBAAkB,gBACf,SAAS,CAAC,CACV,SACC,gGACF;CACF,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,mDAAmD;CAC7F,WAAW,yBACR,SAAS,CAAC,CACV,SAAS,+EAA+E;CAC3F,gBAAgB,kBACb,SAAS,CAAC,CACV,SACC,qFACF;CACF,WAAW,kBACR,SAAS,CAAC,CACV,SAAS,8CAA8C;CAC1D,eAAe,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,kCAAkC;CACvF,kBAAkB,EACf,OAAO,CAAC,CACR,IAAI,CAAC,CAAC,CACN,SAAS,CAAC,CACV,SACC,sLACF;CACF,sBAAsB,kBACnB,SAAS,CAAC,CACV,SACC,6IACF;CACF,aAAa,UAAU,SAAS,CAAC,CAAC,SAAS,kCAAkC;CAC7E,YAAY,kBACT,SAAS,CAAC,CACV,SAAS,uEAAuE;CACnF,OAAO,gBACJ,SAAS,CAAC,CACV,SACC,wFACF;CACF,YAAY,UACT,SAAS,CAAC,CACV,SACC,oGACF;CACF,UAAU,mBAAmB,SAAS;CACtC,gBAAgB,aACb,SAAS,CAAC,CACV,SACC,oFACF;CACF,gBAAgB,EACb,MAAM,cAAc,CAAC,CACrB,SAAS,CAAC,CACV,SAAS,CAAC,CACV,SAAS,qEAAqE;CACjF,UAAU,eACP,SAAS,CAAC,CACV,SAAS,mDAAmD;CAC/D,WAAW,EACR,OAAO,CAAC,CACR,IAAI,CAAC,CAAC,CACN,SAAS,CAAC,CACV,SAAS,8DAA8D;CAC1E,WAAW;CACX,WAAW;AACb,CAAC,CAAC,CACD,aAAa,MAAM,QAAQ;CAC1B,IAAI,KAAK,qBAAqB,KAAA,KAAa,KAAK,UAAU,UACxD,IAAI,SAAS;EACX,MAAM;EACN,MAAM,CAAC,kBAAkB;EACzB,SAAS;CACX,CAAC;CAEH,IACE,KAAK,UAAU,cACd,KAAK,cAAc,KAAA,KAAa,KAAK,kBAAkB,KAAA,IAExD,IAAI,SAAS;EACX,MAAM;EACN,MAAM,CAAC,WAAW;EAClB,SAAS;CACX,CAAC;CAEH,IACE,KAAK,UAAU,kBACd,KAAK,qBAAqB,KAAA,KAAa,KAAK,iBAAiB,KAAK,MAAM,KAEzE,IAAI,SAAS;EACX,MAAM;EACN,MAAM,CAAC,kBAAkB;EACzB,SAAS;CACX,CAAC;CAEH,IACE,KAAK,UAAU,kBACd,KAAK,qBAAqB,KAAA,KAAa,KAAK,yBAAyB,KAAA,IAEtE,IAAI,SAAS;EACX,MAAM;EACN,MAAM,CAAC,kBAAkB;EACzB,SACE;CACJ,CAAC;CAEH,IACE,KAAK,UAAU,kBACb,KAAK,aAAa,KAAA,KAAa,KAAK,mBAAmB,KAAA,KACtD,KAAK,aAAa,KAAA,MAChB,KAAK,SAAS,WAAW,KAAA,KAAa,KAAK,SAAS,eAAe,KAAA,KAExE,IAAI,SAAS;EACX,MAAM;EACN,MAAM,CAAC,UAAU;EACjB,SAAS;CACX,CAAC;CAEH,IAAI,KAAK,aAAa,KAAA,KAAa,KAAK,mBAAmB,KAAA,GACzD,IAAI,SAAS;EACX,MAAM;EACN,MAAM,CAAC,gBAAgB;EACvB,SAAS;CACX,CAAC;CAEH,IACE,KAAK,sBAAsB,KAAA,MAC1B,KAAK,iBAAiB,KAAA,KAAa,KAAK,aAAa,KAAA,IAEtD,IAAI,SAAS;EACX,MAAM;EACN,MAAM,CAAC,mBAAmB;EAC1B,SAAS;CACX,CAAC;CAEH,IAAI,KAAK,iBAAiB,KAAK,IAC7B,IAAI,SAAS;EACX,MAAM;EACN,MAAM,CAAC,cAAc;EACrB,SAAS;CACX,CAAC;CAEH,IAAI,KAAK,iBAAiB,KAAA,KAAa,KAAK,eAAe,KAAK,IAC9D,IAAI,SAAS;EACX,MAAM;EACN,MAAM,CAAC,YAAY;EACnB,SAAS;CACX,CAAC;CAEH,IAAI,KAAK,iBAAiB,KAAA,KAAa,KAAK,eAAe,KAAK,IAC9D,IAAI,SAAS;EACX,MAAM;EACN,MAAM,CAAC,YAAY;EACnB,SAAS;CACX,CAAC;CAEH,IACE,KAAK,iBAAiB,KAAA,KACtB,KAAK,OAAO,aAAa,KAAA,KACzB,KAAK,OAAO,aAAa,KAAA,GAEzB,IAAI,SAAS;EACX,MAAM;EACN,MAAM,CAAC,QAAQ;EACf,SAAS;CACX,CAAC;CAEH,IAAI,KAAK,uBAAuB,QAAQ,KAAK,UAAU,WACrD,IAAI,SAAS;EACX,MAAM;EACN,MAAM,CAAC,oBAAoB;EAC3B,SAAS;CACX,CAAC;CAEH,IAAI,KAAK,UAAU,eAAe,KAAK,eAAe,KAAA,GACpD,IAAI,SAAS;EACX,MAAM;EACN,MAAM,CAAC,YAAY;EACnB,SAAS;CACX,CAAC;AAEL,CAiIwB;;AAwB1B,SAAgB,gBAAgB,MAAmC;CACjE,OAAO,KAAK,UAAU,eAAe,KAAK,eAAe,KAAA;AAC3D;;AAGA,SAAgB,iBAAiB,MAAoC;CACnE,OAAO,KAAK,UAAU,iBAAiB,KAAK,qBAAqB,KAAA;AACnE;;AAGA,SAAgB,qBAAqB,MAAwC;CAC3E,OAAO,KAAK,UAAU,aAAa,KAAK,uBAAuB;AACjE"}
|
|
@@ -46,6 +46,7 @@ declare const transcriptBlockSchema: z.ZodDiscriminatedUnion<[z.ZodReadonly<z.Zo
|
|
|
46
46
|
id: z.ZodString;
|
|
47
47
|
title: z.ZodString;
|
|
48
48
|
text: z.ZodString;
|
|
49
|
+
createdAt: z.ZodOptional<z.ZodISODateTime>;
|
|
49
50
|
}, z.core.$strict>>, z.ZodReadonly<z.ZodObject<{
|
|
50
51
|
kind: z.ZodEnum<{
|
|
51
52
|
error: "error";
|
|
@@ -58,6 +59,7 @@ declare const transcriptBlockSchema: z.ZodDiscriminatedUnion<[z.ZodReadonly<z.Zo
|
|
|
58
59
|
id: z.ZodString;
|
|
59
60
|
title: z.ZodString;
|
|
60
61
|
text: z.ZodString;
|
|
62
|
+
createdAt: z.ZodOptional<z.ZodISODateTime>;
|
|
61
63
|
}, z.core.$strict>>, z.ZodReadonly<z.ZodObject<{
|
|
62
64
|
kind: z.ZodLiteral<"tool">;
|
|
63
65
|
tool: z.ZodReadonly<z.ZodObject<{
|
|
@@ -80,6 +82,7 @@ declare const transcriptBlockSchema: z.ZodDiscriminatedUnion<[z.ZodReadonly<z.Zo
|
|
|
80
82
|
id: z.ZodString;
|
|
81
83
|
title: z.ZodString;
|
|
82
84
|
text: z.ZodString;
|
|
85
|
+
createdAt: z.ZodOptional<z.ZodISODateTime>;
|
|
83
86
|
}, z.core.$strict>>], "kind">;
|
|
84
87
|
/** Validates a cursor-addressed transcript projection and its current execution state. */
|
|
85
88
|
declare const transcriptSnapshotSchema: z.ZodReadonly<z.ZodObject<{
|
|
@@ -99,6 +102,7 @@ declare const transcriptSnapshotSchema: z.ZodReadonly<z.ZodObject<{
|
|
|
99
102
|
id: z.ZodString;
|
|
100
103
|
title: z.ZodString;
|
|
101
104
|
text: z.ZodString;
|
|
105
|
+
createdAt: z.ZodOptional<z.ZodISODateTime>;
|
|
102
106
|
}, z.core.$strict>>, z.ZodReadonly<z.ZodObject<{
|
|
103
107
|
kind: z.ZodEnum<{
|
|
104
108
|
error: "error";
|
|
@@ -111,6 +115,7 @@ declare const transcriptSnapshotSchema: z.ZodReadonly<z.ZodObject<{
|
|
|
111
115
|
id: z.ZodString;
|
|
112
116
|
title: z.ZodString;
|
|
113
117
|
text: z.ZodString;
|
|
118
|
+
createdAt: z.ZodOptional<z.ZodISODateTime>;
|
|
114
119
|
}, z.core.$strict>>, z.ZodReadonly<z.ZodObject<{
|
|
115
120
|
kind: z.ZodLiteral<"tool">;
|
|
116
121
|
tool: z.ZodReadonly<z.ZodObject<{
|
|
@@ -133,6 +138,7 @@ declare const transcriptSnapshotSchema: z.ZodReadonly<z.ZodObject<{
|
|
|
133
138
|
id: z.ZodString;
|
|
134
139
|
title: z.ZodString;
|
|
135
140
|
text: z.ZodString;
|
|
141
|
+
createdAt: z.ZodOptional<z.ZodISODateTime>;
|
|
136
142
|
}, z.core.$strict>>], "kind">>>;
|
|
137
143
|
inputs: z.ZodReadonly<z.ZodArray<z.ZodReadonly<z.ZodObject<{
|
|
138
144
|
requestId: z.ZodString;
|
|
@@ -33,7 +33,8 @@ const toolCallSchema = z.object({
|
|
|
33
33
|
const transcriptBlockBase = {
|
|
34
34
|
id: z.string().describe("Stable block ID used to replace streamed updates in place."),
|
|
35
35
|
title: z.string().describe("Short operator-facing block title."),
|
|
36
|
-
text: z.string().describe("Rendered Markdown or plain-text block content.")
|
|
36
|
+
text: z.string().describe("Rendered Markdown or plain-text block content."),
|
|
37
|
+
createdAt: z.iso.datetime().optional().describe("Source event timestamp retained in older saved transcripts.")
|
|
37
38
|
};
|
|
38
39
|
const userTranscriptBlockSchema = z.strictObject({
|
|
39
40
|
...transcriptBlockBase,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transcript.mjs","names":[],"sources":["../../src/schema/transcript.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { imageAttachmentsSchema } from \"../image-input\";\n\n/** Validates a structured input request projected from a provider transcript. */\nexport const inputRequestSchema = z\n .object({\n requestId: z.string().describe(\"Stable provider input request ID.\"),\n prompt: z.string().describe(\"Question or instruction presented to the operator.\"),\n kind: z.string().describe(\"Provider-defined input request kind.\"),\n allowFreeform: z\n .boolean()\n .optional()\n .describe(\"Whether the operator may enter text instead of selecting an option.\"),\n options: z\n .array(\n z\n .object({\n id: z.string().describe(\"Stable option ID returned in the response.\"),\n label: z.string().describe(\"Operator-facing option label.\"),\n description: z.string().optional().describe(\"Additional option context.\"),\n })\n .readonly(),\n )\n .readonly()\n .optional()\n .describe(\"Selectable answers offered by the provider.\"),\n })\n .readonly();\n\n/** Validates the streamed state and payloads of one projected tool call. */\nexport const toolCallSchema = z\n .object({\n callId: z.string().describe(\"Provider tool-call ID used to correlate streamed updates.\"),\n name: z.string().describe(\"Tool name shown in the transcript.\"),\n input: z.unknown().optional().describe(\"Parsed tool input when complete JSON is available.\"),\n inputText: z.string().describe(\"Accumulated tool input text, including partial JSON.\"),\n output: z.unknown().optional().describe(\"Latest partial or final tool output.\"),\n error: z.unknown().optional().describe(\"Provider error associated with this tool call.\"),\n state: z\n .enum([\"input-streaming\", \"running\", \"completed\", \"failed\", \"cancelled\", \"rejected\"])\n .describe(\"Current streamed tool-call lifecycle state.\"),\n })\n .readonly();\n\nconst transcriptBlockBase = {\n id: z.string().describe(\"Stable block ID used to replace streamed updates in place.\"),\n title: z.string().describe(\"Short operator-facing block title.\"),\n text: z.string().describe(\"Rendered Markdown or plain-text block content.\"),\n};\n\nconst userTranscriptBlockSchema = z\n .strictObject({\n ...transcriptBlockBase,\n kind: z.literal(\"user\").describe(\"Human-authored message block.\"),\n tool: z.never().optional().describe(\"Tool payloads are forbidden on user messages.\"),\n attachments: imageAttachmentsSchema\n .optional()\n .describe(\"Images attached to this human message.\"),\n })\n .readonly();\n\nconst textTranscriptBlockSchema = z\n .strictObject({\n ...transcriptBlockBase,\n kind: z\n .enum([\"assistant\", \"reasoning\", \"status\", \"error\"])\n .describe(\"Non-tool transcript block kind.\"),\n tool: z.never().optional().describe(\"Tool payloads are forbidden on text blocks.\"),\n attachments: z.never().optional().describe(\"Attachments are reserved for user messages.\"),\n })\n .readonly();\n\nconst toolTranscriptBlockSchema = z\n .strictObject({\n ...transcriptBlockBase,\n kind: z.literal(\"tool\").describe(\"Correlated tool-call block.\"),\n tool: toolCallSchema.describe(\"Tool invocation represented by this block.\"),\n attachments: z.never().optional().describe(\"Attachments are reserved for user messages.\"),\n })\n .readonly();\n\n/** Validates a rendered transcript block with payloads correlated to its kind. */\nexport const transcriptBlockSchema = z.discriminatedUnion(\"kind\", [\n userTranscriptBlockSchema,\n textTranscriptBlockSchema,\n toolTranscriptBlockSchema,\n]);\n\n/** Validates a cursor-addressed transcript projection and its current execution state. */\nexport const transcriptSnapshotSchema = z\n .object({\n blocks: z\n .array(transcriptBlockSchema)\n .readonly()\n .describe(\"Ordered rendered transcript blocks.\"),\n inputs: z.array(inputRequestSchema).readonly().describe(\"Unresolved provider input requests.\"),\n cursor: z.number().int().nonnegative().describe(\"Next provider event index to request.\"),\n state: z\n .enum([\"connecting\", \"running\", \"needs input\", \"waiting\", \"completed\", \"failed\"])\n .describe(\"Current execution state shown to the operator.\"),\n turnId: z.string().optional().describe(\"Active provider turn ID, when one is running.\"),\n tokens: z.number().nonnegative().describe(\"Accumulated input and output tokens.\"),\n })\n .readonly();\n\n/** Structured pending input request projected from a provider transcript. */\nexport type InputRequest = z.infer<typeof inputRequestSchema>;\n/** Projected tool invocation with streamed input, result, error, and lifecycle state. */\nexport type ToolCall = z.infer<typeof toolCallSchema>;\n/** Renderable unit in a structured Factory transcript. */\nexport type TranscriptBlock = z.infer<typeof transcriptBlockSchema>;\n/** Cursor-addressed read model of a provider execution transcript. */\nexport type TranscriptSnapshot = z.infer<typeof transcriptSnapshotSchema>;\n"],"mappings":";;;;AAIA,MAAa,qBAAqB,EAC/B,OAAO;CACN,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS,mCAAmC;CAClE,QAAQ,EAAE,OAAO,CAAC,CAAC,SAAS,oDAAoD;CAChF,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS,sCAAsC;CAChE,eAAe,EACZ,QAAQ,CAAC,CACT,SAAS,CAAC,CACV,SAAS,qEAAqE;CACjF,SAAS,EACN,MACC,EACG,OAAO;EACN,IAAI,EAAE,OAAO,CAAC,CAAC,SAAS,4CAA4C;EACpE,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS,+BAA+B;EAC1D,aAAa,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,4BAA4B;CAC1E,CAAC,CAAC,CACD,SAAS,CACd,CAAC,CACA,SAAS,CAAC,CACV,SAAS,CAAC,CACV,SAAS,6CAA6C;AAC3D,CAAC,CAAC,CACD,SAAS;;AAGZ,MAAa,iBAAiB,EAC3B,OAAO;CACN,QAAQ,EAAE,OAAO,CAAC,CAAC,SAAS,2DAA2D;CACvF,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS,oCAAoC;CAC9D,OAAO,EAAE,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,oDAAoD;CAC3F,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS,sDAAsD;CACrF,QAAQ,EAAE,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,sCAAsC;CAC9E,OAAO,EAAE,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,gDAAgD;CACvF,OAAO,EACJ,KAAK;EAAC;EAAmB;EAAW;EAAa;EAAU;EAAa;CAAU,CAAC,CAAC,CACpF,SAAS,6CAA6C;AAC3D,CAAC,CAAC,CACD,SAAS;AAEZ,MAAM,sBAAsB;CAC1B,IAAI,EAAE,OAAO,CAAC,CAAC,SAAS,4DAA4D;CACpF,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS,oCAAoC;CAC/D,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS,gDAAgD;
|
|
1
|
+
{"version":3,"file":"transcript.mjs","names":[],"sources":["../../src/schema/transcript.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { imageAttachmentsSchema } from \"../image-input\";\n\n/** Validates a structured input request projected from a provider transcript. */\nexport const inputRequestSchema = z\n .object({\n requestId: z.string().describe(\"Stable provider input request ID.\"),\n prompt: z.string().describe(\"Question or instruction presented to the operator.\"),\n kind: z.string().describe(\"Provider-defined input request kind.\"),\n allowFreeform: z\n .boolean()\n .optional()\n .describe(\"Whether the operator may enter text instead of selecting an option.\"),\n options: z\n .array(\n z\n .object({\n id: z.string().describe(\"Stable option ID returned in the response.\"),\n label: z.string().describe(\"Operator-facing option label.\"),\n description: z.string().optional().describe(\"Additional option context.\"),\n })\n .readonly(),\n )\n .readonly()\n .optional()\n .describe(\"Selectable answers offered by the provider.\"),\n })\n .readonly();\n\n/** Validates the streamed state and payloads of one projected tool call. */\nexport const toolCallSchema = z\n .object({\n callId: z.string().describe(\"Provider tool-call ID used to correlate streamed updates.\"),\n name: z.string().describe(\"Tool name shown in the transcript.\"),\n input: z.unknown().optional().describe(\"Parsed tool input when complete JSON is available.\"),\n inputText: z.string().describe(\"Accumulated tool input text, including partial JSON.\"),\n output: z.unknown().optional().describe(\"Latest partial or final tool output.\"),\n error: z.unknown().optional().describe(\"Provider error associated with this tool call.\"),\n state: z\n .enum([\"input-streaming\", \"running\", \"completed\", \"failed\", \"cancelled\", \"rejected\"])\n .describe(\"Current streamed tool-call lifecycle state.\"),\n })\n .readonly();\n\nconst transcriptBlockBase = {\n id: z.string().describe(\"Stable block ID used to replace streamed updates in place.\"),\n title: z.string().describe(\"Short operator-facing block title.\"),\n text: z.string().describe(\"Rendered Markdown or plain-text block content.\"),\n createdAt: z.iso\n .datetime()\n .optional()\n .describe(\"Source event timestamp retained in older saved transcripts.\"),\n};\n\nconst userTranscriptBlockSchema = z\n .strictObject({\n ...transcriptBlockBase,\n kind: z.literal(\"user\").describe(\"Human-authored message block.\"),\n tool: z.never().optional().describe(\"Tool payloads are forbidden on user messages.\"),\n attachments: imageAttachmentsSchema\n .optional()\n .describe(\"Images attached to this human message.\"),\n })\n .readonly();\n\nconst textTranscriptBlockSchema = z\n .strictObject({\n ...transcriptBlockBase,\n kind: z\n .enum([\"assistant\", \"reasoning\", \"status\", \"error\"])\n .describe(\"Non-tool transcript block kind.\"),\n tool: z.never().optional().describe(\"Tool payloads are forbidden on text blocks.\"),\n attachments: z.never().optional().describe(\"Attachments are reserved for user messages.\"),\n })\n .readonly();\n\nconst toolTranscriptBlockSchema = z\n .strictObject({\n ...transcriptBlockBase,\n kind: z.literal(\"tool\").describe(\"Correlated tool-call block.\"),\n tool: toolCallSchema.describe(\"Tool invocation represented by this block.\"),\n attachments: z.never().optional().describe(\"Attachments are reserved for user messages.\"),\n })\n .readonly();\n\n/** Validates a rendered transcript block with payloads correlated to its kind. */\nexport const transcriptBlockSchema = z.discriminatedUnion(\"kind\", [\n userTranscriptBlockSchema,\n textTranscriptBlockSchema,\n toolTranscriptBlockSchema,\n]);\n\n/** Validates a cursor-addressed transcript projection and its current execution state. */\nexport const transcriptSnapshotSchema = z\n .object({\n blocks: z\n .array(transcriptBlockSchema)\n .readonly()\n .describe(\"Ordered rendered transcript blocks.\"),\n inputs: z.array(inputRequestSchema).readonly().describe(\"Unresolved provider input requests.\"),\n cursor: z.number().int().nonnegative().describe(\"Next provider event index to request.\"),\n state: z\n .enum([\"connecting\", \"running\", \"needs input\", \"waiting\", \"completed\", \"failed\"])\n .describe(\"Current execution state shown to the operator.\"),\n turnId: z.string().optional().describe(\"Active provider turn ID, when one is running.\"),\n tokens: z.number().nonnegative().describe(\"Accumulated input and output tokens.\"),\n })\n .readonly();\n\n/** Structured pending input request projected from a provider transcript. */\nexport type InputRequest = z.infer<typeof inputRequestSchema>;\n/** Projected tool invocation with streamed input, result, error, and lifecycle state. */\nexport type ToolCall = z.infer<typeof toolCallSchema>;\n/** Renderable unit in a structured Factory transcript. */\nexport type TranscriptBlock = z.infer<typeof transcriptBlockSchema>;\n/** Cursor-addressed read model of a provider execution transcript. */\nexport type TranscriptSnapshot = z.infer<typeof transcriptSnapshotSchema>;\n"],"mappings":"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"}
|
package/dist/schema/work.d.mts
CHANGED
|
@@ -60,38 +60,87 @@ declare const taskWorkResultSchema: z.ZodObject<{
|
|
|
60
60
|
}, z.core.$strict>;
|
|
61
61
|
/** Required title, typed input, criteria, workflow, and optional route contract of a Task. */
|
|
62
62
|
interface TaskWork<Input extends JsonValue = JsonValue, Workflow extends WorkflowBinding = WorkflowBinding> {
|
|
63
|
+
/** Short operator-facing description of the requested work. */
|
|
63
64
|
readonly title: string;
|
|
65
|
+
/** Canonical bounded JSON validated by the exact registered workflow before persistence. */
|
|
64
66
|
readonly input: Input;
|
|
67
|
+
/** Explicit acceptance statements interpreted by workflow or agent policy. */
|
|
65
68
|
readonly completionCriteria: readonly string[];
|
|
69
|
+
/** Exact workflow ID and version that validate this Task's input and output. */
|
|
66
70
|
readonly workflow: Workflow;
|
|
71
|
+
/** Exact agent route to dispatch, or absent when workflow code owns execution. */
|
|
67
72
|
readonly route?: AgentRouteBinding;
|
|
68
73
|
}
|
|
69
74
|
/** Validated canonical output and completion timestamp of succeeded workflow work. */
|
|
70
75
|
type TaskWorkResult = z.infer<typeof taskWorkResultSchema>;
|
|
71
76
|
/** Named fields for constructing generic `task@1` work. */
|
|
72
77
|
interface TaskWorkOptions<Input extends JsonValue = JsonValue> {
|
|
78
|
+
/** Short operator-facing description, trimmed and limited to 256 characters. */
|
|
73
79
|
readonly title: string;
|
|
80
|
+
/** Bounded JSON input. Defaults to an empty object. */
|
|
74
81
|
readonly input?: Input;
|
|
82
|
+
/** Generic work always selects `task@1`; use `WorkflowTaskWorkOptions` for custom workflows. */
|
|
75
83
|
readonly workflow?: never;
|
|
84
|
+
/** Add an exact agent route after construction or use `routeTaskWork`. */
|
|
76
85
|
readonly route?: never;
|
|
86
|
+
/** Generic work starts with no explicit criteria. */
|
|
77
87
|
readonly completionCriteria?: never;
|
|
78
88
|
}
|
|
79
89
|
/** Named fields for constructing work owned by an exact workflow contract. */
|
|
80
90
|
interface WorkflowTaskWorkOptions<Input extends JsonValue = JsonValue, Workflow extends WorkflowBinding | WorkflowReference = WorkflowBinding | WorkflowReference> {
|
|
91
|
+
/** Short operator-facing description, trimmed and limited to 256 characters. */
|
|
81
92
|
readonly title: string;
|
|
93
|
+
/** Input statically checked against the referenced workflow and validated again by the engine. */
|
|
82
94
|
readonly input: Input;
|
|
95
|
+
/** Exact typed workflow definition or binding; no implicit latest version is selected. */
|
|
83
96
|
readonly workflow: Workflow;
|
|
97
|
+
/** Add an exact agent route after construction or use `routeTaskWork`. */
|
|
84
98
|
readonly route?: never;
|
|
99
|
+
/** Workflow policy owns acceptance criteria; this helper starts with an empty list. */
|
|
85
100
|
readonly completionCriteria?: never;
|
|
86
101
|
}
|
|
87
|
-
/**
|
|
102
|
+
/**
|
|
103
|
+
* Constructs generic `task@1` work with an empty completion-criteria list.
|
|
104
|
+
*
|
|
105
|
+
* @remarks
|
|
106
|
+
* This helper constructs the persisted work envelope; it does not create or dispatch a Task.
|
|
107
|
+
* Supplying a workflow definition or typed binding preserves its input/output relationship for
|
|
108
|
+
* later `stores.work.completeWorkflow` calls. The store engine performs authoritative runtime
|
|
109
|
+
* validation against its registered exact workflow version.
|
|
110
|
+
*
|
|
111
|
+
* @param options - Named title and optional bounded JSON input for generic `task@1` work.
|
|
112
|
+
* @returns A new work envelope selecting the generic `task@1` workflow.
|
|
113
|
+
* @throws A Zod validation error when the title, input, or workflow binding is invalid.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* import { taskWork } from "@vercel/factory/workflows";
|
|
118
|
+
*
|
|
119
|
+
* const work = taskWork({
|
|
120
|
+
* title: "Summarize the incident",
|
|
121
|
+
* input: { incidentId: "inc_123" },
|
|
122
|
+
* });
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
88
125
|
declare function taskWork<const Input extends JsonValue = JsonValue>(options: TaskWorkOptions<Input>): TaskWork<Input>;
|
|
89
|
-
/**
|
|
126
|
+
/**
|
|
127
|
+
* Constructs work from a workflow definition while preserving its exact typed binding.
|
|
128
|
+
*
|
|
129
|
+
* @param options - Named title, workflow definition, and input accepted by that definition.
|
|
130
|
+
* @returns A new work envelope carrying the definition's exact workflow binding.
|
|
131
|
+
* @throws A Zod validation error when the title, input envelope, or workflow binding is invalid.
|
|
132
|
+
*/
|
|
90
133
|
declare function taskWork<InputSchema extends z.ZodType, Binding extends WorkflowBinding>(options: WorkflowTaskWorkOptions<NoInfer<z.input<InputSchema>> & JsonValue, {
|
|
91
134
|
readonly input: InputSchema;
|
|
92
135
|
readonly binding: Binding;
|
|
93
136
|
}>): TaskWork<z.input<InputSchema> & JsonValue, Binding>;
|
|
94
|
-
/**
|
|
137
|
+
/**
|
|
138
|
+
* Constructs work from an exact typed workflow binding.
|
|
139
|
+
*
|
|
140
|
+
* @param options - Named title, exact binding, and input carried by that binding.
|
|
141
|
+
* @returns A new work envelope carrying the supplied exact workflow binding.
|
|
142
|
+
* @throws A Zod validation error when the title, input envelope, or workflow binding is invalid.
|
|
143
|
+
*/
|
|
95
144
|
declare function taskWork<Input extends JsonValue, Output extends JsonValue, const Id extends string, const Version extends number>(options: WorkflowTaskWorkOptions<NoInfer<Input>, WorkflowBinding<Input, Output, Id, Version> & {
|
|
96
145
|
readonly binding?: never;
|
|
97
146
|
readonly input?: never;
|
package/dist/schema/work.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"work.mjs","names":[],"sources":["../../src/schema/work.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { agentRouteBindingSchema, type AgentRouteBinding } from \"./agent-route\";\nimport { isoDateTimeSchema } from \"./common\";\n\n/** Finite JSON data accepted at persisted workflow boundaries. */\nexport type JsonValue =\n | null\n | boolean\n | number\n | string\n | readonly JsonValue[]\n | { readonly [key: string]: JsonValue };\n\ndeclare const workflowInputType: unique symbol;\ndeclare const workflowOutputType: unique symbol;\n\n/** Exact workflow identity carrying its input and output types for safe construction. */\nexport type WorkflowBinding<\n Input extends JsonValue = JsonValue,\n Output extends JsonValue = JsonValue,\n Id extends string = string,\n Version extends number = number,\n> = z.infer<typeof workflowBindingSchema> & {\n readonly id: Id;\n readonly version: Version;\n readonly [workflowInputType]?: Input;\n readonly [workflowOutputType]?: Output;\n};\n\n/** Definition-like value exposing an exact typed workflow binding. */\nexport interface WorkflowReference<\n InputSchema extends z.ZodType = z.ZodType,\n Binding extends WorkflowBinding = WorkflowBinding,\n> {\n readonly binding: Binding;\n readonly input: InputSchema;\n}\n\n/** Input type carried by a definition-like workflow reference. */\nexport type WorkflowReferenceInput<Reference extends WorkflowReference> = z.input<\n Reference[\"input\"]\n> &\n JsonValue;\n\n/** Maximum serialized UTF-8 size of workflow input, output, or message JSON. */\nexport const MAX_WORK_JSON_BYTES = 64 * 1024;\n/** Maximum nesting depth below the root of persisted workflow JSON. */\nexport const MAX_WORK_JSON_DEPTH = 32;\n\nconst encoder = new TextEncoder();\n\nfunction isBoundedJson(value: unknown): boolean {\n let bytes = 0;\n const ancestors = new Set<object>();\n const addBytes = (count: number): boolean => {\n bytes += count;\n return bytes <= MAX_WORK_JSON_BYTES;\n };\n const stringFits = (text: string): boolean =>\n text.length <= MAX_WORK_JSON_BYTES && addBytes(encoder.encode(JSON.stringify(text)).byteLength);\n\n const visit = (entry: unknown, depth: number): boolean => {\n if (depth > MAX_WORK_JSON_DEPTH) return false;\n if (entry === null) return addBytes(4);\n if (typeof entry === \"boolean\") return addBytes(entry ? 4 : 5);\n if (typeof entry === \"string\") return stringFits(entry);\n if (typeof entry === \"number\") {\n return Number.isFinite(entry) && addBytes(JSON.stringify(entry).length);\n }\n if (typeof entry !== \"object\" || ancestors.has(entry)) return false;\n\n const array = Array.isArray(entry);\n const prototype: unknown = Object.getPrototypeOf(entry);\n if (\n array ? prototype !== Array.prototype : prototype !== Object.prototype && prototype !== null\n ) {\n return false;\n }\n if (!addBytes(2)) return false;\n ancestors.add(entry);\n const keys = Reflect.ownKeys(entry);\n if (array) {\n if (entry.length > MAX_WORK_JSON_BYTES || keys.length !== entry.length + 1) return false;\n for (let index = 0; index < entry.length; index++) {\n const descriptor = Object.getOwnPropertyDescriptor(entry, String(index));\n if (!descriptor || !descriptor.enumerable || !(\"value\" in descriptor)) return false;\n if (index > 0 && !addBytes(1)) return false;\n if (!visit(descriptor.value, depth + 1)) return false;\n }\n } else {\n for (const [index, key] of keys.entries()) {\n if (typeof key !== \"string\") return false;\n const descriptor = Object.getOwnPropertyDescriptor(entry, key);\n if (!descriptor || !descriptor.enumerable || !(\"value\" in descriptor)) return false;\n if (index > 0 && !addBytes(1)) return false;\n if (!stringFits(key) || !addBytes(1) || !visit(descriptor.value, depth + 1)) return false;\n }\n }\n ancestors.delete(entry);\n return true;\n };\n\n try {\n return visit(value, 0);\n } catch {\n return false;\n }\n}\n\n/** Validates bounded canonical JSON without cycles, accessors, or sparse arrays. */\nexport const jsonValueSchema = z\n .custom<JsonValue>(isBoundedJson, {\n message: `Expected finite JSON with at most ${MAX_WORK_JSON_BYTES} UTF-8 bytes and depth ${MAX_WORK_JSON_DEPTH}; cycles, accessors, sparse arrays, and non-JSON properties are not allowed`,\n })\n .describe(\"Finite JSON value, at most 64 KiB serialized UTF-8 and 32 levels below the root.\");\n\n/** Validates an exact workflow identifier and positive integer version. */\nexport const workflowBindingSchema = z\n .strictObject({\n id: z\n .string()\n .max(64)\n .regex(\n /^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/,\n \"Expected a lowercase hyphenated or snake_case workflow name\",\n )\n .describe(\n \"Registered workflow name, starting with a lowercase letter; at most 64 characters.\",\n ),\n version: z\n .number()\n .int()\n .positive()\n .describe(\"Exact positive integer version of the registered workflow.\"),\n })\n .describe(\"Explicit workflow identity and version; never resolved to an implicit latest version.\")\n .brand<\"WorkflowBinding\">();\n\n/** Plain identifier and version accepted when constructing a workflow binding. */\nexport interface WorkflowBindingInput<Id extends string = string, Version extends number = number> {\n readonly id: Id;\n readonly version: Version;\n}\n\n/** Validates and brands an exact workflow binding while preserving literal identity. */\nexport function parseWorkflowBinding<const Input extends WorkflowBindingInput>(\n input: Input,\n): WorkflowBinding<JsonValue, JsonValue, Input[\"id\"], Input[\"version\"]> {\n return workflowBindingSchema.parse(input) as WorkflowBinding<\n JsonValue,\n JsonValue,\n Input[\"id\"],\n Input[\"version\"]\n >;\n}\n\n/** Validates the required versioned input and completion contract for a Task. */\nexport const taskWorkSchema = z\n .strictObject({\n title: z\n .string()\n .trim()\n .min(1)\n .max(256)\n .describe(\"Short work title, from 1 to 256 characters.\"),\n input: jsonValueSchema.describe(\n \"Bounded JSON input to validate against the registered workflow input schema.\",\n ),\n completionCriteria: z\n .array(\n z\n .string()\n .trim()\n .min(1)\n .max(2048)\n .describe(\"One completion criterion, from 1 to 2048 characters.\"),\n )\n .max(32)\n .readonly()\n .describe(\"Up to 32 explicit completion criteria; workflow code determines completion.\"),\n workflow: workflowBindingSchema.describe(\n \"Exact registered workflow contract that owns this work.\",\n ),\n route: agentRouteBindingSchema\n .optional()\n .describe(\n \"Exact agent execution route selected by the workflow; absent for work not dispatched to an agent.\",\n ),\n })\n .describe(\n \"Required versioned work contract; registered workflow validation is owned by the engine.\",\n );\n\n/** Validates canonical output recorded when workflow work completes. */\nexport const taskWorkResultSchema = z\n .strictObject({\n output: jsonValueSchema.describe(\n \"Canonical bounded JSON output, validated by the engine against the stored workflow output schema.\",\n ),\n completedAt: isoDateTimeSchema.describe(\n \"Engine timestamp when the workflow result was completed.\",\n ),\n })\n .describe(\n \"Completed result of workflow work; registered output validation is owned by the engine.\",\n );\n\n/** Required title, typed input, criteria, workflow, and optional route contract of a Task. */\nexport interface TaskWork<\n Input extends JsonValue = JsonValue,\n Workflow extends WorkflowBinding = WorkflowBinding,\n> {\n readonly title: string;\n readonly input: Input;\n readonly completionCriteria: readonly string[];\n readonly workflow: Workflow;\n readonly route?: AgentRouteBinding;\n}\n/** Validated canonical output and completion timestamp of succeeded workflow work. */\nexport type TaskWorkResult = z.infer<typeof taskWorkResultSchema>;\n\n/** Named fields for constructing generic `task@1` work. */\nexport interface TaskWorkOptions<Input extends JsonValue = JsonValue> {\n readonly title: string;\n readonly input?: Input;\n readonly workflow?: never;\n readonly route?: never;\n readonly completionCriteria?: never;\n}\n\n/** Named fields for constructing work owned by an exact workflow contract. */\nexport interface WorkflowTaskWorkOptions<\n Input extends JsonValue = JsonValue,\n Workflow extends WorkflowBinding | WorkflowReference = WorkflowBinding | WorkflowReference,\n> {\n readonly title: string;\n readonly input: Input;\n readonly workflow: Workflow;\n readonly route?: never;\n readonly completionCriteria?: never;\n}\n\n/** Constructs generic `task@1` work with an empty completion-criteria list. */\nexport function taskWork<const Input extends JsonValue = JsonValue>(\n options: TaskWorkOptions<Input>,\n): TaskWork<Input>;\n/** Constructs work from a definition-like reference with a typed exact workflow binding. */\nexport function taskWork<InputSchema extends z.ZodType, Binding extends WorkflowBinding>(\n options: WorkflowTaskWorkOptions<\n NoInfer<z.input<InputSchema>> & JsonValue,\n { readonly input: InputSchema; readonly binding: Binding }\n >,\n): TaskWork<z.input<InputSchema> & JsonValue, Binding>;\n/** Constructs work from an exact typed workflow binding. */\nexport function taskWork<\n Input extends JsonValue,\n Output extends JsonValue,\n const Id extends string,\n const Version extends number,\n>(\n options: WorkflowTaskWorkOptions<\n NoInfer<Input>,\n WorkflowBinding<Input, Output, Id, Version> & {\n readonly binding?: never;\n readonly input?: never;\n }\n >,\n): TaskWork<Input, WorkflowBinding<Input, Output, Id, Version>>;\nexport function taskWork(options: TaskWorkOptions | WorkflowTaskWorkOptions): TaskWork {\n const { title, input = {} } = options;\n const workflow =\n options.workflow ??\n parseWorkflowBinding({\n id: \"task\",\n version: 1,\n });\n const binding = \"binding\" in workflow ? workflow.binding : workflow;\n const parsed = taskWorkSchema.parse({ title, input, workflow: binding, completionCriteria: [] });\n return structuredClone({\n title: parsed.title,\n input,\n workflow: binding,\n completionCriteria: [],\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"work.mjs","names":[],"sources":["../../src/schema/work.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { agentRouteBindingSchema, type AgentRouteBinding } from \"./agent-route\";\nimport { isoDateTimeSchema } from \"./common\";\n\n/** Finite JSON data accepted at persisted workflow boundaries. */\nexport type JsonValue =\n | null\n | boolean\n | number\n | string\n | readonly JsonValue[]\n | { readonly [key: string]: JsonValue };\n\ndeclare const workflowInputType: unique symbol;\ndeclare const workflowOutputType: unique symbol;\n\n/** Exact workflow identity carrying its input and output types for safe construction. */\nexport type WorkflowBinding<\n Input extends JsonValue = JsonValue,\n Output extends JsonValue = JsonValue,\n Id extends string = string,\n Version extends number = number,\n> = z.infer<typeof workflowBindingSchema> & {\n readonly id: Id;\n readonly version: Version;\n readonly [workflowInputType]?: Input;\n readonly [workflowOutputType]?: Output;\n};\n\n/** Definition-like value exposing an exact typed workflow binding. */\nexport interface WorkflowReference<\n InputSchema extends z.ZodType = z.ZodType,\n Binding extends WorkflowBinding = WorkflowBinding,\n> {\n readonly binding: Binding;\n readonly input: InputSchema;\n}\n\n/** Input type carried by a definition-like workflow reference. */\nexport type WorkflowReferenceInput<Reference extends WorkflowReference> = z.input<\n Reference[\"input\"]\n> &\n JsonValue;\n\n/** Maximum serialized UTF-8 size of workflow input, output, or message JSON. */\nexport const MAX_WORK_JSON_BYTES = 64 * 1024;\n/** Maximum nesting depth below the root of persisted workflow JSON. */\nexport const MAX_WORK_JSON_DEPTH = 32;\n\nconst encoder = new TextEncoder();\n\nfunction isBoundedJson(value: unknown): boolean {\n let bytes = 0;\n const ancestors = new Set<object>();\n const addBytes = (count: number): boolean => {\n bytes += count;\n return bytes <= MAX_WORK_JSON_BYTES;\n };\n const stringFits = (text: string): boolean =>\n text.length <= MAX_WORK_JSON_BYTES && addBytes(encoder.encode(JSON.stringify(text)).byteLength);\n\n const visit = (entry: unknown, depth: number): boolean => {\n if (depth > MAX_WORK_JSON_DEPTH) return false;\n if (entry === null) return addBytes(4);\n if (typeof entry === \"boolean\") return addBytes(entry ? 4 : 5);\n if (typeof entry === \"string\") return stringFits(entry);\n if (typeof entry === \"number\") {\n return Number.isFinite(entry) && addBytes(JSON.stringify(entry).length);\n }\n if (typeof entry !== \"object\" || ancestors.has(entry)) return false;\n\n const array = Array.isArray(entry);\n const prototype: unknown = Object.getPrototypeOf(entry);\n if (\n array ? prototype !== Array.prototype : prototype !== Object.prototype && prototype !== null\n ) {\n return false;\n }\n if (!addBytes(2)) return false;\n ancestors.add(entry);\n const keys = Reflect.ownKeys(entry);\n if (array) {\n if (entry.length > MAX_WORK_JSON_BYTES || keys.length !== entry.length + 1) return false;\n for (let index = 0; index < entry.length; index++) {\n const descriptor = Object.getOwnPropertyDescriptor(entry, String(index));\n if (!descriptor || !descriptor.enumerable || !(\"value\" in descriptor)) return false;\n if (index > 0 && !addBytes(1)) return false;\n if (!visit(descriptor.value, depth + 1)) return false;\n }\n } else {\n for (const [index, key] of keys.entries()) {\n if (typeof key !== \"string\") return false;\n const descriptor = Object.getOwnPropertyDescriptor(entry, key);\n if (!descriptor || !descriptor.enumerable || !(\"value\" in descriptor)) return false;\n if (index > 0 && !addBytes(1)) return false;\n if (!stringFits(key) || !addBytes(1) || !visit(descriptor.value, depth + 1)) return false;\n }\n }\n ancestors.delete(entry);\n return true;\n };\n\n try {\n return visit(value, 0);\n } catch {\n return false;\n }\n}\n\n/** Validates bounded canonical JSON without cycles, accessors, or sparse arrays. */\nexport const jsonValueSchema = z\n .custom<JsonValue>(isBoundedJson, {\n message: `Expected finite JSON with at most ${MAX_WORK_JSON_BYTES} UTF-8 bytes and depth ${MAX_WORK_JSON_DEPTH}; cycles, accessors, sparse arrays, and non-JSON properties are not allowed`,\n })\n .describe(\"Finite JSON value, at most 64 KiB serialized UTF-8 and 32 levels below the root.\");\n\n/** Validates an exact workflow identifier and positive integer version. */\nexport const workflowBindingSchema = z\n .strictObject({\n id: z\n .string()\n .max(64)\n .regex(\n /^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/,\n \"Expected a lowercase hyphenated or snake_case workflow name\",\n )\n .describe(\n \"Registered workflow name, starting with a lowercase letter; at most 64 characters.\",\n ),\n version: z\n .number()\n .int()\n .positive()\n .describe(\"Exact positive integer version of the registered workflow.\"),\n })\n .describe(\"Explicit workflow identity and version; never resolved to an implicit latest version.\")\n .brand<\"WorkflowBinding\">();\n\n/** Plain identifier and version accepted when constructing a workflow binding. */\nexport interface WorkflowBindingInput<Id extends string = string, Version extends number = number> {\n readonly id: Id;\n readonly version: Version;\n}\n\n/** Validates and brands an exact workflow binding while preserving literal identity. */\nexport function parseWorkflowBinding<const Input extends WorkflowBindingInput>(\n input: Input,\n): WorkflowBinding<JsonValue, JsonValue, Input[\"id\"], Input[\"version\"]> {\n return workflowBindingSchema.parse(input) as WorkflowBinding<\n JsonValue,\n JsonValue,\n Input[\"id\"],\n Input[\"version\"]\n >;\n}\n\n/** Validates the required versioned input and completion contract for a Task. */\nexport const taskWorkSchema = z\n .strictObject({\n title: z\n .string()\n .trim()\n .min(1)\n .max(256)\n .describe(\"Short work title, from 1 to 256 characters.\"),\n input: jsonValueSchema.describe(\n \"Bounded JSON input to validate against the registered workflow input schema.\",\n ),\n completionCriteria: z\n .array(\n z\n .string()\n .trim()\n .min(1)\n .max(2048)\n .describe(\"One completion criterion, from 1 to 2048 characters.\"),\n )\n .max(32)\n .readonly()\n .describe(\"Up to 32 explicit completion criteria; workflow code determines completion.\"),\n workflow: workflowBindingSchema.describe(\n \"Exact registered workflow contract that owns this work.\",\n ),\n route: agentRouteBindingSchema\n .optional()\n .describe(\n \"Exact agent execution route selected by the workflow; absent for work not dispatched to an agent.\",\n ),\n })\n .describe(\n \"Required versioned work contract; registered workflow validation is owned by the engine.\",\n );\n\n/** Validates canonical output recorded when workflow work completes. */\nexport const taskWorkResultSchema = z\n .strictObject({\n output: jsonValueSchema.describe(\n \"Canonical bounded JSON output, validated by the engine against the stored workflow output schema.\",\n ),\n completedAt: isoDateTimeSchema.describe(\n \"Engine timestamp when the workflow result was completed.\",\n ),\n })\n .describe(\n \"Completed result of workflow work; registered output validation is owned by the engine.\",\n );\n\n/** Required title, typed input, criteria, workflow, and optional route contract of a Task. */\nexport interface TaskWork<\n Input extends JsonValue = JsonValue,\n Workflow extends WorkflowBinding = WorkflowBinding,\n> {\n /** Short operator-facing description of the requested work. */\n readonly title: string;\n /** Canonical bounded JSON validated by the exact registered workflow before persistence. */\n readonly input: Input;\n /** Explicit acceptance statements interpreted by workflow or agent policy. */\n readonly completionCriteria: readonly string[];\n /** Exact workflow ID and version that validate this Task's input and output. */\n readonly workflow: Workflow;\n /** Exact agent route to dispatch, or absent when workflow code owns execution. */\n readonly route?: AgentRouteBinding;\n}\n/** Validated canonical output and completion timestamp of succeeded workflow work. */\nexport type TaskWorkResult = z.infer<typeof taskWorkResultSchema>;\n\n/** Named fields for constructing generic `task@1` work. */\nexport interface TaskWorkOptions<Input extends JsonValue = JsonValue> {\n /** Short operator-facing description, trimmed and limited to 256 characters. */\n readonly title: string;\n /** Bounded JSON input. Defaults to an empty object. */\n readonly input?: Input;\n /** Generic work always selects `task@1`; use `WorkflowTaskWorkOptions` for custom workflows. */\n readonly workflow?: never;\n /** Add an exact agent route after construction or use `routeTaskWork`. */\n readonly route?: never;\n /** Generic work starts with no explicit criteria. */\n readonly completionCriteria?: never;\n}\n\n/** Named fields for constructing work owned by an exact workflow contract. */\nexport interface WorkflowTaskWorkOptions<\n Input extends JsonValue = JsonValue,\n Workflow extends WorkflowBinding | WorkflowReference = WorkflowBinding | WorkflowReference,\n> {\n /** Short operator-facing description, trimmed and limited to 256 characters. */\n readonly title: string;\n /** Input statically checked against the referenced workflow and validated again by the engine. */\n readonly input: Input;\n /** Exact typed workflow definition or binding; no implicit latest version is selected. */\n readonly workflow: Workflow;\n /** Add an exact agent route after construction or use `routeTaskWork`. */\n readonly route?: never;\n /** Workflow policy owns acceptance criteria; this helper starts with an empty list. */\n readonly completionCriteria?: never;\n}\n\n/**\n * Constructs generic `task@1` work with an empty completion-criteria list.\n *\n * @remarks\n * This helper constructs the persisted work envelope; it does not create or dispatch a Task.\n * Supplying a workflow definition or typed binding preserves its input/output relationship for\n * later `stores.work.completeWorkflow` calls. The store engine performs authoritative runtime\n * validation against its registered exact workflow version.\n *\n * @param options - Named title and optional bounded JSON input for generic `task@1` work.\n * @returns A new work envelope selecting the generic `task@1` workflow.\n * @throws A Zod validation error when the title, input, or workflow binding is invalid.\n *\n * @example\n * ```ts\n * import { taskWork } from \"@vercel/factory/workflows\";\n *\n * const work = taskWork({\n * title: \"Summarize the incident\",\n * input: { incidentId: \"inc_123\" },\n * });\n * ```\n */\nexport function taskWork<const Input extends JsonValue = JsonValue>(\n options: TaskWorkOptions<Input>,\n): TaskWork<Input>;\n/**\n * Constructs work from a workflow definition while preserving its exact typed binding.\n *\n * @param options - Named title, workflow definition, and input accepted by that definition.\n * @returns A new work envelope carrying the definition's exact workflow binding.\n * @throws A Zod validation error when the title, input envelope, or workflow binding is invalid.\n */\nexport function taskWork<InputSchema extends z.ZodType, Binding extends WorkflowBinding>(\n options: WorkflowTaskWorkOptions<\n NoInfer<z.input<InputSchema>> & JsonValue,\n { readonly input: InputSchema; readonly binding: Binding }\n >,\n): TaskWork<z.input<InputSchema> & JsonValue, Binding>;\n/**\n * Constructs work from an exact typed workflow binding.\n *\n * @param options - Named title, exact binding, and input carried by that binding.\n * @returns A new work envelope carrying the supplied exact workflow binding.\n * @throws A Zod validation error when the title, input envelope, or workflow binding is invalid.\n */\nexport function taskWork<\n Input extends JsonValue,\n Output extends JsonValue,\n const Id extends string,\n const Version extends number,\n>(\n options: WorkflowTaskWorkOptions<\n NoInfer<Input>,\n WorkflowBinding<Input, Output, Id, Version> & {\n readonly binding?: never;\n readonly input?: never;\n }\n >,\n): TaskWork<Input, WorkflowBinding<Input, Output, Id, Version>>;\nexport function taskWork(options: TaskWorkOptions | WorkflowTaskWorkOptions): TaskWork {\n const { title, input = {} } = options;\n const workflow =\n options.workflow ??\n parseWorkflowBinding({\n id: \"task\",\n version: 1,\n });\n const binding = \"binding\" in workflow ? workflow.binding : workflow;\n const parsed = taskWorkSchema.parse({ title, input, workflow: binding, completionCriteria: [] });\n return structuredClone({\n title: parsed.title,\n input,\n workflow: binding,\n completionCriteria: [],\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/session-previews.d.ts
|
|
3
|
+
/** Validates an application-supplied preview page with explicit availability and expiry. */
|
|
4
|
+
declare const sessionPreviewSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
5
|
+
status: z.ZodEnum<{
|
|
6
|
+
unknown: "unknown";
|
|
7
|
+
ready: "ready";
|
|
8
|
+
}>;
|
|
9
|
+
url: z.ZodString;
|
|
10
|
+
id: z.ZodString;
|
|
11
|
+
title: z.ZodString;
|
|
12
|
+
instructions: z.ZodOptional<z.ZodString>;
|
|
13
|
+
source: z.ZodString;
|
|
14
|
+
revision: z.ZodNullable<z.ZodString>;
|
|
15
|
+
expiresAt: z.ZodOptional<z.ZodISODateTime>;
|
|
16
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
17
|
+
status: z.ZodEnum<{
|
|
18
|
+
unavailable: "unavailable";
|
|
19
|
+
starting: "starting";
|
|
20
|
+
expired: "expired";
|
|
21
|
+
}>;
|
|
22
|
+
reason: z.ZodString;
|
|
23
|
+
id: z.ZodString;
|
|
24
|
+
title: z.ZodString;
|
|
25
|
+
instructions: z.ZodOptional<z.ZodString>;
|
|
26
|
+
source: z.ZodString;
|
|
27
|
+
revision: z.ZodNullable<z.ZodString>;
|
|
28
|
+
expiresAt: z.ZodOptional<z.ZodISODateTime>;
|
|
29
|
+
}, z.core.$strict>], "status">;
|
|
30
|
+
/** Validates the optional live-preview projection, including instructions for non-web work. */
|
|
31
|
+
declare const sessionPreviewsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
32
|
+
state: z.ZodLiteral<"ready">;
|
|
33
|
+
previews: z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
34
|
+
status: z.ZodEnum<{
|
|
35
|
+
unknown: "unknown";
|
|
36
|
+
ready: "ready";
|
|
37
|
+
}>;
|
|
38
|
+
url: z.ZodString;
|
|
39
|
+
id: z.ZodString;
|
|
40
|
+
title: z.ZodString;
|
|
41
|
+
instructions: z.ZodOptional<z.ZodString>;
|
|
42
|
+
source: z.ZodString;
|
|
43
|
+
revision: z.ZodNullable<z.ZodString>;
|
|
44
|
+
expiresAt: z.ZodOptional<z.ZodISODateTime>;
|
|
45
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
46
|
+
status: z.ZodEnum<{
|
|
47
|
+
unavailable: "unavailable";
|
|
48
|
+
starting: "starting";
|
|
49
|
+
expired: "expired";
|
|
50
|
+
}>;
|
|
51
|
+
reason: z.ZodString;
|
|
52
|
+
id: z.ZodString;
|
|
53
|
+
title: z.ZodString;
|
|
54
|
+
instructions: z.ZodOptional<z.ZodString>;
|
|
55
|
+
source: z.ZodString;
|
|
56
|
+
revision: z.ZodNullable<z.ZodString>;
|
|
57
|
+
expiresAt: z.ZodOptional<z.ZodISODateTime>;
|
|
58
|
+
}, z.core.$strict>], "status">>>;
|
|
59
|
+
instructions: z.ZodNullable<z.ZodString>;
|
|
60
|
+
limitations: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
61
|
+
truncated: z.ZodBoolean;
|
|
62
|
+
executionId: z.ZodNullable<z.ZodString>;
|
|
63
|
+
capturedAt: z.ZodISODateTime;
|
|
64
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
65
|
+
state: z.ZodLiteral<"unavailable">;
|
|
66
|
+
reason: z.ZodString;
|
|
67
|
+
executionId: z.ZodNullable<z.ZodString>;
|
|
68
|
+
capturedAt: z.ZodISODateTime;
|
|
69
|
+
}, z.core.$strict>], "state">;
|
|
70
|
+
/** One application-owned preview page and its recorded availability. */
|
|
71
|
+
type SessionPreview = z.infer<typeof sessionPreviewSchema>;
|
|
72
|
+
/** Provider-neutral preview pages and practical testing instructions for a session. */
|
|
73
|
+
type SessionPreviews = z.infer<typeof sessionPreviewsSchema>;
|
|
74
|
+
//#endregion
|
|
75
|
+
export { SessionPreview, SessionPreviews, sessionPreviewSchema, sessionPreviewsSchema };
|
|
76
|
+
//# sourceMappingURL=session-previews.d.mts.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/session-previews.ts
|
|
3
|
+
const text = z.string().trim().min(1);
|
|
4
|
+
const previewUrl = z.string().refine((value) => {
|
|
5
|
+
if (!/^https?:\/\//iu.test(value) || /[\s\\]/u.test(value) || [...value].some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127)) return false;
|
|
6
|
+
try {
|
|
7
|
+
const url = new URL(value);
|
|
8
|
+
return ["https:", "http:"].includes(url.protocol) && !url.username && !url.password;
|
|
9
|
+
} catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}, "Use an absolute HTTP(S) preview URL without credentials");
|
|
13
|
+
const page = {
|
|
14
|
+
id: text.describe("Stable preview identity within this session."),
|
|
15
|
+
title: text.describe("Page or application to try."),
|
|
16
|
+
instructions: text.optional().describe("Actions to try and expected results, as Markdown."),
|
|
17
|
+
source: text.describe("Application-owned origin of the preview."),
|
|
18
|
+
revision: text.nullable().describe("Exact opaque code revision, or null when not recorded."),
|
|
19
|
+
expiresAt: z.iso.datetime().optional().describe("Known expiry; absent means not recorded.")
|
|
20
|
+
};
|
|
21
|
+
/** Validates an application-supplied preview page with explicit availability and expiry. */
|
|
22
|
+
const sessionPreviewSchema = z.discriminatedUnion("status", [z.strictObject({
|
|
23
|
+
...page,
|
|
24
|
+
status: z.enum(["ready", "unknown"]).describe("Ready as reported by the reader, or unchecked."),
|
|
25
|
+
url: previewUrl.describe("Browser destination; the application owns access and lifetime.")
|
|
26
|
+
}), z.strictObject({
|
|
27
|
+
...page,
|
|
28
|
+
status: z.enum([
|
|
29
|
+
"starting",
|
|
30
|
+
"unavailable",
|
|
31
|
+
"expired"
|
|
32
|
+
]).describe("Why this preview cannot be opened."),
|
|
33
|
+
reason: text.describe("Explanation and next steps for the operator.")
|
|
34
|
+
})]);
|
|
35
|
+
const common = {
|
|
36
|
+
executionId: text.nullable().describe("Observed session execution, or null before execution."),
|
|
37
|
+
capturedAt: z.iso.datetime().describe("When the preview projection was read.")
|
|
38
|
+
};
|
|
39
|
+
/** Validates the optional live-preview projection, including instructions for non-web work. */
|
|
40
|
+
const sessionPreviewsSchema = z.discriminatedUnion("state", [z.strictObject({
|
|
41
|
+
...common,
|
|
42
|
+
state: z.literal("ready").describe("The reader completed; individual pages have their own status."),
|
|
43
|
+
previews: z.array(sessionPreviewSchema).readonly().describe("Recorded preview pages or applications."),
|
|
44
|
+
instructions: text.nullable().describe("How to test the work, including local steps when no live site exists."),
|
|
45
|
+
limitations: z.array(text).readonly().describe("Missing evidence or review limitations."),
|
|
46
|
+
truncated: z.boolean().describe("Whether the reader omitted entries due to its configured limits.")
|
|
47
|
+
}), z.strictObject({
|
|
48
|
+
...common,
|
|
49
|
+
state: z.literal("unavailable").describe("Preview information could not be read."),
|
|
50
|
+
reason: text.describe("Why preview information is unavailable.")
|
|
51
|
+
})]);
|
|
52
|
+
//#endregion
|
|
53
|
+
export { sessionPreviewSchema, sessionPreviewsSchema };
|
|
54
|
+
|
|
55
|
+
//# sourceMappingURL=session-previews.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-previews.mjs","names":[],"sources":["../src/session-previews.ts"],"sourcesContent":["import { z } from \"zod\";\n\nconst text = z.string().trim().min(1);\nconst previewUrl = z.string().refine((value) => {\n if (\n !/^https?:\\/\\//iu.test(value) ||\n /[\\s\\\\]/u.test(value) ||\n [...value].some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127)\n )\n return false;\n try {\n const url = new URL(value);\n return [\"https:\", \"http:\"].includes(url.protocol) && !url.username && !url.password;\n } catch {\n return false;\n }\n}, \"Use an absolute HTTP(S) preview URL without credentials\");\nconst page = {\n id: text.describe(\"Stable preview identity within this session.\"),\n title: text.describe(\"Page or application to try.\"),\n instructions: text.optional().describe(\"Actions to try and expected results, as Markdown.\"),\n source: text.describe(\"Application-owned origin of the preview.\"),\n revision: text.nullable().describe(\"Exact opaque code revision, or null when not recorded.\"),\n expiresAt: z.iso.datetime().optional().describe(\"Known expiry; absent means not recorded.\"),\n};\n\n/** Validates an application-supplied preview page with explicit availability and expiry. */\nexport const sessionPreviewSchema = z.discriminatedUnion(\"status\", [\n z.strictObject({\n ...page,\n status: z.enum([\"ready\", \"unknown\"]).describe(\"Ready as reported by the reader, or unchecked.\"),\n url: previewUrl.describe(\"Browser destination; the application owns access and lifetime.\"),\n }),\n z.strictObject({\n ...page,\n status: z\n .enum([\"starting\", \"unavailable\", \"expired\"])\n .describe(\"Why this preview cannot be opened.\"),\n reason: text.describe(\"Explanation and next steps for the operator.\"),\n }),\n]);\n\nconst common = {\n executionId: text.nullable().describe(\"Observed session execution, or null before execution.\"),\n capturedAt: z.iso.datetime().describe(\"When the preview projection was read.\"),\n};\n\n/** Validates the optional live-preview projection, including instructions for non-web work. */\nexport const sessionPreviewsSchema = z.discriminatedUnion(\"state\", [\n z.strictObject({\n ...common,\n state: z\n .literal(\"ready\")\n .describe(\"The reader completed; individual pages have their own status.\"),\n previews: z\n .array(sessionPreviewSchema)\n .readonly()\n .describe(\"Recorded preview pages or applications.\"),\n instructions: text\n .nullable()\n .describe(\"How to test the work, including local steps when no live site exists.\"),\n limitations: z.array(text).readonly().describe(\"Missing evidence or review limitations.\"),\n truncated: z\n .boolean()\n .describe(\"Whether the reader omitted entries due to its configured limits.\"),\n }),\n z.strictObject({\n ...common,\n state: z.literal(\"unavailable\").describe(\"Preview information could not be read.\"),\n reason: text.describe(\"Why preview information is unavailable.\"),\n }),\n]);\n\n/** One application-owned preview page and its recorded availability. */\nexport type SessionPreview = z.infer<typeof sessionPreviewSchema>;\n/** Provider-neutral preview pages and practical testing instructions for a session. */\nexport type SessionPreviews = z.infer<typeof sessionPreviewsSchema>;\n"],"mappings":";;AAEA,MAAM,OAAO,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC;AACpC,MAAM,aAAa,EAAE,OAAO,CAAC,CAAC,QAAQ,UAAU;CAC9C,IACE,CAAC,iBAAiB,KAAK,KAAK,KAC5B,UAAU,KAAK,KAAK,KACpB,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,cAAc,UAAU,WAAW,CAAC,IAAI,MAAM,UAAU,WAAW,CAAC,MAAM,GAAG,GAE9F,OAAO;CACT,IAAI;EACF,MAAM,MAAM,IAAI,IAAI,KAAK;EACzB,OAAO,CAAC,UAAU,OAAO,CAAC,CAAC,SAAS,IAAI,QAAQ,KAAK,CAAC,IAAI,YAAY,CAAC,IAAI;CAC7E,QAAQ;EACN,OAAO;CACT;AACF,GAAG,yDAAyD;AAC5D,MAAM,OAAO;CACX,IAAI,KAAK,SAAS,8CAA8C;CAChE,OAAO,KAAK,SAAS,6BAA6B;CAClD,cAAc,KAAK,SAAS,CAAC,CAAC,SAAS,mDAAmD;CAC1F,QAAQ,KAAK,SAAS,0CAA0C;CAChE,UAAU,KAAK,SAAS,CAAC,CAAC,SAAS,wDAAwD;CAC3F,WAAW,EAAE,IAAI,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,0CAA0C;AAC5F;;AAGA,MAAa,uBAAuB,EAAE,mBAAmB,UAAU,CACjE,EAAE,aAAa;CACb,GAAG;CACH,QAAQ,EAAE,KAAK,CAAC,SAAS,SAAS,CAAC,CAAC,CAAC,SAAS,gDAAgD;CAC9F,KAAK,WAAW,SAAS,gEAAgE;AAC3F,CAAC,GACD,EAAE,aAAa;CACb,GAAG;CACH,QAAQ,EACL,KAAK;EAAC;EAAY;EAAe;CAAS,CAAC,CAAC,CAC5C,SAAS,oCAAoC;CAChD,QAAQ,KAAK,SAAS,8CAA8C;AACtE,CAAC,CACH,CAAC;AAED,MAAM,SAAS;CACb,aAAa,KAAK,SAAS,CAAC,CAAC,SAAS,uDAAuD;CAC7F,YAAY,EAAE,IAAI,SAAS,CAAC,CAAC,SAAS,uCAAuC;AAC/E;;AAGA,MAAa,wBAAwB,EAAE,mBAAmB,SAAS,CACjE,EAAE,aAAa;CACb,GAAG;CACH,OAAO,EACJ,QAAQ,OAAO,CAAC,CAChB,SAAS,+DAA+D;CAC3E,UAAU,EACP,MAAM,oBAAoB,CAAC,CAC3B,SAAS,CAAC,CACV,SAAS,yCAAyC;CACrD,cAAc,KACX,SAAS,CAAC,CACV,SAAS,uEAAuE;CACnF,aAAa,EAAE,MAAM,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,yCAAyC;CACxF,WAAW,EACR,QAAQ,CAAC,CACT,SAAS,kEAAkE;AAChF,CAAC,GACD,EAAE,aAAa;CACb,GAAG;CACH,OAAO,EAAE,QAAQ,aAAa,CAAC,CAAC,SAAS,wCAAwC;CACjF,QAAQ,KAAK,SAAS,yCAAyC;AACjE,CAAC,CACH,CAAC"}
|