@raysonmeng/agentbridge 0.1.18 → 0.1.19
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/.claude-plugin/marketplace.json +1 -1
- package/dist/cli.js +24 -12
- package/dist/daemon.js +439 -28
- package/package.json +1 -1
- package/plugins/agentbridge/.claude-plugin/plugin.json +1 -1
- package/plugins/agentbridge/server/bridge-server.js +30 -14
- package/plugins/agentbridge/server/daemon.js +439 -28
package/package.json
CHANGED
|
@@ -13858,6 +13858,9 @@ class StateDirResolver {
|
|
|
13858
13858
|
get killedFile() {
|
|
13859
13859
|
return join(this.stateDir, "killed");
|
|
13860
13860
|
}
|
|
13861
|
+
get admissionQuotaFile() {
|
|
13862
|
+
return join(this.stateDir, "admission-quota.json");
|
|
13863
|
+
}
|
|
13861
13864
|
get updateCheckFile() {
|
|
13862
13865
|
return join(this.stateDir, "update-check.json");
|
|
13863
13866
|
}
|
|
@@ -14156,7 +14159,8 @@ var CLAUDE_INSTRUCTIONS = [
|
|
|
14156
14159
|
"",
|
|
14157
14160
|
"## Budget awareness",
|
|
14158
14161
|
"- Use the get_budget tool to check both agents' subscription quota (5h/weekly windows, drift, pause state).",
|
|
14159
|
-
"- If the reply tool returns a budget-pause error, do NOT retry; checkpoint your work and wait for the resume notice."
|
|
14162
|
+
"- If the reply tool returns a budget-pause error (code budget_paused), do NOT retry; checkpoint your work and wait for the resume notice.",
|
|
14163
|
+
"- If the reply tool returns a budget_admission error, the 5h window is in finishing-protection: new tasks are declined, but you may bring the CURRENT collaboration to a checkpoint by resending with wrap_up=true (a small per-window quota). Do NOT start new work; once the quota is used or you are done, write a checkpoint and wait for the 5h window to refresh."
|
|
14160
14164
|
].join(`
|
|
14161
14165
|
`);
|
|
14162
14166
|
|
|
@@ -14400,6 +14404,10 @@ chat_id: ${this.sessionId}`);
|
|
|
14400
14404
|
idempotency_key: {
|
|
14401
14405
|
type: "string",
|
|
14402
14406
|
description: "Optional client-generated key (non-empty, max 128 chars) that makes this reply idempotent: a retry carrying the same key is NOT re-injected \u2014 the bridge answers duplicate_in_flight / duplicate_terminal instead. Use a fresh key per logical message."
|
|
14407
|
+
},
|
|
14408
|
+
wrap_up: {
|
|
14409
|
+
type: "boolean",
|
|
14410
|
+
description: "Set true ONLY to declare a finishing turn when the budget gate is in 5h finishing-protection (you got a budget_admission error or a system_budget_admission notice). A wrap-up reply is let through the admission gate up to a small per-5h-window quota so you can bring the current collaboration to a checkpoint; do NOT use it to start new work. Leave false/unset for normal replies."
|
|
14403
14411
|
}
|
|
14404
14412
|
},
|
|
14405
14413
|
required: ["text"]
|
|
@@ -14552,7 +14560,8 @@ chat_id: ${this.sessionId}`);
|
|
|
14552
14560
|
isError: true
|
|
14553
14561
|
};
|
|
14554
14562
|
}
|
|
14555
|
-
const
|
|
14563
|
+
const wrapUp = args?.wrap_up === true;
|
|
14564
|
+
const result = await this.replySender(bridgeMsg, requireReply, onBusy, idempotencyKey, wrapUp);
|
|
14556
14565
|
if (!result.success) {
|
|
14557
14566
|
this.log(`Reply delivery failed: ${result.error}${result.code ? ` (code=${result.code})` : ""}`);
|
|
14558
14567
|
const codePrefix = result.code ? ` [${result.code}]` : "";
|
|
@@ -14622,11 +14631,11 @@ function defineNumber(value, fallback) {
|
|
|
14622
14631
|
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
14623
14632
|
}
|
|
14624
14633
|
var BUILD_INFO = Object.freeze({
|
|
14625
|
-
version: defineString("0.1.
|
|
14626
|
-
commit: defineString("
|
|
14634
|
+
version: defineString("0.1.19", "0.0.0-source"),
|
|
14635
|
+
commit: defineString("dee06ce", "source"),
|
|
14627
14636
|
bundle: defineBundle("plugin"),
|
|
14628
14637
|
contractVersion: defineNumber(1, CONTRACT_VERSION),
|
|
14629
|
-
codeHash: defineString("
|
|
14638
|
+
codeHash: defineString("9ddee00c61f9", "source")
|
|
14630
14639
|
});
|
|
14631
14640
|
function sameRuntimeContract(a, b) {
|
|
14632
14641
|
if (!a || !b)
|
|
@@ -14873,7 +14882,7 @@ class DaemonClient extends EventEmitter2 {
|
|
|
14873
14882
|
this.ws = null;
|
|
14874
14883
|
this.rejectPendingReplies("Daemon connection closed");
|
|
14875
14884
|
}
|
|
14876
|
-
async sendReply(message, requireReply, onBusy, idempotencyKey) {
|
|
14885
|
+
async sendReply(message, requireReply, onBusy, idempotencyKey, wrapUp) {
|
|
14877
14886
|
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
14878
14887
|
return { success: false, error: "AgentBridge daemon is not connected." };
|
|
14879
14888
|
}
|
|
@@ -14888,7 +14897,8 @@ class DaemonClient extends EventEmitter2 {
|
|
|
14888
14897
|
message,
|
|
14889
14898
|
...requireReply ? { requireReply: true } : {},
|
|
14890
14899
|
...onBusy && onBusy !== "reject" ? { onBusy } : {},
|
|
14891
|
-
...idempotencyKey ? { idempotencyKey } : {}
|
|
14900
|
+
...idempotencyKey ? { idempotencyKey } : {},
|
|
14901
|
+
...wrapUp ? { wrapUp: true } : {}
|
|
14892
14902
|
});
|
|
14893
14903
|
return pending;
|
|
14894
14904
|
}
|
|
@@ -15666,7 +15676,9 @@ var DEFAULT_BUDGET_CONFIG = {
|
|
|
15666
15676
|
reserveSlopePctPerHour: 0.4,
|
|
15667
15677
|
reserveMaxPct: 7,
|
|
15668
15678
|
finishingHorizonMinutes: 30,
|
|
15669
|
-
resumeHysteresisPct: 5
|
|
15679
|
+
resumeHysteresisPct: 5,
|
|
15680
|
+
admissionAt: 85,
|
|
15681
|
+
wrapUpQuota: 2
|
|
15670
15682
|
},
|
|
15671
15683
|
allocation: {
|
|
15672
15684
|
minRunwayRatio: 50,
|
|
@@ -15734,7 +15746,9 @@ function findShapeViolation(raw) {
|
|
|
15734
15746
|
"reserveSlopePctPerHour",
|
|
15735
15747
|
"reserveMaxPct",
|
|
15736
15748
|
"finishingHorizonMinutes",
|
|
15737
|
-
"resumeHysteresisPct"
|
|
15749
|
+
"resumeHysteresisPct",
|
|
15750
|
+
"admissionAt",
|
|
15751
|
+
"wrapUpQuota"
|
|
15738
15752
|
]) {
|
|
15739
15753
|
if (key in maximize && !isCoercibleNumber(maximize[key])) {
|
|
15740
15754
|
return `budget.maximize.${key} is present but not a number`;
|
|
@@ -15759,7 +15773,7 @@ function hasCustomDecisionValues(config2) {
|
|
|
15759
15773
|
const d = DEFAULT_CONFIG;
|
|
15760
15774
|
const b = config2.budget;
|
|
15761
15775
|
const db = d.budget;
|
|
15762
|
-
return config2.idleShutdownSeconds !== d.idleShutdownSeconds || config2.turnCoordination.attentionWindowSeconds !== d.turnCoordination.attentionWindowSeconds || config2.codex.appPort !== d.codex.appPort || config2.codex.proxyPort !== d.codex.proxyPort || b.enabled !== db.enabled || b.pollSeconds !== db.pollSeconds || b.pauseAt !== db.pauseAt || b.resumeBelow !== db.resumeBelow || b.syncDriftPct !== db.syncDriftPct || b.parallel.minRemainingPct !== db.parallel.minRemainingPct || b.parallel.timeWindowSec !== db.parallel.timeWindowSec || b.codexTierControl !== db.codexTierControl || b.maximize.targetUtil !== db.maximize.targetUtil || b.maximize.reserveSlopePctPerHour !== db.maximize.reserveSlopePctPerHour || b.maximize.reserveMaxPct !== db.maximize.reserveMaxPct || b.maximize.finishingHorizonMinutes !== db.maximize.finishingHorizonMinutes || b.maximize.resumeHysteresisPct !== db.maximize.resumeHysteresisPct || b.allocation.minRunwayRatio !== db.allocation.minRunwayRatio || b.allocation.minRunwayGapHours !== db.allocation.minRunwayGapHours;
|
|
15776
|
+
return config2.idleShutdownSeconds !== d.idleShutdownSeconds || config2.turnCoordination.attentionWindowSeconds !== d.turnCoordination.attentionWindowSeconds || config2.codex.appPort !== d.codex.appPort || config2.codex.proxyPort !== d.codex.proxyPort || b.enabled !== db.enabled || b.pollSeconds !== db.pollSeconds || b.pauseAt !== db.pauseAt || b.resumeBelow !== db.resumeBelow || b.syncDriftPct !== db.syncDriftPct || b.parallel.minRemainingPct !== db.parallel.minRemainingPct || b.parallel.timeWindowSec !== db.parallel.timeWindowSec || b.codexTierControl !== db.codexTierControl || b.maximize.targetUtil !== db.maximize.targetUtil || b.maximize.reserveSlopePctPerHour !== db.maximize.reserveSlopePctPerHour || b.maximize.reserveMaxPct !== db.maximize.reserveMaxPct || b.maximize.finishingHorizonMinutes !== db.maximize.finishingHorizonMinutes || b.maximize.resumeHysteresisPct !== db.maximize.resumeHysteresisPct || b.maximize.admissionAt !== db.maximize.admissionAt || b.maximize.wrapUpQuota !== db.maximize.wrapUpQuota || b.allocation.minRunwayRatio !== db.allocation.minRunwayRatio || b.allocation.minRunwayGapHours !== db.allocation.minRunwayGapHours;
|
|
15763
15777
|
}
|
|
15764
15778
|
function normalizeInteger(value, fallback) {
|
|
15765
15779
|
if (typeof value === "number" && Number.isFinite(value))
|
|
@@ -15799,9 +15813,11 @@ function normalizeMaximizeConfig(raw, pauseAt, fallback = DEFAULT_BUDGET_CONFIG.
|
|
|
15799
15813
|
reserveSlopePctPerHour: normalizeBoundedNumber(m.reserveSlopePctPerHour, fallback.reserveSlopePctPerHour, 0, 5),
|
|
15800
15814
|
reserveMaxPct: normalizeBoundedInteger(m.reserveMaxPct, fallback.reserveMaxPct, 0, 30),
|
|
15801
15815
|
finishingHorizonMinutes: normalizeBoundedInteger(m.finishingHorizonMinutes, fallback.finishingHorizonMinutes, 5, 180),
|
|
15802
|
-
resumeHysteresisPct: normalizeBoundedInteger(m.resumeHysteresisPct, fallback.resumeHysteresisPct, 1, 30)
|
|
15816
|
+
resumeHysteresisPct: normalizeBoundedInteger(m.resumeHysteresisPct, fallback.resumeHysteresisPct, 1, 30),
|
|
15817
|
+
admissionAt: normalizeBoundedInteger(m.admissionAt, fallback.admissionAt, 50, 99),
|
|
15818
|
+
wrapUpQuota: Math.floor(normalizeBoundedInteger(m.wrapUpQuota, fallback.wrapUpQuota, 0, 10))
|
|
15803
15819
|
};
|
|
15804
|
-
if (normalized.targetUtil <= pauseAt) {
|
|
15820
|
+
if (normalized.targetUtil <= pauseAt || normalized.admissionAt >= normalized.targetUtil) {
|
|
15805
15821
|
return { ...DEFAULT_BUDGET_CONFIG.maximize };
|
|
15806
15822
|
}
|
|
15807
15823
|
return normalized;
|
|
@@ -16383,7 +16399,7 @@ if (process.env.AGENTBRIDGE_TRACE === "1") {
|
|
|
16383
16399
|
});
|
|
16384
16400
|
} catch {}
|
|
16385
16401
|
}
|
|
16386
|
-
claude.setReplySender(async (msg, requireReply, onBusy, idempotencyKey) => {
|
|
16402
|
+
claude.setReplySender(async (msg, requireReply, onBusy, idempotencyKey, wrapUp) => {
|
|
16387
16403
|
if (msg.source !== "claude") {
|
|
16388
16404
|
return { success: false, error: "Invalid message source" };
|
|
16389
16405
|
}
|
|
@@ -16393,7 +16409,7 @@ claude.setReplySender(async (msg, requireReply, onBusy, idempotencyKey) => {
|
|
|
16393
16409
|
error: disabledReplyError(daemonDisabledReason ?? "killed")
|
|
16394
16410
|
};
|
|
16395
16411
|
}
|
|
16396
|
-
return daemonClient.sendReply(msg, requireReply, onBusy, idempotencyKey);
|
|
16412
|
+
return daemonClient.sendReply(msg, requireReply, onBusy, idempotencyKey, wrapUp);
|
|
16397
16413
|
});
|
|
16398
16414
|
claude.setResumeAckHandler((resumeId, status) => {
|
|
16399
16415
|
if (daemonDisabled) {
|