mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 04:47:03 -06:00
fix(transcripts): mark delivery mirrors as artifacts (#99855)
* fix(transcripts): mark delivery mirrors as artifacts * fix(transcripts): mark delivery mirrors as artifacts * fix(transcripts): mark delivery mirrors as artifacts
This commit is contained in:
@@ -7,6 +7,7 @@ import type {
|
||||
Usage,
|
||||
} from "openclaw/plugin-sdk/llm";
|
||||
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { OPENCLAW_TRANSCRIPT_ARTIFACT_API } from "../shared/transcript-only-openclaw-assistant.js";
|
||||
import {
|
||||
expectOpenAIResponsesStrictSanitizeCall,
|
||||
loadSanitizeSessionHistoryWithCleanMocks,
|
||||
@@ -887,7 +888,7 @@ describe("sanitizeSessionHistory", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("repairs a message-tool delivery-mirror poisoned OpenAI Responses replay", async () => {
|
||||
it("repairs a message-tool delivery-mirror poisoned replay", async () => {
|
||||
const messages: AgentMessage[] = [
|
||||
makeUserMessage("start"),
|
||||
makeAssistantMessage(
|
||||
@@ -905,7 +906,7 @@ describe("sanitizeSessionHistory", () => {
|
||||
role: "assistant",
|
||||
provider: "openclaw",
|
||||
model: "delivery-mirror",
|
||||
api: "openai-responses",
|
||||
api: OPENCLAW_TRANSCRIPT_ARTIFACT_API,
|
||||
content: [{ type: "text", text: "visible reply" }],
|
||||
stopReason: "stop",
|
||||
}),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Coverage for normalizing assistant replay content before provider requests.
|
||||
import type { AgentMessage } from "openclaw/plugin-sdk/agent-core";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { OPENCLAW_TRANSCRIPT_ARTIFACT_API } from "../../shared/transcript-only-openclaw-assistant.js";
|
||||
import {
|
||||
INTERNAL_RUNTIME_CONTEXT_BEGIN,
|
||||
INTERNAL_RUNTIME_CONTEXT_END,
|
||||
@@ -50,7 +51,7 @@ function openclawTranscriptAssistant(model: "delivery-mirror" | "gateway-injecte
|
||||
return {
|
||||
role: "assistant",
|
||||
content: [{ type: "text", text: "channel mirror" }],
|
||||
api: "openai-responses",
|
||||
api: OPENCLAW_TRANSCRIPT_ARTIFACT_API,
|
||||
provider: "openclaw",
|
||||
model,
|
||||
usage: {
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
withOwnedSessionTranscriptWrites,
|
||||
} from "../../../config/sessions/transcript-write-context.js";
|
||||
import { appendExactAssistantMessageToSessionTranscript } from "../../../config/sessions/transcript.js";
|
||||
import { OPENCLAW_TRANSCRIPT_ARTIFACT_API } from "../../../shared/transcript-only-openclaw-assistant.js";
|
||||
import { guardSessionManager } from "../../session-tool-result-guard-wrapper.js";
|
||||
import {
|
||||
SessionWriteLockStaleError,
|
||||
@@ -2602,7 +2603,7 @@ describe("embedded attempt session lock lifecycle", () => {
|
||||
message: {
|
||||
role: "assistant",
|
||||
content: [{ type: "text", text: "first-turn delivery" }],
|
||||
api: "openai-responses",
|
||||
api: OPENCLAW_TRANSCRIPT_ARTIFACT_API,
|
||||
provider: "openclaw",
|
||||
model: "delivery-mirror",
|
||||
usage: {
|
||||
|
||||
@@ -6,6 +6,7 @@ import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { OPENCLAW_TRANSCRIPT_ARTIFACT_API } from "../shared/transcript-only-openclaw-assistant.js";
|
||||
import { repairSessionFileIfNeeded } from "./session-file-repair.js";
|
||||
|
||||
const BLANK_USER_FALLBACK_TEXT = "(continue)";
|
||||
@@ -832,7 +833,7 @@ describe("repairSessionFileIfNeeded", () => {
|
||||
role: "assistant",
|
||||
provider: "openclaw",
|
||||
model: "delivery-mirror",
|
||||
api: "openai-responses",
|
||||
api: OPENCLAW_TRANSCRIPT_ARTIFACT_API,
|
||||
content: [{ type: "text", text: "Process: `wild-wharf`" }],
|
||||
stopReason: "stop",
|
||||
},
|
||||
@@ -892,7 +893,7 @@ describe("repairSessionFileIfNeeded", () => {
|
||||
role: "assistant",
|
||||
provider: "openclaw",
|
||||
model: "delivery-mirror",
|
||||
api: "openai-responses",
|
||||
api: OPENCLAW_TRANSCRIPT_ARTIFACT_API,
|
||||
content: [{ type: "text", text: "visible reply" }],
|
||||
stopReason: "stop",
|
||||
},
|
||||
|
||||
@@ -6,6 +6,7 @@ import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { repairToolUseResultPairing } from "../../agents/session-transcript-repair.js";
|
||||
import * as transcriptEvents from "../../sessions/transcript-events.js";
|
||||
import type { SessionTranscriptUpdate } from "../../sessions/transcript-events.js";
|
||||
import { OPENCLAW_TRANSCRIPT_ARTIFACT_API } from "../../shared/transcript-only-openclaw-assistant.js";
|
||||
import { deleteTestEnvValue, setTestEnvValue } from "../../test-utils/env.js";
|
||||
import { resolveSessionTranscriptPathInDir } from "./paths.js";
|
||||
import { updateSessionStoreEntry } from "./store.js";
|
||||
@@ -513,6 +514,7 @@ describe("appendAssistantMessageToSessionTranscript", () => {
|
||||
const message = event.message as
|
||||
| {
|
||||
role?: string;
|
||||
api?: string;
|
||||
provider?: string;
|
||||
model?: string;
|
||||
content?: unknown;
|
||||
@@ -522,6 +524,7 @@ describe("appendAssistantMessageToSessionTranscript", () => {
|
||||
expect(event?.sessionKey).toBe(sessionKey);
|
||||
expect(event?.messageId).toBeTypeOf("string");
|
||||
expect(message?.role).toBe("assistant");
|
||||
expect(message?.api).toBe(OPENCLAW_TRANSCRIPT_ARTIFACT_API);
|
||||
expect(message?.provider).toBe("openclaw");
|
||||
expect(message?.model).toBe("delivery-mirror");
|
||||
expect(message?.content).toEqual([{ type: "text", text: "Hello from delivery mirror!" }]);
|
||||
@@ -982,6 +985,7 @@ describe("appendAssistantMessageToSessionTranscript", () => {
|
||||
expect(lines.length).toBe(4);
|
||||
|
||||
const messageLine = JSON.parse(lines[3]);
|
||||
expect(messageLine.message.api).toBe(OPENCLAW_TRANSCRIPT_ARTIFACT_API);
|
||||
expect(messageLine.message.provider).toBe("openclaw");
|
||||
expect(messageLine.message.model).toBe("delivery-mirror");
|
||||
expect(messageLine.message.content[0].text).toBe("Repeated answer");
|
||||
@@ -1023,6 +1027,7 @@ describe("appendAssistantMessageToSessionTranscript", () => {
|
||||
const linesAfterMirror = fs.readFileSync(sessionFile, "utf-8").trim().split("\n");
|
||||
expect(linesAfterMirror).toHaveLength(3);
|
||||
const mirrorLine = JSON.parse(linesAfterMirror[2]);
|
||||
expect(mirrorLine.message.api).toBe(OPENCLAW_TRANSCRIPT_ARTIFACT_API);
|
||||
expect(mirrorLine.message.model).toBe("delivery-mirror");
|
||||
|
||||
await appendSessionTranscriptMessage({
|
||||
|
||||
@@ -9,7 +9,12 @@ import {
|
||||
extractAssistantVisibleText,
|
||||
extractFirstTextBlock,
|
||||
} from "../../shared/chat-message-content.js";
|
||||
import { isTranscriptOnlyOpenClawAssistantModel } from "../../shared/transcript-only-openclaw-assistant.js";
|
||||
import {
|
||||
OPENCLAW_DELIVERY_MIRROR_MODEL,
|
||||
OPENCLAW_TRANSCRIPT_ARTIFACT_API,
|
||||
OPENCLAW_TRANSCRIPT_ARTIFACT_PROVIDER,
|
||||
isTranscriptOnlyOpenClawAssistantModel,
|
||||
} from "../../shared/transcript-only-openclaw-assistant.js";
|
||||
import type { OpenClawConfig } from "../types.openclaw.js";
|
||||
import {
|
||||
resolveDefaultSessionStorePath,
|
||||
@@ -358,9 +363,9 @@ export async function appendAssistantMessageToSessionTranscript(params: {
|
||||
message: {
|
||||
role: "assistant" as const,
|
||||
content: [{ type: "text", text: mirrorText }],
|
||||
api: "openai-responses",
|
||||
provider: "openclaw",
|
||||
model: "delivery-mirror",
|
||||
api: OPENCLAW_TRANSCRIPT_ARTIFACT_API,
|
||||
provider: OPENCLAW_TRANSCRIPT_ARTIFACT_PROVIDER,
|
||||
model: OPENCLAW_DELIVERY_MIRROR_MODEL,
|
||||
usage: {
|
||||
input: 0,
|
||||
output: 0,
|
||||
@@ -548,7 +553,10 @@ export async function appendExactAssistantMessageToSessionTranscript(params: {
|
||||
}
|
||||
|
||||
function isRedundantDeliveryMirror(message: SessionTranscriptAssistantMessage): boolean {
|
||||
return message.provider === "openclaw" && message.model === "delivery-mirror";
|
||||
return (
|
||||
message.provider === OPENCLAW_TRANSCRIPT_ARTIFACT_PROVIDER &&
|
||||
message.model === OPENCLAW_DELIVERY_MIRROR_MODEL
|
||||
);
|
||||
}
|
||||
|
||||
function isChannelFinalDeliveryMirror(message: SessionTranscriptAssistantMessage): boolean {
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
emitInternalSessionTranscriptUpdate,
|
||||
emitSessionTranscriptUpdate,
|
||||
} from "../sessions/transcript-events.js";
|
||||
import { OPENCLAW_TRANSCRIPT_ARTIFACT_API } from "../shared/transcript-only-openclaw-assistant.js";
|
||||
import { testState } from "./test-helpers.runtime-state.js";
|
||||
import {
|
||||
connectReq,
|
||||
@@ -126,11 +127,14 @@ function makeTranscriptAssistantMessage(params: {
|
||||
function makeDeliveryMirrorAssistantMessage(
|
||||
params: Parameters<typeof makeTranscriptAssistantMessage>[0],
|
||||
): AssistantMessage {
|
||||
return makeTranscriptAssistantMessage({
|
||||
...params,
|
||||
provider: "openclaw",
|
||||
model: "delivery-mirror",
|
||||
});
|
||||
return {
|
||||
...makeTranscriptAssistantMessage({
|
||||
...params,
|
||||
provider: "openclaw",
|
||||
model: "delivery-mirror",
|
||||
}),
|
||||
api: OPENCLAW_TRANSCRIPT_ARTIFACT_API,
|
||||
};
|
||||
}
|
||||
|
||||
async function appendTranscriptMessage(params: {
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
// Identifies OpenClaw-authored assistant rows that are transcript bookkeeping,
|
||||
// not provider model output. Some history surfaces keep gateway-injected rows
|
||||
// visible, so use the narrower delivery-mirror predicate when visibility matters.
|
||||
export const OPENCLAW_TRANSCRIPT_ARTIFACT_API = "openclaw-transcript" as const;
|
||||
export const OPENCLAW_TRANSCRIPT_ARTIFACT_PROVIDER = "openclaw" as const;
|
||||
export const OPENCLAW_DELIVERY_MIRROR_MODEL = "delivery-mirror" as const;
|
||||
export const OPENCLAW_GATEWAY_INJECTED_MODEL = "gateway-injected" as const;
|
||||
|
||||
const TRANSCRIPT_ONLY_OPENCLAW_ASSISTANT_MODELS = new Set<string>([
|
||||
"delivery-mirror",
|
||||
"gateway-injected",
|
||||
OPENCLAW_DELIVERY_MIRROR_MODEL,
|
||||
OPENCLAW_GATEWAY_INJECTED_MODEL,
|
||||
]);
|
||||
|
||||
export function isTranscriptOnlyOpenClawAssistantModel(provider: unknown, model: unknown): boolean {
|
||||
return (
|
||||
provider === "openclaw" &&
|
||||
provider === OPENCLAW_TRANSCRIPT_ARTIFACT_PROVIDER &&
|
||||
typeof model === "string" &&
|
||||
TRANSCRIPT_ONLY_OPENCLAW_ASSISTANT_MODELS.has(model)
|
||||
);
|
||||
@@ -31,6 +36,8 @@ export function isOpenClawDeliveryMirrorAssistantMessage(message: unknown): bool
|
||||
}
|
||||
const entry = message as { role?: unknown; provider?: unknown; model?: unknown };
|
||||
return (
|
||||
entry.role === "assistant" && entry.provider === "openclaw" && entry.model === "delivery-mirror"
|
||||
entry.role === "assistant" &&
|
||||
entry.provider === OPENCLAW_TRANSCRIPT_ARTIFACT_PROVIDER &&
|
||||
entry.model === OPENCLAW_DELIVERY_MIRROR_MODEL
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user