Merge pull request #1005 from pikasTech/fix/issue1000-trace-refresh-latency
fix: reduce Code Agent trace refresh latency
This commit is contained in:
@@ -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 : [];
|
||||
|
||||
Reference in New Issue
Block a user