@1presence/bridge 0.26.0 → 0.28.0
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/accumulator.js +18 -3
- package/dist/claude.js +10 -1
- package/package.json +1 -1
package/dist/accumulator.js
CHANGED
|
@@ -9,6 +9,14 @@ function makeBridgeAccumulator() {
|
|
|
9
9
|
toolResults: {},
|
|
10
10
|
turns: [],
|
|
11
11
|
};
|
|
12
|
+
// A new API turn bucket only opens when a user event (tool_results) has
|
|
13
|
+
// arrived since the last assistant event — mirrors the gateway translator
|
|
14
|
+
// logic. The CLI splits a single model emission's text and tool_use blocks
|
|
15
|
+
// into separate `{type:'assistant'}` events; without this guard each split
|
|
16
|
+
// creates a stored assistant message and produces consecutive same-role
|
|
17
|
+
// rows that the read-side merger has to repair. Init true so the very first
|
|
18
|
+
// assistant event opens turn 0.
|
|
19
|
+
let sawUserSinceLastAssistant = true;
|
|
12
20
|
// Returns the current open API-turn bucket, creating one lazily if a text
|
|
13
21
|
// event arrives before any `{type:'assistant'}` event (shouldn't normally
|
|
14
22
|
// happen with Claude Code's stream-json, but keep it robust).
|
|
@@ -37,9 +45,14 @@ function makeBridgeAccumulator() {
|
|
|
37
45
|
return;
|
|
38
46
|
}
|
|
39
47
|
if (type === 'assistant') {
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
|
|
48
|
+
// Only open a fresh bucket when a user event has arrived since the
|
|
49
|
+
// last assistant event. Otherwise treat this as a continuation of
|
|
50
|
+
// the current API turn (CLI splits text and tool_use into separate
|
|
51
|
+
// assistant events within one model emission).
|
|
52
|
+
if (sawUserSinceLastAssistant) {
|
|
53
|
+
state.turns.push({ text: '', toolUseIds: [] });
|
|
54
|
+
sawUserSinceLastAssistant = false;
|
|
55
|
+
}
|
|
43
56
|
const msg = event['message'];
|
|
44
57
|
const content = msg?.['content'];
|
|
45
58
|
if (!Array.isArray(content))
|
|
@@ -69,6 +82,8 @@ function makeBridgeAccumulator() {
|
|
|
69
82
|
return;
|
|
70
83
|
}
|
|
71
84
|
if (type === 'user') {
|
|
85
|
+
// Flip the flag so the next assistant event opens a new API turn.
|
|
86
|
+
sawUserSinceLastAssistant = true;
|
|
72
87
|
const msg = event['message'];
|
|
73
88
|
const content = msg?.['content'];
|
|
74
89
|
if (!Array.isArray(content))
|
package/dist/claude.js
CHANGED
|
@@ -147,7 +147,16 @@ function spawnClaude(params) {
|
|
|
147
147
|
throw new Error('claude stdin is null — spawn must use stdio[0]="pipe"');
|
|
148
148
|
}
|
|
149
149
|
for (const msg of history) {
|
|
150
|
-
|
|
150
|
+
// Normalise to array-of-blocks: Claude Code's stream-json input parser
|
|
151
|
+
// iterates `content` directly. A string slips into a `"tool_use_id" in
|
|
152
|
+
// <char>` check inside the CLI and aborts the process with `W is not an
|
|
153
|
+
// Object` (JSC) / exit 1 mid-turn. The gateway also normalises before
|
|
154
|
+
// sending, so a current gateway + any bridge version is safe; this guard
|
|
155
|
+
// covers older gateways and ad-hoc local replay tests.
|
|
156
|
+
const content = Array.isArray(msg.content)
|
|
157
|
+
? msg.content
|
|
158
|
+
: [{ type: 'text', text: typeof msg.content === 'string' ? msg.content : '' }];
|
|
159
|
+
const wrapped = { type: msg.role, message: { role: msg.role, content } };
|
|
151
160
|
stdin.write(JSON.stringify(wrapped) + '\n');
|
|
152
161
|
}
|
|
153
162
|
stdin.end();
|