@flaxia/node 0.3.7 → 0.5.0

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 (93) hide show
  1. package/README.md +43 -19
  2. package/dist/__tests__/consent-policy.test.d.ts +2 -0
  3. package/dist/__tests__/consent-policy.test.d.ts.map +1 -0
  4. package/dist/assets/VectorStoreEngine.js +140 -85
  5. package/dist/assets/ai-inference.js +173 -33
  6. package/dist/assets/container.js +368 -260
  7. package/dist/assets/dist.js +209 -0
  8. package/dist/assets/egress-guard.js +174 -0
  9. package/dist/assets/image-process.js +184 -19
  10. package/dist/assets/nudenet.js +2 -2
  11. package/dist/client/SignalingClient.d.ts +6 -0
  12. package/dist/client/SignalingClient.d.ts.map +1 -1
  13. package/dist/consent/ConsentUI.d.ts +44 -5
  14. package/dist/consent/ConsentUI.d.ts.map +1 -1
  15. package/dist/consent/notice.d.ts +29 -0
  16. package/dist/consent/notice.d.ts.map +1 -0
  17. package/dist/consent/storage.d.ts +91 -7
  18. package/dist/consent/storage.d.ts.map +1 -1
  19. package/dist/executor/WorkerPool.d.ts +35 -1
  20. package/dist/executor/WorkerPool.d.ts.map +1 -1
  21. package/dist/executor/__tests__/WorkerPool.swarm.test.d.ts +13 -0
  22. package/dist/executor/__tests__/WorkerPool.swarm.test.d.ts.map +1 -0
  23. package/dist/executor/__tests__/container-executor.test.d.ts +2 -0
  24. package/dist/executor/__tests__/container-executor.test.d.ts.map +1 -0
  25. package/dist/executor/__tests__/egress-guard.test.d.ts +2 -0
  26. package/dist/executor/__tests__/egress-guard.test.d.ts.map +1 -0
  27. package/dist/executor/__tests__/webgpuProbe.test.d.ts +2 -0
  28. package/dist/executor/__tests__/webgpuProbe.test.d.ts.map +1 -0
  29. package/dist/executor/container-executor.d.ts +49 -1
  30. package/dist/executor/container-executor.d.ts.map +1 -1
  31. package/dist/executor/egress-guard.d.ts +105 -0
  32. package/dist/executor/egress-guard.d.ts.map +1 -0
  33. package/dist/executor/memoryProbe.d.ts +25 -0
  34. package/dist/executor/memoryProbe.d.ts.map +1 -1
  35. package/dist/executor/throttle.d.ts +62 -4
  36. package/dist/executor/throttle.d.ts.map +1 -1
  37. package/dist/executor/webgpuProbe.d.ts +9 -0
  38. package/dist/executor/webgpuProbe.d.ts.map +1 -0
  39. package/dist/index.d.ts +2 -0
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +766 -230
  42. package/dist/swarm/__tests__/adapter.test.d.ts +2 -0
  43. package/dist/swarm/__tests__/adapter.test.d.ts.map +1 -0
  44. package/dist/swarm/__tests__/controller.test.d.ts +2 -0
  45. package/dist/swarm/__tests__/controller.test.d.ts.map +1 -0
  46. package/dist/swarm/__tests__/defects.test.d.ts +16 -0
  47. package/dist/swarm/__tests__/defects.test.d.ts.map +1 -0
  48. package/dist/swarm/__tests__/hardening.test.d.ts +2 -0
  49. package/dist/swarm/__tests__/hardening.test.d.ts.map +1 -0
  50. package/dist/swarm/__tests__/runtime.test.d.ts +2 -0
  51. package/dist/swarm/__tests__/runtime.test.d.ts.map +1 -0
  52. package/dist/swarm/__tests__/session.test.d.ts +2 -0
  53. package/dist/swarm/__tests__/session.test.d.ts.map +1 -0
  54. package/dist/swarm/adapter.d.ts +115 -0
  55. package/dist/swarm/adapter.d.ts.map +1 -0
  56. package/dist/swarm/controller.d.ts +87 -0
  57. package/dist/swarm/controller.d.ts.map +1 -0
  58. package/dist/swarm/messages.d.ts +41 -0
  59. package/dist/swarm/messages.d.ts.map +1 -0
  60. package/dist/swarm/runtime.d.ts +16 -0
  61. package/dist/swarm/runtime.d.ts.map +1 -0
  62. package/dist/swarm/session.d.ts +73 -0
  63. package/dist/swarm/session.d.ts.map +1 -0
  64. package/dist/swarm-engine.js +7477 -0
  65. package/dist/vector-store/HNSWIndex.d.ts +30 -0
  66. package/dist/vector-store/HNSWIndex.d.ts.map +1 -1
  67. package/dist/vector-store/VectorStoreEngine.d.ts +43 -0
  68. package/dist/vector-store/VectorStoreEngine.d.ts.map +1 -1
  69. package/dist/vector-store/__tests__/HNSWIndex.test.d.ts +2 -0
  70. package/dist/vector-store/__tests__/HNSWIndex.test.d.ts.map +1 -0
  71. package/dist/vector-store/__tests__/VectorStoreEngine.test.d.ts +2 -0
  72. package/dist/vector-store/__tests__/VectorStoreEngine.test.d.ts.map +1 -0
  73. package/dist/worker/__tests__/main.worker.abort.test.d.ts +2 -0
  74. package/dist/worker/__tests__/main.worker.abort.test.d.ts.map +1 -0
  75. package/dist/worker/__tests__/main.worker.control.test.d.ts +2 -0
  76. package/dist/worker/__tests__/main.worker.control.test.d.ts.map +1 -0
  77. package/dist/worker.js +643 -67
  78. package/dist/workloads/__tests__/nudenet.test.d.ts +2 -0
  79. package/dist/workloads/__tests__/nudenet.test.d.ts.map +1 -0
  80. package/dist/workloads/ai-inference.d.ts +2 -1
  81. package/dist/workloads/ai-inference.d.ts.map +1 -1
  82. package/dist/workloads/ai-model-registry.d.ts +72 -0
  83. package/dist/workloads/ai-model-registry.d.ts.map +1 -0
  84. package/dist/workloads/container.d.ts +1 -1
  85. package/dist/workloads/container.d.ts.map +1 -1
  86. package/dist/workloads/image-process.d.ts +27 -0
  87. package/dist/workloads/image-process.d.ts.map +1 -1
  88. package/dist/workloads/nudenet.d.ts +8 -0
  89. package/dist/workloads/nudenet.d.ts.map +1 -1
  90. package/package.json +3 -2
  91. package/dist/assets/memoryProbe.js +0 -28
  92. package/dist/client/WebRTCPeer.d.ts +0 -8
  93. package/dist/client/WebRTCPeer.d.ts.map +0 -1
package/dist/worker.js CHANGED
@@ -1,36 +1,55 @@
1
- import { n as e, r as t, t as n } from "./assets/memoryProbe.js";
2
- //#region ../sdk/dist/index.js
3
- var r = new Set([
4
- "ai-inference",
5
- "image-process",
6
- "container",
7
- "vector-embed",
8
- "vector-query",
9
- "nudenet"
10
- ]);
11
- //#endregion
1
+ import { _ as e, a as t, b as n, c as r, g as i, h as a, i as o, l as s, n as c, o as l, s as u, t as d, v as f, x as p, y as m } from "./assets/dist.js";
12
2
  //#region src/executor/throttle.ts
13
- function i(e) {
3
+ function h(e) {
14
4
  return new Promise((t) => setTimeout(t, e));
15
5
  }
16
- var a = 3e4, o = 3e4, s = class {
6
+ var g = 3e4, ee = 500, _ = class extends Error {
7
+ constructor(e, t, n) {
8
+ super(`device is over its CPU budget (load ${e.toFixed(2)} > max ${t.toFixed(2)}) after waiting ${Math.round(n)}ms; task not started`), this.load = e, this.maxLoad = t, this.waitedMs = n, this.retryable = !0, this.name = "ThrottleBusyError";
9
+ }
10
+ }, v = class {
17
11
  constructor(e = .15) {
18
- this.windowStart = performance.now(), this.windowBusyMs = 0, this.lastLoad = 0, this.maxLoad = Math.max(.05, Math.min(.3, e));
12
+ this.windowStart = performance.now(), this.windowBusyMs = 0, this.lastLoad = 0, this.dutyStartedAt = null, this.maxLoad = Math.max(.05, Math.min(.3, e));
19
13
  }
20
14
  markTaskComplete(e) {
21
- let t = performance.now();
22
- t - this.windowStart > a && (this.windowStart = t, this.windowBusyMs = 0), this.windowBusyMs += Math.max(0, e), this.lastLoad = this.estimate();
15
+ this.estimate(this.windowBusyMs + Math.max(0, e)), this.resetDutyCycle();
16
+ }
17
+ beginWork() {
18
+ this.dutyStartedAt = performance.now();
19
+ }
20
+ resetDutyCycle() {
21
+ this.dutyStartedAt = null;
22
+ }
23
+ rollWindow(e) {
24
+ e - this.windowStart > 3e4 && (this.windowStart = e, this.windowBusyMs = 0, this.resetDutyCycle());
23
25
  }
24
- estimate() {
25
- let e = performance.now() - this.windowStart;
26
- return e <= 0 ? 0 : Math.min(1, Math.max(0, this.windowBusyMs / e));
26
+ estimate(e) {
27
+ let t = performance.now();
28
+ this.rollWindow(t), this.windowBusyMs = e;
29
+ let n = t - this.windowStart;
30
+ if (n <= 0) return 0;
31
+ let r = e / n;
32
+ return this.lastLoad = Math.min(1, Math.max(0, r)), this.lastLoad;
27
33
  }
28
34
  async shouldPause() {
29
- return this.estimate() > this.maxLoad;
35
+ return this.rollWindow(performance.now()), this.estimate(this.windowBusyMs) > this.maxLoad;
30
36
  }
31
- async waitForSlot(e = o) {
37
+ async waitForSlot(e = g) {
38
+ if (!Number.isFinite(e) || e < 0) throw Error(`waitForSlot: maxWaitMs must be a non-negative number, got ${String(e)}`);
32
39
  let t = performance.now();
33
- for (; await this.shouldPause() && !(performance.now() - t > e);) await i(500);
40
+ for (; await this.shouldPause();) {
41
+ let n = performance.now() - t;
42
+ if (n >= e) throw new _(this.lastLoad, this.maxLoad, n);
43
+ await h(Math.min(ee, Math.max(1, e - n)));
44
+ }
45
+ }
46
+ async yieldIfOverloaded() {
47
+ let e = performance.now();
48
+ this.rollWindow(e), this.dutyStartedAt === null && (this.dutyStartedAt = e);
49
+ let t = Math.max(0, e - this.dutyStartedAt);
50
+ if (t < 200) return 0;
51
+ let n = Math.ceil(t * (1 / this.maxLoad - 1));
52
+ return this.dutyStartedAt = null, n > 0 && await h(n), this.estimate(this.windowBusyMs), n;
34
53
  }
35
54
  get lastMeasuredLoad() {
36
55
  return this.lastLoad;
@@ -38,80 +57,637 @@ var a = 3e4, o = 3e4, s = class {
38
57
  get maxLoadValue() {
39
58
  return this.maxLoad;
40
59
  }
41
- }, c = null, l = 6e4, u = t(), d = u >= n;
42
- console.log(`[flaxia-node:worker] startup memory probe wasmMemoryBytes=${u} capable=${d}`);
43
- function f() {
44
- return e();
60
+ }, y = 4096;
61
+ function b(e) {
62
+ let t = e.maxSeq;
63
+ return typeof t == "number" && Number.isInteger(t) && t > 0 ? t : y;
64
+ }
65
+ function x(e, t, n) {
66
+ let { pos: r, tokens: i } = e.header, a = b(t);
67
+ if (!Number.isInteger(i) || i < 1) return {
68
+ kind: "corrupt",
69
+ reason: `carried ${i} token columns`
70
+ };
71
+ if (!Number.isInteger(r) || r < 0 || r + i > a) return {
72
+ kind: "corrupt",
73
+ reason: `position ${r}+${i} is outside the ${a}-token context`
74
+ };
75
+ let o;
76
+ try {
77
+ o = n.unpackHidden(e.payload);
78
+ } catch (e) {
79
+ return {
80
+ kind: "corrupt",
81
+ reason: e instanceof Error ? e.message : String(e)
82
+ };
83
+ }
84
+ let s = t.dim * i;
85
+ if (o.length !== s) return {
86
+ kind: "corrupt",
87
+ reason: `carried ${o.length} values, expected ${s}`
88
+ };
89
+ for (let e = 0; e < o.length; e++) if (!Number.isFinite(o[e])) return {
90
+ kind: "corrupt",
91
+ reason: `carried a non-finite value at index ${e}`
92
+ };
93
+ return {
94
+ kind: "ok",
95
+ hidden: o
96
+ };
97
+ }
98
+ function te(e, t, n, r) {
99
+ let i = s(e);
100
+ return i ? i.header.pos !== t || i.header.requestId !== t ? { kind: "stale" } : x(i, n, r) : {
101
+ kind: "corrupt",
102
+ reason: "malformed frame header"
103
+ };
104
+ }
105
+ async function ne(t) {
106
+ let { engine: n, link: i, semantics: o, promptTokens: s, chainLength: c, maxNewTokens: l } = t;
107
+ if (s.length === 0) throw Error("swarm host requires at least one prompt token");
108
+ n.reset();
109
+ let u = null;
110
+ i.onFrame((t) => {
111
+ if (e(t)) return;
112
+ let r = u;
113
+ if (!r) return;
114
+ let i = te(t, r.pos, n, o);
115
+ if (i.kind !== "stale") {
116
+ if (u = null, i.kind === "corrupt") {
117
+ r.reject(/* @__PURE__ */ Error(`swarm hop failed: ${i.reason}`));
118
+ return;
119
+ }
120
+ r.resolve(i.hidden);
121
+ }
122
+ });
123
+ let d = (e, t) => c <= 1 ? Promise.resolve(e) : new Promise((n, a) => {
124
+ u = {
125
+ pos: t,
126
+ resolve: n,
127
+ reject: a
128
+ }, i.send(r({
129
+ requestId: t,
130
+ pos: t,
131
+ tokens: 1
132
+ }, o.packHidden(e)));
133
+ }), f = async (e, t) => d(await n.embedRun(e, t), t), p = null;
134
+ for (let e = 0; e < s.length; e++) {
135
+ let t = await f(s[e], e);
136
+ e === s.length - 1 && (p = await n.headFromHidden(t));
137
+ }
138
+ if (!p) throw Error("swarm host produced no logits for the prompt");
139
+ let m = [], h = s.length, g = o.argmax(p);
140
+ for (; m.length < l && !(t.eosIds?.has(g) || (m.push(g), await t.onToken?.(g), m.length >= l));) {
141
+ let e = await f(g, h++);
142
+ p = await n.headFromHidden(e), g = o.argmax(p);
143
+ }
144
+ return c > 1 && i.send(a()), { tokens: m };
145
+ }
146
+ function re(t) {
147
+ let { engine: n, link: i, semantics: a } = t;
148
+ return n.reset(), new Promise((t, o) => {
149
+ let c = Promise.resolve(), l = !1;
150
+ i.onFrame((u) => {
151
+ if (!l) {
152
+ if (e(u)) {
153
+ l = !0, i.send(u), c = c.then(() => t());
154
+ return;
155
+ }
156
+ c = c.then(async () => {
157
+ if (l) return;
158
+ let e = s(u);
159
+ if (!e) throw Error("swarm frame has a malformed frame header");
160
+ let t = x(e, n, a);
161
+ if (t.kind === "corrupt") throw Error(`swarm frame is unusable: ${t.reason}`);
162
+ let o = await n.runHidden(t.hidden, e.header.pos);
163
+ i.send(r({
164
+ requestId: e.header.requestId,
165
+ pos: e.header.pos,
166
+ tokens: e.header.tokens
167
+ }, a.packHidden(o)));
168
+ }).catch((e) => {
169
+ l = !0, o(e instanceof Error ? e : Error(String(e)));
170
+ });
171
+ }
172
+ });
173
+ });
174
+ }
175
+ //#endregion
176
+ //#region src/swarm/controller.ts
177
+ var S = class {
178
+ constructor(e) {
179
+ this.options = e, this.frameHandler = null, this.engine = null, this.semantics = null, this.sessionId = "", this.model = "", this.chainLength = 1, this.chain = [], this.slice = null, this.hostWarm = void 0, this.prompt = "", this.maxNewTokens = 128, this.sliceLoaded = !1, this.generationStarted = !1, this.settled = !1;
180
+ }
181
+ async start() {
182
+ if (this.settled) return;
183
+ let e = this.options.initial;
184
+ try {
185
+ if (e.type === "swarm-init") {
186
+ if (this.sessionId = e.sessionId, this.model = e.model, !Array.isArray(e.members) || e.members.length < 1 || e.members.length > 16) throw Error(`swarm-init has an invalid member count: ${JSON.stringify(e.members?.length)}`);
187
+ this.chainLength = e.members.length, this.prompt = e.prompt, e.maxNewTokens !== void 0 && (this.maxNewTokens = e.maxNewTokens);
188
+ let t = await this.options.runtime.plan(e.members, e.model);
189
+ this.chain = t, this.options.sendControl({
190
+ type: "swarm-plan",
191
+ sessionId: e.sessionId,
192
+ chain: t
193
+ });
194
+ return;
195
+ }
196
+ await this.loadSlice(e);
197
+ } catch (e) {
198
+ this.fail(e);
199
+ }
200
+ }
201
+ async handleControl(e) {
202
+ if (!this.settled && e.sessionId === this.sessionId) try {
203
+ e.type === "swarm-slice" ? await this.loadSlice(e) : e.type === "swarm-start" ? await this.startHost() : e.type === "swarm-error" && this.fail(Error(e.error || "swarm session aborted by the coordinator"));
204
+ } catch (e) {
205
+ this.fail(e);
206
+ }
207
+ }
208
+ handleFrame(e) {
209
+ this.settled || this.frameHandler?.(e);
210
+ }
211
+ abort(e) {
212
+ this.fail(Error(e));
213
+ }
214
+ link() {
215
+ return {
216
+ send: (e) => this.options.sendFrame(e),
217
+ onFrame: (e) => {
218
+ this.frameHandler = e;
219
+ }
220
+ };
221
+ }
222
+ validateSlice(e) {
223
+ if (!Number.isInteger(e.chainLength) || e.chainLength < 1 || e.chainLength > 16) throw Error(`swarm slice has an invalid chain length: ${JSON.stringify(e.chainLength)}`);
224
+ if (!Number.isInteger(e.index) || e.index < 0 || e.index >= e.chainLength) throw Error(`swarm slice has an invalid index: ${JSON.stringify(e.index)}`);
225
+ if (e.role !== (e.index === 0 ? "host" : "worker")) throw Error(`swarm slice role ${e.role} does not match index ${e.index}`);
226
+ if (!l(e.slice)) throw Error(`swarm slice is out of bounds: ${JSON.stringify(e.slice)}`);
227
+ let t = e.index === 0;
228
+ if (e.slice.hasEmbed !== t || e.slice.hasHead !== t) throw Error("swarm slice embed/head ownership does not match the host position");
229
+ }
230
+ async loadSlice(e) {
231
+ if (this.settled || this.sliceLoaded) return;
232
+ this.validateSlice(e), this.sessionId = e.sessionId, this.model = e.model, this.chainLength = e.chainLength, this.slice = e.slice;
233
+ let { engine: t, semantics: n, warm: r } = await this.options.runtime.load(e.slice, e.model);
234
+ if (this.settled) {
235
+ t.dispose();
236
+ return;
237
+ }
238
+ this.engine = t, this.semantics = n, this.hostWarm = r, this.sliceLoaded = !0, this.options.sendControl({
239
+ type: "swarm-ready",
240
+ sessionId: e.sessionId
241
+ }), e.role === "worker" && (this.generationStarted = !0, re({
242
+ engine: t,
243
+ link: this.link(),
244
+ semantics: n
245
+ }).then(() => this.finish(C())).catch((e) => this.fail(e)));
246
+ }
247
+ async startHost() {
248
+ if (this.generationStarted) return;
249
+ let e = this.engine, t = this.semantics;
250
+ if (!e || !t) throw Error("swarm host received start before loading its slice");
251
+ if (!t.encodePrompt || !t.decodeTokens) throw Error("host semantics must provide encodePrompt and decodeTokens");
252
+ let n = this.maxNewTokens;
253
+ if (!Number.isInteger(n) || n < 1) throw Error(`swarm maxNewTokens must be a positive integer, got ${JSON.stringify(n)}`);
254
+ let r = t.encodePrompt(this.prompt), i = e.maxSeq ?? 4096;
255
+ if (r.length + n > i) throw Error(`swarm request needs ${r.length + n} tokens but the model context holds ${i}`);
256
+ this.generationStarted = !0;
257
+ let a = performance.now(), { tokens: o } = await ne({
258
+ chainLength: this.chainLength,
259
+ promptTokens: r,
260
+ maxNewTokens: n,
261
+ engine: e,
262
+ link: this.link(),
263
+ semantics: t,
264
+ eosIds: t.eosIds,
265
+ onToken: (e) => this.options.emitToken(t.decodeTokens([e]))
266
+ }), s = t.decodeTokens;
267
+ this.finish({
268
+ output: s(o),
269
+ tokens: o.map((e) => s([e])),
270
+ nodes: this.nodeInfos(),
271
+ durationMs: Math.round(performance.now() - a)
272
+ });
273
+ }
274
+ nodeInfos() {
275
+ return (this.chain.length > 0 ? this.chain.map((e) => ({
276
+ slice: e.slice,
277
+ host: e.role === "host"
278
+ })) : this.slice ? [{
279
+ slice: this.slice,
280
+ host: !0
281
+ }] : []).map((e) => {
282
+ let t = {
283
+ layers: [e.slice.start, e.slice.end],
284
+ host: e.host
285
+ };
286
+ return e.host && this.hostWarm !== void 0 && (t.warm = this.hostWarm), t;
287
+ });
288
+ }
289
+ teardown() {
290
+ this.frameHandler = null;
291
+ let e = this.engine;
292
+ if (this.engine = null, this.semantics = null, e) try {
293
+ e.dispose();
294
+ } catch {}
295
+ }
296
+ finish(e) {
297
+ this.settled || (this.settled = !0, this.teardown(), this.options.onDone(e));
298
+ }
299
+ fail(e) {
300
+ this.settled || (this.settled = !0, this.teardown(), this.options.onError(e instanceof Error ? e.message : String(e)));
301
+ }
302
+ };
303
+ function C() {
304
+ return {
305
+ output: "",
306
+ tokens: [],
307
+ nodes: [],
308
+ durationMs: 0
309
+ };
310
+ }
311
+ //#endregion
312
+ //#region src/swarm/adapter.ts
313
+ var w = class extends Error {
314
+ constructor(e) {
315
+ super(e), this.name = "SwarmEngineUnavailableError";
316
+ }
317
+ };
318
+ async function T(e, t) {
319
+ if (!(await f()).webgpu) throw new w("WebGPU is not available in this context");
320
+ let n = t ?? ((e) => import(
321
+ /* @vite-ignore */
322
+ e
323
+ )), r;
324
+ try {
325
+ r = await n(e);
326
+ } catch (e) {
327
+ throw new w(`failed to load swarm engine module: ${e instanceof Error ? e.message : String(e)}`);
328
+ }
329
+ let i = r?.Qwen35Engine;
330
+ if (!i || typeof i.create != "function") throw new w(`module at ${e} does not export Qwen35Engine.create`);
331
+ return r;
332
+ }
333
+ function E(e, t) {
334
+ let n = !1;
335
+ return {
336
+ get dim() {
337
+ return e.dims.dim;
338
+ },
339
+ get nc() {
340
+ return e.NC;
341
+ },
342
+ get maxSeq() {
343
+ return e.maxSeq;
344
+ },
345
+ reset: () => e.reset(),
346
+ embedRun: (t, n) => e.embedRun(t, n),
347
+ runHidden: (t, n) => e.runHidden(t, n),
348
+ headFromHidden: (t) => e.headFromHidden(t),
349
+ setHidden: (t) => e.setHidden(t),
350
+ dispose: () => {
351
+ if (!n) {
352
+ n = !0;
353
+ try {
354
+ e.dispose?.();
355
+ } catch {}
356
+ try {
357
+ t?.destroy?.();
358
+ } catch {}
359
+ }
360
+ }
361
+ };
362
+ }
363
+ //#endregion
364
+ //#region src/swarm/runtime.ts
365
+ var D = {
366
+ "qwen3.5-2b": "https://huggingface.co/unsloth/Qwen3.5-2B-GGUF/resolve/main/Qwen3.5-2B-Q4_0.gguf",
367
+ "qwen3.8-27b": "https://huggingface.co/unsloth/Qwen3.8-27B-GGUF/resolve/main/Qwen3.8-27B-Q4_0.gguf",
368
+ "qwen3.6-35b-moe": "https://huggingface.co/bartowski/Qwen_Qwen3.6-35B-A3B-GGUF/resolve/main/Qwen_Qwen3.6-35B-A3B-Q4_0.gguf"
369
+ }, ie = "flaxia-swarm-weights-v1", ae = 12 * 1024 * 1024, O = 256 * 1024 * 1024;
370
+ function oe(e) {
371
+ let t = D[e];
372
+ if (t) return t;
373
+ throw new w(`unknown swarm model: ${e}`);
374
+ }
375
+ var k = null, A = 0, j = 0;
376
+ async function M() {
377
+ if (k !== null) return k;
378
+ try {
379
+ k = typeof caches < "u" ? await caches.open(ie) : !1;
380
+ } catch {
381
+ k = !1;
382
+ }
383
+ return k;
384
+ }
385
+ function N(e, t, n) {
386
+ return `https://flaxia-weights.local/${encodeURIComponent(e)}/${t}-${n}`;
387
+ }
388
+ async function P(e, t, n) {
389
+ let r = await F(e, t, n), i = new Uint8Array(await r.arrayBuffer()), a = n - t + 1;
390
+ if (i.byteLength !== a) throw Error(`short range ${i.byteLength}/${a}`);
391
+ return i;
392
+ }
393
+ async function F(e, t, n) {
394
+ let r = n - t + 1, i = await M(), a = N(e, t, n);
395
+ if (i) try {
396
+ let e = await i.match(a);
397
+ if (e) {
398
+ let t = new Uint8Array(await e.arrayBuffer());
399
+ if (t.byteLength === r) return A++, new Response(t, { status: 200 });
400
+ await i.delete(a).catch(() => {});
401
+ }
402
+ } catch {}
403
+ let o;
404
+ for (let s = 0; s < 4; s++) {
405
+ try {
406
+ let s = await fetch(e, { headers: { Range: `bytes=${t}-${n}` } });
407
+ if (s.status !== 206) o = /* @__PURE__ */ Error(`model host refused range requests (${s.status})`);
408
+ else return j++, i && s.clone().arrayBuffer().then((e) => {
409
+ if (e.byteLength === r) return i.put(a, new Response(e, {
410
+ status: 200,
411
+ headers: { "content-type": "application/octet-stream" }
412
+ }));
413
+ }).catch(() => {}), s;
414
+ } catch (e) {
415
+ o = e;
416
+ }
417
+ await new Promise((e) => setTimeout(e, 150 * (s + 1)));
418
+ }
419
+ throw Error(`range fetch ${t}-${n} failed: ${o instanceof Error ? o.message : String(o)}`);
420
+ }
421
+ async function I(e, t) {
422
+ let n = ae;
423
+ for (;;) {
424
+ let r = await P(t, 0, n - 1), i = r.buffer.slice(r.byteOffset, r.byteOffset + r.byteLength);
425
+ try {
426
+ return e.parseGGUFHeader(i);
427
+ } catch (e) {
428
+ if (n >= O) throw e;
429
+ n = Math.min(n * 2, O);
430
+ }
431
+ }
432
+ }
433
+ async function L() {
434
+ let e = navigator.gpu;
435
+ if (!e) throw new w("WebGPU is not available in this context");
436
+ let t = await e.requestAdapter({ powerPreference: "high-performance" });
437
+ if (!t) throw new w("no WebGPU adapter");
438
+ return t.requestDevice({ requiredLimits: {
439
+ maxBufferSize: t.limits.maxBufferSize,
440
+ maxStorageBufferBindingSize: t.limits.maxStorageBufferBindingSize
441
+ } });
442
+ }
443
+ function R(e, t) {
444
+ let n = t.vocab, r = n["<|im_start|>"], i = n["<|im_end|>"], a = n["<think>"], o = n["</think>"], s = (e) => [
445
+ r,
446
+ ...t.encode("user\n" + e),
447
+ i,
448
+ ...t.encode("\n"),
449
+ r,
450
+ ...t.encode("assistant\n"),
451
+ a,
452
+ ...t.encode("\n\n"),
453
+ o,
454
+ ...t.encode("\n\n")
455
+ ].filter((e) => typeof e == "number" && e >= 0), c = [i, n["<|endoftext|>"]].filter((e) => typeof e == "number");
456
+ return {
457
+ packHidden: (t) => {
458
+ let n = new Uint16Array(t.length);
459
+ for (let r = 0; r < t.length; r++) n[r] = e.f32ToF16(t[r]);
460
+ return new Uint8Array(n.buffer);
461
+ },
462
+ unpackHidden: (t) => {
463
+ let n = t.slice(), r = new Uint16Array(n.buffer), i = new Float32Array(r.length);
464
+ for (let t = 0; t < r.length; t++) i[t] = e.f16ToF32(r[t]);
465
+ return i;
466
+ },
467
+ argmax: (t) => e.argmax(t),
468
+ encodePrompt: (e) => s(Array.isArray(e) ? e.join("\n") : e),
469
+ decodeTokens: (e) => t.decode(e),
470
+ eosIds: new Set(c)
471
+ };
472
+ }
473
+ function z() {
474
+ let e = null, t = null, n = () => {
475
+ if (!e) {
476
+ let t = new URL("./swarm-engine.js", "" + import.meta.url).href;
477
+ e = T(t).then((e) => e);
478
+ }
479
+ return e;
480
+ }, r = async (e) => {
481
+ let r = await n(), i = oe(e);
482
+ (!t || t.url !== i) && (t = {
483
+ url: i,
484
+ gguf: await I(r, i)
485
+ });
486
+ let a = Number(t.gguf.meta["qwen35.block_count"]) - Number(t.gguf.meta["qwen35.nextn_predict_layers"] || 0);
487
+ if (!Number.isInteger(a) || a < 1) throw new w(`model ${e} has no qwen35 trunk layers`);
488
+ return {
489
+ mod: r,
490
+ url: i,
491
+ gguf: t.gguf,
492
+ layers: a
493
+ };
494
+ };
495
+ return {
496
+ async plan(e, t) {
497
+ let { layers: n } = await r(t);
498
+ return d({
499
+ sessionId: "",
500
+ taskId: "",
501
+ model: t,
502
+ layers: n,
503
+ nodes: e.map((e) => ({
504
+ nodeId: e.nodeId,
505
+ capacity: e.capacity
506
+ }))
507
+ }).chain;
508
+ },
509
+ async load(e, t) {
510
+ A = 0, j = 0;
511
+ let { mod: n, url: i, gguf: a } = await r(t), o = await L(), s = n.makeTokenizer(n.tokenizerFromGGUF(a.meta)), c = (e) => P(i, e.byteOffset, e.byteOffset + e.byteLength - 1);
512
+ a.streamEntry = (e) => n.streamEntryToGPU(o, e, (e) => F(i, e.byteOffset, e.byteOffset + e.byteLength - 1), { staging: 4 * 1024 * 1024 });
513
+ let l = await n.qwen35Weights(a, c, {
514
+ lo: e.start,
515
+ hi: e.end,
516
+ hasEmbed: e.hasEmbed,
517
+ hasHead: e.hasHead,
518
+ mtp: e.hasHead
519
+ }, void 0, (e, t) => n.gpuUploadEntry(o, e, t === n.GGML_EMBED)), u = a.tensors[n.GGML_EMBED]?.shape[0] ?? 0, d = await n.Qwen35Engine.create({
520
+ device: o,
521
+ meta: a.meta,
522
+ layerRange: [e.start, e.end],
523
+ hasEmbed: e.hasEmbed,
524
+ hasHead: e.hasHead,
525
+ vocab: u,
526
+ maxSeq: Math.min(y, Number(a.meta["qwen35.context_length"]) || 4096),
527
+ batchCols: 4,
528
+ weights: l
529
+ }), f = A > 0 && j === 0;
530
+ return {
531
+ engine: E(d, o),
532
+ semantics: R(n, s),
533
+ warm: f
534
+ };
535
+ }
536
+ };
537
+ }
538
+ //#endregion
539
+ //#region src/swarm/messages.ts
540
+ function B(e) {
541
+ return o(e) || c(e) || i(e) || t(e);
45
542
  }
46
- var p = /* @__PURE__ */ new Map(), m = null;
47
- function h() {
48
- for (let e of p.values()) try {
543
+ function V(e) {
544
+ if (!e || typeof e != "object") return !1;
545
+ let t = e;
546
+ return t.type === "swarm-control" && typeof t.id == "string" && B(t.message);
547
+ }
548
+ //#endregion
549
+ //#region src/worker/main.worker.ts
550
+ var H = null, U = g, W = 1, G = 15e3, K = /* @__PURE__ */ new Map(), q = null, J = null, Y = null, se = 6e4;
551
+ async function ce() {
552
+ for (let e = 0;; e++) try {
553
+ await H.waitForSlot(U);
554
+ return;
555
+ } catch (t) {
556
+ if (!(t instanceof _)) throw t;
557
+ if (e >= W) throw Error(`device CPU busy: ${t.message}; task not started, retry on an idle node (retryable)`);
558
+ console.warn(`[flaxia-node:worker] ${t.message}; cooling down ${G}ms before retrying`), await new Promise((e) => setTimeout(e, G));
559
+ }
560
+ }
561
+ function le(e) {
562
+ let t = (t) => {
563
+ let n = K.get(e);
564
+ if (n !== void 0) throw Error(n);
565
+ self.postMessage({
566
+ id: e,
567
+ type: "token",
568
+ token: t
569
+ });
570
+ };
571
+ return async (e) => {
572
+ t(e), await H?.yieldIfOverloaded();
573
+ };
574
+ }
575
+ var X = p(), Z = X >= m;
576
+ console.log(`[flaxia-node:worker] startup memory probe wasmMemoryBytes=${X} capable=${Z}`);
577
+ function ue() {
578
+ return n();
579
+ }
580
+ var Q = /* @__PURE__ */ new Map(), $ = null;
581
+ function de() {
582
+ for (let e of Q.values()) try {
49
583
  e();
50
584
  } catch {}
51
- p.clear();
585
+ Q.clear();
52
586
  }
53
- function g() {
54
- m && clearTimeout(m), m = setTimeout(() => {
55
- m = null, h();
56
- }, l);
587
+ function fe() {
588
+ $ && clearTimeout($), $ = setTimeout(() => {
589
+ $ = null, de();
590
+ }, se);
57
591
  }
58
- async function _(e, t, n) {
592
+ async function pe(e, t, n, r) {
59
593
  switch (e) {
60
594
  case "ai-inference":
61
- let r = await import("./assets/ai-inference.js");
62
- return p.set(e, r.releaseCache), await r.handleAiInference(t, n);
595
+ let i = await import("./assets/ai-inference.js");
596
+ return Q.set(e, i.releaseCache), await i.handleAiInference(t, n);
63
597
  case "image-process": return await (await import("./assets/image-process.js")).handleImageProcess(t);
64
- case "container": return await (await import("./assets/container.js")).handleContainer(t);
598
+ case "container": return await (await import("./assets/container.js")).handleContainer(t, r?.fileSourceOrigins ?? [], r?.containerImageOrigins ?? []);
65
599
  case "vector-embed":
66
- let i = await import("./assets/vector-embed.js");
67
- return p.set(e, i.releaseCache), await i.handleVectorEmbed(t);
600
+ let a = await import("./assets/vector-embed.js");
601
+ return Q.set(e, a.releaseCache), await a.handleVectorEmbed(t);
68
602
  case "vector-store":
69
- let a = await import("./assets/vector-store.js");
70
- return p.set(e, a.releaseCache), await a.handleVectorStore(t);
603
+ let o = await import("./assets/vector-store.js");
604
+ return Q.set(e, o.releaseCache), await o.handleVectorStore(t);
71
605
  case "vector-query":
72
- let o = await import("./assets/vector-query.js");
73
- return p.set(e, o.releaseCache), await o.handleVectorQuery(t);
606
+ let s = await import("./assets/vector-query.js");
607
+ return Q.set(e, s.releaseCache), await s.handleVectorQuery(t);
74
608
  case "nudenet":
75
- let s = await import("./assets/nudenet.js");
76
- return p.set(e, s.releaseCache), await s.handleNudeNet(t);
609
+ let c = await import("./assets/nudenet.js");
610
+ return Q.set(e, c.releaseCache), await c.handleNudeNet(t);
77
611
  default: throw Error(`Unknown workload type: ${e}`);
78
612
  }
79
613
  }
614
+ function me(e, t, n) {
615
+ return new Promise((r, i) => {
616
+ let a = new S({
617
+ initial: t,
618
+ runtime: z(),
619
+ sendControl: (t) => self.postMessage({
620
+ id: e,
621
+ type: "swarm-message",
622
+ message: t
623
+ }),
624
+ sendFrame: (t) => self.postMessage({
625
+ id: e,
626
+ type: "swarm-frame",
627
+ frame: t
628
+ }, [t]),
629
+ emitToken: n,
630
+ onDone: (e) => {
631
+ q === a && (q = null, J = null), r(e);
632
+ },
633
+ onError: (e) => {
634
+ q === a && (q = null, J = null), i(Error(e));
635
+ }
636
+ });
637
+ q = a, J = e, a.start();
638
+ });
639
+ }
80
640
  self.onmessage = async (e) => {
81
- let { id: t, workload: i, payload: a, config: o } = e.data, l = performance.now();
641
+ let t = e.data;
642
+ if (t?.type === "swarm-control") {
643
+ if (!V(t)) {
644
+ console.warn("[flaxia-node:worker] dropped malformed swarm-control message");
645
+ return;
646
+ }
647
+ q && q.handleControl(t.message);
648
+ return;
649
+ }
650
+ if (t?.type === "swarm-frame") {
651
+ t.frame instanceof ArrayBuffer ? q?.handleFrame(t.frame) : console.warn("[flaxia-node:worker] dropped malformed swarm-frame message");
652
+ return;
653
+ }
654
+ if (t?.type === "abort") {
655
+ let e = t.id, n = typeof t.reason == "string" && t.reason ? t.reason : "aborted by the coordinator";
656
+ q && J === e ? q.abort(n) : Y === e && K.set(e, n);
657
+ return;
658
+ }
659
+ let { id: n, workload: r, payload: i, config: a } = t, o = performance.now();
660
+ Y = n;
82
661
  try {
83
- if (c ||= new s(o?.maxCpuLoad), console.log(`[flaxia-node:worker] task start id=${t} workload=${i}`), !d) throw Error(`node incapable: insufficient WASM memory (${u} bytes < ${n}); rejecting all tasks`);
84
- if (r.has(i) && !f()) throw Error(`${i}: insufficient WASM memory (${u} bytes < ${n})`);
85
- await c.waitForSlot();
662
+ if (H ||= new v(a?.maxCpuLoad), console.log(`[flaxia-node:worker] task start id=${n} workload=${r}`), !Z) throw Error(`node incapable: insufficient WASM memory (${X} bytes < ${m}); rejecting all tasks`);
663
+ if (u.has(r) && !ue()) throw Error(`${r}: insufficient WASM memory (${X} bytes < ${m})`);
664
+ await ce(), H.beginWork();
86
665
  let e = setInterval(() => {
87
666
  self.postMessage({
88
- id: t,
667
+ id: n,
89
668
  type: "heartbeat",
90
- cpuLoad: c?.lastMeasuredLoad ?? 0
669
+ cpuLoad: H?.lastMeasuredLoad ?? 0
91
670
  });
92
- }, 1e4), p = performance.now();
671
+ }, 1e4), t = performance.now();
93
672
  try {
94
- let e = await _(i, a, (e) => {
95
- self.postMessage({
96
- id: t,
97
- type: "token",
98
- token: e
99
- });
673
+ let e = le(n), t = Array.isArray(a?.fileSourceOrigins) ? a.fileSourceOrigins.filter((e) => typeof e == "string") : [], s = Array.isArray(a?.containerImageOrigins) ? a.containerImageOrigins.filter((e) => typeof e == "string") : [], c = r === "swarm-inference" ? await me(n, i, e) : await pe(r, i, e, {
674
+ fileSourceOrigins: t,
675
+ containerImageOrigins: s
100
676
  });
101
677
  self.postMessage({
102
- id: t,
678
+ id: n,
103
679
  type: "done",
104
- result: e
105
- }), console.log(`[flaxia-node:worker] task done id=${t} workload=${i} durationMs=${Math.round(performance.now() - l)}`);
680
+ result: c
681
+ }), console.log(`[flaxia-node:worker] task done id=${n} workload=${r} durationMs=${Math.round(performance.now() - o)}`);
106
682
  } finally {
107
- clearInterval(e), c.markTaskComplete(performance.now() - p), g();
683
+ Y = null, K.delete(n), clearInterval(e), H.markTaskComplete(performance.now() - t), fe();
108
684
  }
109
685
  } catch (e) {
110
- let n = e instanceof Error ? e.message : String(e);
111
- console.error(`[flaxia-node:worker] task error id=${t} workload=${i} error=${n}`), self.postMessage({
112
- id: t,
686
+ let t = e instanceof Error ? e.message : String(e);
687
+ console.error(`[flaxia-node:worker] task error id=${n} workload=${r} error=${t}`), Y === n && (Y = null), self.postMessage({
688
+ id: n,
113
689
  type: "error",
114
- error: n
690
+ error: t
115
691
  });
116
692
  }
117
693
  };