@1presence/bridge 0.24.0 → 0.25.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.
@@ -7,15 +7,25 @@ function makeBridgeAccumulator() {
7
7
  assistantText: '',
8
8
  toolCalls: [],
9
9
  toolResults: {},
10
+ turns: [],
10
11
  };
11
- let textEmitted = false;
12
- let turnTextEmitted = false;
12
+ // Returns the current open API-turn bucket, creating one lazily if a text
13
+ // event arrives before any `{type:'assistant'}` event (shouldn't normally
14
+ // happen with Claude Code's stream-json, but keep it robust).
15
+ function currentTurn() {
16
+ if (state.turns.length === 0)
17
+ state.turns.push({ text: '', toolUseIds: [] });
18
+ return state.turns[state.turns.length - 1];
19
+ }
13
20
  function appendText(text) {
14
- if (textEmitted && !turnTextEmitted)
21
+ const turn = currentTurn();
22
+ turn.text += text;
23
+ // Mirror to the flat string with `\n\n` between turns for convenience.
24
+ if (state.assistantText && state.turns.length > 1 && turn.text === text) {
25
+ // First text emission of a new turn — separate from prior turn.
15
26
  state.assistantText += '\n\n';
27
+ }
16
28
  state.assistantText += text;
17
- turnTextEmitted = true;
18
- textEmitted = true;
19
29
  }
20
30
  return {
21
31
  consume(event) {
@@ -27,9 +37,9 @@ function makeBridgeAccumulator() {
27
37
  return;
28
38
  }
29
39
  if (type === 'assistant') {
30
- // New API turn — reset the per-turn flag so the next text emission
31
- // gets a `\n\n` separator iff text was already emitted in a prior turn.
32
- turnTextEmitted = false;
40
+ // New API turn — open a fresh bucket. All text and tool_use blocks
41
+ // in this `assistant` event belong to this single API turn.
42
+ state.turns.push({ text: '', toolUseIds: [] });
33
43
  const msg = event['message'];
34
44
  const content = msg?.['content'];
35
45
  if (!Array.isArray(content))
@@ -48,6 +58,7 @@ function makeBridgeAccumulator() {
48
58
  continue;
49
59
  const bareName = name.replace(/^mcp__1presence__/, '');
50
60
  state.toolCalls.push({ id, name: bareName, input });
61
+ currentTurn().toolUseIds.push(id);
51
62
  if (bareName === 'set_conversation_title') {
52
63
  const raw = String(input['title'] ?? '').trim();
53
64
  if (raw)
@@ -95,6 +106,7 @@ async function postSaveTurn(gatewayHttp, token, record) {
95
106
  assistantText: record.assistantText,
96
107
  toolCalls: record.toolCalls,
97
108
  toolResults: record.toolResults,
109
+ ...(record.apiTurns ? { apiTurns: record.apiTurns } : {}),
98
110
  ...(record.title ? { title: record.title } : {}),
99
111
  ...(record.usage ? { usage: record.usage } : {}),
100
112
  }),
package/dist/index.js CHANGED
@@ -188,6 +188,7 @@ async function handleMessage(conversationId, text, sessionId, history, auth, vau
188
188
  assistantText: s.assistantText,
189
189
  toolCalls: s.toolCalls,
190
190
  toolResults: s.toolResults,
191
+ apiTurns: s.turns,
191
192
  ...(s.title ? { title: s.title } : {}),
192
193
  usage: usage
193
194
  ? { ...usage, ...(model ? { model } : {}) }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1presence/bridge",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "description": "Run 1Presence on your Mac and use your Claude.ai Pro subscription from any device",
5
5
  "bin": {
6
6
  "1presence-bridge": "dist/index.js"