neoagent 2.4.1-beta.41 → 2.4.1-beta.42
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
|
+
ed88f04225b62218697804faf6ff5b05
|
|
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"c416acfeb8126e097f758c664aaa3da929e27d
|
|
|
37
37
|
|
|
38
38
|
_flutter.loader.load({
|
|
39
39
|
serviceWorkerSettings: {
|
|
40
|
-
serviceWorkerVersion: "
|
|
40
|
+
serviceWorkerVersion: "1217250469" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
|
|
41
41
|
}
|
|
42
42
|
});
|
|
@@ -134248,7 +134248,7 @@ r===$&&A.b()
|
|
|
134248
134248
|
o.push(A.jP(p,A.jb(!1,new A.a2(B.up,A.dl(new A.cw(B.hs,new A.a7z(r,p),p),p,p),p),!1,B.H,!0),p,p,0,0,0,p))}r=!1
|
|
134249
134249
|
if(!s.ay)if(!s.ch){r=s.e
|
|
134250
134250
|
r===$&&A.b()
|
|
134251
|
-
r=B.b.t("
|
|
134251
|
+
r=B.b.t("mq5hfdrk-acc903b").length!==0&&r.b}if(r){r=s.d
|
|
134252
134252
|
r===$&&A.b()
|
|
134253
134253
|
r=r.av&&!r.aQ?84:0
|
|
134254
134254
|
q=s.e
|
|
@@ -139889,7 +139889,7 @@ $S:0}
|
|
|
139889
139889
|
A.ZW.prototype={}
|
|
139890
139890
|
A.SC.prototype={
|
|
139891
139891
|
nb(a){var s=this
|
|
139892
|
-
if(B.b.t("
|
|
139892
|
+
if(B.b.t("mq5hfdrk-acc903b").length===0||s.a!=null)return
|
|
139893
139893
|
s.AR()
|
|
139894
139894
|
s.a=A.qh(B.Rl,new A.baD(s))},
|
|
139895
139895
|
AR(){var s=0,r=A.l(t.H),q,p=2,o=[],n=this,m,l,k,j,i,h,g,f
|
|
@@ -139907,7 +139907,7 @@ if(!t.f.b(k)){s=1
|
|
|
139907
139907
|
break}i=J.U(k,"buildId")
|
|
139908
139908
|
h=i==null?null:B.b.t(J.p(i))
|
|
139909
139909
|
j=h==null?"":h
|
|
139910
|
-
if(J.be(j)===0||J.d(j,"
|
|
139910
|
+
if(J.be(j)===0||J.d(j,"mq5hfdrk-acc903b")){s=1
|
|
139911
139911
|
break}n.b=!0
|
|
139912
139912
|
n.D()
|
|
139913
139913
|
p=2
|
|
@@ -139924,7 +139924,7 @@ case 2:return A.i(o.at(-1),r)}})
|
|
|
139924
139924
|
return A.k($async$AR,r)},
|
|
139925
139925
|
vx(){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
|
|
139926
139926
|
var $async$vx=A.h(function(a2,a3){if(a2===1){o.push(a3)
|
|
139927
|
-
s=p}for(;;)switch(s){case 0:if(B.b.t("
|
|
139927
|
+
s=p}for(;;)switch(s){case 0:if(B.b.t("mq5hfdrk-acc903b").length===0||n.c){s=1
|
|
139928
139928
|
break}n.c=!0
|
|
139929
139929
|
n.D()
|
|
139930
139930
|
p=4
|
|
@@ -224,6 +224,14 @@ async function refreshProviderModelList(providerId, apiKey, baseUrl) {
|
|
|
224
224
|
return models;
|
|
225
225
|
} catch (err) {
|
|
226
226
|
console.warn(`[Models] Failed to refresh ${providerId} models:`, err.message);
|
|
227
|
+
// Always record a lastRefresh so we don't hammer the API on every request.
|
|
228
|
+
// Permanent errors (auth/billing/credits) get a longer backoff.
|
|
229
|
+
const isPermanent = /401|403|unauthorized|forbidden|credits|spending/i.test(err.message);
|
|
230
|
+
const backoff = isPermanent ? 30 * 60 * 1000 : DYNAMIC_REFRESH_INTERVAL;
|
|
231
|
+
providerModelCache.set(cacheKey, {
|
|
232
|
+
models: existing?.models || [],
|
|
233
|
+
lastRefresh: now - DYNAMIC_REFRESH_INTERVAL + backoff,
|
|
234
|
+
});
|
|
227
235
|
return existing?.models || [];
|
|
228
236
|
}
|
|
229
237
|
}
|
|
@@ -16,6 +16,8 @@ class OpenRouterProvider extends OpenAICompatibleProvider {
|
|
|
16
16
|
this.client = new OpenAI({
|
|
17
17
|
apiKey: config.apiKey || process.env.OPENROUTER_API_KEY,
|
|
18
18
|
baseURL: this.baseURL,
|
|
19
|
+
timeout: 90_000, // 90 s — free models can queue; avoids hanging forever
|
|
20
|
+
maxRetries: 0, // engine handles retries; avoid SDK silently re-queuing slow models
|
|
19
21
|
defaultHeaders: {
|
|
20
22
|
'HTTP-Referer': 'https://github.com/NeoLabs-Systems/NeoAgent',
|
|
21
23
|
'X-Title': 'NeoAgent',
|
|
@@ -57,6 +59,14 @@ class OpenRouterProvider extends OpenAICompatibleProvider {
|
|
|
57
59
|
return params;
|
|
58
60
|
}
|
|
59
61
|
|
|
62
|
+
_extractOpenRouterError(obj) {
|
|
63
|
+
if (!obj) return null;
|
|
64
|
+
const e = obj.error;
|
|
65
|
+
if (!e) return null;
|
|
66
|
+
const msg = e.message || (typeof e === 'string' ? e : JSON.stringify(e));
|
|
67
|
+
return `OpenRouter: ${msg}${e.code ? ` (code ${e.code})` : ''}`;
|
|
68
|
+
}
|
|
69
|
+
|
|
60
70
|
async chat(messages, tools = [], options = {}) {
|
|
61
71
|
const model = options.model || this.getDefaultModel();
|
|
62
72
|
const params = this._buildParams(model, messages, tools, options);
|
|
@@ -66,6 +76,12 @@ class OpenRouterProvider extends OpenAICompatibleProvider {
|
|
|
66
76
|
} catch (err) {
|
|
67
77
|
throw new Error(`OpenRouter request failed: ${err?.message || String(err)}`);
|
|
68
78
|
}
|
|
79
|
+
// OpenRouter returns HTTP 200 even for errors (rate limits, model unavailable, etc.)
|
|
80
|
+
const orErr = this._extractOpenRouterError(response);
|
|
81
|
+
if (orErr) throw new Error(orErr);
|
|
82
|
+
if (!response?.choices?.length) {
|
|
83
|
+
throw new Error(`OpenRouter: model returned no choices (may be rate-limited or unavailable)`);
|
|
84
|
+
}
|
|
69
85
|
return this.normalizeResponse(response);
|
|
70
86
|
}
|
|
71
87
|
|
|
@@ -88,6 +104,9 @@ class OpenRouterProvider extends OpenAICompatibleProvider {
|
|
|
88
104
|
let content = '';
|
|
89
105
|
let finalUsage = null;
|
|
90
106
|
|
|
107
|
+
// The OpenAI SDK converts OpenRouter's SSE error events (data.error) into
|
|
108
|
+
// APIErrors before yielding — so we wrap the loop to add context.
|
|
109
|
+
try {
|
|
91
110
|
for await (const chunk of stream) {
|
|
92
111
|
if (chunk.usage && (!chunk.choices || chunk.choices.length === 0)) {
|
|
93
112
|
finalUsage = this.normalizeUsage(chunk.usage);
|
|
@@ -127,6 +146,10 @@ class OpenRouterProvider extends OpenAICompatibleProvider {
|
|
|
127
146
|
return;
|
|
128
147
|
}
|
|
129
148
|
}
|
|
149
|
+
} catch (err) {
|
|
150
|
+
// Re-throw SDK APIErrors (from OpenRouter SSE error events) with OpenRouter context.
|
|
151
|
+
throw new Error(`OpenRouter: ${err?.message || String(err)}`);
|
|
152
|
+
}
|
|
130
153
|
|
|
131
154
|
if (toolCalls.length > 0) {
|
|
132
155
|
yield { type: 'tool_calls', toolCalls, content, usage: finalUsage };
|