@appchy/jarvis 0.1.24 → 0.1.26
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/bin.js +116 -9
- package/dist/bin.js.map +1 -1
- package/package.json +3 -3
package/dist/bin.js
CHANGED
|
@@ -886,6 +886,20 @@ var init_anthropic_llm_provider = __esm({
|
|
|
886
886
|
});
|
|
887
887
|
|
|
888
888
|
// ../../providers/anthropic/src/claude-code.llm.provider.ts
|
|
889
|
+
function isRateLimitError(err) {
|
|
890
|
+
if (!err) return { matched: false };
|
|
891
|
+
const e = err;
|
|
892
|
+
const msg = typeof e.message === "string" ? e.message : "";
|
|
893
|
+
const name = typeof e.name === "string" ? e.name : "";
|
|
894
|
+
const status = typeof e.status === "number" ? e.status : void 0;
|
|
895
|
+
const matched = status === 429 || /rate.?limit/i.test(msg) || /rate.?limit/i.test(name);
|
|
896
|
+
if (!matched) return { matched: false };
|
|
897
|
+
return {
|
|
898
|
+
matched: true,
|
|
899
|
+
...typeof e.resetsAt === "string" ? { resetsAt: e.resetsAt } : {},
|
|
900
|
+
...typeof e.tier === "string" ? { tier: e.tier } : {}
|
|
901
|
+
};
|
|
902
|
+
}
|
|
889
903
|
function generateId() {
|
|
890
904
|
return `pui-${Date.now()}-${++_idCounter}`;
|
|
891
905
|
}
|
|
@@ -1080,6 +1094,7 @@ function claudeCodeProvider(config = {}) {
|
|
|
1080
1094
|
let lastAssistantContent = "";
|
|
1081
1095
|
let json;
|
|
1082
1096
|
let sdkError;
|
|
1097
|
+
let rateLimit;
|
|
1083
1098
|
let inputTokens = 0;
|
|
1084
1099
|
let outputTokens = 0;
|
|
1085
1100
|
const isResuming = !!config.session?.resume;
|
|
@@ -1190,6 +1205,13 @@ function claudeCodeProvider(config = {}) {
|
|
|
1190
1205
|
}
|
|
1191
1206
|
}
|
|
1192
1207
|
}
|
|
1208
|
+
if (message.type === "rate_limit_event") {
|
|
1209
|
+
const ev = message;
|
|
1210
|
+
const resetsAt = ev.resetsAt ?? ev.resets_at ?? (typeof ev.resetTime === "number" ? new Date(ev.resetTime).toISOString() : void 0);
|
|
1211
|
+
const tier = ev.tier ?? ev.scope;
|
|
1212
|
+
rateLimit = { ...resetsAt ? { resetsAt } : {}, ...tier ? { tier } : {} };
|
|
1213
|
+
logger.info(ctx, "[ClaudeCode] rate_limit_event (soft warning)", { resetsAt, tier });
|
|
1214
|
+
}
|
|
1193
1215
|
if (message.type === "result") {
|
|
1194
1216
|
const subtype = message.subtype;
|
|
1195
1217
|
if (subtype && subtype !== "success") {
|
|
@@ -1211,20 +1233,35 @@ function claudeCodeProvider(config = {}) {
|
|
|
1211
1233
|
}
|
|
1212
1234
|
}
|
|
1213
1235
|
} catch (error) {
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1236
|
+
const rl = isRateLimitError(error);
|
|
1237
|
+
if (rl.matched) {
|
|
1238
|
+
sdkError = "rate_limit";
|
|
1239
|
+
rateLimit = {
|
|
1240
|
+
...rl.resetsAt ? { resetsAt: rl.resetsAt } : rateLimit?.resetsAt ? { resetsAt: rateLimit.resetsAt } : {},
|
|
1241
|
+
...rl.tier ? { tier: rl.tier } : rateLimit?.tier ? { tier: rateLimit.tier } : {}
|
|
1242
|
+
};
|
|
1243
|
+
logger.warn(ctx, "[ClaudeCode] Query throttled (hard rate limit)", {
|
|
1244
|
+
model: req.model,
|
|
1245
|
+
resetsAt: rl.resetsAt,
|
|
1246
|
+
tier: rl.tier
|
|
1247
|
+
});
|
|
1248
|
+
} else {
|
|
1249
|
+
logger.error(ctx, "[ClaudeCode] Query error", {
|
|
1250
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1251
|
+
model: req.model,
|
|
1252
|
+
apiKeyPresent: !!apiKey,
|
|
1253
|
+
cwd: config.workingDirectory,
|
|
1254
|
+
mcpServers: Object.keys(config.mcpServers || {})
|
|
1255
|
+
});
|
|
1256
|
+
throw error;
|
|
1257
|
+
}
|
|
1222
1258
|
}
|
|
1223
1259
|
logger.info(ctx, "[ClaudeCode] Query complete", { messageCount });
|
|
1224
1260
|
return {
|
|
1225
1261
|
content: lastAssistantContent || aggregatedContent,
|
|
1226
1262
|
json,
|
|
1227
1263
|
error: sdkError,
|
|
1264
|
+
...rateLimit ? { rateLimit } : {},
|
|
1228
1265
|
toolCalls: void 0,
|
|
1229
1266
|
metadata: {
|
|
1230
1267
|
model: req.model,
|
|
@@ -1271,6 +1308,7 @@ function claudeCodeProvider(config = {}) {
|
|
|
1271
1308
|
mcpServers: Object.keys(config.mcpServers || {})
|
|
1272
1309
|
});
|
|
1273
1310
|
let messageCount = 0;
|
|
1311
|
+
let streamRateLimit;
|
|
1274
1312
|
try {
|
|
1275
1313
|
for await (const message of claudeQuery({
|
|
1276
1314
|
prompt: typeof prompt2 === "string" ? prompt2 : JSON.stringify(prompt2),
|
|
@@ -1365,6 +1403,13 @@ function claudeCodeProvider(config = {}) {
|
|
|
1365
1403
|
}
|
|
1366
1404
|
}
|
|
1367
1405
|
}
|
|
1406
|
+
if (message.type === "rate_limit_event") {
|
|
1407
|
+
const ev = message;
|
|
1408
|
+
const resetsAt = ev.resetsAt ?? ev.resets_at ?? (typeof ev.resetTime === "number" ? new Date(ev.resetTime).toISOString() : void 0);
|
|
1409
|
+
const tier = ev.tier ?? ev.scope;
|
|
1410
|
+
streamRateLimit = { ...resetsAt ? { resetsAt } : {}, ...tier ? { tier } : {} };
|
|
1411
|
+
logger.info(ctx, "[ClaudeCode] rate_limit_event (soft warning)", { resetsAt, tier });
|
|
1412
|
+
}
|
|
1368
1413
|
if (message.type === "result") {
|
|
1369
1414
|
if ("usage" in message) {
|
|
1370
1415
|
const usage = message.usage;
|
|
@@ -1377,6 +1422,7 @@ function claudeCodeProvider(config = {}) {
|
|
|
1377
1422
|
content: "",
|
|
1378
1423
|
// Text already yielded incrementally
|
|
1379
1424
|
json: sc,
|
|
1425
|
+
...streamRateLimit ? { rateLimit: streamRateLimit } : {},
|
|
1380
1426
|
metadata: {
|
|
1381
1427
|
model: req.model,
|
|
1382
1428
|
usage: {
|
|
@@ -1391,6 +1437,33 @@ function claudeCodeProvider(config = {}) {
|
|
|
1391
1437
|
}
|
|
1392
1438
|
}
|
|
1393
1439
|
} catch (error) {
|
|
1440
|
+
const rl = isRateLimitError(error);
|
|
1441
|
+
if (rl.matched) {
|
|
1442
|
+
const merged = {
|
|
1443
|
+
...rl.resetsAt ? { resetsAt: rl.resetsAt } : streamRateLimit?.resetsAt ? { resetsAt: streamRateLimit.resetsAt } : {},
|
|
1444
|
+
...rl.tier ? { tier: rl.tier } : streamRateLimit?.tier ? { tier: streamRateLimit.tier } : {}
|
|
1445
|
+
};
|
|
1446
|
+
logger.warn(ctx, "[ClaudeCode] Stream throttled (hard rate limit)", {
|
|
1447
|
+
model: req.model,
|
|
1448
|
+
...merged
|
|
1449
|
+
});
|
|
1450
|
+
yield {
|
|
1451
|
+
content: "",
|
|
1452
|
+
error: "rate_limit",
|
|
1453
|
+
rateLimit: merged,
|
|
1454
|
+
metadata: {
|
|
1455
|
+
model: req.model,
|
|
1456
|
+
usage: {
|
|
1457
|
+
inputTokens,
|
|
1458
|
+
outputTokens,
|
|
1459
|
+
totalTokens: inputTokens + outputTokens
|
|
1460
|
+
},
|
|
1461
|
+
duration: Date.now() - startTime,
|
|
1462
|
+
provider: "claude-code"
|
|
1463
|
+
}
|
|
1464
|
+
};
|
|
1465
|
+
return;
|
|
1466
|
+
}
|
|
1394
1467
|
logger.error(ctx, "[ClaudeCode] Stream error", {
|
|
1395
1468
|
error: error instanceof Error ? error.message : String(error),
|
|
1396
1469
|
model: req.model,
|
|
@@ -4438,13 +4511,20 @@ ${orig.content ?? ""}`
|
|
|
4438
4511
|
runId,
|
|
4439
4512
|
success: !response.error && !aborted
|
|
4440
4513
|
});
|
|
4514
|
+
const isRateLimit = response.error === "rate_limit";
|
|
4441
4515
|
return {
|
|
4442
4516
|
message: response.content ?? "",
|
|
4443
4517
|
success: !response.error && !aborted,
|
|
4444
4518
|
cancelled: aborted,
|
|
4445
4519
|
state: req.state ?? {},
|
|
4446
4520
|
metadata: { inputTokens: 0, outputTokens: 0, totalTokens: 0, iterations: 0 },
|
|
4447
|
-
...
|
|
4521
|
+
...isRateLimit ? {
|
|
4522
|
+
exit: {
|
|
4523
|
+
reason: "rate_limit",
|
|
4524
|
+
message: "Rate limited \u2014 try again in a moment.",
|
|
4525
|
+
...response.rateLimit?.resetsAt ? { resetsAt: response.rateLimit.resetsAt } : {}
|
|
4526
|
+
}
|
|
4527
|
+
} : response.error ? { exit: { reason: "error", message: response.error } } : {}
|
|
4448
4528
|
};
|
|
4449
4529
|
} catch (err) {
|
|
4450
4530
|
const aborted = abortController.signal.aborted;
|
|
@@ -4460,6 +4540,26 @@ ${orig.content ?? ""}`
|
|
|
4460
4540
|
};
|
|
4461
4541
|
}
|
|
4462
4542
|
const message = err instanceof Error ? err.message : String(err);
|
|
4543
|
+
const e = err;
|
|
4544
|
+
const status = typeof e.status === "number" ? e.status : void 0;
|
|
4545
|
+
const name = typeof e.name === "string" ? e.name : "";
|
|
4546
|
+
const isRateLimit = status === 429 || /rate.?limit/i.test(message) || /rate.?limit/i.test(name);
|
|
4547
|
+
if (isRateLimit) {
|
|
4548
|
+
const resetsAt = typeof e.resetsAt === "string" ? e.resetsAt : void 0;
|
|
4549
|
+
logger.warn(ctx, "[claude-code] Throttled", { runId, resetsAt });
|
|
4550
|
+
return {
|
|
4551
|
+
message: "",
|
|
4552
|
+
success: false,
|
|
4553
|
+
cancelled: false,
|
|
4554
|
+
state: req.state ?? {},
|
|
4555
|
+
metadata: { inputTokens: 0, outputTokens: 0, totalTokens: 0, iterations: 0 },
|
|
4556
|
+
exit: {
|
|
4557
|
+
reason: "rate_limit",
|
|
4558
|
+
message: "Rate limited \u2014 try again in a moment.",
|
|
4559
|
+
...resetsAt ? { resetsAt } : {}
|
|
4560
|
+
}
|
|
4561
|
+
};
|
|
4562
|
+
}
|
|
4463
4563
|
logger.error(ctx, "[claude-code] Failed", { runId, error: message });
|
|
4464
4564
|
return {
|
|
4465
4565
|
message: "",
|
|
@@ -5334,6 +5434,13 @@ async function runTask(ctx, req) {
|
|
|
5334
5434
|
content: result.message,
|
|
5335
5435
|
error: result.exit?.message,
|
|
5336
5436
|
interrupted: result.cancelled,
|
|
5437
|
+
...result.exit ? {
|
|
5438
|
+
exit: {
|
|
5439
|
+
reason: result.exit.reason,
|
|
5440
|
+
message: result.exit.message,
|
|
5441
|
+
...result.exit.resetsAt ? { resetsAt: result.exit.resetsAt } : {}
|
|
5442
|
+
}
|
|
5443
|
+
} : {},
|
|
5337
5444
|
...result.sessionId ? { sessionId: result.sessionId } : {}
|
|
5338
5445
|
}
|
|
5339
5446
|
});
|