From a4a7e4c7f299e8aad88bfee4b70ec05f2e96310b Mon Sep 17 00:00:00 2001 From: Lukin Date: Mon, 6 Jul 2026 20:18:30 +0800 Subject: [PATCH] fix(admin): lazy-load request payloads Co-Authored-By: Codex --- apps/admin/src/lib/api/requests.ts | 44 ++++ .../routes/requests/[traceId]/+page.svelte | 234 +++++++++++++++--- .../src/routes/requests/[traceId]/+page.ts | 21 +- .../src/routes/requests/requests.test.ts | 42 +++- apps/gateway/src/routes/admin/admin.test.ts | 49 ++++ apps/gateway/src/routes/admin/memory.test.ts | 21 +- apps/gateway/src/routes/admin/memory.ts | 52 +++- apps/gateway/src/routes/admin/requests.ts | 87 ++++++- implementation-notes.md | 9 + package.json | 2 +- packages/core/src/index.ts | 5 + .../core/src/memory/forgetting/facts.test.ts | 2 +- packages/core/src/store/ports.ts | 27 ++ packages/core/src/store/postgres/telemetry.ts | 58 +++++ packages/core/src/store/sqlite/telemetry.ts | 60 +++++ .../core/src/store/store-contract.test.ts | 11 + 16 files changed, 670 insertions(+), 54 deletions(-) diff --git a/apps/admin/src/lib/api/requests.ts b/apps/admin/src/lib/api/requests.ts index 8fd4fd22..d3b830e6 100644 --- a/apps/admin/src/lib/api/requests.ts +++ b/apps/admin/src/lib/api/requests.ts @@ -716,6 +716,20 @@ export interface RequestPayloadView { // is what the client sent). Null/absent when no provider served or pre-feature. upstream_request?: unknown; created_at?: number; + parts?: { + request: boolean; + response: boolean; + upstream_request: boolean; + }; +} + +export type RequestPayloadPartName = 'request' | 'response' | 'upstream_request'; + +export interface RequestPayloadPartView { + captured: boolean; + part?: RequestPayloadPartName; + value?: unknown; + created_at?: number; } // GET /admin/api/requests/:traceId/payload -> the captured bodies. Resolves to @@ -733,6 +747,36 @@ export async function getRequestPayload(traceId: string): Promise { + try { + const res = await fetch(`${BASE}/${encodeURIComponent(traceId)}/payload?part=meta`, { + headers: { accept: 'application/json' }, + }); + if (!res.ok) return { captured: false }; + return (await res.json()) as RequestPayloadView; + } catch { + return { captured: false }; + } +} + +export async function getRequestPayloadPart( + traceId: string, + part: RequestPayloadPartName, +): Promise { + try { + const res = await fetch( + `${BASE}/${encodeURIComponent(traceId)}/payload?part=${encodeURIComponent(part)}`, + { + headers: { accept: 'application/json' }, + }, + ); + if (!res.ok) return { captured: false }; + return (await res.json()) as RequestPayloadPartView; + } catch { + return { captured: false }; + } +} + // POST /admin/api/requests/:traceId/replay -> { trace_id } | throws. Re-issues the // (optionally edited) request body through the gateway as an ISOLATED debug re-run // and returns the NEW trace id so the page can navigate to the recorded result. diff --git a/apps/admin/src/routes/requests/[traceId]/+page.svelte b/apps/admin/src/routes/requests/[traceId]/+page.svelte index c6607693..b6af3d28 100644 --- a/apps/admin/src/routes/requests/[traceId]/+page.svelte +++ b/apps/admin/src/routes/requests/[traceId]/+page.svelte @@ -1,7 +1,12 @@