export type TriggerSourceType = 'webhook' | 'ui' | 'workflow' | 'schedule' | 'vc_meeting'; export type TriggerTargetKind = 'turn' | 'workflow'; export type TriggerAction = 'queued' | 'delivered' | 'dry_run' | 'ignored' | 'completed'; export type TriggerAsyncStatus = 'pending' | 'completed'; export type LegacyWorkflowRetirementReason = 'pending' | 'migrated' | 'changed_after_migration' | 'identity_conflict'; export interface TriggerRequest { source: { type: TriggerSourceType; connectorId?: string; requestId?: string; receivedAt?: string; }; target: { kind: TriggerTargetKind; botId?: string; chatId?: string; sessionId?: string; rootMessageId?: string; workflowId?: string; }; envelope: { format: string; sourceName: string; trusted: false; headers?: Record; payload?: unknown; rawText?: string; }; instruction?: string; /** Trusted presentation chosen by the connector owner. Undefined keeps the * localized default topic seed; null suppresses the seed entirely. */ presentation?: { topicMessage?: string | null; }; options?: { dryRun?: boolean; dedupKey?: string; /** Caller-provided idempotency key (scoped per bot). A retried /api/trigger * with the same key returns the SAME session + triggerId instead of * creating a new one and re-dispatching — so a lost HTTP response can't make * the turn run twice. Distinct from `dedupKey` (webhook-lifecycle alert * grouping). Non-empty, ≤200 chars. FRESH async virtual only — mutually * exclusive with `turnIdempotencyKey` (which is for follow-up turns). */ idempotencyKey?: string; /** Caller-provided idempotency key for a FOLLOW-UP turn on an existing * session (requires `target.sessionId`). Same at-most-once dispatch lease as * `idempotencyKey`, but scoped to (sessionId, turnIdempotencyKey): a retried * /api/trigger appending to the same session with the same key resolves to * the SAME turn instead of injecting a second time — so a lost HTTP response * on an existing-session append can't double-run. Mutually exclusive with * `idempotencyKey`; only valid with `target.sessionId` + asyncReturnSessionId * (no wait/dryRun). Non-empty, ≤200 chars. */ turnIdempotencyKey?: string; status?: 'firing' | 'resolved' | string; waitForFinalOutput?: boolean; asyncReturnSessionId?: boolean; timeoutMs?: number; /** Connector-owner opt-in: drop the daemon-rendered final_output reply for * this loud trigger's turn. The streaming card / start notice still show; * only the trailing transcript-driven summary is suppressed. */ suppressFinalOutput?: boolean; /** Per-turn CLI model override (e.g. a codex model id). Applies only to a * freshly-spawned session; ignored when folding into an existing worker. * Empty/omitted → the bot's configured default. */ model?: string; /** Per-turn reasoning effort (codex `model_reasoning_effort`). Same * fresh-spawn-only semantics as `model`. */ reasoningEffort?: 'low' | 'medium' | 'high' | 'xhigh' | 'max' | 'ultra'; }; } export type TriggerErrorCode = 'bad_json' | 'bad_request' | 'bot_not_found' | 'bot_not_in_chat' | 'daemon_offline' | 'dry_run' | 'idempotency_conflict' | 'invalid_signature' | 'chat_not_allowed' | 'legacy_workflow_retired' | 'group_create_failed' | 'lifecycle_extract_failed' | 'rate_limited' | 'replay' | 'session_not_found' | 'target_required' | 'trigger_failed' | 'wait_timeout' | 'no_output' | 'workflow_trigger_not_implemented'; /** Four-state async lifecycle for `GET /api/sessions/:id/trigger-result`. * Programmatic callers (task runners) branch on this instead of ok/action: * - running: turn still in flight — keep polling * - completed: final output captured (see output.content) * - failed: session terminated without a captured output (soft terminal — * may be a genuine failure OR a caller-initiated close/cancel) * - not_found: no session record on disk (never existed / invalid id) */ export type AsyncTriggerState = 'running' | 'completed' | 'failed' | 'not_found'; export interface TriggerResponse { ok: boolean; triggerId?: string; action?: TriggerAction; /** Four-state async lifecycle. Present on trigger-result (async polling) * responses; absent on synchronous turn/workflow dispatch responses. */ state?: AsyncTriggerState; /** ISO8601 completion/termination time. Present on completed/failed states. */ finishedAt?: string; target?: { kind: TriggerTargetKind; sessionId?: string; workflowRunId?: string; chatId?: string; }; message?: string; errorCode?: TriggerErrorCode; error?: string; /** Structured recovery metadata when a v2 definition is no longer runnable. */ reason?: LegacyWorkflowRetirementReason; targetWorkflowId?: string; targetRevisionId?: string; promptPreview?: string; output?: { content: string; }; /** Per-turn token usage for a completed async turn (codex-app). Present on * `state:'completed'` when captured; omitted otherwise. Field names mirror the * caller's TaskTokenUsage. */ usage?: { inputTokens: number; outputTokens: number; cacheReadTokens: number; cacheCreateTokens: number; }; async?: { status: TriggerAsyncStatus; sessionId?: string; completedAt?: string; }; /** Echo of the caller's `options.idempotencyKey`, when one was supplied. */ idempotencyKey?: string; /** Echo of the caller's `options.turnIdempotencyKey`, when one was supplied * (follow-up async turn on an existing session). */ turnIdempotencyKey?: string; /** True when this response reused an EXISTING session for the idempotency key * (no new session created, no re-dispatch) instead of creating a fresh one. * Absent/false on the first (creating) call and on non-idempotent triggers. */ idempotent?: boolean; /** Read-only web-terminal URL for the live session's CLI pane, present only * while a worker web server is up (typically `state:'running'` and at * `'completed'` before the session closes). Lets an async caller (e.g. riff's * in-sandbox task-runner) open a live view of the visible CLI TUI — form C. * Carries the `?viewToken=` read capability inline; knowing it grants read * only, never terminal input. Omitted when no live worker terminal exists. */ readOnlyUrl?: string; /** The bare read capability behind `readOnlyUrl`'s `?viewToken=`, exposed * separately for callers that build their own URL. Omitted with readOnlyUrl. */ viewToken?: string; } export declare function isRecord(v: unknown): v is Record; export declare function validateTriggerRequest(raw: unknown): { ok: true; request: TriggerRequest; } | { ok: false; status: number; body: TriggerResponse; }; //# sourceMappingURL=trigger-types.d.ts.map