mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-08-28 08:35:57 +00:00
feat: vendor and persist Codex fast mode
This commit is contained in:
@@ -0,0 +1,299 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { chmodSync, mkdtempSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import test from "node:test";
|
||||
import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
||||
import codexFastModeExtension, {
|
||||
FAST_MODE_SERVICE_TIER,
|
||||
FAST_MODE_STATE_ENTRY_TYPE,
|
||||
FAST_MODE_STATUS_KEY,
|
||||
fastModeArgumentCompletions,
|
||||
getFastModeConfigPath,
|
||||
isFastModeEligibleModel,
|
||||
isPlainObject,
|
||||
loadGlobalFastModeState,
|
||||
parseFastModeCommand,
|
||||
reconstructFastModeState,
|
||||
saveGlobalFastModeState,
|
||||
transformFastModeRequest,
|
||||
type FastModeState,
|
||||
} from "../index.ts";
|
||||
|
||||
type StatusUpdate = { key: string; value: string | undefined };
|
||||
type Notification = { message: string; level: string };
|
||||
type Handler = (event: any, ctx: any) => unknown;
|
||||
|
||||
function createHarness(options: {
|
||||
entries?: unknown[];
|
||||
busy?: boolean;
|
||||
pending?: boolean;
|
||||
globalEnabled?: boolean;
|
||||
saveError?: string;
|
||||
} = {}) {
|
||||
const handlers = new Map<string, Handler>();
|
||||
const commands = new Map<string, any>();
|
||||
const entries = options.entries ?? [];
|
||||
const statusUpdates: StatusUpdate[] = [];
|
||||
const notifications: Notification[] = [];
|
||||
const appendCalls: Array<{ customType: string; data: unknown }> = [];
|
||||
const loadCalls: string[] = [];
|
||||
const saveCalls: Array<{ path: string; state: FastModeState }> = [];
|
||||
let busy = options.busy ?? false;
|
||||
let pending = options.pending ?? false;
|
||||
let globalEnabled = options.globalEnabled ?? false;
|
||||
|
||||
const context = {
|
||||
model: { provider: "openai-codex", api: "openai-codex-responses" },
|
||||
sessionManager: { getBranch: () => entries },
|
||||
isIdle: () => !busy,
|
||||
hasPendingMessages: () => pending,
|
||||
ui: {
|
||||
setStatus(key: string, value: string | undefined) {
|
||||
statusUpdates.push({ key, value });
|
||||
},
|
||||
notify(message: string, level: string) {
|
||||
notifications.push({ message, level });
|
||||
},
|
||||
},
|
||||
} as unknown as ExtensionCommandContext;
|
||||
|
||||
codexFastModeExtension({
|
||||
on(event: string, handler: Handler) {
|
||||
handlers.set(event, handler);
|
||||
},
|
||||
registerCommand(name: string, command: unknown) {
|
||||
commands.set(name, command);
|
||||
},
|
||||
appendEntry(customType: string, data: unknown) {
|
||||
appendCalls.push({ customType, data });
|
||||
entries.push({ type: "custom", customType, data });
|
||||
},
|
||||
} as unknown as ExtensionAPI, {
|
||||
configPath: "/test-agent/extensions/pi-extension-codex-fast-mode/config.json",
|
||||
loadGlobalState(path) {
|
||||
loadCalls.push(path);
|
||||
return { state: { enabled: globalEnabled } };
|
||||
},
|
||||
saveGlobalState(path, state) {
|
||||
saveCalls.push({ path, state });
|
||||
if (options.saveError) return { success: false, error: options.saveError };
|
||||
globalEnabled = state.enabled;
|
||||
return { success: true };
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
appendCalls,
|
||||
commands,
|
||||
context,
|
||||
entries,
|
||||
handlers,
|
||||
loadCalls,
|
||||
notifications,
|
||||
saveCalls,
|
||||
setBusy(value: boolean) { busy = value; },
|
||||
setPending(value: boolean) { pending = value; },
|
||||
statusUpdates,
|
||||
};
|
||||
}
|
||||
|
||||
test("plain-object guard excludes malformed payloads", () => {
|
||||
assert.equal(isPlainObject({}), true);
|
||||
assert.equal(isPlainObject(Object.create(null)), true);
|
||||
assert.equal(isPlainObject([]), false);
|
||||
assert.equal(isPlainObject(new Date()), false);
|
||||
assert.equal(isPlainObject(null), false);
|
||||
assert.equal(isPlainObject("payload"), false);
|
||||
});
|
||||
|
||||
test("provider eligibility is exact", () => {
|
||||
assert.equal(isFastModeEligibleModel({ provider: "openai-codex", api: "openai-codex-responses" }), true);
|
||||
assert.equal(isFastModeEligibleModel({ provider: "openai", api: "openai-codex-responses" }), false);
|
||||
assert.equal(isFastModeEligibleModel({ provider: "openai-codex", api: "openai-responses" }), false);
|
||||
assert.equal(isFastModeEligibleModel(undefined), false);
|
||||
});
|
||||
|
||||
test("request transformer is isolated, non-mutating, and overwrites only service_tier", () => {
|
||||
const payload = { model: "gpt-5.6-codex", service_tier: "default", nested: { preserved: true } };
|
||||
const transformed = transformFastModeRequest(true, { provider: "openai-codex", api: "openai-codex-responses" }, payload);
|
||||
|
||||
assert.deepEqual(transformed, {
|
||||
model: "gpt-5.6-codex",
|
||||
service_tier: FAST_MODE_SERVICE_TIER,
|
||||
nested: { preserved: true },
|
||||
});
|
||||
assert.notStrictEqual(transformed, payload);
|
||||
assert.strictEqual(transformed?.nested, payload.nested);
|
||||
assert.equal(payload.service_tier, "default");
|
||||
assert.equal(transformFastModeRequest(false, { provider: "openai-codex", api: "openai-codex-responses" }, payload), undefined);
|
||||
assert.equal(transformFastModeRequest(true, { provider: "openai", api: "openai-codex-responses" }, payload), undefined);
|
||||
assert.equal(transformFastModeRequest(true, { provider: "openai-codex", api: "openai-codex-responses" }, []), undefined);
|
||||
});
|
||||
|
||||
test("branch reconstruction prefers the latest valid snapshot over the global default", () => {
|
||||
assert.deepEqual(reconstructFastModeState([], true), { enabled: true });
|
||||
assert.deepEqual(reconstructFastModeState([
|
||||
{ type: "custom", customType: FAST_MODE_STATE_ENTRY_TYPE, data: { enabled: true } },
|
||||
{ type: "custom", customType: "other", data: { enabled: false } },
|
||||
{ type: "custom", customType: FAST_MODE_STATE_ENTRY_TYPE, data: { enabled: "invalid" } },
|
||||
{ type: "custom", customType: FAST_MODE_STATE_ENTRY_TYPE, data: { enabled: false } },
|
||||
], true), { enabled: false });
|
||||
});
|
||||
|
||||
test("global config round-trips atomically with owner-only permissions", () => {
|
||||
const agentDir = mkdtempSync(join(tmpdir(), "fast-mode-test-"));
|
||||
const configPath = getFastModeConfigPath(agentDir);
|
||||
try {
|
||||
assert.deepEqual(loadGlobalFastModeState(configPath), { state: { enabled: false } });
|
||||
assert.deepEqual(saveGlobalFastModeState(configPath, { enabled: true }), { success: true });
|
||||
assert.deepEqual(loadGlobalFastModeState(configPath), { state: { enabled: true } });
|
||||
assert.deepEqual(JSON.parse(readFileSync(configPath, "utf8")), { enabled: true });
|
||||
assert.equal(statSync(configPath).mode & 0o777, 0o600);
|
||||
assert.equal(statSync(join(agentDir, "extensions", "pi-extension-codex-fast-mode")).mode & 0o777, 0o700);
|
||||
} finally {
|
||||
rmSync(agentDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("invalid or unreadable global config fails safely to off", () => {
|
||||
const directory = mkdtempSync(join(tmpdir(), "fast-mode-invalid-"));
|
||||
const configPath = join(directory, "config.json");
|
||||
try {
|
||||
writeFileSync(configPath, "{ not-json", "utf8");
|
||||
const invalid = loadGlobalFastModeState(configPath);
|
||||
assert.deepEqual(invalid.state, { enabled: false });
|
||||
assert.match(invalid.warning ?? "", /Could not read/u);
|
||||
|
||||
writeFileSync(configPath, JSON.stringify({ enabled: "yes" }), "utf8");
|
||||
const wrongType = loadGlobalFastModeState(configPath);
|
||||
assert.deepEqual(wrongType.state, { enabled: false });
|
||||
assert.match(wrongType.warning ?? "", /expected/u);
|
||||
|
||||
chmodSync(configPath, 0o600);
|
||||
} finally {
|
||||
rmSync(directory, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("command grammar and completions are deterministic", () => {
|
||||
assert.equal(parseFastModeCommand(""), "toggle");
|
||||
assert.equal(parseFastModeCommand(" ON "), "on");
|
||||
assert.equal(parseFastModeCommand("off"), "off");
|
||||
assert.equal(parseFastModeCommand("status"), "status");
|
||||
assert.equal(parseFastModeCommand("on now"), "invalid");
|
||||
assert.deepEqual(fastModeArgumentCompletions("o"), [
|
||||
{ value: "on", label: "on" },
|
||||
{ value: "off", label: "off" },
|
||||
]);
|
||||
assert.deepEqual(fastModeArgumentCompletions("status"), [{ value: "status", label: "status" }]);
|
||||
});
|
||||
|
||||
test("a new session inherits the global default while a branch snapshot takes precedence", () => {
|
||||
const inherited = createHarness({ globalEnabled: true });
|
||||
const inheritedStart = inherited.handlers.get("session_start");
|
||||
assert.ok(inheritedStart);
|
||||
inheritedStart!({}, inherited.context as unknown as ExtensionContext);
|
||||
assert.deepEqual(inherited.statusUpdates.at(-1), { key: FAST_MODE_STATUS_KEY, value: "on" });
|
||||
|
||||
const overridden = createHarness({
|
||||
globalEnabled: true,
|
||||
entries: [{ type: "custom", customType: FAST_MODE_STATE_ENTRY_TYPE, data: { enabled: false } }],
|
||||
});
|
||||
const overriddenStart = overridden.handlers.get("session_start");
|
||||
assert.ok(overriddenStart);
|
||||
overriddenStart!({}, overridden.context as unknown as ExtensionContext);
|
||||
assert.deepEqual(overridden.statusUpdates.at(-1), { key: FAST_MODE_STATUS_KEY, value: "off" });
|
||||
});
|
||||
|
||||
test("extension restores state, publishes status, and persists session and global mutations", async () => {
|
||||
const harness = createHarness({
|
||||
entries: [{ type: "custom", customType: FAST_MODE_STATE_ENTRY_TYPE, data: { enabled: true } }],
|
||||
});
|
||||
const sessionStart = harness.handlers.get("session_start");
|
||||
const request = harness.handlers.get("before_provider_request");
|
||||
const command = harness.commands.get("fast-mode");
|
||||
assert.ok(sessionStart && request && command);
|
||||
|
||||
sessionStart!({}, harness.context as unknown as ExtensionContext);
|
||||
assert.deepEqual(harness.statusUpdates.at(-1), { key: FAST_MODE_STATUS_KEY, value: "on" });
|
||||
assert.deepEqual(request!({ payload: { service_tier: "standard", keep: true } }, harness.context), {
|
||||
service_tier: FAST_MODE_SERVICE_TIER,
|
||||
keep: true,
|
||||
});
|
||||
|
||||
await command.handler("off", harness.context);
|
||||
assert.deepEqual(harness.appendCalls, [{ customType: FAST_MODE_STATE_ENTRY_TYPE, data: { enabled: false } }]);
|
||||
assert.deepEqual(harness.saveCalls.map((call) => call.state), [{ enabled: false }]);
|
||||
assert.deepEqual(harness.statusUpdates.at(-1), { key: FAST_MODE_STATUS_KEY, value: "off" });
|
||||
assert.equal(request!({ payload: { keep: true } }, harness.context), undefined);
|
||||
|
||||
await command.handler("status", harness.context);
|
||||
assert.match(harness.notifications.at(-1)?.message ?? "", /Fast mode: off.*New sessions default to off/u);
|
||||
assert.equal(harness.notifications.at(-1)?.level, "info");
|
||||
});
|
||||
|
||||
test("an explicit no-op mode command still refreshes the global default", async () => {
|
||||
const harness = createHarness({ globalEnabled: true });
|
||||
const sessionStart = harness.handlers.get("session_start");
|
||||
const command = harness.commands.get("fast-mode");
|
||||
assert.ok(sessionStart && command);
|
||||
sessionStart!({}, harness.context as unknown as ExtensionContext);
|
||||
|
||||
await command.handler("on", harness.context);
|
||||
assert.equal(harness.appendCalls.length, 0);
|
||||
assert.deepEqual(harness.saveCalls.map((call) => call.state), [{ enabled: true }]);
|
||||
});
|
||||
|
||||
test("a global save failure leaves the session usable and reports the persistence failure", async () => {
|
||||
const harness = createHarness({ saveError: "read-only filesystem" });
|
||||
const sessionStart = harness.handlers.get("session_start");
|
||||
const command = harness.commands.get("fast-mode");
|
||||
assert.ok(sessionStart && command);
|
||||
sessionStart!({}, harness.context as unknown as ExtensionContext);
|
||||
|
||||
await command.handler("on", harness.context);
|
||||
assert.deepEqual(harness.appendCalls, [{ customType: FAST_MODE_STATE_ENTRY_TYPE, data: { enabled: true } }]);
|
||||
assert.equal(harness.notifications.at(-1)?.level, "warning");
|
||||
assert.match(harness.notifications.at(-1)?.message ?? "", /could not be saved.*read-only filesystem/u);
|
||||
});
|
||||
|
||||
test("extension rejects every mutation while busy but leaves status readable", async () => {
|
||||
const harness = createHarness({ busy: true });
|
||||
const sessionStart = harness.handlers.get("session_start");
|
||||
const command = harness.commands.get("fast-mode");
|
||||
assert.ok(sessionStart && command);
|
||||
sessionStart!({}, harness.context as unknown as ExtensionContext);
|
||||
|
||||
await command.handler("on", harness.context);
|
||||
await command.handler("", harness.context);
|
||||
await command.handler("off", harness.context);
|
||||
assert.equal(harness.appendCalls.length, 0);
|
||||
assert.equal(harness.saveCalls.length, 0);
|
||||
assert.equal(harness.notifications.filter((item) => item.level === "warning").length, 3);
|
||||
|
||||
await command.handler("status", harness.context);
|
||||
assert.match(harness.notifications.at(-1)?.message ?? "", /Fast mode: off/u);
|
||||
assert.equal(harness.notifications.at(-1)?.level, "info");
|
||||
|
||||
harness.setBusy(false);
|
||||
harness.setPending(true);
|
||||
await command.handler("on", harness.context);
|
||||
assert.equal(harness.appendCalls.length, 0);
|
||||
assert.equal(harness.saveCalls.length, 0);
|
||||
});
|
||||
|
||||
test("tree navigation reconstructs the active branch state", () => {
|
||||
const harness = createHarness({
|
||||
globalEnabled: true,
|
||||
entries: [{ type: "custom", customType: FAST_MODE_STATE_ENTRY_TYPE, data: { enabled: true } }],
|
||||
});
|
||||
const sessionStart = harness.handlers.get("session_start");
|
||||
const sessionTree = harness.handlers.get("session_tree");
|
||||
assert.ok(sessionStart && sessionTree);
|
||||
|
||||
sessionStart!({}, harness.context as unknown as ExtensionContext);
|
||||
harness.entries.push({ type: "custom", customType: FAST_MODE_STATE_ENTRY_TYPE, data: { enabled: false } });
|
||||
sessionTree!({}, harness.context as unknown as ExtensionContext);
|
||||
assert.deepEqual(harness.statusUpdates.at(-1), { key: FAST_MODE_STATUS_KEY, value: "off" });
|
||||
});
|
||||
Reference in New Issue
Block a user