@nextclaw/ncp 0.5.0 → 0.5.1

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +565 -575
  2. package/dist/index.js +254 -291
  3. package/package.json +2 -3
package/dist/index.js CHANGED
@@ -1,321 +1,284 @@
1
- // src/types/message.ts
2
- var NCP_INTERNAL_VISIBILITY_METADATA_KEY = "ncp_internal_visibility";
1
+ //#region src/types/message.ts
2
+ const NCP_INTERNAL_VISIBILITY_METADATA_KEY = "ncp_internal_visibility";
3
3
  function isHiddenNcpMessage(message) {
4
- return message?.metadata?.[NCP_INTERNAL_VISIBILITY_METADATA_KEY] === "hidden";
4
+ return message?.metadata?.[NCP_INTERNAL_VISIBILITY_METADATA_KEY] === "hidden";
5
5
  }
6
-
7
- // src/types/events.ts
8
- var NcpEventType = /* @__PURE__ */ ((NcpEventType2) => {
9
- NcpEventType2["EndpointReady"] = "endpoint.ready";
10
- NcpEventType2["EndpointError"] = "endpoint.error";
11
- NcpEventType2["MessageRequest"] = "message.request";
12
- NcpEventType2["MessageStreamRequest"] = "message.stream-request";
13
- NcpEventType2["MessageSent"] = "message.sent";
14
- NcpEventType2["MessageAccepted"] = "message.accepted";
15
- NcpEventType2["MessageIncoming"] = "message.incoming";
16
- NcpEventType2["MessageCompleted"] = "message.completed";
17
- NcpEventType2["MessageFailed"] = "message.failed";
18
- NcpEventType2["MessageAbort"] = "message.abort";
19
- NcpEventType2["MessageTextStart"] = "message.text-start";
20
- NcpEventType2["MessageTextDelta"] = "message.text-delta";
21
- NcpEventType2["MessageTextEnd"] = "message.text-end";
22
- NcpEventType2["MessageReasoningStart"] = "message.reasoning-start";
23
- NcpEventType2["MessageReasoningDelta"] = "message.reasoning-delta";
24
- NcpEventType2["MessageReasoningEnd"] = "message.reasoning-end";
25
- NcpEventType2["MessageToolCallStart"] = "message.tool-call-start";
26
- NcpEventType2["MessageToolCallArgs"] = "message.tool-call-args";
27
- NcpEventType2["MessageToolCallArgsDelta"] = "message.tool-call-args-delta";
28
- NcpEventType2["MessageToolCallEnd"] = "message.tool-call-end";
29
- NcpEventType2["MessageToolCallResult"] = "message.tool-call-result";
30
- NcpEventType2["MessageRead"] = "message.read";
31
- NcpEventType2["MessageDelivered"] = "message.delivered";
32
- NcpEventType2["MessageRecalled"] = "message.recalled";
33
- NcpEventType2["MessageReaction"] = "message.reaction";
34
- NcpEventType2["RunStarted"] = "run.started";
35
- NcpEventType2["RunFinished"] = "run.finished";
36
- NcpEventType2["RunError"] = "run.error";
37
- NcpEventType2["RunMetadata"] = "run.metadata";
38
- NcpEventType2["TypingStart"] = "typing.start";
39
- NcpEventType2["TypingEnd"] = "typing.end";
40
- NcpEventType2["PresenceUpdated"] = "presence.updated";
41
- return NcpEventType2;
42
- })(NcpEventType || {});
43
-
44
- // src/toolkit/reply-tags.ts
45
- var REPLY_TO_CURRENT_PATTERN = /\[\[\s*reply_to_current\s*\]\]/gi;
46
- var REPLY_TO_ID_PATTERN = /\[\[\s*reply_to\s*:\s*([^\]]+?)\s*\]\]/i;
6
+ //#endregion
7
+ //#region src/types/events.ts
8
+ let NcpEventType = /* @__PURE__ */ function(NcpEventType) {
9
+ NcpEventType["EndpointReady"] = "endpoint.ready";
10
+ NcpEventType["EndpointError"] = "endpoint.error";
11
+ NcpEventType["MessageRequest"] = "message.request";
12
+ NcpEventType["MessageStreamRequest"] = "message.stream-request";
13
+ NcpEventType["MessageSent"] = "message.sent";
14
+ NcpEventType["MessageAccepted"] = "message.accepted";
15
+ NcpEventType["MessageIncoming"] = "message.incoming";
16
+ NcpEventType["MessageCompleted"] = "message.completed";
17
+ NcpEventType["MessageFailed"] = "message.failed";
18
+ NcpEventType["MessageAbort"] = "message.abort";
19
+ NcpEventType["MessageTextStart"] = "message.text-start";
20
+ NcpEventType["MessageTextDelta"] = "message.text-delta";
21
+ NcpEventType["MessageTextEnd"] = "message.text-end";
22
+ NcpEventType["MessageReasoningStart"] = "message.reasoning-start";
23
+ NcpEventType["MessageReasoningDelta"] = "message.reasoning-delta";
24
+ NcpEventType["MessageReasoningEnd"] = "message.reasoning-end";
25
+ NcpEventType["MessageToolCallStart"] = "message.tool-call-start";
26
+ NcpEventType["MessageToolCallArgs"] = "message.tool-call-args";
27
+ NcpEventType["MessageToolCallArgsDelta"] = "message.tool-call-args-delta";
28
+ NcpEventType["MessageToolCallEnd"] = "message.tool-call-end";
29
+ NcpEventType["MessageToolCallResult"] = "message.tool-call-result";
30
+ NcpEventType["MessageRead"] = "message.read";
31
+ NcpEventType["MessageDelivered"] = "message.delivered";
32
+ NcpEventType["MessageRecalled"] = "message.recalled";
33
+ NcpEventType["MessageReaction"] = "message.reaction";
34
+ NcpEventType["RunStarted"] = "run.started";
35
+ NcpEventType["RunFinished"] = "run.finished";
36
+ NcpEventType["RunError"] = "run.error";
37
+ NcpEventType["RunMetadata"] = "run.metadata";
38
+ NcpEventType["TypingStart"] = "typing.start";
39
+ NcpEventType["TypingEnd"] = "typing.end";
40
+ NcpEventType["PresenceUpdated"] = "presence.updated";
41
+ return NcpEventType;
42
+ }({});
43
+ //#endregion
44
+ //#region src/toolkit/reply-tags.ts
45
+ const REPLY_TO_CURRENT_PATTERN = /\[\[\s*reply_to_current\s*\]\]/gi;
46
+ const REPLY_TO_ID_PATTERN = /\[\[\s*reply_to\s*:\s*([^\]]+?)\s*\]\]/i;
47
47
  function normalizeReplyTarget(value) {
48
- if (typeof value !== "string") {
49
- return void 0;
50
- }
51
- const trimmed = value.trim();
52
- return trimmed.length > 0 ? trimmed : void 0;
48
+ if (typeof value !== "string") return;
49
+ const trimmed = value.trim();
50
+ return trimmed.length > 0 ? trimmed : void 0;
53
51
  }
54
52
  function stripReplyTagsFromText(content, currentMessageId) {
55
- let nextContent = content;
56
- let replyTo;
57
- if (REPLY_TO_CURRENT_PATTERN.test(nextContent)) {
58
- replyTo = normalizeReplyTarget(currentMessageId);
59
- nextContent = nextContent.replace(REPLY_TO_CURRENT_PATTERN, "").trim();
60
- }
61
- const explicitReplyTarget = nextContent.match(REPLY_TO_ID_PATTERN)?.[1];
62
- if (explicitReplyTarget) {
63
- replyTo = normalizeReplyTarget(explicitReplyTarget);
64
- nextContent = nextContent.replace(REPLY_TO_ID_PATTERN, "").trim();
65
- }
66
- return replyTo ? { content: nextContent, replyTo } : { content: nextContent };
53
+ let nextContent = content;
54
+ let replyTo;
55
+ if (REPLY_TO_CURRENT_PATTERN.test(nextContent)) {
56
+ replyTo = normalizeReplyTarget(currentMessageId);
57
+ nextContent = nextContent.replace(REPLY_TO_CURRENT_PATTERN, "").trim();
58
+ }
59
+ const explicitReplyTarget = nextContent.match(REPLY_TO_ID_PATTERN)?.[1];
60
+ if (explicitReplyTarget) {
61
+ replyTo = normalizeReplyTarget(explicitReplyTarget);
62
+ nextContent = nextContent.replace(REPLY_TO_ID_PATTERN, "").trim();
63
+ }
64
+ return replyTo ? {
65
+ content: nextContent,
66
+ replyTo
67
+ } : { content: nextContent };
67
68
  }
68
69
  function sanitizeAssistantReplyTags(message, currentMessageId = message.id) {
69
- if (message.role !== "assistant") {
70
- return {
71
- ...message,
72
- parts: [...message.parts],
73
- metadata: message.metadata ? { ...message.metadata } : void 0
74
- };
75
- }
76
- const firstTextIndex = message.parts.findIndex((part) => part.type === "text");
77
- const nextMetadata = message.metadata ? { ...message.metadata } : void 0;
78
- const existingReplyTo = normalizeReplyTarget(nextMetadata?.reply_to);
79
- if (firstTextIndex < 0) {
80
- return {
81
- ...message,
82
- parts: [...message.parts],
83
- metadata: nextMetadata
84
- };
85
- }
86
- const firstTextPart = message.parts[firstTextIndex];
87
- if (!firstTextPart || firstTextPart.type !== "text") {
88
- return {
89
- ...message,
90
- parts: [...message.parts],
91
- metadata: nextMetadata
92
- };
93
- }
94
- const { content, replyTo } = stripReplyTagsFromText(firstTextPart.text, currentMessageId);
95
- const effectiveReplyTo = replyTo ?? existingReplyTo;
96
- const nextParts = message.parts.flatMap((part, index) => {
97
- if (index !== firstTextIndex || part.type !== "text") {
98
- return [part];
99
- }
100
- if (content.length === 0) {
101
- return [];
102
- }
103
- return [{ ...part, text: content }];
104
- });
105
- if (effectiveReplyTo) {
106
- return {
107
- ...message,
108
- parts: nextParts,
109
- metadata: {
110
- ...nextMetadata,
111
- reply_to: effectiveReplyTo
112
- }
113
- };
114
- }
115
- return {
116
- ...message,
117
- parts: nextParts,
118
- metadata: nextMetadata
119
- };
70
+ if (message.role !== "assistant") return {
71
+ ...message,
72
+ parts: [...message.parts],
73
+ metadata: message.metadata ? { ...message.metadata } : void 0
74
+ };
75
+ const firstTextIndex = message.parts.findIndex((part) => part.type === "text");
76
+ const nextMetadata = message.metadata ? { ...message.metadata } : void 0;
77
+ const existingReplyTo = normalizeReplyTarget(nextMetadata?.reply_to);
78
+ if (firstTextIndex < 0) return {
79
+ ...message,
80
+ parts: [...message.parts],
81
+ metadata: nextMetadata
82
+ };
83
+ const firstTextPart = message.parts[firstTextIndex];
84
+ if (!firstTextPart || firstTextPart.type !== "text") return {
85
+ ...message,
86
+ parts: [...message.parts],
87
+ metadata: nextMetadata
88
+ };
89
+ const { content, replyTo } = stripReplyTagsFromText(firstTextPart.text, currentMessageId);
90
+ const effectiveReplyTo = replyTo ?? existingReplyTo;
91
+ const nextParts = message.parts.flatMap((part, index) => {
92
+ if (index !== firstTextIndex || part.type !== "text") return [part];
93
+ if (content.length === 0) return [];
94
+ return [{
95
+ ...part,
96
+ text: content
97
+ }];
98
+ });
99
+ if (effectiveReplyTo) return {
100
+ ...message,
101
+ parts: nextParts,
102
+ metadata: {
103
+ ...nextMetadata,
104
+ reply_to: effectiveReplyTo
105
+ }
106
+ };
107
+ return {
108
+ ...message,
109
+ parts: nextParts,
110
+ metadata: nextMetadata
111
+ };
120
112
  }
121
-
122
- // src/toolkit/reasoning-normalization.ts
123
- var THINK_OPEN_TAG = "<think>";
124
- var THINK_CLOSE_TAG = "</think>";
125
- var FINAL_OPEN_TAG = "<final>";
126
- var FINAL_CLOSE_TAG = "</final>";
127
- var LEADING_CONTROL_TAGS = [THINK_CLOSE_TAG, FINAL_OPEN_TAG, FINAL_CLOSE_TAG];
128
- var MAX_REASONING_DELIMITER_TAIL = THINK_CLOSE_TAG.length - 1;
113
+ //#endregion
114
+ //#region src/toolkit/reasoning-normalization.ts
115
+ const THINK_OPEN_TAG = "<think>";
116
+ const THINK_CLOSE_TAG = "</think>";
117
+ const FINAL_OPEN_TAG = "<final>";
118
+ const LEADING_CONTROL_TAGS = [
119
+ THINK_CLOSE_TAG,
120
+ FINAL_OPEN_TAG,
121
+ "</final>"
122
+ ];
123
+ const MAX_REASONING_DELIMITER_TAIL = 7;
129
124
  function isRecord(value) {
130
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
125
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
131
126
  }
132
127
  function isWhitespace(char) {
133
- return /\s/.test(char);
128
+ return /\s/.test(char);
134
129
  }
135
130
  function normalizeMode(value) {
136
- if (value === "off" || value === "think-tags") {
137
- return value;
138
- }
139
- return null;
131
+ if (value === "off" || value === "think-tags") return value;
132
+ return null;
140
133
  }
141
134
  function readLeadingThinkTagState(buffer) {
142
- let cursor = 0;
143
- while (cursor < buffer.length && isWhitespace(buffer[cursor])) {
144
- cursor += 1;
145
- }
146
- const rest = buffer.slice(cursor);
147
- if (rest.startsWith(THINK_OPEN_TAG)) {
148
- return {
149
- status: "matched",
150
- consumed: cursor + THINK_OPEN_TAG.length
151
- };
152
- }
153
- if (THINK_OPEN_TAG.startsWith(rest)) {
154
- return { status: "pending" };
155
- }
156
- return { status: "rejected" };
135
+ let cursor = 0;
136
+ while (cursor < buffer.length && isWhitespace(buffer[cursor])) cursor += 1;
137
+ const rest = buffer.slice(cursor);
138
+ if (rest.startsWith(THINK_OPEN_TAG)) return {
139
+ status: "matched",
140
+ consumed: cursor + 7
141
+ };
142
+ if (THINK_OPEN_TAG.startsWith(rest)) return { status: "pending" };
143
+ return { status: "rejected" };
157
144
  }
158
145
  function stripLeadingControlTags(buffer) {
159
- let nextBuffer = buffer;
160
- while (true) {
161
- let cursor = 0;
162
- while (cursor < nextBuffer.length && isWhitespace(nextBuffer[cursor])) {
163
- cursor += 1;
164
- }
165
- const rest = nextBuffer.slice(cursor);
166
- if (rest.length === 0) {
167
- return { buffer: "", pending: false };
168
- }
169
- const matchedTag = LEADING_CONTROL_TAGS.find((tag) => rest.startsWith(tag));
170
- if (matchedTag) {
171
- nextBuffer = rest.slice(matchedTag.length);
172
- continue;
173
- }
174
- if (LEADING_CONTROL_TAGS.some((tag) => tag.startsWith(rest))) {
175
- return { buffer: rest, pending: true };
176
- }
177
- return { buffer: rest, pending: false };
178
- }
146
+ let nextBuffer = buffer;
147
+ while (true) {
148
+ let cursor = 0;
149
+ while (cursor < nextBuffer.length && isWhitespace(nextBuffer[cursor])) cursor += 1;
150
+ const rest = nextBuffer.slice(cursor);
151
+ if (rest.length === 0) return {
152
+ buffer: "",
153
+ pending: false
154
+ };
155
+ const matchedTag = LEADING_CONTROL_TAGS.find((tag) => rest.startsWith(tag));
156
+ if (matchedTag) {
157
+ nextBuffer = rest.slice(matchedTag.length);
158
+ continue;
159
+ }
160
+ if (LEADING_CONTROL_TAGS.some((tag) => tag.startsWith(rest))) return {
161
+ buffer: rest,
162
+ pending: true
163
+ };
164
+ return {
165
+ buffer: rest,
166
+ pending: false
167
+ };
168
+ }
179
169
  }
180
170
  function findReasoningBoundary(buffer) {
181
- const indices = [
182
- { index: buffer.indexOf(THINK_CLOSE_TAG), tag: THINK_CLOSE_TAG },
183
- { index: buffer.indexOf(FINAL_OPEN_TAG), tag: FINAL_OPEN_TAG }
184
- ].filter((entry) => entry.index >= 0);
185
- if (indices.length === 0) {
186
- return null;
187
- }
188
- return indices.reduce((left, right) => right.index < left.index ? right : left);
171
+ const indices = [{
172
+ index: buffer.indexOf(THINK_CLOSE_TAG),
173
+ tag: THINK_CLOSE_TAG
174
+ }, {
175
+ index: buffer.indexOf(FINAL_OPEN_TAG),
176
+ tag: FINAL_OPEN_TAG
177
+ }].filter((entry) => entry.index >= 0);
178
+ if (indices.length === 0) return null;
179
+ return indices.reduce((left, right) => right.index < left.index ? right : left);
189
180
  }
190
181
  function readAssistantReasoningNormalizationMode(value) {
191
- if (typeof value === "string") {
192
- return normalizeMode(value);
193
- }
194
- if (isRecord(value)) {
195
- return normalizeMode(value.mode);
196
- }
197
- return null;
182
+ if (typeof value === "string") return normalizeMode(value);
183
+ if (isRecord(value)) return normalizeMode(value.mode);
184
+ return null;
198
185
  }
199
186
  function readAssistantReasoningNormalizationModeFromMetadata(metadata) {
200
- if (!metadata) {
201
- return null;
202
- }
203
- return readAssistantReasoningNormalizationMode(metadata.reasoning_normalization) ?? readAssistantReasoningNormalizationMode(metadata.reasoningNormalization) ?? normalizeMode(metadata.reasoning_normalization_mode) ?? normalizeMode(metadata.reasoningNormalizationMode);
187
+ if (!metadata) return null;
188
+ return readAssistantReasoningNormalizationMode(metadata.reasoning_normalization) ?? readAssistantReasoningNormalizationMode(metadata.reasoningNormalization) ?? normalizeMode(metadata.reasoning_normalization_mode) ?? normalizeMode(metadata.reasoningNormalizationMode);
204
189
  }
205
190
  function writeAssistantReasoningNormalizationModeToMetadata(metadata, mode) {
206
- const nextMetadata = {
207
- ...metadata
208
- };
209
- delete nextMetadata.reasoningNormalization;
210
- delete nextMetadata.reasoningNormalizationMode;
211
- delete nextMetadata.reasoning_normalization_mode;
212
- nextMetadata.reasoning_normalization = { mode };
213
- return nextMetadata;
191
+ const nextMetadata = { ...metadata };
192
+ delete nextMetadata.reasoningNormalization;
193
+ delete nextMetadata.reasoningNormalizationMode;
194
+ delete nextMetadata.reasoning_normalization_mode;
195
+ nextMetadata.reasoning_normalization = { mode };
196
+ return nextMetadata;
214
197
  }
215
198
  var NcpAssistantTextStreamNormalizer = class {
216
- constructor(mode = "off") {
217
- this.mode = mode;
218
- }
219
- buffer = "";
220
- phase = "initial";
221
- stripLeadingTextControlTags = false;
222
- push(delta) {
223
- if (!delta) {
224
- return [];
225
- }
226
- if (this.mode !== "think-tags") {
227
- return [{ type: "text", text: delta }];
228
- }
229
- this.buffer += delta;
230
- return this.flush(false);
231
- }
232
- finish() {
233
- if (this.mode !== "think-tags") {
234
- return [];
235
- }
236
- return this.flush(true);
237
- }
238
- flush(final) {
239
- const segments = [];
240
- while (true) {
241
- if (this.phase === "initial") {
242
- const leadingState = readLeadingThinkTagState(this.buffer);
243
- if (leadingState.status === "matched") {
244
- this.buffer = this.buffer.slice(leadingState.consumed);
245
- this.phase = "reasoning";
246
- continue;
247
- }
248
- if (leadingState.status === "pending" && !final) {
249
- return segments;
250
- }
251
- this.phase = "text";
252
- continue;
253
- }
254
- if (this.phase === "reasoning") {
255
- const boundary = findReasoningBoundary(this.buffer);
256
- if (boundary) {
257
- const reasoningText = this.buffer.slice(0, boundary.index);
258
- if (reasoningText.length > 0) {
259
- segments.push({ type: "reasoning", text: reasoningText });
260
- }
261
- this.buffer = this.buffer.slice(boundary.index + boundary.tag.length);
262
- this.phase = "text";
263
- this.stripLeadingTextControlTags = true;
264
- continue;
265
- }
266
- const safeLength = final ? this.buffer.length : Math.max(0, this.buffer.length - MAX_REASONING_DELIMITER_TAIL);
267
- if (safeLength === 0) {
268
- return segments;
269
- }
270
- segments.push({
271
- type: "reasoning",
272
- text: this.buffer.slice(0, safeLength)
273
- });
274
- this.buffer = this.buffer.slice(safeLength);
275
- if (!final) {
276
- return segments;
277
- }
278
- continue;
279
- }
280
- if (this.stripLeadingTextControlTags) {
281
- const stripped = stripLeadingControlTags(this.buffer);
282
- if (stripped.pending && !final) {
283
- this.buffer = stripped.buffer;
284
- return segments;
285
- }
286
- this.buffer = stripped.buffer;
287
- this.stripLeadingTextControlTags = false;
288
- }
289
- if (this.buffer.length === 0) {
290
- return segments;
291
- }
292
- segments.push({
293
- type: "text",
294
- text: this.buffer
295
- });
296
- this.buffer = "";
297
- return segments;
298
- }
299
- }
199
+ buffer = "";
200
+ phase = "initial";
201
+ stripLeadingTextControlTags = false;
202
+ constructor(mode = "off") {
203
+ this.mode = mode;
204
+ }
205
+ push(delta) {
206
+ if (!delta) return [];
207
+ if (this.mode !== "think-tags") return [{
208
+ type: "text",
209
+ text: delta
210
+ }];
211
+ this.buffer += delta;
212
+ return this.flush(false);
213
+ }
214
+ finish() {
215
+ if (this.mode !== "think-tags") return [];
216
+ return this.flush(true);
217
+ }
218
+ flush(final) {
219
+ const segments = [];
220
+ while (true) {
221
+ if (this.phase === "initial") {
222
+ const leadingState = readLeadingThinkTagState(this.buffer);
223
+ if (leadingState.status === "matched") {
224
+ this.buffer = this.buffer.slice(leadingState.consumed);
225
+ this.phase = "reasoning";
226
+ continue;
227
+ }
228
+ if (leadingState.status === "pending" && !final) return segments;
229
+ this.phase = "text";
230
+ continue;
231
+ }
232
+ if (this.phase === "reasoning") {
233
+ const boundary = findReasoningBoundary(this.buffer);
234
+ if (boundary) {
235
+ const reasoningText = this.buffer.slice(0, boundary.index);
236
+ if (reasoningText.length > 0) segments.push({
237
+ type: "reasoning",
238
+ text: reasoningText
239
+ });
240
+ this.buffer = this.buffer.slice(boundary.index + boundary.tag.length);
241
+ this.phase = "text";
242
+ this.stripLeadingTextControlTags = true;
243
+ continue;
244
+ }
245
+ const safeLength = final ? this.buffer.length : Math.max(0, this.buffer.length - MAX_REASONING_DELIMITER_TAIL);
246
+ if (safeLength === 0) return segments;
247
+ segments.push({
248
+ type: "reasoning",
249
+ text: this.buffer.slice(0, safeLength)
250
+ });
251
+ this.buffer = this.buffer.slice(safeLength);
252
+ if (!final) return segments;
253
+ continue;
254
+ }
255
+ if (this.stripLeadingTextControlTags) {
256
+ const stripped = stripLeadingControlTags(this.buffer);
257
+ if (stripped.pending && !final) {
258
+ this.buffer = stripped.buffer;
259
+ return segments;
260
+ }
261
+ this.buffer = stripped.buffer;
262
+ this.stripLeadingTextControlTags = false;
263
+ }
264
+ if (this.buffer.length === 0) return segments;
265
+ segments.push({
266
+ type: "text",
267
+ text: this.buffer
268
+ });
269
+ this.buffer = "";
270
+ return segments;
271
+ }
272
+ }
300
273
  };
301
274
  function normalizeAssistantText(text, mode) {
302
- const normalizer = new NcpAssistantTextStreamNormalizer(mode);
303
- const parts = [...normalizer.push(text), ...normalizer.finish()].filter((part) => part.text.length > 0);
304
- return {
305
- text: parts.filter((part) => part.type === "text").map((part) => part.text).join(""),
306
- reasoning: parts.filter((part) => part.type === "reasoning").map((part) => part.text).join(""),
307
- parts
308
- };
275
+ const normalizer = new NcpAssistantTextStreamNormalizer(mode);
276
+ const parts = [...normalizer.push(text), ...normalizer.finish()].filter((part) => part.text.length > 0);
277
+ return {
278
+ text: parts.filter((part) => part.type === "text").map((part) => part.text).join(""),
279
+ reasoning: parts.filter((part) => part.type === "reasoning").map((part) => part.text).join(""),
280
+ parts
281
+ };
309
282
  }
310
- export {
311
- NCP_INTERNAL_VISIBILITY_METADATA_KEY,
312
- NcpAssistantTextStreamNormalizer,
313
- NcpEventType,
314
- isHiddenNcpMessage,
315
- normalizeAssistantText,
316
- readAssistantReasoningNormalizationMode,
317
- readAssistantReasoningNormalizationModeFromMetadata,
318
- sanitizeAssistantReplyTags,
319
- stripReplyTagsFromText,
320
- writeAssistantReasoningNormalizationModeToMetadata
321
- };
283
+ //#endregion
284
+ export { NCP_INTERNAL_VISIBILITY_METADATA_KEY, NcpAssistantTextStreamNormalizer, NcpEventType, isHiddenNcpMessage, normalizeAssistantText, readAssistantReasoningNormalizationMode, readAssistantReasoningNormalizationModeFromMetadata, sanitizeAssistantReplyTags, stripReplyTagsFromText, writeAssistantReasoningNormalizationModeToMetadata };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/ncp",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "private": false,
5
5
  "description": "NextClaw Communication Protocol core abstractions and types.",
6
6
  "type": "module",
@@ -17,11 +17,10 @@
17
17
  "devDependencies": {
18
18
  "@types/node": "^20.17.6",
19
19
  "prettier": "^3.3.3",
20
- "tsup": "^8.3.5",
21
20
  "typescript": "^5.6.3"
22
21
  },
23
22
  "scripts": {
24
- "build": "tsup src/index.ts --format esm --dts --out-dir dist",
23
+ "build": "tsdown src/index.ts --dts --clean --target es2022 --no-fixedExtension",
25
24
  "lint": "eslint .",
26
25
  "tsc": "tsc -p tsconfig.json"
27
26
  }