feat(chat): valide le routing cellKind=chat côté frontend et corrige UX
- Ajoute cellKind dans AgentChatHandle et vérifie que launchAgentChat reçoit cellKind:chat - Rejette avec erreur STRUCTURED_ROUTED_TO_PTY si le backend route vers PTY - Ajoute cellKind:chat dans MockAgentGateway.launchAgentChat - Corrige l'overflow du layout CustomAgentChatView (bounded shell avec scroll + composer fixe) - Dédouble les prompts utilisateur quand le stream les echo - Ajoute les tests launchAgentChat returns handle only when confirms chat et launchAgentChat rejects PTY-routed launch - Ajoute les tests does not duplicate user prompt when echoed et keeps chat shell bounded Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -170,4 +170,77 @@ describe("TauriAgentGateway invoke payloads", () => {
|
||||
});
|
||||
expect(invoke).not.toHaveBeenCalledWith("close_agent_session", expect.anything());
|
||||
});
|
||||
|
||||
it("launchAgentChat returns a handle only when launch_agent confirms cellKind chat", async () => {
|
||||
invoke.mockResolvedValueOnce({
|
||||
sessionId: "chat-session-1",
|
||||
cwd: "/repo",
|
||||
rows: 24,
|
||||
cols: 80,
|
||||
cellKind: "chat",
|
||||
assignedConversationId: "conversation-1",
|
||||
});
|
||||
|
||||
const out = await new TauriAgentGateway().launchAgentChat("proj-1", "agent-2", {
|
||||
cwd: "/repo",
|
||||
rows: 24,
|
||||
cols: 80,
|
||||
conversationId: "conversation-0",
|
||||
nodeId: "node-3",
|
||||
});
|
||||
|
||||
expect(invoke).toHaveBeenCalledWith("launch_agent", {
|
||||
request: {
|
||||
projectId: "proj-1",
|
||||
agentId: "agent-2",
|
||||
rows: 24,
|
||||
cols: 80,
|
||||
cellKind: "chat",
|
||||
conversationId: "conversation-0",
|
||||
nodeId: "node-3",
|
||||
},
|
||||
onOutput: expect.anything(),
|
||||
});
|
||||
expect(out).toEqual({
|
||||
sessionId: "chat-session-1",
|
||||
cellKind: "chat",
|
||||
assignedConversationId: "conversation-1",
|
||||
});
|
||||
});
|
||||
|
||||
it("launchAgentChat rejects a PTY-routed launch before returning a fake structured session", async () => {
|
||||
const log = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
invoke.mockResolvedValueOnce({
|
||||
sessionId: "pty-session-1",
|
||||
cwd: "/repo",
|
||||
rows: 24,
|
||||
cols: 80,
|
||||
cellKind: "pty",
|
||||
});
|
||||
|
||||
await expect(
|
||||
new TauriAgentGateway().launchAgentChat("proj-1", "agent-2", {
|
||||
cwd: "/repo",
|
||||
rows: 24,
|
||||
cols: 80,
|
||||
nodeId: "node-3",
|
||||
}),
|
||||
).rejects.toEqual({
|
||||
code: "STRUCTURED_ROUTED_TO_PTY",
|
||||
message:
|
||||
"custom CLI launch for agent agent-2 in project proj-1 returned cellKind=pty; expected chat. sessionId=pty-session-1; nodeId=node-3",
|
||||
});
|
||||
expect(log).toHaveBeenCalledWith(
|
||||
"[ticket149] launchAgentChat:routed-to-non-chat",
|
||||
expect.objectContaining({
|
||||
projectId: "proj-1",
|
||||
agentId: "agent-2",
|
||||
response: expect.objectContaining({
|
||||
sessionId: "pty-session-1",
|
||||
cellKind: "pty",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
log.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user