@emqo/claudebridge 0.5.1 → 0.5.3
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/adapters/discord.js +7 -0
- package/dist/adapters/telegram.js +17 -3
- package/dist/core/agent.d.ts +1 -0
- package/dist/core/agent.js +13 -8
- package/dist/core/store.d.ts +2 -1
- package/dist/core/store.js +7 -5
- package/dist/index.js +5 -1
- package/package.json +1 -1
package/dist/adapters/discord.js
CHANGED
|
@@ -242,6 +242,13 @@ export class DiscordAdapter {
|
|
|
242
242
|
const res = this.maxParallel > 1
|
|
243
243
|
? await this.engine.runParallel(task.user_id, task.description, "discord", task.chat_id)
|
|
244
244
|
: await this.engine.runStream(task.user_id, task.description, "discord", task.chat_id);
|
|
245
|
+
if (res.timedOut) {
|
|
246
|
+
this.store.markTaskResult(task.id, "failed");
|
|
247
|
+
if (res.text)
|
|
248
|
+
this.store.setTaskResult(task.id, res.text.slice(0, 10000));
|
|
249
|
+
await channel.send(t(this.locale, "auto_failed", { id: task.id, err: "timed out" }));
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
245
252
|
this.store.markTaskResult(task.id, "done");
|
|
246
253
|
if (res.text)
|
|
247
254
|
this.store.setTaskResult(task.id, res.text.slice(0, 10000));
|
|
@@ -396,14 +396,28 @@ export class TelegramAdapter {
|
|
|
396
396
|
const res = this.maxParallel > 1
|
|
397
397
|
? await this.engine.runParallel(task.user_id, task.description, "telegram", task.chat_id)
|
|
398
398
|
: await this.engine.runStream(task.user_id, task.description, "telegram", task.chat_id);
|
|
399
|
+
if (res.timedOut) {
|
|
400
|
+
this.store.markTaskResult(task.id, "failed");
|
|
401
|
+
if (res.text)
|
|
402
|
+
this.store.setTaskResult(task.id, res.text.slice(0, 10000));
|
|
403
|
+
await this.reply(chatId, t(this.locale, "auto_failed", { id: task.id, err: "timed out" }));
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
399
406
|
this.store.markTaskResult(task.id, "done");
|
|
400
407
|
if (res.text)
|
|
401
408
|
this.store.setTaskResult(task.id, res.text.slice(0, 10000));
|
|
402
409
|
const maxLen = this.config.chunk_size || 4000;
|
|
403
|
-
const
|
|
410
|
+
const rawChunks = chunkText(res.text || "(no output)", maxLen);
|
|
411
|
+
const mdChunks = chunkText(toTelegramMarkdown(res.text || "(no output)"), maxLen);
|
|
404
412
|
await this.reply(chatId, t(this.locale, "auto_done", { id: task.id, cost: (res.cost || 0).toFixed(4) }));
|
|
405
|
-
for (
|
|
406
|
-
|
|
413
|
+
for (let i = 0; i < mdChunks.length; i++) {
|
|
414
|
+
try {
|
|
415
|
+
await this.call("sendMessage", { chat_id: chatId, text: mdChunks[i], parse_mode: "MarkdownV2" });
|
|
416
|
+
}
|
|
417
|
+
catch {
|
|
418
|
+
await this.reply(chatId, rawChunks[i] || mdChunks[i]);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
407
421
|
// Chain progress reporting
|
|
408
422
|
if (task.parent_id) {
|
|
409
423
|
const progress = this.store.getChainProgress(task.parent_id);
|
package/dist/core/agent.d.ts
CHANGED
package/dist/core/agent.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn } from "child_process";
|
|
2
2
|
import { mkdirSync } from "fs";
|
|
3
|
-
import { join
|
|
3
|
+
import { join } from "path";
|
|
4
4
|
import { UserLock } from "./lock.js";
|
|
5
5
|
import { AccessControl } from "./permissions.js";
|
|
6
6
|
import { EndpointRotator } from "./keys.js";
|
|
@@ -146,11 +146,11 @@ export class AgentEngine {
|
|
|
146
146
|
env.ANTHROPIC_API_KEY = ep.api_key;
|
|
147
147
|
if (ep.base_url)
|
|
148
148
|
env.ANTHROPIC_BASE_URL = ep.base_url;
|
|
149
|
-
env.CLAUDEBRIDGE_DB =
|
|
149
|
+
env.CLAUDEBRIDGE_DB = this.store.dbPath;
|
|
150
150
|
const child = spawn("claude", args, { cwd, env, stdio: ["pipe", "pipe", "pipe"] });
|
|
151
151
|
child.stdin.end();
|
|
152
152
|
console.log(`[agent] spawned claude pid=${child.pid} cwd=${cwd} args=${args.join(" ")}`);
|
|
153
|
-
const timeoutMs = (this.config.agent.timeout_seconds ||
|
|
153
|
+
const timeoutMs = (this.config.agent.timeout_seconds || 600) * 1000;
|
|
154
154
|
const timer = setTimeout(() => { try {
|
|
155
155
|
child.kill("SIGTERM");
|
|
156
156
|
}
|
|
@@ -205,9 +205,10 @@ export class AgentEngine {
|
|
|
205
205
|
clearTimeout(timer);
|
|
206
206
|
console.log(`[agent] claude exited code=${code} signal=${signal} fullText=${fullText.length}chars stderr=${stderr.slice(0, 200)}`);
|
|
207
207
|
if (signal === "SIGTERM") {
|
|
208
|
+
console.warn(`[agent] claude timed out after ${timeoutMs / 1000}s`);
|
|
208
209
|
if (newSessionId)
|
|
209
210
|
this.store.setSession(userId, newSessionId, platform);
|
|
210
|
-
resolve({ text: fullText.trim() || "(timed out)", sessionId: newSessionId, cost });
|
|
211
|
+
resolve({ text: fullText.trim() || "(timed out)", sessionId: newSessionId, cost, timedOut: true });
|
|
211
212
|
return;
|
|
212
213
|
}
|
|
213
214
|
if (code === 0 || fullText.trim()) {
|
|
@@ -252,11 +253,11 @@ export class AgentEngine {
|
|
|
252
253
|
env.ANTHROPIC_API_KEY = ep.api_key;
|
|
253
254
|
if (ep.base_url)
|
|
254
255
|
env.ANTHROPIC_BASE_URL = ep.base_url;
|
|
255
|
-
env.CLAUDEBRIDGE_DB =
|
|
256
|
+
env.CLAUDEBRIDGE_DB = this.store.dbPath;
|
|
256
257
|
const child = spawn("claude", args, { cwd, env, stdio: ["pipe", "pipe", "pipe"] });
|
|
257
258
|
child.stdin.end();
|
|
258
259
|
console.log(`[agent] spawned claude (parallel) pid=${child.pid} cwd=${cwd}`);
|
|
259
|
-
const timeoutMs = (this.config.agent.timeout_seconds ||
|
|
260
|
+
const timeoutMs = (this.config.agent.timeout_seconds || 600) * 1000;
|
|
260
261
|
const timer = setTimeout(() => { try {
|
|
261
262
|
child.kill("SIGTERM");
|
|
262
263
|
}
|
|
@@ -301,8 +302,12 @@ export class AgentEngine {
|
|
|
301
302
|
child.on("close", (code, signal) => {
|
|
302
303
|
clearTimeout(timer);
|
|
303
304
|
console.log(`[agent] claude (parallel) exited code=${code} signal=${signal} text=${fullText.length}chars`);
|
|
304
|
-
if (
|
|
305
|
-
|
|
305
|
+
if (signal === "SIGTERM") {
|
|
306
|
+
console.warn(`[agent] claude (parallel) timed out after ${timeoutMs / 1000}s`);
|
|
307
|
+
resolve({ text: fullText.trim() || "(timed out)", sessionId, cost, timedOut: true });
|
|
308
|
+
}
|
|
309
|
+
else if (code === 0 || fullText.trim()) {
|
|
310
|
+
resolve({ text: fullText.trim() || "(no response)", sessionId, cost });
|
|
306
311
|
}
|
|
307
312
|
else {
|
|
308
313
|
reject(new Error(`claude exited ${code}: ${stderr.slice(0, 500)}`));
|
package/dist/core/store.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare class Store {
|
|
2
2
|
private db;
|
|
3
|
-
|
|
3
|
+
readonly dbPath: string;
|
|
4
|
+
constructor(dbPath?: string);
|
|
4
5
|
getSession(userId: string): string | null;
|
|
5
6
|
setSession(userId: string, sessionId: string, platform: string): void;
|
|
6
7
|
clearSession(userId: string): void;
|
package/dist/core/store.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import Database from "better-sqlite3";
|
|
2
2
|
import { mkdirSync } from "fs";
|
|
3
|
-
import { dirname } from "path";
|
|
4
|
-
const
|
|
3
|
+
import { dirname, resolve } from "path";
|
|
4
|
+
const DEFAULT_DB_PATH = "./data/claudebridge.db";
|
|
5
5
|
export class Store {
|
|
6
6
|
db;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
this.
|
|
7
|
+
dbPath;
|
|
8
|
+
constructor(dbPath) {
|
|
9
|
+
this.dbPath = resolve(dbPath || DEFAULT_DB_PATH);
|
|
10
|
+
mkdirSync(dirname(this.dbPath), { recursive: true });
|
|
11
|
+
this.db = new Database(this.dbPath);
|
|
10
12
|
this.db.pragma("journal_mode = WAL");
|
|
11
13
|
this.db.exec(`
|
|
12
14
|
CREATE TABLE IF NOT EXISTS sessions (
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { setDefaultAutoSelectFamily } from "net";
|
|
2
2
|
setDefaultAutoSelectFamily(false);
|
|
3
3
|
import { watch } from "fs";
|
|
4
|
+
import { join, dirname, resolve } from "path";
|
|
4
5
|
import { loadConfig, reloadConfig } from "./core/config.js";
|
|
5
6
|
import { Store } from "./core/store.js";
|
|
6
7
|
import { AgentEngine } from "./core/agent.js";
|
|
@@ -11,7 +12,10 @@ async function main() {
|
|
|
11
12
|
const _cfgIdx = process.argv.indexOf("--config");
|
|
12
13
|
const _cfgPath = _cfgIdx !== -1 ? process.argv[_cfgIdx + 1] : undefined;
|
|
13
14
|
let config = loadConfig(_cfgPath);
|
|
14
|
-
|
|
15
|
+
// Derive DB path from config file directory (not CWD)
|
|
16
|
+
const configDir = _cfgPath ? dirname(resolve(_cfgPath)) : process.cwd();
|
|
17
|
+
const dbPath = join(configDir, "data", "claudebridge.db");
|
|
18
|
+
const store = new Store(dbPath);
|
|
15
19
|
const engine = new AgentEngine(config, store);
|
|
16
20
|
const adapters = [];
|
|
17
21
|
let webhookServer = null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@emqo/claudebridge",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "Bridge claude CLI to chat platforms (Telegram, Discord) with HITL approval, conditional branching, webhook triggers, parallel execution, and observability",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|