allow proxy auto model selection
CI / 1. BUILD (pull_request) Successful in 2s
CI / 2. TEST (pull_request) Successful in 2s
CI / 3. RESULT (pull_request) Successful in 0s

This commit is contained in:
2026-08-07 06:16:45 +00:00
parent 0eb30cf9d4
commit 651e221e90
10 changed files with 96 additions and 41 deletions
+12 -2
View File
@@ -3,8 +3,8 @@ import assert from 'node:assert/strict';
import { getLLMConfig, getOpenCodeHttpsAgent } from '../config.js';
const ENV_KEYS = [
'CLI_PROXY_API', 'CLI_PROXY_API_KEY', 'INPUT_CLI_PROXY_API', 'INPUT_CLI_PROXY_API_KEY',
'MODEL', 'OPENCODE_MODEL', 'INPUT_MODEL',
'CLI_PROXY_API', 'CLI_PROXY_API_KEY', 'CLI_PROXY_API_MODEL', 'INPUT_CLI_PROXY_API', 'INPUT_CLI_PROXY_API_KEY', 'INPUT_MODEL',
'MODEL', 'OPENCODE_MODEL',
];
let saved = {};
@@ -52,6 +52,16 @@ describe('getLLMConfig', () => {
assert.equal(cfg.model, 'gpt-5-mini');
});
it('uses CLI_PROXY_API_MODEL when INPUT_MODEL is missing', () => {
process.env.CLI_PROXY_API = 'https://proxy.example';
process.env.CLI_PROXY_API_MODEL = 'gpt-5.4-mini';
process.env.MODEL = 'gpt-5.5';
const cfg = getLLMConfig();
assert.equal(cfg.model, 'gpt-5.4-mini');
});
it('returns null provider when CLI_PROXY_API is missing', () => {
process.env.MODEL = 'gpt-5.5';
const cfg = getLLMConfig();
+20 -1
View File
@@ -4,7 +4,7 @@ import axios from 'axios';
import { extractBalancedJSON, extractJSONText, extractMeaningfulError, mapWithConcurrency } from '../llm.js';
const ENV_KEYS = [
'CLI_PROXY_API', 'CLI_PROXY_API_KEY', 'MODEL', 'INPUT_MODEL', 'OPENCODE_MODEL',
'CLI_PROXY_API', 'CLI_PROXY_API_KEY', 'CLI_PROXY_API_MODEL', 'MODEL', 'INPUT_MODEL', 'OPENCODE_MODEL',
'AI_ASSISTANT_TIMEOUT_MS', 'AI_ASSISTANT_MAX_BUFFER',
];
@@ -57,6 +57,25 @@ describe('chat - CLIProxyAPI', async () => {
assert.equal(capturedOpts.headers.Authorization, 'Bearer secret');
});
it('omits model from the request body when auto selection is allowed', async () => {
process.env.CLI_PROXY_API = 'https://proxy.example';
process.env.CLI_PROXY_API_KEY = 'secret';
let capturedBody;
mock.method(axios, 'post', async (url, body) => {
capturedBody = body;
return {
data: { choices: [{ message: { content: 'cli response' } }] },
headers: {},
};
});
const result = await chat('sys', 'user');
assert.equal(result, 'cli response');
assert.equal(Object.hasOwn(capturedBody, 'model'), false);
});
it('throws an error when the API fails', async () => {
process.env.CLI_PROXY_API = 'https://proxy.example';
process.env.MODEL = 'gpt-5-mini';
+6
View File
@@ -131,6 +131,12 @@ describe('main pipeline', () => {
assert.equal(await runMain(), 0);
});
it('無 MODEL 仍可由 Proxy 自動選模並正常走完(exit 0)', async () => {
assert.equal(await runMain({
config: { getLLMConfig: () => ({ provider: 'cliproxyapi', apiKeys: ['secret'], baseURL: 'https://proxy.example', model: null, command: null }) },
}), 0);
});
it('clone 失敗仍繼續、不因 commitAndPush 中斷(無 critical → exit 0)', async () => {
assert.equal(await runMain({ git: { cloneRepo: () => { throw new Error('clone fail'); } } }), 0);
});
+17 -1
View File
@@ -4,7 +4,7 @@ import axios from 'axios';
import { checkRequiredEnv, verifyGiteaToken, verifyCommentToken, verifyLLM, fetchLLMModels, runPreflight } from '../preflight.js';
const LLM_ENV_KEYS = [
'CLI_PROXY_API', 'CLI_PROXY_API_KEY', 'INPUT_CLI_PROXY_API', 'INPUT_CLI_PROXY_API_KEY',
'CLI_PROXY_API', 'CLI_PROXY_API_KEY', 'CLI_PROXY_API_MODEL', 'INPUT_CLI_PROXY_API', 'INPUT_CLI_PROXY_API_KEY',
'MODEL', 'OPENCODE_MODEL', 'INPUT_MODEL',
];
@@ -164,6 +164,22 @@ describe('verifyLLM', () => {
assert.deepEqual(result.models, ['gpt-5.5', 'gpt-5.4-mini']);
});
it('passes when no model is specified and the proxy is reachable', async () => {
clearLLMEnv();
process.env.CLI_PROXY_API = 'https://proxy.example';
process.env.CLI_PROXY_API_KEY = 'secret';
const result = await verifyLLM({
fetchLLMModelsFn: async () => ({ ok: true, slugs: ['gpt-5.5', 'gpt-5.4-mini'] }),
});
assert.equal(result.ok, true);
assert.equal(result.provider, 'cliproxyapi');
assert.equal(result.command, null);
assert.equal(result.model, null);
assert.deepEqual(result.models, ['gpt-5.5', 'gpt-5.4-mini']);
});
it('fails when proxy auth is invalid', async () => {
clearLLMEnv();
process.env.CLI_PROXY_API = 'https://proxy.example';