feat(chat): #155 paste image depuis presse-papier dans le composer custom (QA verte)
- frontend: onPaste sur CustomAgentChatView, détection MIME image, chip/preview d'attachment, envoi via le contrat #154 (adapters/agent, ports) - backend: import d'image par bytes dans le store attachments (commands, chat_attachments app+infra, dto, ports) + tests
This commit is contained in:
@ -171,6 +171,38 @@ describe("TauriAgentGateway invoke payloads", () => {
|
||||
expect(invoke).not.toHaveBeenCalledWith("close_agent_session", expect.anything());
|
||||
});
|
||||
|
||||
it("sendAgentChat forwards structured clipboard attachments to agent_send", async () => {
|
||||
await new TauriAgentGateway().sendAgentChat(
|
||||
"chat-session-1",
|
||||
"",
|
||||
vi.fn(),
|
||||
{
|
||||
attachments: [
|
||||
{
|
||||
filename: "clipboard.png",
|
||||
contentBase64: "AQID",
|
||||
mime: "image/png",
|
||||
sourceKind: "clipboard",
|
||||
},
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
expect(invoke).toHaveBeenCalledWith("agent_send", {
|
||||
sessionId: "chat-session-1",
|
||||
prompt: "",
|
||||
attachments: [
|
||||
{
|
||||
filename: "clipboard.png",
|
||||
contentBase64: "AQID",
|
||||
mime: "image/png",
|
||||
sourceKind: "clipboard",
|
||||
},
|
||||
],
|
||||
onReply: expect.anything(),
|
||||
});
|
||||
});
|
||||
|
||||
it("launchAgentChat returns a handle only when launch_agent confirms cellKind chat", async () => {
|
||||
invoke.mockResolvedValueOnce({
|
||||
sessionId: "chat-session-1",
|
||||
|
||||
@ -32,6 +32,7 @@ import type {
|
||||
OpenTerminalOptions,
|
||||
ReattachAgentChatResult,
|
||||
ReattachResult,
|
||||
SendAgentChatOptions,
|
||||
StoppedLiveAgent,
|
||||
TerminalHandle,
|
||||
} from "@/ports";
|
||||
@ -261,12 +262,14 @@ export class TauriAgentGateway implements AgentGateway {
|
||||
sessionId: string,
|
||||
prompt: string,
|
||||
onChunk: (chunk: ReplyChunk) => void,
|
||||
options: SendAgentChatOptions = {},
|
||||
): Promise<void> {
|
||||
const channel = new Channel<ReplyChunk>();
|
||||
channel.onmessage = onChunk;
|
||||
await invoke("agent_send", {
|
||||
sessionId,
|
||||
prompt,
|
||||
...(options.attachments ? { attachments: options.attachments } : {}),
|
||||
onReply: channel,
|
||||
});
|
||||
}
|
||||
|
||||
@ -150,6 +150,7 @@ import type {
|
||||
RemoteGateway,
|
||||
ReviewPluginPackageInput,
|
||||
SaveOpenCodeProviderProfileInput,
|
||||
SendAgentChatOptions,
|
||||
SkillGateway,
|
||||
StoppedLiveAgent,
|
||||
SystemGateway,
|
||||
@ -826,6 +827,7 @@ export class MockAgentGateway implements AgentGateway {
|
||||
sessionId: string,
|
||||
prompt: string,
|
||||
onChunk: (chunk: ReplyChunk) => void,
|
||||
_options: SendAgentChatOptions = {},
|
||||
): Promise<void> {
|
||||
const chunks = this.chatScrollback.get(sessionId);
|
||||
if (!chunks) {
|
||||
|
||||
Reference in New Issue
Block a user