@appchy/jarvis 0.1.23 → 0.1.25
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 +126 -13
- 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
|
}
|
|
@@ -1063,6 +1077,9 @@ async function processAfterHooks(ctx, req) {
|
|
|
1063
1077
|
}
|
|
1064
1078
|
function claudeCodeProvider(config = {}) {
|
|
1065
1079
|
const useSubscription = config.useSubscription ?? false;
|
|
1080
|
+
if (useSubscription && process.env.ANTHROPIC_API_KEY) {
|
|
1081
|
+
delete process.env.ANTHROPIC_API_KEY;
|
|
1082
|
+
}
|
|
1066
1083
|
const apiKey = useSubscription ? void 0 : config.apiKey ?? process.env.ANTHROPIC_API_KEY;
|
|
1067
1084
|
async function query(ctx, req, _options) {
|
|
1068
1085
|
const { query: claudeQuery } = await import("@anthropic-ai/claude-agent-sdk");
|
|
@@ -1080,6 +1097,7 @@ function claudeCodeProvider(config = {}) {
|
|
|
1080
1097
|
let lastAssistantContent = "";
|
|
1081
1098
|
let json;
|
|
1082
1099
|
let sdkError;
|
|
1100
|
+
let rateLimit;
|
|
1083
1101
|
let inputTokens = 0;
|
|
1084
1102
|
let outputTokens = 0;
|
|
1085
1103
|
const isResuming = !!config.session?.resume;
|
|
@@ -1190,6 +1208,13 @@ function claudeCodeProvider(config = {}) {
|
|
|
1190
1208
|
}
|
|
1191
1209
|
}
|
|
1192
1210
|
}
|
|
1211
|
+
if (message.type === "rate_limit_event") {
|
|
1212
|
+
const ev = message;
|
|
1213
|
+
const resetsAt = ev.resetsAt ?? ev.resets_at ?? (typeof ev.resetTime === "number" ? new Date(ev.resetTime).toISOString() : void 0);
|
|
1214
|
+
const tier = ev.tier ?? ev.scope;
|
|
1215
|
+
rateLimit = { ...resetsAt ? { resetsAt } : {}, ...tier ? { tier } : {} };
|
|
1216
|
+
logger.info(ctx, "[ClaudeCode] rate_limit_event (soft warning)", { resetsAt, tier });
|
|
1217
|
+
}
|
|
1193
1218
|
if (message.type === "result") {
|
|
1194
1219
|
const subtype = message.subtype;
|
|
1195
1220
|
if (subtype && subtype !== "success") {
|
|
@@ -1211,20 +1236,35 @@ function claudeCodeProvider(config = {}) {
|
|
|
1211
1236
|
}
|
|
1212
1237
|
}
|
|
1213
1238
|
} catch (error) {
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1239
|
+
const rl = isRateLimitError(error);
|
|
1240
|
+
if (rl.matched) {
|
|
1241
|
+
sdkError = "rate_limit";
|
|
1242
|
+
rateLimit = {
|
|
1243
|
+
...rl.resetsAt ? { resetsAt: rl.resetsAt } : rateLimit?.resetsAt ? { resetsAt: rateLimit.resetsAt } : {},
|
|
1244
|
+
...rl.tier ? { tier: rl.tier } : rateLimit?.tier ? { tier: rateLimit.tier } : {}
|
|
1245
|
+
};
|
|
1246
|
+
logger.warn(ctx, "[ClaudeCode] Query throttled (hard rate limit)", {
|
|
1247
|
+
model: req.model,
|
|
1248
|
+
resetsAt: rl.resetsAt,
|
|
1249
|
+
tier: rl.tier
|
|
1250
|
+
});
|
|
1251
|
+
} else {
|
|
1252
|
+
logger.error(ctx, "[ClaudeCode] Query error", {
|
|
1253
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1254
|
+
model: req.model,
|
|
1255
|
+
apiKeyPresent: !!apiKey,
|
|
1256
|
+
cwd: config.workingDirectory,
|
|
1257
|
+
mcpServers: Object.keys(config.mcpServers || {})
|
|
1258
|
+
});
|
|
1259
|
+
throw error;
|
|
1260
|
+
}
|
|
1222
1261
|
}
|
|
1223
1262
|
logger.info(ctx, "[ClaudeCode] Query complete", { messageCount });
|
|
1224
1263
|
return {
|
|
1225
1264
|
content: lastAssistantContent || aggregatedContent,
|
|
1226
1265
|
json,
|
|
1227
1266
|
error: sdkError,
|
|
1267
|
+
...rateLimit ? { rateLimit } : {},
|
|
1228
1268
|
toolCalls: void 0,
|
|
1229
1269
|
metadata: {
|
|
1230
1270
|
model: req.model,
|
|
@@ -1271,6 +1311,7 @@ function claudeCodeProvider(config = {}) {
|
|
|
1271
1311
|
mcpServers: Object.keys(config.mcpServers || {})
|
|
1272
1312
|
});
|
|
1273
1313
|
let messageCount = 0;
|
|
1314
|
+
let streamRateLimit;
|
|
1274
1315
|
try {
|
|
1275
1316
|
for await (const message of claudeQuery({
|
|
1276
1317
|
prompt: typeof prompt2 === "string" ? prompt2 : JSON.stringify(prompt2),
|
|
@@ -1365,6 +1406,13 @@ function claudeCodeProvider(config = {}) {
|
|
|
1365
1406
|
}
|
|
1366
1407
|
}
|
|
1367
1408
|
}
|
|
1409
|
+
if (message.type === "rate_limit_event") {
|
|
1410
|
+
const ev = message;
|
|
1411
|
+
const resetsAt = ev.resetsAt ?? ev.resets_at ?? (typeof ev.resetTime === "number" ? new Date(ev.resetTime).toISOString() : void 0);
|
|
1412
|
+
const tier = ev.tier ?? ev.scope;
|
|
1413
|
+
streamRateLimit = { ...resetsAt ? { resetsAt } : {}, ...tier ? { tier } : {} };
|
|
1414
|
+
logger.info(ctx, "[ClaudeCode] rate_limit_event (soft warning)", { resetsAt, tier });
|
|
1415
|
+
}
|
|
1368
1416
|
if (message.type === "result") {
|
|
1369
1417
|
if ("usage" in message) {
|
|
1370
1418
|
const usage = message.usage;
|
|
@@ -1377,6 +1425,7 @@ function claudeCodeProvider(config = {}) {
|
|
|
1377
1425
|
content: "",
|
|
1378
1426
|
// Text already yielded incrementally
|
|
1379
1427
|
json: sc,
|
|
1428
|
+
...streamRateLimit ? { rateLimit: streamRateLimit } : {},
|
|
1380
1429
|
metadata: {
|
|
1381
1430
|
model: req.model,
|
|
1382
1431
|
usage: {
|
|
@@ -1391,6 +1440,33 @@ function claudeCodeProvider(config = {}) {
|
|
|
1391
1440
|
}
|
|
1392
1441
|
}
|
|
1393
1442
|
} catch (error) {
|
|
1443
|
+
const rl = isRateLimitError(error);
|
|
1444
|
+
if (rl.matched) {
|
|
1445
|
+
const merged = {
|
|
1446
|
+
...rl.resetsAt ? { resetsAt: rl.resetsAt } : streamRateLimit?.resetsAt ? { resetsAt: streamRateLimit.resetsAt } : {},
|
|
1447
|
+
...rl.tier ? { tier: rl.tier } : streamRateLimit?.tier ? { tier: streamRateLimit.tier } : {}
|
|
1448
|
+
};
|
|
1449
|
+
logger.warn(ctx, "[ClaudeCode] Stream throttled (hard rate limit)", {
|
|
1450
|
+
model: req.model,
|
|
1451
|
+
...merged
|
|
1452
|
+
});
|
|
1453
|
+
yield {
|
|
1454
|
+
content: "",
|
|
1455
|
+
error: "rate_limit",
|
|
1456
|
+
rateLimit: merged,
|
|
1457
|
+
metadata: {
|
|
1458
|
+
model: req.model,
|
|
1459
|
+
usage: {
|
|
1460
|
+
inputTokens,
|
|
1461
|
+
outputTokens,
|
|
1462
|
+
totalTokens: inputTokens + outputTokens
|
|
1463
|
+
},
|
|
1464
|
+
duration: Date.now() - startTime,
|
|
1465
|
+
provider: "claude-code"
|
|
1466
|
+
}
|
|
1467
|
+
};
|
|
1468
|
+
return;
|
|
1469
|
+
}
|
|
1394
1470
|
logger.error(ctx, "[ClaudeCode] Stream error", {
|
|
1395
1471
|
error: error instanceof Error ? error.message : String(error),
|
|
1396
1472
|
model: req.model,
|
|
@@ -4358,6 +4434,9 @@ function computeCost(model, usage) {
|
|
|
4358
4434
|
return input + output + read2 + write;
|
|
4359
4435
|
}
|
|
4360
4436
|
function claudeCodeAgent(config = {}) {
|
|
4437
|
+
if (config.useSubscription && process.env.ANTHROPIC_API_KEY) {
|
|
4438
|
+
delete process.env.ANTHROPIC_API_KEY;
|
|
4439
|
+
}
|
|
4361
4440
|
const activeRuns = /* @__PURE__ */ new Map();
|
|
4362
4441
|
return {
|
|
4363
4442
|
id: "claude-code",
|
|
@@ -4438,13 +4517,20 @@ ${orig.content ?? ""}`
|
|
|
4438
4517
|
runId,
|
|
4439
4518
|
success: !response.error && !aborted
|
|
4440
4519
|
});
|
|
4520
|
+
const isRateLimit = response.error === "rate_limit";
|
|
4441
4521
|
return {
|
|
4442
4522
|
message: response.content ?? "",
|
|
4443
4523
|
success: !response.error && !aborted,
|
|
4444
4524
|
cancelled: aborted,
|
|
4445
4525
|
state: req.state ?? {},
|
|
4446
4526
|
metadata: { inputTokens: 0, outputTokens: 0, totalTokens: 0, iterations: 0 },
|
|
4447
|
-
...
|
|
4527
|
+
...isRateLimit ? {
|
|
4528
|
+
exit: {
|
|
4529
|
+
reason: "rate_limit",
|
|
4530
|
+
message: "Rate limited \u2014 try again in a moment.",
|
|
4531
|
+
...response.rateLimit?.resetsAt ? { resetsAt: response.rateLimit.resetsAt } : {}
|
|
4532
|
+
}
|
|
4533
|
+
} : response.error ? { exit: { reason: "error", message: response.error } } : {}
|
|
4448
4534
|
};
|
|
4449
4535
|
} catch (err) {
|
|
4450
4536
|
const aborted = abortController.signal.aborted;
|
|
@@ -4460,6 +4546,26 @@ ${orig.content ?? ""}`
|
|
|
4460
4546
|
};
|
|
4461
4547
|
}
|
|
4462
4548
|
const message = err instanceof Error ? err.message : String(err);
|
|
4549
|
+
const e = err;
|
|
4550
|
+
const status = typeof e.status === "number" ? e.status : void 0;
|
|
4551
|
+
const name = typeof e.name === "string" ? e.name : "";
|
|
4552
|
+
const isRateLimit = status === 429 || /rate.?limit/i.test(message) || /rate.?limit/i.test(name);
|
|
4553
|
+
if (isRateLimit) {
|
|
4554
|
+
const resetsAt = typeof e.resetsAt === "string" ? e.resetsAt : void 0;
|
|
4555
|
+
logger.warn(ctx, "[claude-code] Throttled", { runId, resetsAt });
|
|
4556
|
+
return {
|
|
4557
|
+
message: "",
|
|
4558
|
+
success: false,
|
|
4559
|
+
cancelled: false,
|
|
4560
|
+
state: req.state ?? {},
|
|
4561
|
+
metadata: { inputTokens: 0, outputTokens: 0, totalTokens: 0, iterations: 0 },
|
|
4562
|
+
exit: {
|
|
4563
|
+
reason: "rate_limit",
|
|
4564
|
+
message: "Rate limited \u2014 try again in a moment.",
|
|
4565
|
+
...resetsAt ? { resetsAt } : {}
|
|
4566
|
+
}
|
|
4567
|
+
};
|
|
4568
|
+
}
|
|
4463
4569
|
logger.error(ctx, "[claude-code] Failed", { runId, error: message });
|
|
4464
4570
|
return {
|
|
4465
4571
|
message: "",
|
|
@@ -5288,9 +5394,9 @@ function getWorkspacePath() {
|
|
|
5288
5394
|
var provider2 = null;
|
|
5289
5395
|
var pendingInputs = /* @__PURE__ */ new Map();
|
|
5290
5396
|
function initAgent(c) {
|
|
5397
|
+
const useSubscription = c.useSubscription ?? !c.anthropicApiKey;
|
|
5291
5398
|
provider2 = claudeCodeAgent({
|
|
5292
|
-
apiKey: c.anthropicApiKey,
|
|
5293
|
-
useSubscription: c.useSubscription,
|
|
5399
|
+
...useSubscription ? { useSubscription: true } : { apiKey: c.anthropicApiKey },
|
|
5294
5400
|
userId: c.userId,
|
|
5295
5401
|
appUrl: c.appUrl,
|
|
5296
5402
|
defaultWorkspace: getWorkspacePath()
|
|
@@ -5334,6 +5440,13 @@ async function runTask(ctx, req) {
|
|
|
5334
5440
|
content: result.message,
|
|
5335
5441
|
error: result.exit?.message,
|
|
5336
5442
|
interrupted: result.cancelled,
|
|
5443
|
+
...result.exit ? {
|
|
5444
|
+
exit: {
|
|
5445
|
+
reason: result.exit.reason,
|
|
5446
|
+
message: result.exit.message,
|
|
5447
|
+
...result.exit.resetsAt ? { resetsAt: result.exit.resetsAt } : {}
|
|
5448
|
+
}
|
|
5449
|
+
} : {},
|
|
5337
5450
|
...result.sessionId ? { sessionId: result.sessionId } : {}
|
|
5338
5451
|
}
|
|
5339
5452
|
});
|
|
@@ -5534,7 +5647,7 @@ function codeAgents(config) {
|
|
|
5534
5647
|
|
|
5535
5648
|
// src/chats.ts
|
|
5536
5649
|
init_src6();
|
|
5537
|
-
var claudeCode = claudeCodeAgent();
|
|
5650
|
+
var claudeCode = claudeCodeAgent({ useSubscription: true });
|
|
5538
5651
|
var agentProvider = agents({ providers: [claudeCode] });
|
|
5539
5652
|
var codeAgentProvider = codeAgents({ providers: [claudeCode] });
|
|
5540
5653
|
|
|
@@ -6967,7 +7080,7 @@ function register6(program) {
|
|
|
6967
7080
|
console.log(` Connected: ${config.connectedAt}`);
|
|
6968
7081
|
}
|
|
6969
7082
|
} else {
|
|
6970
|
-
console.log(` Config: Not set up. Run 'jarvis
|
|
7083
|
+
console.log(` Config: Not set up. Run 'jarvis start'`);
|
|
6971
7084
|
}
|
|
6972
7085
|
const svc = createServiceManager();
|
|
6973
7086
|
const svcStatus = svc.status();
|