@galaxy-yearn/codex-deepseek-gateway 0.1.7 → 0.2.1
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/README.md +57 -37
- package/README.zh-CN.md +213 -0
- package/config/codex-model-catalog.json +32 -28
- package/config/codex-model-catalog.zh.json +36 -32
- package/package.json +2 -1
- package/src/codex-launch.js +30 -8
- package/src/codex-sessions.js +69 -13
- package/src/common.js +18 -3
- package/src/config.js +13 -2
- package/src/firecrawl.js +15 -19
- package/src/model-map.js +6 -20
- package/src/protocol.js +1395 -572
- package/src/reasoning-cache.js +235 -0
- package/src/server.js +525 -378
- package/src/tavily.js +2 -11
- package/src/upstream.js +14 -12
- package/src/web-search-emulator.js +15 -16
- package/state/reasoning-cache.example.jsonl +1 -0
- package/src/session-store.js +0 -67
package/src/codex-sessions.js
CHANGED
|
@@ -21,12 +21,16 @@ import {
|
|
|
21
21
|
withPickerScreen,
|
|
22
22
|
} from './codex-launch.js';
|
|
23
23
|
|
|
24
|
-
const TIME_WIDTH =
|
|
24
|
+
const TIME_WIDTH = 11;
|
|
25
25
|
const PROVIDER_WIDTH = 17;
|
|
26
|
-
const
|
|
27
|
-
const TITLE_WIDTH = 16;
|
|
26
|
+
const TITLE_WIDTH = 32;
|
|
28
27
|
const TABLE_INDENT = ' ';
|
|
29
28
|
const COLUMN_GAP = ' ';
|
|
29
|
+
const MUTED_TEXT = '\x1b[90m';
|
|
30
|
+
const RESET_STYLE = '\x1b[0m';
|
|
31
|
+
const GRAPHEME_SEGMENTER = new Intl.Segmenter(undefined, { granularity: 'grapheme' });
|
|
32
|
+
const EXTENDED_PICTOGRAPHIC = /\p{Extended_Pictographic}/u;
|
|
33
|
+
const MARK = /\p{Mark}/u;
|
|
30
34
|
export const DEFAULT_SESSION_LIMIT = 15;
|
|
31
35
|
|
|
32
36
|
function print(message = '') {
|
|
@@ -136,12 +140,60 @@ function firstUserPreview(lines) {
|
|
|
136
140
|
return '';
|
|
137
141
|
}
|
|
138
142
|
|
|
143
|
+
function isWideCodePoint(codePoint) {
|
|
144
|
+
return codePoint >= 0x1100 && (
|
|
145
|
+
codePoint <= 0x115f
|
|
146
|
+
|| codePoint === 0x2329
|
|
147
|
+
|| codePoint === 0x232a
|
|
148
|
+
|| (codePoint >= 0x2e80 && codePoint <= 0x303e)
|
|
149
|
+
|| (codePoint >= 0x3040 && codePoint <= 0xa4cf)
|
|
150
|
+
|| (codePoint >= 0xac00 && codePoint <= 0xd7a3)
|
|
151
|
+
|| (codePoint >= 0xf900 && codePoint <= 0xfaff)
|
|
152
|
+
|| (codePoint >= 0xfe10 && codePoint <= 0xfe19)
|
|
153
|
+
|| (codePoint >= 0xfe30 && codePoint <= 0xfe6f)
|
|
154
|
+
|| (codePoint >= 0xff00 && codePoint <= 0xff60)
|
|
155
|
+
|| (codePoint >= 0xffe0 && codePoint <= 0xffe6)
|
|
156
|
+
|| (codePoint >= 0x1b000 && codePoint <= 0x1b2ff)
|
|
157
|
+
|| (codePoint >= 0x1f1e6 && codePoint <= 0x1f1ff)
|
|
158
|
+
|| (codePoint >= 0x1f200 && codePoint <= 0x1f251)
|
|
159
|
+
|| (codePoint >= 0x20000 && codePoint <= 0x3fffd)
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function graphemeWidth(grapheme) {
|
|
164
|
+
const characters = [...grapheme];
|
|
165
|
+
const visible = characters.filter((character) => {
|
|
166
|
+
const codePoint = character.codePointAt(0);
|
|
167
|
+
return codePoint !== 0x200d && codePoint !== 0xfe0e && codePoint !== 0xfe0f && !MARK.test(character);
|
|
168
|
+
});
|
|
169
|
+
if (!visible.length) return 0;
|
|
170
|
+
return characters.some((character) => isWideCodePoint(character.codePointAt(0)) || EXTENDED_PICTOGRAPHIC.test(character)) ? 2 : 1;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function displayWidth(text) {
|
|
174
|
+
let width = 0;
|
|
175
|
+
for (const { segment } of GRAPHEME_SEGMENTER.segment(String(text))) width += graphemeWidth(segment);
|
|
176
|
+
return width;
|
|
177
|
+
}
|
|
178
|
+
|
|
139
179
|
function truncate(text, max) {
|
|
140
|
-
|
|
180
|
+
const value = String(text);
|
|
181
|
+
if (displayWidth(value) <= max) return value;
|
|
182
|
+
const contentWidth = max - 3;
|
|
183
|
+
let result = '';
|
|
184
|
+
let width = 0;
|
|
185
|
+
for (const { segment } of GRAPHEME_SEGMENTER.segment(value)) {
|
|
186
|
+
const nextWidth = graphemeWidth(segment);
|
|
187
|
+
if (width + nextWidth > contentWidth) break;
|
|
188
|
+
result += segment;
|
|
189
|
+
width += nextWidth;
|
|
190
|
+
}
|
|
191
|
+
return `${result}...`;
|
|
141
192
|
}
|
|
142
193
|
|
|
143
194
|
function pad(text, width) {
|
|
144
|
-
|
|
195
|
+
const value = truncate(String(text || ''), width);
|
|
196
|
+
return `${value}${' '.repeat(width - displayWidth(value))}`;
|
|
145
197
|
}
|
|
146
198
|
|
|
147
199
|
function formatTime(value) {
|
|
@@ -190,11 +242,14 @@ function printSessions(sessionsList, options, context) {
|
|
|
190
242
|
print(`Codex sessions ${options.all ? `under ${context.codexHome}` : `for project ${context.projectRoot}`}\n`);
|
|
191
243
|
print(`Target: ${context.provider} / ${context.model} / ${context.reasoningEffort}\n\n`);
|
|
192
244
|
if (!listed.length) {
|
|
193
|
-
print('No matching sessions found.\n');
|
|
245
|
+
print(' No matching sessions found.\n');
|
|
194
246
|
return;
|
|
195
247
|
}
|
|
196
|
-
|
|
197
|
-
|
|
248
|
+
const header = sessionHeader();
|
|
249
|
+
const divider = '─'.repeat(displayWidth(header));
|
|
250
|
+
const styledDivider = process.stdout.isTTY ? `${MUTED_TEXT}${divider}${RESET_STYLE}` : divider;
|
|
251
|
+
print(`${TABLE_INDENT}${header}\n`);
|
|
252
|
+
print(`${TABLE_INDENT}${styledDivider}\n`);
|
|
198
253
|
listed.forEach((session, index) => {
|
|
199
254
|
print(`${String(index + 1).padStart(2, ' ')} ${sessionRow(session)}\n`);
|
|
200
255
|
if (options.all) print(` cwd: ${session.cwd || '(unknown cwd)'}\n`);
|
|
@@ -204,11 +259,11 @@ function printSessions(sessionsList, options, context) {
|
|
|
204
259
|
}
|
|
205
260
|
|
|
206
261
|
function sessionHeader() {
|
|
207
|
-
return `${pad('Date', TIME_WIDTH)}${COLUMN_GAP}${pad('Provider', PROVIDER_WIDTH)}${COLUMN_GAP}${pad('
|
|
262
|
+
return `${pad('Date', TIME_WIDTH)}${COLUMN_GAP}${pad('Provider', PROVIDER_WIDTH)}${COLUMN_GAP}${pad('Title', TITLE_WIDTH)}`;
|
|
208
263
|
}
|
|
209
264
|
|
|
210
265
|
function sessionRow(session) {
|
|
211
|
-
return `${pad(formatTime(session.updatedAt), TIME_WIDTH)}${COLUMN_GAP}${pad(session.provider || '(unknown)', PROVIDER_WIDTH)}${COLUMN_GAP}${
|
|
266
|
+
return `${pad(formatTime(session.updatedAt), TIME_WIDTH)}${COLUMN_GAP}${pad(session.provider || '(unknown)', PROVIDER_WIDTH)}${COLUMN_GAP}${pad(session.title, TITLE_WIDTH)}`;
|
|
212
267
|
}
|
|
213
268
|
|
|
214
269
|
function sessionRows(sessionsList) {
|
|
@@ -238,7 +293,7 @@ async function chooseSessionFlow(allSessions, context, limit) {
|
|
|
238
293
|
{
|
|
239
294
|
windowSize,
|
|
240
295
|
emptyMessage: 'No matching sessions found.',
|
|
241
|
-
shortcuts: [{ key: 'n', action: 'new', label: '
|
|
296
|
+
shortcuts: [{ key: 'n', displayKey: 'N', action: 'new', label: 'new' }],
|
|
242
297
|
},
|
|
243
298
|
);
|
|
244
299
|
if (result.action === 'cancel') return null;
|
|
@@ -247,8 +302,9 @@ async function chooseSessionFlow(allSessions, context, limit) {
|
|
|
247
302
|
step = 'model';
|
|
248
303
|
} else if (step === 'model') {
|
|
249
304
|
const action = await pickModel(context);
|
|
250
|
-
if (action
|
|
251
|
-
step = '
|
|
305
|
+
if (action === 'cancel') return null;
|
|
306
|
+
if (action === 'back') step = 'session';
|
|
307
|
+
else step = 'reasoning';
|
|
252
308
|
} else if (step === 'reasoning') {
|
|
253
309
|
const action = await pickReasoning(context);
|
|
254
310
|
if (action === 'cancel') return null;
|
package/src/common.js
CHANGED
|
@@ -9,7 +9,7 @@ export function generateId(prefix) {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export function normalizeRole(role, provider = 'generic') {
|
|
12
|
-
if (role === 'developer') return 'system';
|
|
12
|
+
if (provider === 'deepseek' && role === 'developer') return 'system';
|
|
13
13
|
return role || 'user';
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -63,10 +63,10 @@ export function mapDeepSeekReasoningEffort(effort) {
|
|
|
63
63
|
if (!effort) return undefined;
|
|
64
64
|
const normalized = String(effort).toLowerCase().replaceAll('_', '-');
|
|
65
65
|
if (normalized === 'low') return undefined;
|
|
66
|
-
if (normalized === 'none' || normalized === 'disabled' || normalized === 'off') return undefined;
|
|
66
|
+
if (normalized === 'none' || normalized === 'disabled' || normalized === 'off' || normalized === 'false') return undefined;
|
|
67
67
|
if (normalized === 'xhigh' || normalized === 'max') return 'max';
|
|
68
68
|
if (normalized === 'medium' || normalized === 'high') return 'high';
|
|
69
|
-
return
|
|
69
|
+
return undefined;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
export function joinUrl(baseUrl, path) {
|
|
@@ -139,3 +139,18 @@ export function safeJsonParse(text) {
|
|
|
139
139
|
return { ok: false, error };
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
|
+
|
|
143
|
+
export function parseJsonObject(value, { source = 'JSON value', throwOnInvalid = false } = {}) {
|
|
144
|
+
if (isObject(value)) return value;
|
|
145
|
+
if (!value || typeof value !== 'string') {
|
|
146
|
+
if (throwOnInvalid && value) throw new Error(`${source} must be a JSON object`);
|
|
147
|
+
return {};
|
|
148
|
+
}
|
|
149
|
+
const parsed = safeJsonParse(value);
|
|
150
|
+
if (parsed.ok && isObject(parsed.value)) return parsed.value;
|
|
151
|
+
if (throwOnInvalid) {
|
|
152
|
+
if (parsed.ok) throw new Error(`${source} must be a JSON object`);
|
|
153
|
+
throw parsed.error;
|
|
154
|
+
}
|
|
155
|
+
return {};
|
|
156
|
+
}
|
package/src/config.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { dirname, resolve } from 'node:path';
|
|
1
2
|
import { loadModelAliases } from './model-map.js';
|
|
2
3
|
import { mergeLocalConfig, readLocalConfigFile, resolveLocalConfigPath } from './local-config.js';
|
|
3
4
|
import { parseBoolean, parseList } from './common.js';
|
|
@@ -5,8 +6,10 @@ import { readCodexConfig } from './codex-config.js';
|
|
|
5
6
|
import { normalizePromptLanguage } from './prompt-language.js';
|
|
6
7
|
|
|
7
8
|
export function loadConfig(env = process.env) {
|
|
9
|
+
const localConfigPath = resolveLocalConfigPath(env);
|
|
10
|
+
const stateDir = resolve(dirname(localConfigPath), '..', 'state');
|
|
8
11
|
const mergedEnv = mergeLocalConfig(env);
|
|
9
|
-
const localConfig = readLocalConfigFile(
|
|
12
|
+
const localConfig = readLocalConfigFile(localConfigPath);
|
|
10
13
|
const codexConfig = readCodexConfig(mergedEnv);
|
|
11
14
|
return {
|
|
12
15
|
port: Number(mergedEnv.PORT || 3000),
|
|
@@ -16,18 +19,26 @@ export function loadConfig(env = process.env) {
|
|
|
16
19
|
upstreamModel: mergedEnv.UPSTREAM_MODEL || '',
|
|
17
20
|
upstreamProvider: mergedEnv.UPSTREAM_PROVIDER || 'deepseek',
|
|
18
21
|
upstreamTimeoutMs: Number(mergedEnv.UPSTREAM_TIMEOUT_MS || 120000),
|
|
22
|
+
upstreamMaxTokens: Number(mergedEnv.UPSTREAM_MAX_TOKENS || mergedEnv.DEEPSEEK_MAX_TOKENS || 0),
|
|
19
23
|
upstreamModels: parseList(mergedEnv.UPSTREAM_MODELS || mergedEnv.MODELS),
|
|
20
24
|
fetchUpstreamModels: parseBoolean(mergedEnv.FETCH_UPSTREAM_MODELS, false),
|
|
21
25
|
modelsTimeoutMs: Number(mergedEnv.MODELS_TIMEOUT_MS || 5000),
|
|
22
26
|
modelsCacheMs: Number(mergedEnv.MODELS_CACHE_MS || 60000),
|
|
23
27
|
proxyApiKey: mergedEnv.PROXY_API_KEY || '',
|
|
24
28
|
debugPayload: parseBoolean(mergedEnv.DEBUG_PAYLOAD || mergedEnv.DEBUG_DEEPSEEK_PAYLOAD, false),
|
|
29
|
+
debugPayloadLogPath: mergedEnv.DEBUG_PAYLOAD_LOG_PATH || 'gateway.debug.log',
|
|
30
|
+
reasoningCacheEnabled: parseBoolean(mergedEnv.REASONING_CACHE_ENABLED, true),
|
|
31
|
+
reasoningCachePath: mergedEnv.REASONING_CACHE_PATH || resolve(stateDir, 'reasoning-cache.jsonl'),
|
|
32
|
+
reasoningCacheMaxMessages: Number(mergedEnv.REASONING_CACHE_MAX_MESSAGES || 1000),
|
|
33
|
+
reasoningCacheMaxBytes: Number(mergedEnv.REASONING_CACHE_MAX_BYTES || 0),
|
|
34
|
+
legacyReasoningCachePath: resolve(stateDir, 'sessions.json'),
|
|
35
|
+
debugPayloadLogMaxBytes: Number(mergedEnv.DEBUG_PAYLOAD_LOG_MAX_BYTES || 0),
|
|
25
36
|
tavilyWebSearchEnabled: parseBoolean(mergedEnv.TAVILY_WEB_SEARCH_ENABLED ?? mergedEnv.ENABLE_TAVILY_WEB_SEARCH, false),
|
|
26
37
|
tavilyApiKey: mergedEnv.TAVILY_API_KEY || '',
|
|
27
38
|
tavilyBaseUrl: mergedEnv.TAVILY_BASE_URL || 'https://api.tavily.com',
|
|
28
39
|
tavilySearchDepth: mergedEnv.TAVILY_SEARCH_DEPTH || 'basic',
|
|
29
40
|
tavilyMaxResults: Number(mergedEnv.TAVILY_MAX_RESULTS || 5),
|
|
30
|
-
tavilyMaxSearchRounds: Number(mergedEnv.TAVILY_MAX_SEARCH_ROUNDS ||
|
|
41
|
+
tavilyMaxSearchRounds: Number(mergedEnv.TAVILY_MAX_SEARCH_ROUNDS || 20),
|
|
31
42
|
tavilyTimeoutMs: Number(mergedEnv.TAVILY_TIMEOUT_MS || 15000),
|
|
32
43
|
tavilySnippetChars: Number(mergedEnv.TAVILY_SNIPPET_CHARS || 650),
|
|
33
44
|
tavilyResultMaxChars: Number(mergedEnv.TAVILY_RESULT_MAX_CHARS || 6000),
|
package/src/firecrawl.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isIP } from 'node:net';
|
|
2
|
+
import { isObject, joinUrl, parseBoolean, safeJsonParse } from './common.js';
|
|
2
3
|
|
|
3
4
|
const DEFAULT_TOTAL_CHARS = 12000;
|
|
4
5
|
const DEFAULT_PAGE_CHARS = 5000;
|
|
@@ -26,15 +27,6 @@ function clampInteger(value, min, max, fallback) {
|
|
|
26
27
|
return Math.min(max, Math.max(min, Math.trunc(number)));
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
function booleanValue(value, fallback) {
|
|
30
|
-
if (typeof value === 'boolean') return value;
|
|
31
|
-
if (value == null || value === '') return fallback;
|
|
32
|
-
const normalized = String(value).trim().toLowerCase();
|
|
33
|
-
if (['1', 'true', 'yes', 'on'].includes(normalized)) return true;
|
|
34
|
-
if (['0', 'false', 'no', 'off'].includes(normalized)) return false;
|
|
35
|
-
return fallback;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
30
|
function cleanText(value, maxChars = DEFAULT_PAGE_CHARS) {
|
|
39
31
|
if (value == null) return '';
|
|
40
32
|
const text = String(value)
|
|
@@ -79,16 +71,20 @@ function isPrivateIpv4(hostname) {
|
|
|
79
71
|
return PRIVATE_IPV4_RANGES.some(([start, end]) => number >= start && number <= end);
|
|
80
72
|
}
|
|
81
73
|
|
|
74
|
+
function isPrivateIpv6(hostname) {
|
|
75
|
+
const host = normalizedHostname(hostname);
|
|
76
|
+
if (isIP(host) !== 6) return false;
|
|
77
|
+
return host === '::1' || host === '0:0:0:0:0:0:0:1' || host.startsWith('fe80:') || host.startsWith('fc') || host.startsWith('fd');
|
|
78
|
+
}
|
|
79
|
+
|
|
82
80
|
function isBlockedHostname(hostname, config = {}) {
|
|
83
81
|
const host = normalizedHostname(hostname);
|
|
84
82
|
if (!host) return true;
|
|
85
|
-
const allowLocal =
|
|
83
|
+
const allowLocal = parseBoolean(config.firecrawlAllowPrivateUrls, false);
|
|
86
84
|
if (allowLocal) return false;
|
|
87
85
|
if (host === 'localhost' || host.endsWith('.localhost')) return true;
|
|
88
86
|
if (host === 'metadata.google.internal') return true;
|
|
89
|
-
|
|
90
|
-
if (host.startsWith('fe80:') || host.startsWith('fc') || host.startsWith('fd')) return true;
|
|
91
|
-
return isPrivateIpv4(host);
|
|
87
|
+
return isPrivateIpv4(host) || isPrivateIpv6(host);
|
|
92
88
|
}
|
|
93
89
|
|
|
94
90
|
export function normalizeFirecrawlUrl(value, config = {}) {
|
|
@@ -127,10 +123,10 @@ function normalizeFormats(args = {}, config = {}) {
|
|
|
127
123
|
.map((format) => format.toLowerCase())
|
|
128
124
|
.filter((format) => ['markdown', 'links', 'summary', 'changeTracking'].includes(format));
|
|
129
125
|
if (!formats.includes('markdown')) formats.unshift('markdown');
|
|
130
|
-
if (
|
|
126
|
+
if (parseBoolean(args.include_links ?? args.includeLinks ?? config.firecrawlIncludeLinks, true) && !formats.includes('links')) {
|
|
131
127
|
formats.push('links');
|
|
132
128
|
}
|
|
133
|
-
if (
|
|
129
|
+
if (parseBoolean(args.include_summary ?? args.includeSummary ?? config.firecrawlIncludeSummary, false) && !formats.includes('summary')) {
|
|
134
130
|
formats.push('summary');
|
|
135
131
|
}
|
|
136
132
|
return [...new Set(formats)];
|
|
@@ -163,14 +159,14 @@ export function buildFirecrawlScrapeRequest(args = {}, config = {}) {
|
|
|
163
159
|
const body = {
|
|
164
160
|
url: normalizedUrl.url,
|
|
165
161
|
formats: normalizeFormats(source, config),
|
|
166
|
-
onlyMainContent:
|
|
167
|
-
removeBase64Images:
|
|
162
|
+
onlyMainContent: parseBoolean(source.only_main_content ?? source.onlyMainContent ?? config.firecrawlOnlyMainContent, true),
|
|
163
|
+
removeBase64Images: parseBoolean(source.remove_base64_images ?? source.removeBase64Images ?? config.firecrawlRemoveBase64Images, true),
|
|
168
164
|
waitFor: clampInteger(source.wait_for ?? source.waitFor ?? config.firecrawlWaitForMs, 0, 10000, 0),
|
|
169
165
|
timeout: clampInteger(source.timeout ?? config.firecrawlTimeoutMs, 1000, 120000, 30000),
|
|
170
166
|
};
|
|
171
167
|
if (!body.waitFor) delete body.waitFor;
|
|
172
168
|
const mobile = source.mobile ?? config.firecrawlMobile;
|
|
173
|
-
if (mobile !== undefined && mobile !== '') body.mobile =
|
|
169
|
+
if (mobile !== undefined && mobile !== '') body.mobile = parseBoolean(mobile, false);
|
|
174
170
|
|
|
175
171
|
return {
|
|
176
172
|
ok: true,
|
package/src/model-map.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
|
-
import { isObject, mapDeepSeekReasoningEffort } from './common.js';
|
|
3
|
+
import { isObject, mapDeepSeekReasoningEffort, parseJsonObject } from './common.js';
|
|
4
4
|
|
|
5
5
|
const DEEPSEEK_V4_MODELS = ['deepseek-v4-flash', 'deepseek-v4-pro'];
|
|
6
6
|
const DEPRECATED_MODEL_PATTERN = /^deepseek-(?:chat|reasoner)$/;
|
|
@@ -15,25 +15,16 @@ function deepseekV4Aliases() {
|
|
|
15
15
|
|
|
16
16
|
export const DEFAULT_MODEL_ALIASES = deepseekV4Aliases();
|
|
17
17
|
|
|
18
|
-
function parseJsonObject(value, source) {
|
|
19
|
-
if (!value) return {};
|
|
20
|
-
const parsed = JSON.parse(value);
|
|
21
|
-
if (!isObject(parsed)) {
|
|
22
|
-
throw new Error(`${source} must be a JSON object`);
|
|
23
|
-
}
|
|
24
|
-
return parsed;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
18
|
function readJsonFile(filePath) {
|
|
28
19
|
if (!filePath || !existsSync(filePath)) return {};
|
|
29
|
-
return parseJsonObject(readFileSync(filePath, 'utf8'), filePath);
|
|
20
|
+
return parseJsonObject(readFileSync(filePath, 'utf8'), { source: filePath, throwOnInvalid: true });
|
|
30
21
|
}
|
|
31
22
|
|
|
32
23
|
export function loadModelAliases(env = process.env, cwd = process.cwd()) {
|
|
33
24
|
const defaultFile = resolve(cwd, 'config', 'model-aliases.json');
|
|
34
25
|
const filePath = env.MODEL_ALIASES_FILE ? resolve(cwd, env.MODEL_ALIASES_FILE) : defaultFile;
|
|
35
26
|
const fileAliases = readJsonFile(filePath);
|
|
36
|
-
const envAliases = parseJsonObject(env.MODEL_ALIASES_JSON, 'MODEL_ALIASES_JSON');
|
|
27
|
+
const envAliases = parseJsonObject(env.MODEL_ALIASES_JSON, { source: 'MODEL_ALIASES_JSON', throwOnInvalid: true });
|
|
37
28
|
return {
|
|
38
29
|
...DEFAULT_MODEL_ALIASES,
|
|
39
30
|
...fileAliases,
|
|
@@ -94,15 +85,10 @@ export function deepseekReasoningPayload({ alias, reasoning } = {}) {
|
|
|
94
85
|
return { thinking: { type: 'disabled' } };
|
|
95
86
|
}
|
|
96
87
|
|
|
97
|
-
const payload = {};
|
|
88
|
+
const payload = { thinking: { type: 'enabled' } };
|
|
98
89
|
const effort = aliasEffort ?? (effortDisablesThinking(requestEffort) ? undefined : requestEffort);
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
if (effort) {
|
|
103
|
-
const reasoningEffort = mapDeepSeekReasoningEffort(effort);
|
|
104
|
-
if (reasoningEffort) payload.reasoning_effort = reasoningEffort;
|
|
105
|
-
}
|
|
90
|
+
const reasoningEffort = mapDeepSeekReasoningEffort(effort);
|
|
91
|
+
if (reasoningEffort) payload.reasoning_effort = reasoningEffort;
|
|
106
92
|
return payload;
|
|
107
93
|
}
|
|
108
94
|
|