feat(ai-review 對話收斂): 讀 PR review 留言判斷解決狀態並收斂 findings #42

Merged
jiantw83 merged 68 commits from ai-review-resolve/20260623-110950 into develop 2026-06-23 08:29:38 +00:00
Showing only changes of commit 54f268c81b - Show all commits
+21
View File
@@ -40,6 +40,11 @@ describe('extractUsage', () => {
assert.deepEqual(u, { promptTokens: 7, completionTokens: 3, totalTokens: 10 }); assert.deepEqual(u, { promptTokens: 7, completionTokens: 3, totalTokens: 10 });
}); });
it('respects an explicit total_tokens of 0 instead of summing', () => {
const u = extractUsage({ usage: { prompt_tokens: 10, completion_tokens: 2, total_tokens: 0 } });
assert.equal(u.totalTokens, 0);
});
it('returns null when no usage info is present', () => { it('returns null when no usage info is present', () => {
assert.equal(extractUsage({ choices: [{ message: { content: 'hi' } }] }), null); assert.equal(extractUsage({ choices: [{ message: { content: 'hi' } }] }), null);
assert.equal(extractUsage(null), null); assert.equal(extractUsage(null), null);
@@ -86,6 +91,22 @@ describe('fetchAccountQuota', () => {
assert.match(q.reason, /API key 無法取得/); assert.match(q.reason, /API key 無法取得/);
}); });
it('does not treat spoofed openrouter hostnames as OpenRouter (no key leak)', async () => {
const get = async () => { throw new Error('should not be called for spoofed host'); };
for (const baseURL of ['https://openrouter.ai.evil.com/api/v1', 'https://evil.com/openrouter.ai']) {
const q = await fetchAccountQuota('openai', { apiKeys: ['sk-secret'], baseURL }, { get });
assert.equal(q.available, false);
assert.match(q.reason, /API key 無法取得/);
}
});
it('accepts a real openrouter subdomain', async () => {
const get = async () => ({ data: { data: { usage: 1, limit: 10, limit_remaining: 9 } } });
const q = await fetchAccountQuota('openai', { apiKeys: ['k'], baseURL: 'https://api.openrouter.ai/api/v1' }, { get });
assert.equal(q.available, true);
assert.equal(q.source, 'openrouter');
});
it('reports 不適用 for local platforms', async () => { it('reports 不適用 for local platforms', async () => {
assert.equal((await fetchAccountQuota('ollama', {})).available, false); assert.equal((await fetchAccountQuota('ollama', {})).available, false);
assert.equal((await fetchAccountQuota('opencode', {})).available, false); assert.equal((await fetchAccountQuota('opencode', {})).available, false);