Merge pull request #1005 from pikasTech/fix/issue1000-trace-refresh-latency

fix: reduce Code Agent trace refresh latency
This commit is contained in:
Lyon
2026-06-06 16:56:05 +08:00
committed by GitHub
5 changed files with 184 additions and 21 deletions
@@ -389,6 +389,71 @@ test("subscribeToTrace merges terminal result without text with trace assistant
}
});
test("subscribeToTrace starts result and trace polls in the same refresh tick (#1000)", async () => {
const originalFetch = globalThis.fetch;
const originalSetTimeout = globalThis.window?.setTimeout;
const originalClearTimeout = globalThis.window?.clearTimeout;
const fetches: string[] = [];
let traceStartedBeforeResultResolved = false;
let resolveResult: (() => void) | null = null;
const resultGate = new Promise<void>((resolve) => { resolveResult = resolve; });
globalThis.window = {
...(globalThis.window ?? {}),
setTimeout: ((callback: () => void) => { callback(); return 1; }) as typeof window.setTimeout,
clearTimeout: (() => undefined) as typeof window.clearTimeout
} as typeof window;
globalThis.fetch = (async (input: RequestInfo | URL) => {
const url = String(input);
fetches.push(url);
if (url.includes("/result/")) {
await resultGate;
return jsonResponse({ status: "completed", traceId: "trc_issue1000_parallel", assistantText: "最终回复" });
}
if (url.includes("/trace/")) {
traceStartedBeforeResultResolved = true;
resolveResult?.();
return jsonResponse({
status: "running",
traceId: "trc_issue1000_parallel",
events: [{ seq: 1, label: "agentrun:assistant:message", type: "assistant", status: "running", message: "trace 已更新" }],
eventCount: 1
});
}
return jsonResponse({});
}) as typeof fetch;
try {
const snapshots: TraceSnapshot[] = [];
const completed = await new Promise<AgentChatResultResponse>((resolve, reject) => {
void subscribeToTrace({
traceId: "trc_issue1000_parallel",
initial: { status: "running", traceId: "trc_issue1000_parallel", resultUrl: "/v1/agent/chat/result/trc_issue1000_parallel" },
onActivity: () => undefined,
onSnapshot: (snapshot) => snapshots.push(snapshot),
onComplete: resolve,
onInfrastructureError: (error) => reject(new Error(error)),
signal: new AbortController().signal,
inactivityTimeoutMs: 1000
}).catch(reject);
});
assert.equal(traceStartedBeforeResultResolved, true);
assert.equal(snapshots.length, 1);
assert.equal(snapshots[0].eventCount, 1);
assert.equal(completed.assistantText, "最终回复");
assert.deepEqual(fetches, [
"/v1/agent/chat/result/trc_issue1000_parallel",
"/v1/agent/chat/trace/trc_issue1000_parallel?projectId=prj_hwpod_workbench"
]);
} finally {
resolveResult?.();
globalThis.fetch = originalFetch;
if (globalThis.window) {
globalThis.window.setTimeout = originalSetTimeout ?? globalThis.window.setTimeout;
globalThis.window.clearTimeout = originalClearTimeout ?? globalThis.window.clearTimeout;
}
}
});
test("replayFullTrace retries transient trace API failures before returning an empty replay", async () => {
const originalFetch = globalThis.fetch;
const originalSetTimeout = globalThis.window?.setTimeout;
@@ -305,8 +305,10 @@ export async function subscribeToTrace(config: TraceSubscriptionConfig): Promise
await new Promise<void>((resolve) => window.setTimeout(resolve, TRACE_POLL_INTERVAL_MS));
if (signal.aborted) return;
// Step 1: poll the result endpoint for terminal status.
const resultPolled = await api.getAgentChatResult(resultUrl, inactivityTimeoutMs, null);
const [resultPolled, tracePolled] = await Promise.all([
api.getAgentChatResult(resultUrl, inactivityTimeoutMs, null),
api.getAgentChatResult(traceUrl, inactivityTimeoutMs, null)
]);
if (signal.aborted) return;
if (resultPolled.ok && resultPolled.data) {
@@ -330,11 +332,6 @@ export async function subscribeToTrace(config: TraceSubscriptionConfig): Promise
return;
}
// Step 2: poll the trace endpoint for live events.
if (signal.aborted) return;
const tracePolled = await api.getAgentChatResult(traceUrl, inactivityTimeoutMs, null);
if (signal.aborted) return;
if (tracePolled.ok && tracePolled.data) {
onActivity();
const events = Array.isArray(tracePolled.data.events) ? tracePolled.data.events : [];