134 lines
4.9 KiB
TypeScript
134 lines
4.9 KiB
TypeScript
// @generated — DO NOT EDIT. Source: packages/shared/agent-jobs.ts
|
|
/**
|
|
* Agent Jobs — shared types, state machine, and SSE helpers.
|
|
*
|
|
* Runtime-agnostic: no node:fs, no node:http, no Bun APIs.
|
|
* Both the Bun server handler and (future) Node handler import
|
|
* this module and wrap it with their respective HTTP transport layers.
|
|
*
|
|
* Mirrors packages/shared/external-annotation.ts in structure.
|
|
*/
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Types
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export type AgentJobStatus = "starting" | "running" | "done" | "failed" | "killed";
|
|
|
|
/**
|
|
* Snapshot of the diff the reviewer was looking at when this job was launched.
|
|
* Carried on the job so downstream UIs (agent-result panel "Copy All") export
|
|
* the same `**Diff:** ...` header the job was actually run against — if the
|
|
* reviewer switches the UI to a different diff afterwards, the job's snapshot
|
|
* still reflects truth. Structurally compatible with the UI-side
|
|
* `FeedbackDiffContext` in `packages/review-editor/utils/exportFeedback.ts`.
|
|
*/
|
|
export interface AgentJobDiffContext {
|
|
mode: string;
|
|
base?: string;
|
|
worktreePath?: string | null;
|
|
}
|
|
|
|
export interface AgentJobInfo {
|
|
/** Unique job identifier (UUID). */
|
|
id: string;
|
|
/** Source identifier for external annotations — "agent-{id prefix}". */
|
|
source: string;
|
|
/** Provider that spawned this job — "claude", "codex", "tour", "shell", etc. */
|
|
provider: string;
|
|
/** Underlying engine used (e.g., "claude" or "codex"). Set when provider is "tour". */
|
|
engine?: string;
|
|
/** Model used (e.g., "sonnet", "opus"). Set when provider is "tour" with Claude engine. */
|
|
model?: string;
|
|
/** Claude --effort level (e.g., "low", "medium", "high", "xhigh", "max"). */
|
|
effort?: string;
|
|
/** Codex reasoning effort level (e.g., "high", "medium"). */
|
|
reasoningEffort?: string;
|
|
/** Whether Codex fast mode (service_tier=fast) was enabled. */
|
|
fastMode?: boolean;
|
|
/** Human-readable label for the job. */
|
|
label: string;
|
|
/** Current lifecycle status. */
|
|
status: AgentJobStatus;
|
|
/** Timestamp when the job was created. */
|
|
startedAt: number;
|
|
/** Timestamp when the job reached a terminal state. */
|
|
endedAt?: number;
|
|
/** Process exit code (set on done/failed). */
|
|
exitCode?: number;
|
|
/** Last ~500 chars of stderr on failure. */
|
|
error?: string;
|
|
/** The actual command that was spawned (for display/debug). */
|
|
command: string[];
|
|
/** Working directory where the process was spawned. */
|
|
cwd?: string;
|
|
/** The review prompt text (system + user message). Stored separately from command for providers that use stdin. */
|
|
prompt?: string;
|
|
/** Review summary set by the agent on completion. */
|
|
summary?: {
|
|
correctness: string;
|
|
explanation: string;
|
|
confidence: number;
|
|
};
|
|
/** PR URL at launch time — used to attribute findings to the correct PR. */
|
|
prUrl?: string;
|
|
/** PR diff scope at launch time — "layer" or "full-stack". */
|
|
diffScope?: string;
|
|
/** Diff context at launch time (see AgentJobDiffContext). */
|
|
diffContext?: AgentJobDiffContext;
|
|
}
|
|
|
|
export interface AgentCapability {
|
|
id: string;
|
|
name: string;
|
|
available: boolean;
|
|
}
|
|
|
|
export interface AgentCapabilities {
|
|
mode: "plan" | "review" | "annotate";
|
|
providers: AgentCapability[];
|
|
/** True if at least one provider is available. */
|
|
available: boolean;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// SSE event types
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export type AgentJobEvent =
|
|
| { type: "snapshot"; jobs: AgentJobInfo[] }
|
|
| { type: "job:started"; job: AgentJobInfo }
|
|
| { type: "job:updated"; job: AgentJobInfo }
|
|
| { type: "job:completed"; job: AgentJobInfo }
|
|
| { type: "job:log"; jobId: string; delta: string }
|
|
| { type: "jobs:cleared" };
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// SSE helpers
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/** Heartbeat comment to keep SSE connections alive (sent every 30s). */
|
|
export const AGENT_HEARTBEAT_COMMENT = ":\n\n";
|
|
|
|
/** Interval in ms between heartbeat comments. */
|
|
export const AGENT_HEARTBEAT_INTERVAL_MS = 30_000;
|
|
|
|
/** Encode an event as an SSE `data:` line. */
|
|
export function serializeAgentSSEEvent(event: AgentJobEvent): string {
|
|
return `data: ${JSON.stringify(event)}\n\n`;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Helpers
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/** Check if a status is terminal (no further transitions). */
|
|
export function isTerminalStatus(status: AgentJobStatus): boolean {
|
|
return status === "done" || status === "failed" || status === "killed";
|
|
}
|
|
|
|
/** Generate the source identifier for a job from its ID. */
|
|
export function jobSource(id: string): string {
|
|
return "agent-" + id.slice(0, 8);
|
|
}
|