mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 21:07:01 -06:00
fix: trust semantic diagnostic progress
This commit is contained in:
@@ -3,6 +3,7 @@ import { importFreshModule } from "openclaw/plugin-sdk/test-fixtures";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { hasInternalDiagnosticEventListeners } from "../infra/diagnostic-event-listener-presence.js";
|
||||
import {
|
||||
emitDiagnosticEvent,
|
||||
emitTrustedDiagnosticEvent,
|
||||
resetDiagnosticEventsForTest,
|
||||
waitForDiagnosticEventsDrained,
|
||||
@@ -630,6 +631,51 @@ describe("repeated request liveness", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps active-owner evidence across untrusted semantic progress", async () => {
|
||||
const ref = { sessionId: "untrusted-session", sessionKey: "agent:main:untrusted" };
|
||||
const runId = "untrusted-run";
|
||||
|
||||
startDiagnosticRunActivityTracking();
|
||||
markDiagnosticEmbeddedRunStarted({ ...ref, runId });
|
||||
for (let attempt = 0; attempt < 2; attempt += 1) {
|
||||
markDiagnosticModelStartedForTest({
|
||||
...ref,
|
||||
runId,
|
||||
provider: "mock",
|
||||
model: "request-model",
|
||||
observationUnit: "request",
|
||||
});
|
||||
}
|
||||
|
||||
emitDiagnosticEvent({
|
||||
type: "run.progress",
|
||||
...ref,
|
||||
runId,
|
||||
reason: "plugin:semantic",
|
||||
progressKind: "semantic",
|
||||
});
|
||||
await waitForDiagnosticEventsDrained();
|
||||
|
||||
expect(getDiagnosticSessionActivitySnapshot(ref)).toMatchObject({
|
||||
lastProgressReason: "plugin:semantic",
|
||||
repeatedRequestNoProgressAgeMs: expect.any(Number),
|
||||
});
|
||||
|
||||
emitTrustedDiagnosticEvent({
|
||||
type: "run.progress",
|
||||
...ref,
|
||||
runId,
|
||||
reason: "model_result:semantic",
|
||||
progressKind: "semantic",
|
||||
});
|
||||
await waitForDiagnosticEventsDrained();
|
||||
|
||||
expect(getDiagnosticSessionActivitySnapshot(ref)).toMatchObject({
|
||||
lastProgressReason: "model_result:semantic",
|
||||
repeatedRequestNoProgressAgeMs: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it("requires an owned semantic event across merged session aliases", () => {
|
||||
vi.useFakeTimers();
|
||||
const startedAt = Date.parse("2026-08-04T02:00:00Z");
|
||||
|
||||
@@ -324,8 +324,8 @@ function recordModelEnded(
|
||||
touchSessionActivity(activity, "model_call:ended");
|
||||
}
|
||||
|
||||
function recordRunProgress(event: DiagnosticRunProgressActivityEvent): void {
|
||||
markDiagnosticRunProgress(event);
|
||||
function recordRunProgress(event: DiagnosticRunProgressActivityEvent, trusted: boolean): void {
|
||||
markDiagnosticRunProgress(trusted ? event : { ...event, progressKind: "liveness" });
|
||||
}
|
||||
|
||||
export function markDiagnosticArgumentChurnObservation(
|
||||
@@ -733,7 +733,7 @@ export function startDiagnosticRunActivityTracking(): void {
|
||||
return;
|
||||
}
|
||||
const startAfterEventSequence = getInternalDiagnosticEventSequence();
|
||||
unregisterDiagnosticRunActivityListener = onInternalDiagnosticEvent((event) => {
|
||||
unregisterDiagnosticRunActivityListener = onInternalDiagnosticEvent((event, metadata) => {
|
||||
// A prior lifecycle can leave already-sequenced events in the async queue.
|
||||
// Ignore them so a restart cannot recreate activity that stop cleared.
|
||||
if (event.seq <= startAfterEventSequence) {
|
||||
@@ -756,7 +756,7 @@ export function startDiagnosticRunActivityTracking(): void {
|
||||
recordModelEnded(event);
|
||||
return;
|
||||
case "run.progress":
|
||||
recordRunProgress(event);
|
||||
recordRunProgress(event, metadata.trusted);
|
||||
return;
|
||||
case "run.completed":
|
||||
recordRunCompleted(event);
|
||||
|
||||
Reference in New Issue
Block a user