@raysonmeng/agentbridge 0.1.2 → 0.1.4
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.
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
{
|
|
13
13
|
"name": "agentbridge",
|
|
14
14
|
"description": "Bridge Claude Code and Codex through a shared daemon, push channel delivery, and reply/get_messages tools.",
|
|
15
|
-
"version": "0.1.
|
|
15
|
+
"version": "0.1.4",
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "AgentBridge Contributors",
|
|
18
18
|
"email": "raysonmeng@qq.com"
|
package/dist/cli.js
CHANGED
|
@@ -1012,7 +1012,7 @@ var init_kill = __esm(() => {
|
|
|
1012
1012
|
var require_package = __commonJS((exports, module) => {
|
|
1013
1013
|
module.exports = {
|
|
1014
1014
|
name: "@raysonmeng/agentbridge",
|
|
1015
|
-
version: "0.1.
|
|
1015
|
+
version: "0.1.4",
|
|
1016
1016
|
description: "Bridge between Claude Code and Codex \u2014 bidirectional agent communication via MCP Channel + JSON-RPC",
|
|
1017
1017
|
type: "module",
|
|
1018
1018
|
bin: {
|
package/package.json
CHANGED
|
@@ -9,8 +9,52 @@ import { spawn, execSync } from "child_process";
|
|
|
9
9
|
import { createInterface } from "readline";
|
|
10
10
|
import { EventEmitter } from "events";
|
|
11
11
|
import { appendFileSync } from "fs";
|
|
12
|
+
|
|
13
|
+
// src/app-server-protocol.ts
|
|
14
|
+
var APP_SERVER_TRACKED_REQUEST_METHODS = [
|
|
15
|
+
"thread/start",
|
|
16
|
+
"thread/resume",
|
|
17
|
+
"turn/start"
|
|
18
|
+
];
|
|
19
|
+
var APP_SERVER_SERVER_REQUEST_METHODS = [
|
|
20
|
+
"item/permissions/requestApproval",
|
|
21
|
+
"item/fileChange/requestApproval",
|
|
22
|
+
"item/commandExecution/requestApproval"
|
|
23
|
+
];
|
|
24
|
+
var APP_SERVER_NOTIFICATION_METHODS = [
|
|
25
|
+
"turn/started",
|
|
26
|
+
"turn/completed",
|
|
27
|
+
"item/started",
|
|
28
|
+
"item/agentMessage/delta",
|
|
29
|
+
"item/completed"
|
|
30
|
+
];
|
|
31
|
+
var TRACKED_REQUEST_METHOD_SET = new Set(APP_SERVER_TRACKED_REQUEST_METHODS);
|
|
32
|
+
var SERVER_REQUEST_METHOD_SET = new Set(APP_SERVER_SERVER_REQUEST_METHODS);
|
|
33
|
+
var NOTIFICATION_METHOD_SET = new Set(APP_SERVER_NOTIFICATION_METHODS);
|
|
34
|
+
function isObjectRecord(value) {
|
|
35
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36
|
+
}
|
|
37
|
+
function isTrackedAppServerRequestMethod(method) {
|
|
38
|
+
return typeof method === "string" && TRACKED_REQUEST_METHOD_SET.has(method);
|
|
39
|
+
}
|
|
40
|
+
function isAppServerRequestMessage(value) {
|
|
41
|
+
if (!isObjectRecord(value))
|
|
42
|
+
return false;
|
|
43
|
+
return (typeof value.id === "number" || typeof value.id === "string") && typeof value.method === "string";
|
|
44
|
+
}
|
|
45
|
+
function isAppServerNotification(value) {
|
|
46
|
+
if (!isObjectRecord(value))
|
|
47
|
+
return false;
|
|
48
|
+
return value.id === undefined && typeof value.method === "string" && NOTIFICATION_METHOD_SET.has(value.method);
|
|
49
|
+
}
|
|
50
|
+
function isAppServerResponseMessage(value) {
|
|
51
|
+
if (!isObjectRecord(value))
|
|
52
|
+
return false;
|
|
53
|
+
return (typeof value.id === "number" || typeof value.id === "string") && value.method === undefined && (("result" in value) || ("error" in value));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/codex-adapter.ts
|
|
12
57
|
var LOG_FILE = "/tmp/agentbridge.log";
|
|
13
|
-
var TRACKED_REQUEST_METHODS = new Set(["thread/start", "thread/resume", "turn/start"]);
|
|
14
58
|
|
|
15
59
|
class CodexAdapter extends EventEmitter {
|
|
16
60
|
static RESPONSE_TRACKING_TTL_MS = 30000;
|
|
@@ -320,16 +364,21 @@ class CodexAdapter extends EventEmitter {
|
|
|
320
364
|
handleAppServerPayload(raw) {
|
|
321
365
|
try {
|
|
322
366
|
const parsed = JSON.parse(raw);
|
|
323
|
-
if (parsed
|
|
324
|
-
const
|
|
325
|
-
this.
|
|
367
|
+
if (isAppServerNotification(parsed) || typeof parsed === "object" && parsed !== null && !("id" in parsed)) {
|
|
368
|
+
const notificationLike = parsed;
|
|
369
|
+
const forwarded = this.patchResponse(notificationLike, raw);
|
|
370
|
+
this.interceptServerMessage(notificationLike);
|
|
326
371
|
return forwarded;
|
|
327
372
|
}
|
|
328
|
-
if (parsed
|
|
373
|
+
if (isAppServerRequestMessage(parsed)) {
|
|
329
374
|
this.handleServerRequest(parsed, raw);
|
|
330
375
|
return null;
|
|
331
376
|
}
|
|
332
|
-
|
|
377
|
+
if (isAppServerResponseMessage(parsed)) {
|
|
378
|
+
return this.handleAppServerResponse(parsed, raw);
|
|
379
|
+
}
|
|
380
|
+
this.log(`Dropping unclassifiable app-server message: ${raw.slice(0, 100)}`);
|
|
381
|
+
return null;
|
|
333
382
|
} catch {
|
|
334
383
|
return raw;
|
|
335
384
|
}
|
|
@@ -392,7 +441,7 @@ class CodexAdapter extends EventEmitter {
|
|
|
392
441
|
return null;
|
|
393
442
|
}
|
|
394
443
|
patchResponse(parsed, raw) {
|
|
395
|
-
if (parsed.error && parsed.id !== undefined) {
|
|
444
|
+
if (isAppServerResponseMessage(parsed) && parsed.error && parsed.id !== undefined) {
|
|
396
445
|
const errMsg = parsed.error.message ?? "";
|
|
397
446
|
if (errMsg.includes("rate limits") || errMsg.includes("rateLimits")) {
|
|
398
447
|
this.log(`Patching rateLimits error \u2192 mock success (id: ${parsed.id})`);
|
|
@@ -427,8 +476,9 @@ class CodexAdapter extends EventEmitter {
|
|
|
427
476
|
}
|
|
428
477
|
interceptServerMessage(msg, connId) {
|
|
429
478
|
this.handleTrackedResponse(msg, connId);
|
|
430
|
-
if (msg.method)
|
|
479
|
+
if ("method" in msg && typeof msg.method === "string" && isAppServerNotification(msg)) {
|
|
431
480
|
this.handleServerNotification(msg);
|
|
481
|
+
}
|
|
432
482
|
}
|
|
433
483
|
handleServerNotification(msg) {
|
|
434
484
|
const { method, params } = msg;
|
|
@@ -443,7 +493,10 @@ class CodexAdapter extends EventEmitter {
|
|
|
443
493
|
break;
|
|
444
494
|
}
|
|
445
495
|
case "item/agentMessage/delta": {
|
|
446
|
-
const
|
|
496
|
+
const itemId = params?.itemId;
|
|
497
|
+
if (typeof itemId !== "string")
|
|
498
|
+
break;
|
|
499
|
+
const buf = this.agentMessageBuffers.get(itemId);
|
|
447
500
|
if (buf && params?.delta)
|
|
448
501
|
buf.push(params.delta);
|
|
449
502
|
break;
|
|
@@ -488,14 +541,16 @@ class CodexAdapter extends EventEmitter {
|
|
|
488
541
|
return `${connId ?? this.tuiConnId}:${base}`;
|
|
489
542
|
}
|
|
490
543
|
trackPendingRequest(message, connId, _proxyId) {
|
|
491
|
-
const
|
|
492
|
-
const
|
|
493
|
-
|
|
494
|
-
|
|
544
|
+
const rpcId = "id" in message ? message.id : undefined;
|
|
545
|
+
const method = "method" in message && typeof message.method === "string" ? message.method : undefined;
|
|
546
|
+
const key = this.pendingKey(rpcId, connId);
|
|
547
|
+
this.log(`[track] method=${method} id=${rpcId} (type=${typeof rpcId}) key=${key}`);
|
|
548
|
+
if (!key || !isTrackedAppServerRequestMethod(method))
|
|
495
549
|
return;
|
|
496
550
|
const pending = { method };
|
|
497
551
|
if (method === "turn/start") {
|
|
498
|
-
const
|
|
552
|
+
const params = "params" in message && typeof message.params === "object" && message.params !== null ? message.params : undefined;
|
|
553
|
+
const threadId = params?.threadId;
|
|
499
554
|
if (typeof threadId === "string" && threadId.length > 0) {
|
|
500
555
|
pending.threadId = threadId;
|
|
501
556
|
}
|