@1presence/bridge 0.24.0 → 0.26.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 +20 -8
- package/dist/claude.js +19 -15
- package/dist/index.js +1 -0
- package/package.json +1 -1
package/dist/accumulator.js
CHANGED
|
@@ -7,15 +7,25 @@ function makeBridgeAccumulator() {
|
|
|
7
7
|
assistantText: '',
|
|
8
8
|
toolCalls: [],
|
|
9
9
|
toolResults: {},
|
|
10
|
+
turns: [],
|
|
10
11
|
};
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
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 —
|
|
31
|
-
//
|
|
32
|
-
|
|
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/claude.js
CHANGED
|
@@ -70,14 +70,17 @@ function spawnClaude(params) {
|
|
|
70
70
|
existing.kill('SIGTERM');
|
|
71
71
|
active.delete(conversationId);
|
|
72
72
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
73
|
+
// Note: ephemeral context (vault_file_open / client_capabilities / synced_folders)
|
|
74
|
+
// is injected into the last user message by the gateway BEFORE history is
|
|
75
|
+
// sent over the WS. The bridge no longer constructs `userMessageText` —
|
|
76
|
+
// `history` is the authoritative stream and already contains the new user
|
|
77
|
+
// prompt with prefix prepended. The `text`, `vaultFileOpen`,
|
|
78
|
+
// `clientCapabilities`, `syncedFolders` SpawnParams are retained for
|
|
79
|
+
// backward-compatible logging / spool correlation only.
|
|
80
|
+
void vaultFileOpen;
|
|
81
|
+
void clientCapabilities;
|
|
82
|
+
void syncedFolders;
|
|
83
|
+
void text;
|
|
81
84
|
// Lockdown rationale:
|
|
82
85
|
// - `--tools ""` disables ALL built-in tools (Bash/Read/Write/Edit/Glob/Grep/
|
|
83
86
|
// WebFetch/etc.). MCP tools are not "built-in" so the 1Presence MCP surface
|
|
@@ -130,11 +133,14 @@ function spawnClaude(params) {
|
|
|
130
133
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
131
134
|
});
|
|
132
135
|
active.set(conversationId, proc);
|
|
133
|
-
// Feed
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
//
|
|
137
|
-
//
|
|
136
|
+
// Feed the full conversation via stdin as stream-json. The gateway's
|
|
137
|
+
// early-save committed the new user message to Firestore BEFORE building
|
|
138
|
+
// `history`, so `history` already ends with the new user prompt (with the
|
|
139
|
+
// ephemeral context prefix prepended by the gateway). The bridge no longer
|
|
140
|
+
// appends a separate `newTurn` — doing so would duplicate the user prompt.
|
|
141
|
+
// Sanitisation (orphan tool_use stripping, displayOnly filtering, consecutive
|
|
142
|
+
// same-role merging) already happened on the gateway via
|
|
143
|
+
// @presence/shared.toModelMessages — replay the history verbatim.
|
|
138
144
|
try {
|
|
139
145
|
const stdin = proc.stdin;
|
|
140
146
|
if (!stdin) {
|
|
@@ -144,8 +150,6 @@ function spawnClaude(params) {
|
|
|
144
150
|
const wrapped = { type: msg.role, message: { role: msg.role, content: msg.content } };
|
|
145
151
|
stdin.write(JSON.stringify(wrapped) + '\n');
|
|
146
152
|
}
|
|
147
|
-
const newTurn = { type: 'user', message: { role: 'user', content: userMessageText } };
|
|
148
|
-
stdin.write(JSON.stringify(newTurn) + '\n');
|
|
149
153
|
stdin.end();
|
|
150
154
|
}
|
|
151
155
|
catch (err) {
|
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 } : {}) }
|