import { AgentActivityMessageSemantics, AgentActivitySession, AgentActivityGoalControlAction, AgentActivityTurn } from '@tutti-os/agent-activity-core'; import { WorkspaceIssueMentionMode } from '@tutti-os/workspace-issue-manager/core'; interface WorkspaceAgentActivityFileChange { path: string; change?: "added" | "modified" | "deleted" | "moved" | string; tools?: string[]; } interface WorkspaceAgentActivityFileChanges { coverage?: string; files?: WorkspaceAgentActivityFileChange[]; } interface WorkspaceAgentActivityTimelineItem { id: number; workspaceId?: string; agentSessionId: string; seq?: number; turnId?: string; eventSource?: string; eventId: string; actorType: string; actorId: string; itemType: "message" | "call" | "event" | "error" | "lifecycle" | string; role?: string; callType?: "tool" | "skill" | "subagent" | "approval" | "workflow" | string; callId?: string; name?: string; status?: string | null; messageSemantics?: AgentActivityMessageSemantics; content?: string; payload?: Record & { content?: unknown; text?: unknown; fileChanges?: WorkspaceAgentActivityFileChanges; }; occurredAtUnixMs?: number; createdAtUnixMs?: number; } type ToolCallStatusKind = "working" | "completed" | "failed" | "canceled" | "waiting"; interface WorkspaceAgentToolCallDisplay { id: string; name: string; status: string | null; statusKind: ToolCallStatusKind | null; detail?: string; } type WorkspaceAgentLatestActivityStatus = "working" | "waiting" | "idle" | "completed" | "canceled" | "failed"; interface WorkspaceAgentConversationPreviewLine { actorName: string; summary: string; } type WorkspaceAgentActivityStatus = WorkspaceAgentLatestActivityStatus; interface WorkspaceAgentChangedFile { path: string; label: string; } interface WorkspaceAgentActivityCard { id: string; sessionId: string; userId: string | null; userName: string; userAvatarUrl?: string; agentProvider: string; agentName: string; title: string; status: WorkspaceAgentActivityStatus; latestActivitySummary: string; /** User prompt + latest agent reply for task/issue execution cards; room status list uses single-line summary only. */ conversationPreview?: WorkspaceAgentConversationPreviewLine[]; latestActivityActorName?: string; toolCalls?: WorkspaceAgentToolCallDisplay[]; changedFiles: WorkspaceAgentChangedFile[]; sortTimeUnixMs: number; readTimeUnixMs?: number; } interface WorkspaceAgentSessionDetailMessage { id: string; body: string; status?: string | null; statusKind?: ToolCallStatusKind | null; turnId?: string; occurredAtUnixMs?: number | null; sourceTimelineItems?: WorkspaceAgentActivityTimelineItem[]; visibleError?: { code: string | null; phase: string | null; provider: string | null; origin?: string | null; detail: string | null; detailAvailable?: boolean; retryable: boolean | null; } | null; systemNotice?: { noticeKind: string | null; semanticKind?: "context-handoff-required" | null; severity: string | null; source?: string | null; command?: AgentActivityMessageSemantics["noticeCommand"] | null; commandStatus?: AgentActivityMessageSemantics["noticeCommandStatus"] | null; title: string | null; detail: string | null; retryable: boolean | null; } | null; } interface WorkspaceAgentSessionDetailThinking { id: string; body: string; statusKind?: ToolCallStatusKind | null; turnId?: string; occurredAtUnixMs?: number | null; sourceTimelineItems?: WorkspaceAgentActivityTimelineItem[]; } interface WorkspaceAgentSessionDetailGoalControl { id: string; action: AgentActivityGoalControlAction; body: string; occurredAtUnixMs?: number | null; sourceTimelineItems?: WorkspaceAgentActivityTimelineItem[]; } interface WorkspaceAgentSessionDetailToolCall { id: string; name: string; toolName: string | null; callType: string | null; status: string | null; statusKind: ToolCallStatusKind | null; summary: string; payload: Record | null; turnId?: string; compactSummary?: string | null; occurredAtUnixMs?: number | null; sourceTimelineItems?: WorkspaceAgentActivityTimelineItem[]; } type WorkspaceAgentSessionDetailToolGroupEntry = { kind: "thinking"; thinking: WorkspaceAgentSessionDetailThinking; } | { kind: "tool-call"; call: WorkspaceAgentSessionDetailToolCall; }; type WorkspaceAgentSessionDetailAgentItem = { kind: "message"; message: WorkspaceAgentSessionDetailMessage; } | { kind: "thinking"; thinking: WorkspaceAgentSessionDetailThinking; } | { kind: "tool-calls"; id: string; toolCalls: WorkspaceAgentSessionDetailToolCall[]; toolCallCount: number; hasFailedToolCall: boolean; summary?: string | null; groupEntries?: WorkspaceAgentSessionDetailToolGroupEntry[]; }; interface WorkspaceAgentSessionDetailTurn { id: string; userMessage: WorkspaceAgentSessionDetailMessage | null; userMessages: WorkspaceAgentSessionDetailMessage[]; agentMessages: WorkspaceAgentSessionDetailMessage[]; toolCalls: WorkspaceAgentSessionDetailToolCall[]; toolCallCount: number; hasFailedToolCall: boolean; rawAgentItems?: WorkspaceAgentSessionDetailAgentItem[]; agentItems: WorkspaceAgentSessionDetailAgentItem[]; } interface WorkspaceAgentSessionDetailViewModel { activity: WorkspaceAgentActivityCard; session: AgentActivitySession; cwd: string; workspaceRoot: string | null; goalControls?: WorkspaceAgentSessionDetailGoalControl[]; turns: WorkspaceAgentSessionDetailTurn[]; sessionTurns?: readonly AgentActivityTurn[]; showProcessingIndicator?: boolean; } interface BuildWorkspaceAgentSessionDetailInput { activity: WorkspaceAgentActivityCard; session: AgentActivitySession; sessionTurns?: readonly AgentActivityTurn[]; timelineItems: WorkspaceAgentActivityTimelineItem[]; workspaceRoot?: string | null; } declare function buildWorkspaceAgentSessionDetailViewModel(input: BuildWorkspaceAgentSessionDetailInput): WorkspaceAgentSessionDetailViewModel; type AgentApprovalPurpose = "edit-files"; interface AgentApprovalOptionVM { id: string; label: string; kind: string; description?: string; } interface AgentApprovalItemVM { kind: "approval"; id: string; agentSessionId?: string; turnId: string; requestId: string; callId: string; approvalPurpose?: AgentApprovalPurpose; title: string; toolName: string | null; status: string | null; input: Record | null; options: AgentApprovalOptionVM[]; output?: Record | null; occurredAtUnixMs: number | null; } interface AgentAskUserQuestionOptionVM { /** Provider-owned durable identity used by interaction automation when present. */ id?: string; label: string; description: string; } interface AgentAskUserQuestionVM { id: string; header: string; question: string; options: AgentAskUserQuestionOptionVM[]; multiSelect: boolean; allowFreeText?: boolean; answer?: string | string[] | null; } interface AgentAskUserQuestionItemVM { kind: "ask-user"; id: string; turnId: string; requestId: string; title: string; status: string | null; questions: AgentAskUserQuestionVM[]; occurredAtUnixMs: number | null; } interface AgentGeneratedImageRowVM { kind: "generated-image"; id: string; turnId: string; sourceCallId: string; uri: string; mimeType: string | null; prompt: string | null; occurredAtUnixMs: number | null; } interface AgentGoalControlRowVM { kind: "goal-control"; id: string; turnId: null; action: AgentActivityGoalControlAction; body: string; occurredAtUnixMs: number | null; sourceTimelineItems?: WorkspaceAgentActivityTimelineItem[]; } type AgentTranscriptPresentationKind = "content" | "specific-progress" | "turn-boundary"; interface AgentCollaborationUsageVM { inputTokens: number; outputTokens: number; } /** * Typed projection of one durable "collaboration" timeline message (the * daemon projects each collaboration run into the source session transcript * with messageId `collab:`; status transitions update the same message * in place). Pure data — rendering and adoption actions live in * `AgentCollaborationRow`. */ interface AgentCollaborationVM { kind: "collaboration"; runId: string; /** Session identity of the source transcript row, for adoption commands. */ workspaceId: string | null; agentSessionId: string | null; mode: "consult" | "fork" | "delegate" | "handoff" | (string & {}); status: "running" | "completed" | "failed" | "canceled" | (string & {}); triggerSource: "user" | "agent" | "policy" | (string & {}); triggerReason: string | null; targetSessionId: string | null; targetAgentTargetId: string | null; modelPlanId: string | null; /** Optional display name when the daemon payload carries it. */ modelPlanName: string | null; model: string | null; contextScope: string | null; resultText: string | null; failureReason: string | null; durationMs: number | null; usage: AgentCollaborationUsageVM | null; adoption: "pending" | "adopted" | "rejected" | "not_applicable" | (string & {}); } type AgentPlanModeKind = "enter" | "exit"; interface AgentPlanModeItemVM { itemKind: "plan-mode"; id: string; turnId: string; requestId?: string; kind: AgentPlanModeKind; title: string; plan?: string | null; status: string | null; filePath?: string | null; options?: AgentApprovalOptionVM[]; keepPlanningOptionId?: string; occurredAtUnixMs: number | null; } type AgentTaskSubAgentStatus = "running" | "completed" | "failed" | "canceled"; type AgentTaskSubAgentActivityKind = "message" | "reasoning" | "tool"; interface AgentTaskSubAgentActivityVM { kind: AgentTaskSubAgentActivityKind; text: string; atUnixMs: number | null; } interface AgentTaskSubAgentVM { childSessionId: string; parentToolCallId: string; status: AgentTaskSubAgentStatus; name: string | null; task: string | null; laneIndex: number; laneCount: number; latestActivity: string | null; latestActivityKind: AgentTaskSubAgentActivityKind | null; assistantMarkdown?: string | null; activityLog: readonly AgentTaskSubAgentActivityVM[]; activityOmittedCount: number; queued?: boolean; failureDetail: string | null; startedAtUnixMs: number | null; latestActivityAtUnixMs: number | null; terminalAtUnixMs: number | null; childSessions: readonly AgentTaskSubAgentVM[]; } interface AgentTaskStepVM { id: string; turnId: string; name: string; toolName: string | null; status: string | null; summary: string; payload: Record | null; tool: AgentToolCallVM | null; occurredAtUnixMs: number | null; } interface AgentTaskItemVM { kind: "task"; id: string; turnId: string; title: string; status: string | null; prompt?: string | null; delegateSessionId?: string | null; steps: AgentTaskStepVM[]; subAgents?: AgentTaskSubAgentVM[]; result?: string | null; resultMarkdown?: string | null; durationMs?: number | null; occurredAtUnixMs: number | null; } type AgentToolRendererKind = "default" | "approval" | "plan-enter" | "plan-exit" | "ask-user" | "task" | "read" | "write" | "edit" | "bash" | "search" | "web-search" | "web-fetch" | "image-generation" | "todo-write" | "tool-search" | "skill" | "mcp"; interface AgentToolCallVM { kind: "tool-call"; id: string; turnId: string; name: string; toolName: string | null; callType: string | null; status: string | null; statusKind: ToolCallStatusKind | null; summary: string; compactSummary: string | null; payload: Record | null; input: Record | null; output: Record | null; error: Record | null; metadata: Record | null; locations: unknown[] | null; rendererKind: AgentToolRendererKind; approval: AgentApprovalItemVM | null; planMode: AgentPlanModeItemVM | null; askUserQuestion: AgentAskUserQuestionItemVM | null; task: AgentTaskItemVM | null; occurredAtUnixMs: number | null; sourceTimelineItems?: WorkspaceAgentActivityTimelineItem[]; } type AgentToolGroupEntryVM = { kind: "thinking"; thinking: AgentThinkingContentVM; } | { kind: "tool-call"; call: AgentToolCallVM; }; interface AgentToolGroupRowVM { kind: "tool-group"; id: string; expansionKey?: string; turnId: string; grouped: boolean; calls: AgentToolCallVM[]; summary?: string | null; entries: AgentToolGroupEntryVM[]; occurredAtUnixMs: number | null; } type AgentMessageContentKind = "text" | "image-grid" | "plan" | "collaboration" | "tutti-checkpoint-wake" | "tutti-plan-issue-link" | "selected-text"; interface AgentMessageContentVM { kind: "message-content"; id: string; turnId: string; body: string; presentationKind: AgentTranscriptPresentationKind; copyText?: string | null; statusKind?: ToolCallStatusKind | null; contentKind?: AgentMessageContentKind; isTurnFinalText?: true; /** Typed payload for `contentKind: "collaboration"` rows. */ collaboration?: AgentCollaborationVM | null; /** * Typed payload for `contentKind: "tutti-checkpoint-wake"` rows: a daemon * checkpoint-wake prompt injected into the source agent. `body` carries the * full prompt (minus the sentinel line) for the expand-to-full affordance. */ checkpointWake?: AgentTuttiModeCheckpointWakeVM | null; /** * Typed payload for `contentKind: "tutti-plan-issue-link"` rows: the durable * plan→Issue reverse link the daemon writes when the user accepts a Tutti * Mode plan (messageId "plan-issue:"). */ planIssueLink?: AgentTuttiPlanIssueLinkVM | null; /** Typed payload for `contentKind: "selected-text"` rows. */ selectedText?: AgentSelectedTextVM | null; images?: AgentMessageImageVM[]; occurredAtUnixMs: number | null; visibleError?: { code: string | null; phase: string | null; provider: string | null; origin?: string | null; detail: string | null; detailAvailable?: boolean; retryable: boolean | null; } | null; systemNotice?: { noticeKind: string | null; semanticKind?: "context-handoff-required" | null; severity: string | null; source?: string | null; command?: AgentActivityMessageSemantics["noticeCommand"] | null; commandStatus?: AgentActivityMessageSemantics["noticeCommandStatus"] | null; title: string | null; detail: string | null; retryable: boolean | null; } | null; sourceTimelineItems?: WorkspaceAgentActivityTimelineItem[]; } interface AgentSelectedTextVM { count: number; texts: readonly string[]; } interface AgentTuttiModeCheckpointWakeVM { /** Wire kind, e.g. "task_settled" | "task_failed" | "all_tasks_terminal". */ kind: string; issueId: string; checkpointId: string; graphRevision: number | null; } interface AgentTuttiPlanIssueLinkVM { issueId: string; /** Issue title with markdown escapes removed; falls back to the issue id. */ title: string; /** The original single-mention markdown, rendered as the issue chip. */ mentionMarkdown: string; } interface AgentMessageImageVM { id: string; workspaceId?: string | null; agentSessionId: string; attachmentId?: string | null; mimeType: string; name?: string | null; data?: string | null; url?: string | null; path?: string | null; } interface AgentThinkingContentVM { kind: "thinking-content"; id: string; turnId: string; body: string; statusKind?: ToolCallStatusKind | null; occurredAtUnixMs: number | null; sourceTimelineItems?: WorkspaceAgentActivityTimelineItem[]; } interface AgentMessageRowVM { kind: "message"; id: string; turnId: string; speaker: "user" | "assistant"; /** * Exact first text block from the submitted structured content. Editing must * not recover this value from displayPrompt, copy text, or rendered Markdown. */ rawFirstTextBlock?: string | null; messages: AgentMessageContentVM[]; thinking: AgentThinkingContentVM[]; /** * Tool-group rows that happened right before this message and are rendered * inside this message's block (under the participant header, above the * content) instead of as standalone transcript rows. Populated only for the * participant-header presentation (e.g. the Agent board session detail). */ leadingToolRows?: AgentToolGroupRowVM[]; occurredAtUnixMs: number | null; } interface AgentProcessingRowVM { kind: "processing"; id: string; turnId: string | null; label?: string | null; occurredAtUnixMs: number | null; } interface AgentTurnSummaryFileVM { label: string; path: string; fileName: string; directory: string | null; changeType: "modified" | "created" | "deleted"; toolName: string | null; messageId: string; unifiedDiff?: string | null; oldString?: string | null; newString?: string | null; content?: string | null; occurredAtUnixMs: number | null; } interface AgentTurnSummaryPatchChangeVM { path: string; changeType: "modified" | "created" | "deleted"; unifiedDiff?: string | null; oldString?: string | null; newString?: string | null; content?: string | null; } interface AgentTurnSummaryPatchBatchVM { cwd: string | null; toolCallId: string; changes: AgentTurnSummaryPatchChangeVM[]; } interface AgentTurnSummaryRowVM { kind: "turn-summary"; id: string; turnId: string; files: AgentTurnSummaryFileVM[]; patchBatches?: AgentTurnSummaryPatchBatchVM[]; fileCount: number; modifiedCount: number; createdCount: number; occurredAtUnixMs: number | null; } type AgentTranscriptRowVM = AgentGeneratedImageRowVM | AgentGoalControlRowVM | AgentMessageRowVM | AgentToolGroupRowVM | AgentTurnSummaryRowVM | AgentProcessingRowVM; interface AgentInteractionResponseInput { agentSessionId?: string; turnId?: string; requestId: string; action?: string; optionId?: string; payload?: Record; } type AgentConversationPromptVM = AgentApprovalItemVM | { kind: "ask-user"; agentSessionId?: string; turnId?: string; requestId: string; title: string; questions: AgentAskUserQuestionVM[]; } | { kind: "exit-plan"; agentSessionId?: string; turnId?: string; requestId: string; title: string; options: AgentApprovalOptionVM[]; keepPlanningOptionId?: string; } | { kind: "plan-implementation"; requestId: string; title: string; }; interface AgentConversationVM { activity: WorkspaceAgentActivityCard; workspaceRoot: string | null; sourceDetail: WorkspaceAgentSessionDetailViewModel; rows: AgentTranscriptRowVM[]; } type WorkspaceLinkActionSource = "agent-markdown" | "agent-file-change" | string; interface OpenWorkspaceUrlLinkAction { type: "open-url"; url: string; source: WorkspaceLinkActionSource; } interface OpenAgentSessionLinkAction { type: "open-agent-session"; workspaceId: string; agentSessionId: string; agentTargetId?: string | null; source: WorkspaceLinkActionSource; } interface OpenWorkspaceFileLinkAction { type: "open-workspace-file"; mode?: "select" | "open"; path: string; directoryPath: string; workspaceRoot: string; source: WorkspaceLinkActionSource; prefetchedDirectoryListing?: WorkspaceFileLinkDirectoryListing | null; } interface OpenLocalAssetPreviewLinkAction { type: "open-local-asset-preview"; path: string; name: string; source: WorkspaceLinkActionSource; } interface WorkspaceFileLinkDirectoryEntry { path: string; name: string; kind: "file" | "directory" | "unknown"; hasChildren: boolean | null; sizeBytes: number | null; mtimeMs: number | null; } interface WorkspaceFileLinkDirectoryListing { workspaceId: string; root: string; directoryPath: string; entries: WorkspaceFileLinkDirectoryEntry[]; } interface OpenWorkspaceIssueLinkAction { type: "open-workspace-issue"; workspaceId: string; issueId: string | null; mode?: WorkspaceIssueMentionMode; outputDir?: string | null; runId?: string | null; taskId?: string | null; topicId?: string | null; source: WorkspaceLinkActionSource; } interface OpenWorkspaceAppLinkAction { type: "open-workspace-app"; workspaceId: string; appId: string; conversationId?: string | null; messageId?: string | null; summaryTaskId?: string | null; source: WorkspaceLinkActionSource; } interface OpenCustomMentionLinkAction { type: "open-custom-mention"; /** 注册表里的 kind(= mention:// providerId)。 */ kind: string; href: string; source: WorkspaceLinkActionSource; } type WorkspaceLinkAction = OpenWorkspaceFileLinkAction | OpenLocalAssetPreviewLinkAction | OpenWorkspaceUrlLinkAction | OpenAgentSessionLinkAction | OpenWorkspaceIssueLinkAction | OpenWorkspaceAppLinkAction | OpenCustomMentionLinkAction; export { type AgentApprovalItemVM as A, type BuildWorkspaceAgentSessionDetailInput as B, type WorkspaceAgentActivityCard as W, type AgentAskUserQuestionVM as a, type AgentConversationPromptVM as b, type AgentConversationVM as c, type AgentInteractionResponseInput as d, type WorkspaceAgentActivityStatus as e, type WorkspaceAgentActivityTimelineItem as f, type WorkspaceAgentSessionDetailViewModel as g, type WorkspaceLinkAction as h, buildWorkspaceAgentSessionDetailViewModel as i };