Fix proxy debug trace truncation previews (#313)

This commit is contained in:
Cita
2026-03-29 15:08:37 +08:00
committed by GitHub
parent 7092e2f129
commit dcfd45ea65
4 changed files with 294 additions and 50 deletions
@@ -150,4 +150,37 @@ describe('proxyDebugTraceStore', () => {
downgradeDecision: true,
});
});
it('stores truncated debug payload previews as valid JSON text for json-capable databases', async () => {
const trace = await store.createProxyDebugTrace({
downstreamPath: '/v1/responses',
clientKind: 'codex',
requestedModel: 'gpt-5.4',
requestHeaders: {
authorization: `Bearer ${'x'.repeat(5000)}`,
'x-client': 'Codex Desktop',
},
requestBody: {
model: 'gpt-5.4',
input: [{ role: 'user', content: 'hello '.repeat(2000) }],
},
maxBodyBytes: 1024,
});
const detail = await store.getProxyDebugTraceDetail(trace.id);
const headersPayload = JSON.parse(detail?.trace.requestHeadersJson || 'null');
const bodyPayload = JSON.parse(detail?.trace.requestBodyJson || 'null');
expect(headersPayload).toMatchObject({
__metapiTruncated: true,
});
expect(typeof headersPayload.preview).toBe('string');
expect(headersPayload.preview).toContain('authorization');
expect(bodyPayload).toMatchObject({
__metapiTruncated: true,
});
expect(typeof bodyPayload.preview).toBe('string');
expect(bodyPayload.preview).toContain('"model": "gpt-5.4"');
});
});
+19 -2
View File
@@ -25,6 +25,24 @@ export type ProxyDebugTraceSession = {
let lastPruneAtMs = 0;
const PRUNE_INTERVAL_MS = 5 * 60 * 1000;
type TruncatedDebugPreview = {
__metapiTruncated: true;
preview: string;
originalBytes: number;
storedBytes: number;
};
function buildTruncatedDebugPreview(text: string, maxBytes: number, originalBytes: number): string {
const truncated = Buffer.from(text, 'utf8').subarray(0, Math.max(0, maxBytes)).toString('utf8');
const payload: TruncatedDebugPreview = {
__metapiTruncated: true,
preview: truncated,
originalBytes,
storedBytes: maxBytes,
};
return JSON.stringify(payload, null, 2);
}
function stringifyDebugValue(value: unknown, maxBytes: number): string | null {
if (value == null) return null;
@@ -45,8 +63,7 @@ function stringifyDebugValue(value: unknown, maxBytes: number): string | null {
return text;
}
const truncated = buffer.subarray(0, Math.max(0, maxBytes)).toString('utf8');
return `${truncated}\n...[truncated ${buffer.length - maxBytes} bytes]`;
return buildTruncatedDebugPreview(text, maxBytes, buffer.length);
}
function normalizeHeadersValue(value: HeadersLike): Record<string, unknown> | null {