feat(webchat): support image attachments
This commit is contained in:
@@ -21,11 +21,18 @@ export function createAgentHandlers(deps: AgentHandlerDeps) {
|
||||
return {
|
||||
'agent.send': async (request: GatewayRequest, send: SendFn): Promise<OutboundMessage | void> => {
|
||||
const params = request.params as { message?: string; connectionId?: string; attachments?: GatewayAttachment[]; metadata?: { isCommand?: boolean; command?: string; commandArgs?: string } } | undefined;
|
||||
if (!params?.message && !params?.metadata?.isCommand) {
|
||||
return makeError(request.id, ErrorCode.InvalidRequest, 'message is required');
|
||||
if (!params) {
|
||||
return makeError(request.id, ErrorCode.InvalidRequest, 'params are required');
|
||||
}
|
||||
|
||||
const connectionId = params.connectionId as string;
|
||||
const safeParams = params;
|
||||
const hasMessage = Boolean(safeParams.message && safeParams.message.trim());
|
||||
const hasAttachments = Boolean(safeParams.attachments && safeParams.attachments.length > 0);
|
||||
if (!hasMessage && !hasAttachments && !safeParams.metadata?.isCommand) {
|
||||
return makeError(request.id, ErrorCode.InvalidRequest, 'message or attachments are required');
|
||||
}
|
||||
|
||||
const connectionId = safeParams.connectionId as string;
|
||||
if (!connectionId) {
|
||||
return makeError(request.id, ErrorCode.InvalidRequest, 'connectionId is required (set by server)');
|
||||
}
|
||||
@@ -48,9 +55,9 @@ export function createAgentHandlers(deps: AgentHandlerDeps) {
|
||||
return deps.laneQueue.enqueue(laneId, async () => {
|
||||
deps.sessionBridge.setBusy(connectionId, true);
|
||||
|
||||
const commandInput = params.metadata?.isCommand && typeof params.metadata.command === 'string'
|
||||
? `/${params.metadata.command}${params.metadata.commandArgs ? ` ${params.metadata.commandArgs}` : ''}`
|
||||
: params.message;
|
||||
const commandInput = safeParams.metadata?.isCommand && typeof safeParams.metadata.command === 'string'
|
||||
? `/${safeParams.metadata.command}${safeParams.metadata.commandArgs ? ` ${safeParams.metadata.commandArgs}` : ''}`
|
||||
: (safeParams.message ?? '');
|
||||
|
||||
if (commandInput && deps.commandRegistry?.isCommand(commandInput)) {
|
||||
const sessionId = deps.sessionBridge.getSessionId(connectionId);
|
||||
@@ -160,14 +167,14 @@ export function createAgentHandlers(deps: AgentHandlerDeps) {
|
||||
|
||||
try {
|
||||
// Convert gateway attachments to channel attachments
|
||||
const attachments: Attachment[] | undefined = params.attachments?.map(a => ({
|
||||
const attachments: Attachment[] | undefined = safeParams.attachments?.map(a => ({
|
||||
mimeType: a.mimeType,
|
||||
data: a.data,
|
||||
url: a.url,
|
||||
filename: a.filename,
|
||||
}));
|
||||
|
||||
const response = await agent.process(params.message!, attachments);
|
||||
const response = await agent.process(safeParams.message ?? '', attachments);
|
||||
deps.metrics?.incrementMessages();
|
||||
send(makeEvent(request.id, 'done', { content: response }));
|
||||
} catch (err) {
|
||||
|
||||
@@ -323,7 +323,28 @@ describe('agent handlers', () => {
|
||||
expect(sent).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('agent.send requires message', async () => {
|
||||
it('agent.send accepts attachment-only requests', async () => {
|
||||
const req: GatewayRequest = {
|
||||
id: 12,
|
||||
method: 'agent.send',
|
||||
params: {
|
||||
connectionId: 'conn-1',
|
||||
attachments: [{ mimeType: 'image/png', data: 'iVBOR...' }],
|
||||
},
|
||||
};
|
||||
const sent: OutboundMessage[] = [];
|
||||
const send = vi.fn((msg: OutboundMessage) => sent.push(msg));
|
||||
|
||||
await handlers['agent.send'](req, send);
|
||||
|
||||
expect(mockAgent.process).toHaveBeenCalledWith('', [
|
||||
{ mimeType: 'image/png', data: 'iVBOR...', url: undefined, filename: undefined },
|
||||
]);
|
||||
expect(sent).toHaveLength(1);
|
||||
expect((sent[0] as GatewayEvent).event).toBe('done');
|
||||
});
|
||||
|
||||
it('agent.send requires message or attachments', async () => {
|
||||
const req: GatewayRequest = { id: 2, method: 'agent.send', params: { connectionId: 'conn-1' } };
|
||||
const send = vi.fn();
|
||||
const result = await handlers['agent.send'](req, send) as GatewayError;
|
||||
|
||||
Reference in New Issue
Block a user