diff --git a/scripts/src/hwlab-node-web-observe-runner-source.ts b/scripts/src/hwlab-node-web-observe-runner-source.ts index dd3df423..9cad5419 100644 --- a/scripts/src/hwlab-node-web-observe-runner-source.ts +++ b/scripts/src/hwlab-node-web-observe-runner-source.ts @@ -527,13 +527,44 @@ async function sendPrompt(text) { if (chatStatus < 200 || chatStatus >= 300) { throw new Error("sendPrompt observed POST /v1/agent/chat HTTP " + chatStatus + " " + chatResponse.statusText()); } + let chatPayload = null; + let chatPayloadError = null; + try { + chatPayload = await chatResponse.json(); + } catch (error) { + chatPayloadError = errorSummary(error); + } let chatUrlPath = "/v1/agent/chat"; try { chatUrlPath = new URL(chatResponse.url()).pathname; } catch { chatUrlPath = "/v1/agent/chat"; } - return { beforeUrl, afterUrl: currentPageUrl(), textHash: sha256Text(text), textBytes: Buffer.byteLength(text), chatSubmit: { status: chatStatus, statusText: chatResponse.statusText(), urlPath: chatUrlPath }, pageId }; + const payloadText = chatPayload ? JSON.stringify(chatPayload) : ""; + const traceId = firstTraceId([payloadText]); + const otelTraceId = typeof chatPayload?.otelTrace?.traceId === "string" && /^[0-9a-f]{32}$/u.test(chatPayload.otelTrace.traceId) + ? chatPayload.otelTrace.traceId + : null; + return { + beforeUrl, + afterUrl: currentPageUrl(), + textHash: sha256Text(text), + textBytes: Buffer.byteLength(text), + chatSubmit: { + status: chatStatus, + statusText: chatResponse.statusText(), + urlPath: chatUrlPath, + traceId, + otelTraceId, + resultUrl: safeUrlPath(chatPayload?.resultUrl), + turnUrl: safeUrlPath(chatPayload?.turnUrl), + streamUrl: safeUrlPath(chatPayload?.streamUrl), + responseParsed: chatPayload !== null, + responseParseError: chatPayloadError, + valuesRedacted: true + }, + pageId + }; } async function waitForPromptSideEffect(beforeEvidence, timeoutMs) {