simple-agents-wasm 0.2.32 → 0.2.34
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/index.js +24 -195
- package/package.json +3 -2
- package/pkg/simple_agents_wasm.d.ts +3 -3
- package/pkg/simple_agents_wasm.js +94 -94
- package/pkg/simple_agents_wasm_bg.wasm +0 -0
- package/pkg/simple_agents_wasm_bg.wasm.d.ts +3 -3
- package/runtime/errors.js +7 -0
- package/runtime/rust-runtime.js +19 -0
- package/runtime/stream.js +140 -0
- package/rust/Cargo.toml +1 -1
package/index.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { parse as parseYaml } from "yaml";
|
|
2
|
+
import { configError, runtimeError } from "./runtime/errors.js";
|
|
3
|
+
import {
|
|
4
|
+
applyDeltaToAggregate,
|
|
5
|
+
createStreamAggregator,
|
|
6
|
+
createStreamEventBridge,
|
|
7
|
+
iterateSse,
|
|
8
|
+
parseSseEventBlock
|
|
9
|
+
} from "./runtime/stream.js";
|
|
10
|
+
import { loadRustModule } from "./runtime/rust-runtime.js";
|
|
2
11
|
|
|
3
12
|
const DEFAULT_BASE_URLS = {
|
|
4
13
|
openai: "https://api.openai.com/v1",
|
|
5
14
|
openrouter: "https://openrouter.ai/api/v1"
|
|
6
15
|
};
|
|
7
16
|
|
|
8
|
-
function configError(message) {
|
|
9
|
-
return new Error(`simple-agents-wasm config error: ${message}`);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function runtimeError(message) {
|
|
13
|
-
return new Error(`simple-agents-wasm runtime error: ${message}`);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
17
|
function toMessages(promptOrMessages) {
|
|
17
18
|
if (typeof promptOrMessages === "string") {
|
|
18
19
|
const content = promptOrMessages.trim();
|
|
@@ -62,62 +63,6 @@ function toToolCalls(toolCalls) {
|
|
|
62
63
|
}));
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
function createStreamEventBridge(model, onChunk) {
|
|
66
|
-
let aggregate = "";
|
|
67
|
-
let finalId = "";
|
|
68
|
-
let finalModel = model;
|
|
69
|
-
let finalFinishReason;
|
|
70
|
-
|
|
71
|
-
return {
|
|
72
|
-
onEvent(event) {
|
|
73
|
-
if (event.eventType === "delta") {
|
|
74
|
-
const delta = event.delta;
|
|
75
|
-
if (!delta) {
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (!finalId && delta.id) {
|
|
80
|
-
finalId = delta.id;
|
|
81
|
-
}
|
|
82
|
-
if (delta.model) {
|
|
83
|
-
finalModel = delta.model;
|
|
84
|
-
}
|
|
85
|
-
if (delta.content) {
|
|
86
|
-
aggregate += delta.content;
|
|
87
|
-
}
|
|
88
|
-
if (delta.finishReason) {
|
|
89
|
-
finalFinishReason = delta.finishReason;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
onChunk({
|
|
93
|
-
id: delta.id,
|
|
94
|
-
model: delta.model,
|
|
95
|
-
content: delta.content,
|
|
96
|
-
finishReason: delta.finishReason,
|
|
97
|
-
raw: delta.raw
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (event.eventType === "error") {
|
|
102
|
-
onChunk({
|
|
103
|
-
id: finalId || "error",
|
|
104
|
-
model: finalModel,
|
|
105
|
-
error: event.error?.message ?? "stream error"
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
mergeResult(result, started) {
|
|
110
|
-
return {
|
|
111
|
-
...result,
|
|
112
|
-
id: result.id || finalId,
|
|
113
|
-
model: result.model || finalModel,
|
|
114
|
-
content: result.content ?? aggregate,
|
|
115
|
-
finishReason: result.finishReason ?? finalFinishReason,
|
|
116
|
-
latencyMs: Math.max(0, Math.round(performance.now() - started))
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
66
|
|
|
122
67
|
function assertWorkflowResultShape(result) {
|
|
123
68
|
if (result === null || typeof result !== "object") {
|
|
@@ -180,36 +125,17 @@ function finiteNumberOrNull(value) {
|
|
|
180
125
|
}
|
|
181
126
|
|
|
182
127
|
function buildStepDetail(step) {
|
|
183
|
-
|
|
184
|
-
elapsed_ms: step.elapsedMs,
|
|
128
|
+
return {
|
|
185
129
|
node_id: step.nodeId,
|
|
186
|
-
node_kind: step.nodeKind
|
|
130
|
+
node_kind: step.nodeKind,
|
|
131
|
+
model_name: step.modelName ?? null,
|
|
132
|
+
elapsed_ms: step.elapsedMs,
|
|
133
|
+
prompt_tokens: finiteNumberOrNull(step.promptTokens),
|
|
134
|
+
completion_tokens: finiteNumberOrNull(step.completionTokens),
|
|
135
|
+
total_tokens: finiteNumberOrNull(step.totalTokens),
|
|
136
|
+
reasoning_tokens: 0,
|
|
137
|
+
tokens_per_second: finiteNumberOrNull(step.tokensPerSecond)
|
|
187
138
|
};
|
|
188
|
-
|
|
189
|
-
if (step.nodeKind === "llm_call") {
|
|
190
|
-
if (typeof step.modelName === "string") {
|
|
191
|
-
detail.model_name = step.modelName;
|
|
192
|
-
}
|
|
193
|
-
const promptTokens = finiteNumberOrNull(step.promptTokens);
|
|
194
|
-
if (promptTokens !== null) {
|
|
195
|
-
detail.prompt_tokens = promptTokens;
|
|
196
|
-
}
|
|
197
|
-
const completionTokens = finiteNumberOrNull(step.completionTokens);
|
|
198
|
-
if (completionTokens !== null) {
|
|
199
|
-
detail.completion_tokens = completionTokens;
|
|
200
|
-
}
|
|
201
|
-
const totalTokens = finiteNumberOrNull(step.totalTokens);
|
|
202
|
-
if (totalTokens !== null) {
|
|
203
|
-
detail.total_tokens = totalTokens;
|
|
204
|
-
}
|
|
205
|
-
detail.reasoning_tokens = 0;
|
|
206
|
-
const tokensPerSecond = finiteNumberOrNull(step.tokensPerSecond);
|
|
207
|
-
if (tokensPerSecond !== null) {
|
|
208
|
-
detail.tokens_per_second = tokensPerSecond;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
return detail;
|
|
213
139
|
}
|
|
214
140
|
|
|
215
141
|
function buildWorkflowNerdstats(summary) {
|
|
@@ -605,10 +531,6 @@ function llmOutputSchema(node) {
|
|
|
605
531
|
};
|
|
606
532
|
}
|
|
607
533
|
|
|
608
|
-
function normalizeSseChunk(chunk) {
|
|
609
|
-
return chunk.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
610
|
-
}
|
|
611
|
-
|
|
612
534
|
function evaluateSwitchCondition(condition, context) {
|
|
613
535
|
if (typeof condition !== "string") {
|
|
614
536
|
return false;
|
|
@@ -629,66 +551,6 @@ function evaluateSwitchCondition(condition, context) {
|
|
|
629
551
|
return false;
|
|
630
552
|
}
|
|
631
553
|
|
|
632
|
-
function parseSseEventBlock(block) {
|
|
633
|
-
const lines = block.split("\n");
|
|
634
|
-
const dataLines = [];
|
|
635
|
-
for (const line of lines) {
|
|
636
|
-
if (line.startsWith("data:")) {
|
|
637
|
-
dataLines.push(line.slice(5).trimStart());
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
if (dataLines.length === 0) {
|
|
642
|
-
return null;
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
const payload = dataLines.join("\n");
|
|
646
|
-
if (payload === "[DONE]") {
|
|
647
|
-
return { done: true };
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
try {
|
|
651
|
-
return { done: false, json: JSON.parse(payload), raw: payload };
|
|
652
|
-
} catch {
|
|
653
|
-
return { done: false, raw: payload };
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
async function* iterateSse(response) {
|
|
658
|
-
if (!response.body) {
|
|
659
|
-
throw runtimeError("stream response had no body");
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
const reader = response.body.getReader();
|
|
663
|
-
const decoder = new TextDecoder();
|
|
664
|
-
let buffer = "";
|
|
665
|
-
|
|
666
|
-
while (true) {
|
|
667
|
-
const { value, done } = await reader.read();
|
|
668
|
-
if (done) {
|
|
669
|
-
break;
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
buffer += normalizeSseChunk(decoder.decode(value, { stream: true }));
|
|
673
|
-
let delimiterIndex = buffer.indexOf("\n\n");
|
|
674
|
-
while (delimiterIndex !== -1) {
|
|
675
|
-
const block = buffer.slice(0, delimiterIndex).trim();
|
|
676
|
-
buffer = buffer.slice(delimiterIndex + 2);
|
|
677
|
-
if (block.length > 0) {
|
|
678
|
-
yield block;
|
|
679
|
-
}
|
|
680
|
-
delimiterIndex = buffer.indexOf("\n\n");
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
buffer += normalizeSseChunk(decoder.decode());
|
|
685
|
-
|
|
686
|
-
const trailing = buffer.trim();
|
|
687
|
-
if (trailing.length > 0) {
|
|
688
|
-
yield trailing;
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
|
|
692
554
|
class BrowserJsClient {
|
|
693
555
|
constructor(provider, config) {
|
|
694
556
|
if (provider !== "openai" && provider !== "openrouter") {
|
|
@@ -829,10 +691,7 @@ class BrowserJsClient {
|
|
|
829
691
|
}
|
|
830
692
|
|
|
831
693
|
const started = performance.now();
|
|
832
|
-
|
|
833
|
-
let responseModel = model;
|
|
834
|
-
let aggregate = "";
|
|
835
|
-
let finishReason;
|
|
694
|
+
const aggregateState = createStreamAggregator(model);
|
|
836
695
|
let usage = {
|
|
837
696
|
promptTokens: 0,
|
|
838
697
|
completionTokens: 0,
|
|
@@ -867,18 +726,7 @@ class BrowserJsClient {
|
|
|
867
726
|
raw: parsed.raw
|
|
868
727
|
};
|
|
869
728
|
|
|
870
|
-
|
|
871
|
-
responseId = delta.id;
|
|
872
|
-
}
|
|
873
|
-
if (delta.model) {
|
|
874
|
-
responseModel = delta.model;
|
|
875
|
-
}
|
|
876
|
-
if (delta.content) {
|
|
877
|
-
aggregate += delta.content;
|
|
878
|
-
}
|
|
879
|
-
if (delta.finishReason) {
|
|
880
|
-
finishReason = delta.finishReason;
|
|
881
|
-
}
|
|
729
|
+
applyDeltaToAggregate(aggregateState, delta);
|
|
882
730
|
if (chunk?.usage && typeof chunk.usage === "object") {
|
|
883
731
|
usage = toUsage(chunk.usage);
|
|
884
732
|
usageAvailable = true;
|
|
@@ -897,11 +745,11 @@ class BrowserJsClient {
|
|
|
897
745
|
const latencyMs = Math.max(0, Math.round(performance.now() - started));
|
|
898
746
|
|
|
899
747
|
return {
|
|
900
|
-
id: responseId,
|
|
901
|
-
model: responseModel,
|
|
748
|
+
id: aggregateState.responseId,
|
|
749
|
+
model: aggregateState.responseModel,
|
|
902
750
|
role: "assistant",
|
|
903
|
-
content: aggregate,
|
|
904
|
-
finishReason,
|
|
751
|
+
content: aggregateState.aggregate,
|
|
752
|
+
finishReason: aggregateState.finishReason,
|
|
905
753
|
usage: {
|
|
906
754
|
...usage
|
|
907
755
|
},
|
|
@@ -1323,25 +1171,6 @@ class BrowserJsClient {
|
|
|
1323
1171
|
}
|
|
1324
1172
|
}
|
|
1325
1173
|
|
|
1326
|
-
let rustModulePromise;
|
|
1327
|
-
|
|
1328
|
-
async function loadRustModule() {
|
|
1329
|
-
if (!rustModulePromise) {
|
|
1330
|
-
rustModulePromise = (async () => {
|
|
1331
|
-
try {
|
|
1332
|
-
const moduleValue = await import("./pkg/simple_agents_wasm.js");
|
|
1333
|
-
const wasmUrl = new URL("./pkg/simple_agents_wasm_bg.wasm", import.meta.url);
|
|
1334
|
-
await moduleValue.default({ module_or_path: wasmUrl });
|
|
1335
|
-
return moduleValue;
|
|
1336
|
-
} catch {
|
|
1337
|
-
return null;
|
|
1338
|
-
}
|
|
1339
|
-
})();
|
|
1340
|
-
}
|
|
1341
|
-
|
|
1342
|
-
return rustModulePromise;
|
|
1343
|
-
}
|
|
1344
|
-
|
|
1345
1174
|
export class Client {
|
|
1346
1175
|
constructor(provider, config) {
|
|
1347
1176
|
this.fallbackClient = new BrowserJsClient(provider, config);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "simple-agents-wasm",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.34",
|
|
4
4
|
"description": "Browser-compatible SimpleAgents client for OpenAI-compatible providers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -11,11 +11,12 @@
|
|
|
11
11
|
"test": "node --test test/*.test.js"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"yaml": "
|
|
14
|
+
"yaml": "2.5.1"
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
17
|
"index.js",
|
|
18
18
|
"index.d.ts",
|
|
19
|
+
"runtime",
|
|
19
20
|
"README.md",
|
|
20
21
|
"pkg",
|
|
21
22
|
"rust/Cargo.toml",
|
|
@@ -27,14 +27,14 @@ export interface InitOutput {
|
|
|
27
27
|
readonly wasmclient_runWorkflowYaml: (a: number, b: number, c: number, d: any) => [number, number, number];
|
|
28
28
|
readonly wasmclient_runWorkflowYamlString: (a: number, b: number, c: number, d: any, e: number) => any;
|
|
29
29
|
readonly wasmclient_streamEvents: (a: number, b: number, c: number, d: any, e: any, f: number) => any;
|
|
30
|
-
readonly
|
|
31
|
-
readonly
|
|
32
|
-
readonly wasm_bindgen__convert__closures_____invoke__h133df7605c346924: (a: number, b: number, c: any, d: any) => void;
|
|
30
|
+
readonly wasm_bindgen__convert__closures_____invoke__h9f53f643b01d7c8e: (a: number, b: number, c: any) => [number, number];
|
|
31
|
+
readonly wasm_bindgen__convert__closures_____invoke__h05acb8c479b21d4b: (a: number, b: number, c: any, d: any) => void;
|
|
33
32
|
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
34
33
|
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
35
34
|
readonly __wbindgen_exn_store: (a: number) => void;
|
|
36
35
|
readonly __externref_table_alloc: () => number;
|
|
37
36
|
readonly __wbindgen_externrefs: WebAssembly.Table;
|
|
37
|
+
readonly __wbindgen_destroy_closure: (a: number, b: number) => void;
|
|
38
38
|
readonly __externref_table_dealloc: (a: number) => void;
|
|
39
39
|
readonly __wbindgen_start: () => void;
|
|
40
40
|
}
|
|
@@ -100,76 +100,76 @@ export function toJsArray(value) {
|
|
|
100
100
|
function __wbg_get_imports() {
|
|
101
101
|
const import0 = {
|
|
102
102
|
__proto__: null,
|
|
103
|
-
|
|
103
|
+
__wbg_Error_2e59b1b37a9a34c3: function(arg0, arg1) {
|
|
104
104
|
const ret = Error(getStringFromWasm0(arg0, arg1));
|
|
105
105
|
return ret;
|
|
106
106
|
},
|
|
107
|
-
|
|
107
|
+
__wbg_Number_e6ffdb596c888833: function(arg0) {
|
|
108
108
|
const ret = Number(arg0);
|
|
109
109
|
return ret;
|
|
110
110
|
},
|
|
111
|
-
|
|
111
|
+
__wbg___wbindgen_bigint_get_as_i64_2c5082002e4826e2: function(arg0, arg1) {
|
|
112
112
|
const v = arg1;
|
|
113
113
|
const ret = typeof(v) === 'bigint' ? v : undefined;
|
|
114
114
|
getDataViewMemory0().setBigInt64(arg0 + 8 * 1, isLikeNone(ret) ? BigInt(0) : ret, true);
|
|
115
115
|
getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
|
|
116
116
|
},
|
|
117
|
-
|
|
117
|
+
__wbg___wbindgen_boolean_get_a86c216575a75c30: function(arg0) {
|
|
118
118
|
const v = arg0;
|
|
119
119
|
const ret = typeof(v) === 'boolean' ? v : undefined;
|
|
120
120
|
return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
|
|
121
121
|
},
|
|
122
|
-
|
|
122
|
+
__wbg___wbindgen_debug_string_dd5d2d07ce9e6c57: function(arg0, arg1) {
|
|
123
123
|
const ret = debugString(arg1);
|
|
124
124
|
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
125
125
|
const len1 = WASM_VECTOR_LEN;
|
|
126
126
|
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
|
127
127
|
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
|
128
128
|
},
|
|
129
|
-
|
|
129
|
+
__wbg___wbindgen_in_4bd7a57e54337366: function(arg0, arg1) {
|
|
130
130
|
const ret = arg0 in arg1;
|
|
131
131
|
return ret;
|
|
132
132
|
},
|
|
133
|
-
|
|
133
|
+
__wbg___wbindgen_is_bigint_6c98f7e945dacdde: function(arg0) {
|
|
134
134
|
const ret = typeof(arg0) === 'bigint';
|
|
135
135
|
return ret;
|
|
136
136
|
},
|
|
137
|
-
|
|
137
|
+
__wbg___wbindgen_is_function_49868bde5eb1e745: function(arg0) {
|
|
138
138
|
const ret = typeof(arg0) === 'function';
|
|
139
139
|
return ret;
|
|
140
140
|
},
|
|
141
|
-
|
|
141
|
+
__wbg___wbindgen_is_null_344c8750a8525473: function(arg0) {
|
|
142
142
|
const ret = arg0 === null;
|
|
143
143
|
return ret;
|
|
144
144
|
},
|
|
145
|
-
|
|
145
|
+
__wbg___wbindgen_is_object_40c5a80572e8f9d3: function(arg0) {
|
|
146
146
|
const val = arg0;
|
|
147
147
|
const ret = typeof(val) === 'object' && val !== null;
|
|
148
148
|
return ret;
|
|
149
149
|
},
|
|
150
|
-
|
|
150
|
+
__wbg___wbindgen_is_string_b29b5c5a8065ba1a: function(arg0) {
|
|
151
151
|
const ret = typeof(arg0) === 'string';
|
|
152
152
|
return ret;
|
|
153
153
|
},
|
|
154
|
-
|
|
154
|
+
__wbg___wbindgen_is_undefined_c0cca72b82b86f4d: function(arg0) {
|
|
155
155
|
const ret = arg0 === undefined;
|
|
156
156
|
return ret;
|
|
157
157
|
},
|
|
158
|
-
|
|
158
|
+
__wbg___wbindgen_jsval_eq_7d430e744a913d26: function(arg0, arg1) {
|
|
159
159
|
const ret = arg0 === arg1;
|
|
160
160
|
return ret;
|
|
161
161
|
},
|
|
162
|
-
|
|
162
|
+
__wbg___wbindgen_jsval_loose_eq_3a72ae764d46d944: function(arg0, arg1) {
|
|
163
163
|
const ret = arg0 == arg1;
|
|
164
164
|
return ret;
|
|
165
165
|
},
|
|
166
|
-
|
|
166
|
+
__wbg___wbindgen_number_get_7579aab02a8a620c: function(arg0, arg1) {
|
|
167
167
|
const obj = arg1;
|
|
168
168
|
const ret = typeof(obj) === 'number' ? obj : undefined;
|
|
169
169
|
getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true);
|
|
170
170
|
getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
|
|
171
171
|
},
|
|
172
|
-
|
|
172
|
+
__wbg___wbindgen_string_get_914df97fcfa788f2: function(arg0, arg1) {
|
|
173
173
|
const obj = arg1;
|
|
174
174
|
const ret = typeof(obj) === 'string' ? obj : undefined;
|
|
175
175
|
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
@@ -177,49 +177,49 @@ function __wbg_get_imports() {
|
|
|
177
177
|
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
|
178
178
|
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
|
179
179
|
},
|
|
180
|
-
|
|
180
|
+
__wbg___wbindgen_throw_81fc77679af83bc6: function(arg0, arg1) {
|
|
181
181
|
throw new Error(getStringFromWasm0(arg0, arg1));
|
|
182
182
|
},
|
|
183
|
-
|
|
183
|
+
__wbg__wbg_cb_unref_3c3b4f651835fbcb: function(arg0) {
|
|
184
184
|
arg0._wbg_cb_unref();
|
|
185
185
|
},
|
|
186
|
-
|
|
187
|
-
const ret = arg0.call(arg1, arg2);
|
|
188
|
-
return ret;
|
|
189
|
-
}, arguments); },
|
|
190
|
-
__wbg_call_dcc2662fa17a72cf: function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
|
186
|
+
__wbg_call_368fa9c372d473ba: function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
|
191
187
|
const ret = arg0.call(arg1, arg2, arg3);
|
|
192
188
|
return ret;
|
|
193
189
|
}, arguments); },
|
|
194
|
-
|
|
190
|
+
__wbg_call_7f2987183bb62793: function() { return handleError(function (arg0, arg1) {
|
|
195
191
|
const ret = arg0.call(arg1);
|
|
196
192
|
return ret;
|
|
197
193
|
}, arguments); },
|
|
198
|
-
|
|
194
|
+
__wbg_call_d578befcc3145dee: function() { return handleError(function (arg0, arg1, arg2) {
|
|
195
|
+
const ret = arg0.call(arg1, arg2);
|
|
196
|
+
return ret;
|
|
197
|
+
}, arguments); },
|
|
198
|
+
__wbg_construct_adeb3d5948c3d19a: function() { return handleError(function (arg0, arg1) {
|
|
199
199
|
const ret = Reflect.construct(arg0, arg1);
|
|
200
200
|
return ret;
|
|
201
201
|
}, arguments); },
|
|
202
|
-
|
|
202
|
+
__wbg_done_547d467e97529006: function(arg0) {
|
|
203
203
|
const ret = arg0.done;
|
|
204
204
|
return ret;
|
|
205
205
|
},
|
|
206
|
-
|
|
206
|
+
__wbg_entries_616b1a459b85be0b: function(arg0) {
|
|
207
207
|
const ret = Object.entries(arg0);
|
|
208
208
|
return ret;
|
|
209
209
|
},
|
|
210
|
-
|
|
210
|
+
__wbg_get_4848e350b40afc16: function(arg0, arg1) {
|
|
211
|
+
const ret = arg0[arg1 >>> 0];
|
|
212
|
+
return ret;
|
|
213
|
+
},
|
|
214
|
+
__wbg_get_ed0642c4b9d31ddf: function() { return handleError(function (arg0, arg1) {
|
|
211
215
|
const ret = Reflect.get(arg0, arg1);
|
|
212
216
|
return ret;
|
|
213
217
|
}, arguments); },
|
|
214
|
-
|
|
218
|
+
__wbg_get_f96702c6245e4ef9: function() { return handleError(function (arg0, arg1) {
|
|
215
219
|
const ret = Reflect.get(arg0, arg1);
|
|
216
220
|
return ret;
|
|
217
221
|
}, arguments); },
|
|
218
|
-
|
|
219
|
-
const ret = arg0[arg1 >>> 0];
|
|
220
|
-
return ret;
|
|
221
|
-
},
|
|
222
|
-
__wbg_get_unchecked_329cfe50afab7352: function(arg0, arg1) {
|
|
222
|
+
__wbg_get_unchecked_7d7babe32e9e6a54: function(arg0, arg1) {
|
|
223
223
|
const ret = arg0[arg1 >>> 0];
|
|
224
224
|
return ret;
|
|
225
225
|
},
|
|
@@ -227,7 +227,7 @@ function __wbg_get_imports() {
|
|
|
227
227
|
const ret = arg0[arg1];
|
|
228
228
|
return ret;
|
|
229
229
|
},
|
|
230
|
-
|
|
230
|
+
__wbg_instanceof_ArrayBuffer_ff7c1337a5e3b33a: function(arg0) {
|
|
231
231
|
let result;
|
|
232
232
|
try {
|
|
233
233
|
result = arg0 instanceof ArrayBuffer;
|
|
@@ -237,7 +237,7 @@ function __wbg_get_imports() {
|
|
|
237
237
|
const ret = result;
|
|
238
238
|
return ret;
|
|
239
239
|
},
|
|
240
|
-
|
|
240
|
+
__wbg_instanceof_Map_a10a2795ef4bfe97: function(arg0) {
|
|
241
241
|
let result;
|
|
242
242
|
try {
|
|
243
243
|
result = arg0 instanceof Map;
|
|
@@ -247,7 +247,7 @@ function __wbg_get_imports() {
|
|
|
247
247
|
const ret = result;
|
|
248
248
|
return ret;
|
|
249
249
|
},
|
|
250
|
-
|
|
250
|
+
__wbg_instanceof_Promise_95d523058012a13d: function(arg0) {
|
|
251
251
|
let result;
|
|
252
252
|
try {
|
|
253
253
|
result = arg0 instanceof Promise;
|
|
@@ -257,7 +257,7 @@ function __wbg_get_imports() {
|
|
|
257
257
|
const ret = result;
|
|
258
258
|
return ret;
|
|
259
259
|
},
|
|
260
|
-
|
|
260
|
+
__wbg_instanceof_Uint8Array_4b8da683deb25d72: function(arg0) {
|
|
261
261
|
let result;
|
|
262
262
|
try {
|
|
263
263
|
result = arg0 instanceof Uint8Array;
|
|
@@ -267,54 +267,54 @@ function __wbg_get_imports() {
|
|
|
267
267
|
const ret = result;
|
|
268
268
|
return ret;
|
|
269
269
|
},
|
|
270
|
-
|
|
270
|
+
__wbg_isArray_db61795ad004c139: function(arg0) {
|
|
271
271
|
const ret = Array.isArray(arg0);
|
|
272
272
|
return ret;
|
|
273
273
|
},
|
|
274
|
-
|
|
274
|
+
__wbg_isSafeInteger_ea83862ba994770c: function(arg0) {
|
|
275
275
|
const ret = Number.isSafeInteger(arg0);
|
|
276
276
|
return ret;
|
|
277
277
|
},
|
|
278
|
-
|
|
278
|
+
__wbg_iterator_de403ef31815a3e6: function() {
|
|
279
279
|
const ret = Symbol.iterator;
|
|
280
280
|
return ret;
|
|
281
281
|
},
|
|
282
|
-
|
|
282
|
+
__wbg_length_0c32cb8543c8e4c8: function(arg0) {
|
|
283
283
|
const ret = arg0.length;
|
|
284
284
|
return ret;
|
|
285
285
|
},
|
|
286
|
-
|
|
286
|
+
__wbg_length_6e821edde497a532: function(arg0) {
|
|
287
287
|
const ret = arg0.length;
|
|
288
288
|
return ret;
|
|
289
289
|
},
|
|
290
|
-
|
|
291
|
-
const ret = new
|
|
290
|
+
__wbg_new_4f9fafbb3909af72: function() {
|
|
291
|
+
const ret = new Object();
|
|
292
292
|
return ret;
|
|
293
293
|
},
|
|
294
|
-
|
|
295
|
-
const ret = new
|
|
294
|
+
__wbg_new_99cabae501c0a8a0: function() {
|
|
295
|
+
const ret = new Map();
|
|
296
296
|
return ret;
|
|
297
297
|
},
|
|
298
|
-
|
|
299
|
-
const ret = new
|
|
298
|
+
__wbg_new_a560378ea1240b14: function(arg0) {
|
|
299
|
+
const ret = new Uint8Array(arg0);
|
|
300
300
|
return ret;
|
|
301
301
|
},
|
|
302
|
-
|
|
303
|
-
const ret = new
|
|
302
|
+
__wbg_new_e3b04b4d53d1b593: function(arg0, arg1) {
|
|
303
|
+
const ret = new Error(getStringFromWasm0(arg0, arg1));
|
|
304
304
|
return ret;
|
|
305
305
|
},
|
|
306
|
-
|
|
307
|
-
const ret = new
|
|
306
|
+
__wbg_new_f3c9df4f38f3f798: function() {
|
|
307
|
+
const ret = new Array();
|
|
308
308
|
return ret;
|
|
309
309
|
},
|
|
310
|
-
|
|
310
|
+
__wbg_new_typed_14d7cc391ce53d2c: function(arg0, arg1) {
|
|
311
311
|
try {
|
|
312
312
|
var state0 = {a: arg0, b: arg1};
|
|
313
313
|
var cb0 = (arg0, arg1) => {
|
|
314
314
|
const a = state0.a;
|
|
315
315
|
state0.a = 0;
|
|
316
316
|
try {
|
|
317
|
-
return
|
|
317
|
+
return wasm_bindgen__convert__closures_____invoke__h05acb8c479b21d4b(a, state0.b, arg0, arg1);
|
|
318
318
|
} finally {
|
|
319
319
|
state0.a = a;
|
|
320
320
|
}
|
|
@@ -322,80 +322,80 @@ function __wbg_get_imports() {
|
|
|
322
322
|
const ret = new Promise(cb0);
|
|
323
323
|
return ret;
|
|
324
324
|
} finally {
|
|
325
|
-
state0.a =
|
|
325
|
+
state0.a = 0;
|
|
326
326
|
}
|
|
327
327
|
},
|
|
328
|
-
|
|
329
|
-
const ret = arg0.next();
|
|
330
|
-
return ret;
|
|
331
|
-
}, arguments); },
|
|
332
|
-
__wbg_next_e01a967809d1aa68: function(arg0) {
|
|
328
|
+
__wbg_next_01132ed6134b8ef5: function(arg0) {
|
|
333
329
|
const ret = arg0.next;
|
|
334
330
|
return ret;
|
|
335
331
|
},
|
|
336
|
-
|
|
332
|
+
__wbg_next_b3713ec761a9dbfd: function() { return handleError(function (arg0) {
|
|
333
|
+
const ret = arg0.next();
|
|
334
|
+
return ret;
|
|
335
|
+
}, arguments); },
|
|
336
|
+
__wbg_prototypesetcall_3e05eb9545565046: function(arg0, arg1, arg2) {
|
|
337
337
|
Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);
|
|
338
338
|
},
|
|
339
|
-
|
|
339
|
+
__wbg_push_6bdbc990be5ac37b: function(arg0, arg1) {
|
|
340
340
|
const ret = arg0.push(arg1);
|
|
341
341
|
return ret;
|
|
342
342
|
},
|
|
343
|
-
|
|
343
|
+
__wbg_queueMicrotask_abaf92f0bd4e80a4: function(arg0) {
|
|
344
344
|
const ret = arg0.queueMicrotask;
|
|
345
345
|
return ret;
|
|
346
346
|
},
|
|
347
|
-
|
|
347
|
+
__wbg_queueMicrotask_df5a6dac26d818f3: function(arg0) {
|
|
348
348
|
queueMicrotask(arg0);
|
|
349
349
|
},
|
|
350
|
-
|
|
350
|
+
__wbg_resolve_0a79de24e9d2267b: function(arg0) {
|
|
351
351
|
const ret = Promise.resolve(arg0);
|
|
352
352
|
return ret;
|
|
353
353
|
},
|
|
354
|
-
|
|
355
|
-
|
|
354
|
+
__wbg_set_08463b1df38a7e29: function(arg0, arg1, arg2) {
|
|
355
|
+
const ret = arg0.set(arg1, arg2);
|
|
356
|
+
return ret;
|
|
356
357
|
},
|
|
357
358
|
__wbg_set_6be42768c690e380: function(arg0, arg1, arg2) {
|
|
358
359
|
arg0[arg1] = arg2;
|
|
359
360
|
},
|
|
360
|
-
|
|
361
|
+
__wbg_set_6c60b2e8ad0e9383: function(arg0, arg1, arg2) {
|
|
362
|
+
arg0[arg1 >>> 0] = arg2;
|
|
363
|
+
},
|
|
364
|
+
__wbg_set_8ee2d34facb8466e: function() { return handleError(function (arg0, arg1, arg2) {
|
|
361
365
|
const ret = Reflect.set(arg0, arg1, arg2);
|
|
362
366
|
return ret;
|
|
363
367
|
}, arguments); },
|
|
364
|
-
|
|
365
|
-
const ret =
|
|
366
|
-
return ret;
|
|
367
|
-
},
|
|
368
|
-
__wbg_static_accessor_GLOBAL_8adb955bd33fac2f: function() {
|
|
369
|
-
const ret = typeof global === 'undefined' ? null : global;
|
|
368
|
+
__wbg_static_accessor_GLOBAL_THIS_a1248013d790bf5f: function() {
|
|
369
|
+
const ret = typeof globalThis === 'undefined' ? null : globalThis;
|
|
370
370
|
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
371
371
|
},
|
|
372
|
-
|
|
373
|
-
const ret = typeof
|
|
372
|
+
__wbg_static_accessor_GLOBAL_f2e0f995a21329ff: function() {
|
|
373
|
+
const ret = typeof global === 'undefined' ? null : global;
|
|
374
374
|
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
375
375
|
},
|
|
376
|
-
|
|
376
|
+
__wbg_static_accessor_SELF_24f78b6d23f286ea: function() {
|
|
377
377
|
const ret = typeof self === 'undefined' ? null : self;
|
|
378
378
|
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
379
379
|
},
|
|
380
|
-
|
|
380
|
+
__wbg_static_accessor_WINDOW_59fd959c540fe405: function() {
|
|
381
381
|
const ret = typeof window === 'undefined' ? null : window;
|
|
382
382
|
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
383
383
|
},
|
|
384
|
-
|
|
385
|
-
const ret = arg0.then(arg1);
|
|
384
|
+
__wbg_then_00eed3ac0b8e82cb: function(arg0, arg1, arg2) {
|
|
385
|
+
const ret = arg0.then(arg1, arg2);
|
|
386
386
|
return ret;
|
|
387
387
|
},
|
|
388
|
-
|
|
389
|
-
const ret = arg0.then(arg1
|
|
388
|
+
__wbg_then_a0c8db0381c8994c: function(arg0, arg1) {
|
|
389
|
+
const ret = arg0.then(arg1);
|
|
390
390
|
return ret;
|
|
391
391
|
},
|
|
392
|
-
|
|
392
|
+
__wbg_value_7f6052747ccf940f: function(arg0) {
|
|
393
393
|
const ret = arg0.value;
|
|
394
394
|
return ret;
|
|
395
395
|
},
|
|
396
396
|
__wbindgen_cast_0000000000000001: function(arg0, arg1) {
|
|
397
|
-
// Cast intrinsic for `Closure(Closure {
|
|
398
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
397
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 146, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
|
398
|
+
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h9f53f643b01d7c8e);
|
|
399
399
|
return ret;
|
|
400
400
|
},
|
|
401
401
|
__wbindgen_cast_0000000000000002: function(arg0) {
|
|
@@ -434,15 +434,15 @@ function __wbg_get_imports() {
|
|
|
434
434
|
};
|
|
435
435
|
}
|
|
436
436
|
|
|
437
|
-
function
|
|
438
|
-
const ret = wasm.
|
|
437
|
+
function wasm_bindgen__convert__closures_____invoke__h9f53f643b01d7c8e(arg0, arg1, arg2) {
|
|
438
|
+
const ret = wasm.wasm_bindgen__convert__closures_____invoke__h9f53f643b01d7c8e(arg0, arg1, arg2);
|
|
439
439
|
if (ret[1]) {
|
|
440
440
|
throw takeFromExternrefTable0(ret[0]);
|
|
441
441
|
}
|
|
442
442
|
}
|
|
443
443
|
|
|
444
|
-
function
|
|
445
|
-
wasm.
|
|
444
|
+
function wasm_bindgen__convert__closures_____invoke__h05acb8c479b21d4b(arg0, arg1, arg2, arg3) {
|
|
445
|
+
wasm.wasm_bindgen__convert__closures_____invoke__h05acb8c479b21d4b(arg0, arg1, arg2, arg3);
|
|
446
446
|
}
|
|
447
447
|
|
|
448
448
|
const WasmClientFinalization = (typeof FinalizationRegistry === 'undefined')
|
|
@@ -457,7 +457,7 @@ function addToExternrefTable0(obj) {
|
|
|
457
457
|
|
|
458
458
|
const CLOSURE_DTORS = (typeof FinalizationRegistry === 'undefined')
|
|
459
459
|
? { register: () => {}, unregister: () => {} }
|
|
460
|
-
: new FinalizationRegistry(state =>
|
|
460
|
+
: new FinalizationRegistry(state => wasm.__wbindgen_destroy_closure(state.a, state.b));
|
|
461
461
|
|
|
462
462
|
function debugString(val) {
|
|
463
463
|
// primitive types
|
|
@@ -563,8 +563,8 @@ function isLikeNone(x) {
|
|
|
563
563
|
return x === undefined || x === null;
|
|
564
564
|
}
|
|
565
565
|
|
|
566
|
-
function makeMutClosure(arg0, arg1,
|
|
567
|
-
const state = { a: arg0, b: arg1, cnt: 1
|
|
566
|
+
function makeMutClosure(arg0, arg1, f) {
|
|
567
|
+
const state = { a: arg0, b: arg1, cnt: 1 };
|
|
568
568
|
const real = (...args) => {
|
|
569
569
|
|
|
570
570
|
// First up with a closure we increment the internal reference
|
|
@@ -582,7 +582,7 @@ function makeMutClosure(arg0, arg1, dtor, f) {
|
|
|
582
582
|
};
|
|
583
583
|
real._wbg_cb_unref = () => {
|
|
584
584
|
if (--state.cnt === 0) {
|
|
585
|
-
|
|
585
|
+
wasm.__wbindgen_destroy_closure(state.a, state.b);
|
|
586
586
|
state.a = 0;
|
|
587
587
|
CLOSURE_DTORS.unregister(state);
|
|
588
588
|
}
|
|
Binary file
|
|
@@ -9,13 +9,13 @@ export const wasmclient_new: (a: number, b: number, c: any) => [number, number,
|
|
|
9
9
|
export const wasmclient_runWorkflowYaml: (a: number, b: number, c: number, d: any) => [number, number, number];
|
|
10
10
|
export const wasmclient_runWorkflowYamlString: (a: number, b: number, c: number, d: any, e: number) => any;
|
|
11
11
|
export const wasmclient_streamEvents: (a: number, b: number, c: number, d: any, e: any, f: number) => any;
|
|
12
|
-
export const
|
|
13
|
-
export const
|
|
14
|
-
export const wasm_bindgen__convert__closures_____invoke__h133df7605c346924: (a: number, b: number, c: any, d: any) => void;
|
|
12
|
+
export const wasm_bindgen__convert__closures_____invoke__h9f53f643b01d7c8e: (a: number, b: number, c: any) => [number, number];
|
|
13
|
+
export const wasm_bindgen__convert__closures_____invoke__h05acb8c479b21d4b: (a: number, b: number, c: any, d: any) => void;
|
|
15
14
|
export const __wbindgen_malloc: (a: number, b: number) => number;
|
|
16
15
|
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
17
16
|
export const __wbindgen_exn_store: (a: number) => void;
|
|
18
17
|
export const __externref_table_alloc: () => number;
|
|
19
18
|
export const __wbindgen_externrefs: WebAssembly.Table;
|
|
19
|
+
export const __wbindgen_destroy_closure: (a: number, b: number) => void;
|
|
20
20
|
export const __externref_table_dealloc: (a: number) => void;
|
|
21
21
|
export const __wbindgen_start: () => void;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
let rustModulePromise;
|
|
2
|
+
|
|
3
|
+
export async function loadRustModule() {
|
|
4
|
+
if (!rustModulePromise) {
|
|
5
|
+
rustModulePromise = (async () => {
|
|
6
|
+
try {
|
|
7
|
+
const moduleValue = await import("../pkg/simple_agents_wasm.js");
|
|
8
|
+
const wasmUrl = new URL("../pkg/simple_agents_wasm_bg.wasm", import.meta.url);
|
|
9
|
+
await moduleValue.default({ module_or_path: wasmUrl });
|
|
10
|
+
return moduleValue;
|
|
11
|
+
} catch (error) {
|
|
12
|
+
console.debug("[simple-agents-wasm] Rust module unavailable, falling back to JS runtime", error);
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
})();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return rustModulePromise;
|
|
19
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { runtimeError } from "./errors.js";
|
|
2
|
+
|
|
3
|
+
export function createStreamAggregator(model) {
|
|
4
|
+
return {
|
|
5
|
+
responseId: "",
|
|
6
|
+
responseModel: model,
|
|
7
|
+
aggregate: "",
|
|
8
|
+
finishReason: undefined
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function applyDeltaToAggregate(state, delta) {
|
|
13
|
+
if (!state || !delta) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (!state.responseId && delta.id) {
|
|
18
|
+
state.responseId = delta.id;
|
|
19
|
+
}
|
|
20
|
+
if (delta.model) {
|
|
21
|
+
state.responseModel = delta.model;
|
|
22
|
+
}
|
|
23
|
+
if (delta.content) {
|
|
24
|
+
state.aggregate += delta.content;
|
|
25
|
+
}
|
|
26
|
+
if (delta.finishReason) {
|
|
27
|
+
state.finishReason = delta.finishReason;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function createStreamEventBridge(model, onChunk) {
|
|
32
|
+
const aggregateState = createStreamAggregator(model);
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
onEvent(event) {
|
|
36
|
+
if (event.eventType === "delta") {
|
|
37
|
+
const delta = event.delta;
|
|
38
|
+
if (!delta) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
applyDeltaToAggregate(aggregateState, delta);
|
|
43
|
+
|
|
44
|
+
onChunk({
|
|
45
|
+
id: delta.id,
|
|
46
|
+
model: delta.model,
|
|
47
|
+
content: delta.content,
|
|
48
|
+
finishReason: delta.finishReason,
|
|
49
|
+
raw: delta.raw
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (event.eventType === "error") {
|
|
54
|
+
onChunk({
|
|
55
|
+
id: aggregateState.responseId || "error",
|
|
56
|
+
model: aggregateState.responseModel,
|
|
57
|
+
error: event.error?.message ?? "stream error"
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
mergeResult(result, started) {
|
|
62
|
+
return {
|
|
63
|
+
...result,
|
|
64
|
+
id: result.id || aggregateState.responseId,
|
|
65
|
+
model: result.model || aggregateState.responseModel,
|
|
66
|
+
content: result.content ?? aggregateState.aggregate,
|
|
67
|
+
finishReason: result.finishReason ?? aggregateState.finishReason,
|
|
68
|
+
latencyMs: Math.max(0, Math.round(performance.now() - started))
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function normalizeSseChunk(chunk) {
|
|
75
|
+
return chunk.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function parseSseEventBlock(block) {
|
|
79
|
+
const lines = block.split("\n");
|
|
80
|
+
const dataLines = [];
|
|
81
|
+
for (const line of lines) {
|
|
82
|
+
if (line.startsWith("data:")) {
|
|
83
|
+
dataLines.push(line.slice(5).trimStart());
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (dataLines.length === 0) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const payload = dataLines.join("\n");
|
|
92
|
+
if (payload === "[DONE]") {
|
|
93
|
+
return { done: true };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
return { done: false, json: JSON.parse(payload), raw: payload };
|
|
98
|
+
} catch {
|
|
99
|
+
return { done: false, raw: payload };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export async function* iterateSse(response) {
|
|
104
|
+
if (!response.body) {
|
|
105
|
+
throw runtimeError("stream response had no body");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const reader = response.body.getReader();
|
|
109
|
+
const decoder = new TextDecoder();
|
|
110
|
+
let buffer = "";
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
while (true) {
|
|
114
|
+
const { value, done } = await reader.read();
|
|
115
|
+
if (done) {
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
buffer += normalizeSseChunk(decoder.decode(value, { stream: true }));
|
|
120
|
+
let delimiterIndex = buffer.indexOf("\n\n");
|
|
121
|
+
while (delimiterIndex !== -1) {
|
|
122
|
+
const block = buffer.slice(0, delimiterIndex).trim();
|
|
123
|
+
buffer = buffer.slice(delimiterIndex + 2);
|
|
124
|
+
if (block.length > 0) {
|
|
125
|
+
yield block;
|
|
126
|
+
}
|
|
127
|
+
delimiterIndex = buffer.indexOf("\n\n");
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
buffer += normalizeSseChunk(decoder.decode());
|
|
132
|
+
|
|
133
|
+
const trailing = buffer.trim();
|
|
134
|
+
if (trailing.length > 0) {
|
|
135
|
+
yield trailing;
|
|
136
|
+
}
|
|
137
|
+
} finally {
|
|
138
|
+
reader.releaseLock();
|
|
139
|
+
}
|
|
140
|
+
}
|