fix(review): run claude-cli models directly

This commit is contained in:
Claude
2026-08-23 00:23:02 -04:00
parent 6b131e1427
commit 0db44a4d73
5 changed files with 215 additions and 4 deletions
+57
View File
@@ -0,0 +1,57 @@
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { ReviewQueue } from '../src/lib/queue.js';
test('newer jobs supersede queued work for the same pull request', async () => {
const queue = new ReviewQueue();
const ran = [];
const superseded = [];
const first = queue.enqueue(
'nirpa/hermes-agent',
async () => ran.push('old'),
{ dedupeKey: 'pr:86', onSuperseded: () => superseded.push('old') }
);
const second = queue.enqueue(
'nirpa/hermes-agent',
async () => ran.push('new'),
{ dedupeKey: 'pr:86', onSuperseded: () => superseded.push('new') }
);
await Promise.all([first, second]);
assert.deepEqual(ran, ['new']);
assert.deepEqual(superseded, ['old']);
assert.equal(queue.pending, 0);
});
test('different pull requests are not deduplicated', async () => {
const queue = new ReviewQueue();
const ran = [];
await Promise.all([
queue.enqueue('nirpa/hermes-agent', async () => ran.push('pr-86'), { dedupeKey: 'pr:86' }),
queue.enqueue('nirpa/hermes-agent', async () => ran.push('pr-87'), { dedupeKey: 'pr:87' })
]);
assert.deepEqual(ran, ['pr-86', 'pr-87']);
});
test('shared sha key deduplicates push and pull-request webhooks', async () => {
const queue = new ReviewQueue();
const ran = [];
const push = queue.enqueue(
'nirpa/hermes-agent',
async () => ran.push('push'),
{ dedupeKeys: ['sha:final'] }
);
const pullRequest = queue.enqueue(
'nirpa/hermes-agent',
async () => ran.push('pull-request'),
{ dedupeKeys: ['pr:86', 'sha:final'] }
);
await Promise.all([push, pullRequest]);
assert.deepEqual(ran, ['pull-request']);
});
+72
View File
@@ -1,5 +1,8 @@
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { chmod, mkdtemp, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { chat } from '../src/lib/router.js';
test('review router client disables model fallbacks explicitly', async () => {
@@ -32,3 +35,72 @@ test('review router client disables model fallbacks explicitly', async () => {
assert.equal(body.raw, true);
assert.equal(body.stream, false);
});
test('claude-cli models bypass the router and use subscription credentials', async () => {
const dir = await mkdtemp(join(tmpdir(), 'granthi-review-claude-'));
const fakeClaude = join(dir, 'claude');
await writeFile(fakeClaude, `#!/bin/sh
case " $* " in
*" --model claude-sonnet-4-6 "*) ;;
*) exit 21 ;;
esac
case " $* " in
*" --tools --permission-mode dontAsk --no-session-persistence "*) ;;
*) exit 22 ;;
esac
[ -z "\${ANTHROPIC_API_KEY:-}" ] || exit 23
[ -z "\${ANTHROPIC_TOKEN:-}" ] || exit 24
printf '%s' '{"result":"{\\"axes\\":{},\\"overall\\":90,\\"grade\\":\\"A\\",\\"findings\\":[]}"}'
`);
await chmod(fakeClaude, 0o700);
const originalFetch = globalThis.fetch;
const originalApiKey = process.env.ANTHROPIC_API_KEY;
const originalToken = process.env.ANTHROPIC_TOKEN;
globalThis.fetch = async () => { throw new Error('router must not be called'); };
process.env.ANTHROPIC_API_KEY = 'test-api-key';
process.env.ANTHROPIC_TOKEN = 'test-token';
try {
const result = await chat({
routerUrl: 'http://router.test',
model: 'claude-cli/claude-sonnet-4-6',
messages: [{ role: 'user', content: 'review this diff' }],
agentId: 'code-reviewer',
sessionId: 'review-test',
tenantId: 'nirlab',
timeoutMs: 1000,
claudeBin: fakeClaude
});
assert.match(result.content, /"overall":90/);
assert.equal(result.servedModel, 'claude-cli/claude-sonnet-4-6');
} finally {
globalThis.fetch = originalFetch;
if (originalApiKey === undefined) delete process.env.ANTHROPIC_API_KEY;
else process.env.ANTHROPIC_API_KEY = originalApiKey;
if (originalToken === undefined) delete process.env.ANTHROPIC_TOKEN;
else process.env.ANTHROPIC_TOKEN = originalToken;
}
});
test('claude-cli failures do not leak the review prompt', async () => {
const dir = await mkdtemp(join(tmpdir(), 'granthi-review-claude-error-'));
const fakeClaude = join(dir, 'claude');
await writeFile(fakeClaude, '#!/bin/sh\nprintf "%s\\n" "$*" >&2\nexit 25\n');
await chmod(fakeClaude, 0o700);
await assert.rejects(
chat({
routerUrl: 'http://router.test',
model: 'claude-cli/claude-sonnet-4-6',
messages: [{ role: 'user', content: 'SECRET_REVIEW_DIFF_MARKER' }],
timeoutMs: 1000,
claudeBin: fakeClaude
}),
(error) => {
assert.match(error.message, /claude-cli failed/);
assert.doesNotMatch(error.message, /SECRET_REVIEW_DIFF_MARKER/);
return true;
}
);
});