robotrock 0.9.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/index.d.ts +18 -7
- package/dist/ai/index.js +581 -82
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/trigger.d.ts +4 -3
- package/dist/ai/trigger.js +539 -82
- package/dist/ai/trigger.js.map +1 -1
- package/dist/ai/workflow.d.ts +15 -4
- package/dist/ai/workflow.js +458 -82
- package/dist/ai/workflow.js.map +1 -1
- package/dist/{client-Cy7YLxms.d.ts → client-CzVmjXpz.d.ts} +86 -12
- package/dist/index.d.ts +10 -3
- package/dist/index.js +263 -66
- package/dist/index.js.map +1 -1
- package/dist/schemas/index.d.ts +11 -1
- package/dist/schemas/index.js +59 -4
- package/dist/schemas/index.js.map +1 -1
- package/dist/{tool-approval-bridge-G765kMJR.d.ts → tool-approval-bridge-DbwUEBHv.d.ts} +93 -2
- package/dist/trigger/index.d.ts +2 -1
- package/dist/trigger/index.js +250 -56
- package/dist/trigger/index.js.map +1 -1
- package/dist/{trigger-D0shjqk0.d.ts → trigger-BCKBbAV7.d.ts} +64 -3
- package/dist/workflow/index.d.ts +2 -1
- package/dist/workflow/index.js +251 -57
- package/dist/workflow/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/workflow/index.ts","../../src/schemas/index.ts","../../../core/src/utils/safe-url.ts","../../../core/src/schemas/task.ts","../../../core/src/schemas/context-urls.ts","../../src/approval-result.ts","../../src/client.ts","../../src/env.ts","../../src/handler-webhook.ts","../../src/wait-timing.ts","../../src/record-handled-to-otel.ts","../../src/otel-platform.ts"],"sourcesContent":["import { createWebhook, sleep } from \"workflow\";\nimport type {\n DiscriminatedApprovalResult,\n ThreadUpdate,\n ThreadUpdateStatus,\n} from \"../schemas/index.js\";\nimport {\n createClient,\n type SendToHumanActionInput,\n type SendToHumanInput,\n} from \"../client.js\";\nimport { resolveRobotRockConfig } from \"../env.js\";\nimport { toDiscriminatedApprovalResult } from \"../approval-result.js\";\nimport {\n isRobotRockHandlerWebhookPayload,\n type RobotRockHandlerWebhookPayload,\n} from \"../handler-webhook.js\";\nimport { parseValidUntilMs, resolveWaitTiming } from \"../wait-timing.js\";\nimport {\n beginRobotRockHumanWaitOtel,\n finishRobotRockHumanWaitOtel,\n stripPlatformOtelFields,\n type RobotRockPlatformOtelFields,\n} from \"../otel-platform.js\";\n\nexport type SendToHumanWorkflowPayload<\n A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[],\n> = SendToHumanInput<A> &\n RobotRockPlatformOtelFields & {\n /** Inbox app bucket. Overrides `ROBOTROCK_APP` when set. */\n app?: string;\n };\n\nexport type ApproveByHumanWorkflowPayload = Omit<SendToHumanWorkflowPayload, \"actions\">;\n\ntype Expand<T> = T extends unknown ? { [K in keyof T]: T[K] } : never;\n\nconst APPROVE_BY_HUMAN_ACTIONS = [\n { id: \"approve\", title: \"Approve\" },\n { id: \"decline\", title: \"Decline\" },\n] as const;\n\ntype CreateTaskStepInput = {\n webhookUrl: string;\n app?: string;\n validUntil: Date | string;\n taskInput: Omit<SendToHumanWorkflowPayload, \"validUntil\" | \"app\" | \"recordOtel\" | \"otelIncludeActionData\">;\n};\n\n/**\n * Creates the RobotRock inbox task with the workflow webhook URL as the handler.\n * Marked as a step so API calls run in full Node.js with retries.\n */\nasync function createRobotRockTaskForWebhook(input: CreateTaskStepInput) {\n \"use step\";\n\n const baseConfig = resolveRobotRockConfig();\n const client = createClient({\n apiKey: baseConfig.apiKey,\n baseUrl: baseConfig.baseUrl,\n ...((input.app ?? baseConfig.app) ? { app: input.app ?? baseConfig.app } : {}),\n ...(baseConfig.version ? { version: baseConfig.version } : {}),\n ...(baseConfig.advanced ? { advanced: baseConfig.advanced } : {}),\n webhook: { url: input.webhookUrl },\n });\n\n return client.sendToHuman({\n ...input.taskInput,\n validUntil: input.validUntil,\n });\n}\n\nasync function parseRobotRockWebhookRequest(request: Request) {\n \"use step\";\n\n const body: unknown = await request.json();\n if (!isRobotRockHandlerWebhookPayload(body)) {\n throw new Error(\n \"Workflow webhook completed with unexpected payload; expected RobotRock handler body (taskId, action.id, action.data).\"\n );\n }\n\n return body;\n}\n\n/**\n * Durable human-in-the-loop wait for Vercel Workflow.\n *\n * Call from a function with `\"use workflow\"` as its first statement. Creates a\n * {@link createWebhook} URL, registers it as the RobotRock task webhook, and\n * suspends until a human handles an action or `validUntil` passes.\n */\nexport async function sendToHumanInWorkflow<\n const A extends readonly SendToHumanActionInput[],\n>(\n payload: SendToHumanWorkflowPayload<A>\n): Promise<Expand<DiscriminatedApprovalResult<A>>> {\n const { validUntil: validUntilInput, app, recordOtel, otelIncludeActionData, ...taskFields } =\n payload;\n const { validUntil, timeout } = resolveWaitTiming(validUntilInput);\n const timeoutMs = parseValidUntilMs(validUntil) - Date.now();\n\n using webhook = createWebhook();\n\n const sendResult = await createRobotRockTaskForWebhook({\n webhookUrl: webhook.url,\n app,\n validUntil,\n taskInput: stripPlatformOtelFields(taskFields),\n });\n\n const otelSession = beginRobotRockHumanWaitOtel(sendResult.task, {\n recordOtel,\n otelIncludeActionData,\n });\n\n let handledPayload: RobotRockHandlerWebhookPayload | null = null;\n let waitOutcome: \"handled\" | \"timeout\" | \"error\" | \"pending\" = \"pending\";\n\n try {\n const outcome = await Promise.race([\n webhook.then((request) => parseRobotRockWebhookRequest(request)),\n sleep(timeoutMs).then(() => ({ timedOut: true }) as const),\n ]);\n\n if (\"timedOut\" in outcome) {\n waitOutcome = \"timeout\";\n throw new Error(`Human response timed out before validUntil (${timeout})`);\n }\n\n handledPayload = outcome;\n waitOutcome = \"handled\";\n\n return toDiscriminatedApprovalResult(payload.actions, {\n id: outcome.taskId,\n createdAt: new Date(),\n status: \"handled\",\n context: sendResult.task.context,\n validUntil: Date.now(),\n handledAt: new Date(outcome.handledAt).getTime(),\n handled: {\n action: {\n id: outcome.action.id,\n data: outcome.action.data,\n },\n handledBy: outcome.handledBy,\n },\n }) as unknown as Expand<DiscriminatedApprovalResult<A>>;\n } catch (error) {\n if (waitOutcome === \"pending\") {\n waitOutcome = \"error\";\n }\n throw error;\n } finally {\n if (waitOutcome !== \"pending\") {\n finishRobotRockHumanWaitOtel(\n otelSession,\n handledPayload,\n waitOutcome === \"handled\" ? \"handled\" : waitOutcome\n );\n }\n }\n}\n\n/**\n * Approve / decline gate for Vercel Workflow (`sendToHumanInWorkflow` with fixed actions).\n */\nexport async function approveByHumanInWorkflow(\n payload: ApproveByHumanWorkflowPayload\n): Promise<Expand<DiscriminatedApprovalResult<typeof APPROVE_BY_HUMAN_ACTIONS>>> {\n return sendToHumanInWorkflow({\n ...payload,\n actions: APPROVE_BY_HUMAN_ACTIONS,\n });\n}\n\nexport type SendUpdateWorkflowPayload = {\n /** Thread to log the update against (from a prior task's `threadId`). */\n threadId: string;\n /** Short status update (1-2 sentences) shown in the inbox status bar. */\n message: string;\n /** Lifecycle status driving the status-bar icon/color. @default \"info\" */\n status?: ThreadUpdateStatus;\n /** Inbox app bucket. Overrides `ROBOTROCK_APP` when set. */\n app?: string;\n};\n\n/**\n * Posts a thread update via `client.sendUpdate()`. Marked as a step so the API\n * call runs in full Node.js with retries and is recorded in the workflow run.\n */\nasync function sendRobotRockUpdate(payload: SendUpdateWorkflowPayload): Promise<ThreadUpdate> {\n \"use step\";\n\n const { app, ...update } = payload;\n const baseConfig = resolveRobotRockConfig();\n const client = createClient({\n apiKey: baseConfig.apiKey,\n baseUrl: baseConfig.baseUrl,\n ...((app ?? baseConfig.app) ? { app: app ?? baseConfig.app } : {}),\n ...(baseConfig.version ? { version: baseConfig.version } : {}),\n ...(baseConfig.advanced ? { advanced: baseConfig.advanced } : {}),\n });\n\n return client.sendUpdate(update);\n}\n\n/**\n * Durable thread update for Vercel Workflow.\n *\n * Wraps {@link createClient}'s `sendUpdate` in a `\"use step\"` so progress\n * reports are retried and recorded in the run. Fire-and-forget: returns the\n * created update without suspending the workflow (no human wait involved).\n *\n * Call from a function with `\"use workflow\"` as its first statement.\n */\nexport async function sendUpdateInWorkflow(\n payload: SendUpdateWorkflowPayload\n): Promise<ThreadUpdate> {\n return sendRobotRockUpdate(payload);\n}\n\nexport type { RobotRockHandlerWebhookPayload } from \"../handler-webhook.js\";\nexport type { RobotRockPlatformOtelFields } from \"../otel-platform.js\";\nexport type {\n ApprovalResult,\n DiscriminatedApprovalResult,\n TaskContextInput,\n TaskResult,\n ThreadUpdate,\n ThreadUpdateStatus,\n} from \"../schemas/index.js\";\n","import { z } from \"zod\";\nimport {\n isPublicHttpUrl,\n PUBLIC_HTTP_URL_ERROR,\n} from \"@robotrock/core/utils\";\nimport { validateContextPublicUrls } from \"@robotrock/core/schemas\";\n\nexport interface JSONSchema7 {\n $id?: string;\n $ref?: string;\n $schema?: string;\n $comment?: string;\n type?: JSONSchema7TypeName | JSONSchema7TypeName[];\n enum?: unknown[];\n const?: unknown;\n multipleOf?: number;\n maximum?: number;\n exclusiveMaximum?: number;\n minimum?: number;\n exclusiveMinimum?: number;\n maxLength?: number;\n minLength?: number;\n pattern?: string;\n format?: string;\n items?: JSONSchema7 | JSONSchema7[];\n additionalItems?: JSONSchema7 | boolean;\n maxItems?: number;\n minItems?: number;\n uniqueItems?: boolean;\n contains?: JSONSchema7;\n maxProperties?: number;\n minProperties?: number;\n required?: string[];\n properties?: Record<string, JSONSchema7>;\n patternProperties?: Record<string, JSONSchema7>;\n additionalProperties?: JSONSchema7 | boolean;\n dependencies?: Record<string, JSONSchema7 | string[]>;\n propertyNames?: JSONSchema7;\n if?: JSONSchema7;\n then?: JSONSchema7;\n else?: JSONSchema7;\n allOf?: JSONSchema7[];\n anyOf?: JSONSchema7[];\n oneOf?: JSONSchema7[];\n not?: JSONSchema7;\n title?: string;\n description?: string;\n default?: unknown;\n readOnly?: boolean;\n writeOnly?: boolean;\n examples?: unknown[];\n}\n\nexport type JSONSchema7TypeName =\n | \"string\"\n | \"number\"\n | \"integer\"\n | \"boolean\"\n | \"object\"\n | \"array\"\n | \"null\";\n\nexport type ExtendedJSONSchema7 = JSONSchema7 & {\n enumNames?: string[];\n [key: string]: unknown;\n};\n\nexport type UiSchema = {\n \"ui:widget\"?: string;\n \"ui:title\"?: string;\n \"ui:description\"?: string;\n \"ui:placeholder\"?: string;\n \"ui:options\"?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\nconst safeUrlSchema = z.string().refine((url) => isPublicHttpUrl(url), {\n message: PUBLIC_HTTP_URL_ERROR,\n});\n\nconst jsonSchema7Schema = z.custom<ExtendedJSONSchema7>(\n (val) => typeof val === \"object\" && val !== null,\n { message: \"Must be a valid JSON Schema object\" }\n);\n\nconst uiSchemaSchema = z.custom<UiSchema>((val) => typeof val === \"object\" && val !== null, {\n message: \"Must be a valid UiSchema object\",\n});\n\nconst webhookHandlerSchema = z.object({\n type: z.literal(\"webhook\"),\n url: safeUrlSchema,\n headers: z.record(z.string(), z.string()),\n});\n\nconst triggerHandlerSchema = webhookHandlerSchema.extend({\n type: z.literal(\"trigger\"),\n tokenId: z.string().min(1),\n});\n\nconst handlerSchema = z.discriminatedUnion(\"type\", [webhookHandlerSchema, triggerHandlerSchema]);\n\nconst taskActionSchema = z.object({\n id: z.string().min(1),\n title: z.string().min(1),\n description: z.string().optional(),\n schema: jsonSchema7Schema.optional(),\n ui: uiSchemaSchema.optional(),\n data: z.record(z.string(), z.unknown()).optional(),\n handlers: z.array(handlerSchema).min(1).optional(),\n});\n\nconst uiFieldSchemaSchema: z.ZodType<Record<string, unknown>> = z\n .object({\n \"ui:widget\": z.string().optional(),\n \"ui:title\": z.string().optional(),\n \"ui:description\": z.string().optional(),\n \"ui:options\": z.record(z.string(), z.unknown()).optional(),\n items: z.lazy(() => z.record(z.string(), uiFieldSchemaSchema)).optional(),\n })\n .passthrough();\n\nconst contextUiSchema = z.record(z.string(), uiFieldSchemaSchema).optional();\n\nconst contextDataSchema = z\n .object({\n data: z.record(z.string(), z.unknown()),\n ui: contextUiSchema,\n })\n .optional();\n\n/** Task context wire format version (always `2` today). */\nexport const TASK_CONTEXT_FORMAT_VERSION = 2 as const;\nexport type TaskContextFormatVersion = typeof TASK_CONTEXT_FORMAT_VERSION;\n\nconst taskContextObjectBaseSchema = z.object({\n app: z.string().min(1).optional(),\n type: z.string().min(1),\n name: z.string().min(1),\n description: z.string().optional(),\n validUntil: z.string().optional(),\n context: contextDataSchema,\n contextVersion: z.literal(2).optional(),\n /** @deprecated Use `contextVersion`. Accepted on ingest only. */\n version: z.literal(2).optional(),\n actions: z.array(taskActionSchema).min(1, \"At least one action is required\"),\n});\n\nfunction normalizeTaskContextVersion<T extends { contextVersion?: 2; version?: 2 }>(\n data: T\n): Omit<T, \"version\" | \"contextVersion\"> & { contextVersion: 2 } {\n const { version: legacyVersion, contextVersion, ...rest } = data;\n return {\n ...rest,\n contextVersion: contextVersion ?? legacyVersion ?? TASK_CONTEXT_FORMAT_VERSION,\n };\n}\n\nconst taskContextObjectSchema = taskContextObjectBaseSchema.transform(\n normalizeTaskContextVersion\n);\n\nfunction refineContextPublicUrls<T extends { context?: z.infer<typeof contextDataSchema> }>(\n data: T,\n ctx: z.RefinementCtx\n) {\n const error = validateContextPublicUrls(data.context);\n if (error) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: error,\n path: [\"context\"],\n });\n }\n}\n\nexport const taskContextSchema = taskContextObjectSchema.superRefine(\n refineContextPublicUrls\n);\n\n/**\n * Assignment targets at task create (not stored in task context JSON).\n * Unknown user emails are auto-provisioned as assignee memberships (count toward seat limits).\n */\nexport const assignToSchema = z\n .object({\n users: z.array(z.string().email()).optional(),\n groups: z.array(z.string().min(1)).optional(),\n })\n .refine(\n (data) => {\n const groups = data.groups ?? [];\n if (groups.includes(\"all\") && groups.length > 1) {\n return false;\n }\n return true;\n },\n { message: 'Cannot combine \"all\" with other group slugs' }\n );\n\n/** A short thread-scoped status update message (1-2 sentences). */\nexport const threadUpdateMessageSchema = z.string().min(1).max(500);\n\n/**\n * Lifecycle status carried by a thread update. Drives the icon and color shown\n * in the inbox status bar. Defaults to `info` when omitted.\n */\nexport const threadUpdateStatuses = [\n \"info\",\n \"queued\",\n \"running\",\n \"waiting\",\n \"succeeded\",\n \"failed\",\n \"cancelled\",\n] as const;\n\nexport const threadUpdateStatusSchema = z.enum(threadUpdateStatuses);\n\n/** The default status applied when an update omits one. */\nexport const DEFAULT_THREAD_UPDATE_STATUS: ThreadUpdateStatus = \"info\";\n\n/** Shared shape for a thread update (standalone and at task creation). */\nexport const threadUpdateInputSchema = z.object({\n message: threadUpdateMessageSchema,\n status: threadUpdateStatusSchema.optional(),\n});\n\n/** Thread priority levels for inbox ordering and display. */\nexport const taskPriorities = [\"low\", \"normal\", \"high\", \"urgent\"] as const;\n\nexport const taskPrioritySchema = z.enum(taskPriorities);\n\nexport type TaskPriority = (typeof taskPriorities)[number];\n\nexport const DEFAULT_TASK_PRIORITY: TaskPriority = \"normal\";\n\nexport const LOWEST_TASK_PRIORITY: TaskPriority = \"low\";\n\nexport const TASK_PRIORITY_RANK: Record<TaskPriority, number> = {\n low: 1,\n normal: 2,\n high: 3,\n urgent: 4,\n};\n\nexport const agentTelemetrySchema = z.object({\n version: z.string().min(1),\n});\n\nexport const createTaskBodySchema = taskContextObjectBaseSchema\n .extend({\n assignTo: assignToSchema.optional(),\n /**\n * Groups related tasks together. When omitted, the server generates one and\n * returns it so the caller can reuse it on later tasks in the same thread.\n */\n threadId: z.string().min(1).optional(),\n /**\n * Optional thread priority. When set, applies to the whole thread and\n * overwrites any previous priority. Omit on later tasks to leave unchanged.\n */\n priority: taskPrioritySchema.optional(),\n /**\n * Optional initial status update logged against the task's thread. Shows in\n * the inbox status bar and the thread update log.\n */\n update: threadUpdateInputSchema.optional(),\n agent: agentTelemetrySchema.optional(),\n })\n .transform(normalizeTaskContextVersion)\n .superRefine(refineContextPublicUrls);\n\n/** POST /v1/threads/:threadId/updates body: a standalone thread update. */\nexport const threadUpdateBodySchema = threadUpdateInputSchema;\n\n/** Where a thread update originated. */\nexport type ThreadUpdateSource = \"api\" | \"task_create\" | \"dashboard\";\n\n/** Lifecycle status carried by a thread update. */\nexport type ThreadUpdateStatus = (typeof threadUpdateStatuses)[number];\n\n/** A logged thread update as returned by the API. */\nexport interface ThreadUpdate {\n id: string;\n threadId: string;\n message: string;\n status: ThreadUpdateStatus;\n source: ThreadUpdateSource;\n createdAt: number;\n}\n\nexport type AssignToInput = z.infer<typeof assignToSchema>;\nexport type CreateTaskBodyInput = z.input<typeof createTaskBodySchema>;\nexport type CreateTaskBody = z.output<typeof createTaskBodySchema>;\nexport type ThreadUpdateBodyInput = z.input<typeof threadUpdateBodySchema>;\nexport type ThreadUpdateBody = z.output<typeof threadUpdateBodySchema>;\nexport type ThreadUpdateInput = z.input<typeof threadUpdateInputSchema>;\nexport type TaskContextInput = z.input<typeof taskContextSchema>;\nexport type TaskContextOutput = z.output<typeof taskContextSchema>;\nexport type TaskContext = TaskContextOutput;\nexport type TaskAction = z.infer<typeof taskActionSchema>;\nexport type WebhookHandler = z.infer<typeof webhookHandlerSchema>;\nexport type TriggerHandler = z.infer<typeof triggerHandlerSchema>;\nexport type Handler = z.infer<typeof handlerSchema>;\nexport type AgentTelemetry = z.infer<typeof agentTelemetrySchema>;\nexport type AgentTelemetryInput = z.input<typeof agentTelemetrySchema>;\n\ntype InferObjectProperties<\n Props,\n Req extends PropertyKey,\n> = Props extends Record<string, unknown>\n ? ({\n [K in keyof Props as K extends Req ? K : never]-?: InferJsonSchema7<Props[K]>;\n } & {\n [K in keyof Props as K extends Req ? never : K]?: InferJsonSchema7<Props[K]>;\n } extends infer O\n ? { [K in keyof O]: O[K] }\n : never)\n : Record<string, unknown>;\n\ntype RequiredKeys<S> =\n S extends { readonly required: readonly string[] } ? S[\"required\"][number] : never;\n\nexport type InferJsonSchema7<S> = [S] extends [undefined]\n ? Record<string, never>\n : S extends { readonly const: infer C }\n ? C\n : S extends {\n readonly enum: readonly (infer E)[];\n }\n ? E\n : S extends {\n readonly type: \"object\";\n readonly properties?: infer Props;\n }\n ? InferObjectProperties<Props, RequiredKeys<S>>\n : S extends {\n readonly type: \"object\";\n readonly properties?: undefined;\n }\n ? Record<string, unknown>\n : S extends {\n readonly type: \"array\";\n readonly items?: infer Items;\n }\n ? Items extends readonly unknown[]\n ? InferJsonSchema7<Items[number]>[]\n : Items extends object\n ? InferJsonSchema7<Items>[]\n : unknown[]\n : S extends { readonly type: \"string\" }\n ? string\n : S extends { readonly type: \"number\" } | { readonly type: \"integer\" }\n ? number\n : S extends { readonly type: \"boolean\" }\n ? boolean\n : unknown;\n\nexport type TaskStatus = \"pending\" | \"open\" | \"handled\" | \"expired\";\n\nexport interface TaskResponse {\n success: boolean;\n task: {\n taskId: string;\n threadId: string;\n status: \"pending\" | \"open\";\n context: TaskContext;\n validUntil: string;\n submittedAt: string;\n };\n message: string;\n}\n\nexport interface ThreadUpdateResponse {\n success: boolean;\n update: ThreadUpdate;\n message: string;\n}\n\nexport interface Task {\n id: string;\n threadId?: string;\n createdAt: Date;\n status: TaskStatus;\n context: TaskContext;\n validUntil: number;\n handledAt?: number;\n handled?: {\n action: {\n id: string;\n data: unknown;\n };\n handledBy?: string;\n userId?: string;\n token?: string;\n };\n}\n\nexport type InferActionData<T extends { schema?: unknown }> = [\n Exclude<T[\"schema\"], undefined>,\n] extends [\n never,\n]\n ? Record<string, never>\n : Exclude<T[\"schema\"], undefined> extends infer S\n ? InferJsonSchema7<S>\n : Record<string, never>;\n\nexport type TupleElementIndices<T extends readonly unknown[]> = T extends readonly [\n unknown,\n ...unknown[],\n]\n ? Exclude<keyof T, keyof unknown[]>\n : number;\n\nexport interface TaskResult<T = Record<string, unknown>> {\n actionId: string;\n data: T;\n handledBy?: string;\n handledAt: Date;\n}\n\nexport interface ApprovalResult<T = Record<string, unknown>> extends TaskResult<T> {\n taskId: string;\n}\n\nexport type DiscriminatedApprovalResult<\n TActions extends readonly { id: string; schema?: unknown }[],\n> = {\n [I in TupleElementIndices<TActions>]: TActions[I] extends { id: string; schema?: unknown }\n ? Omit<ApprovalResult<InferActionData<TActions[I]>>, \"actionId\" | \"data\"> & {\n actionId: TActions[I][\"id\"];\n data: InferActionData<TActions[I]>;\n }\n : never\n}[TupleElementIndices<TActions>];\n","const BLOCKED_HOSTNAMES = new Set([\n \"localhost\",\n \"metadata.google.internal\",\n \"metadata.goog\",\n]);\n\nfunction normalizeHostname(hostname: string): string {\n return hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n}\n\nfunction isBlockedIpv4(host: string): boolean {\n const match = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(host);\n if (!match) {\n return false;\n }\n\n const octets = match.slice(1, 5).map((part) => Number(part));\n if (octets.some((octet) => Number.isNaN(octet) || octet < 0 || octet > 255)) {\n return true;\n }\n\n const [a, b, _c, _d] = octets;\n if (a === undefined || b === undefined) {\n return true;\n }\n if (a === 127 || a === 0) return true;\n if (a === 10) return true;\n if (a === 169 && b === 254) return true;\n if (a === 192 && b === 168) return true;\n if (a === 172 && b >= 16 && b <= 31) return true;\n if (a === 100 && b >= 64 && b <= 127) return true;\n\n return false;\n}\n\nfunction ipv4FromNumericHost(host: string): string | null {\n if (/^\\d+$/.test(host)) {\n const num = Number(host);\n if (!Number.isFinite(num) || num < 0 || num > 0xffffffff) {\n return null;\n }\n const a = (num >>> 24) & 0xff;\n const b = (num >>> 16) & 0xff;\n const c = (num >>> 8) & 0xff;\n const d = num & 0xff;\n return `${a}.${b}.${c}.${d}`;\n }\n\n const hexMatch = /^0x([0-9a-f]{1,8})$/i.exec(host);\n if (hexMatch) {\n const num = Number.parseInt(hexMatch[1]!, 16);\n if (!Number.isFinite(num) || num < 0 || num > 0xffffffff) {\n return null;\n }\n const a = (num >>> 24) & 0xff;\n const b = (num >>> 16) & 0xff;\n const c = (num >>> 8) & 0xff;\n const d = num & 0xff;\n return `${a}.${b}.${c}.${d}`;\n }\n\n return null;\n}\n\nfunction isBlockedIpv4Mapped(host: string): boolean {\n const mappedDotted = /^::ffff:(\\d{1,3}(?:\\.\\d{1,3}){3})$/i.exec(host);\n if (mappedDotted) {\n return isBlockedIpv4(mappedDotted[1]!);\n }\n\n const mappedHex = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i.exec(host);\n if (mappedHex) {\n const high = Number.parseInt(mappedHex[1]!, 16);\n const low = Number.parseInt(mappedHex[2]!, 16);\n if (Number.isFinite(high) && Number.isFinite(low)) {\n const a = (high >> 8) & 0xff;\n const b = high & 0xff;\n const c = (low >> 8) & 0xff;\n const d = low & 0xff;\n return isBlockedIpv4(`${a}.${b}.${c}.${d}`);\n }\n }\n\n return false;\n}\n\nfunction isBlockedIpv6(host: string): boolean {\n if (host === \"::1\" || host === \"0:0:0:0:0:0:0:1\") {\n return true;\n }\n if (host.startsWith(\"fc\") || host.startsWith(\"fd\")) {\n return true;\n }\n if (host.startsWith(\"fe80:\")) {\n return true;\n }\n if (isBlockedIpv4Mapped(host)) {\n return true;\n }\n return false;\n}\n\nfunction isBlockedHostname(hostname: string): boolean {\n const host = normalizeHostname(hostname);\n if (!host) {\n return true;\n }\n if (BLOCKED_HOSTNAMES.has(host)) {\n return true;\n }\n if (host.endsWith(\".localhost\") || host.endsWith(\".local\")) {\n return true;\n }\n\n const numericIpv4 = ipv4FromNumericHost(host);\n if (numericIpv4 && isBlockedIpv4(numericIpv4)) {\n return true;\n }\n\n return isBlockedIpv4(host) || isBlockedIpv6(host);\n}\n\n/**\n * Returns true when the URL uses http(s) and targets a public, non-reserved host.\n */\nexport function isPublicHttpUrl(urlString: string): boolean {\n let url: URL;\n try {\n url = new URL(urlString);\n } catch {\n return false;\n }\n\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n return false;\n }\n if (url.username || url.password) {\n return false;\n }\n\n return !isBlockedHostname(url.hostname);\n}\n\nexport const PUBLIC_HTTP_URL_ERROR =\n \"URL must be a public http:// or https:// address\";\n\nconst FORBIDDEN_HANDLER_HEADERS = new Set([\n \"host\",\n \"connection\",\n \"content-length\",\n \"transfer-encoding\",\n \"te\",\n \"trailer\",\n \"upgrade\",\n \"proxy-authorization\",\n \"proxy-connection\",\n \"keep-alive\",\n \"x-robotrock-signature\",\n \"x-robotrock-delivery-id\",\n \"x-robotrock-delivery-attempt\",\n]);\n\n/**\n * Allow only safe custom webhook headers; blocks overrides of delivery metadata.\n */\nexport function filterHandlerHeaders(\n headers: Record<string, string> | undefined\n): Record<string, string> {\n if (!headers) {\n return {};\n }\n\n const filtered: Record<string, string> = {};\n for (const [rawKey, value] of Object.entries(headers)) {\n const key = rawKey.toLowerCase().trim();\n if (!key || FORBIDDEN_HANDLER_HEADERS.has(key)) {\n continue;\n }\n if (!/^[a-z0-9][a-z0-9._-]*$/.test(key)) {\n continue;\n }\n filtered[key] = value;\n }\n return filtered;\n}\n","import { z } from \"zod\";\nimport { isPublicHttpUrl, PUBLIC_HTTP_URL_ERROR } from \"../utils/safe-url\";\nimport { validateContextPublicUrls } from \"./context-urls\";\nimport type { JSONSchema7 } from \"./json-schema\";\n\n/**\n * Extended JSONSchema7 type that includes RJSF extensions like enumNames\n */\nexport type ExtendedJSONSchema7 = JSONSchema7 & {\n enumNames?: string[];\n [key: string]: unknown;\n};\n\n/**\n * UI Schema for RJSF form customization\n */\nexport type UiSchema = {\n \"ui:widget\"?: string;\n \"ui:title\"?: string;\n \"ui:description\"?: string;\n \"ui:placeholder\"?: string;\n \"ui:options\"?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\n// Helper schemas\nconst safeUrlSchema = z.string().refine((url) => isPublicHttpUrl(url), {\n message: PUBLIC_HTTP_URL_ERROR,\n});\n\n// JSONSchema7 validation\nconst jsonSchema7Schema = z.custom<ExtendedJSONSchema7>(\n (val) => typeof val === \"object\" && val !== null,\n { message: \"Must be a valid JSON Schema object\" }\n);\n\n// UiSchema validation\nconst uiSchemaSchema = z.custom<UiSchema>((val) => typeof val === \"object\" && val !== null, {\n message: \"Must be a valid UiSchema object\",\n});\n\n// Handler schemas (per-action handlers for webhooks, triggers, etc.)\nconst webhookHandlerSchema = z.object({\n type: z.literal(\"webhook\"),\n url: safeUrlSchema,\n headers: z.record(z.string(), z.string()),\n});\n\nconst triggerHandlerSchema = webhookHandlerSchema.extend({\n type: z.literal(\"trigger\"),\n tokenId: z.string().min(1),\n});\n\nconst handlerSchema = z.discriminatedUnion(\"type\", [webhookHandlerSchema, triggerHandlerSchema]);\n\n// Action schema with JSONSchema-based feedback and optional handlers\nconst taskActionSchema = z.object({\n id: z.string().min(1),\n title: z.string().min(1),\n description: z.string().optional(),\n schema: jsonSchema7Schema.optional(),\n ui: uiSchemaSchema.optional(),\n data: z.record(z.string(), z.unknown()).optional(),\n // Optional handlers for this action - if present, must have at least 1\n handlers: z.array(handlerSchema).min(1).optional(),\n});\n\n// UI Field Schema\nconst uiFieldSchemaSchema: z.ZodType<Record<string, unknown>> = z\n .object({\n \"ui:widget\": z.string().optional(),\n \"ui:title\": z.string().optional(),\n \"ui:description\": z.string().optional(),\n \"ui:options\": z.record(z.string(), z.unknown()).optional(),\n items: z.lazy(() => z.record(z.string(), uiFieldSchemaSchema)).optional(),\n })\n .passthrough();\n\n// Context UI Schema\nconst contextUiSchema = z.record(z.string(), uiFieldSchemaSchema).optional();\n\n// Context data schema\nconst contextDataSchema = z\n .object({\n data: z.record(z.string(), z.unknown()),\n ui: contextUiSchema,\n })\n .optional();\n\nexport const TASK_CONTEXT_FORMAT_VERSION = 2 as const;\nexport type TaskContextFormatVersion = typeof TASK_CONTEXT_FORMAT_VERSION;\n\n// Main TaskContext schema\nconst taskContextObjectBaseSchema = z.object({\n /** Source application id; omitted tasks are grouped in the default inbox. */\n app: z.string().min(1).optional(),\n type: z.string().min(1),\n name: z.string().min(1),\n description: z.string().optional(),\n validUntil: z.string().optional(),\n context: contextDataSchema,\n /** Task context wire format version. @default 2 */\n contextVersion: z.literal(2).optional(),\n /** @deprecated Use `contextVersion`. Accepted on ingest only. */\n version: z.literal(2).optional(),\n actions: z.array(taskActionSchema).min(1, \"At least one action is required\"),\n});\n\nfunction normalizeTaskContextVersion<T extends { contextVersion?: 2; version?: 2 }>(\n data: T\n): Omit<T, \"version\" | \"contextVersion\"> & { contextVersion: 2 } {\n const { version: legacyVersion, contextVersion, ...rest } = data;\n return {\n ...rest,\n contextVersion: contextVersion ?? legacyVersion ?? TASK_CONTEXT_FORMAT_VERSION,\n };\n}\n\nconst taskContextObjectSchema = taskContextObjectBaseSchema.transform(\n normalizeTaskContextVersion\n);\n\nfunction refineContextPublicUrls<T extends { context?: z.infer<typeof contextDataSchema> }>(\n data: T,\n ctx: z.RefinementCtx\n) {\n const error = validateContextPublicUrls(data.context);\n if (error) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: error,\n path: [\"context\"],\n });\n }\n}\n\nexport const taskContextSchema = taskContextObjectSchema.superRefine(\n refineContextPublicUrls\n);\n\n/**\n * Assignment targets at task create (not stored in task context JSON).\n * Unknown user emails are auto-provisioned as assignee memberships (count toward seat limits).\n */\nexport const assignToSchema = z\n .object({\n users: z.array(z.string().email()).optional(),\n groups: z.array(z.string().min(1)).optional(),\n })\n .refine(\n (data) => {\n const groups = data.groups ?? [];\n if (groups.includes(\"all\") && groups.length > 1) {\n return false;\n }\n return true;\n },\n { message: 'Cannot combine \"all\" with other group slugs' }\n );\n\n/** A short thread-scoped status update message (1-2 sentences). */\nexport const threadUpdateMessageSchema = z.string().min(1).max(500);\n\n/**\n * Lifecycle status carried by a thread update. Drives the icon and color shown\n * in the inbox status bar. Defaults to `info` when omitted.\n */\nexport const threadUpdateStatuses = [\n \"info\",\n \"queued\",\n \"running\",\n \"waiting\",\n \"succeeded\",\n \"failed\",\n \"cancelled\",\n] as const;\n\nexport const threadUpdateStatusSchema = z.enum(threadUpdateStatuses);\n\n/** The default status applied when an update omits one. */\nexport const DEFAULT_THREAD_UPDATE_STATUS: ThreadUpdateStatus = \"info\";\n\n/** Shared shape for a thread update (standalone and at task creation). */\nexport const threadUpdateInputSchema = z.object({\n message: threadUpdateMessageSchema,\n status: threadUpdateStatusSchema.optional(),\n});\n\n/** Thread priority levels for inbox ordering and display. */\nexport const taskPriorities = [\"low\", \"normal\", \"high\", \"urgent\"] as const;\n\nexport const taskPrioritySchema = z.enum(taskPriorities);\n\nexport type TaskPriority = (typeof taskPriorities)[number];\n\nexport const DEFAULT_TASK_PRIORITY: TaskPriority = \"normal\";\n\nexport const LOWEST_TASK_PRIORITY: TaskPriority = \"low\";\n\nexport const TASK_PRIORITY_RANK: Record<TaskPriority, number> = {\n low: 1,\n normal: 2,\n high: 3,\n urgent: 4,\n};\n\n/**\n * Agent release at task create (not shown in inbox reviewer UI).\n * Used for feedback analysis over deploys.\n */\nexport const agentTelemetrySchema = z.object({\n /** Agent or app version (semver, git SHA, deploy tag — caller-defined). */\n version: z.string().min(1),\n});\n\n/** POST /v1 body: task context plus optional assignment. */\nexport const createTaskBodySchema = taskContextObjectBaseSchema\n .extend({\n assignTo: assignToSchema.optional(),\n /**\n * Groups related tasks together. When omitted, the server generates one and\n * returns it so the caller can reuse it on later tasks in the same thread.\n */\n threadId: z.string().min(1).optional(),\n /**\n * Optional thread priority. When set, applies to the whole thread and\n * overwrites any previous priority. Omit on later tasks to leave unchanged.\n */\n priority: taskPrioritySchema.optional(),\n /**\n * Optional initial status update logged against the task's thread. Shows in\n * the inbox status bar and the thread update log.\n */\n update: threadUpdateInputSchema.optional(),\n /** Agent release version — not shown in inbox UI. */\n agent: agentTelemetrySchema.optional(),\n })\n .transform(normalizeTaskContextVersion)\n .superRefine(refineContextPublicUrls);\n\n/** POST /v1/threads/:threadId/updates body: a standalone thread update. */\nexport const threadUpdateBodySchema = threadUpdateInputSchema;\n\n/** Where a thread update originated. */\nexport type ThreadUpdateSource = \"api\" | \"task_create\" | \"dashboard\";\n\n/** Lifecycle status carried by a thread update. */\nexport type ThreadUpdateStatus = (typeof threadUpdateStatuses)[number];\n\n/** A logged thread update as returned by the API. */\nexport interface ThreadUpdate {\n id: string;\n threadId: string;\n message: string;\n status: ThreadUpdateStatus;\n source: ThreadUpdateSource;\n createdAt: number;\n}\n\n// Type exports\nexport type AssignToInput = z.infer<typeof assignToSchema>;\nexport type CreateTaskBodyInput = z.input<typeof createTaskBodySchema>;\nexport type CreateTaskBody = z.output<typeof createTaskBodySchema>;\nexport type ThreadUpdateBodyInput = z.input<typeof threadUpdateBodySchema>;\nexport type ThreadUpdateBody = z.output<typeof threadUpdateBodySchema>;\nexport type ThreadUpdateInput = z.input<typeof threadUpdateInputSchema>;\nexport type TaskContextInput = z.input<typeof taskContextSchema>;\nexport type TaskContextOutput = z.output<typeof taskContextSchema>;\nexport type TaskContext = TaskContextOutput;\nexport type SafeUrl = z.infer<typeof safeUrlSchema>;\nexport type TaskAction = z.infer<typeof taskActionSchema>;\nexport type WebhookHandler = z.infer<typeof webhookHandlerSchema>;\nexport type TriggerHandler = z.infer<typeof triggerHandlerSchema>;\nexport type Handler = z.infer<typeof handlerSchema>;\nexport type ContextData = z.infer<typeof contextDataSchema>;\nexport type ContextUiSchema = z.infer<typeof contextUiSchema>;\nexport type UiFieldSchema = z.infer<typeof uiFieldSchemaSchema>;\nexport type AgentTelemetry = z.infer<typeof agentTelemetrySchema>;\nexport type AgentTelemetryInput = z.input<typeof agentTelemetrySchema>;\n","import { isPublicHttpUrl, PUBLIC_HTTP_URL_ERROR } from \"../utils/safe-url\";\n\ntype ContextInput = {\n data?: Record<string, unknown>;\n ui?: Record<string, unknown>;\n};\n\nfunction resolveLinkUrl(value: string): string {\n return value.startsWith(\"http://\") || value.startsWith(\"https://\")\n ? value\n : `https://${value}`;\n}\n\nfunction widgetType(\n ui: Record<string, unknown> | undefined,\n field: string\n): string | undefined {\n const fieldUi = ui?.[field];\n if (typeof fieldUi !== \"object\" || fieldUi === null) {\n return undefined;\n }\n const widget = (fieldUi as Record<string, unknown>)[\"ui:widget\"];\n return typeof widget === \"string\" ? widget : undefined;\n}\n\nfunction validateUrlValue(value: unknown, widget: string): string | null {\n if (widget === \"image\" || widget === \"link\") {\n if (typeof value !== \"string\") {\n return PUBLIC_HTTP_URL_ERROR;\n }\n const url = widget === \"link\" ? resolveLinkUrl(value) : value;\n if (!isPublicHttpUrl(url)) {\n return PUBLIC_HTTP_URL_ERROR;\n }\n return null;\n }\n\n if (widget === \"attachments\" && Array.isArray(value)) {\n for (const item of value) {\n if (typeof item !== \"object\" || item === null) {\n continue;\n }\n const url = (item as { url?: unknown }).url;\n if (typeof url === \"string\" && !isPublicHttpUrl(resolveLinkUrl(url))) {\n return PUBLIC_HTTP_URL_ERROR;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Validates URL-bearing context widget values (image, link, attachments).\n * Returns an error message or null when valid.\n */\nexport function validateContextPublicUrls(\n context: ContextInput | undefined\n): string | null {\n if (!context?.data) {\n return null;\n }\n\n for (const [field, value] of Object.entries(context.data)) {\n const widget = widgetType(context.ui, field);\n if (!widget) {\n continue;\n }\n const error = validateUrlValue(value, widget);\n if (error) {\n return `context.data.${field}: ${error}`;\n }\n }\n\n return null;\n}\n","import type { DiscriminatedApprovalResult, Task } from \"./schemas/index.js\";\n\nexport class TaskTimeoutError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TaskTimeoutError\";\n }\n}\n\nexport class TaskExpiredError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TaskExpiredError\";\n }\n}\n\n/**\n * Map a handled API task to a discriminated approval result.\n * Runtime validation is minimal; TypeScript narrows via `task.actions` at the call site.\n */\nexport function toDiscriminatedApprovalResult<A extends readonly { id: string; schema?: unknown }[]>(\n actions: A,\n task: Task\n): DiscriminatedApprovalResult<A> {\n void actions;\n\n if (!task.handled) {\n throw new Error(\"Task has no handled result\");\n }\n\n return {\n actionId: task.handled.action.id,\n data: task.handled.action.data,\n handledBy: task.handled.handledBy,\n handledAt: new Date(task.handledAt ?? Date.now()),\n taskId: task.id,\n } as DiscriminatedApprovalResult<A>;\n}\n","import {\n type AssignToInput,\n type TaskContextInput,\n createTaskBodySchema,\n threadUpdateBodySchema,\n TASK_CONTEXT_FORMAT_VERSION,\n} from \"./schemas/index.js\";\nimport {\n TaskExpiredError,\n TaskTimeoutError,\n toDiscriminatedApprovalResult,\n} from \"./approval-result.js\";\nimport type {\n DiscriminatedApprovalResult,\n Task,\n TaskPriority,\n TaskResponse,\n ThreadUpdate,\n ThreadUpdateResponse,\n ThreadUpdateStatus,\n TaskContextFormatVersion,\n} from \"./schemas/index.js\";\n\nexport type RobotRockWebhookConfig = {\n url: string;\n headers?: Record<string, string>;\n};\n\nexport interface RobotRockPollingOptions {\n /** Poll interval when no webhook is configured (ms). @default 2000 */\n intervalMs?: number;\n /**\n * Max time to poll when no webhook is configured (ms).\n * Polling also stops when the task's `validUntil` passes, whichever is sooner.\n * @default 86400000 (24h)\n */\n timeoutMs?: number;\n};\n\n/** Advanced client settings rarely changed by integrators. */\nexport type RobotRockAdvancedConfig = {\n /** Task context wire format version sent on every request. @default 2 */\n contextVersion?: TaskContextFormatVersion;\n};\n\ntype RobotRockClientBaseConfig = {\n /** Optional override for API key. Falls back to ROBOTROCK_API_KEY. */\n apiKey?: string;\n /**\n * Base URL for the RobotRock API\n * @default \"https://api.robotrock.io/v1\"\n */\n baseUrl?: string;\n /**\n * Default inbox app bucket for every task from this client.\n * When omitted, the API uses your API key name.\n */\n app?: string;\n /**\n * Agent release version (semver, git SHA, deploy tag).\n * Defaults to `AGENT_VERSION` or `ROBOTROCK_AGENT_VERSION` from env when omitted.\n */\n version?: string;\n /** Advanced settings (context wire format, etc.). */\n advanced?: RobotRockAdvancedConfig;\n};\n\n/** Client config with a webhook (mutually exclusive with `polling`). */\nexport type RobotRockWebhookClientConfig = RobotRockClientBaseConfig & {\n webhook: RobotRockWebhookConfig;\n polling?: never;\n};\n\n/** Client config without a webhook; optional `polling` controls the wait loop. */\nexport type RobotRockPollingClientConfig = RobotRockClientBaseConfig & {\n webhook?: never;\n polling?: RobotRockPollingOptions;\n};\n\nexport type RobotRockConfig = RobotRockWebhookClientConfig | RobotRockPollingClientConfig;\n\nexport type SendToHumanActionInput = Omit<TaskContextInput[\"actions\"][number], \"handlers\">;\n\nexport type SendToHumanValidUntil = Date | string;\n\nexport type SendToHumanInput<\n A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[],\n> = Omit<TaskContextInput, \"app\" | \"actions\" | \"contextVersion\" | \"version\" | \"validUntil\"> & {\n actions: A;\n /** Task deadline; serialized to an ISO 8601 string on the wire. */\n validUntil?: SendToHumanValidUntil;\n /** Optional idempotency key to prevent duplicate tasks */\n idempotencyKey?: string;\n /** Assign to tenant users (email) and/or groups (slug). Narrows inbox visibility. */\n assignTo?: AssignToInput;\n /**\n * Groups related tasks together in the inbox. Omit to let the server generate\n * one (returned as `task.threadId`) and reuse it on later tasks in the thread.\n */\n threadId?: string;\n /**\n * Optional thread priority. When set, applies to the whole thread and\n * overwrites any previous priority. Omit on later tasks to leave unchanged.\n */\n priority?: TaskPriority;\n /**\n * Optional initial status update logged against the task's thread. Shows in\n * the inbox status bar and the thread update log.\n */\n update?: {\n /** A short status update (1-2 sentences). */\n message: string;\n /** Lifecycle status for the icon/color in the status bar. @default \"info\" */\n status?: ThreadUpdateStatus;\n };\n /**\n * Agent release version override. When omitted, uses the client `version`.\n * Used for statistics and feedback analysis.\n */\n version?: string;\n};\n\ntype SendToHumanWithAppInput<\n A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[],\n> = (SendToHumanInput<A> | Readonly<SendToHumanInput<A>>) & {\n /** Inbox app bucket. Overrides the client `app` when set. */\n app?: string;\n};\n\nexport type SendUpdateInput = {\n /** The thread to log the update against (from `task.threadId`). */\n threadId: string;\n /** A short status update (1-2 sentences). */\n message: string;\n /** Lifecycle status for the icon/color in the status bar. @default \"info\" */\n status?: ThreadUpdateStatus;\n};\n\nexport type SendToHumanResult<\n A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[],\n> =\n | {\n mode: \"created\";\n task: TaskResponse[\"task\"];\n }\n | ({\n mode: \"handled\";\n task: TaskResponse[\"task\"];\n } & DiscriminatedApprovalResult<A>);\n\nconst DEFAULT_POLL_INTERVAL_MS = 2_000;\nconst DEFAULT_TIMEOUT_MS = 24 * 60 * 60 * 1_000;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction resolveAgentVersionFromEnv(): string | undefined {\n const fromEnv =\n process.env.AGENT_VERSION?.trim() || process.env.ROBOTROCK_AGENT_VERSION?.trim();\n return fromEnv || undefined;\n}\n\nfunction parseValidUntilMs(value: string | number | Date | undefined): number | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n if (value instanceof Date) {\n const ms = value.getTime();\n return Number.isNaN(ms) ? undefined : ms;\n }\n\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value : undefined;\n }\n\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? undefined : parsed;\n}\n\nfunction serializeValidUntil(value: SendToHumanValidUntil): string {\n if (value instanceof Date) {\n const ms = value.getTime();\n if (Number.isNaN(ms)) {\n throw new RobotRockError(\"Invalid validUntil: Date is invalid\", 400);\n }\n return value.toISOString();\n }\n\n if (typeof value === \"string\" && !Number.isNaN(Date.parse(value))) {\n return new Date(value).toISOString();\n }\n\n throw new RobotRockError(\"Invalid validUntil: expected a Date or parseable date string\", 400);\n}\n\nexport class RobotRockError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly response?: unknown\n ) {\n super(message);\n this.name = \"RobotRockError\";\n }\n}\n\n/**\n * RobotRock API client for creating and querying human-in-the-loop tasks.\n */\nexport class RobotRock {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly app?: string;\n private readonly agentVersion?: string;\n private readonly contextVersion: TaskContextFormatVersion;\n private readonly webhook?: RobotRockWebhookConfig;\n private readonly polling: RobotRockPollingOptions;\n\n constructor(config: RobotRockConfig) {\n if (config.webhook && config.polling) {\n throw new Error(\n \"RobotRock client cannot configure both webhook and polling. Use webhook for callbacks or polling to block until handled.\"\n );\n }\n\n const apiKey = config.apiKey ?? process.env.ROBOTROCK_API_KEY;\n if (!apiKey) {\n throw new Error(\n \"RobotRock API key is required. Set ROBOTROCK_API_KEY or pass apiKey when creating the client.\"\n );\n }\n this.apiKey = apiKey;\n const rawBase = config.baseUrl ?? \"https://api.robotrock.io/v1\";\n this.baseUrl = rawBase.replace(/\\/+$/, \"\");\n this.app = config.app;\n this.agentVersion = config.version ?? resolveAgentVersionFromEnv();\n this.contextVersion =\n config.advanced?.contextVersion ?? TASK_CONTEXT_FORMAT_VERSION;\n this.webhook = config.webhook;\n this.polling = config.polling ?? {};\n }\n\n /**\n * Create a task via POST /v1 without waiting for a human response.\n */\n async createTask<const A extends readonly SendToHumanActionInput[]>(\n task: SendToHumanWithAppInput<A>\n ): Promise<TaskResponse[\"task\"]> {\n const normalizedTask = normalizeSendToHumanInput(task, {\n webhook: this.webhook,\n app: this.app,\n contextVersion: this.contextVersion,\n agentVersion: this.agentVersion,\n });\n const agentVersion = task.version ?? this.agentVersion;\n const bodyPayload = {\n ...normalizedTask,\n ...(task.assignTo !== undefined ? { assignTo: task.assignTo } : {}),\n ...(task.threadId !== undefined ? { threadId: task.threadId } : {}),\n ...(task.priority !== undefined ? { priority: task.priority } : {}),\n ...(task.update !== undefined ? { update: task.update } : {}),\n ...(agentVersion !== undefined ? { agent: { version: agentVersion } } : {}),\n };\n const validation = createTaskBodySchema.safeParse(bodyPayload);\n if (!validation.success) {\n throw new RobotRockError(\n `Invalid task: ${validation.error.issues[0]?.message}`,\n 400,\n validation.error.issues\n );\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"X-Api-Key\": this.apiKey,\n };\n\n if (task.idempotencyKey) {\n headers[\"Idempotency-Key\"] = task.idempotencyKey;\n }\n\n const response = await fetch(`${this.baseUrl}/`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(validation.data),\n });\n\n const data = await parseResponseBody(response);\n\n if (!response.ok) {\n throw new RobotRockError(\n getErrorMessage(data, \"Failed to create task\"),\n response.status,\n data\n );\n }\n\n return (data as unknown as TaskResponse).task;\n }\n\n async sendToHuman<const A extends readonly SendToHumanActionInput[]>(\n task: SendToHumanWithAppInput<A>\n ): Promise<SendToHumanResult<A>> {\n const normalizedTask = normalizeSendToHumanInput(task, {\n webhook: this.webhook,\n app: this.app,\n contextVersion: this.contextVersion,\n agentVersion: this.agentVersion,\n });\n const createdTaskTask = await this.createTask(task);\n const hasHandlers = normalizedTask.actions.some(\n (action) => Array.isArray(action.handlers) && action.handlers.length > 0\n );\n\n if (hasHandlers) {\n return {\n mode: \"created\",\n task: createdTaskTask,\n };\n }\n\n const timeoutMs = this.polling.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const pollIntervalMs = this.polling.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;\n const pollingDeadline = Date.now() + timeoutMs;\n const validUntilMs = parseValidUntilMs(createdTaskTask.validUntil);\n const deadline =\n validUntilMs !== undefined ? Math.min(pollingDeadline, validUntilMs) : pollingDeadline;\n const taskId = createdTaskTask.taskId;\n\n while (Date.now() < deadline) {\n const existing = await this.getTask(taskId);\n\n if (existing?.status === \"handled\" && existing.handled) {\n return {\n mode: \"handled\",\n task: createdTaskTask,\n ...(toDiscriminatedApprovalResult(\n normalizedTask.actions as unknown as A,\n existing\n ) as DiscriminatedApprovalResult<A>),\n };\n }\n\n if (existing?.status === \"expired\" || (existing && Date.now() >= existing.validUntil)) {\n throw new TaskExpiredError(\"Task reached validUntil before a human completed it\");\n }\n\n const remainingMs = deadline - Date.now();\n await sleep(Math.min(pollIntervalMs, Math.max(0, remainingMs)));\n }\n\n if (validUntilMs !== undefined && Date.now() >= validUntilMs) {\n throw new TaskExpiredError(\"Task reached validUntil before a human completed it\");\n }\n\n throw new TaskTimeoutError(`No human response within ${timeoutMs}ms`);\n }\n\n /**\n * Get a task by public task id (returned as `task.taskId` from {@link sendToHuman}).\n */\n async getTask(taskId: string): Promise<Task | null> {\n const response = await fetch(`${this.baseUrl}/tasks/${taskId}`, {\n method: \"GET\",\n headers: {\n \"X-Api-Key\": this.apiKey,\n },\n });\n\n if (response.status === 404) {\n return null;\n }\n\n const data = await parseResponseBody(response);\n\n if (!response.ok) {\n throw new RobotRockError(\n getErrorMessage(data, \"Failed to get task\"),\n response.status,\n data\n );\n }\n\n return data as unknown as Task;\n }\n\n /**\n * Log a status update against a thread. The update shows in the inbox status\n * bar and thread update log for every task in the thread.\n */\n async sendUpdate({ threadId, message, status }: SendUpdateInput): Promise<ThreadUpdate> {\n if (!threadId) {\n throw new RobotRockError(\"threadId is required to send an update\", 400);\n }\n\n const validation = threadUpdateBodySchema.safeParse({ message, status });\n if (!validation.success) {\n throw new RobotRockError(\n `Invalid update: ${validation.error.issues[0]?.message}`,\n 400,\n validation.error.issues\n );\n }\n\n const response = await fetch(\n `${this.baseUrl}/threads/${encodeURIComponent(threadId)}/updates`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Api-Key\": this.apiKey,\n },\n body: JSON.stringify(validation.data),\n }\n );\n\n const data = await parseResponseBody(response);\n\n if (!response.ok) {\n throw new RobotRockError(\n getErrorMessage(data, \"Failed to send update\"),\n response.status,\n data\n );\n }\n\n return (data as unknown as ThreadUpdateResponse).update;\n }\n\n async cancelTask(taskId: string): Promise<void> {\n const response = await fetch(`${this.baseUrl}/tasks/${taskId}/cancel`, {\n method: \"POST\",\n headers: {\n \"X-Api-Key\": this.apiKey,\n },\n });\n\n if (!response.ok) {\n const data = await parseResponseBody(response);\n throw new RobotRockError(\n getErrorMessage(data, \"Failed to cancel task\"),\n response.status,\n data\n );\n }\n }\n}\n\nexport function createClient(config: RobotRockConfig): RobotRock {\n return new RobotRock(config);\n}\n\nexport function attachWebhookToActions(\n actions: readonly SendToHumanActionInput[],\n webhook: RobotRockWebhookConfig\n): TaskContextInput[\"actions\"] {\n return actions.map((action) => ({\n ...action,\n handlers: webhookToHandlers(webhook),\n }));\n}\n\nfunction webhookToHandlers(\n webhook: RobotRockWebhookConfig\n): TaskContextInput[\"actions\"][number][\"handlers\"] {\n return [\n {\n type: \"webhook\" as const,\n url: webhook.url,\n headers: webhook.headers ?? {},\n },\n ];\n}\n\nfunction normalizeSendToHumanInput<\n A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[],\n>(\n task: SendToHumanWithAppInput<A>,\n clientDefaults: {\n webhook?: RobotRockWebhookConfig;\n app?: string;\n contextVersion: TaskContextFormatVersion;\n agentVersion?: string;\n }\n): TaskContextInput {\n const {\n actions,\n idempotencyKey: _idempotencyKey,\n assignTo: _assignTo,\n threadId: _threadId,\n priority: _priority,\n update: _update,\n version: _version,\n validUntil,\n app: taskApp,\n ...rest\n } = task;\n\n const webhook = clientDefaults.webhook;\n const normalizedActions: TaskContextInput[\"actions\"] = webhook\n ? attachWebhookToActions(actions, webhook)\n : (actions as unknown as TaskContextInput[\"actions\"]);\n\n const app = taskApp ?? clientDefaults.app;\n\n return {\n ...rest,\n contextVersion: clientDefaults.contextVersion,\n ...(app ? { app } : {}),\n ...(validUntil !== undefined ? { validUntil: serializeValidUntil(validUntil) } : {}),\n actions: normalizedActions,\n };\n}\n\ntype ParsedResponseBody = Record<string, unknown> | unknown[] | string | null;\n\nasync function parseResponseBody(response: Response): Promise<ParsedResponseBody> {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n const bodyText = await response.text();\n\n if (!bodyText) {\n return null;\n }\n\n if (contentType.toLowerCase().includes(\"application/json\")) {\n try {\n return JSON.parse(bodyText) as ParsedResponseBody;\n } catch {\n // Fall through and return text body below so error messages stay useful.\n }\n }\n\n try {\n return JSON.parse(bodyText) as ParsedResponseBody;\n } catch {\n return bodyText;\n }\n}\n\nfunction getErrorMessage(data: ParsedResponseBody, fallback: string): string {\n if (data && typeof data === \"object\" && !Array.isArray(data)) {\n const maybeMessage = (data as Record<string, unknown>).message;\n if (typeof maybeMessage === \"string\" && maybeMessage.trim()) {\n return maybeMessage;\n }\n }\n\n if (typeof data === \"string\" && data.trim()) {\n const compact = data.replace(/\\s+/g, \" \").trim();\n const snippet = compact.length > 180 ? `${compact.slice(0, 180)}...` : compact;\n return `${fallback}. Server returned non-JSON response: ${snippet}`;\n }\n\n return fallback;\n}\n","import { createClient, type RobotRock, type RobotRockConfig } from \"./client.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.robotrock.io/v1\";\n\n/**\n * Read RobotRock client config from environment variables.\n *\n * - `ROBOTROCK_API_KEY` (required when not passed explicitly)\n * - `ROBOTROCK_BASE_URL` or `ROBOTROCK_API_URL` (optional)\n * - `ROBOTROCK_APP` (optional inbox app bucket)\n */\nexport function resolveRobotRockConfig(\n overrides?: Partial<RobotRockConfig>\n): RobotRockConfig {\n const apiKey = overrides?.apiKey ?? process.env.ROBOTROCK_API_KEY;\n if (!apiKey) {\n throw new Error(\n \"RobotRock API key is required. Set ROBOTROCK_API_KEY or pass apiKey when creating the client.\"\n );\n }\n\n const baseUrl =\n overrides?.baseUrl ??\n process.env.ROBOTROCK_BASE_URL ??\n process.env.ROBOTROCK_API_URL ??\n DEFAULT_BASE_URL;\n\n const app = overrides?.app ?? process.env.ROBOTROCK_APP;\n\n return app ? { apiKey, baseUrl, app } : { apiKey, baseUrl };\n}\n\n/** Use an explicit client or create one from env / optional config overrides. */\nexport function resolveRobotRockClient(\n client?: RobotRock,\n configOverrides?: Partial<RobotRockConfig>\n): RobotRock {\n if (client) {\n return client;\n }\n return createClient(resolveRobotRockConfig(configOverrides));\n}\n","/**\n * JSON body posted when a RobotRock action handler runs (webhook or Trigger wait token).\n */\nexport interface RobotRockHandlerWebhookPayload {\n taskId: string;\n action: {\n id: string;\n title: string;\n data: unknown;\n };\n handledBy?: string;\n handledAt: string;\n handlerType: string;\n}\n\nexport function isRobotRockHandlerWebhookPayload(\n value: unknown\n): value is RobotRockHandlerWebhookPayload {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const v = value as Record<string, unknown>;\n if (typeof v.taskId !== \"string\" || typeof v.handledAt !== \"string\") {\n return false;\n }\n const action = v.action;\n if (typeof action !== \"object\" || action === null) {\n return false;\n }\n const a = action as Record<string, unknown>;\n return typeof a.id === \"string\" && \"data\" in a;\n}\n","/** Default wait when `validUntil` is omitted. */\nexport const DEFAULT_WAIT_DURATION_MS = 7 * 24 * 60 * 60 * 1000;\n\nexport function resolveWaitTiming(validUntilInput?: Date | string): {\n validUntil: Date | string;\n timeout: string;\n} {\n const validUntilMs =\n validUntilInput !== undefined\n ? parseValidUntilMs(validUntilInput)\n : Date.now() + DEFAULT_WAIT_DURATION_MS;\n\n const durationMs = validUntilMs - Date.now();\n if (durationMs <= 0) {\n throw new Error(\"validUntil must be in the future\");\n }\n\n return {\n validUntil: validUntilInput ?? new Date(validUntilMs),\n timeout: durationMsToTimeout(durationMs),\n };\n}\n\nexport function parseValidUntilMs(value: Date | string): number {\n if (value instanceof Date) {\n const ms = value.getTime();\n if (Number.isNaN(ms)) {\n throw new Error(\"Invalid validUntil: Date is invalid\");\n }\n return ms;\n }\n\n const parsed = Date.parse(value);\n if (Number.isNaN(parsed)) {\n throw new Error(\"Invalid validUntil: expected a parseable date string\");\n }\n\n return parsed;\n}\n\n/** Duration string for Trigger.dev `wait.createToken` and Workflow `sleep`. */\nexport function durationMsToTimeout(durationMs: number): string {\n const seconds = Math.ceil(durationMs / 1000);\n if (seconds <= 0) {\n throw new Error(\"validUntil must be in the future\");\n }\n\n if (seconds >= 86_400) {\n return `${Math.ceil(seconds / 86_400)}d`;\n }\n if (seconds >= 3_600) {\n return `${Math.ceil(seconds / 3_600)}h`;\n }\n if (seconds >= 60) {\n return `${Math.ceil(seconds / 60)}m`;\n }\n\n return `${seconds}s`;\n}\n","import {\n context,\n trace,\n SpanStatusCode,\n type Span,\n} from \"@opentelemetry/api\";\nimport type { ApprovalResult, DiscriminatedApprovalResult } from \"./schemas/index.js\";\nimport type { RobotRockHandlerWebhookPayload } from \"./handler-webhook.js\";\n\n/** Minimal span surface used by handle-time OTel recording. */\nexport type OtelSpanLike = Pick<Span, \"spanContext\" | \"setAttribute\" | \"addEvent\" | \"setStatus\" | \"end\">;\n\nconst TRACER_NAME = \"robotrock\";\nconst WAIT_SPAN_NAME = \"robotrock.wait_for_human\";\nconst HANDLED_EVENT_NAME = \"robotrock.task_handled\";\n\nconst INVALID_TRACE_ID = \"00000000000000000000000000000000\";\n\nexport type RobotRockOtelHandle = {\n traceId: string;\n spanId: string;\n taskId: string;\n taskCreatedAt: number;\n threadId?: string;\n};\n\nexport type RobotRockOtelRecordOptions = {\n handle?: RobotRockOtelHandle;\n span?: OtelSpanLike | Span | null;\n includeActionData?: boolean;\n tracerName?: string;\n};\n\nexport type RobotRockHandledOtelInput = {\n taskId: string;\n threadId?: string;\n action: { id: string; title?: string; data: unknown };\n handledBy?: string;\n handledAt: string | number | Date;\n};\n\nfunction isValidTraceId(traceId: string | undefined): traceId is string {\n return (\n typeof traceId === \"string\" &&\n traceId.length > 0 &&\n traceId !== INVALID_TRACE_ID\n );\n}\n\nfunction resolveSpanContext(\n span?: OtelSpanLike | Span | null\n): { traceId: string; spanId: string } | undefined {\n const active = span ?? trace.getActiveSpan();\n const ctx = active?.spanContext();\n if (!ctx || !isValidTraceId(ctx.traceId)) {\n return undefined;\n }\n return { traceId: ctx.traceId, spanId: ctx.spanId };\n}\n\nfunction parseTaskCreatedAt(submittedAt?: string): number {\n if (submittedAt) {\n const parsed = Date.parse(submittedAt);\n if (!Number.isNaN(parsed)) {\n return parsed;\n }\n }\n return Date.now();\n}\n\nfunction parseHandledAtMs(handledAt: string | number | Date): number {\n if (handledAt instanceof Date) {\n return handledAt.getTime();\n }\n if (typeof handledAt === \"number\") {\n return handledAt;\n }\n const parsed = Date.parse(handledAt);\n return Number.isNaN(parsed) ? Date.now() : parsed;\n}\n\nexport type RobotRockHandledRecordInput =\n | RobotRockHandlerWebhookPayload\n | ApprovalResult\n | DiscriminatedApprovalResult<readonly { id: string; schema?: unknown }[]>;\n\n/** Normalize handled payloads from Trigger, Workflow, or polling. */\nexport function toRobotRockHandledOtelInput(\n handled: RobotRockHandledRecordInput\n): RobotRockHandledOtelInput {\n if (\"actionId\" in handled) {\n return {\n taskId: handled.taskId,\n action: {\n id: handled.actionId,\n data: handled.data,\n },\n handledBy: handled.handledBy,\n handledAt: handled.handledAt,\n };\n }\n\n return {\n taskId: handled.taskId,\n action: {\n id: handled.action.id,\n title: handled.action.title,\n data: handled.action.data,\n },\n handledBy: handled.handledBy,\n handledAt: handled.handledAt,\n };\n}\n\n/**\n * Capture trace + task metadata after RobotRock task create (before human wait).\n * Used by Trigger.dev and Vercel Workflow durable integrations.\n */\nexport function captureRobotRockOtelHandle(\n task: { taskId: string; threadId?: string; submittedAt?: string },\n options?: { span?: OtelSpanLike | Span | null }\n): RobotRockOtelHandle {\n const spanCtx = resolveSpanContext(options?.span);\n return {\n traceId: spanCtx?.traceId ?? \"\",\n spanId: spanCtx?.spanId ?? \"\",\n taskId: task.taskId,\n threadId: task.threadId,\n taskCreatedAt: parseTaskCreatedAt(task.submittedAt),\n };\n}\n\n/**\n * Start a child span for the human-wait phase on the active trace.\n */\nexport function startRobotRockHumanWaitSpan(\n handle: RobotRockOtelHandle,\n options?: { tracerName?: string; span?: OtelSpanLike | Span | null }\n): Span | undefined {\n const parent = (options?.span ?? trace.getActiveSpan()) as Span | undefined;\n if (!parent) {\n return undefined;\n }\n\n const tracer = trace.getTracer(options?.tracerName ?? TRACER_NAME);\n const span = tracer.startSpan(\n WAIT_SPAN_NAME,\n {},\n trace.setSpan(context.active(), parent)\n );\n\n span.setAttribute(\"robotrock.task_id\", handle.taskId);\n if (handle.threadId) {\n span.setAttribute(\"robotrock.thread_id\", handle.threadId);\n }\n\n return span;\n}\n\n/**\n * Record human action attributes and a span event on the active or wait span.\n */\nexport function recordRobotRockHandledToOtel(\n handled: RobotRockHandledRecordInput,\n options: RobotRockOtelRecordOptions = {}\n): void {\n const span = (options.span ?? trace.getActiveSpan()) as Span | undefined;\n if (!span) {\n return;\n }\n\n const input = toRobotRockHandledOtelInput(handled);\n const handledAtMs = parseHandledAtMs(input.handledAt);\n const handle = options.handle;\n const humanWaitMs =\n handle != null ? Math.max(0, handledAtMs - handle.taskCreatedAt) : undefined;\n\n span.setAttribute(\"robotrock.task_id\", input.taskId);\n span.setAttribute(\"robotrock.action.id\", input.action.id);\n if (input.action.title) {\n span.setAttribute(\"robotrock.action.title\", input.action.title);\n }\n if (input.handledBy) {\n span.setAttribute(\"robotrock.handled_by\", input.handledBy);\n }\n span.setAttribute(\"robotrock.handled_at\", new Date(handledAtMs).toISOString());\n if (humanWaitMs != null) {\n span.setAttribute(\"robotrock.human_wait_ms\", humanWaitMs);\n }\n if (input.threadId) {\n span.setAttribute(\"robotrock.thread_id\", input.threadId);\n }\n\n const eventAttributes: Record<string, string | number | boolean> = {\n \"robotrock.task_id\": input.taskId,\n \"robotrock.action.id\": input.action.id,\n };\n if (input.handledBy) {\n eventAttributes[\"robotrock.handled_by\"] = input.handledBy;\n }\n if (humanWaitMs != null) {\n eventAttributes[\"robotrock.human_wait_ms\"] = humanWaitMs;\n }\n\n if (options.includeActionData && input.action.data != null) {\n const serialized = JSON.stringify(input.action.data);\n const truncated =\n serialized.length > 512 ? `${serialized.slice(0, 512)}…` : serialized;\n span.setAttribute(\"robotrock.action.data\", truncated);\n eventAttributes[\"robotrock.action.data\"] = truncated;\n }\n\n span.addEvent(HANDLED_EVENT_NAME, eventAttributes);\n}\n\nexport type EndRobotRockHumanWaitSpanOptions = {\n handle?: RobotRockOtelHandle;\n outcome?: \"handled\" | \"timeout\" | \"error\";\n includeActionData?: boolean;\n};\n\n/**\n * End the human-wait child span, recording handled data or a timeout/error outcome.\n */\nexport function endRobotRockHumanWaitSpan(\n span: Span | undefined,\n handled: RobotRockHandledRecordInput | null,\n options: EndRobotRockHumanWaitSpanOptions = {}\n): void {\n if (!span) {\n return;\n }\n\n const outcome = options.outcome ?? (handled ? \"handled\" : \"timeout\");\n\n if (handled && outcome === \"handled\") {\n recordRobotRockHandledToOtel(handled, {\n span,\n handle: options.handle,\n includeActionData: options.includeActionData,\n });\n span.setStatus({ code: SpanStatusCode.OK });\n } else {\n span.setAttribute(\"robotrock.outcome\", outcome);\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message:\n outcome === \"timeout\"\n ? \"Human response timed out before validUntil\"\n : \"Human wait failed\",\n });\n }\n\n span.end();\n}\n","import type { Span } from \"@opentelemetry/api\";\nimport {\n captureRobotRockOtelHandle,\n endRobotRockHumanWaitSpan,\n startRobotRockHumanWaitSpan,\n type RobotRockOtelHandle,\n} from \"./record-handled-to-otel.js\";\n\nexport type RobotRockPlatformOtelFields = {\n /**\n * Record human handle result on the active OTel span (Trigger / Workflow).\n * Defaults to `ROBOTROCK_OTEL_RECORD_HANDLED` env (`true` / `1`).\n */\n recordOtel?: boolean;\n /** Include truncated action feedback data on OTel spans (off by default). */\n otelIncludeActionData?: boolean;\n};\n\nexport function shouldRecordRobotRockOtel(recordOtel?: boolean): boolean {\n if (recordOtel === true) {\n return true;\n }\n if (recordOtel === false) {\n return false;\n }\n const env = process.env.ROBOTROCK_OTEL_RECORD_HANDLED;\n return env === \"true\" || env === \"1\";\n}\n\nexport function stripPlatformOtelFields<\n T extends RobotRockPlatformOtelFields & Record<string, unknown>,\n>(payload: T): Omit<T, \"recordOtel\" | \"otelIncludeActionData\"> {\n const { recordOtel: _recordOtel, otelIncludeActionData: _otelIncludeActionData, ...rest } =\n payload;\n return rest;\n}\n\nexport type RobotRockCreatedTask = {\n taskId: string;\n threadId?: string;\n submittedAt?: string;\n};\n\nexport type RobotRockHumanWaitOtelSession = {\n recordOtel: boolean;\n handle?: RobotRockOtelHandle;\n waitSpan?: Span;\n includeActionData?: boolean;\n};\n\nexport function beginRobotRockHumanWaitOtel(\n task: RobotRockCreatedTask,\n options: Pick<RobotRockPlatformOtelFields, \"recordOtel\" | \"otelIncludeActionData\"> = {}\n): RobotRockHumanWaitOtelSession {\n const recordOtel = shouldRecordRobotRockOtel(options.recordOtel);\n if (!recordOtel) {\n return { recordOtel: false };\n }\n\n const handle = captureRobotRockOtelHandle(task);\n const waitSpan = startRobotRockHumanWaitSpan(handle);\n\n return {\n recordOtel: true,\n handle,\n waitSpan,\n includeActionData: options.otelIncludeActionData,\n };\n}\n\nexport function finishRobotRockHumanWaitOtel(\n session: RobotRockHumanWaitOtelSession,\n handled: Parameters<typeof endRobotRockHumanWaitSpan>[1],\n outcome: \"handled\" | \"timeout\" | \"error\"\n): void {\n if (!session.recordOtel) {\n return;\n }\n\n endRobotRockHumanWaitSpan(session.waitSpan, handled, {\n handle: session.handle,\n outcome,\n includeActionData: session.includeActionData,\n });\n}\n"],"mappings":"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","names":["sleep","z","context","safeUrlSchema","z","jsonSchema7Schema","uiSchemaSchema","webhookHandlerSchema","triggerHandlerSchema","handlerSchema","taskActionSchema","uiFieldSchemaSchema","contextUiSchema","contextDataSchema","TASK_CONTEXT_FORMAT_VERSION","taskContextObjectBaseSchema","normalizeTaskContextVersion","taskContextObjectSchema","refineContextPublicUrls","taskContextSchema","assignToSchema","threadUpdateMessageSchema","threadUpdateStatuses","threadUpdateStatusSchema","threadUpdateInputSchema","z","threadUpdateMessageSchema","threadUpdateStatusSchema","taskPriorities","taskPrioritySchema","agentTelemetrySchema","z","createTaskBodySchema","taskContextObjectBaseSchema","assignToSchema","taskPrioritySchema","threadUpdateInputSchema","normalizeTaskContextVersion","refineContextPublicUrls","TASK_CONTEXT_FORMAT_VERSION","createTaskBodySchema","parseValidUntilMs","parseValidUntilMs","sleep"]}
|
|
1
|
+
{"version":3,"sources":["../../src/workflow/index.ts","../../src/schemas/index.ts","../../../core/src/utils/safe-url.ts","../../../core/src/schemas/task.ts","../../../core/src/schemas/context-urls.ts","../../src/approval-result.ts","../../src/http.ts","../../../core/src/handler-retry.ts","../../../core/src/attribution/index.ts","../../../core/src/app-url.ts","../../src/chats.ts","../../src/client.ts","../../src/env.ts","../../src/handler-webhook.ts","../../src/wait-timing.ts","../../src/record-handled-to-otel.ts","../../src/otel-platform.ts"],"sourcesContent":["import { createWebhook, sleep } from \"workflow\";\nimport type {\n DiscriminatedApprovalResult,\n ThreadUpdate,\n ThreadUpdateStatus,\n} from \"../schemas/index.js\";\nimport {\n createClient,\n type SendToHumanActionInput,\n type SendToHumanInput,\n} from \"../client.js\";\nimport { resolveRobotRockConfig } from \"../env.js\";\nimport { toDiscriminatedApprovalResult } from \"../approval-result.js\";\nimport {\n isRobotRockHandlerWebhookPayload,\n type RobotRockHandlerWebhookPayload,\n} from \"../handler-webhook.js\";\nimport { parseValidUntilMs, resolveWaitTiming } from \"../wait-timing.js\";\nimport {\n beginRobotRockHumanWaitOtel,\n finishRobotRockHumanWaitOtel,\n stripPlatformOtelFields,\n type RobotRockPlatformOtelFields,\n} from \"../otel-platform.js\";\n\nexport type SendToHumanWorkflowPayload<\n A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[],\n> = SendToHumanInput<A> &\n RobotRockPlatformOtelFields & {\n /** Inbox app bucket. Overrides `ROBOTROCK_APP` when set. */\n app?: string;\n };\n\nexport type ApproveByHumanWorkflowPayload = Omit<SendToHumanWorkflowPayload, \"actions\">;\n\ntype Expand<T> = T extends unknown ? { [K in keyof T]: T[K] } : never;\n\nconst APPROVE_BY_HUMAN_ACTIONS = [\n { id: \"approve\", title: \"Approve\" },\n { id: \"decline\", title: \"Decline\" },\n] as const;\n\ntype CreateTaskStepInput = {\n webhookUrl: string;\n app?: string;\n validUntil: Date | string;\n taskInput: Omit<SendToHumanWorkflowPayload, \"validUntil\" | \"app\" | \"recordOtel\" | \"otelIncludeActionData\">;\n};\n\n/**\n * Creates the RobotRock inbox task with the workflow webhook URL as the handler.\n * Marked as a step so API calls run in full Node.js with retries.\n */\nasync function createRobotRockTaskForWebhook(input: CreateTaskStepInput) {\n \"use step\";\n\n const baseConfig = resolveRobotRockConfig();\n const client = createClient({\n apiKey: baseConfig.apiKey,\n baseUrl: baseConfig.baseUrl,\n ...((input.app ?? baseConfig.app) ? { app: input.app ?? baseConfig.app } : {}),\n ...(baseConfig.version ? { version: baseConfig.version } : {}),\n ...(baseConfig.advanced ? { advanced: baseConfig.advanced } : {}),\n webhook: { url: input.webhookUrl },\n });\n\n return client.sendToHuman({\n ...input.taskInput,\n validUntil: input.validUntil,\n });\n}\n\nasync function parseRobotRockWebhookRequest(request: Request) {\n \"use step\";\n\n const body: unknown = await request.json();\n if (!isRobotRockHandlerWebhookPayload(body)) {\n throw new Error(\n \"Workflow webhook completed with unexpected payload; expected RobotRock handler body (taskId, action.id, action.data).\"\n );\n }\n\n return body;\n}\n\n/**\n * Durable human-in-the-loop wait for Vercel Workflow.\n *\n * Call from a function with `\"use workflow\"` as its first statement. Creates a\n * {@link createWebhook} URL, registers it as the RobotRock task webhook, and\n * suspends until a human handles an action or `validUntil` passes.\n */\nexport async function sendToHumanInWorkflow<\n const A extends readonly SendToHumanActionInput[],\n>(\n payload: SendToHumanWorkflowPayload<A>\n): Promise<Expand<DiscriminatedApprovalResult<A>>> {\n const { validUntil: validUntilInput, app, recordOtel, otelIncludeActionData, ...taskFields } =\n payload;\n const { validUntil, timeout } = resolveWaitTiming(validUntilInput);\n const timeoutMs = parseValidUntilMs(validUntil) - Date.now();\n\n using webhook = createWebhook();\n\n const sendResult = await createRobotRockTaskForWebhook({\n webhookUrl: webhook.url,\n app,\n validUntil,\n taskInput: stripPlatformOtelFields(taskFields),\n });\n\n const otelSession = beginRobotRockHumanWaitOtel(sendResult.task, {\n recordOtel,\n otelIncludeActionData,\n });\n\n let handledPayload: RobotRockHandlerWebhookPayload | null = null;\n let waitOutcome: \"handled\" | \"timeout\" | \"error\" | \"pending\" = \"pending\";\n\n try {\n const outcome = await Promise.race([\n webhook.then((request) => parseRobotRockWebhookRequest(request)),\n sleep(timeoutMs).then(() => ({ timedOut: true }) as const),\n ]);\n\n if (\"timedOut\" in outcome) {\n waitOutcome = \"timeout\";\n throw new Error(`Human response timed out before validUntil (${timeout})`);\n }\n\n handledPayload = outcome;\n waitOutcome = \"handled\";\n\n return toDiscriminatedApprovalResult(payload.actions, {\n id: outcome.taskId,\n createdAt: new Date(),\n status: \"handled\",\n context: sendResult.task.context,\n validUntil: Date.now(),\n handledAt: new Date(outcome.handledAt).getTime(),\n handled: {\n action: {\n id: outcome.action.id,\n data: outcome.action.data,\n },\n handledBy: outcome.handledBy,\n },\n }) as unknown as Expand<DiscriminatedApprovalResult<A>>;\n } catch (error) {\n if (waitOutcome === \"pending\") {\n waitOutcome = \"error\";\n }\n throw error;\n } finally {\n if (waitOutcome !== \"pending\") {\n finishRobotRockHumanWaitOtel(\n otelSession,\n handledPayload,\n waitOutcome === \"handled\" ? \"handled\" : waitOutcome\n );\n }\n }\n}\n\n/**\n * Approve / decline gate for Vercel Workflow (`sendToHumanInWorkflow` with fixed actions).\n */\nexport async function approveByHumanInWorkflow(\n payload: ApproveByHumanWorkflowPayload\n): Promise<Expand<DiscriminatedApprovalResult<typeof APPROVE_BY_HUMAN_ACTIONS>>> {\n return sendToHumanInWorkflow({\n ...payload,\n actions: APPROVE_BY_HUMAN_ACTIONS,\n });\n}\n\nexport type SendUpdateWorkflowPayload = {\n /** Thread to log the update against (from a prior task's `threadId`). */\n threadId: string;\n /** Short status update (1-2 sentences) shown in the inbox status bar. */\n message: string;\n /** Lifecycle status driving the status-bar icon/color. @default \"info\" */\n status?: ThreadUpdateStatus;\n /** Inbox app bucket. Overrides `ROBOTROCK_APP` when set. */\n app?: string;\n};\n\n/**\n * Posts a thread update via `client.sendUpdate()`. Marked as a step so the API\n * call runs in full Node.js with retries and is recorded in the workflow run.\n */\nasync function sendRobotRockUpdate(payload: SendUpdateWorkflowPayload): Promise<ThreadUpdate> {\n \"use step\";\n\n const { app, ...update } = payload;\n const baseConfig = resolveRobotRockConfig();\n const client = createClient({\n apiKey: baseConfig.apiKey,\n baseUrl: baseConfig.baseUrl,\n ...((app ?? baseConfig.app) ? { app: app ?? baseConfig.app } : {}),\n ...(baseConfig.version ? { version: baseConfig.version } : {}),\n ...(baseConfig.advanced ? { advanced: baseConfig.advanced } : {}),\n });\n\n return client.tasks.sendUpdate(update);\n}\n\n/**\n * Durable thread update for Vercel Workflow.\n *\n * Wraps {@link createClient}'s `sendUpdate` in a `\"use step\"` so progress\n * reports are retried and recorded in the run. Fire-and-forget: returns the\n * created update without suspending the workflow (no human wait involved).\n *\n * Call from a function with `\"use workflow\"` as its first statement.\n */\nexport async function sendUpdateInWorkflow(\n payload: SendUpdateWorkflowPayload\n): Promise<ThreadUpdate> {\n return sendRobotRockUpdate(payload);\n}\n\nexport type { RobotRockHandlerWebhookPayload } from \"../handler-webhook.js\";\nexport type { RobotRockPlatformOtelFields } from \"../otel-platform.js\";\nexport type {\n ApprovalResult,\n DiscriminatedApprovalResult,\n TaskContextInput,\n TaskResult,\n ThreadUpdate,\n ThreadUpdateStatus,\n} from \"../schemas/index.js\";\n","import { z } from \"zod\";\nimport {\n isPublicHttpUrl,\n PUBLIC_HTTP_URL_ERROR,\n} from \"@robotrock/core/utils\";\nimport { validateContextPublicUrls } from \"@robotrock/core/schemas\";\n\nexport interface JSONSchema7 {\n $id?: string;\n $ref?: string;\n $schema?: string;\n $comment?: string;\n type?: JSONSchema7TypeName | JSONSchema7TypeName[];\n enum?: unknown[];\n const?: unknown;\n multipleOf?: number;\n maximum?: number;\n exclusiveMaximum?: number;\n minimum?: number;\n exclusiveMinimum?: number;\n maxLength?: number;\n minLength?: number;\n pattern?: string;\n format?: string;\n items?: JSONSchema7 | JSONSchema7[];\n additionalItems?: JSONSchema7 | boolean;\n maxItems?: number;\n minItems?: number;\n uniqueItems?: boolean;\n contains?: JSONSchema7;\n maxProperties?: number;\n minProperties?: number;\n required?: string[];\n properties?: Record<string, JSONSchema7>;\n patternProperties?: Record<string, JSONSchema7>;\n additionalProperties?: JSONSchema7 | boolean;\n dependencies?: Record<string, JSONSchema7 | string[]>;\n propertyNames?: JSONSchema7;\n if?: JSONSchema7;\n then?: JSONSchema7;\n else?: JSONSchema7;\n allOf?: JSONSchema7[];\n anyOf?: JSONSchema7[];\n oneOf?: JSONSchema7[];\n not?: JSONSchema7;\n title?: string;\n description?: string;\n default?: unknown;\n readOnly?: boolean;\n writeOnly?: boolean;\n examples?: unknown[];\n}\n\nexport type JSONSchema7TypeName =\n | \"string\"\n | \"number\"\n | \"integer\"\n | \"boolean\"\n | \"object\"\n | \"array\"\n | \"null\";\n\nexport type ExtendedJSONSchema7 = JSONSchema7 & {\n enumNames?: string[];\n [key: string]: unknown;\n};\n\nexport type UiSchema = {\n \"ui:widget\"?: string;\n \"ui:title\"?: string;\n \"ui:description\"?: string;\n \"ui:placeholder\"?: string;\n \"ui:options\"?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\nconst safeUrlSchema = z.string().refine((url) => isPublicHttpUrl(url), {\n message: PUBLIC_HTTP_URL_ERROR,\n});\n\nconst jsonSchema7Schema = z.custom<ExtendedJSONSchema7>(\n (val) => typeof val === \"object\" && val !== null,\n { message: \"Must be a valid JSON Schema object\" }\n);\n\nconst uiSchemaSchema = z.custom<UiSchema>((val) => typeof val === \"object\" && val !== null, {\n message: \"Must be a valid UiSchema object\",\n});\n\nconst webhookHandlerSchema = z.object({\n type: z.literal(\"webhook\"),\n url: safeUrlSchema,\n headers: z.record(z.string(), z.string()),\n});\n\nconst triggerHandlerSchema = webhookHandlerSchema.extend({\n type: z.literal(\"trigger\"),\n tokenId: z.string().min(1),\n});\n\nconst handlerSchema = z.discriminatedUnion(\"type\", [webhookHandlerSchema, triggerHandlerSchema]);\n\n/** Action config without handlers — used for chat widgets and agent tool input. */\nexport const taskActionInputSchema = z.object({\n id: z.string().min(1),\n title: z.string().min(1),\n description: z.string().optional(),\n schema: jsonSchema7Schema.optional(),\n ui: uiSchemaSchema.optional(),\n data: z.record(z.string(), z.unknown()).optional(),\n});\n\nconst taskActionSchema = taskActionInputSchema.extend({\n handlers: z.array(handlerSchema).min(1).optional(),\n});\n\nconst uiFieldSchemaSchema: z.ZodType<Record<string, unknown>> = z\n .object({\n \"ui:widget\": z.string().optional(),\n \"ui:title\": z.string().optional(),\n \"ui:description\": z.string().optional(),\n \"ui:options\": z.record(z.string(), z.unknown()).optional(),\n items: z.lazy(() => z.record(z.string(), uiFieldSchemaSchema)).optional(),\n })\n .passthrough();\n\nconst contextUiSchema = z.record(z.string(), uiFieldSchemaSchema).optional();\n\nconst contextDataSchema = z\n .object({\n data: z.record(z.string(), z.unknown()),\n ui: contextUiSchema,\n })\n .optional();\n\n/** Task context wire format version (always `2` today). */\nexport const TASK_CONTEXT_FORMAT_VERSION = 2 as const;\nexport type TaskContextFormatVersion = typeof TASK_CONTEXT_FORMAT_VERSION;\n\nconst taskContextObjectBaseSchema = z.object({\n app: z.string().min(1).optional(),\n type: z.string().min(1),\n name: z.string().min(1),\n description: z.string().optional(),\n validUntil: z.string().optional(),\n context: contextDataSchema,\n contextVersion: z.literal(2).optional(),\n /** @deprecated Use `contextVersion`. Accepted on ingest only. */\n version: z.literal(2).optional(),\n actions: z.array(taskActionSchema).min(1, \"At least one action is required\"),\n});\n\nfunction normalizeTaskContextVersion<T extends { contextVersion?: 2; version?: 2 }>(\n data: T\n): Omit<T, \"version\" | \"contextVersion\"> & { contextVersion: 2 } {\n const { version: legacyVersion, contextVersion, ...rest } = data;\n return {\n ...rest,\n contextVersion: contextVersion ?? legacyVersion ?? TASK_CONTEXT_FORMAT_VERSION,\n };\n}\n\nconst taskContextObjectSchema = taskContextObjectBaseSchema.transform(\n normalizeTaskContextVersion\n);\n\nfunction refineContextPublicUrls<T extends { context?: z.infer<typeof contextDataSchema> }>(\n data: T,\n ctx: z.RefinementCtx\n) {\n const error = validateContextPublicUrls(data.context);\n if (error) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: error,\n path: [\"context\"],\n });\n }\n}\n\nexport const taskContextSchema = taskContextObjectSchema.superRefine(\n refineContextPublicUrls\n);\n\n/**\n * Assignment targets at task create (not stored in task context JSON).\n * Unknown user emails are auto-provisioned as assignee memberships (count toward seat limits).\n */\nexport const assignToSchema = z\n .object({\n users: z.array(z.string().email()).optional(),\n groups: z.array(z.string().min(1)).optional(),\n })\n .refine(\n (data) => {\n const groups = data.groups ?? [];\n if (groups.includes(\"all\") && groups.length > 1) {\n return false;\n }\n return true;\n },\n { message: 'Cannot combine \"all\" with other group slugs' }\n );\n\n/** A short thread-scoped status update message (1-2 sentences). */\nexport const threadUpdateMessageSchema = z.string().min(1).max(500);\n\n/**\n * Lifecycle status carried by a thread update. Drives the icon and color shown\n * in the inbox status bar. Defaults to `info` when omitted.\n */\nexport const threadUpdateStatuses = [\n \"info\",\n \"queued\",\n \"running\",\n \"waiting\",\n \"succeeded\",\n \"failed\",\n \"cancelled\",\n] as const;\n\nexport const threadUpdateStatusSchema = z.enum(threadUpdateStatuses);\n\n/** The default status applied when an update omits one. */\nexport const DEFAULT_THREAD_UPDATE_STATUS: ThreadUpdateStatus = \"info\";\n\n/** Shared shape for a thread update (standalone and at task creation). */\nexport const threadUpdateInputSchema = z.object({\n message: threadUpdateMessageSchema,\n status: threadUpdateStatusSchema.optional(),\n});\n\n/** Thread priority levels for inbox ordering and display. */\nexport const taskPriorities = [\"low\", \"normal\", \"high\", \"urgent\"] as const;\n\nexport const taskPrioritySchema = z.enum(taskPriorities);\n\nexport type TaskPriority = (typeof taskPriorities)[number];\n\nexport const DEFAULT_TASK_PRIORITY: TaskPriority = \"normal\";\n\nexport const LOWEST_TASK_PRIORITY: TaskPriority = \"low\";\n\nexport const TASK_PRIORITY_RANK: Record<TaskPriority, number> = {\n low: 1,\n normal: 2,\n high: 3,\n urgent: 4,\n};\n\nexport const agentTelemetrySchema = z.object({\n version: z.string().min(1),\n});\n\nexport const createTaskBodySchema = taskContextObjectBaseSchema\n .extend({\n assignTo: assignToSchema.optional(),\n /**\n * Groups related tasks together. When omitted, the server generates one and\n * returns it so the caller can reuse it on later tasks in the same thread.\n */\n threadId: z.string().min(1).optional(),\n /**\n * Optional thread priority. When set, applies to the whole thread and\n * overwrites any previous priority. Omit on later tasks to leave unchanged.\n */\n priority: taskPrioritySchema.optional(),\n /**\n * Optional initial status update logged against the task's thread. Shows in\n * the inbox status bar and the thread update log.\n */\n update: threadUpdateInputSchema.optional(),\n agent: agentTelemetrySchema.optional(),\n })\n .transform(normalizeTaskContextVersion)\n .superRefine(refineContextPublicUrls);\n\n/** POST /v1/threads/:threadId/updates body: a standalone thread update. */\nexport const threadUpdateBodySchema = threadUpdateInputSchema;\n\n/** Where a thread update originated. */\nexport type ThreadUpdateSource = \"api\" | \"task_create\" | \"dashboard\";\n\n/** Lifecycle status carried by a thread update. */\nexport type ThreadUpdateStatus = (typeof threadUpdateStatuses)[number];\n\n/** A logged thread update as returned by the API. */\nexport interface ThreadUpdate {\n id: string;\n threadId: string;\n message: string;\n status: ThreadUpdateStatus;\n source: ThreadUpdateSource;\n createdAt: number;\n}\n\nexport type AssignToInput = z.infer<typeof assignToSchema>;\nexport type CreateTaskBodyInput = z.input<typeof createTaskBodySchema>;\nexport type CreateTaskBody = z.output<typeof createTaskBodySchema>;\nexport type ThreadUpdateBodyInput = z.input<typeof threadUpdateBodySchema>;\nexport type ThreadUpdateBody = z.output<typeof threadUpdateBodySchema>;\nexport type ThreadUpdateInput = z.input<typeof threadUpdateInputSchema>;\nexport type TaskContextInput = z.input<typeof taskContextSchema>;\nexport type TaskContextOutput = z.output<typeof taskContextSchema>;\nexport type TaskContext = TaskContextOutput;\nexport type TaskActionInput = z.infer<typeof taskActionInputSchema>;\nexport type TaskAction = z.infer<typeof taskActionSchema>;\nexport type WebhookHandler = z.infer<typeof webhookHandlerSchema>;\nexport type TriggerHandler = z.infer<typeof triggerHandlerSchema>;\nexport type Handler = z.infer<typeof handlerSchema>;\nexport type AgentTelemetry = z.infer<typeof agentTelemetrySchema>;\nexport type AgentTelemetryInput = z.input<typeof agentTelemetrySchema>;\n\ntype InferObjectProperties<\n Props,\n Req extends PropertyKey,\n> = Props extends Record<string, unknown>\n ? ({\n [K in keyof Props as K extends Req ? K : never]-?: InferJsonSchema7<Props[K]>;\n } & {\n [K in keyof Props as K extends Req ? never : K]?: InferJsonSchema7<Props[K]>;\n } extends infer O\n ? { [K in keyof O]: O[K] }\n : never)\n : Record<string, unknown>;\n\ntype RequiredKeys<S> =\n S extends { readonly required: readonly string[] } ? S[\"required\"][number] : never;\n\nexport type InferJsonSchema7<S> = [S] extends [undefined]\n ? Record<string, never>\n : S extends { readonly const: infer C }\n ? C\n : S extends {\n readonly enum: readonly (infer E)[];\n }\n ? E\n : S extends {\n readonly type: \"object\";\n readonly properties?: infer Props;\n }\n ? InferObjectProperties<Props, RequiredKeys<S>>\n : S extends {\n readonly type: \"object\";\n readonly properties?: undefined;\n }\n ? Record<string, unknown>\n : S extends {\n readonly type: \"array\";\n readonly items?: infer Items;\n }\n ? Items extends readonly unknown[]\n ? InferJsonSchema7<Items[number]>[]\n : Items extends object\n ? InferJsonSchema7<Items>[]\n : unknown[]\n : S extends { readonly type: \"string\" }\n ? string\n : S extends { readonly type: \"number\" } | { readonly type: \"integer\" }\n ? number\n : S extends { readonly type: \"boolean\" }\n ? boolean\n : unknown;\n\nexport type TaskStatus = \"pending\" | \"open\" | \"handled\" | \"expired\";\n\nexport interface TaskResponse {\n success: boolean;\n task: {\n taskId: string;\n threadId: string;\n status: \"pending\" | \"open\";\n context: TaskContext;\n validUntil: string;\n submittedAt: string;\n };\n message: string;\n}\n\nexport interface ThreadUpdateResponse {\n success: boolean;\n update: ThreadUpdate;\n message: string;\n}\n\nexport interface Task {\n id: string;\n threadId?: string;\n createdAt: Date;\n status: TaskStatus;\n context: TaskContext;\n validUntil: number;\n handledAt?: number;\n handled?: {\n action: {\n id: string;\n data: unknown;\n };\n handledBy?: string;\n userId?: string;\n token?: string;\n };\n}\n\nexport type InferActionData<T extends { schema?: unknown }> = [\n Exclude<T[\"schema\"], undefined>,\n] extends [\n never,\n]\n ? Record<string, never>\n : Exclude<T[\"schema\"], undefined> extends infer S\n ? InferJsonSchema7<S>\n : Record<string, never>;\n\nexport type TupleElementIndices<T extends readonly unknown[]> = T extends readonly [\n unknown,\n ...unknown[],\n]\n ? Exclude<keyof T, keyof unknown[]>\n : number;\n\nexport interface TaskResult<T = Record<string, unknown>> {\n actionId: string;\n data: T;\n handledBy?: string;\n handledAt: Date;\n}\n\nexport interface ApprovalResult<T = Record<string, unknown>> extends TaskResult<T> {\n taskId: string;\n}\n\nexport type DiscriminatedApprovalResult<\n TActions extends readonly { id: string; schema?: unknown }[],\n> = {\n [I in TupleElementIndices<TActions>]: TActions[I] extends { id: string; schema?: unknown }\n ? Omit<ApprovalResult<InferActionData<TActions[I]>>, \"actionId\" | \"data\"> & {\n actionId: TActions[I][\"id\"];\n data: InferActionData<TActions[I]>;\n }\n : never\n}[TupleElementIndices<TActions>];\n","const BLOCKED_HOSTNAMES = new Set([\n \"localhost\",\n \"metadata.google.internal\",\n \"metadata.goog\",\n]);\n\nfunction normalizeHostname(hostname: string): string {\n return hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n}\n\nfunction isBlockedIpv4(host: string): boolean {\n const match = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(host);\n if (!match) {\n return false;\n }\n\n const octets = match.slice(1, 5).map((part) => Number(part));\n if (octets.some((octet) => Number.isNaN(octet) || octet < 0 || octet > 255)) {\n return true;\n }\n\n const [a, b, _c, _d] = octets;\n if (a === undefined || b === undefined) {\n return true;\n }\n if (a === 127 || a === 0) return true;\n if (a === 10) return true;\n if (a === 169 && b === 254) return true;\n if (a === 192 && b === 168) return true;\n if (a === 172 && b >= 16 && b <= 31) return true;\n if (a === 100 && b >= 64 && b <= 127) return true;\n\n return false;\n}\n\nfunction ipv4FromNumericHost(host: string): string | null {\n if (/^\\d+$/.test(host)) {\n const num = Number(host);\n if (!Number.isFinite(num) || num < 0 || num > 0xffffffff) {\n return null;\n }\n const a = (num >>> 24) & 0xff;\n const b = (num >>> 16) & 0xff;\n const c = (num >>> 8) & 0xff;\n const d = num & 0xff;\n return `${a}.${b}.${c}.${d}`;\n }\n\n const hexMatch = /^0x([0-9a-f]{1,8})$/i.exec(host);\n if (hexMatch) {\n const num = Number.parseInt(hexMatch[1]!, 16);\n if (!Number.isFinite(num) || num < 0 || num > 0xffffffff) {\n return null;\n }\n const a = (num >>> 24) & 0xff;\n const b = (num >>> 16) & 0xff;\n const c = (num >>> 8) & 0xff;\n const d = num & 0xff;\n return `${a}.${b}.${c}.${d}`;\n }\n\n return null;\n}\n\nfunction isBlockedIpv4Mapped(host: string): boolean {\n const mappedDotted = /^::ffff:(\\d{1,3}(?:\\.\\d{1,3}){3})$/i.exec(host);\n if (mappedDotted) {\n return isBlockedIpv4(mappedDotted[1]!);\n }\n\n const mappedHex = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i.exec(host);\n if (mappedHex) {\n const high = Number.parseInt(mappedHex[1]!, 16);\n const low = Number.parseInt(mappedHex[2]!, 16);\n if (Number.isFinite(high) && Number.isFinite(low)) {\n const a = (high >> 8) & 0xff;\n const b = high & 0xff;\n const c = (low >> 8) & 0xff;\n const d = low & 0xff;\n return isBlockedIpv4(`${a}.${b}.${c}.${d}`);\n }\n }\n\n return false;\n}\n\nfunction isBlockedIpv6(host: string): boolean {\n if (host === \"::1\" || host === \"0:0:0:0:0:0:0:1\") {\n return true;\n }\n if (host.startsWith(\"fc\") || host.startsWith(\"fd\")) {\n return true;\n }\n if (host.startsWith(\"fe80:\")) {\n return true;\n }\n if (isBlockedIpv4Mapped(host)) {\n return true;\n }\n return false;\n}\n\nfunction isBlockedHostname(hostname: string): boolean {\n const host = normalizeHostname(hostname);\n if (!host) {\n return true;\n }\n if (BLOCKED_HOSTNAMES.has(host)) {\n return true;\n }\n if (host.endsWith(\".localhost\") || host.endsWith(\".local\")) {\n return true;\n }\n\n const numericIpv4 = ipv4FromNumericHost(host);\n if (numericIpv4 && isBlockedIpv4(numericIpv4)) {\n return true;\n }\n\n return isBlockedIpv4(host) || isBlockedIpv6(host);\n}\n\n/**\n * Returns true when the URL uses http(s) and targets a public, non-reserved host.\n */\nexport function isPublicHttpUrl(urlString: string): boolean {\n let url: URL;\n try {\n url = new URL(urlString);\n } catch {\n return false;\n }\n\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n return false;\n }\n if (url.username || url.password) {\n return false;\n }\n\n return !isBlockedHostname(url.hostname);\n}\n\nexport const PUBLIC_HTTP_URL_ERROR =\n \"URL must be a public http:// or https:// address\";\n\nconst FORBIDDEN_HANDLER_HEADERS = new Set([\n \"host\",\n \"connection\",\n \"content-length\",\n \"transfer-encoding\",\n \"te\",\n \"trailer\",\n \"upgrade\",\n \"proxy-authorization\",\n \"proxy-connection\",\n \"keep-alive\",\n \"x-robotrock-signature\",\n \"x-robotrock-delivery-id\",\n \"x-robotrock-delivery-attempt\",\n]);\n\n/**\n * Allow only safe custom webhook headers; blocks overrides of delivery metadata.\n */\nexport function filterHandlerHeaders(\n headers: Record<string, string> | undefined\n): Record<string, string> {\n if (!headers) {\n return {};\n }\n\n const filtered: Record<string, string> = {};\n for (const [rawKey, value] of Object.entries(headers)) {\n const key = rawKey.toLowerCase().trim();\n if (!key || FORBIDDEN_HANDLER_HEADERS.has(key)) {\n continue;\n }\n if (!/^[a-z0-9][a-z0-9._-]*$/.test(key)) {\n continue;\n }\n filtered[key] = value;\n }\n return filtered;\n}\n","import { z } from \"zod\";\nimport { isPublicHttpUrl, PUBLIC_HTTP_URL_ERROR } from \"../utils/safe-url\";\nimport { validateContextPublicUrls } from \"./context-urls\";\nimport type { JSONSchema7 } from \"./json-schema\";\n\n/**\n * Extended JSONSchema7 type that includes RJSF extensions like enumNames\n */\nexport type ExtendedJSONSchema7 = JSONSchema7 & {\n enumNames?: string[];\n [key: string]: unknown;\n};\n\n/**\n * UI Schema for RJSF form customization\n */\nexport type UiSchema = {\n \"ui:widget\"?: string;\n \"ui:title\"?: string;\n \"ui:description\"?: string;\n \"ui:placeholder\"?: string;\n \"ui:options\"?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\n// Helper schemas\nconst safeUrlSchema = z.string().refine((url) => isPublicHttpUrl(url), {\n message: PUBLIC_HTTP_URL_ERROR,\n});\n\n// JSONSchema7 validation\nconst jsonSchema7Schema = z.custom<ExtendedJSONSchema7>(\n (val) => typeof val === \"object\" && val !== null,\n { message: \"Must be a valid JSON Schema object\" }\n);\n\n// UiSchema validation\nconst uiSchemaSchema = z.custom<UiSchema>((val) => typeof val === \"object\" && val !== null, {\n message: \"Must be a valid UiSchema object\",\n});\n\n// Handler schemas (per-action handlers for webhooks, triggers, etc.)\nconst webhookHandlerSchema = z.object({\n type: z.literal(\"webhook\"),\n url: safeUrlSchema,\n headers: z.record(z.string(), z.string()),\n});\n\nconst triggerHandlerSchema = webhookHandlerSchema.extend({\n type: z.literal(\"trigger\"),\n tokenId: z.string().min(1),\n});\n\nconst handlerSchema = z.discriminatedUnion(\"type\", [webhookHandlerSchema, triggerHandlerSchema]);\n\n/** Action config without handlers — used for chat widgets and agent tool input. */\nexport const taskActionInputSchema = z.object({\n id: z.string().min(1),\n title: z.string().min(1),\n description: z.string().optional(),\n schema: jsonSchema7Schema.optional(),\n ui: uiSchemaSchema.optional(),\n data: z.record(z.string(), z.unknown()).optional(),\n});\n\n// Action schema with JSONSchema-based feedback and optional handlers\nconst taskActionSchema = taskActionInputSchema.extend({\n // Optional handlers for this action - if present, must have at least 1\n handlers: z.array(handlerSchema).min(1).optional(),\n});\n\n// UI Field Schema\nconst uiFieldSchemaSchema: z.ZodType<Record<string, unknown>> = z\n .object({\n \"ui:widget\": z.string().optional(),\n \"ui:title\": z.string().optional(),\n \"ui:description\": z.string().optional(),\n \"ui:options\": z.record(z.string(), z.unknown()).optional(),\n items: z.lazy(() => z.record(z.string(), uiFieldSchemaSchema)).optional(),\n })\n .passthrough();\n\n// Context UI Schema\nconst contextUiSchema = z.record(z.string(), uiFieldSchemaSchema).optional();\n\n// Context data schema\nconst contextDataSchema = z\n .object({\n data: z.record(z.string(), z.unknown()),\n ui: contextUiSchema,\n })\n .optional();\n\nexport const TASK_CONTEXT_FORMAT_VERSION = 2 as const;\nexport type TaskContextFormatVersion = typeof TASK_CONTEXT_FORMAT_VERSION;\n\n// Main TaskContext schema\nconst taskContextObjectBaseSchema = z.object({\n /** Source application id; omitted tasks are grouped in the default inbox. */\n app: z.string().min(1).optional(),\n type: z.string().min(1),\n name: z.string().min(1),\n description: z.string().optional(),\n validUntil: z.string().optional(),\n context: contextDataSchema,\n /** Task context wire format version. @default 2 */\n contextVersion: z.literal(2).optional(),\n /** @deprecated Use `contextVersion`. Accepted on ingest only. */\n version: z.literal(2).optional(),\n actions: z.array(taskActionSchema).min(1, \"At least one action is required\"),\n});\n\nfunction normalizeTaskContextVersion<T extends { contextVersion?: 2; version?: 2 }>(\n data: T\n): Omit<T, \"version\" | \"contextVersion\"> & { contextVersion: 2 } {\n const { version: legacyVersion, contextVersion, ...rest } = data;\n return {\n ...rest,\n contextVersion: contextVersion ?? legacyVersion ?? TASK_CONTEXT_FORMAT_VERSION,\n };\n}\n\nconst taskContextObjectSchema = taskContextObjectBaseSchema.transform(\n normalizeTaskContextVersion\n);\n\nfunction refineContextPublicUrls<T extends { context?: z.infer<typeof contextDataSchema> }>(\n data: T,\n ctx: z.RefinementCtx\n) {\n const error = validateContextPublicUrls(data.context);\n if (error) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: error,\n path: [\"context\"],\n });\n }\n}\n\nexport const taskContextSchema = taskContextObjectSchema.superRefine(\n refineContextPublicUrls\n);\n\n/**\n * Assignment targets at task create (not stored in task context JSON).\n * Unknown user emails are auto-provisioned as assignee memberships (count toward seat limits).\n */\nexport const assignToSchema = z\n .object({\n users: z.array(z.string().email()).optional(),\n groups: z.array(z.string().min(1)).optional(),\n })\n .refine(\n (data) => {\n const groups = data.groups ?? [];\n if (groups.includes(\"all\") && groups.length > 1) {\n return false;\n }\n return true;\n },\n { message: 'Cannot combine \"all\" with other group slugs' }\n );\n\n/** A short thread-scoped status update message (1-2 sentences). */\nexport const threadUpdateMessageSchema = z.string().min(1).max(500);\n\n/**\n * Lifecycle status carried by a thread update. Drives the icon and color shown\n * in the inbox status bar. Defaults to `info` when omitted.\n */\nexport const threadUpdateStatuses = [\n \"info\",\n \"queued\",\n \"running\",\n \"waiting\",\n \"succeeded\",\n \"failed\",\n \"cancelled\",\n] as const;\n\nexport const threadUpdateStatusSchema = z.enum(threadUpdateStatuses);\n\n/** The default status applied when an update omits one. */\nexport const DEFAULT_THREAD_UPDATE_STATUS: ThreadUpdateStatus = \"info\";\n\n/** Shared shape for a thread update (standalone and at task creation). */\nexport const threadUpdateInputSchema = z.object({\n message: threadUpdateMessageSchema,\n status: threadUpdateStatusSchema.optional(),\n});\n\n/** Thread priority levels for inbox ordering and display. */\nexport const taskPriorities = [\"low\", \"normal\", \"high\", \"urgent\"] as const;\n\nexport const taskPrioritySchema = z.enum(taskPriorities);\n\nexport type TaskPriority = (typeof taskPriorities)[number];\n\nexport const DEFAULT_TASK_PRIORITY: TaskPriority = \"normal\";\n\nexport const LOWEST_TASK_PRIORITY: TaskPriority = \"low\";\n\nexport const TASK_PRIORITY_RANK: Record<TaskPriority, number> = {\n low: 1,\n normal: 2,\n high: 3,\n urgent: 4,\n};\n\n/**\n * Agent release at task create (not shown in inbox reviewer UI).\n * Used for feedback analysis over deploys.\n */\nexport const agentTelemetrySchema = z.object({\n /** Agent or app version (semver, git SHA, deploy tag — caller-defined). */\n version: z.string().min(1),\n});\n\n/** POST /v1 body: task context plus optional assignment. */\nexport const createTaskBodySchema = taskContextObjectBaseSchema\n .extend({\n assignTo: assignToSchema.optional(),\n /**\n * Groups related tasks together. When omitted, the server generates one and\n * returns it so the caller can reuse it on later tasks in the same thread.\n */\n threadId: z.string().min(1).optional(),\n /**\n * Optional thread priority. When set, applies to the whole thread and\n * overwrites any previous priority. Omit on later tasks to leave unchanged.\n */\n priority: taskPrioritySchema.optional(),\n /**\n * Optional initial status update logged against the task's thread. Shows in\n * the inbox status bar and the thread update log.\n */\n update: threadUpdateInputSchema.optional(),\n /** Agent release version — not shown in inbox UI. */\n agent: agentTelemetrySchema.optional(),\n })\n .transform(normalizeTaskContextVersion)\n .superRefine(refineContextPublicUrls);\n\n/** POST /v1/threads/:threadId/updates body: a standalone thread update. */\nexport const threadUpdateBodySchema = threadUpdateInputSchema;\n\n/** Action widget config for a seeded assistant message (mirrors the `requestActionInput` tool input). */\nexport const agentChatSeedActionSchema = z.object({\n /** Stable action id echoed back on submit; auto-derived from title when omitted. */\n id: z.string().min(1).optional(),\n title: z.string().min(1),\n description: z.string().optional(),\n /** JSON Schema object for the form fields. */\n schema: z.record(z.string(), z.unknown()).optional(),\n /** RJSF ui schema overrides (ui:widget, ui:enumNames, etc.). */\n ui: z.record(z.string(), z.unknown()).optional(),\n /** Optional default field values. */\n data: z.record(z.string(), z.unknown()).optional(),\n});\n\n/** A single pre-seeded chat message injected into a programmatic agent chat. */\nexport const agentChatSeedMessageSchema = z.object({\n role: z.enum([\"user\", \"assistant\"]),\n text: z.string().min(1),\n /** Optional display-name override for the message sender. */\n senderName: z.string().min(1).optional(),\n /**\n * Optional structured input request rendered as a styled RobotRock action\n * widget below the message text. Use this instead of asking the user to reply\n * in plain text so the request is always a proper action form.\n */\n requestActionInput: z\n .object({\n prompt: z.string().optional(),\n action: agentChatSeedActionSchema,\n })\n .optional(),\n});\n\n/**\n * POST /v1/agent-chats body: create + assign one or more agent chat sessions.\n * Either `agentIdentifier` (new chat) or `parentChatId` (spawned from a chat) is required.\n */\nexport const createAgentChatBodySchema = z\n .object({\n /** Trigger chat agent id (task slug). Required unless `parentChatId` is set. */\n agentIdentifier: z.string().min(1).optional(),\n /** Inherit tenant/connection/agent from an existing chat (agent-spawned chats). */\n parentChatId: z.string().min(1).optional(),\n /** Convex tenantTriggerConnections id; resolved from the tenant when omitted. */\n connectionId: z.string().min(1).optional(),\n /** Source application id; groups the chat under an inbox section. */\n app: z.string().min(1).optional(),\n assignTo: assignToSchema.optional(),\n title: z.string().min(1),\n messages: z.array(agentChatSeedMessageSchema).default([]),\n /** Provenance label stored on the session (\"cron\" | \"agent\" | ...). */\n source: z.string().min(1).optional(),\n })\n .refine((data) => Boolean(data.agentIdentifier || data.parentChatId), {\n message: \"Provide either agentIdentifier or parentChatId\",\n });\n\n/** POST /v1/agent-chats/transport body: store a backend-minted public token. */\nexport const agentChatTransportBodySchema = z.object({\n chatId: z.string().min(1),\n publicAccessToken: z.string().min(1),\n lastEventId: z.string().optional(),\n isStreaming: z.boolean().optional(),\n});\n\n/** Where a thread update originated. */\nexport type ThreadUpdateSource = \"api\" | \"task_create\" | \"dashboard\";\n\n/** Lifecycle status carried by a thread update. */\nexport type ThreadUpdateStatus = (typeof threadUpdateStatuses)[number];\n\n/** A logged thread update as returned by the API. */\nexport interface ThreadUpdate {\n id: string;\n threadId: string;\n message: string;\n status: ThreadUpdateStatus;\n source: ThreadUpdateSource;\n createdAt: number;\n}\n\n// Type exports\nexport type AssignToInput = z.infer<typeof assignToSchema>;\nexport type CreateTaskBodyInput = z.input<typeof createTaskBodySchema>;\nexport type CreateTaskBody = z.output<typeof createTaskBodySchema>;\nexport type ThreadUpdateBodyInput = z.input<typeof threadUpdateBodySchema>;\nexport type ThreadUpdateBody = z.output<typeof threadUpdateBodySchema>;\nexport type ThreadUpdateInput = z.input<typeof threadUpdateInputSchema>;\nexport type AgentChatSeedAction = z.output<typeof agentChatSeedActionSchema>;\nexport type AgentChatSeedMessage = z.output<typeof agentChatSeedMessageSchema>;\nexport type CreateAgentChatBodyInput = z.input<typeof createAgentChatBodySchema>;\nexport type CreateAgentChatBody = z.output<typeof createAgentChatBodySchema>;\nexport type AgentChatTransportBody = z.output<typeof agentChatTransportBodySchema>;\nexport type TaskContextInput = z.input<typeof taskContextSchema>;\nexport type TaskContextOutput = z.output<typeof taskContextSchema>;\nexport type TaskContext = TaskContextOutput;\nexport type SafeUrl = z.infer<typeof safeUrlSchema>;\nexport type TaskActionInput = z.infer<typeof taskActionInputSchema>;\nexport type TaskAction = z.infer<typeof taskActionSchema>;\nexport type WebhookHandler = z.infer<typeof webhookHandlerSchema>;\nexport type TriggerHandler = z.infer<typeof triggerHandlerSchema>;\nexport type Handler = z.infer<typeof handlerSchema>;\nexport type ContextData = z.infer<typeof contextDataSchema>;\nexport type ContextUiSchema = z.infer<typeof contextUiSchema>;\nexport type UiFieldSchema = z.infer<typeof uiFieldSchemaSchema>;\nexport type AgentTelemetry = z.infer<typeof agentTelemetrySchema>;\nexport type AgentTelemetryInput = z.input<typeof agentTelemetrySchema>;\n","import { isPublicHttpUrl, PUBLIC_HTTP_URL_ERROR } from \"../utils/safe-url\";\n\ntype ContextInput = {\n data?: Record<string, unknown>;\n ui?: Record<string, unknown>;\n};\n\nfunction resolveLinkUrl(value: string): string {\n return value.startsWith(\"http://\") || value.startsWith(\"https://\")\n ? value\n : `https://${value}`;\n}\n\nfunction widgetType(\n ui: Record<string, unknown> | undefined,\n field: string\n): string | undefined {\n const fieldUi = ui?.[field];\n if (typeof fieldUi !== \"object\" || fieldUi === null) {\n return undefined;\n }\n const widget = (fieldUi as Record<string, unknown>)[\"ui:widget\"];\n return typeof widget === \"string\" ? widget : undefined;\n}\n\nfunction validateUrlValue(value: unknown, widget: string): string | null {\n if (widget === \"image\" || widget === \"link\") {\n if (typeof value !== \"string\") {\n return PUBLIC_HTTP_URL_ERROR;\n }\n const url = widget === \"link\" ? resolveLinkUrl(value) : value;\n if (!isPublicHttpUrl(url)) {\n return PUBLIC_HTTP_URL_ERROR;\n }\n return null;\n }\n\n if (widget === \"attachments\" && Array.isArray(value)) {\n for (const item of value) {\n if (typeof item !== \"object\" || item === null) {\n continue;\n }\n const url = (item as { url?: unknown }).url;\n if (typeof url === \"string\" && !isPublicHttpUrl(resolveLinkUrl(url))) {\n return PUBLIC_HTTP_URL_ERROR;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Validates URL-bearing context widget values (image, link, attachments).\n * Returns an error message or null when valid.\n */\nexport function validateContextPublicUrls(\n context: ContextInput | undefined\n): string | null {\n if (!context?.data) {\n return null;\n }\n\n for (const [field, value] of Object.entries(context.data)) {\n const widget = widgetType(context.ui, field);\n if (!widget) {\n continue;\n }\n const error = validateUrlValue(value, widget);\n if (error) {\n return `context.data.${field}: ${error}`;\n }\n }\n\n return null;\n}\n","import type { DiscriminatedApprovalResult, Task } from \"./schemas/index.js\";\n\nexport class TaskTimeoutError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TaskTimeoutError\";\n }\n}\n\nexport class TaskExpiredError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TaskExpiredError\";\n }\n}\n\n/**\n * Map a handled API task to a discriminated approval result.\n * Runtime validation is minimal; TypeScript narrows via `task.actions` at the call site.\n */\nexport function toDiscriminatedApprovalResult<A extends readonly { id: string; schema?: unknown }[]>(\n actions: A,\n task: Task\n): DiscriminatedApprovalResult<A> {\n void actions;\n\n if (!task.handled) {\n throw new Error(\"Task has no handled result\");\n }\n\n return {\n actionId: task.handled.action.id,\n data: task.handled.action.data,\n handledBy: task.handled.handledBy,\n handledAt: new Date(task.handledAt ?? Date.now()),\n taskId: task.id,\n } as DiscriminatedApprovalResult<A>;\n}\n","export class RobotRockError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly response?: unknown\n ) {\n super(message);\n this.name = \"RobotRockError\";\n }\n}\n\ntype ParsedResponseBody = Record<string, unknown> | unknown[] | string | null;\n\nexport async function parseResponseBody(\n response: Response\n): Promise<ParsedResponseBody> {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n const bodyText = await response.text();\n\n if (!bodyText) {\n return null;\n }\n\n if (contentType.toLowerCase().includes(\"application/json\")) {\n try {\n return JSON.parse(bodyText) as ParsedResponseBody;\n } catch {\n // Fall through and return text body below so error messages stay useful.\n }\n }\n\n try {\n return JSON.parse(bodyText) as ParsedResponseBody;\n } catch {\n return bodyText;\n }\n}\n\nexport function getErrorMessage(\n data: ParsedResponseBody,\n fallback: string\n): string {\n if (data && typeof data === \"object\" && !Array.isArray(data)) {\n const maybeMessage = (data as Record<string, unknown>).message;\n if (typeof maybeMessage === \"string\" && maybeMessage.trim()) {\n return maybeMessage;\n }\n }\n\n if (typeof data === \"string\" && data.trim()) {\n const compact = data.replace(/\\s+/g, \" \").trim();\n const snippet = compact.length > 180 ? `${compact.slice(0, 180)}...` : compact;\n return `${fallback}. Server returned non-JSON response: ${snippet}`;\n }\n\n return fallback;\n}\n","/** Delays between handler delivery attempts (after attempts 1–7). */\nexport const HANDLER_RETRY_DELAYS_MS = [\n 60_000, // 1m\n 300_000, // 5m\n 1_800_000, // 30m\n 3_600_000, // 1h\n 21_600_000, // 6h\n 86_400_000, // 24h\n 172_800_000, // 48h\n] as const;\n\nexport const HANDLER_MAX_ATTEMPTS = HANDLER_RETRY_DELAYS_MS.length + 1;\n\nexport const HANDLER_FETCH_TIMEOUT_MS = 30_000;\n\nexport function handlerRetryDelayMs(failedAttempt: number): number | null {\n if (failedAttempt < 1 || failedAttempt >= HANDLER_MAX_ATTEMPTS) {\n return null;\n }\n return HANDLER_RETRY_DELAYS_MS[failedAttempt - 1] ?? null;\n}\n\nexport function isRetriableHandlerFailure(\n statusCode: number | undefined,\n _error?: string\n): boolean {\n if (statusCode === undefined) {\n return true;\n }\n if (statusCode >= 200 && statusCode < 300) {\n return false;\n }\n if (statusCode === 408 || statusCode === 429) {\n return true;\n }\n if (statusCode >= 500) {\n return true;\n }\n return false;\n}\n","import { z } from \"zod\";\nimport { getAppBaseUrl } from \"../app-url\";\n\nexport { APP_SIGNUP_URL } from \"../app-url\";\n\nexport const ATTRIBUTION_COOKIE_NAME = \"rr_attribution\";\nexport const ATTRIBUTION_COOKIE_MAX_AGE = 60 * 60 * 24 * 90; // 90 days\nexport const ATTRIBUTION_COOKIE_DOMAIN = \".robotrock.io\";\n\nconst UTM_PARAM_MAP = {\n utm_source: \"utmSource\",\n utm_medium: \"utmMedium\",\n utm_campaign: \"utmCampaign\",\n utm_content: \"utmContent\",\n utm_term: \"utmTerm\",\n gclid: \"gclid\",\n} as const;\n\nexport const attributionSchema = z.object({\n utmSource: z.string().optional(),\n utmMedium: z.string().optional(),\n utmCampaign: z.string().optional(),\n utmContent: z.string().optional(),\n utmTerm: z.string().optional(),\n gclid: z.string().optional(),\n landingUrl: z.string().optional(),\n referrer: z.string().optional(),\n capturedAt: z.number(),\n});\n\nexport type Attribution = z.infer<typeof attributionSchema>;\n\nexport function hasAttributionSignal(attribution: Partial<Attribution>): boolean {\n return Boolean(\n attribution.utmSource ||\n attribution.utmMedium ||\n attribution.utmCampaign ||\n attribution.utmContent ||\n attribution.utmTerm ||\n attribution.gclid\n );\n}\n\nexport function parseAttributionFromSearchParams(\n params: URLSearchParams | Record<string, string | string[] | undefined>\n): Partial<Attribution> {\n const getParam = (key: string): string | undefined => {\n if (params instanceof URLSearchParams) {\n return params.get(key)?.trim() || undefined;\n }\n const value = params[key];\n if (Array.isArray(value)) {\n return value[0]?.trim() || undefined;\n }\n return value?.trim() || undefined;\n };\n\n const result: Partial<Attribution> = {};\n\n for (const [param, field] of Object.entries(UTM_PARAM_MAP)) {\n const value = getParam(param);\n if (value) {\n result[field as keyof typeof UTM_PARAM_MAP & keyof Partial<Attribution>] =\n value;\n }\n }\n\n return result;\n}\n\nexport function buildAttributionFromRequest(input: {\n searchParams: URLSearchParams;\n landingUrl?: string;\n referrer?: string;\n capturedAt?: number;\n}): Attribution | null {\n const parsed = parseAttributionFromSearchParams(input.searchParams);\n if (!hasAttributionSignal(parsed)) {\n return null;\n }\n\n return attributionSchema.parse({\n ...parsed,\n landingUrl: input.landingUrl,\n referrer: input.referrer || undefined,\n capturedAt: input.capturedAt ?? Date.now(),\n });\n}\n\nexport function serializeAttributionCookie(attribution: Attribution): string {\n return encodeURIComponent(JSON.stringify(attribution));\n}\n\nexport function parseAttributionCookie(raw: string | undefined | null): Attribution | null {\n if (!raw) return null;\n\n const candidates = [raw];\n try {\n const decoded = decodeURIComponent(raw);\n if (decoded !== raw) {\n candidates.push(decoded);\n }\n } catch {\n // Keep only the raw value.\n }\n\n for (const candidate of candidates) {\n try {\n const parsed = attributionSchema.parse(JSON.parse(candidate));\n if (hasAttributionSignal(parsed)) {\n return parsed;\n }\n } catch {\n continue;\n }\n }\n\n return null;\n}\n\nexport function formatAttributionCampaign(\n attribution: Partial<Attribution> | null | undefined\n): string | null {\n if (!attribution) return null;\n return attribution.utmCampaign ?? attribution.utmSource ?? null;\n}\n\nexport function appendAttributionToUrl(\n baseUrl: string,\n attribution: Partial<Attribution> | null | undefined,\n origin = getAppBaseUrl()\n): string {\n if (!attribution || !hasAttributionSignal(attribution)) {\n return baseUrl;\n }\n\n const url = baseUrl.startsWith(\"http\")\n ? new URL(baseUrl)\n : new URL(baseUrl, origin);\n const paramEntries: Array<[string, string | undefined]> = [\n [\"utm_source\", attribution.utmSource],\n [\"utm_medium\", attribution.utmMedium],\n [\"utm_campaign\", attribution.utmCampaign],\n [\"utm_content\", attribution.utmContent],\n [\"utm_term\", attribution.utmTerm],\n [\"gclid\", attribution.gclid],\n ];\n\n for (const [param, value] of paramEntries) {\n if (value) {\n url.searchParams.set(param, value);\n }\n }\n\n return baseUrl.startsWith(\"http\")\n ? url.toString()\n : `${url.pathname}${url.search}${url.hash}`;\n}\n\nexport function getAttributionCookieDomain(hostname: string): string | undefined {\n if (hostname === \"localhost\" || hostname.endsWith(\".localhost\")) {\n return undefined;\n }\n if (hostname === \"robotrock.io\" || hostname.endsWith(\".robotrock.io\")) {\n return ATTRIBUTION_COOKIE_DOMAIN;\n }\n return undefined;\n}\n","export const PRODUCTION_APP_URL = \"https://app.robotrock.io\";\nexport const DEV_APP_URL = \"http://localhost:4004\";\nexport const DEV_API_URL = \"http://localhost:4001/v1\";\nexport const DEV_DOCS_URL = \"http://localhost:4002\";\n\n/** Local dev server ports for all RobotRock apps (4000–4008). */\nexport const DEV_PORTS = {\n marketing: 4000,\n api: 4001,\n docs: 4002,\n status: 4003,\n app: 4004,\n admin: 4005,\n triggerTest: 4006,\n workflowTest: 4007,\n mcp: 4008,\n} as const;\n\n/** Production signup URL (stable constant for tests and production defaults). */\nexport const APP_SIGNUP_URL = `${PRODUCTION_APP_URL}/sign-up`;\n\nfunction readExplicitAppUrl(): string | undefined {\n const url =\n process.env.NEXT_PUBLIC_APP_URL?.trim() ||\n process.env.NEXT_PUBLIC_APP_PREVIEW_URL?.trim();\n return url ? url.replace(/\\/$/, \"\") : undefined;\n}\n\n/** Dashboard origin — localhost:4004 in dev unless overridden via env. */\nexport function getAppBaseUrl(): string {\n const explicit = readExplicitAppUrl();\n if (explicit) return explicit;\n if (process.env.NODE_ENV === \"development\") {\n return DEV_APP_URL;\n }\n return PRODUCTION_APP_URL;\n}\n\nexport function getAppSignupBaseUrl(): string {\n return `${getAppBaseUrl()}/sign-up`;\n}\n","import {\n createAgentChatBodySchema,\n type AgentChatSeedMessage,\n type AssignToInput,\n} from \"@robotrock/core\";\nimport { RobotRockError, getErrorMessage, parseResponseBody } from \"./http.js\";\n\n/** A chat created via {@link ChatsApi.create}. */\nexport type CreatedChat = {\n chatId: string;\n sessionId: string;\n userId?: string;\n agentIdentifier: string;\n deepLink: string;\n};\n\nexport type CreateChatResult = {\n tenantSlug: string;\n chats: CreatedChat[];\n};\n\nexport type CreateChatInput = {\n /** Agent to run the chat. Required unless `parentChatId` is provided. */\n agentIdentifier?: string;\n /** Spawn a chat from an existing chat; inherits its agent/app/owner and links audit. */\n parentChatId?: string;\n /** Trigger connection id to run the chat under (defaults to the tenant's). */\n connectionId?: string;\n /** Inbox app bucket. Overrides the client `app` when set. */\n app?: string;\n /** Assign to tenant users (email) and/or groups (slug). Narrows inbox visibility. */\n assignTo?: AssignToInput;\n /** Chat title shown in the inbox. */\n title: string;\n /** Seed messages to preload the conversation. Defaults to a welcome message. */\n messages?: AgentChatSeedMessage[];\n /** How the chat was created (statistics/audit). @default \"api\" */\n source?: string;\n};\n\nexport type CloseChatOptions = {\n /** Optional human-readable reason recorded on the audit trail. */\n reason?: string;\n};\n\nexport interface ChatsApi {\n /** Create one or more agent chats and assign them (task-style). */\n create(input: CreateChatInput): Promise<CreateChatResult>;\n /** Close (archive) a chat by its public chatId — e.g. when an agent is done. */\n close(chatId: string, options?: CloseChatOptions): Promise<void>;\n}\n\n/**\n * Build the `client.chats` namespace. Mirrors the `client.tasks` surface for the\n * long-lived chat resource, so a single client creates both tasks and chats.\n */\nexport function createChatsApi(config: {\n baseUrl: string;\n apiKey: string;\n app?: string;\n}): ChatsApi {\n const headers = (): Record<string, string> => ({\n \"Content-Type\": \"application/json\",\n \"X-Api-Key\": config.apiKey,\n });\n\n return {\n async create(input: CreateChatInput): Promise<CreateChatResult> {\n const bodyPayload = {\n ...input,\n app: input.app ?? config.app,\n messages: input.messages ?? [],\n };\n const validation = createAgentChatBodySchema.safeParse(bodyPayload);\n if (!validation.success) {\n throw new RobotRockError(\n `Invalid chat: ${validation.error.issues[0]?.message}`,\n 400,\n validation.error.issues\n );\n }\n\n const response = await fetch(`${config.baseUrl}/agent-chats`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(validation.data),\n });\n\n const data = await parseResponseBody(response);\n if (!response.ok) {\n throw new RobotRockError(\n getErrorMessage(data, \"Failed to create chat\"),\n response.status,\n data\n );\n }\n\n const result = data as unknown as CreateChatResult;\n return { tenantSlug: result.tenantSlug, chats: result.chats };\n },\n\n async close(chatId: string, options?: CloseChatOptions): Promise<void> {\n if (!chatId) {\n throw new RobotRockError(\"chatId is required to close a chat\", 400);\n }\n\n const response = await fetch(\n `${config.baseUrl}/agent-chats/${encodeURIComponent(chatId)}/close`,\n {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ reason: options?.reason }),\n }\n );\n\n if (!response.ok) {\n const data = await parseResponseBody(response);\n throw new RobotRockError(\n getErrorMessage(data, \"Failed to close chat\"),\n response.status,\n data\n );\n }\n },\n };\n}\n","import {\n type AssignToInput,\n type TaskContextInput,\n createTaskBodySchema,\n threadUpdateBodySchema,\n TASK_CONTEXT_FORMAT_VERSION,\n} from \"./schemas/index.js\";\nimport {\n TaskExpiredError,\n TaskTimeoutError,\n toDiscriminatedApprovalResult,\n} from \"./approval-result.js\";\nimport { RobotRockError, getErrorMessage, parseResponseBody } from \"./http.js\";\nimport { createChatsApi, type ChatsApi } from \"./chats.js\";\nimport type {\n DiscriminatedApprovalResult,\n Task,\n TaskPriority,\n TaskResponse,\n ThreadUpdate,\n ThreadUpdateResponse,\n ThreadUpdateStatus,\n TaskContextFormatVersion,\n} from \"./schemas/index.js\";\n\nexport type RobotRockWebhookConfig = {\n url: string;\n headers?: Record<string, string>;\n};\n\nexport interface RobotRockPollingOptions {\n /** Poll interval when no webhook is configured (ms). @default 2000 */\n intervalMs?: number;\n /**\n * Max time to poll when no webhook is configured (ms).\n * Polling also stops when the task's `validUntil` passes, whichever is sooner.\n * @default 86400000 (24h)\n */\n timeoutMs?: number;\n};\n\n/** Advanced client settings rarely changed by integrators. */\nexport type RobotRockAdvancedConfig = {\n /** Task context wire format version sent on every request. @default 2 */\n contextVersion?: TaskContextFormatVersion;\n};\n\ntype RobotRockClientBaseConfig = {\n /** Optional override for API key. Falls back to ROBOTROCK_API_KEY. */\n apiKey?: string;\n /**\n * Base URL for the RobotRock API\n * @default \"https://api.robotrock.io/v1\"\n */\n baseUrl?: string;\n /**\n * Default inbox app bucket for every task from this client.\n * When omitted, the API uses your API key name.\n */\n app?: string;\n /**\n * Agent release version (semver, git SHA, deploy tag).\n * Defaults to `AGENT_VERSION` or `ROBOTROCK_AGENT_VERSION` from env when omitted.\n */\n version?: string;\n /** Advanced settings (context wire format, etc.). */\n advanced?: RobotRockAdvancedConfig;\n};\n\n/** Client config with a webhook (mutually exclusive with `polling`). */\nexport type RobotRockWebhookClientConfig = RobotRockClientBaseConfig & {\n webhook: RobotRockWebhookConfig;\n polling?: never;\n};\n\n/** Client config without a webhook; optional `polling` controls the wait loop. */\nexport type RobotRockPollingClientConfig = RobotRockClientBaseConfig & {\n webhook?: never;\n polling?: RobotRockPollingOptions;\n};\n\nexport type RobotRockConfig = RobotRockWebhookClientConfig | RobotRockPollingClientConfig;\n\nexport type SendToHumanActionInput = Omit<TaskContextInput[\"actions\"][number], \"handlers\">;\n\nexport type SendToHumanValidUntil = Date | string;\n\nexport type SendToHumanInput<\n A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[],\n> = Omit<TaskContextInput, \"app\" | \"actions\" | \"contextVersion\" | \"version\" | \"validUntil\"> & {\n actions: A;\n /** Task deadline; serialized to an ISO 8601 string on the wire. */\n validUntil?: SendToHumanValidUntil;\n /** Optional idempotency key to prevent duplicate tasks */\n idempotencyKey?: string;\n /** Assign to tenant users (email) and/or groups (slug). Narrows inbox visibility. */\n assignTo?: AssignToInput;\n /**\n * Groups related tasks together in the inbox. Omit to let the server generate\n * one (returned as `task.threadId`) and reuse it on later tasks in the thread.\n */\n threadId?: string;\n /**\n * Optional thread priority. When set, applies to the whole thread and\n * overwrites any previous priority. Omit on later tasks to leave unchanged.\n */\n priority?: TaskPriority;\n /**\n * Optional initial status update logged against the task's thread. Shows in\n * the inbox status bar and the thread update log.\n */\n update?: {\n /** A short status update (1-2 sentences). */\n message: string;\n /** Lifecycle status for the icon/color in the status bar. @default \"info\" */\n status?: ThreadUpdateStatus;\n };\n /**\n * Agent release version override. When omitted, uses the client `version`.\n * Used for statistics and feedback analysis.\n */\n version?: string;\n};\n\ntype SendToHumanWithAppInput<\n A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[],\n> = (SendToHumanInput<A> | Readonly<SendToHumanInput<A>>) & {\n /** Inbox app bucket. Overrides the client `app` when set. */\n app?: string;\n};\n\nexport type SendUpdateInput = {\n /** The thread to log the update against (from `task.threadId`). */\n threadId: string;\n /** A short status update (1-2 sentences). */\n message: string;\n /** Lifecycle status for the icon/color in the status bar. @default \"info\" */\n status?: ThreadUpdateStatus;\n};\n\nexport type SendToHumanResult<\n A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[],\n> =\n | {\n mode: \"created\";\n task: TaskResponse[\"task\"];\n }\n | ({\n mode: \"handled\";\n task: TaskResponse[\"task\"];\n } & DiscriminatedApprovalResult<A>);\n\nconst DEFAULT_POLL_INTERVAL_MS = 2_000;\nconst DEFAULT_TIMEOUT_MS = 24 * 60 * 60 * 1_000;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction resolveAgentVersionFromEnv(): string | undefined {\n const fromEnv =\n process.env.AGENT_VERSION?.trim() || process.env.ROBOTROCK_AGENT_VERSION?.trim();\n return fromEnv || undefined;\n}\n\nfunction parseValidUntilMs(value: string | number | Date | undefined): number | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n if (value instanceof Date) {\n const ms = value.getTime();\n return Number.isNaN(ms) ? undefined : ms;\n }\n\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value : undefined;\n }\n\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? undefined : parsed;\n}\n\nfunction serializeValidUntil(value: SendToHumanValidUntil): string {\n if (value instanceof Date) {\n const ms = value.getTime();\n if (Number.isNaN(ms)) {\n throw new RobotRockError(\"Invalid validUntil: Date is invalid\", 400);\n }\n return value.toISOString();\n }\n\n if (typeof value === \"string\" && !Number.isNaN(Date.parse(value))) {\n return new Date(value).toISOString();\n }\n\n throw new RobotRockError(\"Invalid validUntil: expected a Date or parseable date string\", 400);\n}\n\nexport { RobotRockError } from \"./http.js\";\n\n/** Task CRUD surface, exposed as `client.tasks`. */\nexport interface TasksApi {\n /** Create a task via POST /v1 without waiting for a human response. */\n create<const A extends readonly SendToHumanActionInput[]>(\n task: SendToHumanWithAppInput<A>\n ): Promise<TaskResponse[\"task\"]>;\n /** Get a task by public task id. */\n get(taskId: string): Promise<Task | null>;\n /** Cancel a task by public task id. */\n cancel(taskId: string): Promise<void>;\n /** Log a status update against a thread. */\n sendUpdate(input: SendUpdateInput): Promise<ThreadUpdate>;\n}\n\n/**\n * RobotRock API client for creating and querying human-in-the-loop tasks and\n * chats. CRUD lives under `client.tasks` and `client.chats`; the headline\n * `sendToHuman` verb stays top-level.\n */\nexport class RobotRock {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly app?: string;\n private readonly agentVersion?: string;\n private readonly contextVersion: TaskContextFormatVersion;\n private readonly webhook?: RobotRockWebhookConfig;\n private readonly polling: RobotRockPollingOptions;\n\n /** Task CRUD: `create`, `get`, `cancel`, `sendUpdate`. */\n readonly tasks: TasksApi;\n /** Chat CRUD: `create`, `close`. */\n readonly chats: ChatsApi;\n\n constructor(config: RobotRockConfig) {\n if (config.webhook && config.polling) {\n throw new Error(\n \"RobotRock client cannot configure both webhook and polling. Use webhook for callbacks or polling to block until handled.\"\n );\n }\n\n const apiKey = config.apiKey ?? process.env.ROBOTROCK_API_KEY;\n if (!apiKey) {\n throw new Error(\n \"RobotRock API key is required. Set ROBOTROCK_API_KEY or pass apiKey when creating the client.\"\n );\n }\n this.apiKey = apiKey;\n const rawBase = config.baseUrl ?? \"https://api.robotrock.io/v1\";\n this.baseUrl = rawBase.replace(/\\/+$/, \"\");\n this.app = config.app;\n this.agentVersion = config.version ?? resolveAgentVersionFromEnv();\n this.contextVersion =\n config.advanced?.contextVersion ?? TASK_CONTEXT_FORMAT_VERSION;\n this.webhook = config.webhook;\n this.polling = config.polling ?? {};\n\n this.tasks = {\n create: (task) => this.createTaskRequest(task),\n get: (taskId) => this.getTaskById(taskId),\n cancel: (taskId) => this.cancelTaskRequest(taskId),\n sendUpdate: (input) => this.sendThreadUpdate(input),\n };\n this.chats = createChatsApi({\n baseUrl: this.baseUrl,\n apiKey: this.apiKey,\n app: this.app,\n });\n }\n\n private async createTaskRequest<const A extends readonly SendToHumanActionInput[]>(\n task: SendToHumanWithAppInput<A>\n ): Promise<TaskResponse[\"task\"]> {\n const normalizedTask = normalizeSendToHumanInput(task, {\n webhook: this.webhook,\n app: this.app,\n contextVersion: this.contextVersion,\n agentVersion: this.agentVersion,\n });\n const agentVersion = task.version ?? this.agentVersion;\n const bodyPayload = {\n ...normalizedTask,\n ...(task.assignTo !== undefined ? { assignTo: task.assignTo } : {}),\n ...(task.threadId !== undefined ? { threadId: task.threadId } : {}),\n ...(task.priority !== undefined ? { priority: task.priority } : {}),\n ...(task.update !== undefined ? { update: task.update } : {}),\n ...(agentVersion !== undefined ? { agent: { version: agentVersion } } : {}),\n };\n const validation = createTaskBodySchema.safeParse(bodyPayload);\n if (!validation.success) {\n throw new RobotRockError(\n `Invalid task: ${validation.error.issues[0]?.message}`,\n 400,\n validation.error.issues\n );\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"X-Api-Key\": this.apiKey,\n };\n\n if (task.idempotencyKey) {\n headers[\"Idempotency-Key\"] = task.idempotencyKey;\n }\n\n const response = await fetch(`${this.baseUrl}/`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(validation.data),\n });\n\n const data = await parseResponseBody(response);\n\n if (!response.ok) {\n throw new RobotRockError(\n getErrorMessage(data, \"Failed to create task\"),\n response.status,\n data\n );\n }\n\n return (data as unknown as TaskResponse).task;\n }\n\n async sendToHuman<const A extends readonly SendToHumanActionInput[]>(\n task: SendToHumanWithAppInput<A>\n ): Promise<SendToHumanResult<A>> {\n const normalizedTask = normalizeSendToHumanInput(task, {\n webhook: this.webhook,\n app: this.app,\n contextVersion: this.contextVersion,\n agentVersion: this.agentVersion,\n });\n const createdTaskTask = await this.createTaskRequest(task);\n const hasHandlers = normalizedTask.actions.some(\n (action) => Array.isArray(action.handlers) && action.handlers.length > 0\n );\n\n if (hasHandlers) {\n return {\n mode: \"created\",\n task: createdTaskTask,\n };\n }\n\n const timeoutMs = this.polling.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const pollIntervalMs = this.polling.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;\n const pollingDeadline = Date.now() + timeoutMs;\n const validUntilMs = parseValidUntilMs(createdTaskTask.validUntil);\n const deadline =\n validUntilMs !== undefined ? Math.min(pollingDeadline, validUntilMs) : pollingDeadline;\n const taskId = createdTaskTask.taskId;\n\n while (Date.now() < deadline) {\n const existing = await this.getTaskById(taskId);\n\n if (existing?.status === \"handled\" && existing.handled) {\n return {\n mode: \"handled\",\n task: createdTaskTask,\n ...(toDiscriminatedApprovalResult(\n normalizedTask.actions as unknown as A,\n existing\n ) as DiscriminatedApprovalResult<A>),\n };\n }\n\n if (existing?.status === \"expired\" || (existing && Date.now() >= existing.validUntil)) {\n throw new TaskExpiredError(\"Task reached validUntil before a human completed it\");\n }\n\n const remainingMs = deadline - Date.now();\n await sleep(Math.min(pollIntervalMs, Math.max(0, remainingMs)));\n }\n\n if (validUntilMs !== undefined && Date.now() >= validUntilMs) {\n throw new TaskExpiredError(\"Task reached validUntil before a human completed it\");\n }\n\n throw new TaskTimeoutError(`No human response within ${timeoutMs}ms`);\n }\n\n /**\n * Create a task via POST /v1 without waiting for a human response.\n * @deprecated Use `client.tasks.create()` instead.\n */\n async createTask<const A extends readonly SendToHumanActionInput[]>(\n task: SendToHumanWithAppInput<A>\n ): Promise<TaskResponse[\"task\"]> {\n return this.tasks.create(task);\n }\n\n /**\n * Get a task by public task id (returned as `task.taskId` from {@link sendToHuman}).\n * @deprecated Use `client.tasks.get()` instead.\n */\n async getTask(taskId: string): Promise<Task | null> {\n return this.tasks.get(taskId);\n }\n\n /**\n * Log a status update against a thread.\n * @deprecated Use `client.tasks.sendUpdate()` instead.\n */\n async sendUpdate(input: SendUpdateInput): Promise<ThreadUpdate> {\n return this.tasks.sendUpdate(input);\n }\n\n /**\n * Cancel a task by public task id.\n * @deprecated Use `client.tasks.cancel()` instead.\n */\n async cancelTask(taskId: string): Promise<void> {\n return this.tasks.cancel(taskId);\n }\n\n private async getTaskById(taskId: string): Promise<Task | null> {\n const response = await fetch(`${this.baseUrl}/tasks/${taskId}`, {\n method: \"GET\",\n headers: {\n \"X-Api-Key\": this.apiKey,\n },\n });\n\n if (response.status === 404) {\n return null;\n }\n\n const data = await parseResponseBody(response);\n\n if (!response.ok) {\n throw new RobotRockError(\n getErrorMessage(data, \"Failed to get task\"),\n response.status,\n data\n );\n }\n\n return data as unknown as Task;\n }\n\n private async sendThreadUpdate({\n threadId,\n message,\n status,\n }: SendUpdateInput): Promise<ThreadUpdate> {\n if (!threadId) {\n throw new RobotRockError(\"threadId is required to send an update\", 400);\n }\n\n const validation = threadUpdateBodySchema.safeParse({ message, status });\n if (!validation.success) {\n throw new RobotRockError(\n `Invalid update: ${validation.error.issues[0]?.message}`,\n 400,\n validation.error.issues\n );\n }\n\n const response = await fetch(\n `${this.baseUrl}/threads/${encodeURIComponent(threadId)}/updates`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Api-Key\": this.apiKey,\n },\n body: JSON.stringify(validation.data),\n }\n );\n\n const data = await parseResponseBody(response);\n\n if (!response.ok) {\n throw new RobotRockError(\n getErrorMessage(data, \"Failed to send update\"),\n response.status,\n data\n );\n }\n\n return (data as unknown as ThreadUpdateResponse).update;\n }\n\n private async cancelTaskRequest(taskId: string): Promise<void> {\n const response = await fetch(`${this.baseUrl}/tasks/${taskId}/cancel`, {\n method: \"POST\",\n headers: {\n \"X-Api-Key\": this.apiKey,\n },\n });\n\n if (!response.ok) {\n const data = await parseResponseBody(response);\n throw new RobotRockError(\n getErrorMessage(data, \"Failed to cancel task\"),\n response.status,\n data\n );\n }\n }\n}\n\nexport function createClient(config: RobotRockConfig): RobotRock {\n return new RobotRock(config);\n}\n\nexport function attachWebhookToActions(\n actions: readonly SendToHumanActionInput[],\n webhook: RobotRockWebhookConfig\n): TaskContextInput[\"actions\"] {\n return actions.map((action) => ({\n ...action,\n handlers: webhookToHandlers(webhook),\n }));\n}\n\nfunction webhookToHandlers(\n webhook: RobotRockWebhookConfig\n): TaskContextInput[\"actions\"][number][\"handlers\"] {\n return [\n {\n type: \"webhook\" as const,\n url: webhook.url,\n headers: webhook.headers ?? {},\n },\n ];\n}\n\nfunction normalizeSendToHumanInput<\n A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[],\n>(\n task: SendToHumanWithAppInput<A>,\n clientDefaults: {\n webhook?: RobotRockWebhookConfig;\n app?: string;\n contextVersion: TaskContextFormatVersion;\n agentVersion?: string;\n }\n): TaskContextInput {\n const {\n actions,\n idempotencyKey: _idempotencyKey,\n assignTo: _assignTo,\n threadId: _threadId,\n priority: _priority,\n update: _update,\n version: _version,\n validUntil,\n app: taskApp,\n ...rest\n } = task;\n\n const webhook = clientDefaults.webhook;\n const normalizedActions: TaskContextInput[\"actions\"] = webhook\n ? attachWebhookToActions(actions, webhook)\n : (actions as unknown as TaskContextInput[\"actions\"]);\n\n const app = taskApp ?? clientDefaults.app;\n\n return {\n ...rest,\n contextVersion: clientDefaults.contextVersion,\n ...(app ? { app } : {}),\n ...(validUntil !== undefined ? { validUntil: serializeValidUntil(validUntil) } : {}),\n actions: normalizedActions,\n };\n}\n\n","import { createClient, type RobotRock, type RobotRockConfig } from \"./client.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.robotrock.io/v1\";\n\n/**\n * Read RobotRock client config from environment variables.\n *\n * - `ROBOTROCK_API_KEY` (required when not passed explicitly)\n * - `ROBOTROCK_BASE_URL` or `ROBOTROCK_API_URL` (optional)\n * - `ROBOTROCK_APP` (optional inbox app bucket)\n */\nexport function resolveRobotRockConfig(\n overrides?: Partial<RobotRockConfig>\n): RobotRockConfig {\n const apiKey = overrides?.apiKey ?? process.env.ROBOTROCK_API_KEY;\n if (!apiKey) {\n throw new Error(\n \"RobotRock API key is required. Set ROBOTROCK_API_KEY or pass apiKey when creating the client.\"\n );\n }\n\n const baseUrl =\n overrides?.baseUrl ??\n process.env.ROBOTROCK_BASE_URL ??\n process.env.ROBOTROCK_API_URL ??\n DEFAULT_BASE_URL;\n\n const app = overrides?.app ?? process.env.ROBOTROCK_APP;\n\n return app ? { apiKey, baseUrl, app } : { apiKey, baseUrl };\n}\n\n/** Use an explicit client or create one from env / optional config overrides. */\nexport function resolveRobotRockClient(\n client?: RobotRock,\n configOverrides?: Partial<RobotRockConfig>\n): RobotRock {\n if (client) {\n return client;\n }\n return createClient(resolveRobotRockConfig(configOverrides));\n}\n","/**\n * JSON body posted when a RobotRock action handler runs (webhook or Trigger wait token).\n */\nexport interface RobotRockHandlerWebhookPayload {\n taskId: string;\n action: {\n id: string;\n title: string;\n data: unknown;\n };\n handledBy?: string;\n handledAt: string;\n handlerType: string;\n}\n\nexport function isRobotRockHandlerWebhookPayload(\n value: unknown\n): value is RobotRockHandlerWebhookPayload {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const v = value as Record<string, unknown>;\n if (typeof v.taskId !== \"string\" || typeof v.handledAt !== \"string\") {\n return false;\n }\n const action = v.action;\n if (typeof action !== \"object\" || action === null) {\n return false;\n }\n const a = action as Record<string, unknown>;\n return typeof a.id === \"string\" && \"data\" in a;\n}\n","/** Default wait when `validUntil` is omitted. */\nexport const DEFAULT_WAIT_DURATION_MS = 7 * 24 * 60 * 60 * 1000;\n\nexport function resolveWaitTiming(validUntilInput?: Date | string): {\n validUntil: Date | string;\n timeout: string;\n} {\n const validUntilMs =\n validUntilInput !== undefined\n ? parseValidUntilMs(validUntilInput)\n : Date.now() + DEFAULT_WAIT_DURATION_MS;\n\n const durationMs = validUntilMs - Date.now();\n if (durationMs <= 0) {\n throw new Error(\"validUntil must be in the future\");\n }\n\n return {\n validUntil: validUntilInput ?? new Date(validUntilMs),\n timeout: durationMsToTimeout(durationMs),\n };\n}\n\nexport function parseValidUntilMs(value: Date | string): number {\n if (value instanceof Date) {\n const ms = value.getTime();\n if (Number.isNaN(ms)) {\n throw new Error(\"Invalid validUntil: Date is invalid\");\n }\n return ms;\n }\n\n const parsed = Date.parse(value);\n if (Number.isNaN(parsed)) {\n throw new Error(\"Invalid validUntil: expected a parseable date string\");\n }\n\n return parsed;\n}\n\n/** Duration string for Trigger.dev `wait.createToken` and Workflow `sleep`. */\nexport function durationMsToTimeout(durationMs: number): string {\n const seconds = Math.ceil(durationMs / 1000);\n if (seconds <= 0) {\n throw new Error(\"validUntil must be in the future\");\n }\n\n if (seconds >= 86_400) {\n return `${Math.ceil(seconds / 86_400)}d`;\n }\n if (seconds >= 3_600) {\n return `${Math.ceil(seconds / 3_600)}h`;\n }\n if (seconds >= 60) {\n return `${Math.ceil(seconds / 60)}m`;\n }\n\n return `${seconds}s`;\n}\n","import {\n context,\n trace,\n SpanStatusCode,\n type Span,\n} from \"@opentelemetry/api\";\nimport type { ApprovalResult, DiscriminatedApprovalResult } from \"./schemas/index.js\";\nimport type { RobotRockHandlerWebhookPayload } from \"./handler-webhook.js\";\n\n/** Minimal span surface used by handle-time OTel recording. */\nexport type OtelSpanLike = Pick<Span, \"spanContext\" | \"setAttribute\" | \"addEvent\" | \"setStatus\" | \"end\">;\n\nconst TRACER_NAME = \"robotrock\";\nconst WAIT_SPAN_NAME = \"robotrock.wait_for_human\";\nconst HANDLED_EVENT_NAME = \"robotrock.task_handled\";\n\nconst INVALID_TRACE_ID = \"00000000000000000000000000000000\";\n\nexport type RobotRockOtelHandle = {\n traceId: string;\n spanId: string;\n taskId: string;\n taskCreatedAt: number;\n threadId?: string;\n};\n\nexport type RobotRockOtelRecordOptions = {\n handle?: RobotRockOtelHandle;\n span?: OtelSpanLike | Span | null;\n includeActionData?: boolean;\n tracerName?: string;\n};\n\nexport type RobotRockHandledOtelInput = {\n taskId: string;\n threadId?: string;\n action: { id: string; title?: string; data: unknown };\n handledBy?: string;\n handledAt: string | number | Date;\n};\n\nfunction isValidTraceId(traceId: string | undefined): traceId is string {\n return (\n typeof traceId === \"string\" &&\n traceId.length > 0 &&\n traceId !== INVALID_TRACE_ID\n );\n}\n\nfunction resolveSpanContext(\n span?: OtelSpanLike | Span | null\n): { traceId: string; spanId: string } | undefined {\n const active = span ?? trace.getActiveSpan();\n const ctx = active?.spanContext();\n if (!ctx || !isValidTraceId(ctx.traceId)) {\n return undefined;\n }\n return { traceId: ctx.traceId, spanId: ctx.spanId };\n}\n\nfunction parseTaskCreatedAt(submittedAt?: string): number {\n if (submittedAt) {\n const parsed = Date.parse(submittedAt);\n if (!Number.isNaN(parsed)) {\n return parsed;\n }\n }\n return Date.now();\n}\n\nfunction parseHandledAtMs(handledAt: string | number | Date): number {\n if (handledAt instanceof Date) {\n return handledAt.getTime();\n }\n if (typeof handledAt === \"number\") {\n return handledAt;\n }\n const parsed = Date.parse(handledAt);\n return Number.isNaN(parsed) ? Date.now() : parsed;\n}\n\nexport type RobotRockHandledRecordInput =\n | RobotRockHandlerWebhookPayload\n | ApprovalResult\n | DiscriminatedApprovalResult<readonly { id: string; schema?: unknown }[]>;\n\n/** Normalize handled payloads from Trigger, Workflow, or polling. */\nexport function toRobotRockHandledOtelInput(\n handled: RobotRockHandledRecordInput\n): RobotRockHandledOtelInput {\n if (\"actionId\" in handled) {\n return {\n taskId: handled.taskId,\n action: {\n id: handled.actionId,\n data: handled.data,\n },\n handledBy: handled.handledBy,\n handledAt: handled.handledAt,\n };\n }\n\n return {\n taskId: handled.taskId,\n action: {\n id: handled.action.id,\n title: handled.action.title,\n data: handled.action.data,\n },\n handledBy: handled.handledBy,\n handledAt: handled.handledAt,\n };\n}\n\n/**\n * Capture trace + task metadata after RobotRock task create (before human wait).\n * Used by Trigger.dev and Vercel Workflow durable integrations.\n */\nexport function captureRobotRockOtelHandle(\n task: { taskId: string; threadId?: string; submittedAt?: string },\n options?: { span?: OtelSpanLike | Span | null }\n): RobotRockOtelHandle {\n const spanCtx = resolveSpanContext(options?.span);\n return {\n traceId: spanCtx?.traceId ?? \"\",\n spanId: spanCtx?.spanId ?? \"\",\n taskId: task.taskId,\n threadId: task.threadId,\n taskCreatedAt: parseTaskCreatedAt(task.submittedAt),\n };\n}\n\n/**\n * Start a child span for the human-wait phase on the active trace.\n */\nexport function startRobotRockHumanWaitSpan(\n handle: RobotRockOtelHandle,\n options?: { tracerName?: string; span?: OtelSpanLike | Span | null }\n): Span | undefined {\n const parent = (options?.span ?? trace.getActiveSpan()) as Span | undefined;\n if (!parent) {\n return undefined;\n }\n\n const tracer = trace.getTracer(options?.tracerName ?? TRACER_NAME);\n const span = tracer.startSpan(\n WAIT_SPAN_NAME,\n {},\n trace.setSpan(context.active(), parent)\n );\n\n span.setAttribute(\"robotrock.task_id\", handle.taskId);\n if (handle.threadId) {\n span.setAttribute(\"robotrock.thread_id\", handle.threadId);\n }\n\n return span;\n}\n\n/**\n * Record human action attributes and a span event on the active or wait span.\n */\nexport function recordRobotRockHandledToOtel(\n handled: RobotRockHandledRecordInput,\n options: RobotRockOtelRecordOptions = {}\n): void {\n const span = (options.span ?? trace.getActiveSpan()) as Span | undefined;\n if (!span) {\n return;\n }\n\n const input = toRobotRockHandledOtelInput(handled);\n const handledAtMs = parseHandledAtMs(input.handledAt);\n const handle = options.handle;\n const humanWaitMs =\n handle != null ? Math.max(0, handledAtMs - handle.taskCreatedAt) : undefined;\n\n span.setAttribute(\"robotrock.task_id\", input.taskId);\n span.setAttribute(\"robotrock.action.id\", input.action.id);\n if (input.action.title) {\n span.setAttribute(\"robotrock.action.title\", input.action.title);\n }\n if (input.handledBy) {\n span.setAttribute(\"robotrock.handled_by\", input.handledBy);\n }\n span.setAttribute(\"robotrock.handled_at\", new Date(handledAtMs).toISOString());\n if (humanWaitMs != null) {\n span.setAttribute(\"robotrock.human_wait_ms\", humanWaitMs);\n }\n if (input.threadId) {\n span.setAttribute(\"robotrock.thread_id\", input.threadId);\n }\n\n const eventAttributes: Record<string, string | number | boolean> = {\n \"robotrock.task_id\": input.taskId,\n \"robotrock.action.id\": input.action.id,\n };\n if (input.handledBy) {\n eventAttributes[\"robotrock.handled_by\"] = input.handledBy;\n }\n if (humanWaitMs != null) {\n eventAttributes[\"robotrock.human_wait_ms\"] = humanWaitMs;\n }\n\n if (options.includeActionData && input.action.data != null) {\n const serialized = JSON.stringify(input.action.data);\n const truncated =\n serialized.length > 512 ? `${serialized.slice(0, 512)}…` : serialized;\n span.setAttribute(\"robotrock.action.data\", truncated);\n eventAttributes[\"robotrock.action.data\"] = truncated;\n }\n\n span.addEvent(HANDLED_EVENT_NAME, eventAttributes);\n}\n\nexport type EndRobotRockHumanWaitSpanOptions = {\n handle?: RobotRockOtelHandle;\n outcome?: \"handled\" | \"timeout\" | \"error\";\n includeActionData?: boolean;\n};\n\n/**\n * End the human-wait child span, recording handled data or a timeout/error outcome.\n */\nexport function endRobotRockHumanWaitSpan(\n span: Span | undefined,\n handled: RobotRockHandledRecordInput | null,\n options: EndRobotRockHumanWaitSpanOptions = {}\n): void {\n if (!span) {\n return;\n }\n\n const outcome = options.outcome ?? (handled ? \"handled\" : \"timeout\");\n\n if (handled && outcome === \"handled\") {\n recordRobotRockHandledToOtel(handled, {\n span,\n handle: options.handle,\n includeActionData: options.includeActionData,\n });\n span.setStatus({ code: SpanStatusCode.OK });\n } else {\n span.setAttribute(\"robotrock.outcome\", outcome);\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message:\n outcome === \"timeout\"\n ? \"Human response timed out before validUntil\"\n : \"Human wait failed\",\n });\n }\n\n span.end();\n}\n","import type { Span } from \"@opentelemetry/api\";\nimport {\n captureRobotRockOtelHandle,\n endRobotRockHumanWaitSpan,\n startRobotRockHumanWaitSpan,\n type RobotRockOtelHandle,\n} from \"./record-handled-to-otel.js\";\n\nexport type RobotRockPlatformOtelFields = {\n /**\n * Record human handle result on the active OTel span (Trigger / Workflow).\n * Defaults to `ROBOTROCK_OTEL_RECORD_HANDLED` env (`true` / `1`).\n */\n recordOtel?: boolean;\n /** Include truncated action feedback data on OTel spans (off by default). */\n otelIncludeActionData?: boolean;\n};\n\nexport function shouldRecordRobotRockOtel(recordOtel?: boolean): boolean {\n if (recordOtel === true) {\n return true;\n }\n if (recordOtel === false) {\n return false;\n }\n const env = process.env.ROBOTROCK_OTEL_RECORD_HANDLED;\n return env === \"true\" || env === \"1\";\n}\n\nexport function stripPlatformOtelFields<\n T extends RobotRockPlatformOtelFields & Record<string, unknown>,\n>(payload: T): Omit<T, \"recordOtel\" | \"otelIncludeActionData\"> {\n const { recordOtel: _recordOtel, otelIncludeActionData: _otelIncludeActionData, ...rest } =\n payload;\n return rest;\n}\n\nexport type RobotRockCreatedTask = {\n taskId: string;\n threadId?: string;\n submittedAt?: string;\n};\n\nexport type RobotRockHumanWaitOtelSession = {\n recordOtel: boolean;\n handle?: RobotRockOtelHandle;\n waitSpan?: Span;\n includeActionData?: boolean;\n};\n\nexport function beginRobotRockHumanWaitOtel(\n task: RobotRockCreatedTask,\n options: Pick<RobotRockPlatformOtelFields, \"recordOtel\" | \"otelIncludeActionData\"> = {}\n): RobotRockHumanWaitOtelSession {\n const recordOtel = shouldRecordRobotRockOtel(options.recordOtel);\n if (!recordOtel) {\n return { recordOtel: false };\n }\n\n const handle = captureRobotRockOtelHandle(task);\n const waitSpan = startRobotRockHumanWaitSpan(handle);\n\n return {\n recordOtel: true,\n handle,\n waitSpan,\n includeActionData: options.otelIncludeActionData,\n };\n}\n\nexport function finishRobotRockHumanWaitOtel(\n session: RobotRockHumanWaitOtelSession,\n handled: Parameters<typeof endRobotRockHumanWaitSpan>[1],\n outcome: \"handled\" | \"timeout\" | \"error\"\n): void {\n if (!session.recordOtel) {\n return;\n }\n\n endRobotRockHumanWaitSpan(session.waitSpan, handled, {\n handle: session.handle,\n outcome,\n includeActionData: session.includeActionData,\n });\n}\n"],"mappings":"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","names":["sleep","z","context","safeUrlSchema","z","jsonSchema7Schema","uiSchemaSchema","webhookHandlerSchema","triggerHandlerSchema","handlerSchema","taskActionInputSchema","taskActionSchema","uiFieldSchemaSchema","contextUiSchema","contextDataSchema","TASK_CONTEXT_FORMAT_VERSION","taskContextObjectBaseSchema","normalizeTaskContextVersion","taskContextObjectSchema","refineContextPublicUrls","taskContextSchema","assignToSchema","threadUpdateMessageSchema","threadUpdateStatuses","threadUpdateStatusSchema","threadUpdateInputSchema","z","threadUpdateMessageSchema","threadUpdateStatusSchema","taskPriorities","taskPrioritySchema","agentTelemetrySchema","z","createTaskBodySchema","taskContextObjectBaseSchema","assignToSchema","taskPrioritySchema","threadUpdateInputSchema","normalizeTaskContextVersion","refineContextPublicUrls","z","z","TASK_CONTEXT_FORMAT_VERSION","createTaskBodySchema","parseValidUntilMs","parseValidUntilMs","sleep"]}
|