feat(v2): add agent pane with SDK message adapter and dispatcher
Implement full agent session frontend: SDK message adapter parsing stream-json into 9 typed message types, agent bridge for Tauri IPC, dispatcher routing sidecar events to store, agent session store with cost tracking, and AgentPane component with prompt input, message rendering (text, thinking, tool calls, results, cost), and stop button. Add Ctrl+Shift+N shortcut and sidebar agent button.
This commit is contained in:
parent
f928501075
commit
314c6d77aa
8 changed files with 914 additions and 41 deletions
|
|
@ -1,34 +1,91 @@
|
|||
// Agent tracking state — Svelte 5 runes
|
||||
// Phase 3: SDK agent lifecycle, subagent tree
|
||||
// Manages agent session lifecycle and message history
|
||||
|
||||
export type AgentStatus = 'idle' | 'running' | 'thinking' | 'waiting' | 'done' | 'error';
|
||||
import type { AgentMessage } from '../adapters/sdk-messages';
|
||||
|
||||
export interface AgentState {
|
||||
export type AgentStatus = 'idle' | 'starting' | 'running' | 'done' | 'error';
|
||||
|
||||
export interface AgentSession {
|
||||
id: string;
|
||||
sessionId: string;
|
||||
parentId?: string;
|
||||
sdkSessionId?: string;
|
||||
status: AgentStatus;
|
||||
model?: string;
|
||||
costUsd?: number;
|
||||
tokensIn?: number;
|
||||
tokensOut?: number;
|
||||
prompt: string;
|
||||
messages: AgentMessage[];
|
||||
costUsd: number;
|
||||
inputTokens: number;
|
||||
outputTokens: number;
|
||||
numTurns: number;
|
||||
durationMs: number;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
let agents = $state<AgentState[]>([]);
|
||||
let sessions = $state<AgentSession[]>([]);
|
||||
|
||||
export function getAgents() {
|
||||
return agents;
|
||||
export function getAgentSessions(): AgentSession[] {
|
||||
return sessions;
|
||||
}
|
||||
|
||||
export function getAgentTree(rootId: string): AgentState[] {
|
||||
const result: AgentState[] = [];
|
||||
const root = agents.find(a => a.id === rootId);
|
||||
if (!root) return result;
|
||||
|
||||
result.push(root);
|
||||
const children = agents.filter(a => a.parentId === rootId);
|
||||
for (const child of children) {
|
||||
result.push(...getAgentTree(child.id));
|
||||
}
|
||||
return result;
|
||||
export function getAgentSession(id: string): AgentSession | undefined {
|
||||
return sessions.find(s => s.id === id);
|
||||
}
|
||||
|
||||
export function createAgentSession(id: string, prompt: string): void {
|
||||
sessions.push({
|
||||
id,
|
||||
status: 'starting',
|
||||
prompt,
|
||||
messages: [],
|
||||
costUsd: 0,
|
||||
inputTokens: 0,
|
||||
outputTokens: 0,
|
||||
numTurns: 0,
|
||||
durationMs: 0,
|
||||
});
|
||||
}
|
||||
|
||||
export function updateAgentStatus(id: string, status: AgentStatus, error?: string): void {
|
||||
const session = sessions.find(s => s.id === id);
|
||||
if (!session) return;
|
||||
session.status = status;
|
||||
if (error) session.error = error;
|
||||
}
|
||||
|
||||
export function setAgentSdkSessionId(id: string, sdkSessionId: string): void {
|
||||
const session = sessions.find(s => s.id === id);
|
||||
if (session) session.sdkSessionId = sdkSessionId;
|
||||
}
|
||||
|
||||
export function setAgentModel(id: string, model: string): void {
|
||||
const session = sessions.find(s => s.id === id);
|
||||
if (session) session.model = model;
|
||||
}
|
||||
|
||||
export function appendAgentMessage(id: string, message: AgentMessage): void {
|
||||
const session = sessions.find(s => s.id === id);
|
||||
if (!session) return;
|
||||
session.messages.push(message);
|
||||
}
|
||||
|
||||
export function appendAgentMessages(id: string, messages: AgentMessage[]): void {
|
||||
const session = sessions.find(s => s.id === id);
|
||||
if (!session) return;
|
||||
session.messages.push(...messages);
|
||||
}
|
||||
|
||||
export function updateAgentCost(
|
||||
id: string,
|
||||
cost: { costUsd: number; inputTokens: number; outputTokens: number; numTurns: number; durationMs: number },
|
||||
): void {
|
||||
const session = sessions.find(s => s.id === id);
|
||||
if (!session) return;
|
||||
session.costUsd = cost.costUsd;
|
||||
session.inputTokens = cost.inputTokens;
|
||||
session.outputTokens = cost.outputTokens;
|
||||
session.numTurns = cost.numTurns;
|
||||
session.durationMs = cost.durationMs;
|
||||
}
|
||||
|
||||
export function removeAgentSession(id: string): void {
|
||||
sessions = sessions.filter(s => s.id !== id);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue