neoagent 2.3.1-beta.113 → 2.3.1-beta.114
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/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
d24ae5d149080cae1dd694a9d7d1cca7
|
|
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"42d3d75a56efe1a2e9902f52dc8006099c45d9
|
|
|
37
37
|
|
|
38
38
|
_flutter.loader.load({
|
|
39
39
|
serviceWorkerSettings: {
|
|
40
|
-
serviceWorkerVersion: "
|
|
40
|
+
serviceWorkerVersion: "2783772789" /* 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("mpb91fkt-6e44b2b").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("mpb91fkt-6e44b2b").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,"mpb91fkt-6e44b2b")){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("mpb91fkt-6e44b2b").length===0||n.c){s=1
|
|
134185
134185
|
break}n.c=!0
|
|
134186
134186
|
n.D()
|
|
134187
134187
|
p=4
|
|
@@ -9,25 +9,39 @@ const CLAUDE_CODE_BASE_URL = 'https://api.anthropic.com';
|
|
|
9
9
|
const CLAUDE_CODE_VERSION = process.env.CLAUDE_CODE_VERSION || '2.1.75';
|
|
10
10
|
const CLAUDE_CODE_OAUTH_BETA = 'claude-code-20250219,oauth-2025-04-20,fine-grained-tool-streaming-2025-05-14';
|
|
11
11
|
const CLAUDE_CODE_SYSTEM_PROMPT = "You are Claude Code, Anthropic's official CLI for Claude.";
|
|
12
|
+
const CLAUDE_CODE_CLIENT_ID = '9d1c250a-e61b-44d9-88ed-5944d1962f5e';
|
|
13
|
+
const CLAUDE_CODE_TOKEN_URL = 'https://platform.claude.com/v1/oauth/token';
|
|
14
|
+
|
|
15
|
+
function readTokenRecord(data) {
|
|
16
|
+
const tokens = data?.claudeAiOauthTokens || data?.claudeAiOauth || {};
|
|
17
|
+
const access = tokens.accessToken || tokens.access;
|
|
18
|
+
const refresh = tokens.refreshToken || tokens.refresh;
|
|
19
|
+
const expires = tokens.expiresAt || tokens.expires;
|
|
20
|
+
return {
|
|
21
|
+
access: typeof access === 'string' && access ? access : null,
|
|
22
|
+
refresh: typeof refresh === 'string' && refresh ? refresh : null,
|
|
23
|
+
expires: typeof expires === 'number' && Number.isFinite(expires) ? expires : null,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
12
26
|
|
|
13
27
|
function readTokenValue(data) {
|
|
14
|
-
return data
|
|
15
|
-
|| data?.claudeAiOauth?.accessToken
|
|
16
|
-
|| data?.claudeAiOauth?.access
|
|
17
|
-
|| null;
|
|
28
|
+
return readTokenRecord(data).access;
|
|
18
29
|
}
|
|
19
30
|
|
|
20
|
-
function
|
|
31
|
+
function readClaudeCliTokenRecord() {
|
|
21
32
|
try {
|
|
22
33
|
const raw = fs.readFileSync(CLAUDE_CLI_CREDS_PATH, 'utf8');
|
|
23
34
|
const data = JSON.parse(raw);
|
|
24
|
-
|
|
25
|
-
return typeof token === 'string' && token ? token : null;
|
|
35
|
+
return readTokenRecord(data);
|
|
26
36
|
} catch {
|
|
27
|
-
return null;
|
|
37
|
+
return { access: null, refresh: null, expires: null };
|
|
28
38
|
}
|
|
29
39
|
}
|
|
30
40
|
|
|
41
|
+
function readClaudeCliToken() {
|
|
42
|
+
return readClaudeCliTokenRecord().access;
|
|
43
|
+
}
|
|
44
|
+
|
|
31
45
|
function mergeAnthropicBeta(existing) {
|
|
32
46
|
if (!existing) return CLAUDE_CODE_OAUTH_BETA;
|
|
33
47
|
const seen = new Set();
|
|
@@ -43,6 +57,93 @@ function mergeAnthropicBeta(existing) {
|
|
|
43
57
|
.join(',');
|
|
44
58
|
}
|
|
45
59
|
|
|
60
|
+
function normalizeExpiresAt(data) {
|
|
61
|
+
if (typeof data.expires_at === 'number' && Number.isFinite(data.expires_at)) {
|
|
62
|
+
return data.expires_at > 10_000_000_000 ? data.expires_at : data.expires_at * 1000;
|
|
63
|
+
}
|
|
64
|
+
if (typeof data.expiresAt === 'number' && Number.isFinite(data.expiresAt)) {
|
|
65
|
+
return data.expiresAt > 10_000_000_000 ? data.expiresAt : data.expiresAt * 1000;
|
|
66
|
+
}
|
|
67
|
+
if (typeof data.expires_in === 'number' && Number.isFinite(data.expires_in)) {
|
|
68
|
+
return Date.now() + (data.expires_in * 1000);
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function sanitizeEnvKey(key) {
|
|
74
|
+
return String(key).replace(/[\r\n]/g, '');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function sanitizeEnvValue(value) {
|
|
78
|
+
return String(value).replace(/[\r\n]/g, '');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function persistEnvValue(key, value) {
|
|
82
|
+
if (!value) return;
|
|
83
|
+
try {
|
|
84
|
+
const { ENV_FILE } = require('../../../../runtime/paths');
|
|
85
|
+
const safeKey = sanitizeEnvKey(key);
|
|
86
|
+
const safeValue = sanitizeEnvValue(value);
|
|
87
|
+
const raw = fs.existsSync(ENV_FILE) ? fs.readFileSync(ENV_FILE, 'utf8') : '';
|
|
88
|
+
const lines = raw ? raw.split('\n') : [];
|
|
89
|
+
let replaced = false;
|
|
90
|
+
for (let i = 0; i < lines.length; i++) {
|
|
91
|
+
if (lines[i].startsWith(`${safeKey}=`)) {
|
|
92
|
+
lines[i] = `${safeKey}=${safeValue}`;
|
|
93
|
+
replaced = true;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (!replaced) lines.push(`${safeKey}=${safeValue}`);
|
|
98
|
+
const output = lines.filter((_, idx, arr) => idx !== arr.length - 1 || arr[idx] !== '').join('\n') + '\n';
|
|
99
|
+
fs.mkdirSync(path.dirname(ENV_FILE), { recursive: true });
|
|
100
|
+
fs.writeFileSync(ENV_FILE, output, { mode: 0o600 });
|
|
101
|
+
} catch { }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async function refreshClaudeCodeAccessToken(refreshToken, fetchImpl = fetch) {
|
|
105
|
+
if (!refreshToken) return null;
|
|
106
|
+
const response = await fetchImpl(CLAUDE_CODE_TOKEN_URL, {
|
|
107
|
+
method: 'POST',
|
|
108
|
+
headers: {
|
|
109
|
+
'Content-Type': 'application/json',
|
|
110
|
+
'Accept': 'application/json',
|
|
111
|
+
'anthropic-version': '2023-06-01',
|
|
112
|
+
},
|
|
113
|
+
body: JSON.stringify({
|
|
114
|
+
grant_type: 'refresh_token',
|
|
115
|
+
refresh_token: refreshToken,
|
|
116
|
+
client_id: CLAUDE_CODE_CLIENT_ID,
|
|
117
|
+
}),
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const text = await response.text();
|
|
121
|
+
let data = {};
|
|
122
|
+
try {
|
|
123
|
+
data = text ? JSON.parse(text) : {};
|
|
124
|
+
} catch {
|
|
125
|
+
data = {};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (!response.ok) {
|
|
129
|
+
const detail = data?.error?.message || data?.error_description || data?.error || text || 'Unknown error';
|
|
130
|
+
throw new Error(`Claude Code OAuth refresh failed: HTTP ${response.status} ${detail}`);
|
|
131
|
+
}
|
|
132
|
+
if (!data.access_token) {
|
|
133
|
+
throw new Error('Claude Code OAuth refresh succeeded but no access_token was returned.');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
access: data.access_token,
|
|
138
|
+
refresh: data.refresh_token || refreshToken,
|
|
139
|
+
expires: normalizeExpiresAt(data),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function isAuthenticationError(err) {
|
|
144
|
+
return err?.status === 401 || err?.error?.type === 'authentication_error';
|
|
145
|
+
}
|
|
146
|
+
|
|
46
147
|
class ClaudeCodeProvider extends AnthropicProvider {
|
|
47
148
|
constructor(config = {}) {
|
|
48
149
|
super(config);
|
|
@@ -58,12 +159,17 @@ class ClaudeCodeProvider extends AnthropicProvider {
|
|
|
58
159
|
'claude-haiku-4-5-20251001': 200000,
|
|
59
160
|
};
|
|
60
161
|
|
|
61
|
-
const
|
|
162
|
+
const cliTokenRecord = readClaudeCliTokenRecord();
|
|
163
|
+
const authToken = config.apiKey || process.env.CLAUDE_CODE_OAUTH_TOKEN || cliTokenRecord.access;
|
|
62
164
|
if (!authToken) {
|
|
63
165
|
console.warn('[ClaudeCode] No access token. Run `neoagent login claude-code` to authenticate.');
|
|
64
166
|
}
|
|
65
167
|
|
|
66
|
-
|
|
168
|
+
this.authToken = authToken || null;
|
|
169
|
+
this.refreshToken = config.refreshToken || process.env.CLAUDE_CODE_REFRESH_TOKEN || cliTokenRecord.refresh || null;
|
|
170
|
+
this.fetchImpl = config.fetch || fetch;
|
|
171
|
+
this.baseURL = config.baseUrl || CLAUDE_CODE_BASE_URL;
|
|
172
|
+
this.defaultHeaders = {
|
|
67
173
|
...(config.defaultHeaders || {}),
|
|
68
174
|
accept: 'application/json',
|
|
69
175
|
'anthropic-dangerous-direct-browser-access': 'true',
|
|
@@ -72,16 +178,35 @@ class ClaudeCodeProvider extends AnthropicProvider {
|
|
|
72
178
|
'x-app': 'cli',
|
|
73
179
|
};
|
|
74
180
|
|
|
181
|
+
this.client = this.createClient(this.authToken, config);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
createClient(authToken, config = this.config) {
|
|
75
185
|
// OAuth tokens use Authorization: Bearer. Claude Code subscription inference
|
|
76
186
|
// also requires the Claude Code beta surface headers used by the official CLI.
|
|
77
|
-
|
|
187
|
+
return new Anthropic({
|
|
78
188
|
authToken: authToken || undefined,
|
|
79
|
-
baseURL:
|
|
80
|
-
defaultHeaders: authToken ? defaultHeaders : config.defaultHeaders,
|
|
81
|
-
...(
|
|
189
|
+
baseURL: this.baseURL,
|
|
190
|
+
defaultHeaders: authToken ? this.defaultHeaders : config.defaultHeaders,
|
|
191
|
+
...(this.fetchImpl ? { fetch: this.fetchImpl } : {}),
|
|
82
192
|
});
|
|
83
193
|
}
|
|
84
194
|
|
|
195
|
+
async refreshClient() {
|
|
196
|
+
const refreshed = await refreshClaudeCodeAccessToken(this.refreshToken, this.fetchImpl);
|
|
197
|
+
if (!refreshed?.access) return false;
|
|
198
|
+
this.authToken = refreshed.access;
|
|
199
|
+
this.refreshToken = refreshed.refresh || this.refreshToken;
|
|
200
|
+
process.env.CLAUDE_CODE_OAUTH_TOKEN = this.authToken;
|
|
201
|
+
persistEnvValue('CLAUDE_CODE_OAUTH_TOKEN', this.authToken);
|
|
202
|
+
if (this.refreshToken) {
|
|
203
|
+
process.env.CLAUDE_CODE_REFRESH_TOKEN = this.refreshToken;
|
|
204
|
+
persistEnvValue('CLAUDE_CODE_REFRESH_TOKEN', this.refreshToken);
|
|
205
|
+
}
|
|
206
|
+
this.client = this.createClient(this.authToken);
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
|
|
85
210
|
convertMessages(messages) {
|
|
86
211
|
const converted = super.convertMessages(messages);
|
|
87
212
|
if (!converted.system) {
|
|
@@ -94,6 +219,26 @@ class ClaudeCodeProvider extends AnthropicProvider {
|
|
|
94
219
|
];
|
|
95
220
|
return converted;
|
|
96
221
|
}
|
|
222
|
+
|
|
223
|
+
async chat(messages, tools = [], options = {}) {
|
|
224
|
+
try {
|
|
225
|
+
return await super.chat(messages, tools, options);
|
|
226
|
+
} catch (err) {
|
|
227
|
+
if (!isAuthenticationError(err) || !this.refreshToken) throw err;
|
|
228
|
+
await this.refreshClient();
|
|
229
|
+
return await super.chat(messages, tools, options);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async *stream(messages, tools = [], options = {}) {
|
|
234
|
+
try {
|
|
235
|
+
yield* super.stream(messages, tools, options);
|
|
236
|
+
} catch (err) {
|
|
237
|
+
if (!isAuthenticationError(err) || !this.refreshToken) throw err;
|
|
238
|
+
await this.refreshClient();
|
|
239
|
+
yield* super.stream(messages, tools, options);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
97
242
|
}
|
|
98
243
|
|
|
99
|
-
module.exports = { ClaudeCodeProvider, readClaudeCliToken };
|
|
244
|
+
module.exports = { ClaudeCodeProvider, readClaudeCliToken, refreshClaudeCodeAccessToken };
|
|
@@ -79,33 +79,45 @@ function normalizeContent(content) {
|
|
|
79
79
|
return String(content);
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
function
|
|
82
|
+
function normalizeMessageContent(content, role = 'user') {
|
|
83
83
|
if (content == null) return [];
|
|
84
|
+
const isAssistant = role === 'assistant';
|
|
85
|
+
const textType = isAssistant ? 'output_text' : 'input_text';
|
|
84
86
|
|
|
85
87
|
if (typeof content === 'string') {
|
|
86
|
-
return [{ type:
|
|
88
|
+
return [{ type: textType, text: content, ...(isAssistant ? { annotations: [] } : {}) }];
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
if (!Array.isArray(content)) {
|
|
90
92
|
const text = String(content);
|
|
91
|
-
return text ? [{ type:
|
|
93
|
+
return text ? [{ type: textType, text, ...(isAssistant ? { annotations: [] } : {}) }] : [];
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
const parts = [];
|
|
95
97
|
for (const part of content) {
|
|
96
98
|
if (!part) continue;
|
|
97
99
|
if (typeof part === 'string') {
|
|
98
|
-
if (part.trim()) parts.push({ type:
|
|
100
|
+
if (part.trim()) parts.push({ type: textType, text: part, ...(isAssistant ? { annotations: [] } : {}) });
|
|
99
101
|
continue;
|
|
100
102
|
}
|
|
101
103
|
if (part.type === 'text' && typeof part.text === 'string') {
|
|
102
|
-
parts.push({ type:
|
|
104
|
+
parts.push({ type: textType, text: part.text, ...(isAssistant ? { annotations: [] } : {}) });
|
|
103
105
|
continue;
|
|
104
106
|
}
|
|
105
107
|
if (part.type === 'input_text' && typeof part.text === 'string') {
|
|
106
|
-
parts.push({ type:
|
|
108
|
+
parts.push({ type: textType, text: part.text, ...(isAssistant ? { annotations: [] } : {}) });
|
|
107
109
|
continue;
|
|
108
110
|
}
|
|
111
|
+
if (part.type === 'output_text' && typeof part.text === 'string') {
|
|
112
|
+
parts.push({ type: textType, text: part.text, ...(isAssistant ? { annotations: part.annotations || [] } : {}) });
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (isAssistant && part.type === 'refusal') {
|
|
116
|
+
const refusal = typeof part.refusal === 'string' ? part.refusal : part.text;
|
|
117
|
+
if (typeof refusal === 'string') parts.push({ type: 'refusal', refusal });
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (isAssistant) continue;
|
|
109
121
|
if (part.type === 'image_url') {
|
|
110
122
|
const imageUrl = typeof part.image_url === 'string' ? part.image_url : part.image_url?.url;
|
|
111
123
|
if (imageUrl) {
|
|
@@ -278,11 +290,12 @@ class OpenAICodexProvider extends BaseProvider {
|
|
|
278
290
|
continue;
|
|
279
291
|
}
|
|
280
292
|
|
|
281
|
-
const
|
|
293
|
+
const role = msg.role === 'assistant' ? 'assistant' : 'user';
|
|
294
|
+
const content = normalizeMessageContent(msg.content, role);
|
|
282
295
|
if (content.length > 0) {
|
|
283
296
|
input.push({
|
|
284
297
|
type: 'message',
|
|
285
|
-
role
|
|
298
|
+
role,
|
|
286
299
|
content,
|
|
287
300
|
});
|
|
288
301
|
}
|