arisa 2.0.5 → 2.0.7
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 +2 -3
- package/src/core/index.ts +25 -5
- package/src/shared/ai-cli.ts +43 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arisa",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.7",
|
|
4
4
|
"description": "Arisa - dynamic agent runtime with daemon/core architecture that evolves through user interaction",
|
|
5
5
|
"preferGlobal": true,
|
|
6
6
|
"bin": {
|
|
@@ -29,8 +29,7 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"croner": "^9.0.0",
|
|
31
31
|
"crypto-js": "^4.2.0",
|
|
32
|
-
"deepbase": "^3.4.
|
|
33
|
-
"deepbase-json": "^3.4.6",
|
|
32
|
+
"deepbase": "^3.4.9",
|
|
34
33
|
"elevenlabs": "^1.59.0",
|
|
35
34
|
"grammy": "^1.21.0",
|
|
36
35
|
"openai": "^6.19.0",
|
package/src/core/index.ts
CHANGED
|
@@ -49,16 +49,25 @@ function defaultBackend(): "claude" | "codex" {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
function getBackend(chatId: string): "claude" | "codex" {
|
|
52
|
+
const deps = checkDeps();
|
|
53
|
+
|
|
54
|
+
const preferInstalled = (candidate: "claude" | "codex"): "claude" | "codex" => {
|
|
55
|
+
if (candidate === "claude" && !deps.claude && deps.codex) return "codex";
|
|
56
|
+
if (candidate === "codex" && !deps.codex && deps.claude) return "claude";
|
|
57
|
+
return candidate;
|
|
58
|
+
};
|
|
59
|
+
|
|
52
60
|
const current = backendState.get(chatId);
|
|
53
|
-
if (current) return current;
|
|
61
|
+
if (current) return preferInstalled(current);
|
|
54
62
|
|
|
55
63
|
const fromHistory = getLastBackend(chatId);
|
|
56
64
|
if (fromHistory) {
|
|
57
|
-
|
|
58
|
-
|
|
65
|
+
const resolved = preferInstalled(fromHistory);
|
|
66
|
+
backendState.set(chatId, resolved);
|
|
67
|
+
return resolved;
|
|
59
68
|
}
|
|
60
69
|
|
|
61
|
-
return defaultBackend();
|
|
70
|
+
return preferInstalled(defaultBackend());
|
|
62
71
|
}
|
|
63
72
|
|
|
64
73
|
// Initialize auth + scheduler + attachments
|
|
@@ -329,9 +338,15 @@ ${messageText}`;
|
|
|
329
338
|
return Response.json(response);
|
|
330
339
|
}
|
|
331
340
|
|
|
341
|
+
const deps = checkDeps();
|
|
342
|
+
if (!deps.claude && !deps.codex) {
|
|
343
|
+
return Response.json({
|
|
344
|
+
text: "No AI CLI is installed. Install at least one:\n<code>bun add -g @anthropic-ai/claude-code</code>\n<code>bun add -g @openai/codex</code>",
|
|
345
|
+
} as CoreResponse);
|
|
346
|
+
}
|
|
347
|
+
|
|
332
348
|
// Route based on current backend state
|
|
333
349
|
const backend = getBackend(msg.chatId);
|
|
334
|
-
const deps = checkDeps();
|
|
335
350
|
const canFallback = backend === "codex" ? deps.claude : deps.codex;
|
|
336
351
|
let agentResponse: string;
|
|
337
352
|
let historyResponse: string | null = null;
|
|
@@ -363,6 +378,11 @@ ${messageText}`;
|
|
|
363
378
|
} else {
|
|
364
379
|
try {
|
|
365
380
|
agentResponse = await processWithClaude(enrichedMessage, msg.chatId);
|
|
381
|
+
if (agentResponse.startsWith("Error:") && canFallback) {
|
|
382
|
+
log.warn("Claude failed, falling back to Codex");
|
|
383
|
+
agentResponse = await processWithCodex(enrichedMessage);
|
|
384
|
+
usedBackend = "codex";
|
|
385
|
+
}
|
|
366
386
|
if (isClaudeRateLimitResponse(agentResponse) && canFallback) {
|
|
367
387
|
log.warn("Claude credits exhausted, falling back to Codex");
|
|
368
388
|
const codexResponse = await processWithCodex(enrichedMessage);
|
package/src/shared/ai-cli.ts
CHANGED
|
@@ -3,10 +3,51 @@
|
|
|
3
3
|
* @role Resolve agent CLI binaries and execute them via Bun runtime.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { existsSync } from "fs";
|
|
7
|
+
import { delimiter, dirname, join } from "path";
|
|
8
|
+
|
|
6
9
|
export type AgentCliName = "claude" | "codex";
|
|
7
10
|
|
|
11
|
+
function unique(paths: Array<string | null | undefined>): string[] {
|
|
12
|
+
const seen = new Set<string>();
|
|
13
|
+
const out: string[] = [];
|
|
14
|
+
for (const p of paths) {
|
|
15
|
+
if (!p) continue;
|
|
16
|
+
if (seen.has(p)) continue;
|
|
17
|
+
seen.add(p);
|
|
18
|
+
out.push(p);
|
|
19
|
+
}
|
|
20
|
+
return out;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function cliOverrideEnvVar(cli: AgentCliName): string | undefined {
|
|
24
|
+
return cli === "codex" ? process.env.ARISA_CODEX_BIN : process.env.ARISA_CLAUDE_BIN;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function candidatePaths(cli: AgentCliName): string[] {
|
|
28
|
+
const bunInstall = process.env.BUN_INSTALL?.trim();
|
|
29
|
+
const bunDir = dirname(process.execPath);
|
|
30
|
+
const fromPath = Bun.which(cli);
|
|
31
|
+
const fromEnvPath = (process.env.PATH || "")
|
|
32
|
+
.split(delimiter)
|
|
33
|
+
.map((entry) => entry.trim())
|
|
34
|
+
.filter(Boolean)
|
|
35
|
+
.map((entry) => join(entry, cli));
|
|
36
|
+
|
|
37
|
+
return unique([
|
|
38
|
+
cliOverrideEnvVar(cli),
|
|
39
|
+
bunInstall ? join(bunInstall, "bin", cli) : null,
|
|
40
|
+
join(bunDir, cli),
|
|
41
|
+
fromPath,
|
|
42
|
+
...fromEnvPath,
|
|
43
|
+
]);
|
|
44
|
+
}
|
|
45
|
+
|
|
8
46
|
export function resolveAgentCliPath(cli: AgentCliName): string | null {
|
|
9
|
-
|
|
47
|
+
for (const candidate of candidatePaths(cli)) {
|
|
48
|
+
if (existsSync(candidate)) return candidate;
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
10
51
|
}
|
|
11
52
|
|
|
12
53
|
export function isAgentCliInstalled(cli: AgentCliName): boolean {
|
|
@@ -16,7 +57,7 @@ export function isAgentCliInstalled(cli: AgentCliName): boolean {
|
|
|
16
57
|
export function buildBunWrappedAgentCliCommand(cli: AgentCliName, args: string[]): string[] {
|
|
17
58
|
const cliPath = resolveAgentCliPath(cli);
|
|
18
59
|
if (!cliPath) {
|
|
19
|
-
throw new Error(`${cli} CLI not found
|
|
60
|
+
throw new Error(`${cli} CLI not found`);
|
|
20
61
|
}
|
|
21
62
|
return ["bun", "--bun", cliPath, ...args];
|
|
22
63
|
}
|