File size: 4,165 Bytes
a861001 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | import { spawnSync } from "node:child_process";
import {
existsSync,
mkdirSync,
mkdtempSync,
readFileSync,
readdirSync,
realpathSync,
writeFileSync,
} from "node:fs";
import { tmpdir } from "node:os";
import { join, resolve } from "node:path";
const executableName = process.platform === "win32" ? "rsih.exe" : "rsih";
const binaryPath = resolve(
process.env.RSIH_BINARY ?? join("dist", executableName),
);
if (!existsSync(binaryPath)) {
throw new Error(`Binary does not exist: ${binaryPath}`);
}
const runtimeDirectory = mkdtempSync(join(tmpdir(), "rsih-binary-"));
const configPath = join(runtimeDirectory, "providers.json");
const genomesDirectory = join(runtimeDirectory, ".rsih", "genomes");
const extensionsDirectory = join(runtimeDirectory, "extensions");
const extensionPath = join(extensionsDirectory, "echo.ts");
mkdirSync(genomesDirectory, { recursive: true });
mkdirSync(extensionsDirectory, { recursive: true });
writeFileSync(
configPath,
JSON.stringify({
mock: {
kind: "mock",
model: "binary-smoke",
mock_responses: [
{
text: "",
tool_calls: [
{
id: "binary-extension-call",
name: "binary_echo",
arguments: { value: "binary tool ok" },
},
],
},
"binary ok",
],
},
}),
"utf8",
);
writeFileSync(
extensionPath,
[
"export default function extension(pi) {",
" pi.registerTool({",
' name: "binary_echo",',
' label: "Binary echo",',
' description: "Echo a value.",',
' parameters: { type: "object", required: ["value"], additionalProperties: false, properties: { value: { type: "string" } } },',
" async execute(_id, params) {",
' return { content: [{ type: "text", text: params.value }], details: {} };',
" },",
" });",
"}",
].join("\n"),
"utf8",
);
const genome = JSON.parse(
readFileSync(resolve("config", "harness.default.json"), "utf8"),
);
genome.genome_id = "harness:binary-smoke";
genome.model = { profile: "mock", id: "binary-smoke" };
genome.extensions = [{ source: "../../extensions/echo.ts" }];
writeFileSync(
join(genomesDirectory, "smoke.json"),
JSON.stringify(genome),
"utf8",
);
const result = spawnSync(
binaryPath,
[
"-p",
"Say binary ok.",
"--genome",
"smoke",
"--config",
configPath,
"--cwd",
runtimeDirectory,
],
{
encoding: "utf8",
env: {
...process.env,
PI_OFFLINE: "1",
PI_SKIP_VERSION_CHECK: "1",
RSIH_CODING_AGENT_DIR: join(runtimeDirectory, ".rsih-agent"),
},
},
);
if (result.status !== 0) {
throw new Error(result.stderr || `Binary exited with ${result.status}.`);
}
if (result.stdout.trim() !== "binary ok") {
throw new Error(`Unexpected binary output: ${result.stdout.trim()}`);
}
// Sessions live wherever Pi puts them: <agentDir>/sessions/--<cwd>--/.
const canonicalCwd = realpathSync(runtimeDirectory);
const sessionDirectory = join(
runtimeDirectory,
".rsih-agent",
"sessions",
`--${canonicalCwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`,
);
const sessionFiles = readdirSync(sessionDirectory).filter((name) =>
name.endsWith(".jsonl"),
);
if (sessionFiles.length !== 1) {
throw new Error(`Expected one Pi session, found ${sessionFiles.length}.`);
}
const entries = readFileSync(join(sessionDirectory, sessionFiles[0]), "utf8")
.split(/\r?\n/)
.filter(Boolean)
.map((line) => JSON.parse(line));
if (
!entries.some(
(entry) =>
entry.type === "custom" &&
entry.customType === "rsih.genome" &&
entry.data.genome_id === "harness:binary-smoke",
)
) {
throw new Error("Binary did not persist the Genome snapshot in the Pi session.");
}
if (
!entries.some(
(entry) =>
entry.type === "message" &&
entry.message.role === "toolResult" &&
entry.message.content.some(
(content) =>
content.type === "text" && content.text === "binary tool ok",
),
)
) {
throw new Error("Binary did not execute the Genome Pi extension tool.");
}
console.log(`Binary smoke passed: ${binaryPath}`);
|