automaker / scripts /probe-opencode-compatible.mjs
Leon4gr45's picture
Upload folder using huggingface_hub (part 6)
5090f42 verified
Raw History Blame Contribute Delete
8.11 kB
// Bounded, non-mutating smoke test against a local OpenAI-compatible fixture.
// Run after npm run build:server: timeout 120s node scripts/probe-opencode-compatible.mjs
// OPENCODE_BIN may name a locally installed OpenCode executable. No real endpoint is used.
import fs from 'node:fs/promises';
import os from 'node:os';
import crypto from 'node:crypto';
import { execFileSync } from 'node:child_process';
import path from 'node:path';
import http from 'node:http';
import { spawn } from 'node:child_process';
import { OpencodeProvider } from '../apps/server/dist/providers/opencode-provider.js';
import { AgentExecutor } from '../apps/server/dist/services/agent-executor.js';
import { OpenCodeRoleRunner } from '../apps/server/dist/services/argus/opencode-role-runner.js';
import { configureOpenCode } from '../apps/server/dist/services/argus/opencode-config.js';
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'automaker-opencode-probe-'));
const originalEnv = { ...process.env };
const cli = process.env.OPENCODE_BIN || 'opencode';
const env = {
...process.env,
PATH: (cli.includes('/') ? path.dirname(path.resolve(cli)) + ':' : '') + process.env.PATH,
XDG_DATA_HOME: root + '/data',
XDG_CONFIG_HOME: root + '/config',
XDG_CACHE_HOME: root + '/cache',
XDG_STATE_HOME: root + '/state',
COMPATIBLE_MODEL: 'MiniMax-M2.7',
COMPATIBLE_API_KEY: crypto.randomUUID(),
};
const requests = [];
const server = http.createServer(async (req, res) => {
let raw = '';
for await (const chunk of req) raw += chunk;
let body = {};
try {
body = JSON.parse(raw);
} catch {}
requests.push({
path: req.url,
model: body.model,
authenticated: req.headers.authorization === 'Bearer ' + env.COMPATIBLE_API_KEY,
});
if (req.url?.endsWith('/chat/completions')) {
res.writeHead(200, { 'Content-Type': 'text/event-stream' });
const prompt = JSON.stringify(body.messages);
const reply = prompt.includes('diagnostic probe')
? JSON.stringify({
rootCause: 'routing',
recommendedFix: 'canonical identity',
juniorCanRepair: true,
evidence: [],
filesLikelyAffected: [],
})
: prompt.includes('review probe')
? JSON.stringify({
verdict: 'approve',
reviewedHeadSha: 'abc',
findings: [],
requiredChanges: [],
evidence: [],
})
: 'LOCAL_PROBE_OK';
const base = {
id: 'chatcmpl-local',
object: 'chat.completion.chunk',
created: 1,
model: 'MiniMax-M2.7',
};
res.write(
'data: ' +
JSON.stringify({
...base,
choices: [
{ index: 0, delta: { role: 'assistant', content: reply }, finish_reason: null },
],
}) +
'\n\n'
);
res.write(
'data: ' +
JSON.stringify({
...base,
choices: [{ index: 0, delta: {}, finish_reason: 'stop' }],
usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 },
}) +
'\n\n'
);
res.end('data: [DONE]\n\n');
} else {
res.writeHead(404);
res.end('{}');
}
});
await new Promise((r) => server.listen(0, '127.0.0.1', r));
env.COMPATIBLE_URL = `http://127.0.0.1:${server.address().port}/v1`;
process.env.PATH = env.PATH;
Object.assign(process.env, {
XDG_DATA_HOME: env.XDG_DATA_HOME,
XDG_CONFIG_HOME: env.XDG_CONFIG_HOME,
XDG_CACHE_HOME: env.XDG_CACHE_HOME,
XDG_STATE_HOME: env.XDG_STATE_HOME,
});
const cfg = root + '/config/opencode';
await fs.mkdir(cfg, { recursive: true });
await fs.writeFile(cfg + '/opencode.json', JSON.stringify({ permission: { '*': 'deny' } }));
let outcome;
try {
const cliVersion = execFileSync(cli, ['--version'], {
env,
encoding: 'utf8',
timeout: 15000,
stdio: ['ignore', 'pipe', 'pipe'],
}).trim();
const model = await configureOpenCode(env, cfg);
env.OPENCODE_CONFIG = cfg + '/opencode.json';
const runProbe = (selector) =>
new Promise((resolve) => {
const child = spawn(cli, ['run', '--format', 'json', '--model', selector], {
cwd: root,
env,
stdio: ['pipe', 'pipe', 'pipe'],
});
let stdout = '',
stderr = '';
child.stdout.on('data', (b) => (stdout += b));
child.stderr.on('data', (b) => (stderr += b));
child.stdin.end(
'Return LOCAL_PROBE_OK. Do not use any tools, read files or modify anything.'
);
const timer = setTimeout(() => child.kill('SIGKILL'), 45000);
child.on('exit', (exit) => {
clearTimeout(timer);
resolve({
exit,
textReceived: stdout.includes('LOCAL_PROBE_OK'),
events: stdout
.split('\n')
.filter(Boolean)
.map((l) => {
try {
return JSON.parse(l).type;
} catch {
return 'non-json';
}
}),
stderrPresent: !!stderr,
genericServerError: (stdout + stderr).includes('Unexpected server error'),
});
});
});
const beforeRequestCount = requests.length;
const before = await runProbe('opencode/MiniMax-M2.7');
const wrongProviderReachedEndpoint = requests.length !== beforeRequestCount;
outcome = await runProbe(model);
Object.assign(process.env, env);
const provider = new OpencodeProvider();
const invocations = [];
const build = provider.buildCliArgs.bind(provider);
provider.buildCliArgs = (options) => {
const args = build(options);
invocations.push(args);
return args;
};
const noop = async () => {};
const executor = new AgentExecutor(
{ emitAutoModeEvent: () => {} },
{ saveFeatureSummary: noop, updateFeaturePlanSpec: noop },
{ waitForApproval: noop }
);
const normal = await executor.execute(
{
workDir: root,
projectPath: root,
featureId: 'bounded-cli-probe',
prompt: 'Return LOCAL_PROBE_OK without tools.',
abortController: new AbortController(),
provider,
effectiveBareModel: 'MiniMax-M2.7',
model: 'MiniMax-M2.7',
sdkOptions: { model, maxTurns: 1 },
planningMode: 'skip',
},
{
waitForApproval: noop,
saveFeatureSummary: noop,
updateFeatureSummary: noop,
buildTaskPrompt: () => '',
}
);
const runner = new OpenCodeRoleRunner();
const diagnosis = await runner.diagnose({ fixture: 'diagnostic probe' });
const review = await runner.review({ fixture: 'review probe' });
const engineer = await runner.execute('Return LOCAL_PROBE_OK without tools.', root);
console.log(
JSON.stringify({
cliVersion,
identity: model,
before: { ...before, wrongProviderReachedEndpoint },
outcome,
normalFeature: { textReceived: normal.responseText.includes('LOCAL_PROBE_OK'), invocations },
roles: {
diagnosisValid: diagnosis.result.rootCause === 'routing',
reviewValid: review.result.verdict === 'approve',
engineerValid: engineer.output.includes('LOCAL_PROBE_OK'),
},
requests,
})
);
if (
!normal.responseText.includes('LOCAL_PROBE_OK') ||
!invocations.some((a) => a.includes(model)) ||
diagnosis.result.rootCause !== 'routing' ||
review.result.verdict !== 'approve' ||
!engineer.output.includes('LOCAL_PROBE_OK') ||
requests.some((r) => r.model !== 'MiniMax-M2.7' || !r.authenticated)
)
process.exitCode = 1;
if (
before.exit === 0 ||
before.textReceived ||
wrongProviderReachedEndpoint ||
outcome.exit !== 0 ||
!outcome.textReceived ||
!requests.some((r) => r.model === 'MiniMax-M2.7' && r.authenticated)
)
process.exitCode = 1;
} catch {
console.error('OpenCode compatible smoke test failed; inspect sanitized diagnostics above.');
process.exitCode = 1;
} finally {
await new Promise((resolve) => server.close(resolve));
for (const key of Object.keys(process.env)) if (!(key in originalEnv)) delete process.env[key];
Object.assign(process.env, originalEnv);
await fs.rm(root, { recursive: true, force: true });
}