fix(logs): summarize operational tool previews

This commit is contained in:
777genius 2026-05-07 19:25:34 +03:00
parent cade7b4fdb
commit 8bc460721f
2 changed files with 427 additions and 14 deletions

View file

@ -1257,6 +1257,149 @@ Reply to this comment using MCP tool task_add_comment.
preview: '2 processes - vite dev running; pnpm test exited',
});
expect(processResult.items[0]?.preview).not.toContain('[{');
const taskUpdateResult = extractMemberLogPreviewItems({
provider: 'opencode_runtime',
maxItems: 3,
textLimit: 160,
messages: [
message({
uuid: 'task-update-call',
timestamp: '2026-04-01T10:00:00.000Z',
content: [
{
type: 'tool_use',
id: 'tool-task-update',
name: 'agent-teams_task_update',
input: {
taskId: 'abc12345-0000-0000-0000-000000000000',
status: 'in_progress',
},
},
],
}),
message({
uuid: 'task-update-result',
type: 'user',
role: 'user',
timestamp: '2026-04-01T10:01:00.000Z',
content: [
{
type: 'tool_result',
tool_use_id: 'tool-task-update',
content: {
taskId: 'abc12345-0000-0000-0000-000000000000',
status: 'in_progress',
},
},
],
}),
],
});
expect(taskUpdateResult.items[0]).toMatchObject({
kind: 'tool_result',
title: 'Task updated',
preview: '#abc12345 -> in_progress',
});
const remainingOperationalTools = [
{
toolName: 'agent-teams_lead_briefing',
input: { teamName: 'relay-works-10' },
result: 'Lead briefing for team relay-works-10. CRITICAL: hidden rules',
expectedTitle: 'Lead briefing',
expectedPreview: 'Loaded lead briefing for relay-works-10',
},
{
toolName: 'agent-teams_runtime_deliver_message',
input: { to: 'bob', text: 'Follow-up ready', runtimeSessionId: 'ses-secret' },
result: 'ok',
expectedTitle: 'Runtime delivery',
expectedPreview: 'Delivered to bob - Follow-up ready',
},
{
toolName: 'agent-teams_cross_team_list_targets',
input: { teamName: 'relay-works-10' },
result: JSON.stringify([{ teamName: 'qa-team' }, { name: 'design-team' }]),
expectedTitle: 'Cross-team targets',
expectedPreview: '2 teams - qa-team; design-team',
},
{
toolName: 'agent-teams_cross_team_get_outbox',
input: { teamName: 'relay-works-10' },
result: {
messages: [{ toTeam: 'qa-team', summary: 'Need smoke-test help' }],
},
expectedTitle: 'Cross-team outbox',
expectedPreview: '1 message - to qa-team: Need smoke-test help',
},
{
toolName: 'agent-teams_process_register',
input: { label: 'vite dev', command: 'pnpm dev' },
result: { process: { label: 'vite dev', status: 'running' } },
expectedTitle: 'Process registered',
expectedPreview: 'Registered vite dev running',
},
{
toolName: 'agent-teams_process_stop',
input: { label: 'vite dev' },
result: 'ok',
expectedTitle: 'Process stopped',
expectedPreview: 'Stopped vite dev',
},
{
toolName: 'agent-teams_process_unregister',
input: { pid: 123 },
result: 'ok',
expectedTitle: 'Process unregistered',
expectedPreview: 'Unregistered 123',
},
] as const;
for (const [index, tool] of remainingOperationalTools.entries()) {
const result = extractMemberLogPreviewItems({
provider: 'opencode_runtime',
maxItems: 3,
textLimit: 160,
messages: [
message({
uuid: `remaining-tool-call-${index}`,
timestamp: '2026-04-01T10:00:00.000Z',
content: [
{
type: 'tool_use',
id: `tool-remaining-${index}`,
name: tool.toolName,
input: tool.input,
},
],
}),
message({
uuid: `remaining-tool-result-${index}`,
type: 'user',
role: 'user',
timestamp: '2026-04-01T10:01:00.000Z',
content: [
{
type: 'tool_result',
tool_use_id: `tool-remaining-${index}`,
content: tool.result,
},
],
}),
],
});
expect(result.items[0]).toMatchObject({
kind: 'tool_result',
title: tool.expectedTitle,
preview: tool.expectedPreview,
});
expect(`${result.items[0]?.title ?? ''} ${result.items[0]?.preview ?? ''}`).not.toMatch(
/CRITICAL|runtimeSessionId|agent_teams_|process_register|cross_team_/i
);
}
});
it('uses concrete names for generic runtime tool results', () => {

View file

@ -136,20 +136,24 @@ function timestampIso(value: Date | string): string {
function stripAngleTags(value: string): string {
let result = '';
let insideTag = false;
for (const char of value) {
if (char === '<') {
insideTag = true;
result += ' ';
for (let index = 0; index < value.length; index += 1) {
const char = value[index];
if (!insideTag && char === '<') {
const next = value[index + 1] ?? '';
if (/[A-Za-z/!]/.test(next)) {
insideTag = true;
result += ' ';
continue;
}
}
if (insideTag) {
if (char === '>') {
insideTag = false;
result += ' ';
}
continue;
}
if (char === '>') {
insideTag = false;
result += ' ';
continue;
}
if (!insideTag) {
result += char;
}
result += char;
}
return result;
}
@ -468,6 +472,8 @@ function formatToolTitle(toolName: string): string {
const canonical = canonicalToolName(toolName);
if (canonical === 'sendmessage' || canonical === 'message_send') return 'Send message';
if (canonical === 'cross_team_send') return 'Cross-team message';
if (canonical === 'cross_team_list_targets') return 'List teams';
if (canonical === 'cross_team_get_outbox') return 'Cross-team outbox';
if (canonical === 'runtime_deliver_message') return 'Runtime delivery';
if (canonical === 'runtime_task_event') return 'Runtime task event';
if (canonical === 'runtime_heartbeat') return 'Runtime heartbeat';
@ -492,6 +498,7 @@ function formatToolTitle(toolName: string): string {
if (canonical === 'review_approve') return 'Approve review';
if (canonical === 'review_request_changes') return 'Request changes';
if (canonical === 'runtime_bootstrap_checkin') return 'Runtime check-in';
if (canonical === 'lead_briefing') return 'Lead briefing';
if (canonical === 'member_briefing') return 'Member briefing';
if (canonical === 'member_work_sync_status') return 'Work sync status';
if (canonical === 'member_work_sync_report') return 'Work sync report';
@ -499,6 +506,9 @@ function formatToolTitle(toolName: string): string {
if (canonical === 'task_update') return 'Update task';
if (canonical === 'task_delete') return 'Delete task';
if (canonical === 'process_list') return 'List processes';
if (canonical === 'process_register') return 'Register process';
if (canonical === 'process_stop') return 'Stop process';
if (canonical === 'process_unregister') return 'Unregister process';
return humanizeFallbackToolName(toolName);
}
@ -525,14 +535,16 @@ function isToolUseSupersededBySuccessResult(toolName: string): boolean {
return (
canonical === 'sendmessage' ||
canonical === 'message_send' ||
canonical === 'cross_team_send' ||
canonical.startsWith('cross_team_') ||
canonical === 'runtime_deliver_message' ||
canonical === 'runtime_bootstrap_checkin' ||
canonical === 'runtime_heartbeat' ||
canonical === 'runtime_task_event' ||
canonical === 'lead_briefing' ||
canonical === 'member_briefing' ||
canonical === 'member_work_sync_status' ||
canonical === 'member_work_sync_report' ||
canonical.startsWith('process_') ||
canonical.startsWith('task_') ||
canonical.startsWith('review_')
);
@ -765,6 +777,172 @@ function formatProcessCollectionArrayPayload(items: readonly unknown[]): KnownPa
};
}
function processLabelFromPayload(
payload: Record<string, unknown>,
fallbackInput?: Record<string, unknown> | null
): string | null {
const process = asRecord(payload.process) ?? asRecord(fallbackInput?.process) ?? undefined;
return (
[
stringField(payload, 'label'),
stringField(payload, 'name'),
stringField(payload, 'command'),
stringField(payload, 'processId'),
stringField(payload, 'id'),
stringifyPrimitive(payload.pid),
stringField(process, 'label'),
stringField(process, 'name'),
stringField(process, 'command'),
stringField(process, 'processId'),
stringField(process, 'id'),
stringifyPrimitive(process?.pid),
stringField(fallbackInput ?? undefined, 'label'),
stringField(fallbackInput ?? undefined, 'name'),
stringField(fallbackInput ?? undefined, 'command'),
stringField(fallbackInput ?? undefined, 'processId'),
stringField(fallbackInput ?? undefined, 'id'),
stringifyPrimitive(fallbackInput?.pid),
].find((value) => typeof value === 'string' && value.trim().length > 0) ?? null
);
}
function formatProcessLifecyclePayload(
payload: Record<string, unknown>,
canonicalToolNameValue: string | null,
fallbackInput?: Record<string, unknown> | null
): KnownPayloadPreview | null {
const canonical = canonicalToolNameValue ?? '';
if (
canonical !== 'process_register' &&
canonical !== 'process_stop' &&
canonical !== 'process_unregister'
) {
return null;
}
const label = processLabelFromPayload(payload, fallbackInput);
const status =
stringField(payload, 'status') ??
stringField(asRecord(payload.process), 'status') ??
stringField(fallbackInput ?? undefined, 'status');
if (canonical === 'process_register') {
const suffix = status && label ? ` ${status}` : '';
return {
title: 'Process registered',
text: label ? `Registered ${label}${suffix}` : 'Registered process',
};
}
if (canonical === 'process_stop') {
return {
title: 'Process stopped',
text: label ? `Stopped ${label}` : 'Stopped process',
};
}
return {
title: 'Process unregistered',
text: label ? `Unregistered ${label}` : 'Unregistered process',
};
}
function formatCrossTeamTargetItem(item: Record<string, unknown>): string | null {
return (
stringField(item, 'teamName') ??
stringField(item, 'name') ??
stringField(item, 'id') ??
stringField(item, 'slug')
);
}
function formatCrossTeamOutboxItem(item: Record<string, unknown>): string | null {
const target =
stringField(item, 'toTeam') ??
stringField(item, 'targetTeam') ??
stringField(item, 'teamName') ??
stringField(item, 'target');
const summary =
stringField(item, 'summary') ??
stringField(item, 'text') ??
stringField(item, 'message') ??
stringField(item, 'content');
if (target && summary) return `to ${target}: ${summary}`;
return target ?? summary;
}
function formatCrossTeamCollectionArrayPayload(
items: readonly unknown[],
canonicalToolNameValue: string | null
): KnownPayloadPreview | null {
const canonical = canonicalToolNameValue ?? '';
const title =
canonical === 'cross_team_list_targets'
? 'Cross-team targets'
: canonical === 'cross_team_get_outbox'
? 'Cross-team outbox'
: null;
if (!title) return null;
const records = items
.map((item) => asRecord(item))
.filter((item): item is Record<string, unknown> => Boolean(item));
const summaries = records
.slice(0, 3)
.map((item) =>
canonical === 'cross_team_list_targets'
? formatCrossTeamTargetItem(item)
: formatCrossTeamOutboxItem(item)
)
.filter(Boolean);
const remainingCount = Math.max(0, records.length - summaries.length);
const moreText = remainingCount > 0 ? `; +${remainingCount} more` : '';
if (canonical === 'cross_team_list_targets') {
const countText = `${records.length} ${records.length === 1 ? 'team' : 'teams'}`;
return {
title,
text: summaries.length > 0 ? `${countText} - ${summaries.join('; ')}${moreText}` : countText,
};
}
const countText = `${records.length} ${records.length === 1 ? 'message' : 'messages'}`;
return {
title,
text: summaries.length > 0 ? `${countText} - ${summaries.join('; ')}${moreText}` : countText,
};
}
function formatCrossTeamCollectionPayload(
payload: Record<string, unknown>,
canonicalToolNameValue: string | null
): KnownPayloadPreview | null {
const canonical = canonicalToolNameValue ?? '';
if (canonical !== 'cross_team_list_targets' && canonical !== 'cross_team_get_outbox') {
return null;
}
const rawItems =
(Array.isArray(payload.targets) ? payload.targets : null) ??
(Array.isArray(payload.teams) ? payload.teams : null) ??
(Array.isArray(payload.messages) ? payload.messages : null) ??
(Array.isArray(payload.outbox) ? payload.outbox : null) ??
(Array.isArray(payload.items) ? payload.items : null);
if (rawItems) {
return formatCrossTeamCollectionArrayPayload(rawItems, canonical);
}
const summary =
stringField(payload, 'summary') ??
stringField(payload, 'message') ??
stringField(payload, 'text');
if (summary) {
return {
title: canonical === 'cross_team_list_targets' ? 'Cross-team targets' : 'Cross-team outbox',
text: summary,
};
}
return null;
}
function formatRelationshipPayload(
payload: Record<string, unknown>,
fallbackInput?: Record<string, unknown> | null
@ -959,6 +1137,26 @@ function formatRuntimePayload(
text: memberName ? `${memberName} checked in` : 'Runtime checked in',
};
}
if (canonical === 'runtime_deliver_message') {
const target =
stringField(payload, 'to') ??
stringField(payload, 'target') ??
stringField(fallbackInput ?? undefined, 'to') ??
stringField(fallbackInput ?? undefined, 'target');
const summary =
stringField(payload, 'summary') ??
stringField(payload, 'message') ??
stringField(payload, 'text') ??
stringField(fallbackInput ?? undefined, 'summary') ??
stringField(fallbackInput ?? undefined, 'message') ??
stringField(fallbackInput ?? undefined, 'text');
if (target && summary) {
return { title: 'Runtime delivery', text: `Delivered to ${target} - ${summary}` };
}
if (target) return { title: 'Runtime delivery', text: `Delivered to ${target}` };
if (summary) return { title: 'Runtime delivery', text: summary };
return { title: 'Runtime delivery', text: 'Delivered runtime message' };
}
if (canonical === 'runtime_heartbeat') {
return {
title: 'Runtime heartbeat',
@ -985,6 +1183,14 @@ function formatRuntimePayload(
text: memberName ? `Loaded briefing for ${memberName}` : 'Loaded member briefing',
};
}
if (canonical === 'lead_briefing') {
const teamName =
stringField(payload, 'teamName') ?? stringField(fallbackInput ?? undefined, 'teamName');
return {
title: 'Lead briefing',
text: teamName ? `Loaded lead briefing for ${teamName}` : 'Loaded lead briefing',
};
}
return null;
}
@ -1125,14 +1331,25 @@ function formatPlainToolResultStatus(
if (!toolContext) {
return null;
}
if (toolContext.canonicalName === 'member_briefing') {
if (
toolContext.canonicalName === 'member_briefing' ||
toolContext.canonicalName === 'lead_briefing'
) {
const memberMatch = /^member briefing for\s+([^\s]+)\s+on team\b/i.exec(
compactWhitespace(value)
);
const teamMatch = /^lead briefing for team\s+([^\s.]+)/i.exec(compactWhitespace(value));
const memberName =
memberMatch?.[1] ??
stringField(asRecord(toolContext.input), 'memberName') ??
stringField(asRecord(toolContext.input), 'member');
if (toolContext.canonicalName === 'lead_briefing') {
const teamName = teamMatch?.[1] ?? stringField(asRecord(toolContext.input), 'teamName');
return {
title: 'Lead briefing',
text: teamName ? `Loaded lead briefing for ${teamName}` : 'Loaded lead briefing',
};
}
return {
title: 'Member briefing',
text: memberName ? `Loaded briefing for ${memberName}` : 'Loaded member briefing',
@ -1151,12 +1368,30 @@ function formatPlainToolResultStatus(
const text = fallbackInput ? formatCrossTeamPayload(fallbackInput) : null;
return text ? { title: 'Cross-team message', text } : null;
}
if (toolContext.canonicalName === 'cross_team_list_targets') {
const teamName = stringField(fallbackInput ?? undefined, 'teamName');
return {
title: 'Cross-team targets',
text: teamName ? `Listed teams for ${teamName}` : 'Listed cross-team targets',
};
}
if (toolContext.canonicalName === 'cross_team_get_outbox') {
const teamName = stringField(fallbackInput ?? undefined, 'teamName');
return {
title: 'Cross-team outbox',
text: teamName ? `Loaded outbox for ${teamName}` : 'Loaded cross-team outbox',
};
}
if (
toolContext.canonicalName === 'member_work_sync_status' ||
toolContext.canonicalName === 'member_work_sync_report'
) {
return formatWorkSyncPayload({}, toolContext.canonicalName, fallbackInput);
}
const processText = formatProcessLifecyclePayload({}, toolContext.canonicalName, fallbackInput);
if (processText) {
return processText;
}
return (
formatTaskToolPayload({}, toolContext.canonicalName, fallbackInput) ??
formatRuntimePayload({}, toolContext.canonicalName, fallbackInput)
@ -1268,6 +1503,14 @@ function formatKnownPayloadPreview(
if (workSyncText) {
return workSyncText;
}
const processLifecycleText = formatProcessLifecyclePayload(payload, canonical, fallbackInput);
if (processLifecycleText) {
return processLifecycleText;
}
const crossTeamCollectionText = formatCrossTeamCollectionPayload(payload, canonical);
if (crossTeamCollectionText) {
return crossTeamCollectionText;
}
if (canonical === 'process_list') {
const processText = formatProcessCollectionPayload(payload);
if (processText) {
@ -1340,6 +1583,16 @@ function previewUnknownValue(
if (knownCollection) {
return { ...truncatePreview(knownCollection.text, limit), title: knownCollection.title };
}
const crossTeamCollection = formatCrossTeamCollectionArrayPayload(
value,
toolContext?.canonicalName ?? null
);
if (crossTeamCollection) {
return {
...truncatePreview(crossTeamCollection.text, limit),
title: crossTeamCollection.title,
};
}
if (toolContext?.canonicalName === 'process_list') {
const processCollection = formatProcessCollectionArrayPayload(value);
return { ...truncatePreview(processCollection.text, limit), title: processCollection.title };
@ -1396,6 +1649,19 @@ function previewToolInputValue(toolName: string, value: unknown, limit: number):
return truncatePreview(formatted, limit);
}
}
if (canonical === 'cross_team_list_targets' || canonical === 'cross_team_get_outbox') {
const payload = recordFromUnknown(value);
const teamName = payload ? stringField(payload, 'teamName') : null;
const text =
canonical === 'cross_team_list_targets'
? teamName
? `for ${teamName}`
: 'List cross-team targets'
: teamName
? `for ${teamName}`
: 'Read cross-team outbox';
return truncatePreview(text, limit);
}
const payload = recordFromUnknown(value);
if (payload) {
const runtimeFormatted = formatRuntimePayload(payload, canonical, payload);
@ -1406,6 +1672,10 @@ function previewToolInputValue(toolName: string, value: unknown, limit: number):
if (workSyncFormatted) {
return truncatePreview(workSyncFormatted.text, limit);
}
const processFormatted = formatProcessLifecyclePayload(payload, canonical, payload);
if (processFormatted) {
return truncatePreview(processFormatted.text, limit);
}
const taskFormatted = formatTaskToolInputPayload(canonical, payload);
if (taskFormatted) {
return truncatePreview(taskFormatted, limit);