mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 11:13:43 +08:00
fix(chat): preserve large ids in JSON detail viewer
This commit is contained in:
parent
7a34f3a502
commit
04a61fda19
@ -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 || '') }
|
||||
|
||||
@ -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')
|
||||
})
|
||||
})
|
||||
53
mateclaw-ui/src/components/chat/jsonViewFormat.ts
Normal file
53
mateclaw-ui/src/components/chat/jsonViewFormat.ts
Normal 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
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user