// 从 Agent-System-Core ts/types.ts 同步(make contracts 生成;Core 为权威)。 // Agent-System-Core 契约的 TypeScript 镜像。 // 线格式契约以 Go 类型(camelCase JSON 标签)与 testdata/golden/*.json 黄金样本为准; // 本文件手工镜像同一契约,前端按未知 type/字段静默忽略(前向兼容原则)。 export type ID = string; // ---- 领域模型 ---- export interface Project { id: ID; owner?: ID; name: string; createdAt: string; updatedAt: string; settings?: Record; } export interface Conversation { id: ID; projectId: ID; owner?: ID; title: string; profileId?: ID; pinned?: boolean; archived?: boolean; allowCrossRead?: boolean; crossPrivate?: boolean; permissionMode?: 'default' | 'plan' | 'auto_edit' | ''; sessionNote?: string; /** 无项目对话:服务端内部项目只承载这一条会话,不出现在项目列表里。 */ scratch?: boolean; createdAt: string; updatedAt: string; } export type Role = 'user' | 'assistant' | 'system'; export type PartType = | 'text' | 'thinking' | 'tool_call' | 'tool_result' | 'artifact_ref' | 'hitl' | 'plan' | 'error' | 'card' | 'check'; export interface Part { type: PartType; text?: string; toolCall?: { id: string; name: string; arguments?: string; durationMs?: number }; toolResult?: { callId: string; status: 'ok' | 'error'; summary?: string; truncated?: boolean }; artifact?: { artifactId: ID; name: string; kind?: string }; hitl?: { cardId: ID; question: string; resolved: boolean; answer?: string }; plan?: PlanSnapshot; card?: { kind: string; data: UINode[]; cardId?: ID }; // cardId 非空 = 收件箱卡片引用部件(submit_card) error?: { code: string; message: string }; check?: { passed: boolean; reason?: string }; // 终轮自动检查,过程区一行 process?: boolean; // run 终态后折叠为摘要行 durationMs?: number; // thinking 部件的思考时长(毫秒);工具耗时在 toolCall.durationMs } export interface Message { id: ID; conversationId: ID; runId?: ID; role: Role; parts: Part[]; createdAt: string; excluded?: boolean; variantGroup?: string; variantIndex?: number; } export type RunKind = 'conversation' | 'subagent' | 'tool'; export type RunStatus = | 'pending' | 'running' | 'waiting_hitl' | 'completed' | 'failed' | 'cancelled' | 'interrupted'; export type RunPhase = 'thinking' | 'acting' | 'responding' | 'finalizing' | 'done'; export interface Usage { promptTokens: number; completionTokens: number; totalTokens: number; durationMs: number; toolCalls: number; model?: string; // N3 计费拆分(additive;旧记录缺省为 0): // Last* 是最近一次请求的用量,Cache* 是缓存命中累计。 lastPromptTokens?: number; lastCompletionTokens?: number; cacheReadTokens?: number; cacheWriteTokens?: number; } export interface Run { id: ID; parentRunId?: ID; conversationId: ID; projectId: ID; owner?: ID; kind: RunKind; profileId?: ID; status: RunStatus; phase?: RunPhase; agentName?: string; createdAt: string; endedAt?: string; usage?: Usage; error?: { code: string; message: string }; } export interface Artifact { id: ID; projectId: ID; owner?: ID; name: string; kind: string; mime?: string; size: number; sourceRun?: ID; createdAt: string; updatedAt: string; } export interface PlanSnapshot { planId: ID; title: string; steps: { id: string; text: string; status: 'pending' | 'in_progress' | 'done' | 'skipped'; agentRun?: ID }[]; } export interface TodoList { conversationId: ID; items: { id: string; text: string; status: 'pending' | 'in_progress' | 'done' }[]; } // ---- 流式事件 ---- export type StreamEventType = | 'message.delta' | 'thinking.delta' | 'tool.call.delta' | 'tool.call' | 'tool.output' | 'tool.result' | 'run.phase' | 'run.check' | 'hitl.request' | 'hitl.resolved' | 'plan.update' | 'todo.update' | 'agent.spawn' | 'agent.progress' | 'agent.result' | 'artifact.created' | 'artifact.updated' | 'run.completed' | 'run.failed' | 'error' | 'card.created' | 'card.updated' | 'card.status' | 'card.resolved' | 'surface.updated'; export interface StreamEvent

{ seq: number; runId?: ID; conversationId: ID; ts: string; v: number; type: StreamEventType; payload?: P; } // payload 形状(按 type 判别;未知字段忽略) export interface MessageDeltaPayload { index: number; text: string } export interface ToolCallDeltaPayload { index: number; callId?: string; name?: string; delta: string } export interface ToolOutputPayload { callId: string; stream: 'stdout' | 'stderr'; text: string } export interface ToolResultPayload { callId: string; status: string; summary?: string; truncated?: boolean; durationMs?: number } export interface AgentSpawnPayload { agentRun: ID; name: string; task: string } export interface AgentProgressPayload { agentRun: ID; note?: string; phase?: RunPhase } export interface AgentResultPayload { agentRun: ID; status: RunStatus; summary?: string } export interface HITLResolvedPayload { cardId: ID; answer?: string; kind: 'choice' | 'free' | 'timeout' | 'cancelled' } export interface RunCompletedPayload { usage: Usage context?: ContextObservation } interface ContextSection { name: string estTokens: number } export interface ContextObservation { items: string[] truncations?: string[] estChars: number sections?: ContextSection[] prefixHash?: string } export interface RunCheckPayload { passed: boolean; reason?: string } export interface RunFailedPayload { code: string; message: string } // ---- 收件箱卡片 ---- export type CardKind = | 'progress' | 'confirm' | 'compare' | 'review-list' | 'result' | 'error' | 'status'; export type CardStatus = | 'active' | 'action_required' | 'done' | 'resolved' | 'failed' | 'dismissed'; export interface ActivityCard { id: ID; projectId: ID; conversationId?: ID; sourceRunId?: ID; anchorMessageId?: ID; kind: CardKind; title: string; status: CardStatus; tone?: string; task?: TaskSnapshot; body?: UINode[]; actions?: { id: string; label: string; style?: 'primary' | 'default' | 'danger'; command?: string }[]; pinned?: boolean; createdAt: string; updatedAt: string; work?: WorkCard; } export interface WorkCard { result?: string; resultVersion: number; readVersion: number; completedAt?: string; decision?: WorkDecision; } export interface WorkDecision { runId?: ID; mode: 'single' | 'multiple'; state: 'open' | 'deferred' | 'dispatching' | 'submitted'; options?: { id: string; label: string }[]; selectedIds?: string[]; freeText?: string; respondedAt?: string; } export interface WorkCardAction { resultVersion: number; selectedIds?: string[]; freeText?: string; } export interface CardPayload { card: ActivityCard } export interface CardStatusPayload { cardId: ID; status: CardStatus; tone?: string; note?: string } export interface CardResolvedPayload { cardId: ID; actionId?: string; answer?: string } // ---- HITL ---- export type HITLKind = 'choice' | 'input' | 'confirm' | 'form'; export interface HITLChoice { id: string; label: string; description: string; impact: string; recommended?: boolean; } export interface HITLCard { id: ID; runId: ID; conversationId: ID; question: string; kind: HITLKind; choices?: HITLChoice[]; allowFreeInput: boolean; freeInputHint?: string; timeoutSec?: number | null; form?: UINode[]; createdAt: string; resolved: boolean; anchorMessageId?: ID; blocked?: boolean; blockReason?: string; detail?: string; } export interface HITLResponse { cardId: ID; choiceId?: string; freeText?: string; formData?: unknown; } // ---- UI 词汇 ---- export type UINodeType = | 'section' | 'list' | 'kv' | 'form' | 'markdown' | 'doc-ref' | 'actions' | 'chart-lite' | 'avatar' | 'progress' | 'compare' | 'tree' | 'table' | 'steps' | 'tabs' | 'timeline'; export interface UINode { type: UINodeType; /** Surface 层节点级标注(Generative UI U2):整页唯一稳定 id 与事实来源标识,旧路径不填。 */ id?: string; source?: string[]; title?: string; items?: string[]; kv?: [string, string][]; fields?: UIField[]; markdown?: string; docId?: ID; actions?: { id: string; label: string; style?: 'primary' | 'default' | 'danger' }[]; chart?: { kind: 'bar' | 'line'; labels: string[]; series: number[] }; children?: UINode[]; avatar?: { name?: string; sub?: string; tone?: string; stack?: { name?: string; sub?: string; tone?: string }[] }; progress?: { label?: string; value: number; tone?: string }; compare?: { left: { title?: string; tone?: string; nodes?: UINode[] }; right: { title?: string; tone?: string; nodes?: UINode[] }; }; tree?: { nodes: { id: string; label: string; tone?: string; badge?: string; count?: number; selected?: boolean; children?: unknown[]; }[]; }; table?: { columns: { key: string; label: string }[]; rows: { id?: string; cells: [string, string][]; actions?: UINode['actions'] }[]; }; steps?: { current: number; steps: { label: string; status?: 'pending' | 'active' | 'done' | 'failed'; tone?: string }[] }; tabs?: { active?: string; tabs: { id: string; label: string; nodes?: UINode[] }[] }; timeline?: { items: { time?: string; title: string; tone?: string; markdown?: string; ref?: string }[] }; } export interface UIField { key: string; label: string; type: 'text' | 'textarea' | 'number' | 'boolean' | 'select'; options?: string[]; required?: boolean; placeholder?: string; help?: string; default?: string; } // ---- 提示词库(prompt-library)---- export interface PromptTrigger { kind: 'intent' | 'command' | 'attachment' | 'manual'; keywords?: string[]; command?: string; } export interface PromptModule { id: string; layer: 'base' | 'env' | 'task' | 'agent' | 'tool' | 'aux' | 'style'; version: number; title: string; description?: string; priority?: number; triggers?: PromptTrigger[]; requiresAttachments?: boolean; body: string; outputContract?: string; source?: 'builtin' | 'plugin' | 'user'; owner?: string; basedOnVersion?: number; drifted?: boolean; disabled?: boolean; /** 子代理 profile。只对 agent.sub.* 有意义;空字段表示沿用内置。 */ tools?: string[]; model?: string; maxTurns?: number; } export interface PromptBlock { moduleId: string; version: number; layer: string; body: string; } export interface PromptHitRecord { moduleId: string; layer: string; reason: string; injected: boolean; } // ---- 画像 / 设置 ---- export interface AgentProfile { id: string; owner?: string; name: string; description?: string; builtin?: boolean; source?: string; systemPrompt: string; /** 提示词库模块引用(有序;空 = 默认 base+env 全集)。 */ promptModules?: string[]; model: { chat?: string; lightweight?: string; embedding?: string; rerank?: string }; tools: { allow: string[]; deny?: string[]; confirm?: string[] }; context: { maxHistoryMessages: number; summarizeBeyond?: boolean; memoryBudgetPct?: number; knowledgeBudgetPct?: number; maxToolResultChars?: number; }; hitl: { askOnAmbiguity: boolean; timeoutSec?: number | null }; budget: { maxTokens?: number | null; maxToolCalls?: number | null; maxTurns?: number | null }; } export interface SettingDesc { key: string; group: string; label: string; description?: string; type: 'string' | 'number' | 'boolean' | 'enum' | 'secret'; default?: unknown; options?: string[]; effect: 'hot' | 'new-run' | 'restart'; secret?: boolean; /** P2 受管:system = 系统受管项,仅系统管理面可写(用户/项目层拒绝)。 */ scope?: 'system'; } // ---- 插件 ---- export interface PluginManifest { id: string; name: string; version: string; apiVersion: string; requires?: { network?: string[] }; provides: { tools?: string[]; workflows?: string[]; intents?: string[]; prompts?: string[]; panels?: string[]; cards?: string[]; settings?: string[]; commands?: string[]; workspaces?: string[]; skills?: string[]; mcpServers?: string[]; knowledge?: string[]; parsers?: string[]; agents?: string[]; channels?: string[]; pages?: string[]; }; scope?: { tenants?: string[]; projects?: string[] }; backend?: { mode?: 'inproc' | 'sidecar'; command?: string; args?: string[]; schemaVersion?: number }; } export interface PluginPanel { id: string; title: string; icon?: string; body: UINode[]; refreshTool?: string; } /** 模板占位符:{{input}}、{{slots.}}、{{steps..output}}。 */ export interface WorkflowDef { id: string; title: string; description?: string; intentId?: string; /** 整条工作流的 critic 重试上限。 */ maxRetries?: number; steps: WorkflowStep[]; } export interface StepCritic { criteria: string; /** 本步重试上限;缺省 1 次。 */ maxRetries?: number; } export interface WorkflowStep { id: string; title: string; kind: 'prompt' | 'tool' | 'hitl' | 'artifact' | 'card' | 'script'; prompt?: string; /** prompt 步骤的子代理 profile,缺省 general。 */ agent?: string; tool?: string; args?: unknown; hitl?: { question: string; kind: HITLKind; choices?: HITLChoice[]; allowFreeInput: boolean; freeInputHint?: string }; artifact?: string; card?: { kind: CardKind; title: string; tone?: string; body?: UINode[]; actions?: { id: string; label: string; style?: 'primary' | 'default' | 'danger'; command?: string }[] }; /** script 步骤在插件目录内的相对路径。 */ script?: string; critic?: StepCritic; } export interface PluginWorkspace { id: string; title: string; icon?: string; shortcut?: string; badgeTool?: string; body: UINode[]; refreshTool?: string; } export interface PluginPageDecl { id: string; title: string; module: string; } // ---- 摄取 / 检索 ---- export interface ParsedDocument { meta: { filename: string; mime?: string; parser: string; confidence?: number; origin?: DocumentOrigin; crossCheck?: { with: string; diffBlocks: number; verdict: 'agree' | 'differ' }; parsedAt: string; }; blocks: { type: 'heading' | 'para' | 'list' | 'table' | 'code' | 'image-ref'; level?: number; text?: string; items?: string[]; rows?: string[][]; ref?: string; confidence?: number; }[]; warnings?: string[]; } export interface RetrievalHit { doc: { id: ID; owner?: ID; projectId?: ID; source: string; title: string; ref?: string; chunk: string; createdAt: string }; score: number; kind: 'fulltext' | 'vector' | 'plugin'; } export interface UploadInfo { artifactId: ID; filename: string; mime?: string; size: number; parsed?: ParsedDocument; } // ---- Generative UI Surface(提案 U2/U4;与 Go surface.go 同步)---- export interface SurfaceCompat { schemaVersion: number; catalogVersion: string; pluginVersion?: string; } export interface SurfaceIdentity { surfaceId: ID; owner: string; projectId?: ID; conversationId?: ID; sourceRunId?: ID; pluginId: string; } export interface SurfaceSpec { title: string; nodes: UINode[]; } export interface SurfaceSnapshot { identity: SurfaceIdentity; compat: SurfaceCompat; revision: number; baseRevision?: number; contextVersion?: string; activationEpoch: number; spec: SurfaceSpec; semanticText?: string; } export interface SurfaceMeta { surfaceId: ID; title: string; pluginId: string; revision: number; conversationId?: ID; updatedAt: string; } // Persistent work projection; host-owned identities and revisions. export interface DocumentOrigin { artifactId: ID; contentHash: string; parserRevision: string } export interface TaskPhase { id: string; label: string; observedAt?: string } export interface TaskSourceRef { id: string; artifactId: ID; contentHash: string; parserRevision: string; blockIndex: number; label: string; quote?: string; availability?: string } export interface TaskResultRef { artifactId?: ID; surfaceId?: ID; version?: string; contentHash?: string; availability: string; name?: string } export interface TaskFinding { id: string; text: string; impact?: string; kind: string; status: string; revision: number; sources: TaskSourceRef[]; assumptions?: string; corrects?: string } export interface TaskSnapshot { inputs?: TaskSourceRef[] limitations?: string[] schemaVersion: number; taskId: ID; attemptId: ID; cardId: ID; projectId: ID; conversationId: ID; sourceMessageId?: ID; parentRunId?: ID; runId?: ID; ownerInstanceId: string; executionEpoch?: number; revision: number; sourceSeq: number; streamScope: string; inputRevision?: string; title: string; goal?: string; executionState: 'queued'|'running'|'awaiting_user'|'completed'|'failed'|'interrupted'; outcomeCompleteness: 'none'|'partial'|'complete'; deliveryState: 'pending'|'available'|'reported'; phase: TaskPhase; focus?: string; coverage?: string; remaining?: string; nextStep?: string; conclusion?: string; findings?: TaskFinding[]; actions?: UIAction[]; resultRefs?: TaskResultRef[]; lastActivityAt?: string; lastMeaningfulUpdateAt?: string; checkpointKeys?: Record; checkpointCount?: number; checkpointSeq?: number; } export interface TaskSourceQuote { sourceId: string; blockIndex: number; quote: string } interface WorkEvidencePremise { role: "total" | "phase" | "dependent" | "direct_relation"; sourceIndex: number; value?: number } interface WorkFindingEvidence { mode: "direct_relation" | "difference" | "unresolved_relation"; premises: WorkEvidencePremise[]; result?: number } export interface WorkFindingCandidate { findingKey: string; text: string; impact?: string; kind: string; assumptions?: string; corrects?: string; sources: TaskSourceQuote[]; evidence?: WorkFindingEvidence } export interface WorkCheckpointCandidate { checkpointId: string; phaseId: string; focus?: string; remaining?: string; nextStep?: string; findings: WorkFindingCandidate[] } export interface UIAction { id: string; label: string; style?: string; command?: string }