@agentvault/claude-bridge 0.7.8 → 0.7.10
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/index.js +75 -3
- package/dist/session.d.ts +30 -0
- package/dist/worker-queue.d.ts +23 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -64124,6 +64124,31 @@ var init_transport2 = __esm2({
|
|
|
64124
64124
|
"use strict";
|
|
64125
64125
|
}
|
|
64126
64126
|
});
|
|
64127
|
+
function a2aChannelSignature(channels) {
|
|
64128
|
+
return JSON.stringify(
|
|
64129
|
+
channels.map((c22) => ({
|
|
64130
|
+
id: c22.channelId?.slice(0, 8),
|
|
64131
|
+
status: c22.status,
|
|
64132
|
+
participants: c22.participant_count
|
|
64133
|
+
})).sort((a2, b22) => (a2.id ?? "").localeCompare(b22.id ?? ""))
|
|
64134
|
+
);
|
|
64135
|
+
}
|
|
64136
|
+
var A2ALogGate;
|
|
64137
|
+
var init_a2a_log_gate = __esm2({
|
|
64138
|
+
"src/a2a-log-gate.ts"() {
|
|
64139
|
+
"use strict";
|
|
64140
|
+
A2ALogGate = class {
|
|
64141
|
+
last = null;
|
|
64142
|
+
/** True when this state differs from the last reported one. Records it. */
|
|
64143
|
+
shouldReport(channels) {
|
|
64144
|
+
const sig = a2aChannelSignature(channels);
|
|
64145
|
+
if (sig === this.last) return false;
|
|
64146
|
+
this.last = sig;
|
|
64147
|
+
return true;
|
|
64148
|
+
}
|
|
64149
|
+
};
|
|
64150
|
+
}
|
|
64151
|
+
});
|
|
64127
64152
|
var openclaw_compat_exports = {};
|
|
64128
64153
|
__export2(openclaw_compat_exports, {
|
|
64129
64154
|
AGENT_EVENT_CANDIDATES: () => AGENT_EVENT_CANDIDATES,
|
|
@@ -64683,6 +64708,7 @@ var init_channel = __esm2({
|
|
|
64683
64708
|
await init_crypto_helpers();
|
|
64684
64709
|
await init_state();
|
|
64685
64710
|
init_transport2();
|
|
64711
|
+
init_a2a_log_gate();
|
|
64686
64712
|
ROOM_AGENT_TYPES = /* @__PURE__ */ new Set([
|
|
64687
64713
|
"message",
|
|
64688
64714
|
"text",
|
|
@@ -64748,6 +64774,11 @@ var init_channel = __esm2({
|
|
|
64748
64774
|
_heartbeatTimer = null;
|
|
64749
64775
|
_heartbeatCallback = null;
|
|
64750
64776
|
_heartbeatIntervalSeconds = 0;
|
|
64777
|
+
/** #798: report the A2A channel set only when it CHANGES. This line polls
|
|
64778
|
+
* every 30s and produced 90.2% of bridge.log (90,841/100,702 lines) and a
|
|
64779
|
+
* 27.9MB gateway.log on wren, every one reading `channels=0`. Not deleted —
|
|
64780
|
+
* #794's A2A watch needs the transitions. */
|
|
64781
|
+
_a2aLogGate = new A2ALogGate();
|
|
64751
64782
|
_wakeDetectorTimer = null;
|
|
64752
64783
|
_lastWakeTick = Date.now();
|
|
64753
64784
|
_trustToken = null;
|
|
@@ -67201,7 +67232,9 @@ var init_channel = __esm2({
|
|
|
67201
67232
|
}
|
|
67202
67233
|
const myHub = this._persisted.hubAddress || "";
|
|
67203
67234
|
const myHubId = this._persisted.hubId || "";
|
|
67204
|
-
|
|
67235
|
+
if (this._a2aLogGate.shouldReport(channels)) {
|
|
67236
|
+
console.log(`[listA2AChannels] myHub=${myHub}, channels=${channels.length}, raw=${JSON.stringify(channels.map((c22) => ({ id: c22.channelId?.slice(0, 8), status: c22.status, participants: c22.participant_count })))}`);
|
|
67237
|
+
}
|
|
67205
67238
|
for (const ch2 of channels) {
|
|
67206
67239
|
if (ch2.status === "active" || ch2.status === "approved") {
|
|
67207
67240
|
const myParticipant = ch2.participants?.find(
|
|
@@ -133175,6 +133208,28 @@ var PersistentClaudeSession = class {
|
|
|
133175
133208
|
* #416 fallback delivery (which delivers via `void reply(...)` WITHOUT setting
|
|
133176
133209
|
* saidThisTurn, so !saidThisTurn alone would false-flag it). */
|
|
133177
133210
|
sawResultThisTurn = false;
|
|
133211
|
+
/**
|
|
133212
|
+
* Per-turn telemetry lifted off the SDK's `result` message.
|
|
133213
|
+
*
|
|
133214
|
+
* The message arrives on EVERY turn and we kept one boolean from it
|
|
133215
|
+
* (`sawResultThisTurn`), discarding the rest. That is the #791 shape: data
|
|
133216
|
+
* delivered on the healthy path that nothing reads.
|
|
133217
|
+
*
|
|
133218
|
+
* It costs us a real answer. A turn that produced nothing (`composed=0,
|
|
133219
|
+
* said=false`) could be the model choosing silence, the turn cap being hit, or
|
|
133220
|
+
* the provider returning 429 — three different bugs with one symptom, and
|
|
133221
|
+
* `subtype`/`apiErrorStatus` are what separate them. 4 of 12 turns on
|
|
133222
|
+
* 2026-08-07 were silent and could not be attributed.
|
|
133223
|
+
*
|
|
133224
|
+
* `durationApiMs` vs `durationMs` also gives the model-time / SDK-overhead
|
|
133225
|
+
* split directly. That split previously had to be reconstructed by joining
|
|
133226
|
+
* `WorkerIncident.ranMs` against SDK transcripts on disk by wall clock.
|
|
133227
|
+
*
|
|
133228
|
+
* Every field is OPTIONAL and left undefined when no result arrives (abort or
|
|
133229
|
+
* crash mid-turn): absent must read as absent, never as a zero that looks like
|
|
133230
|
+
* a real measurement.
|
|
133231
|
+
*/
|
|
133232
|
+
resultTelemetry = {};
|
|
133178
133233
|
/** In-process room MCP server — hoisted so buildSdkOptions can reference it. */
|
|
133179
133234
|
roomServer;
|
|
133180
133235
|
/** AbortController for the in-flight query(); abort() triggers it (queue timeout). */
|
|
@@ -133239,7 +133294,8 @@ var PersistentClaudeSession = class {
|
|
|
133239
133294
|
return {
|
|
133240
133295
|
composedChars: this.turnText.length,
|
|
133241
133296
|
sawResult: this.sawResultThisTurn,
|
|
133242
|
-
said: this.saidThisTurn
|
|
133297
|
+
said: this.saidThisTurn,
|
|
133298
|
+
...this.resultTelemetry
|
|
133243
133299
|
};
|
|
133244
133300
|
}
|
|
133245
133301
|
async *input() {
|
|
@@ -133261,6 +133317,7 @@ var PersistentClaudeSession = class {
|
|
|
133261
133317
|
this.saidThisTurn = false;
|
|
133262
133318
|
this.turnText = "";
|
|
133263
133319
|
this.sawResultThisTurn = false;
|
|
133320
|
+
this.resultTelemetry = {};
|
|
133264
133321
|
yield item.msg;
|
|
133265
133322
|
}
|
|
133266
133323
|
}
|
|
@@ -133403,6 +133460,21 @@ var PersistentClaudeSession = class {
|
|
|
133403
133460
|
}
|
|
133404
133461
|
} else if (m6.type === "result") {
|
|
133405
133462
|
this.sawResultThisTurn = true;
|
|
133463
|
+
const r7 = m6;
|
|
133464
|
+
const num = (k2) => typeof r7[k2] === "number" ? r7[k2] : void 0;
|
|
133465
|
+
const str = (k2) => typeof r7[k2] === "string" ? r7[k2] : void 0;
|
|
133466
|
+
const usage = r7.usage ?? {};
|
|
133467
|
+
const unum = (k2) => typeof usage[k2] === "number" ? usage[k2] : void 0;
|
|
133468
|
+
this.resultTelemetry = {
|
|
133469
|
+
durationMs: num("duration_ms"),
|
|
133470
|
+
durationApiMs: num("duration_api_ms"),
|
|
133471
|
+
numTurns: num("num_turns"),
|
|
133472
|
+
subtype: str("subtype"),
|
|
133473
|
+
stopReason: str("stop_reason"),
|
|
133474
|
+
apiErrorStatus: num("api_error_status"),
|
|
133475
|
+
cacheReadTokens: unum("cache_read_input_tokens"),
|
|
133476
|
+
cacheCreationTokens: unum("cache_creation_input_tokens")
|
|
133477
|
+
};
|
|
133406
133478
|
const reply = this.activeReply;
|
|
133407
133479
|
if (this.currentReplyExpected && !this.saidThisTurn && this.turnText.trim()) {
|
|
133408
133480
|
if (reply) {
|
|
@@ -134113,7 +134185,7 @@ async function main() {
|
|
|
134113
134185
|
"[bridge] warning: passing the invite token on the command line is visible to other local users via 'ps'. Prefer: AV_INVITE_TOKEN=\u2026 npx @agentvault/claude-bridge"
|
|
134114
134186
|
);
|
|
134115
134187
|
}
|
|
134116
|
-
logLine(`[bridge] version: ${true ? "0.7.
|
|
134188
|
+
logLine(`[bridge] version: ${true ? "0.7.10" : "dev"}`);
|
|
134117
134189
|
logLine(`[bridge] data dir: ${cfg.dataDir} (${cfg.dataDirSource})`);
|
|
134118
134190
|
logLine(`[bridge] workspace: ${cfg.workspaceDir} \xB7 permissions: ${cfg.permissionMode} \xB7 enclave dir fenced`);
|
|
134119
134191
|
if (cfg.armRoom) {
|
package/dist/session.d.ts
CHANGED
|
@@ -143,6 +143,28 @@ export declare class PersistentClaudeSession {
|
|
|
143
143
|
* #416 fallback delivery (which delivers via `void reply(...)` WITHOUT setting
|
|
144
144
|
* saidThisTurn, so !saidThisTurn alone would false-flag it). */
|
|
145
145
|
private sawResultThisTurn;
|
|
146
|
+
/**
|
|
147
|
+
* Per-turn telemetry lifted off the SDK's `result` message.
|
|
148
|
+
*
|
|
149
|
+
* The message arrives on EVERY turn and we kept one boolean from it
|
|
150
|
+
* (`sawResultThisTurn`), discarding the rest. That is the #791 shape: data
|
|
151
|
+
* delivered on the healthy path that nothing reads.
|
|
152
|
+
*
|
|
153
|
+
* It costs us a real answer. A turn that produced nothing (`composed=0,
|
|
154
|
+
* said=false`) could be the model choosing silence, the turn cap being hit, or
|
|
155
|
+
* the provider returning 429 — three different bugs with one symptom, and
|
|
156
|
+
* `subtype`/`apiErrorStatus` are what separate them. 4 of 12 turns on
|
|
157
|
+
* 2026-08-07 were silent and could not be attributed.
|
|
158
|
+
*
|
|
159
|
+
* `durationApiMs` vs `durationMs` also gives the model-time / SDK-overhead
|
|
160
|
+
* split directly. That split previously had to be reconstructed by joining
|
|
161
|
+
* `WorkerIncident.ranMs` against SDK transcripts on disk by wall clock.
|
|
162
|
+
*
|
|
163
|
+
* Every field is OPTIONAL and left undefined when no result arrives (abort or
|
|
164
|
+
* crash mid-turn): absent must read as absent, never as a zero that looks like
|
|
165
|
+
* a real measurement.
|
|
166
|
+
*/
|
|
167
|
+
private resultTelemetry;
|
|
146
168
|
/** In-process room MCP server — hoisted so buildSdkOptions can reference it. */
|
|
147
169
|
private roomServer;
|
|
148
170
|
/** AbortController for the in-flight query(); abort() triggers it (queue timeout). */
|
|
@@ -185,6 +207,14 @@ export declare class PersistentClaudeSession {
|
|
|
185
207
|
composedChars: number;
|
|
186
208
|
sawResult: boolean;
|
|
187
209
|
said: boolean;
|
|
210
|
+
durationMs?: number;
|
|
211
|
+
durationApiMs?: number;
|
|
212
|
+
numTurns?: number;
|
|
213
|
+
subtype?: string;
|
|
214
|
+
stopReason?: string;
|
|
215
|
+
apiErrorStatus?: number;
|
|
216
|
+
cacheReadTokens?: number;
|
|
217
|
+
cacheCreationTokens?: number;
|
|
188
218
|
};
|
|
189
219
|
private input;
|
|
190
220
|
/**
|
package/dist/worker-queue.d.ts
CHANGED
|
@@ -61,11 +61,33 @@ export type WorkerIncident = {
|
|
|
61
61
|
* could not separate them.
|
|
62
62
|
*/
|
|
63
63
|
replyExpected?: boolean;
|
|
64
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* What the worker had produced when it died, when the session can report it.
|
|
66
|
+
*
|
|
67
|
+
* The `duration*`/`numTurns`/`subtype`/`stopReason`/`apiErrorStatus` fields are
|
|
68
|
+
* lifted off the SDK's `result` message (see `PersistentClaudeSession`). They
|
|
69
|
+
* are what makes a SILENT turn attributable: `composed=0, said=false` is
|
|
70
|
+
* produced identically by the model choosing silence (`subtype: success`), the
|
|
71
|
+
* turn cap (`error_max_turns`) and a provider error (`apiErrorStatus: 429`).
|
|
72
|
+
* Absent on any turn that never reached a result boundary — undefined means
|
|
73
|
+
* "no result arrived", never zero.
|
|
74
|
+
*/
|
|
65
75
|
session?: {
|
|
66
76
|
composedChars: number;
|
|
67
77
|
sawResult: boolean;
|
|
68
78
|
said: boolean;
|
|
79
|
+
durationMs?: number;
|
|
80
|
+
durationApiMs?: number;
|
|
81
|
+
numTurns?: number;
|
|
82
|
+
subtype?: string;
|
|
83
|
+
stopReason?: string;
|
|
84
|
+
apiErrorStatus?: number;
|
|
85
|
+
/** Prompt-cache state — `cacheReadTokens === 0` with a large
|
|
86
|
+
* `cacheCreationTokens` marks a COLD turn, which costs ~2x a warm one for
|
|
87
|
+
* reasons unrelated to the code under test. Without it, a latency figure
|
|
88
|
+
* in this file cannot be read honestly. */
|
|
89
|
+
cacheReadTokens?: number;
|
|
90
|
+
cacheCreationTokens?: number;
|
|
69
91
|
};
|
|
70
92
|
};
|
|
71
93
|
export interface WorkerQueueDeps {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentvault/claude-bridge",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AgentVault Claude Bridge \u2014 daemon for bridging a Claude agent into secure E2E-encrypted AgentVault 1:1 direct messages and rooms.",
|
|
6
6
|
"main": "dist/index.js",
|