shennian 0.2.8 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/src/agents/codex.js
CHANGED
|
@@ -785,10 +785,19 @@ function normalizeCodexStderr(stderr) {
|
|
|
785
785
|
.join('\n');
|
|
786
786
|
}
|
|
787
787
|
function normalizeTerminalText(text) {
|
|
788
|
+
const escape = String.fromCharCode(27);
|
|
789
|
+
const bell = String.fromCharCode(7);
|
|
790
|
+
const csiPattern = new RegExp(`${escape}\\[[0-?]*[ -/]*[@-~]`, 'g');
|
|
791
|
+
const oscPattern = new RegExp(`${escape}\\][^${bell}]*(?:${bell}|${escape}\\\\)`, 'g');
|
|
788
792
|
return text
|
|
789
|
-
.replace(
|
|
790
|
-
.replace(
|
|
791
|
-
.
|
|
793
|
+
.replace(csiPattern, ' ')
|
|
794
|
+
.replace(oscPattern, ' ')
|
|
795
|
+
.split('')
|
|
796
|
+
.map((char) => {
|
|
797
|
+
const code = char.charCodeAt(0);
|
|
798
|
+
return (code <= 8 || code === 11 || code === 12 || (code >= 14 && code <= 31) || code === 127) ? ' ' : char;
|
|
799
|
+
})
|
|
800
|
+
.join('')
|
|
792
801
|
.replace(/\s+/g, ' ')
|
|
793
802
|
.trim();
|
|
794
803
|
}
|
|
@@ -3,9 +3,12 @@ export declare function stripAnsi(text: string): string;
|
|
|
3
3
|
export declare function parseCursorModels(raw: string): ModelInfo[];
|
|
4
4
|
export declare function parseOpenClawModels(raw: string): ModelInfo[];
|
|
5
5
|
export declare function parseClaudeModels(raw: string): ModelInfo[];
|
|
6
|
+
type EnvLike = Record<string, string | undefined>;
|
|
7
|
+
export declare function applyClaudeModelEnvOverrides(models: ModelInfo[], env?: EnvLike): ModelInfo[];
|
|
6
8
|
export declare function parseClaudeBinaryModels(raw: string): ModelInfo[];
|
|
7
9
|
export declare function fallbackClaudeAliasModels(): ModelInfo[];
|
|
8
10
|
export declare function parseCodexModels(raw: string): ModelInfo[];
|
|
9
11
|
export declare function parseCodexAppServerModels(raw: unknown): ModelInfo[];
|
|
10
12
|
export declare function parseGeminiModels(raw: string): ModelInfo[];
|
|
11
13
|
export declare function fallbackGeminiModels(): ModelInfo[];
|
|
14
|
+
export {};
|
|
@@ -97,7 +97,11 @@ export function parseOpenClawModels(raw) {
|
|
|
97
97
|
export function parseClaudeModels(raw) {
|
|
98
98
|
const rawClean = stripAnsi(raw).replace(/\s+/g, ' ');
|
|
99
99
|
const patterns = [
|
|
100
|
-
[
|
|
100
|
+
[
|
|
101
|
+
/\d+\.Default\(recommended\).*?(?:Sonnet|currently\s*Sonnet)\s*([\d.]+)/i,
|
|
102
|
+
'default',
|
|
103
|
+
'Default (recommended)',
|
|
104
|
+
],
|
|
101
105
|
[/\d+\.Sonnet.*?Sonnet\s*([\d.]+)/i, 'sonnet', 'Sonnet'],
|
|
102
106
|
[/\d+\.Opus.*?Opus\s*([\d.]+)/i, 'opus', 'Opus'],
|
|
103
107
|
[/\d+\.Haiku.*?Haiku\s*([\d.]+)/i, 'haiku', 'Haiku'],
|
|
@@ -126,9 +130,7 @@ export function parseClaudeModels(raw) {
|
|
|
126
130
|
if (!alias)
|
|
127
131
|
continue;
|
|
128
132
|
const version = match[2] ?? '';
|
|
129
|
-
const isDefault = defaultMatch &&
|
|
130
|
-
defaultMatch[1]?.toLowerCase() === family &&
|
|
131
|
-
defaultMatch[2] === version;
|
|
133
|
+
const isDefault = defaultMatch && defaultMatch[1]?.toLowerCase() === family && defaultMatch[2] === version;
|
|
132
134
|
fallback.push({
|
|
133
135
|
id: alias,
|
|
134
136
|
name: `${titleCaseSegment(family)} ${version}`,
|
|
@@ -166,14 +168,51 @@ function formatClaudeVersion(version) {
|
|
|
166
168
|
return undefined;
|
|
167
169
|
return `v${version.join('.')}`;
|
|
168
170
|
}
|
|
171
|
+
const CLAUDE_ALIAS_LABELS = {
|
|
172
|
+
default: 'Default (recommended)',
|
|
173
|
+
sonnet: 'Sonnet',
|
|
174
|
+
opus: 'Opus',
|
|
175
|
+
haiku: 'Haiku',
|
|
176
|
+
};
|
|
177
|
+
const CLAUDE_ALIAS_MODEL_ENV = {
|
|
178
|
+
default: 'ANTHROPIC_MODEL',
|
|
179
|
+
sonnet: 'ANTHROPIC_DEFAULT_SONNET_MODEL',
|
|
180
|
+
opus: 'ANTHROPIC_DEFAULT_OPUS_MODEL',
|
|
181
|
+
haiku: 'ANTHROPIC_DEFAULT_HAIKU_MODEL',
|
|
182
|
+
};
|
|
183
|
+
function readEnvValue(env, key) {
|
|
184
|
+
const value = env[key]?.trim();
|
|
185
|
+
return value || null;
|
|
186
|
+
}
|
|
187
|
+
function inferClaudeOverrideProvider(modelName, env) {
|
|
188
|
+
const baseUrl = readEnvValue(env, 'ANTHROPIC_BASE_URL')?.toLowerCase() ?? '';
|
|
189
|
+
if (baseUrl.includes('deepseek.com') || modelName.toLowerCase().startsWith('deepseek-')) {
|
|
190
|
+
return 'deepseek';
|
|
191
|
+
}
|
|
192
|
+
return baseUrl ? 'custom' : 'anthropic';
|
|
193
|
+
}
|
|
194
|
+
export function applyClaudeModelEnvOverrides(models, env = process.env) {
|
|
195
|
+
return models.map((model) => {
|
|
196
|
+
if (!['default', 'sonnet', 'opus', 'haiku'].includes(model.id))
|
|
197
|
+
return model;
|
|
198
|
+
const alias = model.id;
|
|
199
|
+
const configuredModel = readEnvValue(env, CLAUDE_ALIAS_MODEL_ENV[alias]);
|
|
200
|
+
if (!configuredModel)
|
|
201
|
+
return model;
|
|
202
|
+
const aliasLabel = CLAUDE_ALIAS_LABELS[alias];
|
|
203
|
+
const aliasDescription = `Claude Code alias: ${aliasLabel}`;
|
|
204
|
+
return {
|
|
205
|
+
...model,
|
|
206
|
+
name: configuredModel,
|
|
207
|
+
description: model.description
|
|
208
|
+
? `${aliasDescription} · ${model.description}`
|
|
209
|
+
: aliasDescription,
|
|
210
|
+
provider: inferClaudeOverrideProvider(configuredModel, env),
|
|
211
|
+
};
|
|
212
|
+
});
|
|
213
|
+
}
|
|
169
214
|
export function parseClaudeBinaryModels(raw) {
|
|
170
215
|
const clean = stripAnsi(raw);
|
|
171
|
-
const aliasMap = {
|
|
172
|
-
default: 'Default (recommended)',
|
|
173
|
-
sonnet: 'Sonnet',
|
|
174
|
-
opus: 'Opus',
|
|
175
|
-
haiku: 'Haiku',
|
|
176
|
-
};
|
|
177
216
|
const familyVersions = new Map();
|
|
178
217
|
for (const family of ['sonnet', 'opus', 'haiku']) {
|
|
179
218
|
for (const match of clean.matchAll(new RegExp(`\\bclaude-${family}-[0-9.-]+\\b`, 'gi'))) {
|
|
@@ -194,7 +233,7 @@ export function parseClaudeBinaryModels(raw) {
|
|
|
194
233
|
const version = (alias === 'default' ? familyVersions.get('sonnet') : familyVersions.get(alias)) ?? null;
|
|
195
234
|
models.push({
|
|
196
235
|
id: alias,
|
|
197
|
-
name:
|
|
236
|
+
name: CLAUDE_ALIAS_LABELS[alias],
|
|
198
237
|
description: formatClaudeVersion(version),
|
|
199
238
|
provider: 'anthropic',
|
|
200
239
|
isDefault: alias === 'default',
|
|
@@ -203,12 +242,12 @@ export function parseClaudeBinaryModels(raw) {
|
|
|
203
242
|
return uniqueModels(models);
|
|
204
243
|
}
|
|
205
244
|
export function fallbackClaudeAliasModels() {
|
|
206
|
-
return [
|
|
245
|
+
return applyClaudeModelEnvOverrides([
|
|
207
246
|
{ id: 'default', name: 'Default (recommended)', provider: 'anthropic', isDefault: true },
|
|
208
247
|
{ id: 'sonnet', name: 'Sonnet', provider: 'anthropic' },
|
|
209
248
|
{ id: 'opus', name: 'Opus', provider: 'anthropic' },
|
|
210
249
|
{ id: 'haiku', name: 'Haiku', provider: 'anthropic' },
|
|
211
|
-
];
|
|
250
|
+
]);
|
|
212
251
|
}
|
|
213
252
|
export function parseCodexModels(raw) {
|
|
214
253
|
const clean = stripAnsi(raw);
|
|
@@ -218,7 +257,10 @@ export function parseCodexModels(raw) {
|
|
|
218
257
|
if (!match)
|
|
219
258
|
continue;
|
|
220
259
|
const id = match[1].trim();
|
|
221
|
-
const description = line
|
|
260
|
+
const description = line
|
|
261
|
+
.replace(id, '')
|
|
262
|
+
.replace(/^[^\w]+/, '')
|
|
263
|
+
.trim() || undefined;
|
|
222
264
|
models.push({
|
|
223
265
|
id,
|
|
224
266
|
name: prettifyCodexModel(id),
|
|
@@ -242,11 +284,7 @@ export function parseCodexAppServerModels(raw) {
|
|
|
242
284
|
if (typeof entry !== 'object' || entry === null)
|
|
243
285
|
continue;
|
|
244
286
|
const item = entry;
|
|
245
|
-
const id = typeof item.id === 'string'
|
|
246
|
-
? item.id
|
|
247
|
-
: typeof item.model === 'string'
|
|
248
|
-
? item.model
|
|
249
|
-
: '';
|
|
287
|
+
const id = typeof item.id === 'string' ? item.id : typeof item.model === 'string' ? item.model : '';
|
|
250
288
|
if (!id)
|
|
251
289
|
continue;
|
|
252
290
|
const displayName = typeof item.displayName === 'string'
|
|
@@ -255,9 +293,7 @@ export function parseCodexAppServerModels(raw) {
|
|
|
255
293
|
? item.name
|
|
256
294
|
: undefined;
|
|
257
295
|
const description = typeof item.description === 'string' ? item.description : undefined;
|
|
258
|
-
const defaultReasoningEffort = typeof item.defaultReasoningEffort === 'string'
|
|
259
|
-
? item.defaultReasoningEffort
|
|
260
|
-
: undefined;
|
|
296
|
+
const defaultReasoningEffort = typeof item.defaultReasoningEffort === 'string' ? item.defaultReasoningEffort : undefined;
|
|
261
297
|
const supportedReasoningEfforts = Array.isArray(item.supportedReasoningEfforts)
|
|
262
298
|
? item.supportedReasoningEfforts
|
|
263
299
|
.map((effort) => {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export { getCachedAgentInfos, refreshAgentInfos, resolveAgentInfos } from './model-registry/service.js';
|
|
2
|
-
import { parseClaudeBinaryModels, parseClaudeModels, parseCodexModels, parseCodexAppServerModels, parseCursorModels, parseGeminiModels, parseOpenClawModels, stripAnsi } from './model-registry/parsers.js';
|
|
1
|
+
export { getCachedAgentInfos, refreshAgentInfos, resolveAgentInfos, } from './model-registry/service.js';
|
|
2
|
+
import { applyClaudeModelEnvOverrides, parseClaudeBinaryModels, parseClaudeModels, parseCodexModels, parseCodexAppServerModels, parseCursorModels, parseGeminiModels, parseOpenClawModels, stripAnsi } from './model-registry/parsers.js';
|
|
3
3
|
/** Used by Vitest / `model-switching-e2e.ts` — not a stable public API. */
|
|
4
4
|
export declare const modelSwitchingTestExports: {
|
|
5
|
+
readonly applyClaudeModelEnvOverrides: typeof applyClaudeModelEnvOverrides;
|
|
5
6
|
readonly parseClaudeBinaryModels: typeof parseClaudeBinaryModels;
|
|
6
7
|
readonly parseClaudeModels: typeof parseClaudeModels;
|
|
7
8
|
readonly parseCodexModels: typeof parseCodexModels;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// @arch docs/architecture/cli/model-discovery.md
|
|
2
2
|
// @test src/__tests__/model-switching.test.ts
|
|
3
|
-
export { getCachedAgentInfos, refreshAgentInfos, resolveAgentInfos } from './model-registry/service.js';
|
|
4
|
-
import { parseClaudeBinaryModels, parseClaudeModels, parseCodexModels, parseCodexAppServerModels, parseCursorModels, parseGeminiModels, parseOpenClawModels, stripAnsi, } from './model-registry/parsers.js';
|
|
3
|
+
export { getCachedAgentInfos, refreshAgentInfos, resolveAgentInfos, } from './model-registry/service.js';
|
|
4
|
+
import { applyClaudeModelEnvOverrides, parseClaudeBinaryModels, parseClaudeModels, parseCodexModels, parseCodexAppServerModels, parseCursorModels, parseGeminiModels, parseOpenClawModels, stripAnsi, } from './model-registry/parsers.js';
|
|
5
5
|
/** Used by Vitest / `model-switching-e2e.ts` — not a stable public API. */
|
|
6
6
|
export const modelSwitchingTestExports = {
|
|
7
|
+
applyClaudeModelEnvOverrides,
|
|
7
8
|
parseClaudeBinaryModels,
|
|
8
9
|
parseClaudeModels,
|
|
9
10
|
parseCodexModels,
|