@nextclaw/ncp-toolkit 0.6.1 → 0.6.2
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.d.ts +3 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +145 -100
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NcpAgentClientEndpoint, NcpAgentConversationHydrationParams, NcpAgentConversationSnapshot, NcpAgentConversationStateManager, NcpAgentRunInput, NcpAgentRuntime, NcpAgentServerEndpoint, NcpContextWindowUpdatedPayload, NcpEndpointEvent, NcpEndpointSubscriber, NcpError, NcpErrorCode, NcpMessage, NcpMessageAbortPayload, NcpMessagePart, NcpMessageSentPayload, NcpReasoningDeltaPayload, NcpReasoningEndPayload, NcpReasoningStartPayload, NcpRequestEnvelope, NcpRunErrorPayload, NcpRunFinishedPayload, NcpRunMetadataPayload, NcpRunStartedPayload, NcpSessionSummary, NcpTextDeltaPayload, NcpTextEndPayload, NcpTextStartPayload, NcpToolCallArgsDeltaPayload, NcpToolCallArgsPayload, NcpToolCallEndPayload, NcpToolCallResultPayload, NcpToolCallStartPayload, OpenAITool } from "@nextclaw/ncp";
|
|
2
2
|
|
|
3
|
-
//#region src/agent/agent-conversation-state
|
|
3
|
+
//#region src/agent/agent-conversation-state.manager.d.ts
|
|
4
4
|
declare class DefaultNcpAgentConversationStateManager implements NcpAgentConversationStateManager {
|
|
5
5
|
private messages;
|
|
6
6
|
private streamingMessage;
|
|
@@ -8,12 +8,12 @@ declare class DefaultNcpAgentConversationStateManager implements NcpAgentConvers
|
|
|
8
8
|
private activeRun;
|
|
9
9
|
private contextWindow;
|
|
10
10
|
private readonly listeners;
|
|
11
|
-
private readonly
|
|
12
|
-
private readonly toolCallArgsRawByCallId;
|
|
11
|
+
private readonly toolCalls;
|
|
13
12
|
private lastSettledRunId;
|
|
14
13
|
private snapshotCache;
|
|
15
14
|
private snapshotVersion;
|
|
16
15
|
private stateVersion;
|
|
16
|
+
constructor();
|
|
17
17
|
getSnapshot: () => NcpAgentConversationSnapshot;
|
|
18
18
|
subscribe: (listener: (snapshot: NcpAgentConversationSnapshot) => void) => () => boolean;
|
|
19
19
|
reset: () => void;
|
|
@@ -40,9 +40,7 @@ declare class DefaultNcpAgentConversationStateManager implements NcpAgentConvers
|
|
|
40
40
|
handleRunMetadata: (payload: NcpRunMetadataPayload) => void;
|
|
41
41
|
handleContextWindowUpdated: (payload: NcpContextWindowUpdatedPayload) => void;
|
|
42
42
|
handleEndpointError: (payload: NcpError) => void;
|
|
43
|
-
private applyToolCallArgs;
|
|
44
43
|
private ensureStreamingMessage;
|
|
45
|
-
private resolveToolCallTargetMessage;
|
|
46
44
|
private updateMessageContainingToolCall;
|
|
47
45
|
private upsertMessage;
|
|
48
46
|
private replaceStreamingMessage;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/agent/agent-conversation-state
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/agent/agent-conversation-state.manager.ts","../src/agent/agent-client-from-server.ts","../src/agent/agent-backend/event-publisher.ts","../src/agent/agent-backend/agent-backend.types.ts","../src/agent/agent-backend/in-memory-agent-session.store.ts","../src/errors/ncp-error-exception.ts","../src/chat/chat.types.ts","../src/chat/ncp-reply-consumer.ts"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -116,7 +116,118 @@ function cancelInFlightToolInvocations(parts) {
|
|
|
116
116
|
};
|
|
117
117
|
}
|
|
118
118
|
//#endregion
|
|
119
|
-
//#region src/agent/agent-conversation-
|
|
119
|
+
//#region src/agent/agent-conversation-tool-call.manager.ts
|
|
120
|
+
var AgentConversationToolCallManager = class {
|
|
121
|
+
messageIdByCallId = /* @__PURE__ */ new Map();
|
|
122
|
+
argsRawByCallId = /* @__PURE__ */ new Map();
|
|
123
|
+
constructor(port) {
|
|
124
|
+
this.port = port;
|
|
125
|
+
}
|
|
126
|
+
isEmpty = () => this.messageIdByCallId.size === 0 && this.argsRawByCallId.size === 0;
|
|
127
|
+
clear = () => {
|
|
128
|
+
this.messageIdByCallId.clear();
|
|
129
|
+
this.argsRawByCallId.clear();
|
|
130
|
+
};
|
|
131
|
+
clearByMessageId = (messageId) => {
|
|
132
|
+
clearToolCallTrackingByMessageId(this.messageIdByCallId, this.argsRawByCallId, messageId);
|
|
133
|
+
};
|
|
134
|
+
markAborted = (toolCallIds) => {
|
|
135
|
+
toolCallIds.forEach((toolCallId) => this.argsRawByCallId.set(toolCallId, ABORTED_TOOL_CALL_SENTINEL));
|
|
136
|
+
};
|
|
137
|
+
remapMessageId = (fromMessageId, toMessageId) => {
|
|
138
|
+
remapTrackedToolCallsToMessageId(this.messageIdByCallId, fromMessageId, toMessageId);
|
|
139
|
+
};
|
|
140
|
+
handleToolCallStart = (payload) => {
|
|
141
|
+
if (this.argsRawByCallId.get(payload.toolCallId) === "__nextclaw_aborted_tool_call__") return;
|
|
142
|
+
const targetMessage = this.resolveToolCallTargetMessage(payload.sessionId, payload.toolCallId, payload.messageId);
|
|
143
|
+
this.argsRawByCallId.set(payload.toolCallId, "");
|
|
144
|
+
this.port.replaceStreamingMessage({
|
|
145
|
+
...targetMessage,
|
|
146
|
+
parts: upsertToolInvocationPart(targetMessage.parts, {
|
|
147
|
+
type: "tool-invocation",
|
|
148
|
+
toolCallId: payload.toolCallId,
|
|
149
|
+
toolName: payload.toolName,
|
|
150
|
+
state: "partial-call",
|
|
151
|
+
args: ""
|
|
152
|
+
}),
|
|
153
|
+
status: "streaming"
|
|
154
|
+
});
|
|
155
|
+
};
|
|
156
|
+
handleToolCallArgs = (payload) => {
|
|
157
|
+
if (this.argsRawByCallId.get(payload.toolCallId) === "__nextclaw_aborted_tool_call__") return;
|
|
158
|
+
this.argsRawByCallId.set(payload.toolCallId, payload.args);
|
|
159
|
+
this.applyToolCallArgs(payload.sessionId, payload.toolCallId, payload.args);
|
|
160
|
+
};
|
|
161
|
+
handleToolCallArgsDelta = (payload) => {
|
|
162
|
+
if (this.argsRawByCallId.get(payload.toolCallId) === "__nextclaw_aborted_tool_call__") return;
|
|
163
|
+
const nextArgs = `${this.argsRawByCallId.get(payload.toolCallId) ?? ""}${payload.delta}`;
|
|
164
|
+
this.argsRawByCallId.set(payload.toolCallId, nextArgs);
|
|
165
|
+
this.applyToolCallArgs(payload.sessionId, payload.toolCallId, nextArgs, payload.messageId);
|
|
166
|
+
};
|
|
167
|
+
handleToolCallEnd = (payload) => {
|
|
168
|
+
if (this.argsRawByCallId.get(payload.toolCallId) === "__nextclaw_aborted_tool_call__") return;
|
|
169
|
+
const targetMessage = this.resolveToolCallTargetMessage(payload.sessionId, payload.toolCallId);
|
|
170
|
+
const args = this.argsRawByCallId.get(payload.toolCallId) ?? "";
|
|
171
|
+
this.port.replaceStreamingMessage({
|
|
172
|
+
...targetMessage,
|
|
173
|
+
parts: upsertToolInvocationPart(targetMessage.parts, {
|
|
174
|
+
type: "tool-invocation",
|
|
175
|
+
toolCallId: payload.toolCallId,
|
|
176
|
+
toolName: findToolNameByCallId(targetMessage.parts, payload.toolCallId) ?? "unknown",
|
|
177
|
+
state: "call",
|
|
178
|
+
args
|
|
179
|
+
}),
|
|
180
|
+
status: "streaming"
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
handleToolCallResult = (payload) => {
|
|
184
|
+
if (this.argsRawByCallId.get(payload.toolCallId) === "__nextclaw_aborted_tool_call__") return;
|
|
185
|
+
if (this.port.updateMessageContainingToolCall(payload.toolCallId, (targetMessage, existingPart) => upsertToolInvocationPart(targetMessage.parts, {
|
|
186
|
+
type: "tool-invocation",
|
|
187
|
+
toolCallId: payload.toolCallId,
|
|
188
|
+
toolName: existingPart.toolName,
|
|
189
|
+
state: "result",
|
|
190
|
+
args: existingPart.args,
|
|
191
|
+
result: payload.content,
|
|
192
|
+
resultContentItems: payload.contentItems
|
|
193
|
+
}))) return;
|
|
194
|
+
const fallbackMessage = this.resolveToolCallTargetMessage(payload.sessionId, payload.toolCallId);
|
|
195
|
+
this.port.replaceStreamingMessage({
|
|
196
|
+
...fallbackMessage,
|
|
197
|
+
parts: upsertToolInvocationPart(fallbackMessage.parts, {
|
|
198
|
+
type: "tool-invocation",
|
|
199
|
+
toolCallId: payload.toolCallId,
|
|
200
|
+
toolName: "unknown",
|
|
201
|
+
state: "result",
|
|
202
|
+
result: payload.content,
|
|
203
|
+
resultContentItems: payload.contentItems
|
|
204
|
+
}),
|
|
205
|
+
status: "streaming"
|
|
206
|
+
});
|
|
207
|
+
};
|
|
208
|
+
applyToolCallArgs = (sessionId, toolCallId, args, messageId) => {
|
|
209
|
+
const targetMessage = this.resolveToolCallTargetMessage(sessionId, toolCallId, messageId);
|
|
210
|
+
const toolName = findToolNameByCallId(targetMessage.parts, toolCallId) ?? "unknown";
|
|
211
|
+
this.port.replaceStreamingMessage({
|
|
212
|
+
...targetMessage,
|
|
213
|
+
parts: upsertToolInvocationPart(targetMessage.parts, {
|
|
214
|
+
type: "tool-invocation",
|
|
215
|
+
toolCallId,
|
|
216
|
+
toolName,
|
|
217
|
+
state: "partial-call",
|
|
218
|
+
args
|
|
219
|
+
}),
|
|
220
|
+
status: "streaming"
|
|
221
|
+
});
|
|
222
|
+
};
|
|
223
|
+
resolveToolCallTargetMessage = (sessionId, toolCallId, messageId) => {
|
|
224
|
+
const preferredMessageId = messageId?.trim() || this.messageIdByCallId.get(toolCallId) || this.port.readStreamingMessageId() || `tool-${toolCallId}`;
|
|
225
|
+
this.messageIdByCallId.set(toolCallId, preferredMessageId);
|
|
226
|
+
return this.port.ensureStreamingMessage(sessionId, preferredMessageId, "streaming");
|
|
227
|
+
};
|
|
228
|
+
};
|
|
229
|
+
//#endregion
|
|
230
|
+
//#region src/agent/agent-conversation-state.manager.ts
|
|
120
231
|
const DEFAULT_ASSISTANT_ROLE = "assistant";
|
|
121
232
|
var DefaultNcpAgentConversationStateManager = class {
|
|
122
233
|
messages = [];
|
|
@@ -125,12 +236,19 @@ var DefaultNcpAgentConversationStateManager = class {
|
|
|
125
236
|
activeRun = null;
|
|
126
237
|
contextWindow = null;
|
|
127
238
|
listeners = /* @__PURE__ */ new Set();
|
|
128
|
-
|
|
129
|
-
toolCallArgsRawByCallId = /* @__PURE__ */ new Map();
|
|
239
|
+
toolCalls;
|
|
130
240
|
lastSettledRunId = null;
|
|
131
241
|
snapshotCache = null;
|
|
132
242
|
snapshotVersion = -1;
|
|
133
243
|
stateVersion = 0;
|
|
244
|
+
constructor() {
|
|
245
|
+
this.toolCalls = new AgentConversationToolCallManager({
|
|
246
|
+
ensureStreamingMessage: this.ensureStreamingMessage,
|
|
247
|
+
readStreamingMessageId: () => this.streamingMessage?.id ?? null,
|
|
248
|
+
replaceStreamingMessage: this.replaceStreamingMessage,
|
|
249
|
+
updateMessageContainingToolCall: this.updateMessageContainingToolCall
|
|
250
|
+
});
|
|
251
|
+
}
|
|
134
252
|
getSnapshot = () => {
|
|
135
253
|
if (this.snapshotCache && this.snapshotVersion === this.stateVersion) return this.snapshotCache;
|
|
136
254
|
const snapshot = {
|
|
@@ -152,14 +270,13 @@ var DefaultNcpAgentConversationStateManager = class {
|
|
|
152
270
|
return () => this.listeners.delete(listener);
|
|
153
271
|
};
|
|
154
272
|
reset = () => {
|
|
155
|
-
if (this.messages.length === 0 && !this.streamingMessage && !this.error && !this.activeRun && !this.contextWindow && this.
|
|
273
|
+
if (this.messages.length === 0 && !this.streamingMessage && !this.error && !this.activeRun && !this.contextWindow && this.toolCalls.isEmpty()) return;
|
|
156
274
|
this.messages = [];
|
|
157
275
|
this.streamingMessage = null;
|
|
158
276
|
this.error = null;
|
|
159
277
|
this.activeRun = null;
|
|
160
278
|
this.contextWindow = null;
|
|
161
|
-
this.
|
|
162
|
-
this.toolCallArgsRawByCallId.clear();
|
|
279
|
+
this.toolCalls.clear();
|
|
163
280
|
this.lastSettledRunId = null;
|
|
164
281
|
this.stateVersion += 1;
|
|
165
282
|
this.notifyListeners();
|
|
@@ -174,8 +291,7 @@ var DefaultNcpAgentConversationStateManager = class {
|
|
|
174
291
|
sessionId: payload.activeRun.sessionId ?? payload.sessionId,
|
|
175
292
|
abortDisabledReason: payload.activeRun.abortDisabledReason ?? null
|
|
176
293
|
} : null;
|
|
177
|
-
this.
|
|
178
|
-
this.toolCallArgsRawByCallId.clear();
|
|
294
|
+
this.toolCalls.clear();
|
|
179
295
|
this.lastSettledRunId = null;
|
|
180
296
|
this.stateVersion += 1;
|
|
181
297
|
this.notifyListeners();
|
|
@@ -266,13 +382,23 @@ var DefaultNcpAgentConversationStateManager = class {
|
|
|
266
382
|
parts: nextParts
|
|
267
383
|
});
|
|
268
384
|
this.replaceStreamingMessage(null);
|
|
269
|
-
if (targetMessageId)
|
|
270
|
-
else
|
|
271
|
-
|
|
385
|
+
if (targetMessageId) this.toolCalls.clearByMessageId(targetMessageId);
|
|
386
|
+
else this.toolCalls.clearByMessageId(streamingMessageId);
|
|
387
|
+
this.toolCalls.markAborted(toolCallIds);
|
|
272
388
|
}
|
|
273
389
|
};
|
|
274
390
|
handleMessageTextStart = (payload) => {
|
|
275
|
-
this.
|
|
391
|
+
const wasActiveStreamingMessage = this.streamingMessage?.id === payload.messageId;
|
|
392
|
+
const targetMessage = this.ensureStreamingMessage(payload.sessionId, payload.messageId, "streaming");
|
|
393
|
+
const lastPart = targetMessage.parts[targetMessage.parts.length - 1];
|
|
394
|
+
if (wasActiveStreamingMessage && lastPart?.type === "text" && lastPart.text.length > 0) this.replaceStreamingMessage({
|
|
395
|
+
...targetMessage,
|
|
396
|
+
parts: [...targetMessage.parts, {
|
|
397
|
+
type: "text",
|
|
398
|
+
text: ""
|
|
399
|
+
}],
|
|
400
|
+
status: "streaming"
|
|
401
|
+
});
|
|
276
402
|
this.setError(null);
|
|
277
403
|
};
|
|
278
404
|
handleMessageTextDelta = (payload) => {
|
|
@@ -328,80 +454,20 @@ var DefaultNcpAgentConversationStateManager = class {
|
|
|
328
454
|
if (this.streamingMessage?.id !== payload.messageId) return;
|
|
329
455
|
};
|
|
330
456
|
handleMessageToolCallStart = (payload) => {
|
|
331
|
-
|
|
332
|
-
const targetMessage = this.resolveToolCallTargetMessage(payload.sessionId, payload.toolCallId, payload.messageId);
|
|
333
|
-
this.toolCallArgsRawByCallId.set(payload.toolCallId, "");
|
|
334
|
-
const nextParts = upsertToolInvocationPart(targetMessage.parts, {
|
|
335
|
-
type: "tool-invocation",
|
|
336
|
-
toolCallId: payload.toolCallId,
|
|
337
|
-
toolName: payload.toolName,
|
|
338
|
-
state: "partial-call",
|
|
339
|
-
args: ""
|
|
340
|
-
});
|
|
341
|
-
this.replaceStreamingMessage({
|
|
342
|
-
...targetMessage,
|
|
343
|
-
parts: nextParts,
|
|
344
|
-
status: "streaming"
|
|
345
|
-
});
|
|
457
|
+
this.toolCalls.handleToolCallStart(payload);
|
|
346
458
|
this.setError(null);
|
|
347
459
|
};
|
|
348
460
|
handleMessageToolCallArgs = (payload) => {
|
|
349
|
-
|
|
350
|
-
this.toolCallArgsRawByCallId.set(payload.toolCallId, payload.args);
|
|
351
|
-
this.applyToolCallArgs(payload.sessionId, payload.toolCallId, payload.args);
|
|
461
|
+
this.toolCalls.handleToolCallArgs(payload);
|
|
352
462
|
};
|
|
353
463
|
handleMessageToolCallArgsDelta = (payload) => {
|
|
354
|
-
|
|
355
|
-
const nextArgs = `${this.toolCallArgsRawByCallId.get(payload.toolCallId) ?? ""}${payload.delta}`;
|
|
356
|
-
this.toolCallArgsRawByCallId.set(payload.toolCallId, nextArgs);
|
|
357
|
-
this.applyToolCallArgs(payload.sessionId, payload.toolCallId, nextArgs, payload.messageId);
|
|
464
|
+
this.toolCalls.handleToolCallArgsDelta(payload);
|
|
358
465
|
};
|
|
359
466
|
handleMessageToolCallEnd = (payload) => {
|
|
360
|
-
|
|
361
|
-
const targetMessage = this.resolveToolCallTargetMessage(payload.sessionId, payload.toolCallId);
|
|
362
|
-
const args = this.toolCallArgsRawByCallId.get(payload.toolCallId) ?? "";
|
|
363
|
-
const nextParts = upsertToolInvocationPart(targetMessage.parts, {
|
|
364
|
-
type: "tool-invocation",
|
|
365
|
-
toolCallId: payload.toolCallId,
|
|
366
|
-
toolName: findToolNameByCallId(targetMessage.parts, payload.toolCallId) ?? "unknown",
|
|
367
|
-
state: "call",
|
|
368
|
-
args
|
|
369
|
-
});
|
|
370
|
-
this.replaceStreamingMessage({
|
|
371
|
-
...targetMessage,
|
|
372
|
-
parts: nextParts,
|
|
373
|
-
status: "streaming"
|
|
374
|
-
});
|
|
467
|
+
this.toolCalls.handleToolCallEnd(payload);
|
|
375
468
|
};
|
|
376
469
|
handleMessageToolCallResult = (payload) => {
|
|
377
|
-
|
|
378
|
-
if (!this.updateMessageContainingToolCall(payload.toolCallId, (targetMessage, existingPart) => {
|
|
379
|
-
const mergedPart = {
|
|
380
|
-
type: "tool-invocation",
|
|
381
|
-
toolCallId: payload.toolCallId,
|
|
382
|
-
toolName: existingPart.toolName,
|
|
383
|
-
state: "result",
|
|
384
|
-
args: existingPart.args,
|
|
385
|
-
result: payload.content,
|
|
386
|
-
resultContentItems: payload.contentItems
|
|
387
|
-
};
|
|
388
|
-
return upsertToolInvocationPart(targetMessage.parts, mergedPart);
|
|
389
|
-
})) {
|
|
390
|
-
const fallbackMessage = this.resolveToolCallTargetMessage(payload.sessionId, payload.toolCallId);
|
|
391
|
-
const nextParts = upsertToolInvocationPart(fallbackMessage.parts, {
|
|
392
|
-
type: "tool-invocation",
|
|
393
|
-
toolCallId: payload.toolCallId,
|
|
394
|
-
toolName: "unknown",
|
|
395
|
-
state: "result",
|
|
396
|
-
result: payload.content,
|
|
397
|
-
resultContentItems: payload.contentItems
|
|
398
|
-
});
|
|
399
|
-
this.replaceStreamingMessage({
|
|
400
|
-
...fallbackMessage,
|
|
401
|
-
parts: nextParts,
|
|
402
|
-
status: "streaming"
|
|
403
|
-
});
|
|
404
|
-
}
|
|
470
|
+
this.toolCalls.handleToolCallResult(payload);
|
|
405
471
|
};
|
|
406
472
|
handleRunStarted = (payload) => {
|
|
407
473
|
if (this.isSettledRunId(payload.runId)) return;
|
|
@@ -456,22 +522,6 @@ var DefaultNcpAgentConversationStateManager = class {
|
|
|
456
522
|
this.clearActiveRun();
|
|
457
523
|
this.setError(payload);
|
|
458
524
|
};
|
|
459
|
-
applyToolCallArgs = (sessionId, toolCallId, args, messageId) => {
|
|
460
|
-
const targetMessage = this.resolveToolCallTargetMessage(sessionId, toolCallId, messageId);
|
|
461
|
-
const toolName = findToolNameByCallId(targetMessage.parts, toolCallId) ?? "unknown";
|
|
462
|
-
const nextParts = upsertToolInvocationPart(targetMessage.parts, {
|
|
463
|
-
type: "tool-invocation",
|
|
464
|
-
toolCallId,
|
|
465
|
-
toolName,
|
|
466
|
-
state: "partial-call",
|
|
467
|
-
args
|
|
468
|
-
});
|
|
469
|
-
this.replaceStreamingMessage({
|
|
470
|
-
...targetMessage,
|
|
471
|
-
parts: nextParts,
|
|
472
|
-
status: "streaming"
|
|
473
|
-
});
|
|
474
|
-
};
|
|
475
525
|
ensureStreamingMessage = (sessionId, messageId, status) => {
|
|
476
526
|
if (this.streamingMessage?.id === messageId) {
|
|
477
527
|
if (this.streamingMessage.status === status) return this.streamingMessage;
|
|
@@ -505,7 +555,7 @@ var DefaultNcpAgentConversationStateManager = class {
|
|
|
505
555
|
sessionId,
|
|
506
556
|
status
|
|
507
557
|
};
|
|
508
|
-
|
|
558
|
+
this.toolCalls.remapMessageId(existingStreamingMessage.id, messageId);
|
|
509
559
|
this.replaceStreamingMessage(nextStreamingMessage);
|
|
510
560
|
return nextStreamingMessage;
|
|
511
561
|
}
|
|
@@ -520,11 +570,6 @@ var DefaultNcpAgentConversationStateManager = class {
|
|
|
520
570
|
this.replaceStreamingMessage(nextStreamingMessage);
|
|
521
571
|
return nextStreamingMessage;
|
|
522
572
|
};
|
|
523
|
-
resolveToolCallTargetMessage = (sessionId, toolCallId, messageId) => {
|
|
524
|
-
const preferredMessageId = messageId?.trim() || this.toolCallMessageIdByCallId.get(toolCallId) || this.streamingMessage?.id || `tool-${toolCallId}`;
|
|
525
|
-
this.toolCallMessageIdByCallId.set(toolCallId, preferredMessageId);
|
|
526
|
-
return this.ensureStreamingMessage(sessionId, preferredMessageId, "streaming");
|
|
527
|
-
};
|
|
528
573
|
updateMessageContainingToolCall = (toolCallId, updater) => {
|
|
529
574
|
if (this.streamingMessage) {
|
|
530
575
|
const part = findToolInvocationPart(this.streamingMessage.parts, toolCallId);
|
|
@@ -595,7 +640,7 @@ var DefaultNcpAgentConversationStateManager = class {
|
|
|
595
640
|
const settledMessage = settleMessageWithLifecycle(this.streamingMessage, status, lifecycle);
|
|
596
641
|
this.upsertMessage(settledMessage);
|
|
597
642
|
this.replaceStreamingMessage(null);
|
|
598
|
-
|
|
643
|
+
this.toolCalls.clearByMessageId(settledMessage.id);
|
|
599
644
|
};
|
|
600
645
|
notifyListeners = () => {
|
|
601
646
|
const snapshot = this.getSnapshot();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/agent/agent-conversation-message-normalizer.ts","../src/agent/agent-conversation-state-manager.utils.ts","../src/agent/agent-conversation-state-manager.ts","../src/agent/agent-client-from-server.ts","../src/agent/agent-backend/event-publisher.ts","../src/agent/agent-backend/in-memory-agent-session.store.ts","../src/errors/ncp-error-exception.ts","../src/chat/ncp-reply-consumer.ts"],"sourcesContent":["import { type NcpMessage, sanitizeAssistantReplyTags } from \"@nextclaw/ncp\";\n\nexport function cloneConversationMessage(message: NcpMessage): NcpMessage {\n return {\n ...message,\n parts: [...message.parts],\n lifecycle: message.lifecycle ? { ...message.lifecycle } : undefined,\n metadata: message.metadata ? { ...message.metadata } : undefined,\n };\n}\n\nexport function normalizeConversationMessage(message: NcpMessage): NcpMessage {\n return cloneConversationMessage(sanitizeAssistantReplyTags(message));\n}\n","import type {\n NcpError,\n NcpMessage,\n NcpMessageStatus,\n NcpRunErrorPayload,\n NcpRunFinishedPayload,\n} from \"@nextclaw/ncp\";\n\nexport const ABORTED_TOOL_CALL_SENTINEL = \"__nextclaw_aborted_tool_call__\";\n\nexport function buildRuntimeError(payload: NcpRunErrorPayload): NcpError {\n const message = payload.error?.trim();\n return {\n code: \"runtime-error\",\n message: message && message.length > 0 ? message : \"Agent run failed.\",\n details: {\n sessionId: payload.sessionId,\n messageId: payload.messageId,\n threadId: payload.threadId,\n runId: payload.runId,\n },\n };\n}\n\nexport function readMessageLifecycleFromRunPayload(\n payload: Pick<NcpRunFinishedPayload | NcpRunErrorPayload, \"startedAt\" | \"endedAt\">,\n): NcpMessage[\"lifecycle\"] | undefined {\n if (!payload.startedAt && !payload.endedAt) {\n return undefined;\n }\n return {\n startedAt: payload.startedAt,\n endedAt: payload.endedAt,\n };\n}\n\nexport function settleMessageWithLifecycle(\n message: NcpMessage,\n status: Extract<NcpMessageStatus, \"final\" | \"error\">,\n lifecycle?: NcpMessage[\"lifecycle\"],\n): NcpMessage {\n return lifecycle\n ? {\n ...message,\n status,\n lifecycle,\n }\n : {\n ...message,\n status,\n };\n}\n\nfunction resolveTimelineInsertIndex(\n messages: readonly NcpMessage[],\n message: NcpMessage,\n): number {\n const targetTimestamp = Date.parse(message.timestamp);\n if (!Number.isFinite(targetTimestamp)) {\n return messages.length;\n }\n const laterMessageIndex = messages.findIndex((item) => {\n const timestamp = Date.parse(item.timestamp);\n return Number.isFinite(timestamp) && timestamp > targetTimestamp;\n });\n return laterMessageIndex < 0 ? messages.length : laterMessageIndex;\n}\n\nexport function insertMessageByTimeline(\n messages: readonly NcpMessage[],\n message: NcpMessage,\n): NcpMessage[] {\n const nextMessages = [...messages];\n nextMessages.splice(resolveTimelineInsertIndex(messages, message), 0, message);\n return nextMessages;\n}\n\nexport function shouldPromoteStreamingMessageId(\n message: NcpMessage,\n nextMessageId: string,\n): boolean {\n if (!nextMessageId.trim()) {\n return false;\n }\n if (message.id.startsWith(\"tool-\")) {\n return true;\n }\n return message.parts.some((part) => part.type === \"tool-invocation\");\n}\n\nexport function remapTrackedToolCallsToMessageId(\n toolCallMessageIdByCallId: Map<string, string>,\n fromMessageId: string,\n toMessageId: string,\n): void {\n for (const [toolCallId, trackedMessageId] of toolCallMessageIdByCallId) {\n if (trackedMessageId !== fromMessageId) {\n continue;\n }\n toolCallMessageIdByCallId.set(toolCallId, toMessageId);\n }\n}\n\nexport function clearToolCallTrackingByMessageId(\n toolCallMessageIdByCallId: Map<string, string>,\n toolCallArgsRawByCallId: Map<string, string>,\n messageId: string,\n): void {\n for (const [toolCallId, trackedMessageId] of toolCallMessageIdByCallId) {\n if (trackedMessageId !== messageId) {\n continue;\n }\n toolCallMessageIdByCallId.delete(toolCallId);\n toolCallArgsRawByCallId.delete(toolCallId);\n }\n}\n\nexport function findToolInvocationPart(\n parts: NcpMessage[\"parts\"],\n toolCallId: string,\n): Extract<NcpMessage[\"parts\"][number], { type: \"tool-invocation\" }> | null {\n for (let index = parts.length - 1; index >= 0; index -= 1) {\n const part = parts[index];\n if (part.type === \"tool-invocation\" && part.toolCallId === toolCallId) {\n return part;\n }\n }\n return null;\n}\n\nexport function findToolNameByCallId(\n parts: NcpMessage[\"parts\"],\n toolCallId: string,\n): string | null {\n const part = findToolInvocationPart(parts, toolCallId);\n return part?.toolName ?? null;\n}\n\nexport function upsertToolInvocationPart(\n parts: NcpMessage[\"parts\"],\n toolPart: Extract<NcpMessage[\"parts\"][number], { type: \"tool-invocation\" }>,\n): NcpMessage[\"parts\"] {\n const nextParts = [...parts];\n for (let index = nextParts.length - 1; index >= 0; index -= 1) {\n const part = nextParts[index];\n if (part.type === \"tool-invocation\" && part.toolCallId === toolPart.toolCallId) {\n nextParts[index] = {\n ...part,\n ...toolPart,\n };\n return nextParts;\n }\n }\n nextParts.push(toolPart);\n return nextParts;\n}\n\nexport function cancelInFlightToolInvocations(parts: NcpMessage[\"parts\"]): {\n parts: NcpMessage[\"parts\"];\n toolCallIds: string[];\n} {\n const toolCallIds: string[] = [];\n return {\n parts: parts.map((part) => {\n if (\n part.type !== \"tool-invocation\" ||\n !part.toolCallId ||\n part.state === \"result\" ||\n part.state === \"cancelled\"\n ) {\n return part;\n }\n toolCallIds.push(part.toolCallId);\n return {\n ...part,\n state: \"cancelled\" as const,\n };\n }),\n toolCallIds,\n };\n}\n","import {\n type NcpAgentConversationSnapshot,\n type NcpAgentConversationStateManager,\n type NcpAgentConversationHydrationParams,\n type NcpContextWindowUpdatedPayload,\n type NcpEndpointEvent,\n type NcpError,\n type NcpMessage,\n type NcpMessageAbortPayload,\n type NcpMessageRole,\n type NcpMessageSentPayload,\n type NcpMessageStatus,\n type NcpRunContext,\n type NcpRunErrorPayload,\n type NcpRunFinishedPayload,\n type NcpRunMetadataPayload,\n type NcpRunReadyMetadata,\n type NcpRunStartedPayload,\n type NcpReasoningDeltaPayload,\n type NcpReasoningEndPayload,\n type NcpReasoningStartPayload,\n type NcpTextDeltaPayload,\n type NcpTextEndPayload,\n type NcpTextStartPayload,\n type NcpToolCallArgsDeltaPayload,\n type NcpToolCallArgsPayload,\n type NcpToolCallEndPayload,\n type NcpToolCallResultPayload,\n type NcpToolCallStartPayload,\n NcpEventType,\n} from \"@nextclaw/ncp\";\nimport { cloneConversationMessage, normalizeConversationMessage } from \"./agent-conversation-message-normalizer.js\";\nimport { ABORTED_TOOL_CALL_SENTINEL, buildRuntimeError, cancelInFlightToolInvocations, clearToolCallTrackingByMessageId, findToolInvocationPart, findToolNameByCallId, insertMessageByTimeline, readMessageLifecycleFromRunPayload, remapTrackedToolCallsToMessageId, settleMessageWithLifecycle, shouldPromoteStreamingMessageId, upsertToolInvocationPart } from \"./agent-conversation-state-manager.utils.js\";\n\nconst DEFAULT_ASSISTANT_ROLE: NcpMessageRole = \"assistant\";\n\nexport class DefaultNcpAgentConversationStateManager implements NcpAgentConversationStateManager {\n private messages: NcpMessage[] = [];\n private streamingMessage: NcpMessage | null = null;\n private error: NcpError | null = null;\n private activeRun: NcpRunContext | null = null;\n private contextWindow: Record<string, unknown> | null = null;\n private readonly listeners = new Set<(snapshot: NcpAgentConversationSnapshot) => void>();\n private readonly toolCallMessageIdByCallId = new Map<string, string>();\n private readonly toolCallArgsRawByCallId = new Map<string, string>();\n private lastSettledRunId: string | null = null;\n private snapshotCache: NcpAgentConversationSnapshot | null = null;\n private snapshotVersion = -1;\n private stateVersion = 0;\n\n getSnapshot = (): NcpAgentConversationSnapshot => {\n if (this.snapshotCache && this.snapshotVersion === this.stateVersion) {\n return this.snapshotCache;\n }\n const snapshot: NcpAgentConversationSnapshot = {\n messages: this.messages,\n streamingMessage: this.streamingMessage,\n error: this.error\n ? {\n ...this.error,\n details: this.error.details ? { ...this.error.details } : undefined,\n }\n : null,\n activeRun: this.activeRun ? { ...this.activeRun } : null,\n contextWindow: this.contextWindow ? { ...this.contextWindow } : null,\n };\n this.snapshotCache = snapshot;\n this.snapshotVersion = this.stateVersion;\n return snapshot;\n };\n\n subscribe = (listener: (snapshot: NcpAgentConversationSnapshot) => void) => {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n };\n\n reset = (): void => {\n if (\n this.messages.length === 0 &&\n !this.streamingMessage &&\n !this.error &&\n !this.activeRun &&\n !this.contextWindow &&\n this.toolCallMessageIdByCallId.size === 0 &&\n this.toolCallArgsRawByCallId.size === 0\n ) {\n return;\n }\n this.messages = [];\n this.streamingMessage = null;\n this.error = null;\n this.activeRun = null;\n this.contextWindow = null;\n this.toolCallMessageIdByCallId.clear();\n this.toolCallArgsRawByCallId.clear();\n this.lastSettledRunId = null;\n this.stateVersion += 1;\n this.notifyListeners();\n };\n\n hydrate = (payload: NcpAgentConversationHydrationParams): void => {\n this.messages = payload.messages.map((message: NcpMessage) => normalizeConversationMessage(message));\n this.streamingMessage = null;\n this.error = null;\n this.contextWindow = payload.contextWindow ? { ...payload.contextWindow } : null;\n this.activeRun = payload.activeRun\n ? {\n ...payload.activeRun,\n sessionId: payload.activeRun.sessionId ?? payload.sessionId,\n abortDisabledReason: payload.activeRun.abortDisabledReason ?? null,\n }\n : null;\n this.toolCallMessageIdByCallId.clear();\n this.toolCallArgsRawByCallId.clear();\n this.lastSettledRunId = null;\n this.stateVersion += 1;\n this.notifyListeners();\n };\n\n dispatch = (event: NcpEndpointEvent): Promise<void> => this.dispatchBatch([event]);\n\n dispatchBatch = async (events: readonly NcpEndpointEvent[]): Promise<void> => {\n if (!events.length) return;\n const versionBeforeDispatch = this.stateVersion;\n events.forEach(this.applyEvent);\n if (this.stateVersion !== versionBeforeDispatch) this.notifyListeners();\n };\n\n private applyEvent = (event: NcpEndpointEvent): void => {\n switch (event.type) {\n case NcpEventType.MessageSent:\n this.handleMessageSent(event.payload);\n break;\n case NcpEventType.MessageAbort:\n this.handleMessageAbort(event.payload);\n break;\n case NcpEventType.MessageTextStart:\n this.handleMessageTextStart(event.payload);\n break;\n case NcpEventType.MessageTextDelta:\n this.handleMessageTextDelta(event.payload);\n break;\n case NcpEventType.MessageTextEnd:\n this.handleMessageTextEnd(event.payload);\n break;\n case NcpEventType.MessageReasoningStart:\n this.handleMessageReasoningStart(event.payload);\n break;\n case NcpEventType.MessageReasoningDelta:\n this.handleMessageReasoningDelta(event.payload);\n break;\n case NcpEventType.MessageReasoningEnd:\n this.handleMessageReasoningEnd(event.payload);\n break;\n case NcpEventType.MessageToolCallStart:\n this.handleMessageToolCallStart(event.payload);\n break;\n case NcpEventType.MessageToolCallArgs:\n this.handleMessageToolCallArgs(event.payload);\n break;\n case NcpEventType.MessageToolCallArgsDelta:\n this.handleMessageToolCallArgsDelta(event.payload);\n break;\n case NcpEventType.MessageToolCallEnd:\n this.handleMessageToolCallEnd(event.payload);\n break;\n case NcpEventType.MessageToolCallResult:\n this.handleMessageToolCallResult(event.payload);\n break;\n case NcpEventType.RunStarted:\n this.handleRunStarted(event.payload);\n break;\n case NcpEventType.RunFinished:\n this.handleRunFinished(event.payload);\n break;\n case NcpEventType.RunError:\n this.handleRunError(event.payload);\n break;\n case NcpEventType.RunMetadata:\n this.handleRunMetadata(event.payload);\n break;\n case NcpEventType.ContextWindowUpdated:\n this.handleContextWindowUpdated(event.payload);\n break;\n case NcpEventType.EndpointError:\n this.handleEndpointError(event.payload);\n break;\n default:\n break;\n }\n };\n\n handleMessageSent = (payload: NcpMessageSentPayload): void => {\n this.upsertMessage(payload.message);\n this.setError(null);\n };\n\n handleMessageAbort = (payload: NcpMessageAbortPayload): void => {\n const targetMessageId = payload.messageId?.trim();\n this.clearActiveRun();\n this.setError(null);\n\n if (\n this.streamingMessage &&\n (!targetMessageId || this.streamingMessage.id === targetMessageId)\n ) {\n const streamingMessageId = this.streamingMessage.id;\n const { parts: nextParts, toolCallIds } = cancelInFlightToolInvocations(this.streamingMessage.parts);\n this.upsertMessage({\n ...this.streamingMessage,\n status: \"final\",\n parts: nextParts,\n });\n this.replaceStreamingMessage(null);\n if (targetMessageId) {\n clearToolCallTrackingByMessageId(this.toolCallMessageIdByCallId, this.toolCallArgsRawByCallId, targetMessageId);\n } else {\n clearToolCallTrackingByMessageId(this.toolCallMessageIdByCallId, this.toolCallArgsRawByCallId, streamingMessageId);\n }\n toolCallIds.forEach((toolCallId) => this.toolCallArgsRawByCallId.set(toolCallId, ABORTED_TOOL_CALL_SENTINEL));\n }\n };\n\n handleMessageTextStart = (payload: NcpTextStartPayload): void => {\n this.ensureStreamingMessage(payload.sessionId, payload.messageId, \"streaming\");\n this.setError(null);\n };\n\n handleMessageTextDelta = (payload: NcpTextDeltaPayload): void => {\n if (!payload.delta) {\n return;\n }\n\n const targetMessage = this.ensureStreamingMessage(payload.sessionId, payload.messageId, \"streaming\");\n const nextParts = [...targetMessage.parts];\n const lastPart = nextParts[nextParts.length - 1];\n if (lastPart?.type === \"text\") {\n nextParts[nextParts.length - 1] = {\n type: \"text\",\n text: `${lastPart.text}${payload.delta}`,\n };\n } else {\n nextParts.push({ type: \"text\", text: payload.delta });\n }\n\n this.replaceStreamingMessage({ ...targetMessage, parts: nextParts, status: \"streaming\" });\n };\n\n handleMessageTextEnd = (payload: NcpTextEndPayload): void => {\n if (this.streamingMessage?.id !== payload.messageId) {\n return;\n }\n if (this.streamingMessage.status !== \"streaming\") {\n return;\n }\n this.replaceStreamingMessage({ ...this.streamingMessage, status: \"pending\" });\n };\n\n handleMessageReasoningStart = (payload: NcpReasoningStartPayload): void => {\n this.ensureStreamingMessage(payload.sessionId, payload.messageId, \"streaming\");\n };\n\n handleMessageReasoningDelta = (payload: NcpReasoningDeltaPayload): void => {\n if (!payload.delta) {\n return;\n }\n\n const targetMessage = this.ensureStreamingMessage(payload.sessionId, payload.messageId, \"streaming\");\n const nextParts = [...targetMessage.parts];\n const lastPart = nextParts[nextParts.length - 1];\n\n if (lastPart?.type === \"reasoning\") {\n nextParts[nextParts.length - 1] = {\n type: \"reasoning\",\n text: `${lastPart.text}${payload.delta}`,\n };\n } else {\n nextParts.push({ type: \"reasoning\", text: payload.delta });\n }\n\n this.replaceStreamingMessage({ ...targetMessage, parts: nextParts, status: \"streaming\" });\n };\n\n handleMessageReasoningEnd = (payload: NcpReasoningEndPayload): void => {\n if (this.streamingMessage?.id !== payload.messageId) {\n return;\n }\n // End is an event boundary; no snapshot mutation required.\n };\n\n handleMessageToolCallStart = (payload: NcpToolCallStartPayload): void => {\n if (this.toolCallArgsRawByCallId.get(payload.toolCallId) === ABORTED_TOOL_CALL_SENTINEL) return;\n const targetMessage = this.resolveToolCallTargetMessage(payload.sessionId, payload.toolCallId, payload.messageId);\n this.toolCallArgsRawByCallId.set(payload.toolCallId, \"\");\n\n const nextParts = upsertToolInvocationPart(targetMessage.parts, {\n type: \"tool-invocation\",\n toolCallId: payload.toolCallId,\n toolName: payload.toolName,\n state: \"partial-call\",\n args: \"\",\n });\n\n this.replaceStreamingMessage({\n ...targetMessage,\n parts: nextParts,\n status: \"streaming\",\n });\n this.setError(null);\n };\n\n handleMessageToolCallArgs = (payload: NcpToolCallArgsPayload): void => {\n if (this.toolCallArgsRawByCallId.get(payload.toolCallId) === ABORTED_TOOL_CALL_SENTINEL) return;\n this.toolCallArgsRawByCallId.set(payload.toolCallId, payload.args);\n this.applyToolCallArgs(payload.sessionId, payload.toolCallId, payload.args);\n };\n\n handleMessageToolCallArgsDelta = (payload: NcpToolCallArgsDeltaPayload): void => {\n if (this.toolCallArgsRawByCallId.get(payload.toolCallId) === ABORTED_TOOL_CALL_SENTINEL) return;\n const currentArgs = this.toolCallArgsRawByCallId.get(payload.toolCallId) ?? \"\";\n const nextArgs = `${currentArgs}${payload.delta}`;\n this.toolCallArgsRawByCallId.set(payload.toolCallId, nextArgs);\n this.applyToolCallArgs(payload.sessionId, payload.toolCallId, nextArgs, payload.messageId);\n };\n\n handleMessageToolCallEnd = (payload: NcpToolCallEndPayload): void => {\n if (this.toolCallArgsRawByCallId.get(payload.toolCallId) === ABORTED_TOOL_CALL_SENTINEL) return;\n const targetMessage = this.resolveToolCallTargetMessage(payload.sessionId, payload.toolCallId);\n const args = this.toolCallArgsRawByCallId.get(payload.toolCallId) ?? \"\";\n const nextParts = upsertToolInvocationPart(targetMessage.parts, {\n type: \"tool-invocation\",\n toolCallId: payload.toolCallId,\n toolName: findToolNameByCallId(targetMessage.parts, payload.toolCallId) ?? \"unknown\",\n state: \"call\",\n args,\n });\n\n this.replaceStreamingMessage({\n ...targetMessage,\n parts: nextParts,\n status: \"streaming\",\n });\n };\n\n handleMessageToolCallResult = (payload: NcpToolCallResultPayload): void => {\n if (this.toolCallArgsRawByCallId.get(payload.toolCallId) === ABORTED_TOOL_CALL_SENTINEL) return;\n const updated = this.updateMessageContainingToolCall(\n payload.toolCallId,\n (targetMessage, existingPart) => {\n const mergedPart = {\n type: \"tool-invocation\" as const,\n toolCallId: payload.toolCallId,\n toolName: existingPart.toolName,\n state: \"result\" as const,\n args: existingPart.args,\n result: payload.content,\n resultContentItems: payload.contentItems,\n };\n return upsertToolInvocationPart(targetMessage.parts, mergedPart);\n },\n );\n if (!updated) {\n const fallbackMessage = this.resolveToolCallTargetMessage(\n payload.sessionId,\n payload.toolCallId,\n );\n const nextParts = upsertToolInvocationPart(fallbackMessage.parts, {\n type: \"tool-invocation\",\n toolCallId: payload.toolCallId,\n toolName: \"unknown\",\n state: \"result\",\n result: payload.content,\n resultContentItems: payload.contentItems,\n });\n this.replaceStreamingMessage({\n ...fallbackMessage,\n parts: nextParts,\n status: \"streaming\",\n });\n }\n };\n handleRunStarted = (payload: NcpRunStartedPayload): void => {\n if (this.isSettledRunId(payload.runId)) return;\n this.setError(null);\n this.activeRun = { runId: payload.runId ?? null, sessionId: payload.sessionId };\n this.stateVersion += 1;\n };\n\n handleRunFinished = (payload: NcpRunFinishedPayload): void => {\n this.markRunAsSettled(payload.runId ?? this.activeRun?.runId ?? null);\n this.settleStreamingMessage(\"final\", readMessageLifecycleFromRunPayload(payload));\n this.setError(null);\n this.clearActiveRun();\n };\n\n handleRunError = (payload: NcpRunErrorPayload): void => {\n this.markRunAsSettled(payload.runId ?? this.activeRun?.runId ?? null);\n this.settleStreamingMessage(\"error\", readMessageLifecycleFromRunPayload(payload));\n this.setError(buildRuntimeError(payload));\n this.clearActiveRun();\n };\n\n handleRunMetadata = (payload: NcpRunMetadataPayload): void => {\n const m = payload.metadata as Record<string, unknown>;\n if (m?.kind === \"ready\") {\n const ready = m as NcpRunReadyMetadata;\n if (this.isSettledRunId(ready.runId)) return;\n this.activeRun = {\n runId: ready.runId ?? this.activeRun?.runId ?? null,\n sessionId: ready.sessionId ?? this.activeRun?.sessionId,\n abortDisabledReason: ready.supportsAbort === false ? (ready.abortDisabledReason ?? \"Unsupported\") : null,\n };\n this.stateVersion += 1;\n } else if (m?.kind === \"final\") {\n this.markRunAsSettled(payload.runId ?? this.activeRun?.runId ?? null);\n this.clearActiveRun();\n }\n };\n\n handleContextWindowUpdated = (payload: NcpContextWindowUpdatedPayload): void => {\n this.contextWindow = { ...payload.contextWindow };\n this.stateVersion += 1;\n };\n\n handleEndpointError = (payload: NcpError): void => {\n if (payload.code === \"abort-error\") {\n this.handleMessageAbort({\n sessionId: this.activeRun?.sessionId ?? this.streamingMessage?.sessionId ?? \"\",\n ...(this.streamingMessage?.id ? { messageId: this.streamingMessage.id } : {}),\n });\n return;\n }\n this.settleStreamingMessage(\"error\");\n this.clearActiveRun();\n this.setError(payload);\n };\n\n private applyToolCallArgs = (\n sessionId: string,\n toolCallId: string,\n args: string,\n messageId?: string,\n ): void => {\n const targetMessage = this.resolveToolCallTargetMessage(\n sessionId,\n toolCallId,\n messageId,\n );\n const toolName =\n findToolNameByCallId(targetMessage.parts, toolCallId) ?? \"unknown\";\n const nextParts = upsertToolInvocationPart(targetMessage.parts, {\n type: \"tool-invocation\",\n toolCallId,\n toolName,\n state: \"partial-call\",\n args,\n });\n\n this.replaceStreamingMessage({\n ...targetMessage,\n parts: nextParts,\n status: \"streaming\",\n });\n };\n\n private ensureStreamingMessage = (\n sessionId: string,\n messageId: string,\n status: NcpMessageStatus,\n ): NcpMessage => {\n if (this.streamingMessage?.id === messageId) {\n if (this.streamingMessage.status === status) {\n return this.streamingMessage;\n }\n const nextStreamingMessage = {\n ...this.streamingMessage,\n status,\n };\n this.replaceStreamingMessage(nextStreamingMessage);\n return nextStreamingMessage;\n }\n\n const messageIndex = this.messages.findIndex(\n (message) => message.id === messageId,\n );\n if (messageIndex >= 0) {\n const existingMessage = cloneConversationMessage(\n this.messages[messageIndex]!,\n );\n const nextMessages = [...this.messages];\n nextMessages.splice(messageIndex, 1);\n this.messages = nextMessages;\n this.stateVersion += 1;\n const nextStreamingMessage = {\n ...existingMessage,\n sessionId,\n status,\n };\n this.replaceStreamingMessage(nextStreamingMessage);\n return nextStreamingMessage;\n }\n\n const existingStreamingMessage = this.streamingMessage;\n if (\n existingStreamingMessage &&\n existingStreamingMessage.id !== messageId &&\n existingStreamingMessage.sessionId === sessionId &&\n shouldPromoteStreamingMessageId(existingStreamingMessage, messageId)\n ) {\n const nextStreamingMessage: NcpMessage = {\n ...existingStreamingMessage,\n id: messageId,\n sessionId,\n status,\n };\n remapTrackedToolCallsToMessageId(\n this.toolCallMessageIdByCallId,\n existingStreamingMessage.id,\n messageId,\n );\n this.replaceStreamingMessage(nextStreamingMessage);\n return nextStreamingMessage;\n }\n\n const nextStreamingMessage: NcpMessage = {\n id: messageId,\n sessionId,\n role: DEFAULT_ASSISTANT_ROLE,\n status,\n parts: [],\n timestamp: new Date().toISOString(),\n };\n this.replaceStreamingMessage(nextStreamingMessage);\n return nextStreamingMessage;\n };\n\n private resolveToolCallTargetMessage = (\n sessionId: string,\n toolCallId: string,\n messageId?: string,\n ): NcpMessage => {\n const preferredMessageId =\n messageId?.trim() ||\n this.toolCallMessageIdByCallId.get(toolCallId) ||\n this.streamingMessage?.id ||\n `tool-${toolCallId}`;\n\n this.toolCallMessageIdByCallId.set(toolCallId, preferredMessageId);\n return this.ensureStreamingMessage(sessionId, preferredMessageId, \"streaming\");\n };\n\n private updateMessageContainingToolCall = (\n toolCallId: string,\n updater: (\n targetMessage: NcpMessage,\n existingPart: Extract<\n NcpMessage[\"parts\"][number],\n { type: \"tool-invocation\" }\n >,\n ) => NcpMessage[\"parts\"],\n ): boolean => {\n if (this.streamingMessage) {\n const part = findToolInvocationPart(\n this.streamingMessage.parts,\n toolCallId,\n );\n if (part) {\n const nextParts = updater(this.streamingMessage, part);\n this.replaceStreamingMessage({ ...this.streamingMessage, parts: nextParts });\n return true;\n }\n }\n\n for (let index = this.messages.length - 1; index >= 0; index -= 1) {\n const candidateMessage = this.messages[index];\n const part = findToolInvocationPart(candidateMessage.parts, toolCallId);\n if (!part) {\n continue;\n }\n const nextMessages = [...this.messages];\n nextMessages[index] = {\n ...candidateMessage,\n parts: updater(candidateMessage, part),\n };\n this.messages = nextMessages;\n this.stateVersion += 1;\n return true;\n }\n\n return false;\n };\n\n private upsertMessage = (message: NcpMessage): void => {\n const normalizedMessage = normalizeConversationMessage(message);\n if (this.streamingMessage?.id === normalizedMessage.id) this.streamingMessage = null;\n const messageIndex = this.messages.findIndex((item) => item.id === normalizedMessage.id);\n if (messageIndex < 0) {\n this.messages = insertMessageByTimeline(this.messages, normalizedMessage);\n this.stateVersion += 1;\n return;\n }\n\n const nextMessages = [...this.messages];\n nextMessages[messageIndex] = normalizedMessage;\n this.messages = nextMessages;\n this.stateVersion += 1;\n };\n\n private replaceStreamingMessage = (nextStreamingMessage: NcpMessage | null): void => {\n if (!nextStreamingMessage && !this.streamingMessage) {\n return;\n }\n this.streamingMessage = nextStreamingMessage ? normalizeConversationMessage(nextStreamingMessage) : null;\n this.stateVersion += 1;\n };\n\n private setError = (nextError: NcpError | null): void => {\n const hasSameError =\n this.error?.code === nextError?.code &&\n this.error?.message === nextError?.message &&\n this.error?.details === nextError?.details &&\n this.error?.cause === nextError?.cause;\n if (hasSameError) {\n return;\n }\n\n this.error = nextError\n ? {\n ...nextError,\n details: nextError.details ? { ...nextError.details } : undefined,\n }\n : null;\n this.stateVersion += 1;\n };\n\n private clearActiveRun = (): void => {\n if (!this.activeRun) return;\n this.activeRun = null;\n this.stateVersion += 1;\n };\n\n private isSettledRunId = (runId: string | null | undefined): boolean => {\n return Boolean(runId?.trim()) && runId === this.lastSettledRunId;\n };\n\n private markRunAsSettled = (runId: string | null | undefined): void => {\n this.lastSettledRunId = runId?.trim() || null;\n };\n\n private settleStreamingMessage = (\n status: Extract<NcpMessageStatus, \"final\" | \"error\">,\n lifecycle?: NcpMessage[\"lifecycle\"],\n ): void => {\n if (!this.streamingMessage) return;\n const settledMessage = settleMessageWithLifecycle(this.streamingMessage, status, lifecycle);\n this.upsertMessage(settledMessage);\n this.replaceStreamingMessage(null);\n clearToolCallTrackingByMessageId(\n this.toolCallMessageIdByCallId,\n this.toolCallArgsRawByCallId,\n settledMessage.id,\n );\n };\n\n private notifyListeners = (): void => {\n const snapshot: NcpAgentConversationSnapshot = this.getSnapshot();\n for (const listener of this.listeners) listener(snapshot);\n };\n}\n","import {\n type NcpAgentClientEndpoint,\n type NcpAgentSendEnvelope,\n type NcpAgentServerEndpoint,\n type NcpEndpointEvent,\n type NcpEndpointSubscriber,\n type NcpMessageAbortPayload,\n type NcpRequestEnvelope,\n type NcpRunHandle,\n type NcpStreamRequestPayload,\n consumeNcpRunHandle,\n createNcpRunHandle,\n NcpEventType,\n} from \"@nextclaw/ncp\";\n\nfunction assertMaterializedEnvelope(\n envelope: NcpAgentSendEnvelope,\n): asserts envelope is NcpRequestEnvelope {\n if (!envelope.sessionId?.trim() || !envelope.message.sessionId?.trim()) {\n throw new Error(\"NCP request envelope must be materialized before server dispatch.\");\n }\n}\n\n/**\n * Creates an NcpAgentClientEndpoint that forwards to an in-process NcpAgentServerEndpoint.\n * Use when the agent runs in-process and you need to pass a client endpoint to the HTTP server.\n */\nexport function createAgentClientFromServer(\n server: NcpAgentServerEndpoint,\n): NcpAgentClientEndpoint {\n return {\n get manifest() {\n return server.manifest;\n },\n async start(): Promise<void> {\n await server.start();\n },\n async stop(): Promise<void> {\n await server.stop();\n },\n async emit(event: NcpEndpointEvent): Promise<void> {\n switch (event.type) {\n case NcpEventType.MessageRequest:\n assertMaterializedEnvelope(event.payload);\n await consumeNcpRunHandle(server.send(event.payload), createNcpRunHandle(event.payload));\n return;\n case NcpEventType.MessageStreamRequest:\n await consume(server.stream(event.payload));\n return;\n case NcpEventType.MessageAbort:\n await server.abort(event.payload);\n return;\n default:\n await server.emit(event);\n }\n },\n subscribe(listener: NcpEndpointSubscriber) {\n return server.subscribe(listener);\n },\n async send(envelope: NcpAgentSendEnvelope): Promise<NcpRunHandle> {\n assertMaterializedEnvelope(envelope);\n return await consumeNcpRunHandle(server.send(envelope), createNcpRunHandle(envelope));\n },\n async stream(payload: NcpStreamRequestPayload): Promise<void> {\n await consume(server.stream(payload));\n },\n async abort(payload: NcpMessageAbortPayload): Promise<void> {\n await server.abort(payload);\n },\n };\n}\n\nasync function consume(events: AsyncIterable<unknown>): Promise<void> {\n for await (const event of events) {\n // Consume iterator to execute server-side async generator side effects.\n void event;\n }\n}\n","import type { NcpEndpointEvent, NcpEndpointSubscriber } from \"@nextclaw/ncp\";\n\nexport class EventPublisher {\n private readonly listeners = new Set<NcpEndpointSubscriber>();\n private readonly closeListeners = new Set<() => void>();\n private closed = false;\n\n subscribe(listener: NcpEndpointSubscriber): () => void {\n if (this.closed) {\n return () => undefined;\n }\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n onClose(listener: () => void): () => void {\n if (this.closed) {\n listener();\n return () => undefined;\n }\n this.closeListeners.add(listener);\n return () => {\n this.closeListeners.delete(listener);\n };\n }\n\n publish(event: NcpEndpointEvent): void {\n if (this.closed) {\n return;\n }\n for (const listener of this.listeners) {\n listener(structuredClone(event));\n }\n }\n\n close(): void {\n if (this.closed) {\n return;\n }\n this.closed = true;\n this.listeners.clear();\n for (const listener of this.closeListeners) {\n listener();\n }\n this.closeListeners.clear();\n }\n}\n","import type { AgentSessionRecord, AgentSessionStore } from \"./agent-backend.types.js\";\n\nexport class InMemoryAgentSessionStore implements AgentSessionStore {\n private readonly sessions = new Map<string, AgentSessionRecord>();\n\n getSession = async (sessionId: string): Promise<AgentSessionRecord | null> => {\n const session = this.sessions.get(sessionId);\n return session ? structuredClone(session) : null;\n };\n\n listSessions = async (): Promise<AgentSessionRecord[]> => {\n return [...this.sessions.values()].map((session) => structuredClone(session));\n };\n\n saveSession = async (session: AgentSessionRecord): Promise<void> => {\n this.sessions.set(session.sessionId, structuredClone(session));\n };\n\n setSessionMetadata = async (params: {\n sessionId: string;\n metadata: Record<string, unknown>;\n updatedAt: string;\n }): Promise<boolean> => {\n const { metadata, sessionId, updatedAt } = params;\n const session = this.sessions.get(sessionId);\n if (!session) {\n return false;\n }\n this.sessions.set(sessionId, {\n ...session,\n metadata: structuredClone(metadata),\n updatedAt,\n });\n return true;\n };\n\n updateSessionMetadata = async (params: {\n sessionId: string;\n metadata: Record<string, unknown>;\n updatedAt: string;\n }): Promise<boolean> => {\n const session = this.sessions.get(params.sessionId);\n if (!session) {\n return false;\n }\n return await this.setSessionMetadata({\n ...params,\n metadata: {\n ...(session.metadata ? structuredClone(session.metadata) : {}),\n ...structuredClone(params.metadata),\n },\n });\n };\n\n deleteSession = async (sessionId: string): Promise<AgentSessionRecord | null> => {\n const session = this.sessions.get(sessionId);\n if (!session) {\n return null;\n }\n\n this.sessions.delete(sessionId);\n return structuredClone(session);\n };\n}\n","import type { NcpErrorCode } from \"@nextclaw/ncp\";\n\n/**\n * Throwable form of protocol error for exception-based control flows.\n */\nexport class NcpErrorException extends Error {\n readonly code: NcpErrorCode;\n readonly details?: Record<string, unknown>;\n\n constructor(\n code: NcpErrorCode,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = \"NcpErrorException\";\n this.code = code;\n this.details = details;\n }\n}\n","import {\n NcpEventType,\n sanitizeAssistantReplyTags,\n type NcpEndpointEvent,\n type NcpMessage,\n type NcpMessagePart,\n type NcpRichTextPart,\n type NcpTextPart,\n} from \"@nextclaw/ncp\";\nimport type { Chat, ChatTarget, NcpEventStream, NcpReplyInput } from \"./chat.types.js\";\n\nfunction isTextLikePart(\n part: NcpMessagePart,\n): part is Extract<NcpMessagePart, { type: \"text\" | \"rich-text\" }> {\n return part.type === \"text\" || part.type === \"rich-text\";\n}\n\nfunction normalizeMessageParts(message: NcpMessage): NcpMessagePart[] {\n const normalizedMessage =\n message.role === \"assistant\" ? sanitizeAssistantReplyTags(message) : message;\n return normalizedMessage.parts;\n}\n\nfunction cloneTextLikePartTail(\n part: Extract<NcpMessagePart, { type: \"text\" | \"rich-text\" }>,\n skipChars: number,\n): NcpTextPart | NcpRichTextPart | null {\n const nextText = part.text.slice(skipChars);\n if (!nextText) {\n return null;\n }\n if (part.type === \"text\") {\n return {\n type: \"text\",\n text: nextText,\n };\n }\n return {\n ...part,\n text: nextText,\n };\n}\n\nfunction resolveFallbackUnsentParts(\n fallbackText: string,\n sentText: string,\n): NcpMessagePart[] {\n if (!fallbackText || fallbackText === sentText) {\n return [];\n }\n const nextText =\n sentText && fallbackText.startsWith(sentText)\n ? fallbackText.slice(sentText.length)\n : fallbackText;\n return nextText ? [{ type: \"text\", text: nextText }] : [];\n}\n\nfunction canReuseCompletedTextPrefix(\n normalizedParts: NcpMessagePart[],\n sentText: string,\n): boolean {\n const finalText = normalizedParts\n .filter(isTextLikePart)\n .map((part) => part.text)\n .join(\"\");\n return !(sentText && finalText && !finalText.startsWith(sentText));\n}\n\nfunction collectUnsentPartsFromNormalizedParts(\n normalizedParts: NcpMessagePart[],\n sentText: string,\n): NcpMessagePart[] {\n let remainingSentChars = sentText.length;\n const unsentParts: NcpMessagePart[] = [];\n\n for (const part of normalizedParts) {\n if (!isTextLikePart(part)) {\n unsentParts.push(part);\n continue;\n }\n if (remainingSentChars >= part.text.length) {\n remainingSentChars -= part.text.length;\n continue;\n }\n if (remainingSentChars > 0) {\n const tail = cloneTextLikePartTail(part, remainingSentChars);\n remainingSentChars = 0;\n if (tail) {\n unsentParts.push(tail);\n }\n continue;\n }\n unsentParts.push(part);\n }\n\n return unsentParts;\n}\n\nfunction resolveUnsentMessageParts(\n message: NcpMessage,\n sentText: string,\n fallbackText: string,\n): NcpMessagePart[] {\n const normalizedParts = normalizeMessageParts(message);\n if (normalizedParts.length === 0) {\n return resolveFallbackUnsentParts(fallbackText, sentText);\n }\n if (!canReuseCompletedTextPrefix(normalizedParts, sentText)) {\n return normalizedParts;\n }\n return collectUnsentPartsFromNormalizedParts(normalizedParts, sentText);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction readOptionalString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction readOptionalNumber(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) && value >= 0\n ? value\n : undefined;\n}\n\nfunction projectAssetPutFiles(\n result: unknown,\n): Extract<NcpMessagePart, { type: \"file\" }>[] {\n if (!isRecord(result)) {\n return [];\n }\n\n const assetCandidates = isRecord(result.asset)\n ? [result.asset]\n : Array.isArray(result.assets)\n ? result.assets.filter(isRecord)\n : [];\n\n return assetCandidates.flatMap((asset) => {\n const assetUri = readOptionalString(asset.uri);\n const url = readOptionalString(asset.url);\n if (!assetUri && !url) {\n return [];\n }\n return [\n {\n type: \"file\" as const,\n ...(readOptionalString(asset.name)\n ? { name: readOptionalString(asset.name) }\n : {}),\n ...(readOptionalString(asset.mimeType)\n ? { mimeType: readOptionalString(asset.mimeType) }\n : {}),\n ...(assetUri ? { assetUri } : {}),\n ...(url ? { url } : {}),\n ...(readOptionalNumber(asset.sizeBytes) != null\n ? { sizeBytes: readOptionalNumber(asset.sizeBytes) }\n : {}),\n },\n ];\n });\n}\n\nfunction projectToolResultParts(params: {\n toolCallId?: string;\n toolName?: string;\n content: unknown;\n projectedToolCallIds: Set<string>;\n}): NcpMessagePart[] {\n if (\n params.toolName !== \"asset_put\" ||\n !params.toolCallId ||\n params.projectedToolCallIds.has(params.toolCallId)\n ) {\n return [];\n }\n const projectedFiles = projectAssetPutFiles(params.content);\n if (projectedFiles.length > 0) {\n params.projectedToolCallIds.add(params.toolCallId);\n }\n return projectedFiles;\n}\n\nfunction projectChannelOutputParts(\n parts: NcpMessagePart[],\n projectedToolCallIds: Set<string>,\n): NcpMessagePart[] {\n return parts.flatMap((part) => {\n if (\n part.type === \"tool-invocation\" &&\n part.toolName === \"asset_put\" &&\n part.result\n ) {\n if (\n part.toolCallId &&\n projectedToolCallIds.has(part.toolCallId)\n ) {\n return [];\n }\n const projectedFiles = projectAssetPutFiles(part.result);\n if (projectedFiles.length > 0) {\n if (part.toolCallId) {\n projectedToolCallIds.add(part.toolCallId);\n }\n return projectedFiles;\n }\n }\n return [part];\n });\n}\n\nclass NcpReplySession {\n private activeText = \"\";\n private fullText = \"\";\n private sentText = \"\";\n private typingStarted = false;\n private closed = false;\n private readonly toolNameByCallId = new Map<string, string>();\n private readonly projectedToolCallIds = new Set<string>();\n\n constructor(private readonly chat: Chat, private readonly target: ChatTarget) {}\n\n consume = async (eventStream: NcpEventStream): Promise<void> => {\n try {\n for await (const event of eventStream) {\n if (this.closed) {\n break;\n }\n await this.applyEvent(event);\n }\n } finally {\n await this.stopTyping();\n }\n };\n\n private applyEvent = async (event: NcpEndpointEvent): Promise<void> => {\n switch (event.type) {\n case NcpEventType.MessageTextStart:\n await this.handleTextStart();\n return;\n case NcpEventType.MessageTextDelta:\n await this.handleTextDelta(event.payload.delta);\n return;\n case NcpEventType.MessageTextEnd:\n await this.handleTextEnd();\n return;\n case NcpEventType.MessageToolCallStart:\n await this.handleToolCallStart(\n event.payload.toolCallId,\n event.payload.toolName,\n );\n return;\n case NcpEventType.MessageReasoningStart:\n await this.flushTextPart();\n return;\n case NcpEventType.MessageToolCallResult:\n await this.handleToolCallResult(\n event.payload.toolCallId,\n event.payload.content,\n );\n return;\n case NcpEventType.MessageCompleted:\n await this.handleCompleted(event.payload.message);\n return;\n case NcpEventType.MessageFailed:\n await this.handleReplyFailure(event.payload.error.message.trim());\n return;\n case NcpEventType.RunError:\n await this.handleReplyFailure(\n String(event.payload.error ?? \"NCP run failed.\").trim(),\n );\n return;\n default:\n return;\n }\n };\n\n private handleTextStart = async (): Promise<void> => {\n await this.ensureTypingStarted();\n if (this.activeText) {\n await this.flushTextPart();\n }\n this.activeText = \"\";\n };\n\n private handleTextDelta = async (delta: string): Promise<void> => {\n await this.ensureTypingStarted();\n this.activeText += delta;\n this.fullText += delta;\n };\n\n private handleTextEnd = async (): Promise<void> => this.flushTextPart();\n\n private handleToolCallStart = async (\n toolCallId: string,\n toolName: string,\n ): Promise<void> => {\n this.toolNameByCallId.set(toolCallId, toolName);\n await this.ensureTypingStarted();\n await this.flushTextPart();\n };\n\n private handleToolCallResult = async (\n toolCallId: string,\n content: unknown,\n ): Promise<void> => {\n await this.ensureTypingStarted();\n const projectedParts = projectToolResultParts({\n toolCallId,\n toolName: this.toolNameByCallId.get(toolCallId),\n content,\n projectedToolCallIds: this.projectedToolCallIds,\n });\n if (projectedParts.length === 0) {\n return;\n }\n await this.flushTextPart();\n for (const part of projectedParts) {\n await this.chat.sendPart(this.target, part);\n }\n };\n\n private handleCompleted = async (message: NcpMessage): Promise<void> => {\n await this.flushTextPart();\n const unsentParts = projectChannelOutputParts(\n resolveUnsentMessageParts(message, this.sentText, this.fullText),\n this.projectedToolCallIds,\n );\n for (const part of unsentParts) {\n await this.ensureTypingStarted();\n await this.chat.sendPart(this.target, part);\n if (isTextLikePart(part)) {\n this.sentText += part.text;\n }\n }\n await this.stopTyping();\n };\n\n private handleReplyFailure = async (message: string): Promise<void> => {\n if (message) {\n await this.ensureTypingStarted();\n await this.chat.sendError(this.target, message);\n }\n await this.stopTyping();\n };\n\n private flushTextPart = async (): Promise<void> => {\n if (!this.activeText.trim()) {\n this.activeText = \"\";\n return;\n }\n\n await this.ensureTypingStarted();\n await this.chat.sendPart(this.target, {\n type: \"text\",\n text: this.activeText,\n });\n this.sentText += this.activeText;\n this.activeText = \"\";\n };\n\n private ensureTypingStarted = async (): Promise<void> => {\n if (this.typingStarted) {\n return;\n }\n await this.chat.startTyping(this.target);\n this.typingStarted = true;\n };\n\n private stopTyping = async (): Promise<void> => {\n if (this.closed || !this.typingStarted) {\n return;\n }\n await this.chat.stopTyping(this.target);\n this.closed = true;\n };\n};\n\nexport class NcpReplyConsumer {\n constructor(private readonly chat: Chat) {}\n\n consume = async (input: NcpReplyInput): Promise<void> => {\n const session = new NcpReplySession(this.chat, input.target);\n await session.consume(input.eventStream);\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/agent/agent-conversation-message-normalizer.ts","../src/agent/agent-conversation-state-manager.utils.ts","../src/agent/agent-conversation-tool-call.manager.ts","../src/agent/agent-conversation-state.manager.ts","../src/agent/agent-client-from-server.ts","../src/agent/agent-backend/event-publisher.ts","../src/agent/agent-backend/in-memory-agent-session.store.ts","../src/errors/ncp-error-exception.ts","../src/chat/ncp-reply-consumer.ts"],"sourcesContent":["import { type NcpMessage, sanitizeAssistantReplyTags } from \"@nextclaw/ncp\";\n\nexport function cloneConversationMessage(message: NcpMessage): NcpMessage {\n return {\n ...message,\n parts: [...message.parts],\n lifecycle: message.lifecycle ? { ...message.lifecycle } : undefined,\n metadata: message.metadata ? { ...message.metadata } : undefined,\n };\n}\n\nexport function normalizeConversationMessage(message: NcpMessage): NcpMessage {\n return cloneConversationMessage(sanitizeAssistantReplyTags(message));\n}\n","import type {\n NcpError,\n NcpMessage,\n NcpMessageStatus,\n NcpRunErrorPayload,\n NcpRunFinishedPayload,\n} from \"@nextclaw/ncp\";\n\nexport const ABORTED_TOOL_CALL_SENTINEL = \"__nextclaw_aborted_tool_call__\";\n\nexport function buildRuntimeError(payload: NcpRunErrorPayload): NcpError {\n const message = payload.error?.trim();\n return {\n code: \"runtime-error\",\n message: message && message.length > 0 ? message : \"Agent run failed.\",\n details: {\n sessionId: payload.sessionId,\n messageId: payload.messageId,\n threadId: payload.threadId,\n runId: payload.runId,\n },\n };\n}\n\nexport function readMessageLifecycleFromRunPayload(\n payload: Pick<NcpRunFinishedPayload | NcpRunErrorPayload, \"startedAt\" | \"endedAt\">,\n): NcpMessage[\"lifecycle\"] | undefined {\n if (!payload.startedAt && !payload.endedAt) {\n return undefined;\n }\n return {\n startedAt: payload.startedAt,\n endedAt: payload.endedAt,\n };\n}\n\nexport function settleMessageWithLifecycle(\n message: NcpMessage,\n status: Extract<NcpMessageStatus, \"final\" | \"error\">,\n lifecycle?: NcpMessage[\"lifecycle\"],\n): NcpMessage {\n return lifecycle\n ? {\n ...message,\n status,\n lifecycle,\n }\n : {\n ...message,\n status,\n };\n}\n\nfunction resolveTimelineInsertIndex(\n messages: readonly NcpMessage[],\n message: NcpMessage,\n): number {\n const targetTimestamp = Date.parse(message.timestamp);\n if (!Number.isFinite(targetTimestamp)) {\n return messages.length;\n }\n const laterMessageIndex = messages.findIndex((item) => {\n const timestamp = Date.parse(item.timestamp);\n return Number.isFinite(timestamp) && timestamp > targetTimestamp;\n });\n return laterMessageIndex < 0 ? messages.length : laterMessageIndex;\n}\n\nexport function insertMessageByTimeline(\n messages: readonly NcpMessage[],\n message: NcpMessage,\n): NcpMessage[] {\n const nextMessages = [...messages];\n nextMessages.splice(resolveTimelineInsertIndex(messages, message), 0, message);\n return nextMessages;\n}\n\nexport function shouldPromoteStreamingMessageId(\n message: NcpMessage,\n nextMessageId: string,\n): boolean {\n if (!nextMessageId.trim()) {\n return false;\n }\n if (message.id.startsWith(\"tool-\")) {\n return true;\n }\n return message.parts.some((part) => part.type === \"tool-invocation\");\n}\n\nexport function remapTrackedToolCallsToMessageId(\n toolCallMessageIdByCallId: Map<string, string>,\n fromMessageId: string,\n toMessageId: string,\n): void {\n for (const [toolCallId, trackedMessageId] of toolCallMessageIdByCallId) {\n if (trackedMessageId !== fromMessageId) {\n continue;\n }\n toolCallMessageIdByCallId.set(toolCallId, toMessageId);\n }\n}\n\nexport function clearToolCallTrackingByMessageId(\n toolCallMessageIdByCallId: Map<string, string>,\n toolCallArgsRawByCallId: Map<string, string>,\n messageId: string,\n): void {\n for (const [toolCallId, trackedMessageId] of toolCallMessageIdByCallId) {\n if (trackedMessageId !== messageId) {\n continue;\n }\n toolCallMessageIdByCallId.delete(toolCallId);\n toolCallArgsRawByCallId.delete(toolCallId);\n }\n}\n\nexport function findToolInvocationPart(\n parts: NcpMessage[\"parts\"],\n toolCallId: string,\n): Extract<NcpMessage[\"parts\"][number], { type: \"tool-invocation\" }> | null {\n for (let index = parts.length - 1; index >= 0; index -= 1) {\n const part = parts[index];\n if (part.type === \"tool-invocation\" && part.toolCallId === toolCallId) {\n return part;\n }\n }\n return null;\n}\n\nexport function findToolNameByCallId(\n parts: NcpMessage[\"parts\"],\n toolCallId: string,\n): string | null {\n const part = findToolInvocationPart(parts, toolCallId);\n return part?.toolName ?? null;\n}\n\nexport function upsertToolInvocationPart(\n parts: NcpMessage[\"parts\"],\n toolPart: Extract<NcpMessage[\"parts\"][number], { type: \"tool-invocation\" }>,\n): NcpMessage[\"parts\"] {\n const nextParts = [...parts];\n for (let index = nextParts.length - 1; index >= 0; index -= 1) {\n const part = nextParts[index];\n if (part.type === \"tool-invocation\" && part.toolCallId === toolPart.toolCallId) {\n nextParts[index] = {\n ...part,\n ...toolPart,\n };\n return nextParts;\n }\n }\n nextParts.push(toolPart);\n return nextParts;\n}\n\nexport function cancelInFlightToolInvocations(parts: NcpMessage[\"parts\"]): {\n parts: NcpMessage[\"parts\"];\n toolCallIds: string[];\n} {\n const toolCallIds: string[] = [];\n return {\n parts: parts.map((part) => {\n if (\n part.type !== \"tool-invocation\" ||\n !part.toolCallId ||\n part.state === \"result\" ||\n part.state === \"cancelled\"\n ) {\n return part;\n }\n toolCallIds.push(part.toolCallId);\n return {\n ...part,\n state: \"cancelled\" as const,\n };\n }),\n toolCallIds,\n };\n}\n","import type {\n NcpMessage,\n NcpToolCallArgsDeltaPayload,\n NcpToolCallArgsPayload,\n NcpToolCallEndPayload,\n NcpToolCallResultPayload,\n NcpToolCallStartPayload,\n} from \"@nextclaw/ncp\";\nimport {\n ABORTED_TOOL_CALL_SENTINEL,\n clearToolCallTrackingByMessageId,\n findToolNameByCallId,\n remapTrackedToolCallsToMessageId,\n upsertToolInvocationPart,\n} from \"./agent-conversation-state-manager.utils.js\";\n\ntype ToolCallPart = Extract<NcpMessage[\"parts\"][number], { type: \"tool-invocation\" }>;\n\ntype AgentConversationToolCallManagerPort = {\n ensureStreamingMessage: (\n sessionId: string,\n messageId: string,\n status: \"streaming\",\n ) => NcpMessage;\n replaceStreamingMessage: (message: NcpMessage) => void;\n updateMessageContainingToolCall: (\n toolCallId: string,\n updater: (\n targetMessage: NcpMessage,\n existingPart: ToolCallPart,\n ) => NcpMessage[\"parts\"],\n ) => boolean;\n readStreamingMessageId: () => string | null;\n};\n\nexport class AgentConversationToolCallManager {\n private readonly messageIdByCallId = new Map<string, string>();\n private readonly argsRawByCallId = new Map<string, string>();\n\n constructor(private readonly port: AgentConversationToolCallManagerPort) {}\n\n isEmpty = (): boolean =>\n this.messageIdByCallId.size === 0 && this.argsRawByCallId.size === 0;\n\n clear = (): void => {\n this.messageIdByCallId.clear();\n this.argsRawByCallId.clear();\n };\n\n clearByMessageId = (messageId: string): void => {\n clearToolCallTrackingByMessageId(\n this.messageIdByCallId,\n this.argsRawByCallId,\n messageId,\n );\n };\n\n markAborted = (toolCallIds: readonly string[]): void => {\n toolCallIds.forEach((toolCallId) => this.argsRawByCallId.set(toolCallId, ABORTED_TOOL_CALL_SENTINEL));\n };\n\n remapMessageId = (fromMessageId: string, toMessageId: string): void => {\n remapTrackedToolCallsToMessageId(\n this.messageIdByCallId,\n fromMessageId,\n toMessageId,\n );\n };\n\n handleToolCallStart = (payload: NcpToolCallStartPayload): void => {\n if (this.argsRawByCallId.get(payload.toolCallId) === ABORTED_TOOL_CALL_SENTINEL) return;\n const targetMessage = this.resolveToolCallTargetMessage(payload.sessionId, payload.toolCallId, payload.messageId);\n this.argsRawByCallId.set(payload.toolCallId, \"\");\n this.port.replaceStreamingMessage({\n ...targetMessage,\n parts: upsertToolInvocationPart(targetMessage.parts, {\n type: \"tool-invocation\",\n toolCallId: payload.toolCallId,\n toolName: payload.toolName,\n state: \"partial-call\",\n args: \"\",\n }),\n status: \"streaming\",\n });\n };\n\n handleToolCallArgs = (payload: NcpToolCallArgsPayload): void => {\n if (this.argsRawByCallId.get(payload.toolCallId) === ABORTED_TOOL_CALL_SENTINEL) return;\n this.argsRawByCallId.set(payload.toolCallId, payload.args);\n this.applyToolCallArgs(payload.sessionId, payload.toolCallId, payload.args);\n };\n\n handleToolCallArgsDelta = (payload: NcpToolCallArgsDeltaPayload): void => {\n if (this.argsRawByCallId.get(payload.toolCallId) === ABORTED_TOOL_CALL_SENTINEL) return;\n const currentArgs = this.argsRawByCallId.get(payload.toolCallId) ?? \"\";\n const nextArgs = `${currentArgs}${payload.delta}`;\n this.argsRawByCallId.set(payload.toolCallId, nextArgs);\n this.applyToolCallArgs(payload.sessionId, payload.toolCallId, nextArgs, payload.messageId);\n };\n\n handleToolCallEnd = (payload: NcpToolCallEndPayload): void => {\n if (this.argsRawByCallId.get(payload.toolCallId) === ABORTED_TOOL_CALL_SENTINEL) return;\n const targetMessage = this.resolveToolCallTargetMessage(payload.sessionId, payload.toolCallId);\n const args = this.argsRawByCallId.get(payload.toolCallId) ?? \"\";\n this.port.replaceStreamingMessage({\n ...targetMessage,\n parts: upsertToolInvocationPart(targetMessage.parts, {\n type: \"tool-invocation\",\n toolCallId: payload.toolCallId,\n toolName: findToolNameByCallId(targetMessage.parts, payload.toolCallId) ?? \"unknown\",\n state: \"call\",\n args,\n }),\n status: \"streaming\",\n });\n };\n\n handleToolCallResult = (payload: NcpToolCallResultPayload): void => {\n if (this.argsRawByCallId.get(payload.toolCallId) === ABORTED_TOOL_CALL_SENTINEL) return;\n const updated = this.port.updateMessageContainingToolCall(\n payload.toolCallId,\n (targetMessage, existingPart) =>\n upsertToolInvocationPart(targetMessage.parts, {\n type: \"tool-invocation\",\n toolCallId: payload.toolCallId,\n toolName: existingPart.toolName,\n state: \"result\",\n args: existingPart.args,\n result: payload.content,\n resultContentItems: payload.contentItems,\n }),\n );\n if (updated) {\n return;\n }\n const fallbackMessage = this.resolveToolCallTargetMessage(\n payload.sessionId,\n payload.toolCallId,\n );\n this.port.replaceStreamingMessage({\n ...fallbackMessage,\n parts: upsertToolInvocationPart(fallbackMessage.parts, {\n type: \"tool-invocation\",\n toolCallId: payload.toolCallId,\n toolName: \"unknown\",\n state: \"result\",\n result: payload.content,\n resultContentItems: payload.contentItems,\n }),\n status: \"streaming\",\n });\n };\n\n private applyToolCallArgs = (\n sessionId: string,\n toolCallId: string,\n args: string,\n messageId?: string,\n ): void => {\n const targetMessage = this.resolveToolCallTargetMessage(\n sessionId,\n toolCallId,\n messageId,\n );\n const toolName =\n findToolNameByCallId(targetMessage.parts, toolCallId) ?? \"unknown\";\n this.port.replaceStreamingMessage({\n ...targetMessage,\n parts: upsertToolInvocationPart(targetMessage.parts, {\n type: \"tool-invocation\",\n toolCallId,\n toolName,\n state: \"partial-call\",\n args,\n }),\n status: \"streaming\",\n });\n };\n\n private resolveToolCallTargetMessage = (\n sessionId: string,\n toolCallId: string,\n messageId?: string,\n ): NcpMessage => {\n const preferredMessageId =\n messageId?.trim() ||\n this.messageIdByCallId.get(toolCallId) ||\n this.port.readStreamingMessageId() ||\n `tool-${toolCallId}`;\n this.messageIdByCallId.set(toolCallId, preferredMessageId);\n return this.port.ensureStreamingMessage(sessionId, preferredMessageId, \"streaming\");\n };\n}\n","import {\n type NcpAgentConversationSnapshot,\n type NcpAgentConversationStateManager,\n type NcpAgentConversationHydrationParams,\n type NcpContextWindowUpdatedPayload,\n type NcpEndpointEvent,\n type NcpError,\n type NcpMessage,\n type NcpMessageAbortPayload,\n type NcpMessageRole,\n type NcpMessageSentPayload,\n type NcpMessageStatus,\n type NcpRunContext,\n type NcpRunErrorPayload,\n type NcpRunFinishedPayload,\n type NcpRunMetadataPayload,\n type NcpRunReadyMetadata,\n type NcpRunStartedPayload,\n type NcpReasoningDeltaPayload,\n type NcpReasoningEndPayload,\n type NcpReasoningStartPayload,\n type NcpTextDeltaPayload,\n type NcpTextEndPayload,\n type NcpTextStartPayload,\n type NcpToolCallArgsDeltaPayload,\n type NcpToolCallArgsPayload,\n type NcpToolCallEndPayload,\n type NcpToolCallResultPayload,\n type NcpToolCallStartPayload,\n NcpEventType,\n} from \"@nextclaw/ncp\";\nimport { cloneConversationMessage, normalizeConversationMessage } from \"./agent-conversation-message-normalizer.js\";\nimport { AgentConversationToolCallManager } from \"./agent-conversation-tool-call.manager.js\";\nimport { buildRuntimeError, cancelInFlightToolInvocations, findToolInvocationPart, insertMessageByTimeline, readMessageLifecycleFromRunPayload, settleMessageWithLifecycle, shouldPromoteStreamingMessageId } from \"./agent-conversation-state-manager.utils.js\";\n\nconst DEFAULT_ASSISTANT_ROLE: NcpMessageRole = \"assistant\";\n\nexport class DefaultNcpAgentConversationStateManager implements NcpAgentConversationStateManager {\n private messages: NcpMessage[] = [];\n private streamingMessage: NcpMessage | null = null;\n private error: NcpError | null = null;\n private activeRun: NcpRunContext | null = null;\n private contextWindow: Record<string, unknown> | null = null;\n private readonly listeners = new Set<(snapshot: NcpAgentConversationSnapshot) => void>();\n private readonly toolCalls: AgentConversationToolCallManager;\n private lastSettledRunId: string | null = null;\n private snapshotCache: NcpAgentConversationSnapshot | null = null;\n private snapshotVersion = -1;\n private stateVersion = 0;\n\n constructor() {\n this.toolCalls = new AgentConversationToolCallManager({\n ensureStreamingMessage: this.ensureStreamingMessage,\n readStreamingMessageId: () => this.streamingMessage?.id ?? null,\n replaceStreamingMessage: this.replaceStreamingMessage,\n updateMessageContainingToolCall: this.updateMessageContainingToolCall,\n });\n }\n\n getSnapshot = (): NcpAgentConversationSnapshot => {\n if (this.snapshotCache && this.snapshotVersion === this.stateVersion) {\n return this.snapshotCache;\n }\n const snapshot: NcpAgentConversationSnapshot = {\n messages: this.messages,\n streamingMessage: this.streamingMessage,\n error: this.error\n ? {\n ...this.error,\n details: this.error.details ? { ...this.error.details } : undefined,\n }\n : null,\n activeRun: this.activeRun ? { ...this.activeRun } : null,\n contextWindow: this.contextWindow ? { ...this.contextWindow } : null,\n };\n this.snapshotCache = snapshot;\n this.snapshotVersion = this.stateVersion;\n return snapshot;\n };\n\n subscribe = (listener: (snapshot: NcpAgentConversationSnapshot) => void) => {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n };\n\n reset = (): void => {\n if (\n this.messages.length === 0 &&\n !this.streamingMessage &&\n !this.error &&\n !this.activeRun &&\n !this.contextWindow &&\n this.toolCalls.isEmpty()\n ) {\n return;\n }\n this.messages = [];\n this.streamingMessage = null;\n this.error = null;\n this.activeRun = null;\n this.contextWindow = null;\n this.toolCalls.clear();\n this.lastSettledRunId = null;\n this.stateVersion += 1;\n this.notifyListeners();\n };\n\n hydrate = (payload: NcpAgentConversationHydrationParams): void => {\n this.messages = payload.messages.map((message: NcpMessage) => normalizeConversationMessage(message));\n this.streamingMessage = null;\n this.error = null;\n this.contextWindow = payload.contextWindow ? { ...payload.contextWindow } : null;\n this.activeRun = payload.activeRun\n ? {\n ...payload.activeRun,\n sessionId: payload.activeRun.sessionId ?? payload.sessionId,\n abortDisabledReason: payload.activeRun.abortDisabledReason ?? null,\n }\n : null;\n this.toolCalls.clear();\n this.lastSettledRunId = null;\n this.stateVersion += 1;\n this.notifyListeners();\n };\n\n dispatch = (event: NcpEndpointEvent): Promise<void> => this.dispatchBatch([event]);\n\n dispatchBatch = async (events: readonly NcpEndpointEvent[]): Promise<void> => {\n if (!events.length) return;\n const versionBeforeDispatch = this.stateVersion;\n events.forEach(this.applyEvent);\n if (this.stateVersion !== versionBeforeDispatch) this.notifyListeners();\n };\n\n private applyEvent = (event: NcpEndpointEvent): void => {\n switch (event.type) {\n case NcpEventType.MessageSent:\n this.handleMessageSent(event.payload);\n break;\n case NcpEventType.MessageAbort:\n this.handleMessageAbort(event.payload);\n break;\n case NcpEventType.MessageTextStart:\n this.handleMessageTextStart(event.payload);\n break;\n case NcpEventType.MessageTextDelta:\n this.handleMessageTextDelta(event.payload);\n break;\n case NcpEventType.MessageTextEnd:\n this.handleMessageTextEnd(event.payload);\n break;\n case NcpEventType.MessageReasoningStart:\n this.handleMessageReasoningStart(event.payload);\n break;\n case NcpEventType.MessageReasoningDelta:\n this.handleMessageReasoningDelta(event.payload);\n break;\n case NcpEventType.MessageReasoningEnd:\n this.handleMessageReasoningEnd(event.payload);\n break;\n case NcpEventType.MessageToolCallStart:\n this.handleMessageToolCallStart(event.payload);\n break;\n case NcpEventType.MessageToolCallArgs:\n this.handleMessageToolCallArgs(event.payload);\n break;\n case NcpEventType.MessageToolCallArgsDelta:\n this.handleMessageToolCallArgsDelta(event.payload);\n break;\n case NcpEventType.MessageToolCallEnd:\n this.handleMessageToolCallEnd(event.payload);\n break;\n case NcpEventType.MessageToolCallResult:\n this.handleMessageToolCallResult(event.payload);\n break;\n case NcpEventType.RunStarted:\n this.handleRunStarted(event.payload);\n break;\n case NcpEventType.RunFinished:\n this.handleRunFinished(event.payload);\n break;\n case NcpEventType.RunError:\n this.handleRunError(event.payload);\n break;\n case NcpEventType.RunMetadata:\n this.handleRunMetadata(event.payload);\n break;\n case NcpEventType.ContextWindowUpdated:\n this.handleContextWindowUpdated(event.payload);\n break;\n case NcpEventType.EndpointError:\n this.handleEndpointError(event.payload);\n break;\n default:\n break;\n }\n };\n\n handleMessageSent = (payload: NcpMessageSentPayload): void => {\n this.upsertMessage(payload.message);\n this.setError(null);\n };\n\n handleMessageAbort = (payload: NcpMessageAbortPayload): void => {\n const targetMessageId = payload.messageId?.trim();\n this.clearActiveRun();\n this.setError(null);\n\n if (\n this.streamingMessage &&\n (!targetMessageId || this.streamingMessage.id === targetMessageId)\n ) {\n const streamingMessageId = this.streamingMessage.id;\n const { parts: nextParts, toolCallIds } = cancelInFlightToolInvocations(this.streamingMessage.parts);\n this.upsertMessage({\n ...this.streamingMessage,\n status: \"final\",\n parts: nextParts,\n });\n this.replaceStreamingMessage(null);\n if (targetMessageId) {\n this.toolCalls.clearByMessageId(targetMessageId);\n } else {\n this.toolCalls.clearByMessageId(streamingMessageId);\n }\n this.toolCalls.markAborted(toolCallIds);\n }\n };\n\n handleMessageTextStart = (payload: NcpTextStartPayload): void => {\n const wasActiveStreamingMessage = this.streamingMessage?.id === payload.messageId;\n const targetMessage = this.ensureStreamingMessage(payload.sessionId, payload.messageId, \"streaming\");\n const lastPart = targetMessage.parts[targetMessage.parts.length - 1];\n if (wasActiveStreamingMessage && lastPart?.type === \"text\" && lastPart.text.length > 0) {\n this.replaceStreamingMessage({\n ...targetMessage,\n parts: [...targetMessage.parts, { type: \"text\", text: \"\" }],\n status: \"streaming\",\n });\n }\n this.setError(null);\n };\n\n handleMessageTextDelta = (payload: NcpTextDeltaPayload): void => {\n if (!payload.delta) {\n return;\n }\n\n const targetMessage = this.ensureStreamingMessage(payload.sessionId, payload.messageId, \"streaming\");\n const nextParts = [...targetMessage.parts];\n const lastPart = nextParts[nextParts.length - 1];\n if (lastPart?.type === \"text\") {\n nextParts[nextParts.length - 1] = {\n type: \"text\",\n text: `${lastPart.text}${payload.delta}`,\n };\n } else {\n nextParts.push({ type: \"text\", text: payload.delta });\n }\n\n this.replaceStreamingMessage({ ...targetMessage, parts: nextParts, status: \"streaming\" });\n };\n\n handleMessageTextEnd = (payload: NcpTextEndPayload): void => {\n if (this.streamingMessage?.id !== payload.messageId) {\n return;\n }\n if (this.streamingMessage.status !== \"streaming\") {\n return;\n }\n this.replaceStreamingMessage({ ...this.streamingMessage, status: \"pending\" });\n };\n\n handleMessageReasoningStart = (payload: NcpReasoningStartPayload): void => {\n this.ensureStreamingMessage(payload.sessionId, payload.messageId, \"streaming\");\n };\n\n handleMessageReasoningDelta = (payload: NcpReasoningDeltaPayload): void => {\n if (!payload.delta) {\n return;\n }\n\n const targetMessage = this.ensureStreamingMessage(payload.sessionId, payload.messageId, \"streaming\");\n const nextParts = [...targetMessage.parts];\n const lastPart = nextParts[nextParts.length - 1];\n\n if (lastPart?.type === \"reasoning\") {\n nextParts[nextParts.length - 1] = {\n type: \"reasoning\",\n text: `${lastPart.text}${payload.delta}`,\n };\n } else {\n nextParts.push({ type: \"reasoning\", text: payload.delta });\n }\n\n this.replaceStreamingMessage({ ...targetMessage, parts: nextParts, status: \"streaming\" });\n };\n\n handleMessageReasoningEnd = (payload: NcpReasoningEndPayload): void => {\n if (this.streamingMessage?.id !== payload.messageId) {\n return;\n }\n // End is an event boundary; no snapshot mutation required.\n };\n\n handleMessageToolCallStart = (payload: NcpToolCallStartPayload): void => {\n this.toolCalls.handleToolCallStart(payload);\n this.setError(null);\n };\n\n handleMessageToolCallArgs = (payload: NcpToolCallArgsPayload): void => {\n this.toolCalls.handleToolCallArgs(payload);\n };\n\n handleMessageToolCallArgsDelta = (payload: NcpToolCallArgsDeltaPayload): void => {\n this.toolCalls.handleToolCallArgsDelta(payload);\n };\n\n handleMessageToolCallEnd = (payload: NcpToolCallEndPayload): void => {\n this.toolCalls.handleToolCallEnd(payload);\n };\n\n handleMessageToolCallResult = (payload: NcpToolCallResultPayload): void => {\n this.toolCalls.handleToolCallResult(payload);\n };\n\n handleRunStarted = (payload: NcpRunStartedPayload): void => {\n if (this.isSettledRunId(payload.runId)) return;\n this.setError(null);\n this.activeRun = { runId: payload.runId ?? null, sessionId: payload.sessionId };\n this.stateVersion += 1;\n };\n\n handleRunFinished = (payload: NcpRunFinishedPayload): void => {\n this.markRunAsSettled(payload.runId ?? this.activeRun?.runId ?? null);\n this.settleStreamingMessage(\"final\", readMessageLifecycleFromRunPayload(payload));\n this.setError(null);\n this.clearActiveRun();\n };\n\n handleRunError = (payload: NcpRunErrorPayload): void => {\n this.markRunAsSettled(payload.runId ?? this.activeRun?.runId ?? null);\n this.settleStreamingMessage(\"error\", readMessageLifecycleFromRunPayload(payload));\n this.setError(buildRuntimeError(payload));\n this.clearActiveRun();\n };\n\n handleRunMetadata = (payload: NcpRunMetadataPayload): void => {\n const m = payload.metadata as Record<string, unknown>;\n if (m?.kind === \"ready\") {\n const ready = m as NcpRunReadyMetadata;\n if (this.isSettledRunId(ready.runId)) return;\n this.activeRun = {\n runId: ready.runId ?? this.activeRun?.runId ?? null,\n sessionId: ready.sessionId ?? this.activeRun?.sessionId,\n abortDisabledReason: ready.supportsAbort === false ? (ready.abortDisabledReason ?? \"Unsupported\") : null,\n };\n this.stateVersion += 1;\n } else if (m?.kind === \"final\") {\n this.markRunAsSettled(payload.runId ?? this.activeRun?.runId ?? null);\n this.clearActiveRun();\n }\n };\n\n handleContextWindowUpdated = (payload: NcpContextWindowUpdatedPayload): void => {\n this.contextWindow = { ...payload.contextWindow };\n this.stateVersion += 1;\n };\n\n handleEndpointError = (payload: NcpError): void => {\n if (payload.code === \"abort-error\") {\n this.handleMessageAbort({\n sessionId: this.activeRun?.sessionId ?? this.streamingMessage?.sessionId ?? \"\",\n ...(this.streamingMessage?.id ? { messageId: this.streamingMessage.id } : {}),\n });\n return;\n }\n this.settleStreamingMessage(\"error\");\n this.clearActiveRun();\n this.setError(payload);\n };\n\n private ensureStreamingMessage = (\n sessionId: string,\n messageId: string,\n status: NcpMessageStatus,\n ): NcpMessage => {\n if (this.streamingMessage?.id === messageId) {\n if (this.streamingMessage.status === status) {\n return this.streamingMessage;\n }\n const nextStreamingMessage = {\n ...this.streamingMessage,\n status,\n };\n this.replaceStreamingMessage(nextStreamingMessage);\n return nextStreamingMessage;\n }\n\n const messageIndex = this.messages.findIndex(\n (message) => message.id === messageId,\n );\n if (messageIndex >= 0) {\n const existingMessage = cloneConversationMessage(\n this.messages[messageIndex]!,\n );\n const nextMessages = [...this.messages];\n nextMessages.splice(messageIndex, 1);\n this.messages = nextMessages;\n this.stateVersion += 1;\n const nextStreamingMessage = {\n ...existingMessage,\n sessionId,\n status,\n };\n this.replaceStreamingMessage(nextStreamingMessage);\n return nextStreamingMessage;\n }\n\n const existingStreamingMessage = this.streamingMessage;\n if (\n existingStreamingMessage &&\n existingStreamingMessage.id !== messageId &&\n existingStreamingMessage.sessionId === sessionId &&\n shouldPromoteStreamingMessageId(existingStreamingMessage, messageId)\n ) {\n const nextStreamingMessage: NcpMessage = {\n ...existingStreamingMessage,\n id: messageId,\n sessionId,\n status,\n };\n this.toolCalls.remapMessageId(existingStreamingMessage.id, messageId);\n this.replaceStreamingMessage(nextStreamingMessage);\n return nextStreamingMessage;\n }\n\n const nextStreamingMessage: NcpMessage = {\n id: messageId,\n sessionId,\n role: DEFAULT_ASSISTANT_ROLE,\n status,\n parts: [],\n timestamp: new Date().toISOString(),\n };\n this.replaceStreamingMessage(nextStreamingMessage);\n return nextStreamingMessage;\n };\n\n private updateMessageContainingToolCall = (\n toolCallId: string,\n updater: (\n targetMessage: NcpMessage,\n existingPart: Extract<\n NcpMessage[\"parts\"][number],\n { type: \"tool-invocation\" }\n >,\n ) => NcpMessage[\"parts\"],\n ): boolean => {\n if (this.streamingMessage) {\n const part = findToolInvocationPart(\n this.streamingMessage.parts,\n toolCallId,\n );\n if (part) {\n const nextParts = updater(this.streamingMessage, part);\n this.replaceStreamingMessage({ ...this.streamingMessage, parts: nextParts });\n return true;\n }\n }\n\n for (let index = this.messages.length - 1; index >= 0; index -= 1) {\n const candidateMessage = this.messages[index];\n const part = findToolInvocationPart(candidateMessage.parts, toolCallId);\n if (!part) {\n continue;\n }\n const nextMessages = [...this.messages];\n nextMessages[index] = {\n ...candidateMessage,\n parts: updater(candidateMessage, part),\n };\n this.messages = nextMessages;\n this.stateVersion += 1;\n return true;\n }\n\n return false;\n };\n\n private upsertMessage = (message: NcpMessage): void => {\n const normalizedMessage = normalizeConversationMessage(message);\n if (this.streamingMessage?.id === normalizedMessage.id) this.streamingMessage = null;\n const messageIndex = this.messages.findIndex((item) => item.id === normalizedMessage.id);\n if (messageIndex < 0) {\n this.messages = insertMessageByTimeline(this.messages, normalizedMessage);\n this.stateVersion += 1;\n return;\n }\n\n const nextMessages = [...this.messages];\n nextMessages[messageIndex] = normalizedMessage;\n this.messages = nextMessages;\n this.stateVersion += 1;\n };\n\n private replaceStreamingMessage = (nextStreamingMessage: NcpMessage | null): void => {\n if (!nextStreamingMessage && !this.streamingMessage) {\n return;\n }\n this.streamingMessage = nextStreamingMessage ? normalizeConversationMessage(nextStreamingMessage) : null;\n this.stateVersion += 1;\n };\n\n private setError = (nextError: NcpError | null): void => {\n const hasSameError =\n this.error?.code === nextError?.code &&\n this.error?.message === nextError?.message &&\n this.error?.details === nextError?.details &&\n this.error?.cause === nextError?.cause;\n if (hasSameError) {\n return;\n }\n\n this.error = nextError\n ? {\n ...nextError,\n details: nextError.details ? { ...nextError.details } : undefined,\n }\n : null;\n this.stateVersion += 1;\n };\n\n private clearActiveRun = (): void => {\n if (!this.activeRun) return;\n this.activeRun = null;\n this.stateVersion += 1;\n };\n\n private isSettledRunId = (runId: string | null | undefined): boolean => {\n return Boolean(runId?.trim()) && runId === this.lastSettledRunId;\n };\n\n private markRunAsSettled = (runId: string | null | undefined): void => {\n this.lastSettledRunId = runId?.trim() || null;\n };\n\n private settleStreamingMessage = (\n status: Extract<NcpMessageStatus, \"final\" | \"error\">,\n lifecycle?: NcpMessage[\"lifecycle\"],\n ): void => {\n if (!this.streamingMessage) return;\n const settledMessage = settleMessageWithLifecycle(this.streamingMessage, status, lifecycle);\n this.upsertMessage(settledMessage);\n this.replaceStreamingMessage(null);\n this.toolCalls.clearByMessageId(settledMessage.id);\n };\n\n private notifyListeners = (): void => {\n const snapshot: NcpAgentConversationSnapshot = this.getSnapshot();\n for (const listener of this.listeners) listener(snapshot);\n };\n}\n","import {\n type NcpAgentClientEndpoint,\n type NcpAgentSendEnvelope,\n type NcpAgentServerEndpoint,\n type NcpEndpointEvent,\n type NcpEndpointSubscriber,\n type NcpMessageAbortPayload,\n type NcpRequestEnvelope,\n type NcpRunHandle,\n type NcpStreamRequestPayload,\n consumeNcpRunHandle,\n createNcpRunHandle,\n NcpEventType,\n} from \"@nextclaw/ncp\";\n\nfunction assertMaterializedEnvelope(\n envelope: NcpAgentSendEnvelope,\n): asserts envelope is NcpRequestEnvelope {\n if (!envelope.sessionId?.trim() || !envelope.message.sessionId?.trim()) {\n throw new Error(\"NCP request envelope must be materialized before server dispatch.\");\n }\n}\n\n/**\n * Creates an NcpAgentClientEndpoint that forwards to an in-process NcpAgentServerEndpoint.\n * Use when the agent runs in-process and you need to pass a client endpoint to the HTTP server.\n */\nexport function createAgentClientFromServer(\n server: NcpAgentServerEndpoint,\n): NcpAgentClientEndpoint {\n return {\n get manifest() {\n return server.manifest;\n },\n async start(): Promise<void> {\n await server.start();\n },\n async stop(): Promise<void> {\n await server.stop();\n },\n async emit(event: NcpEndpointEvent): Promise<void> {\n switch (event.type) {\n case NcpEventType.MessageRequest:\n assertMaterializedEnvelope(event.payload);\n await consumeNcpRunHandle(server.send(event.payload), createNcpRunHandle(event.payload));\n return;\n case NcpEventType.MessageStreamRequest:\n await consume(server.stream(event.payload));\n return;\n case NcpEventType.MessageAbort:\n await server.abort(event.payload);\n return;\n default:\n await server.emit(event);\n }\n },\n subscribe(listener: NcpEndpointSubscriber) {\n return server.subscribe(listener);\n },\n async send(envelope: NcpAgentSendEnvelope): Promise<NcpRunHandle> {\n assertMaterializedEnvelope(envelope);\n return await consumeNcpRunHandle(server.send(envelope), createNcpRunHandle(envelope));\n },\n async stream(payload: NcpStreamRequestPayload): Promise<void> {\n await consume(server.stream(payload));\n },\n async abort(payload: NcpMessageAbortPayload): Promise<void> {\n await server.abort(payload);\n },\n };\n}\n\nasync function consume(events: AsyncIterable<unknown>): Promise<void> {\n for await (const event of events) {\n // Consume iterator to execute server-side async generator side effects.\n void event;\n }\n}\n","import type { NcpEndpointEvent, NcpEndpointSubscriber } from \"@nextclaw/ncp\";\n\nexport class EventPublisher {\n private readonly listeners = new Set<NcpEndpointSubscriber>();\n private readonly closeListeners = new Set<() => void>();\n private closed = false;\n\n subscribe(listener: NcpEndpointSubscriber): () => void {\n if (this.closed) {\n return () => undefined;\n }\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n onClose(listener: () => void): () => void {\n if (this.closed) {\n listener();\n return () => undefined;\n }\n this.closeListeners.add(listener);\n return () => {\n this.closeListeners.delete(listener);\n };\n }\n\n publish(event: NcpEndpointEvent): void {\n if (this.closed) {\n return;\n }\n for (const listener of this.listeners) {\n listener(structuredClone(event));\n }\n }\n\n close(): void {\n if (this.closed) {\n return;\n }\n this.closed = true;\n this.listeners.clear();\n for (const listener of this.closeListeners) {\n listener();\n }\n this.closeListeners.clear();\n }\n}\n","import type { AgentSessionRecord, AgentSessionStore } from \"./agent-backend.types.js\";\n\nexport class InMemoryAgentSessionStore implements AgentSessionStore {\n private readonly sessions = new Map<string, AgentSessionRecord>();\n\n getSession = async (sessionId: string): Promise<AgentSessionRecord | null> => {\n const session = this.sessions.get(sessionId);\n return session ? structuredClone(session) : null;\n };\n\n listSessions = async (): Promise<AgentSessionRecord[]> => {\n return [...this.sessions.values()].map((session) => structuredClone(session));\n };\n\n saveSession = async (session: AgentSessionRecord): Promise<void> => {\n this.sessions.set(session.sessionId, structuredClone(session));\n };\n\n setSessionMetadata = async (params: {\n sessionId: string;\n metadata: Record<string, unknown>;\n updatedAt: string;\n }): Promise<boolean> => {\n const { metadata, sessionId, updatedAt } = params;\n const session = this.sessions.get(sessionId);\n if (!session) {\n return false;\n }\n this.sessions.set(sessionId, {\n ...session,\n metadata: structuredClone(metadata),\n updatedAt,\n });\n return true;\n };\n\n updateSessionMetadata = async (params: {\n sessionId: string;\n metadata: Record<string, unknown>;\n updatedAt: string;\n }): Promise<boolean> => {\n const session = this.sessions.get(params.sessionId);\n if (!session) {\n return false;\n }\n return await this.setSessionMetadata({\n ...params,\n metadata: {\n ...(session.metadata ? structuredClone(session.metadata) : {}),\n ...structuredClone(params.metadata),\n },\n });\n };\n\n deleteSession = async (sessionId: string): Promise<AgentSessionRecord | null> => {\n const session = this.sessions.get(sessionId);\n if (!session) {\n return null;\n }\n\n this.sessions.delete(sessionId);\n return structuredClone(session);\n };\n}\n","import type { NcpErrorCode } from \"@nextclaw/ncp\";\n\n/**\n * Throwable form of protocol error for exception-based control flows.\n */\nexport class NcpErrorException extends Error {\n readonly code: NcpErrorCode;\n readonly details?: Record<string, unknown>;\n\n constructor(\n code: NcpErrorCode,\n message: string,\n details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = \"NcpErrorException\";\n this.code = code;\n this.details = details;\n }\n}\n","import {\n NcpEventType,\n sanitizeAssistantReplyTags,\n type NcpEndpointEvent,\n type NcpMessage,\n type NcpMessagePart,\n type NcpRichTextPart,\n type NcpTextPart,\n} from \"@nextclaw/ncp\";\nimport type { Chat, ChatTarget, NcpEventStream, NcpReplyInput } from \"./chat.types.js\";\n\nfunction isTextLikePart(\n part: NcpMessagePart,\n): part is Extract<NcpMessagePart, { type: \"text\" | \"rich-text\" }> {\n return part.type === \"text\" || part.type === \"rich-text\";\n}\n\nfunction normalizeMessageParts(message: NcpMessage): NcpMessagePart[] {\n const normalizedMessage =\n message.role === \"assistant\" ? sanitizeAssistantReplyTags(message) : message;\n return normalizedMessage.parts;\n}\n\nfunction cloneTextLikePartTail(\n part: Extract<NcpMessagePart, { type: \"text\" | \"rich-text\" }>,\n skipChars: number,\n): NcpTextPart | NcpRichTextPart | null {\n const nextText = part.text.slice(skipChars);\n if (!nextText) {\n return null;\n }\n if (part.type === \"text\") {\n return {\n type: \"text\",\n text: nextText,\n };\n }\n return {\n ...part,\n text: nextText,\n };\n}\n\nfunction resolveFallbackUnsentParts(\n fallbackText: string,\n sentText: string,\n): NcpMessagePart[] {\n if (!fallbackText || fallbackText === sentText) {\n return [];\n }\n const nextText =\n sentText && fallbackText.startsWith(sentText)\n ? fallbackText.slice(sentText.length)\n : fallbackText;\n return nextText ? [{ type: \"text\", text: nextText }] : [];\n}\n\nfunction canReuseCompletedTextPrefix(\n normalizedParts: NcpMessagePart[],\n sentText: string,\n): boolean {\n const finalText = normalizedParts\n .filter(isTextLikePart)\n .map((part) => part.text)\n .join(\"\");\n return !(sentText && finalText && !finalText.startsWith(sentText));\n}\n\nfunction collectUnsentPartsFromNormalizedParts(\n normalizedParts: NcpMessagePart[],\n sentText: string,\n): NcpMessagePart[] {\n let remainingSentChars = sentText.length;\n const unsentParts: NcpMessagePart[] = [];\n\n for (const part of normalizedParts) {\n if (!isTextLikePart(part)) {\n unsentParts.push(part);\n continue;\n }\n if (remainingSentChars >= part.text.length) {\n remainingSentChars -= part.text.length;\n continue;\n }\n if (remainingSentChars > 0) {\n const tail = cloneTextLikePartTail(part, remainingSentChars);\n remainingSentChars = 0;\n if (tail) {\n unsentParts.push(tail);\n }\n continue;\n }\n unsentParts.push(part);\n }\n\n return unsentParts;\n}\n\nfunction resolveUnsentMessageParts(\n message: NcpMessage,\n sentText: string,\n fallbackText: string,\n): NcpMessagePart[] {\n const normalizedParts = normalizeMessageParts(message);\n if (normalizedParts.length === 0) {\n return resolveFallbackUnsentParts(fallbackText, sentText);\n }\n if (!canReuseCompletedTextPrefix(normalizedParts, sentText)) {\n return normalizedParts;\n }\n return collectUnsentPartsFromNormalizedParts(normalizedParts, sentText);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction readOptionalString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction readOptionalNumber(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) && value >= 0\n ? value\n : undefined;\n}\n\nfunction projectAssetPutFiles(\n result: unknown,\n): Extract<NcpMessagePart, { type: \"file\" }>[] {\n if (!isRecord(result)) {\n return [];\n }\n\n const assetCandidates = isRecord(result.asset)\n ? [result.asset]\n : Array.isArray(result.assets)\n ? result.assets.filter(isRecord)\n : [];\n\n return assetCandidates.flatMap((asset) => {\n const assetUri = readOptionalString(asset.uri);\n const url = readOptionalString(asset.url);\n if (!assetUri && !url) {\n return [];\n }\n return [\n {\n type: \"file\" as const,\n ...(readOptionalString(asset.name)\n ? { name: readOptionalString(asset.name) }\n : {}),\n ...(readOptionalString(asset.mimeType)\n ? { mimeType: readOptionalString(asset.mimeType) }\n : {}),\n ...(assetUri ? { assetUri } : {}),\n ...(url ? { url } : {}),\n ...(readOptionalNumber(asset.sizeBytes) != null\n ? { sizeBytes: readOptionalNumber(asset.sizeBytes) }\n : {}),\n },\n ];\n });\n}\n\nfunction projectToolResultParts(params: {\n toolCallId?: string;\n toolName?: string;\n content: unknown;\n projectedToolCallIds: Set<string>;\n}): NcpMessagePart[] {\n if (\n params.toolName !== \"asset_put\" ||\n !params.toolCallId ||\n params.projectedToolCallIds.has(params.toolCallId)\n ) {\n return [];\n }\n const projectedFiles = projectAssetPutFiles(params.content);\n if (projectedFiles.length > 0) {\n params.projectedToolCallIds.add(params.toolCallId);\n }\n return projectedFiles;\n}\n\nfunction projectChannelOutputParts(\n parts: NcpMessagePart[],\n projectedToolCallIds: Set<string>,\n): NcpMessagePart[] {\n return parts.flatMap((part) => {\n if (\n part.type === \"tool-invocation\" &&\n part.toolName === \"asset_put\" &&\n part.result\n ) {\n if (\n part.toolCallId &&\n projectedToolCallIds.has(part.toolCallId)\n ) {\n return [];\n }\n const projectedFiles = projectAssetPutFiles(part.result);\n if (projectedFiles.length > 0) {\n if (part.toolCallId) {\n projectedToolCallIds.add(part.toolCallId);\n }\n return projectedFiles;\n }\n }\n return [part];\n });\n}\n\nclass NcpReplySession {\n private activeText = \"\";\n private fullText = \"\";\n private sentText = \"\";\n private typingStarted = false;\n private closed = false;\n private readonly toolNameByCallId = new Map<string, string>();\n private readonly projectedToolCallIds = new Set<string>();\n\n constructor(private readonly chat: Chat, private readonly target: ChatTarget) {}\n\n consume = async (eventStream: NcpEventStream): Promise<void> => {\n try {\n for await (const event of eventStream) {\n if (this.closed) {\n break;\n }\n await this.applyEvent(event);\n }\n } finally {\n await this.stopTyping();\n }\n };\n\n private applyEvent = async (event: NcpEndpointEvent): Promise<void> => {\n switch (event.type) {\n case NcpEventType.MessageTextStart:\n await this.handleTextStart();\n return;\n case NcpEventType.MessageTextDelta:\n await this.handleTextDelta(event.payload.delta);\n return;\n case NcpEventType.MessageTextEnd:\n await this.handleTextEnd();\n return;\n case NcpEventType.MessageToolCallStart:\n await this.handleToolCallStart(\n event.payload.toolCallId,\n event.payload.toolName,\n );\n return;\n case NcpEventType.MessageReasoningStart:\n await this.flushTextPart();\n return;\n case NcpEventType.MessageToolCallResult:\n await this.handleToolCallResult(\n event.payload.toolCallId,\n event.payload.content,\n );\n return;\n case NcpEventType.MessageCompleted:\n await this.handleCompleted(event.payload.message);\n return;\n case NcpEventType.MessageFailed:\n await this.handleReplyFailure(event.payload.error.message.trim());\n return;\n case NcpEventType.RunError:\n await this.handleReplyFailure(\n String(event.payload.error ?? \"NCP run failed.\").trim(),\n );\n return;\n default:\n return;\n }\n };\n\n private handleTextStart = async (): Promise<void> => {\n await this.ensureTypingStarted();\n if (this.activeText) {\n await this.flushTextPart();\n }\n this.activeText = \"\";\n };\n\n private handleTextDelta = async (delta: string): Promise<void> => {\n await this.ensureTypingStarted();\n this.activeText += delta;\n this.fullText += delta;\n };\n\n private handleTextEnd = async (): Promise<void> => this.flushTextPart();\n\n private handleToolCallStart = async (\n toolCallId: string,\n toolName: string,\n ): Promise<void> => {\n this.toolNameByCallId.set(toolCallId, toolName);\n await this.ensureTypingStarted();\n await this.flushTextPart();\n };\n\n private handleToolCallResult = async (\n toolCallId: string,\n content: unknown,\n ): Promise<void> => {\n await this.ensureTypingStarted();\n const projectedParts = projectToolResultParts({\n toolCallId,\n toolName: this.toolNameByCallId.get(toolCallId),\n content,\n projectedToolCallIds: this.projectedToolCallIds,\n });\n if (projectedParts.length === 0) {\n return;\n }\n await this.flushTextPart();\n for (const part of projectedParts) {\n await this.chat.sendPart(this.target, part);\n }\n };\n\n private handleCompleted = async (message: NcpMessage): Promise<void> => {\n await this.flushTextPart();\n const unsentParts = projectChannelOutputParts(\n resolveUnsentMessageParts(message, this.sentText, this.fullText),\n this.projectedToolCallIds,\n );\n for (const part of unsentParts) {\n await this.ensureTypingStarted();\n await this.chat.sendPart(this.target, part);\n if (isTextLikePart(part)) {\n this.sentText += part.text;\n }\n }\n await this.stopTyping();\n };\n\n private handleReplyFailure = async (message: string): Promise<void> => {\n if (message) {\n await this.ensureTypingStarted();\n await this.chat.sendError(this.target, message);\n }\n await this.stopTyping();\n };\n\n private flushTextPart = async (): Promise<void> => {\n if (!this.activeText.trim()) {\n this.activeText = \"\";\n return;\n }\n\n await this.ensureTypingStarted();\n await this.chat.sendPart(this.target, {\n type: \"text\",\n text: this.activeText,\n });\n this.sentText += this.activeText;\n this.activeText = \"\";\n };\n\n private ensureTypingStarted = async (): Promise<void> => {\n if (this.typingStarted) {\n return;\n }\n await this.chat.startTyping(this.target);\n this.typingStarted = true;\n };\n\n private stopTyping = async (): Promise<void> => {\n if (this.closed || !this.typingStarted) {\n return;\n }\n await this.chat.stopTyping(this.target);\n this.closed = true;\n };\n};\n\nexport class NcpReplyConsumer {\n constructor(private readonly chat: Chat) {}\n\n consume = async (input: NcpReplyInput): Promise<void> => {\n const session = new NcpReplySession(this.chat, input.target);\n await session.consume(input.eventStream);\n };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/ncp-toolkit",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Toolkit implementations built on top of the NextClaw Communication Protocol.",
|
|
6
6
|
"type": "module",
|
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
"dist"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@nextclaw/ncp": "0.7.
|
|
18
|
+
"@nextclaw/ncp": "0.7.2"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/node": "^20.17.6",
|
|
22
22
|
"prettier": "^3.3.3",
|
|
23
23
|
"typescript": "^5.6.3",
|
|
24
24
|
"vitest": "^4.1.2",
|
|
25
|
-
"@nextclaw/ncp-agent-runtime": "0.4.
|
|
25
|
+
"@nextclaw/ncp-agent-runtime": "0.4.2"
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"build": "tsdown src/index.ts --dts.sourcemap --clean --target es2022 --no-fixedExtension",
|