refactor(auto-reply): remove pi json fallback
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
import { spawn } from "node:child_process";
|
|
||||||
import fs from "node:fs/promises";
|
import fs from "node:fs/promises";
|
||||||
import os from "node:os";
|
import os from "node:os";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
@@ -81,55 +80,6 @@ function stripRpcNoise(raw: string): string {
|
|||||||
return kept.join("\n");
|
return kept.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runJsonFallback(opts: {
|
|
||||||
argv: string[];
|
|
||||||
cwd?: string;
|
|
||||||
timeoutMs: number;
|
|
||||||
}): Promise<{
|
|
||||||
stdout: string;
|
|
||||||
stderr: string;
|
|
||||||
code: number;
|
|
||||||
signal?: NodeJS.Signals | null;
|
|
||||||
killed?: boolean;
|
|
||||||
}> {
|
|
||||||
return await new Promise((resolve, reject) => {
|
|
||||||
const child = spawn(opts.argv[0], opts.argv.slice(1), {
|
|
||||||
cwd: opts.cwd,
|
|
||||||
stdio: ["ignore", "pipe", "pipe"],
|
|
||||||
});
|
|
||||||
let stdout = "";
|
|
||||||
let stderr = "";
|
|
||||||
const timer = setTimeout(() => {
|
|
||||||
child.kill("SIGKILL");
|
|
||||||
reject(
|
|
||||||
new Error(
|
|
||||||
`pi json fallback timed out after ${Math.round(opts.timeoutMs / 1000)}s`,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}, opts.timeoutMs);
|
|
||||||
child.stdout.on("data", (d) => {
|
|
||||||
stdout += d.toString();
|
|
||||||
});
|
|
||||||
child.stderr.on("data", (d) => {
|
|
||||||
stderr += d.toString();
|
|
||||||
});
|
|
||||||
child.on("error", (err) => {
|
|
||||||
clearTimeout(timer);
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
child.on("exit", (code, signal) => {
|
|
||||||
clearTimeout(timer);
|
|
||||||
resolve({
|
|
||||||
stdout,
|
|
||||||
stderr,
|
|
||||||
code: code ?? 0,
|
|
||||||
signal,
|
|
||||||
killed: child.killed,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractRpcAssistantText(raw: string): string | undefined {
|
function extractRpcAssistantText(raw: string): string | undefined {
|
||||||
if (!raw.trim()) return undefined;
|
if (!raw.trim()) return undefined;
|
||||||
let deltaBuffer = "";
|
let deltaBuffer = "";
|
||||||
@@ -611,33 +561,12 @@ export async function runCommandReply(
|
|||||||
streamedAny = true;
|
streamedAny = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Default to RPC (it is testable/offline and avoids spawning long-lived CLI processes).
|
|
||||||
// Set `CLAWDIS_USE_PI_RPC=0` to force the JSON fallback path.
|
|
||||||
const preferRpc = process.env.CLAWDIS_USE_PI_RPC !== "0";
|
|
||||||
|
|
||||||
const run = async () => {
|
const run = async () => {
|
||||||
const runId = params.runId ?? crypto.randomUUID();
|
const runId = params.runId ?? crypto.randomUUID();
|
||||||
let body = promptArg ?? "";
|
let body = promptArg ?? "";
|
||||||
if (!body || !body.trim()) {
|
if (!body || !body.trim()) {
|
||||||
body = templatingCtx.Body ?? templatingCtx.BodyStripped ?? "";
|
body = templatingCtx.Body ?? templatingCtx.BodyStripped ?? "";
|
||||||
}
|
}
|
||||||
if (!preferRpc) {
|
|
||||||
const jsonArgv = (() => {
|
|
||||||
const copy = [...finalArgv];
|
|
||||||
const idx = copy.indexOf("--mode");
|
|
||||||
if (idx >= 0 && copy[idx + 1]) copy[idx + 1] = "json";
|
|
||||||
else copy.push("--mode", "json");
|
|
||||||
return copy;
|
|
||||||
})();
|
|
||||||
logVerbose(
|
|
||||||
`Running command auto-reply in json mode: ${jsonArgv.join(" ")}${reply.cwd ? ` (cwd: ${reply.cwd})` : ""}`,
|
|
||||||
);
|
|
||||||
return await runJsonFallback({
|
|
||||||
argv: jsonArgv,
|
|
||||||
cwd: reply.cwd,
|
|
||||||
timeoutMs,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const rpcPromptIndex =
|
const rpcPromptIndex =
|
||||||
promptIndex >= 0 ? promptIndex : finalArgv.length - 1;
|
promptIndex >= 0 ? promptIndex : finalArgv.length - 1;
|
||||||
|
|||||||
@@ -106,8 +106,6 @@ describe("trigger handling", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("ignores think directives that only appear in the context wrapper", async () => {
|
it("ignores think directives that only appear in the context wrapper", async () => {
|
||||||
const prevPreferRpc = process.env.CLAWDIS_USE_PI_RPC;
|
|
||||||
process.env.CLAWDIS_USE_PI_RPC = "1";
|
|
||||||
const rpcMock = vi.spyOn(tauRpc, "runPiRpc").mockResolvedValue({
|
const rpcMock = vi.spyOn(tauRpc, "runPiRpc").mockResolvedValue({
|
||||||
stdout:
|
stdout:
|
||||||
'{"type":"message_end","message":{"role":"assistant","content":[{"type":"text","text":"ok"}]}}',
|
'{"type":"message_end","message":{"role":"assistant","content":[{"type":"text","text":"ok"}]}}',
|
||||||
@@ -139,17 +137,9 @@ describe("trigger handling", () => {
|
|||||||
const prompt = rpcMock.mock.calls[0]?.[0]?.prompt ?? "";
|
const prompt = rpcMock.mock.calls[0]?.[0]?.prompt ?? "";
|
||||||
expect(prompt).toContain("Give me the status");
|
expect(prompt).toContain("Give me the status");
|
||||||
expect(prompt).not.toContain("/thinking high");
|
expect(prompt).not.toContain("/thinking high");
|
||||||
|
|
||||||
if (prevPreferRpc === undefined) {
|
|
||||||
delete process.env.CLAWDIS_USE_PI_RPC;
|
|
||||||
} else {
|
|
||||||
process.env.CLAWDIS_USE_PI_RPC = prevPreferRpc;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not emit directive acks for heartbeats with /think", async () => {
|
it("does not emit directive acks for heartbeats with /think", async () => {
|
||||||
const prevPreferRpc = process.env.CLAWDIS_USE_PI_RPC;
|
|
||||||
process.env.CLAWDIS_USE_PI_RPC = "1";
|
|
||||||
const rpcMock = vi.spyOn(tauRpc, "runPiRpc").mockResolvedValue({
|
const rpcMock = vi.spyOn(tauRpc, "runPiRpc").mockResolvedValue({
|
||||||
stdout:
|
stdout:
|
||||||
'{"type":"message_end","message":{"role":"assistant","content":[{"type":"text","text":"ok"}]}}',
|
'{"type":"message_end","message":{"role":"assistant","content":[{"type":"text","text":"ok"}]}}',
|
||||||
@@ -182,11 +172,5 @@ describe("trigger handling", () => {
|
|||||||
expect(text).toBe("ok");
|
expect(text).toBe("ok");
|
||||||
expect(text).not.toMatch(/Thinking level set/i);
|
expect(text).not.toMatch(/Thinking level set/i);
|
||||||
expect(rpcMock).toHaveBeenCalledOnce();
|
expect(rpcMock).toHaveBeenCalledOnce();
|
||||||
|
|
||||||
if (prevPreferRpc === undefined) {
|
|
||||||
delete process.env.CLAWDIS_USE_PI_RPC;
|
|
||||||
} else {
|
|
||||||
process.env.CLAWDIS_USE_PI_RPC = prevPreferRpc;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user