diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index d57df01d..ca10fbde 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -12,6 +12,7 @@ - Fixed HTML export losing indentation in ANSI-rendered tool output (e.g. JSON code blocks in custom tool results) ([#1269](https://github.com/badlogic/pi-mono/pull/1269) by [@aliou](https://github.com/aliou)) - Fixed images being silently dropped when `prompt()` is called with both `images` and `streamingBehavior` during streaming. `steer()`, `followUp()`, and the corresponding RPC commands now accept optional images. ([#1271](https://github.com/badlogic/pi-mono/pull/1271) by [@aliou](https://github.com/aliou)) - CLI `--help`, `--version`, `--list-models`, and `--export` now exit even if extensions keep the event loop alive ([#1285](https://github.com/badlogic/pi-mono/pull/1285) by [@ferologics](https://github.com/ferologics)) +- Fixed crash when models send malformed tool arguments (objects instead of strings) ([#1259](https://github.com/badlogic/pi-mono/issues/1259)) ## [0.51.6] - 2026-02-04 diff --git a/packages/coding-agent/src/core/export-html/template.css b/packages/coding-agent/src/core/export-html/template.css index bbf8e326..fbcec72a 100644 --- a/packages/coding-agent/src/core/export-html/template.css +++ b/packages/coding-agent/src/core/export-html/template.css @@ -693,6 +693,9 @@ color: var(--error); padding: 0 var(--line-height); } + .tool-error { + color: var(--error); + } /* Images */ .message-images { diff --git a/packages/coding-agent/src/core/export-html/template.js b/packages/coding-agent/src/core/export-html/template.js index 7d5edae0..551e34f5 100644 --- a/packages/coding-agent/src/core/export-html/template.js +++ b/packages/coding-agent/src/core/export-html/template.js @@ -540,6 +540,7 @@ // ============================================================ function shortenPath(p) { + if (typeof p !== 'string') return ''; if (p.startsWith('/Users/')) { const parts = p.split('/'); if (parts.length > 2) return '~' + p.slice(('/Users/' + parts[2]).length); @@ -771,6 +772,13 @@ return text.replace(/\t/g, ' '); } + /** Safely coerce value to string for display. Returns null if invalid type. */ + function str(value) { + if (typeof value === 'string') return value; + if (value == null) return ''; + return null; + } + function getLanguageFromPath(filePath) { const ext = filePath.split('.').pop()?.toLowerCase(); const extToLang = { @@ -880,10 +888,13 @@ const args = call.arguments || {}; const name = call.name; + const invalidArg = '[invalid arg]'; + switch (name) { case 'bash': { - const command = args.command || ''; - html += `