mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-04 23:44:41 +00:00
Paseo tool rows put the variable part first ("QA messenger finished"), so
truncation hid the fixed part, and MCP calls showed only the humanized tool
name with no context. Every Paseo tool now has one catalog entry in
protocol/paseo-tool-presentation owning its fixed label, the input field
shown as context, and its detail layout. Agent-message events read
noun-first ("Agent finished" + sender) and use the Paseo icon; the app
ignored it before because the wire detail's legacy "bot" icon won.
Summaries are capped in code at 120 characters because prompts can be one
enormous line; the renderer is not trusted to clip them.
The activity curator behind `paseo logs` and get_agent_activity printed a
bare "[Agent message]" because the server tool-call type never declared the
agentMessage field the projection sets; it now prints the event, sender,
and body.
22 lines
900 B
TypeScript
22 lines
900 B
TypeScript
/**
|
|
* Prompts and results can be one enormous line. Summaries are capped here so no
|
|
* consumer relies on its renderer to clip them.
|
|
*/
|
|
export const MAX_SUMMARY_CHARS = 120;
|
|
// Bounds the whitespace scan: inputs can be megabytes.
|
|
const SCAN_WINDOW_CHARS = MAX_SUMMARY_CHARS * 4;
|
|
|
|
export function toSummaryText(value: string): string | undefined {
|
|
const isPartial = value.length > SCAN_WINDOW_CHARS;
|
|
const collapsed = value.slice(0, SCAN_WINDOW_CHARS).replace(/\s+/g, " ").trim();
|
|
if (!collapsed) return undefined;
|
|
if (collapsed.length <= MAX_SUMMARY_CHARS && !isPartial) return collapsed;
|
|
const kept = dropTrailingHighSurrogate(collapsed.slice(0, MAX_SUMMARY_CHARS - 1)).trimEnd();
|
|
return `${kept}…`;
|
|
}
|
|
|
|
function dropTrailingHighSurrogate(text: string): string {
|
|
const last = text.charCodeAt(text.length - 1);
|
|
return last >= 0xd800 && last <= 0xdbff ? text.slice(0, -1) : text;
|
|
}
|