fix(agents): enforcer l'invariant « 1 session vivante par agent » (singleton)
Un agent ne peut tourner que dans une seule cellule à la fois. La garde dans LaunchAgent refuse le spawn si l'agent est déjà vivant dans un autre node (AGENT_ALREADY_RUNNING) ; idempotent sur le même node ; le chemin resume (agent mort) reste inchangé. Le node_id est désormais plombé jusqu'au use case. Corrige le reset asymétrique d'une cellule au changement d'onglet : deux leaves partageant le même agent id rendaient session_for_agent/is_agent_live/stop_agent ambigus (cible arbitraire). Le churn reset/reattach déclenchait aussi les accents mélangés (FIFO intact, non touché). - snapshot agentWasRunning calculé par node (is_node_live) et non par agent - commande list_live_agents + live_agents()/node_for_agent()/is_node_live() - UI : dropdown grise les agents déjà placés ailleurs ; 2e cellule en doublon affiche « disponible » au lieu d'une relance fantôme Tests : cargo test (application + app-tauri) vert ; tsc + vitest vert. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -19,6 +19,7 @@ import type {
|
||||
AgentGateway,
|
||||
ConversationDetails,
|
||||
CreateAgentInput,
|
||||
LiveAgent,
|
||||
OpenTerminalOptions,
|
||||
ReattachResult,
|
||||
TerminalHandle,
|
||||
@ -40,6 +41,10 @@ export class TauriAgentGateway implements AgentGateway {
|
||||
return invoke<Agent[]>("list_agents", { projectId });
|
||||
}
|
||||
|
||||
listLiveAgents(projectId: string): Promise<LiveAgent[]> {
|
||||
return invoke<LiveAgent[]>("list_live_agents", { projectId });
|
||||
}
|
||||
|
||||
createAgent(projectId: string, input: CreateAgentInput): Promise<Agent> {
|
||||
// The `create_agent` command takes a single `request` DTO; `projectId` must
|
||||
// live *inside* it (camelCase), not at the top level.
|
||||
@ -91,6 +96,8 @@ export class TauriAgentGateway implements AgentGateway {
|
||||
// Resume id: the leaf's persisted conversation id, when any (T4b). The
|
||||
// backend resumes it; absent ⇒ a fresh cell that may get a new id.
|
||||
conversationId: options.conversationId ?? null,
|
||||
// Hosting cell: lets the backend enforce one-live-session-per-agent.
|
||||
nodeId: options.nodeId ?? null,
|
||||
},
|
||||
onOutput: channel,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user