Collect and send tool_log with final message

Router collects tool calls (name + truncated result) during agent run.
Sends tool_log array with final chat.send via WS.
This commit is contained in:
Markov 2026-02-27 11:55:19 +01:00
parent 1322a0b480
commit 4c7a41494a
2 changed files with 18 additions and 7 deletions

View File

@ -121,6 +121,7 @@ export class EventRouter {
[], [],
result.thinking || undefined, result.thinking || undefined,
target.task_id, target.task_id,
result.toolLog.length > 0 ? result.toolLog : undefined,
); );
} else { } else {
// Fallback to REST if no WS transport // Fallback to REST if no WS transport
@ -147,10 +148,12 @@ export class EventRouter {
private async runAgent( private async runAgent(
prompt: string, prompt: string,
target: { chat_id?: string; task_id?: string } | null, target: { chat_id?: string; task_id?: string } | null,
): Promise<{ text: string; thinking: string; usedSendMessage: boolean }> { ): Promise<{ text: string; thinking: string; toolLog: Array<{name: string; args?: string; result?: string; error?: boolean}>; usedSendMessage: boolean }> {
let text = ''; let text = '';
let thinking = ''; let thinking = '';
let usedSendMessage = false; let usedSendMessage = false;
const toolLog: Array<{name: string; args?: string; result?: string; error?: boolean}> = [];
let currentToolName = '';
for await (const msg of runAgent(prompt, { for await (const msg of runAgent(prompt, {
workDir: this.config.workDir, workDir: this.config.workDir,
@ -194,31 +197,38 @@ export class EventRouter {
} }
} }
// Stream tool calls // Stream tool calls and collect for tool_log
if (msg.type === 'tool_use') { if (msg.type === 'tool_use') {
if (msg.content?.startsWith('send_message')) { currentToolName = msg.content || '';
if (currentToolName.startsWith('send_message')) {
usedSendMessage = true; usedSendMessage = true;
} }
toolLog.push({ name: currentToolName });
if (this.wsTransport && target) { if (this.wsTransport && target) {
this.wsTransport.sendStreamEvent('agent.stream.tool', { this.wsTransport.sendStreamEvent('agent.stream.tool', {
...target, ...target,
tool: msg.content || '', tool: currentToolName,
status: 'running', status: 'running',
}); });
} }
} }
if (msg.type === 'tool_result') { if (msg.type === 'tool_result') {
// Update last tool log entry with result
if (toolLog.length > 0) {
const last = toolLog[toolLog.length - 1];
last.result = (msg.content || '').slice(0, 500); // truncate long results
}
if (this.wsTransport && target) { if (this.wsTransport && target) {
this.wsTransport.sendStreamEvent('agent.stream.tool', { this.wsTransport.sendStreamEvent('agent.stream.tool', {
...target, ...target,
tool: msg.content || '', tool: currentToolName,
status: 'done', status: 'done',
}); });
} }
} }
} }
return { text: text.trim(), thinking: thinking.trim(), usedSendMessage }; return { text: text.trim(), thinking: thinking.trim(), toolLog, usedSendMessage };
} }
} }

View File

@ -263,11 +263,12 @@ export class WsClientTransport implements TaskTracker {
} }
/** Send a chat message via WebSocket (with optional thinking) */ /** Send a chat message via WebSocket (with optional thinking) */
sendChatMessage(chatId: string, content: string, mentions: string[] = [], thinking?: string, taskId?: string): void { sendChatMessage(chatId: string, content: string, mentions: string[] = [], thinking?: string, taskId?: string, toolLog?: Array<Record<string, unknown>>): void {
const payload: Record<string, unknown> = { content, mentions }; const payload: Record<string, unknown> = { content, mentions };
if (chatId) payload.chat_id = chatId; if (chatId) payload.chat_id = chatId;
if (taskId) payload.task_id = taskId; if (taskId) payload.task_id = taskId;
if (thinking) payload.thinking = thinking; if (thinking) payload.thinking = thinking;
if (toolLog && toolLog.length > 0) payload.tool_log = toolLog;
this.send('chat.send', payload); this.send('chat.send', payload);
} }