mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-16 23:20:43 +00:00
* test: add pi codex runtime contract coverage * test: expand pi codex tool runtime contracts * test: tighten tool runtime contracts * test: reset tool contract param cache * test: document codex tool middleware fixture * test: type pi tool contract events * test: satisfy pi tool contract test types * test: cover tool media telemetry contracts * test: reset plugin runtime after tool contracts * test: add auth profile runtime contracts * test: strengthen auth profile runtime contracts * test: clarify auth profile contract fixtures * test: expand auth profile contract matrix * test: assert unrelated cli auth isolation * test: expand auth profile contract matrix * test: tighten auth profile contract expectations * test: add outcome fallback runtime contracts * test: strengthen outcome fallback contracts * test: isolate outcome fallback contracts * test: cover codex terminal outcome signals * test: expand terminal fallback contracts * test: add delivery no reply runtime contracts * test: document json no-reply delivery gap * test: align delivery contract fixtures * test: add transcript repair runtime contracts * test: tighten transcript repair contracts * test: add prompt overlay runtime contracts * test: tighten prompt overlay contract scope * test: type prompt overlay contracts * test: add schema normalization runtime contracts * test: clarify schema normalization contract gaps * test: simplify schema normalization contracts * test: tighten schema normalization contract gaps * test: cover compaction schema contract * test: satisfy schema contract lint * test: add transport params runtime contracts * test: tighten transport params contract scope * test: isolate transport params contracts * test: lock exact transport defaults * feat: add agent runtime plan foundation * fix: preserve codex harness auth profiles * fix: route followup delivery through runtime plan * fix: normalize parameter-free openai tool schemas * fix: satisfy runtime plan type checks * fix: narrow followup delivery runtime planning * fix: apply codex app-server auth profiles * fix: classify codex terminal outcomes * fix: prevent harness auth leakage into unrelated cli providers * feat: expand agent runtime plan policy contract * fix: route pi runtime policy through runtime plan * fix: route codex runtime policy through runtime plan * fix: route fallback outcome classification through runtime plan * refactor: make runtime plan contracts topology-safe * fix: restore runtime plan test type coverage * fix: align runtime plan schema contract assertions * fix: stabilize incomplete turn runtime tests * fix: stabilize codex native web search test * fix: preserve codex auth profile secret refs * fix: keep runtime resolved refs canonical * fix: preserve permissive nested openai schemas * fix: accept Codex auth provider aliases * test: update media-only groups mock * fix: resolve runtime plan rebase checks * fix: resolve runtime plan rebase checks --------- Co-authored-by: Eva <eva@100yen.org> Co-authored-by: Peter Steinberger <steipete@gmail.com>
81 lines
2.9 KiB
TypeScript
81 lines
2.9 KiB
TypeScript
import fs from "node:fs/promises";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { SessionManager } from "@mariozechner/pi-coding-agent";
|
|
import type { EmbeddedRunAttemptParams } from "openclaw/plugin-sdk/agent-harness";
|
|
import { afterEach, describe, expect, it } from "vitest";
|
|
import { isSilentReplyPayloadText } from "../../../../src/auto-reply/tokens.js";
|
|
import { DELIVERY_NO_REPLY_RUNTIME_CONTRACT } from "../../../../test/helpers/agents/delivery-no-reply-runtime-contract.js";
|
|
import { CodexAppServerEventProjector } from "./event-projector.js";
|
|
import { createCodexTestModel } from "./test-support.js";
|
|
|
|
const THREAD_ID = "thread-delivery-contract";
|
|
const TURN_ID = "turn-delivery-contract";
|
|
const tempDirs = new Set<string>();
|
|
|
|
type ProjectorNotification = Parameters<CodexAppServerEventProjector["handleNotification"]>[0];
|
|
|
|
async function createParams(): Promise<EmbeddedRunAttemptParams> {
|
|
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-codex-delivery-contract-"));
|
|
tempDirs.add(tempDir);
|
|
const sessionFile = path.join(tempDir, "session.jsonl");
|
|
SessionManager.open(sessionFile);
|
|
return {
|
|
prompt: DELIVERY_NO_REPLY_RUNTIME_CONTRACT.prompt,
|
|
sessionId: DELIVERY_NO_REPLY_RUNTIME_CONTRACT.sessionId,
|
|
sessionKey: DELIVERY_NO_REPLY_RUNTIME_CONTRACT.sessionKey,
|
|
sessionFile,
|
|
workspaceDir: tempDir,
|
|
runId: DELIVERY_NO_REPLY_RUNTIME_CONTRACT.runId,
|
|
provider: "codex",
|
|
modelId: "gpt-5.4-codex",
|
|
model: createCodexTestModel("codex"),
|
|
thinkLevel: "medium",
|
|
} as EmbeddedRunAttemptParams;
|
|
}
|
|
|
|
function forCurrentTurn(
|
|
method: ProjectorNotification["method"],
|
|
params: Record<string, unknown>,
|
|
): ProjectorNotification {
|
|
return {
|
|
method,
|
|
params: { threadId: THREAD_ID, turnId: TURN_ID, ...params },
|
|
} as ProjectorNotification;
|
|
}
|
|
|
|
afterEach(async () => {
|
|
for (const tempDir of tempDirs) {
|
|
await fs.rm(tempDir, { recursive: true, force: true });
|
|
}
|
|
tempDirs.clear();
|
|
});
|
|
|
|
describe("Delivery/NO_REPLY runtime contract - Codex app-server adapter", () => {
|
|
it.each([
|
|
DELIVERY_NO_REPLY_RUNTIME_CONTRACT.silentText,
|
|
` ${DELIVERY_NO_REPLY_RUNTIME_CONTRACT.silentText} `,
|
|
DELIVERY_NO_REPLY_RUNTIME_CONTRACT.jsonSilentText,
|
|
])("preserves silent terminal text %s for shared delivery suppression", async (text) => {
|
|
const projector = new CodexAppServerEventProjector(await createParams(), THREAD_ID, TURN_ID);
|
|
await projector.handleNotification(
|
|
forCurrentTurn("item/agentMessage/delta", {
|
|
itemId: "msg-1",
|
|
delta: text,
|
|
}),
|
|
);
|
|
|
|
const result = projector.buildResult({
|
|
didSendViaMessagingTool: false,
|
|
messagingToolSentTexts: [],
|
|
messagingToolSentMediaUrls: [],
|
|
messagingToolSentTargets: [],
|
|
toolMediaUrls: [],
|
|
toolAudioAsVoice: false,
|
|
});
|
|
|
|
expect(result.assistantTexts).toEqual([text.trim()]);
|
|
expect(isSilentReplyPayloadText(result.assistantTexts[0])).toBe(true);
|
|
});
|
|
});
|