fix(chat): preserve large ids in JSON detail viewer

This commit is contained in:
matevip 2026-08-13 04:00:47 -04:00
parent 7a34f3a502
commit 04a61fda19
3 changed files with 68 additions and 1 deletions

View File

@ -1,5 +1,6 @@
<script setup lang="ts">
import { computed } from 'vue'
import { prettyPrintJsonForDisplay } from './jsonViewFormat'
/**
* Lightweight, dependency-free JSON viewer with syntax highlighting.
@ -40,7 +41,7 @@ const parsed = computed(() => {
const s = (props.raw || '').trim()
if (!s) return { empty: true, isJson: false, html: '' }
try {
const pretty = JSON.stringify(JSON.parse(s), null, 2)
const pretty = prettyPrintJsonForDisplay(s)
return { empty: false, isJson: true, html: highlight(pretty) }
} catch {
return { empty: false, isJson: false, html: escapeHtml(props.raw || '') }

View File

@ -0,0 +1,13 @@
import { describe, expect, it } from 'vitest'
import { prettyPrintJsonForDisplay } from '../jsonViewFormat'
describe('prettyPrintJsonForDisplay', () => {
it('preserves large integer text in tool arguments instead of rounding through JS Number', () => {
const raw = '{"agentId":2079862124134313986,"type":"reference"}'
const pretty = prettyPrintJsonForDisplay(raw)
expect(pretty).toContain('2079862124134313986')
expect(pretty).not.toContain('2079862124134314000')
})
})

View File

@ -0,0 +1,53 @@
export function prettyPrintJsonForDisplay(raw: string): string {
// Validate JSON, but do not use the parsed value for rendering: JSON.parse
// coerces 19-digit Snowflake IDs through JS Number and changes their text.
JSON.parse(raw)
return prettyPrintJsonLexically(raw)
}
function prettyPrintJsonLexically(raw: string): string {
let out = ''
let indent = 0
let inString = false
let escaped = false
const pad = () => ' '.repeat(indent)
for (let i = 0; i < raw.length; i++) {
const ch = raw[i]
if (inString) {
out += ch
if (escaped) {
escaped = false
} else if (ch === '\\') {
escaped = true
} else if (ch === '"') {
inString = false
}
continue
}
if (/\s/.test(ch)) continue
if (ch === '"') {
inString = true
out += ch
} else if (ch === '{' || ch === '[') {
out += ch
indent++
out += '\n' + pad()
} else if (ch === '}' || ch === ']') {
indent = Math.max(0, indent - 1)
out = out.replace(/[ \t]*$/, '')
out += '\n' + pad() + ch
} else if (ch === ',') {
out += ch + '\n' + pad()
} else if (ch === ':') {
out += ': '
} else {
out += ch
}
}
return out
}