@cabane/companion 0.6.41 → 0.6.42
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/cli.js +24 -15
- package/dist/runtime.js +24 -15
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -7444,16 +7444,22 @@ async function proveWorkspaceTools(req, runtime, opts = {}) {
|
|
|
7444
7444
|
"x-cabane-active-conversation": req.cabane.activeConversationId
|
|
7445
7445
|
};
|
|
7446
7446
|
try {
|
|
7447
|
-
const initialized = await initializeWithRetry(
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7447
|
+
const initialized = await initializeWithRetry(
|
|
7448
|
+
fetchImpl,
|
|
7449
|
+
req.cabane.mcpUrl,
|
|
7450
|
+
headers,
|
|
7451
|
+
{
|
|
7452
|
+
jsonrpc: "2.0",
|
|
7453
|
+
id: 1,
|
|
7454
|
+
method: "initialize",
|
|
7455
|
+
params: {
|
|
7456
|
+
protocolVersion: "2025-03-26",
|
|
7457
|
+
capabilities: {},
|
|
7458
|
+
clientInfo: { name: "cabane-companion-readiness", version: "1" }
|
|
7459
|
+
}
|
|
7460
|
+
},
|
|
7461
|
+
opts.retryDelaysMs ?? INITIALIZE_RETRY_DELAYS_MS
|
|
7462
|
+
);
|
|
7457
7463
|
if (initialized.status === 401 || initialized.status === 403)
|
|
7458
7464
|
return fail(base, "authentication_failed", `initialize returned HTTP ${initialized.status}`);
|
|
7459
7465
|
if (initialized.transient)
|
|
@@ -7497,10 +7503,10 @@ async function proveWorkspaceTools(req, runtime, opts = {}) {
|
|
|
7497
7503
|
);
|
|
7498
7504
|
}
|
|
7499
7505
|
}
|
|
7500
|
-
async function initializeWithRetry(fetchImpl, url, headers, body) {
|
|
7506
|
+
async function initializeWithRetry(fetchImpl, url, headers, body, retryDelaysMs) {
|
|
7501
7507
|
let lastFailure = null;
|
|
7502
7508
|
const deadline = Date.now() + INITIALIZE_RETRY_BUDGET_MS;
|
|
7503
|
-
for (let attempt = 0; attempt <=
|
|
7509
|
+
for (let attempt = 0; attempt <= retryDelaysMs.length; attempt += 1) {
|
|
7504
7510
|
try {
|
|
7505
7511
|
const remainingMs = deadline - Date.now();
|
|
7506
7512
|
if (remainingMs <= 0) break;
|
|
@@ -7524,7 +7530,7 @@ async function initializeWithRetry(fetchImpl, url, headers, body) {
|
|
|
7524
7530
|
transient: true
|
|
7525
7531
|
};
|
|
7526
7532
|
}
|
|
7527
|
-
const retryDelayMs =
|
|
7533
|
+
const retryDelayMs = retryDelaysMs[attempt];
|
|
7528
7534
|
if (retryDelayMs === void 0 || Date.now() + retryDelayMs >= deadline) break;
|
|
7529
7535
|
await delay(retryDelayMs);
|
|
7530
7536
|
}
|
|
@@ -8160,6 +8166,7 @@ ${reason}`,
|
|
|
8160
8166
|
}
|
|
8161
8167
|
const proof = await proveWorkspaceTools(request, adapter.name, {
|
|
8162
8168
|
...this.opts.workspaceProofFetch ? { fetchImpl: this.opts.workspaceProofFetch } : {},
|
|
8169
|
+
...this.opts.workspaceProofRetryDelaysMs ? { retryDelaysMs: this.opts.workspaceProofRetryDelaysMs } : {},
|
|
8163
8170
|
harnessFingerprint: turnContext.runtime
|
|
8164
8171
|
});
|
|
8165
8172
|
turnLog[proof.ok ? "info" : "error"](
|
|
@@ -8977,6 +8984,7 @@ var ASSIGNMENTS_POLL_MS = 6e4;
|
|
|
8977
8984
|
var DRAIN_BASE_MS = 1e3;
|
|
8978
8985
|
var DRAIN_MAX_MS = 3e4;
|
|
8979
8986
|
var DRAIN_IDLE_MS = 15e3;
|
|
8987
|
+
var DEFAULT_UNRUNNABLE_RETRY_DELAYS_MS = [0, 1e3, 3e3];
|
|
8980
8988
|
var CompanionSupervisor = class {
|
|
8981
8989
|
workspaces = /* @__PURE__ */ new Map();
|
|
8982
8990
|
config;
|
|
@@ -9003,6 +9011,7 @@ var CompanionSupervisor = class {
|
|
|
9003
9011
|
exitFn;
|
|
9004
9012
|
reexecFn;
|
|
9005
9013
|
dispatcherFactory;
|
|
9014
|
+
unrunnableRetryDelaysMs;
|
|
9006
9015
|
deviceApi = null;
|
|
9007
9016
|
deviceSub = null;
|
|
9008
9017
|
heartbeatTimer = null;
|
|
@@ -9035,6 +9044,7 @@ var CompanionSupervisor = class {
|
|
|
9035
9044
|
this.exitFn = opts.exit ?? ((code) => process.exit(code));
|
|
9036
9045
|
this.reexecFn = opts.reexec ?? defaultReexec;
|
|
9037
9046
|
this.dispatcherFactory = opts.dispatcherFactory;
|
|
9047
|
+
this.unrunnableRetryDelaysMs = opts.unrunnableRetryDelaysMs ?? DEFAULT_UNRUNNABLE_RETRY_DELAYS_MS;
|
|
9038
9048
|
}
|
|
9039
9049
|
// Stand up the data plane: pair check, initial assignments pull, then the
|
|
9040
9050
|
// heartbeat + poll loops. A companion with no device token (logged out) does
|
|
@@ -9539,9 +9549,8 @@ var CompanionSupervisor = class {
|
|
|
9539
9549
|
// wedge the workspace's whole stream.
|
|
9540
9550
|
async reportUnrunnableDispatch(wr, payload) {
|
|
9541
9551
|
if (!this.deviceApi) return false;
|
|
9542
|
-
const backoffMs = [0, 1e3, 3e3];
|
|
9543
9552
|
let lastErr;
|
|
9544
|
-
for (const wait of
|
|
9553
|
+
for (const wait of this.unrunnableRetryDelaysMs) {
|
|
9545
9554
|
if (this.stopped) return false;
|
|
9546
9555
|
if (wait > 0) await new Promise((r) => setTimeout(r, wait));
|
|
9547
9556
|
try {
|
package/dist/runtime.js
CHANGED
|
@@ -6953,16 +6953,22 @@ async function proveWorkspaceTools(req, runtime, opts = {}) {
|
|
|
6953
6953
|
"x-cabane-active-conversation": req.cabane.activeConversationId
|
|
6954
6954
|
};
|
|
6955
6955
|
try {
|
|
6956
|
-
const initialized = await initializeWithRetry(
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
|
|
6962
|
-
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
|
|
6956
|
+
const initialized = await initializeWithRetry(
|
|
6957
|
+
fetchImpl,
|
|
6958
|
+
req.cabane.mcpUrl,
|
|
6959
|
+
headers,
|
|
6960
|
+
{
|
|
6961
|
+
jsonrpc: "2.0",
|
|
6962
|
+
id: 1,
|
|
6963
|
+
method: "initialize",
|
|
6964
|
+
params: {
|
|
6965
|
+
protocolVersion: "2025-03-26",
|
|
6966
|
+
capabilities: {},
|
|
6967
|
+
clientInfo: { name: "cabane-companion-readiness", version: "1" }
|
|
6968
|
+
}
|
|
6969
|
+
},
|
|
6970
|
+
opts.retryDelaysMs ?? INITIALIZE_RETRY_DELAYS_MS
|
|
6971
|
+
);
|
|
6966
6972
|
if (initialized.status === 401 || initialized.status === 403)
|
|
6967
6973
|
return fail(base, "authentication_failed", `initialize returned HTTP ${initialized.status}`);
|
|
6968
6974
|
if (initialized.transient)
|
|
@@ -7006,10 +7012,10 @@ async function proveWorkspaceTools(req, runtime, opts = {}) {
|
|
|
7006
7012
|
);
|
|
7007
7013
|
}
|
|
7008
7014
|
}
|
|
7009
|
-
async function initializeWithRetry(fetchImpl, url, headers, body) {
|
|
7015
|
+
async function initializeWithRetry(fetchImpl, url, headers, body, retryDelaysMs) {
|
|
7010
7016
|
let lastFailure = null;
|
|
7011
7017
|
const deadline = Date.now() + INITIALIZE_RETRY_BUDGET_MS;
|
|
7012
|
-
for (let attempt = 0; attempt <=
|
|
7018
|
+
for (let attempt = 0; attempt <= retryDelaysMs.length; attempt += 1) {
|
|
7013
7019
|
try {
|
|
7014
7020
|
const remainingMs = deadline - Date.now();
|
|
7015
7021
|
if (remainingMs <= 0) break;
|
|
@@ -7033,7 +7039,7 @@ async function initializeWithRetry(fetchImpl, url, headers, body) {
|
|
|
7033
7039
|
transient: true
|
|
7034
7040
|
};
|
|
7035
7041
|
}
|
|
7036
|
-
const retryDelayMs =
|
|
7042
|
+
const retryDelayMs = retryDelaysMs[attempt];
|
|
7037
7043
|
if (retryDelayMs === void 0 || Date.now() + retryDelayMs >= deadline) break;
|
|
7038
7044
|
await delay(retryDelayMs);
|
|
7039
7045
|
}
|
|
@@ -7669,6 +7675,7 @@ ${reason}`,
|
|
|
7669
7675
|
}
|
|
7670
7676
|
const proof = await proveWorkspaceTools(request, adapter.name, {
|
|
7671
7677
|
...this.opts.workspaceProofFetch ? { fetchImpl: this.opts.workspaceProofFetch } : {},
|
|
7678
|
+
...this.opts.workspaceProofRetryDelaysMs ? { retryDelaysMs: this.opts.workspaceProofRetryDelaysMs } : {},
|
|
7672
7679
|
harnessFingerprint: turnContext.runtime
|
|
7673
7680
|
});
|
|
7674
7681
|
turnLog[proof.ok ? "info" : "error"](
|
|
@@ -8486,6 +8493,7 @@ var ASSIGNMENTS_POLL_MS = 6e4;
|
|
|
8486
8493
|
var DRAIN_BASE_MS = 1e3;
|
|
8487
8494
|
var DRAIN_MAX_MS = 3e4;
|
|
8488
8495
|
var DRAIN_IDLE_MS = 15e3;
|
|
8496
|
+
var DEFAULT_UNRUNNABLE_RETRY_DELAYS_MS = [0, 1e3, 3e3];
|
|
8489
8497
|
var CompanionSupervisor = class {
|
|
8490
8498
|
workspaces = /* @__PURE__ */ new Map();
|
|
8491
8499
|
config;
|
|
@@ -8512,6 +8520,7 @@ var CompanionSupervisor = class {
|
|
|
8512
8520
|
exitFn;
|
|
8513
8521
|
reexecFn;
|
|
8514
8522
|
dispatcherFactory;
|
|
8523
|
+
unrunnableRetryDelaysMs;
|
|
8515
8524
|
deviceApi = null;
|
|
8516
8525
|
deviceSub = null;
|
|
8517
8526
|
heartbeatTimer = null;
|
|
@@ -8544,6 +8553,7 @@ var CompanionSupervisor = class {
|
|
|
8544
8553
|
this.exitFn = opts.exit ?? ((code) => process.exit(code));
|
|
8545
8554
|
this.reexecFn = opts.reexec ?? defaultReexec;
|
|
8546
8555
|
this.dispatcherFactory = opts.dispatcherFactory;
|
|
8556
|
+
this.unrunnableRetryDelaysMs = opts.unrunnableRetryDelaysMs ?? DEFAULT_UNRUNNABLE_RETRY_DELAYS_MS;
|
|
8547
8557
|
}
|
|
8548
8558
|
// Stand up the data plane: pair check, initial assignments pull, then the
|
|
8549
8559
|
// heartbeat + poll loops. A companion with no device token (logged out) does
|
|
@@ -9048,9 +9058,8 @@ var CompanionSupervisor = class {
|
|
|
9048
9058
|
// wedge the workspace's whole stream.
|
|
9049
9059
|
async reportUnrunnableDispatch(wr, payload) {
|
|
9050
9060
|
if (!this.deviceApi) return false;
|
|
9051
|
-
const backoffMs = [0, 1e3, 3e3];
|
|
9052
9061
|
let lastErr;
|
|
9053
|
-
for (const wait of
|
|
9062
|
+
for (const wait of this.unrunnableRetryDelaysMs) {
|
|
9054
9063
|
if (this.stopped) return false;
|
|
9055
9064
|
if (wait > 0) await new Promise((r) => setTimeout(r, wait));
|
|
9056
9065
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cabane/companion",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.42",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The Cabane Companion (headless): connect a coding agent on your machine to your Cabane workspace as a responder — drive work against your own codebase, files, and MCP servers without putting any of it in Cabane.",
|
|
6
6
|
"license": "UNLICENSED",
|