@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.
- package/dist/index.d.ts +565 -575
- package/dist/index.js +254 -291
- package/package.json +2 -3
package/dist/index.js
CHANGED
|
@@ -1,321 +1,284 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/types/message.ts
|
|
2
|
+
const NCP_INTERNAL_VISIBILITY_METADATA_KEY = "ncp_internal_visibility";
|
|
3
3
|
function isHiddenNcpMessage(message) {
|
|
4
|
-
|
|
4
|
+
return message?.metadata?.[NCP_INTERNAL_VISIBILITY_METADATA_KEY] === "hidden";
|
|
5
5
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
49
|
-
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
|
|
125
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
131
126
|
}
|
|
132
127
|
function isWhitespace(char) {
|
|
133
|
-
|
|
128
|
+
return /\s/.test(char);
|
|
134
129
|
}
|
|
135
130
|
function normalizeMode(value) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
return null;
|
|
131
|
+
if (value === "off" || value === "think-tags") return value;
|
|
132
|
+
return null;
|
|
140
133
|
}
|
|
141
134
|
function readLeadingThinkTagState(buffer) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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
|
-
|
|
192
|
-
|
|
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
|
-
|
|
201
|
-
|
|
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
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
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
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
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
|
-
|
|
311
|
-
|
|
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.
|
|
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": "
|
|
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
|
}
|