waifu-code 1.0.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/README.md +51 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.js +188 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +35 -0
- package/dist/config.js +73 -0
- package/dist/config.js.map +1 -0
- package/dist/observer/eventDetector.d.ts +16 -0
- package/dist/observer/eventDetector.js +30 -0
- package/dist/observer/eventDetector.js.map +1 -0
- package/dist/observer/streamObserver.d.ts +8 -0
- package/dist/observer/streamObserver.js +24 -0
- package/dist/observer/streamObserver.js.map +1 -0
- package/dist/providers/converter.d.ts +18 -0
- package/dist/providers/converter.js +168 -0
- package/dist/providers/converter.js.map +1 -0
- package/dist/providers/nim.d.ts +23 -0
- package/dist/providers/nim.js +276 -0
- package/dist/providers/nim.js.map +1 -0
- package/dist/providers/sseBuilder.d.ts +53 -0
- package/dist/providers/sseBuilder.js +280 -0
- package/dist/providers/sseBuilder.js.map +1 -0
- package/dist/providers/thinkParser.d.ts +21 -0
- package/dist/providers/thinkParser.js +130 -0
- package/dist/providers/thinkParser.js.map +1 -0
- package/dist/providers/toolParser.d.ts +31 -0
- package/dist/providers/toolParser.js +163 -0
- package/dist/providers/toolParser.js.map +1 -0
- package/dist/providers/types.d.ts +57 -0
- package/dist/providers/types.js +20 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/proxy/auth.d.ts +13 -0
- package/dist/proxy/auth.js +37 -0
- package/dist/proxy/auth.js.map +1 -0
- package/dist/proxy/commandUtils.d.ts +15 -0
- package/dist/proxy/commandUtils.js +155 -0
- package/dist/proxy/commandUtils.js.map +1 -0
- package/dist/proxy/detection.d.ts +13 -0
- package/dist/proxy/detection.js +107 -0
- package/dist/proxy/detection.js.map +1 -0
- package/dist/proxy/optimizer.d.ts +14 -0
- package/dist/proxy/optimizer.js +56 -0
- package/dist/proxy/optimizer.js.map +1 -0
- package/dist/proxy/routes.d.ts +21 -0
- package/dist/proxy/routes.js +142 -0
- package/dist/proxy/routes.js.map +1 -0
- package/dist/proxy/server.d.ts +31 -0
- package/dist/proxy/server.js +87 -0
- package/dist/proxy/server.js.map +1 -0
- package/dist/proxy/tokenCounter.d.ts +12 -0
- package/dist/proxy/tokenCounter.js +91 -0
- package/dist/proxy/tokenCounter.js.map +1 -0
- package/dist/proxy/types.d.ts +89 -0
- package/dist/proxy/types.js +7 -0
- package/dist/proxy/types.js.map +1 -0
- package/dist/waifu/overlayRenderer.d.ts +14 -0
- package/dist/waifu/overlayRenderer.js +49 -0
- package/dist/waifu/overlayRenderer.js.map +1 -0
- package/package.json +40 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converter.js","sourceRoot":"","sources":["../../src/providers/converter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NVIDIA NIM provider — sends requests to NVIDIA NIM API.
|
|
3
|
+
*
|
|
4
|
+
* Converts Anthropic-format requests to OpenAI chat completions format,
|
|
5
|
+
* sends them to NIM, and streams back responses as Anthropic SSE events.
|
|
6
|
+
* Port of Python NvidiaNimProvider + OpenAICompatibleProvider from proxy server.
|
|
7
|
+
*/
|
|
8
|
+
import type { EventDetector } from "../observer/eventDetector.js";
|
|
9
|
+
export declare const NVIDIA_NIM_BASE_URL = "https://integrate.api.nvidia.com/v1";
|
|
10
|
+
export declare const DEFAULT_MODEL = "moonshotai/kimi-k2-thinking";
|
|
11
|
+
export declare const DEFAULT_MAX_TOKENS = 81920;
|
|
12
|
+
export interface NimConfig {
|
|
13
|
+
apiKey: string;
|
|
14
|
+
model?: string;
|
|
15
|
+
maxTokens?: number;
|
|
16
|
+
temperature?: number;
|
|
17
|
+
topP?: number;
|
|
18
|
+
baseUrl?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Stream a response from NVIDIA NIM and yield Anthropic-format SSE events.
|
|
22
|
+
*/
|
|
23
|
+
export declare function streamNimResponse(requestData: any, config: NimConfig, inputTokens: number, requestId?: string, detector?: EventDetector): AsyncGenerator<string>;
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NVIDIA NIM provider — sends requests to NVIDIA NIM API.
|
|
3
|
+
*
|
|
4
|
+
* Converts Anthropic-format requests to OpenAI chat completions format,
|
|
5
|
+
* sends them to NIM, and streams back responses as Anthropic SSE events.
|
|
6
|
+
* Port of Python NvidiaNimProvider + OpenAICompatibleProvider from proxy server.
|
|
7
|
+
*/
|
|
8
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
9
|
+
import { randomUUID } from "node:crypto";
|
|
10
|
+
import { buildBaseRequestBody } from "./converter.js";
|
|
11
|
+
import { SSEBuilder } from "./sseBuilder.js";
|
|
12
|
+
import { ThinkTagParser } from "./thinkParser.js";
|
|
13
|
+
import { HeuristicToolParser } from "./toolParser.js";
|
|
14
|
+
import { ContentType, mapStopReason, } from "./types.js";
|
|
15
|
+
export const NVIDIA_NIM_BASE_URL = "https://integrate.api.nvidia.com/v1";
|
|
16
|
+
export const DEFAULT_MODEL = "moonshotai/kimi-k2-thinking";
|
|
17
|
+
export const DEFAULT_MAX_TOKENS = 81920;
|
|
18
|
+
function buildNimRequestBody(requestData, config) {
|
|
19
|
+
const body = buildBaseRequestBody(requestData);
|
|
20
|
+
// Override model to the configured NIM model
|
|
21
|
+
body.model = config.model ?? DEFAULT_MODEL;
|
|
22
|
+
// Cap max_tokens
|
|
23
|
+
const maxTokens = config.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
24
|
+
if (body.max_tokens == null) {
|
|
25
|
+
body.max_tokens = maxTokens;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
body.max_tokens = Math.min(body.max_tokens, maxTokens);
|
|
29
|
+
}
|
|
30
|
+
// NIM defaults
|
|
31
|
+
body.temperature ??= config.temperature ?? 1.0;
|
|
32
|
+
body.top_p ??= config.topP ?? 1.0;
|
|
33
|
+
// Parallel tool calls
|
|
34
|
+
if (body.tools && body.tools.length > 0) {
|
|
35
|
+
body.parallel_tool_calls = true;
|
|
36
|
+
}
|
|
37
|
+
return body;
|
|
38
|
+
}
|
|
39
|
+
function processToolCall(tc, sse) {
|
|
40
|
+
const events = [];
|
|
41
|
+
const tcIndex = tc.index < 0 ? sse.blocks.toolStates.size : tc.index;
|
|
42
|
+
const fnDelta = tc.function ?? {};
|
|
43
|
+
if (fnDelta.name != null) {
|
|
44
|
+
sse.blocks.registerToolName(tcIndex, fnDelta.name);
|
|
45
|
+
}
|
|
46
|
+
const state = sse.blocks.toolStates.get(tcIndex);
|
|
47
|
+
if (!state || !state.started) {
|
|
48
|
+
const name = state?.name ?? "";
|
|
49
|
+
if (name || tc.id) {
|
|
50
|
+
const toolId = tc.id ?? `tool_${randomUUID()}`;
|
|
51
|
+
events.push(sse.startToolBlock(tcIndex, toolId, name));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const args = fnDelta.arguments ?? "";
|
|
55
|
+
if (args) {
|
|
56
|
+
let currentState = sse.blocks.toolStates.get(tcIndex);
|
|
57
|
+
if (!currentState || !currentState.started) {
|
|
58
|
+
const toolId = tc.id ?? `tool_${randomUUID()}`;
|
|
59
|
+
const name = currentState?.name ?? "tool_call";
|
|
60
|
+
events.push(sse.startToolBlock(tcIndex, toolId, name));
|
|
61
|
+
currentState = sse.blocks.toolStates.get(tcIndex);
|
|
62
|
+
}
|
|
63
|
+
const currentName = currentState?.name ?? "";
|
|
64
|
+
if (currentName === "Task") {
|
|
65
|
+
const parsed = sse.blocks.bufferTaskArgs(tcIndex, args);
|
|
66
|
+
if (parsed != null) {
|
|
67
|
+
events.push(sse.emitToolDelta(tcIndex, JSON.stringify(parsed)));
|
|
68
|
+
}
|
|
69
|
+
return events;
|
|
70
|
+
}
|
|
71
|
+
events.push(sse.emitToolDelta(tcIndex, args));
|
|
72
|
+
}
|
|
73
|
+
return events;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Parse a single SSE line from the NIM API response.
|
|
77
|
+
* Returns the parsed JSON chunk, or null for non-data lines.
|
|
78
|
+
*/
|
|
79
|
+
function parseSSELine(line) {
|
|
80
|
+
if (!line.startsWith("data: "))
|
|
81
|
+
return null;
|
|
82
|
+
const data = line.slice(6).trim();
|
|
83
|
+
if (data === "[DONE]")
|
|
84
|
+
return null;
|
|
85
|
+
try {
|
|
86
|
+
return JSON.parse(data);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Stream a response from NVIDIA NIM and yield Anthropic-format SSE events.
|
|
94
|
+
*/
|
|
95
|
+
export async function* streamNimResponse(requestData, config, inputTokens, requestId, detector) {
|
|
96
|
+
const messageId = `msg_${randomUUID()}`;
|
|
97
|
+
const sse = new SSEBuilder(messageId, requestData.model, inputTokens);
|
|
98
|
+
const body = buildNimRequestBody(requestData, config);
|
|
99
|
+
const baseUrl = config.baseUrl ?? NVIDIA_NIM_BASE_URL;
|
|
100
|
+
yield sse.messageStart();
|
|
101
|
+
const thinkParser = new ThinkTagParser();
|
|
102
|
+
const heuristicParser = new HeuristicToolParser();
|
|
103
|
+
let finishReason = null;
|
|
104
|
+
let usageInfo = null;
|
|
105
|
+
let errorOccurred = false;
|
|
106
|
+
try {
|
|
107
|
+
const response = await fetch(`${baseUrl}/chat/completions`, {
|
|
108
|
+
method: "POST",
|
|
109
|
+
headers: {
|
|
110
|
+
"Content-Type": "application/json",
|
|
111
|
+
"Accept": "text/event-stream",
|
|
112
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
113
|
+
},
|
|
114
|
+
body: JSON.stringify({ ...body, stream: true }),
|
|
115
|
+
});
|
|
116
|
+
if (!response.ok) {
|
|
117
|
+
const errText = await response.text().catch(() => "Unknown error");
|
|
118
|
+
throw new Error(`NIM API error ${response.status}: ${errText.slice(0, 500)}`);
|
|
119
|
+
}
|
|
120
|
+
if (!response.body) {
|
|
121
|
+
throw new Error("NIM API returned no response body");
|
|
122
|
+
}
|
|
123
|
+
const reader = response.body.getReader();
|
|
124
|
+
const decoder = new TextDecoder();
|
|
125
|
+
let buffer = "";
|
|
126
|
+
while (true) {
|
|
127
|
+
const { done, value } = await reader.read();
|
|
128
|
+
if (done)
|
|
129
|
+
break;
|
|
130
|
+
buffer += decoder.decode(value, { stream: true });
|
|
131
|
+
const lines = buffer.split("\n");
|
|
132
|
+
buffer = lines.pop() ?? "";
|
|
133
|
+
for (const line of lines) {
|
|
134
|
+
const trimmed = line.trim();
|
|
135
|
+
if (!trimmed)
|
|
136
|
+
continue;
|
|
137
|
+
if (process.env.WAIFU_VERBOSE)
|
|
138
|
+
console.log("[NIM_RAW]", trimmed);
|
|
139
|
+
const chunk = parseSSELine(trimmed);
|
|
140
|
+
if (!chunk)
|
|
141
|
+
continue;
|
|
142
|
+
if (chunk.usage) {
|
|
143
|
+
usageInfo = chunk.usage;
|
|
144
|
+
}
|
|
145
|
+
if (!chunk.choices || chunk.choices.length === 0)
|
|
146
|
+
continue;
|
|
147
|
+
const choice = chunk.choices[0];
|
|
148
|
+
const delta = choice.delta;
|
|
149
|
+
if (!delta)
|
|
150
|
+
continue;
|
|
151
|
+
if (choice.finish_reason) {
|
|
152
|
+
finishReason = choice.finish_reason;
|
|
153
|
+
}
|
|
154
|
+
// Handle reasoning_content (OpenAI extended format)
|
|
155
|
+
if (delta.reasoning_content) {
|
|
156
|
+
detector?.onThinking();
|
|
157
|
+
for (const ev of sse.ensureThinkingBlock())
|
|
158
|
+
yield ev;
|
|
159
|
+
yield sse.emitThinkingDelta(delta.reasoning_content);
|
|
160
|
+
}
|
|
161
|
+
// Handle text content
|
|
162
|
+
if (delta.content) {
|
|
163
|
+
for (const part of thinkParser.feed(delta.content)) {
|
|
164
|
+
if (part.type === ContentType.THINKING) {
|
|
165
|
+
detector?.onThinking();
|
|
166
|
+
for (const ev of sse.ensureThinkingBlock())
|
|
167
|
+
yield ev;
|
|
168
|
+
yield sse.emitThinkingDelta(part.content);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
const [filteredText, detectedTools] = heuristicParser.feed(part.content);
|
|
172
|
+
if (filteredText) {
|
|
173
|
+
for (const ev of sse.ensureTextBlock())
|
|
174
|
+
yield ev;
|
|
175
|
+
yield sse.emitTextDelta(filteredText);
|
|
176
|
+
}
|
|
177
|
+
for (const toolUse of detectedTools) {
|
|
178
|
+
for (const ev of sse.closeContentBlocks())
|
|
179
|
+
yield ev;
|
|
180
|
+
const blockIdx = sse.blocks.allocateIndex();
|
|
181
|
+
if (toolUse.name === "Task" &&
|
|
182
|
+
typeof toolUse.input === "object") {
|
|
183
|
+
toolUse.input.run_in_background = false;
|
|
184
|
+
}
|
|
185
|
+
yield sse.contentBlockStart(blockIdx, "tool_use", {
|
|
186
|
+
id: toolUse.id,
|
|
187
|
+
name: toolUse.name,
|
|
188
|
+
});
|
|
189
|
+
yield sse.contentBlockDelta(blockIdx, "input_json_delta", JSON.stringify(toolUse.input));
|
|
190
|
+
yield sse.contentBlockStop(blockIdx);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Handle native tool calls
|
|
196
|
+
if (delta.tool_calls) {
|
|
197
|
+
for (const ev of sse.closeContentBlocks())
|
|
198
|
+
yield ev;
|
|
199
|
+
for (const tc of delta.tool_calls) {
|
|
200
|
+
const tcInfo = {
|
|
201
|
+
index: tc.index,
|
|
202
|
+
id: tc.id,
|
|
203
|
+
function: {
|
|
204
|
+
name: tc.function?.name,
|
|
205
|
+
arguments: tc.function?.arguments,
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
for (const ev of processToolCall(tcInfo, sse)) {
|
|
209
|
+
yield ev;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
errorOccurred = true;
|
|
218
|
+
const errorMsg = err.message ?? "NIM provider request failed";
|
|
219
|
+
const fullMsg = requestId
|
|
220
|
+
? `${errorMsg} (request_id=${requestId})`
|
|
221
|
+
: errorMsg;
|
|
222
|
+
for (const ev of sse.closeContentBlocks())
|
|
223
|
+
yield ev;
|
|
224
|
+
for (const ev of sse.emitError(fullMsg))
|
|
225
|
+
yield ev;
|
|
226
|
+
}
|
|
227
|
+
// Flush remaining think content
|
|
228
|
+
const remaining = thinkParser.flush();
|
|
229
|
+
if (remaining) {
|
|
230
|
+
if (remaining.type === ContentType.THINKING) {
|
|
231
|
+
for (const ev of sse.ensureThinkingBlock())
|
|
232
|
+
yield ev;
|
|
233
|
+
yield sse.emitThinkingDelta(remaining.content);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
for (const ev of sse.ensureTextBlock())
|
|
237
|
+
yield ev;
|
|
238
|
+
yield sse.emitTextDelta(remaining.content);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// Flush heuristic tool calls
|
|
242
|
+
for (const toolUse of heuristicParser.flush()) {
|
|
243
|
+
for (const ev of sse.closeContentBlocks())
|
|
244
|
+
yield ev;
|
|
245
|
+
const blockIdx = sse.blocks.allocateIndex();
|
|
246
|
+
if (toolUse.name === "Task" && typeof toolUse.input === "object") {
|
|
247
|
+
toolUse.input.run_in_background = false;
|
|
248
|
+
}
|
|
249
|
+
yield sse.contentBlockStart(blockIdx, "tool_use", {
|
|
250
|
+
id: toolUse.id,
|
|
251
|
+
name: toolUse.name,
|
|
252
|
+
});
|
|
253
|
+
yield sse.contentBlockDelta(blockIdx, "input_json_delta", JSON.stringify(toolUse.input));
|
|
254
|
+
yield sse.contentBlockStop(blockIdx);
|
|
255
|
+
}
|
|
256
|
+
// Ensure at least one text block exists
|
|
257
|
+
if (!errorOccurred &&
|
|
258
|
+
sse.blocks.textIndex === -1 &&
|
|
259
|
+
sse.blocks.toolStates.size === 0) {
|
|
260
|
+
for (const ev of sse.ensureTextBlock())
|
|
261
|
+
yield ev;
|
|
262
|
+
yield sse.emitTextDelta(" ");
|
|
263
|
+
}
|
|
264
|
+
// Flush Task arg buffers
|
|
265
|
+
for (const [toolIndex, out] of sse.blocks.flushTaskArgBuffers()) {
|
|
266
|
+
yield sse.emitToolDelta(toolIndex, out);
|
|
267
|
+
}
|
|
268
|
+
// Close all open blocks
|
|
269
|
+
for (const ev of sse.closeAllBlocks())
|
|
270
|
+
yield ev;
|
|
271
|
+
// Final message events
|
|
272
|
+
const outputTokens = usageInfo?.completion_tokens ?? sse.estimateOutputTokens();
|
|
273
|
+
yield sse.messageDelta(mapStopReason(finishReason), outputTokens);
|
|
274
|
+
yield sse.messageStop();
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=nim.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nim.js","sourceRoot":"","sources":["../../src/providers/nim.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSE event builder for Anthropic-format streaming responses.
|
|
3
|
+
*
|
|
4
|
+
* Generates properly formatted Server-Sent Events that match the
|
|
5
|
+
* Anthropic Messages API streaming protocol.
|
|
6
|
+
* Port of Python SSEBuilder from the proxy server.
|
|
7
|
+
*/
|
|
8
|
+
import { ToolCallState } from "./types.js";
|
|
9
|
+
/** Manages content block indices and state. */
|
|
10
|
+
declare class ContentBlockManager {
|
|
11
|
+
nextIndex: number;
|
|
12
|
+
thinkingIndex: number;
|
|
13
|
+
textIndex: number;
|
|
14
|
+
thinkingStarted: boolean;
|
|
15
|
+
textStarted: boolean;
|
|
16
|
+
toolStates: Map<number, ToolCallState>;
|
|
17
|
+
allocateIndex(): number;
|
|
18
|
+
registerToolName(index: number, name: string): void;
|
|
19
|
+
bufferTaskArgs(index: number, args: string): any | null;
|
|
20
|
+
flushTaskArgBuffers(): Array<[number, string]>;
|
|
21
|
+
}
|
|
22
|
+
export declare class SSEBuilder {
|
|
23
|
+
readonly messageId: string;
|
|
24
|
+
readonly model: string;
|
|
25
|
+
readonly inputTokens: number;
|
|
26
|
+
readonly blocks: ContentBlockManager;
|
|
27
|
+
private accumulatedTextParts;
|
|
28
|
+
private accumulatedReasoningParts;
|
|
29
|
+
constructor(messageId: string, model: string, inputTokens?: number);
|
|
30
|
+
private formatEvent;
|
|
31
|
+
messageStart(): string;
|
|
32
|
+
messageDelta(stopReason: string, outputTokens: number): string;
|
|
33
|
+
messageStop(): string;
|
|
34
|
+
contentBlockStart(index: number, blockType: string, extra?: any): string;
|
|
35
|
+
contentBlockDelta(index: number, deltaType: string, content: string): string;
|
|
36
|
+
contentBlockStop(index: number): string;
|
|
37
|
+
startThinkingBlock(): string;
|
|
38
|
+
emitThinkingDelta(content: string): string;
|
|
39
|
+
stopThinkingBlock(): string;
|
|
40
|
+
startTextBlock(): string;
|
|
41
|
+
emitTextDelta(content: string): string;
|
|
42
|
+
stopTextBlock(): string;
|
|
43
|
+
startToolBlock(toolIndex: number, toolId: string, name: string): string;
|
|
44
|
+
emitToolDelta(toolIndex: number, partialJson: string): string;
|
|
45
|
+
stopToolBlock(toolIndex: number): string;
|
|
46
|
+
ensureThinkingBlock(): Generator<string>;
|
|
47
|
+
ensureTextBlock(): Generator<string>;
|
|
48
|
+
closeContentBlocks(): Generator<string>;
|
|
49
|
+
closeAllBlocks(): Generator<string>;
|
|
50
|
+
emitError(errorMessage: string): Generator<string>;
|
|
51
|
+
estimateOutputTokens(): number;
|
|
52
|
+
}
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSE event builder for Anthropic-format streaming responses.
|
|
3
|
+
*
|
|
4
|
+
* Generates properly formatted Server-Sent Events that match the
|
|
5
|
+
* Anthropic Messages API streaming protocol.
|
|
6
|
+
* Port of Python SSEBuilder from the proxy server.
|
|
7
|
+
*/
|
|
8
|
+
/** Manages content block indices and state. */
|
|
9
|
+
class ContentBlockManager {
|
|
10
|
+
nextIndex = 0;
|
|
11
|
+
thinkingIndex = -1;
|
|
12
|
+
textIndex = -1;
|
|
13
|
+
thinkingStarted = false;
|
|
14
|
+
textStarted = false;
|
|
15
|
+
toolStates = new Map();
|
|
16
|
+
allocateIndex() {
|
|
17
|
+
return this.nextIndex++;
|
|
18
|
+
}
|
|
19
|
+
registerToolName(index, name) {
|
|
20
|
+
const existing = this.toolStates.get(index);
|
|
21
|
+
if (!existing) {
|
|
22
|
+
this.toolStates.set(index, {
|
|
23
|
+
blockIndex: -1,
|
|
24
|
+
toolId: "",
|
|
25
|
+
name,
|
|
26
|
+
contents: [],
|
|
27
|
+
started: false,
|
|
28
|
+
taskArgBuffer: "",
|
|
29
|
+
taskArgsEmitted: false,
|
|
30
|
+
});
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const prev = existing.name;
|
|
34
|
+
if (!prev || name.startsWith(prev)) {
|
|
35
|
+
existing.name = name;
|
|
36
|
+
}
|
|
37
|
+
else if (!prev.startsWith(name)) {
|
|
38
|
+
existing.name = prev + name;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
bufferTaskArgs(index, args) {
|
|
42
|
+
const state = this.toolStates.get(index);
|
|
43
|
+
if (!state || state.taskArgsEmitted)
|
|
44
|
+
return null;
|
|
45
|
+
state.taskArgBuffer += args;
|
|
46
|
+
try {
|
|
47
|
+
const argsJson = JSON.parse(state.taskArgBuffer);
|
|
48
|
+
if (argsJson.run_in_background !== false) {
|
|
49
|
+
argsJson.run_in_background = false;
|
|
50
|
+
}
|
|
51
|
+
state.taskArgsEmitted = true;
|
|
52
|
+
state.taskArgBuffer = "";
|
|
53
|
+
return argsJson;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
flushTaskArgBuffers() {
|
|
60
|
+
const results = [];
|
|
61
|
+
for (const [toolIndex, state] of this.toolStates.entries()) {
|
|
62
|
+
if (!state.taskArgBuffer || state.taskArgsEmitted)
|
|
63
|
+
continue;
|
|
64
|
+
let out = "{}";
|
|
65
|
+
try {
|
|
66
|
+
const argsJson = JSON.parse(state.taskArgBuffer);
|
|
67
|
+
if (argsJson.run_in_background !== false) {
|
|
68
|
+
argsJson.run_in_background = false;
|
|
69
|
+
}
|
|
70
|
+
out = JSON.stringify(argsJson);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// Best effort
|
|
74
|
+
}
|
|
75
|
+
state.taskArgsEmitted = true;
|
|
76
|
+
state.taskArgBuffer = "";
|
|
77
|
+
results.push([toolIndex, out]);
|
|
78
|
+
}
|
|
79
|
+
return results;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
export class SSEBuilder {
|
|
83
|
+
messageId;
|
|
84
|
+
model;
|
|
85
|
+
inputTokens;
|
|
86
|
+
blocks;
|
|
87
|
+
accumulatedTextParts = [];
|
|
88
|
+
accumulatedReasoningParts = [];
|
|
89
|
+
constructor(messageId, model, inputTokens = 0) {
|
|
90
|
+
this.messageId = messageId;
|
|
91
|
+
this.model = model;
|
|
92
|
+
this.inputTokens = inputTokens;
|
|
93
|
+
this.blocks = new ContentBlockManager();
|
|
94
|
+
}
|
|
95
|
+
formatEvent(eventType, data) {
|
|
96
|
+
return `event: ${eventType}\ndata: ${JSON.stringify(data)}\n\n`;
|
|
97
|
+
}
|
|
98
|
+
// ── Message lifecycle ──
|
|
99
|
+
messageStart() {
|
|
100
|
+
return this.formatEvent("message_start", {
|
|
101
|
+
type: "message_start",
|
|
102
|
+
message: {
|
|
103
|
+
id: this.messageId,
|
|
104
|
+
type: "message",
|
|
105
|
+
role: "assistant",
|
|
106
|
+
content: [],
|
|
107
|
+
model: this.model,
|
|
108
|
+
stop_reason: null,
|
|
109
|
+
stop_sequence: null,
|
|
110
|
+
usage: { input_tokens: this.inputTokens, output_tokens: 1 },
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
messageDelta(stopReason, outputTokens) {
|
|
115
|
+
return this.formatEvent("message_delta", {
|
|
116
|
+
type: "message_delta",
|
|
117
|
+
delta: { stop_reason: stopReason, stop_sequence: null },
|
|
118
|
+
usage: {
|
|
119
|
+
input_tokens: this.inputTokens,
|
|
120
|
+
output_tokens: outputTokens,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
messageStop() {
|
|
125
|
+
return this.formatEvent("message_stop", { type: "message_stop" });
|
|
126
|
+
}
|
|
127
|
+
// ── Content block events ──
|
|
128
|
+
contentBlockStart(index, blockType, extra = {}) {
|
|
129
|
+
const contentBlock = { type: blockType };
|
|
130
|
+
if (blockType === "thinking") {
|
|
131
|
+
contentBlock.thinking = extra.thinking ?? "";
|
|
132
|
+
}
|
|
133
|
+
else if (blockType === "text") {
|
|
134
|
+
contentBlock.text = extra.text ?? "";
|
|
135
|
+
}
|
|
136
|
+
else if (blockType === "tool_use") {
|
|
137
|
+
contentBlock.id = extra.id ?? "";
|
|
138
|
+
contentBlock.name = extra.name ?? "";
|
|
139
|
+
contentBlock.input = extra.input ?? {};
|
|
140
|
+
}
|
|
141
|
+
return this.formatEvent("content_block_start", {
|
|
142
|
+
type: "content_block_start",
|
|
143
|
+
index,
|
|
144
|
+
content_block: contentBlock,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
contentBlockDelta(index, deltaType, content) {
|
|
148
|
+
const delta = { type: deltaType };
|
|
149
|
+
if (deltaType === "thinking_delta") {
|
|
150
|
+
delta.thinking = content;
|
|
151
|
+
}
|
|
152
|
+
else if (deltaType === "text_delta") {
|
|
153
|
+
delta.text = content;
|
|
154
|
+
}
|
|
155
|
+
else if (deltaType === "input_json_delta") {
|
|
156
|
+
delta.partial_json = content;
|
|
157
|
+
}
|
|
158
|
+
return this.formatEvent("content_block_delta", {
|
|
159
|
+
type: "content_block_delta",
|
|
160
|
+
index,
|
|
161
|
+
delta,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
contentBlockStop(index) {
|
|
165
|
+
return this.formatEvent("content_block_stop", {
|
|
166
|
+
type: "content_block_stop",
|
|
167
|
+
index,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
// ── Thinking block helpers ──
|
|
171
|
+
startThinkingBlock() {
|
|
172
|
+
this.blocks.thinkingIndex = this.blocks.allocateIndex();
|
|
173
|
+
this.blocks.thinkingStarted = true;
|
|
174
|
+
return this.contentBlockStart(this.blocks.thinkingIndex, "thinking");
|
|
175
|
+
}
|
|
176
|
+
emitThinkingDelta(content) {
|
|
177
|
+
this.accumulatedReasoningParts.push(content);
|
|
178
|
+
return this.contentBlockDelta(this.blocks.thinkingIndex, "thinking_delta", content);
|
|
179
|
+
}
|
|
180
|
+
stopThinkingBlock() {
|
|
181
|
+
this.blocks.thinkingStarted = false;
|
|
182
|
+
return this.contentBlockStop(this.blocks.thinkingIndex);
|
|
183
|
+
}
|
|
184
|
+
// ── Text block helpers ──
|
|
185
|
+
startTextBlock() {
|
|
186
|
+
this.blocks.textIndex = this.blocks.allocateIndex();
|
|
187
|
+
this.blocks.textStarted = true;
|
|
188
|
+
return this.contentBlockStart(this.blocks.textIndex, "text");
|
|
189
|
+
}
|
|
190
|
+
emitTextDelta(content) {
|
|
191
|
+
this.accumulatedTextParts.push(content);
|
|
192
|
+
return this.contentBlockDelta(this.blocks.textIndex, "text_delta", content);
|
|
193
|
+
}
|
|
194
|
+
stopTextBlock() {
|
|
195
|
+
this.blocks.textStarted = false;
|
|
196
|
+
return this.contentBlockStop(this.blocks.textIndex);
|
|
197
|
+
}
|
|
198
|
+
// ── Tool block helpers ──
|
|
199
|
+
startToolBlock(toolIndex, toolId, name) {
|
|
200
|
+
const blockIdx = this.blocks.allocateIndex();
|
|
201
|
+
const existing = this.blocks.toolStates.get(toolIndex);
|
|
202
|
+
if (existing) {
|
|
203
|
+
existing.blockIndex = blockIdx;
|
|
204
|
+
existing.toolId = toolId;
|
|
205
|
+
existing.started = true;
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
this.blocks.toolStates.set(toolIndex, {
|
|
209
|
+
blockIndex: blockIdx,
|
|
210
|
+
toolId,
|
|
211
|
+
name,
|
|
212
|
+
contents: [],
|
|
213
|
+
started: true,
|
|
214
|
+
taskArgBuffer: "",
|
|
215
|
+
taskArgsEmitted: false,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return this.contentBlockStart(blockIdx, "tool_use", { id: toolId, name });
|
|
219
|
+
}
|
|
220
|
+
emitToolDelta(toolIndex, partialJson) {
|
|
221
|
+
const state = this.blocks.toolStates.get(toolIndex);
|
|
222
|
+
state.contents.push(partialJson);
|
|
223
|
+
return this.contentBlockDelta(state.blockIndex, "input_json_delta", partialJson);
|
|
224
|
+
}
|
|
225
|
+
stopToolBlock(toolIndex) {
|
|
226
|
+
const blockIdx = this.blocks.toolStates.get(toolIndex).blockIndex;
|
|
227
|
+
return this.contentBlockStop(blockIdx);
|
|
228
|
+
}
|
|
229
|
+
// ── State management ──
|
|
230
|
+
*ensureThinkingBlock() {
|
|
231
|
+
if (this.blocks.textStarted)
|
|
232
|
+
yield this.stopTextBlock();
|
|
233
|
+
if (!this.blocks.thinkingStarted)
|
|
234
|
+
yield this.startThinkingBlock();
|
|
235
|
+
}
|
|
236
|
+
*ensureTextBlock() {
|
|
237
|
+
if (this.blocks.thinkingStarted)
|
|
238
|
+
yield this.stopThinkingBlock();
|
|
239
|
+
if (!this.blocks.textStarted)
|
|
240
|
+
yield this.startTextBlock();
|
|
241
|
+
}
|
|
242
|
+
*closeContentBlocks() {
|
|
243
|
+
if (this.blocks.thinkingStarted)
|
|
244
|
+
yield this.stopThinkingBlock();
|
|
245
|
+
if (this.blocks.textStarted)
|
|
246
|
+
yield this.stopTextBlock();
|
|
247
|
+
}
|
|
248
|
+
*closeAllBlocks() {
|
|
249
|
+
if (this.blocks.thinkingStarted)
|
|
250
|
+
yield this.stopThinkingBlock();
|
|
251
|
+
if (this.blocks.textStarted)
|
|
252
|
+
yield this.stopTextBlock();
|
|
253
|
+
for (const [toolIndex, state] of this.blocks.toolStates.entries()) {
|
|
254
|
+
if (state.started)
|
|
255
|
+
yield this.stopToolBlock(toolIndex);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// ── Error handling ──
|
|
259
|
+
*emitError(errorMessage) {
|
|
260
|
+
const errorIndex = this.blocks.allocateIndex();
|
|
261
|
+
yield this.contentBlockStart(errorIndex, "text");
|
|
262
|
+
yield this.contentBlockDelta(errorIndex, "text_delta", errorMessage);
|
|
263
|
+
yield this.contentBlockStop(errorIndex);
|
|
264
|
+
}
|
|
265
|
+
// ── Token estimation ──
|
|
266
|
+
estimateOutputTokens() {
|
|
267
|
+
const text = this.accumulatedTextParts.join("");
|
|
268
|
+
const reasoning = this.accumulatedReasoningParts.join("");
|
|
269
|
+
// Simple char/4 estimation (no tiktoken in Node.js without native deps)
|
|
270
|
+
const textTokens = Math.ceil(text.length / 4);
|
|
271
|
+
const reasoningTokens = Math.ceil(reasoning.length / 4);
|
|
272
|
+
let toolTokens = 0;
|
|
273
|
+
for (const state of this.blocks.toolStates.values()) {
|
|
274
|
+
if (state.started)
|
|
275
|
+
toolTokens += 50;
|
|
276
|
+
}
|
|
277
|
+
return textTokens + reasoningTokens + toolTokens;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=sseBuilder.js.map
|