neoagent 2.3.1-beta.110 → 2.3.1-beta.113
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/lib/manager.js +1 -0
- package/package.json +1 -1
- package/server/public/.last_build_id +1 -1
- package/server/public/flutter_bootstrap.js +1 -1
- package/server/public/main.dart.js +4 -4
- package/server/services/ai/providers/claudeCode.js +53 -3
- package/server/services/ai/providers/openaiCodex.js +77 -7
package/lib/manager.js
CHANGED
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
0c62ef7d28ad8b7fe9751b4f055e1afb
|
|
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"42d3d75a56efe1a2e9902f52dc8006099c45d9
|
|
|
37
37
|
|
|
38
38
|
_flutter.loader.load({
|
|
39
39
|
serviceWorkerSettings: {
|
|
40
|
-
serviceWorkerVersion: "
|
|
40
|
+
serviceWorkerVersion: "699610273" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
|
|
41
41
|
}
|
|
42
42
|
});
|
|
@@ -129338,7 +129338,7 @@ r===$&&A.b()
|
|
|
129338
129338
|
o.push(A.ii(p,A.iY(!1,new A.a3(B.tM,A.dT(new A.cI(B.he,new A.a5V(r,p),p),p,p),p),!1,B.I,!0),p,p,0,0,0,p))}r=!1
|
|
129339
129339
|
if(!s.ay)if(!s.ch){r=s.e
|
|
129340
129340
|
r===$&&A.b()
|
|
129341
|
-
r=B.b.t("
|
|
129341
|
+
r=B.b.t("mpb8ba09-f0b0778").length!==0&&r.b}if(r){r=s.d
|
|
129342
129342
|
r===$&&A.b()
|
|
129343
129343
|
r=r.ag&&!r.V?84:0
|
|
129344
129344
|
q=s.e
|
|
@@ -134146,7 +134146,7 @@ $S:236}
|
|
|
134146
134146
|
A.Ys.prototype={}
|
|
134147
134147
|
A.Rr.prototype={
|
|
134148
134148
|
mT(a){var s=this
|
|
134149
|
-
if(B.b.t("
|
|
134149
|
+
if(B.b.t("mpb8ba09-f0b0778").length===0||s.a!=null)return
|
|
134150
134150
|
s.A5()
|
|
134151
134151
|
s.a=A.q1(B.PP,new A.b58(s))},
|
|
134152
134152
|
A5(){var s=0,r=A.l(t.H),q,p=2,o=[],n=this,m,l,k,j,i,h,g,f
|
|
@@ -134164,7 +134164,7 @@ if(!t.f.b(k)){s=1
|
|
|
134164
134164
|
break}i=J.Z(k,"buildId")
|
|
134165
134165
|
h=i==null?null:B.b.t(J.r(i))
|
|
134166
134166
|
j=h==null?"":h
|
|
134167
|
-
if(J.bm(j)===0||J.d(j,"
|
|
134167
|
+
if(J.bm(j)===0||J.d(j,"mpb8ba09-f0b0778")){s=1
|
|
134168
134168
|
break}n.b=!0
|
|
134169
134169
|
n.D()
|
|
134170
134170
|
p=2
|
|
@@ -134181,7 +134181,7 @@ case 2:return A.i(o.at(-1),r)}})
|
|
|
134181
134181
|
return A.k($async$A5,r)},
|
|
134182
134182
|
vb(){var s=0,r=A.l(t.H),q,p=2,o=[],n=this,m,l,k,j,i,h,g,f,e,d,c,b,a,a0,a1
|
|
134183
134183
|
var $async$vb=A.h(function(a2,a3){if(a2===1){o.push(a3)
|
|
134184
|
-
s=p}for(;;)switch(s){case 0:if(B.b.t("
|
|
134184
|
+
s=p}for(;;)switch(s){case 0:if(B.b.t("mpb8ba09-f0b0778").length===0||n.c){s=1
|
|
134185
134185
|
break}n.c=!0
|
|
134186
134186
|
n.D()
|
|
134187
134187
|
p=4
|
|
@@ -5,19 +5,44 @@ const Anthropic = require('@anthropic-ai/sdk');
|
|
|
5
5
|
const { AnthropicProvider } = require('./anthropic');
|
|
6
6
|
|
|
7
7
|
const CLAUDE_CLI_CREDS_PATH = path.join(os.homedir(), '.claude', '.credentials.json');
|
|
8
|
-
const CLAUDE_CODE_BASE_URL = 'https://api.
|
|
8
|
+
const CLAUDE_CODE_BASE_URL = 'https://api.anthropic.com';
|
|
9
|
+
const CLAUDE_CODE_VERSION = process.env.CLAUDE_CODE_VERSION || '2.1.75';
|
|
10
|
+
const CLAUDE_CODE_OAUTH_BETA = 'claude-code-20250219,oauth-2025-04-20,fine-grained-tool-streaming-2025-05-14';
|
|
11
|
+
const CLAUDE_CODE_SYSTEM_PROMPT = "You are Claude Code, Anthropic's official CLI for Claude.";
|
|
12
|
+
|
|
13
|
+
function readTokenValue(data) {
|
|
14
|
+
return data?.claudeAiOauthTokens?.accessToken
|
|
15
|
+
|| data?.claudeAiOauth?.accessToken
|
|
16
|
+
|| data?.claudeAiOauth?.access
|
|
17
|
+
|| null;
|
|
18
|
+
}
|
|
9
19
|
|
|
10
20
|
function readClaudeCliToken() {
|
|
11
21
|
try {
|
|
12
22
|
const raw = fs.readFileSync(CLAUDE_CLI_CREDS_PATH, 'utf8');
|
|
13
23
|
const data = JSON.parse(raw);
|
|
14
|
-
const token = data
|
|
24
|
+
const token = readTokenValue(data);
|
|
15
25
|
return typeof token === 'string' && token ? token : null;
|
|
16
26
|
} catch {
|
|
17
27
|
return null;
|
|
18
28
|
}
|
|
19
29
|
}
|
|
20
30
|
|
|
31
|
+
function mergeAnthropicBeta(existing) {
|
|
32
|
+
if (!existing) return CLAUDE_CODE_OAUTH_BETA;
|
|
33
|
+
const seen = new Set();
|
|
34
|
+
return String(existing)
|
|
35
|
+
.split(',')
|
|
36
|
+
.concat(CLAUDE_CODE_OAUTH_BETA.split(','))
|
|
37
|
+
.map((item) => item.trim())
|
|
38
|
+
.filter((item) => {
|
|
39
|
+
if (!item || seen.has(item)) return false;
|
|
40
|
+
seen.add(item);
|
|
41
|
+
return true;
|
|
42
|
+
})
|
|
43
|
+
.join(',');
|
|
44
|
+
}
|
|
45
|
+
|
|
21
46
|
class ClaudeCodeProvider extends AnthropicProvider {
|
|
22
47
|
constructor(config = {}) {
|
|
23
48
|
super(config);
|
|
@@ -38,12 +63,37 @@ class ClaudeCodeProvider extends AnthropicProvider {
|
|
|
38
63
|
console.warn('[ClaudeCode] No access token. Run `neoagent login claude-code` to authenticate.');
|
|
39
64
|
}
|
|
40
65
|
|
|
41
|
-
|
|
66
|
+
const defaultHeaders = {
|
|
67
|
+
...(config.defaultHeaders || {}),
|
|
68
|
+
accept: 'application/json',
|
|
69
|
+
'anthropic-dangerous-direct-browser-access': 'true',
|
|
70
|
+
'anthropic-beta': mergeAnthropicBeta(config.defaultHeaders?.['anthropic-beta']),
|
|
71
|
+
'user-agent': `claude-cli/${CLAUDE_CODE_VERSION}`,
|
|
72
|
+
'x-app': 'cli',
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// OAuth tokens use Authorization: Bearer. Claude Code subscription inference
|
|
76
|
+
// also requires the Claude Code beta surface headers used by the official CLI.
|
|
42
77
|
this.client = new Anthropic({
|
|
43
78
|
authToken: authToken || undefined,
|
|
44
79
|
baseURL: config.baseUrl || CLAUDE_CODE_BASE_URL,
|
|
80
|
+
defaultHeaders: authToken ? defaultHeaders : config.defaultHeaders,
|
|
81
|
+
...(config.fetch ? { fetch: config.fetch } : {}),
|
|
45
82
|
});
|
|
46
83
|
}
|
|
84
|
+
|
|
85
|
+
convertMessages(messages) {
|
|
86
|
+
const converted = super.convertMessages(messages);
|
|
87
|
+
if (!converted.system) {
|
|
88
|
+
converted.system = [{ type: 'text', text: CLAUDE_CODE_SYSTEM_PROMPT }];
|
|
89
|
+
return converted;
|
|
90
|
+
}
|
|
91
|
+
converted.system = [
|
|
92
|
+
{ type: 'text', text: CLAUDE_CODE_SYSTEM_PROMPT },
|
|
93
|
+
{ type: 'text', text: converted.system },
|
|
94
|
+
];
|
|
95
|
+
return converted;
|
|
96
|
+
}
|
|
47
97
|
}
|
|
48
98
|
|
|
49
99
|
module.exports = { ClaudeCodeProvider, readClaudeCliToken };
|
|
@@ -3,6 +3,14 @@ const OpenAI = require('openai');
|
|
|
3
3
|
const { BaseProvider } = require('./base');
|
|
4
4
|
|
|
5
5
|
const DEFAULT_BASE_URL = 'https://chatgpt.com/backend-api/codex';
|
|
6
|
+
const OPENAI_CODEX_EMPTY_INPUT_TEXT = ' ';
|
|
7
|
+
const NEOAGENT_VERSION = (() => {
|
|
8
|
+
try {
|
|
9
|
+
return require('../../../../package.json').version || 'unknown';
|
|
10
|
+
} catch {
|
|
11
|
+
return 'unknown';
|
|
12
|
+
}
|
|
13
|
+
})();
|
|
6
14
|
|
|
7
15
|
// Stable per-process installation ID — Codex backend uses it for request tracking.
|
|
8
16
|
const INSTALLATION_ID = crypto.randomUUID();
|
|
@@ -26,7 +34,7 @@ function isCodexBackendBaseUrl(baseURL) {
|
|
|
26
34
|
const url = new URL(trimmed);
|
|
27
35
|
const path = url.pathname.replace(/\/+$/, '');
|
|
28
36
|
return url.hostname === 'chatgpt.com'
|
|
29
|
-
&& (path === '/backend-api' || path === '/backend-api/codex' || path === '/backend-api/codex/v1');
|
|
37
|
+
&& (path === '/backend-api' || path === '/backend-api/v1' || path === '/backend-api/codex' || path === '/backend-api/codex/v1');
|
|
30
38
|
} catch {
|
|
31
39
|
return false;
|
|
32
40
|
}
|
|
@@ -52,6 +60,10 @@ function normalizeCodexBaseUrl(baseURL) {
|
|
|
52
60
|
return baseURL;
|
|
53
61
|
}
|
|
54
62
|
|
|
63
|
+
function isNativeCodexResponsesBaseUrl(baseURL) {
|
|
64
|
+
return isCodexBackendBaseUrl(baseURL);
|
|
65
|
+
}
|
|
66
|
+
|
|
55
67
|
function normalizeContent(content) {
|
|
56
68
|
if (content == null) return '';
|
|
57
69
|
if (typeof content === 'string') return content;
|
|
@@ -211,11 +223,9 @@ class OpenAICodexProvider extends BaseProvider {
|
|
|
211
223
|
|
|
212
224
|
const defaultHeaders = this.usesCodexBackend
|
|
213
225
|
? {
|
|
214
|
-
|
|
215
|
-
'
|
|
216
|
-
'User-Agent':
|
|
217
|
-
// Required by the Codex responses endpoint
|
|
218
|
-
'OpenAI-Beta': 'responses_websockets=2026-02-06',
|
|
226
|
+
'originator': 'openclaw',
|
|
227
|
+
'version': NEOAGENT_VERSION,
|
|
228
|
+
'User-Agent': `openclaw/${NEOAGENT_VERSION}`,
|
|
219
229
|
'x-codex-installation-id': INSTALLATION_ID,
|
|
220
230
|
'x-openai-internal-codex-residency': process.env.OPENAI_CODEX_RESIDENCY || 'us',
|
|
221
231
|
...(accountId ? { 'ChatGPT-Account-Id': accountId } : {}),
|
|
@@ -226,6 +236,7 @@ class OpenAICodexProvider extends BaseProvider {
|
|
|
226
236
|
apiKey: config.apiKey || process.env.OPENAI_CODEX_ACCESS_TOKEN,
|
|
227
237
|
baseURL,
|
|
228
238
|
defaultHeaders,
|
|
239
|
+
...(config.fetch ? { fetch: config.fetch } : {}),
|
|
229
240
|
});
|
|
230
241
|
}
|
|
231
242
|
|
|
@@ -297,6 +308,13 @@ class OpenAICodexProvider extends BaseProvider {
|
|
|
297
308
|
};
|
|
298
309
|
|
|
299
310
|
if (this.usesCodexBackend) {
|
|
311
|
+
if (input.length === 0 && instructions.length > 0) {
|
|
312
|
+
input.push({
|
|
313
|
+
type: 'message',
|
|
314
|
+
role: 'user',
|
|
315
|
+
content: [{ type: 'input_text', text: OPENAI_CODEX_EMPTY_INPUT_TEXT }],
|
|
316
|
+
});
|
|
317
|
+
}
|
|
300
318
|
// instructions must always be present (even empty) — backend returns 400 if omitted
|
|
301
319
|
request.instructions = instructions.join('\n\n');
|
|
302
320
|
request.store = false;
|
|
@@ -315,6 +333,7 @@ class OpenAICodexProvider extends BaseProvider {
|
|
|
315
333
|
request.reasoning = { effort, summary: 'auto' };
|
|
316
334
|
request.include = ['reasoning.encrypted_content'];
|
|
317
335
|
}
|
|
336
|
+
this._sanitizeNativeCodexRequest(request);
|
|
318
337
|
} else {
|
|
319
338
|
if (instructions.length > 0) {
|
|
320
339
|
request.instructions = instructions.join('\n\n');
|
|
@@ -337,12 +356,63 @@ class OpenAICodexProvider extends BaseProvider {
|
|
|
337
356
|
}
|
|
338
357
|
|
|
339
358
|
_requestHeaders() {
|
|
359
|
+
const requestId = crypto.randomUUID();
|
|
340
360
|
return this.usesCodexBackend
|
|
341
|
-
? {
|
|
361
|
+
? {
|
|
362
|
+
'x-client-request-id': requestId,
|
|
363
|
+
'x-openclaw-session-id': requestId,
|
|
364
|
+
'x-openclaw-turn-id': requestId,
|
|
365
|
+
'x-openclaw-turn-attempt': '1',
|
|
366
|
+
}
|
|
342
367
|
: undefined;
|
|
343
368
|
}
|
|
344
369
|
|
|
370
|
+
_sanitizeNativeCodexRequest(request) {
|
|
371
|
+
if (!isNativeCodexResponsesBaseUrl(this.baseURL)) return request;
|
|
372
|
+
for (const key of [
|
|
373
|
+
'max_output_tokens',
|
|
374
|
+
'metadata',
|
|
375
|
+
'prompt_cache_retention',
|
|
376
|
+
'service_tier',
|
|
377
|
+
'temperature',
|
|
378
|
+
'top_p',
|
|
379
|
+
]) {
|
|
380
|
+
delete request[key];
|
|
381
|
+
}
|
|
382
|
+
if (request.text && typeof request.text === 'object' && !Array.isArray(request.text)) {
|
|
383
|
+
const text = { ...request.text };
|
|
384
|
+
delete text.format;
|
|
385
|
+
if (Object.keys(text).length > 0) {
|
|
386
|
+
request.text = text;
|
|
387
|
+
} else {
|
|
388
|
+
delete request.text;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return request;
|
|
392
|
+
}
|
|
393
|
+
|
|
345
394
|
async chat(messages, tools = [], options = {}) {
|
|
395
|
+
if (this.usesCodexBackend) {
|
|
396
|
+
let final = null;
|
|
397
|
+
let content = '';
|
|
398
|
+
for await (const event of this.stream(messages, tools, options)) {
|
|
399
|
+
if (event.type === 'content') {
|
|
400
|
+
content += event.content || '';
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
if (event.type === 'tool_calls' || event.type === 'done') {
|
|
404
|
+
final = event;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return {
|
|
408
|
+
content: final?.content || content,
|
|
409
|
+
toolCalls: final?.toolCalls || [],
|
|
410
|
+
finishReason: final?.finishReason || (final?.toolCalls?.length > 0 ? 'tool_calls' : 'stop'),
|
|
411
|
+
usage: final?.usage || null,
|
|
412
|
+
model: final?.model || options.model || this.config.model || this.getDefaultModel(),
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
|
|
346
416
|
const model = options.model || this.config.model || this.getDefaultModel();
|
|
347
417
|
const request = this._buildRequest(messages, tools, options, model);
|
|
348
418
|
let response;
|