@atomic-chat/core 0.19.0 → 0.20.5

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 (219) hide show
  1. package/dist/app-daemon.js +5 -0
  2. package/dist/app-daemon.js.map +1 -1
  3. package/dist/cli/bin.js +0 -0
  4. package/dist/cli/launch.js +2 -0
  5. package/dist/cli/launch.js.map +1 -1
  6. package/dist/cli/main.d.ts +1 -1
  7. package/dist/cli/main.js +5 -0
  8. package/dist/cli/main.js.map +1 -1
  9. package/dist/cloud/registry.js +1 -0
  10. package/dist/cloud/registry.js.map +1 -1
  11. package/dist/config/paths.d.ts +1 -1
  12. package/dist/config/paths.js +12 -0
  13. package/dist/config/paths.js.map +1 -1
  14. package/dist/contracts/engine-builds.d.ts +6 -1
  15. package/dist/contracts/engine-builds.js +1 -1
  16. package/dist/contracts/engine-builds.js.map +1 -1
  17. package/dist/contracts/engines.d.ts +1 -1
  18. package/dist/contracts/engines.js +2 -0
  19. package/dist/contracts/engines.js.map +1 -1
  20. package/dist/contracts/errors.d.ts +7 -1
  21. package/dist/contracts/errors.js.map +1 -1
  22. package/dist/contracts/events.d.ts +3 -1
  23. package/dist/contracts/geniex.d.ts +98 -0
  24. package/dist/contracts/geniex.js +15 -0
  25. package/dist/contracts/geniex.js.map +1 -0
  26. package/dist/contracts/index.d.ts +1 -0
  27. package/dist/contracts/index.js +1 -0
  28. package/dist/contracts/index.js.map +1 -1
  29. package/dist/contracts/model-yml.d.ts +40 -0
  30. package/dist/contracts/model-yml.js +7 -0
  31. package/dist/contracts/model-yml.js.map +1 -1
  32. package/dist/contracts/session.d.ts +6 -1
  33. package/dist/contracts/session.js.map +1 -1
  34. package/dist/contracts/settings.d.ts +12 -1
  35. package/dist/contracts/settings.js.map +1 -1
  36. package/dist/core/app-lease.d.ts +56 -0
  37. package/dist/core/app-lease.js +50 -0
  38. package/dist/core/app-lease.js.map +1 -0
  39. package/dist/core/atomic-core.d.ts +1 -1
  40. package/dist/core/create.js +109 -5
  41. package/dist/core/create.js.map +1 -1
  42. package/dist/engine-builds/engines.d.ts +28 -7
  43. package/dist/engine-builds/engines.js +49 -5
  44. package/dist/engine-builds/engines.js.map +1 -1
  45. package/dist/engine-builds/geniex.d.ts +35 -0
  46. package/dist/engine-builds/geniex.js +111 -0
  47. package/dist/engine-builds/geniex.js.map +1 -0
  48. package/dist/engine-builds/manifest.d.ts +43 -0
  49. package/dist/engine-builds/manifest.js +92 -0
  50. package/dist/engine-builds/manifest.js.map +1 -1
  51. package/dist/engine-builds/order.d.ts +2 -1
  52. package/dist/engine-builds/order.js +2 -0
  53. package/dist/engine-builds/order.js.map +1 -1
  54. package/dist/engine-builds/select.d.ts +15 -0
  55. package/dist/engine-builds/select.js +14 -0
  56. package/dist/engine-builds/select.js.map +1 -1
  57. package/dist/engine-builds/service.d.ts +5 -3
  58. package/dist/engine-builds/service.js +21 -2
  59. package/dist/engine-builds/service.js.map +1 -1
  60. package/dist/engines/service.d.ts +2 -1
  61. package/dist/engines/service.js +3 -1
  62. package/dist/engines/service.js.map +1 -1
  63. package/dist/engines/versions.js +3 -0
  64. package/dist/engines/versions.js.map +1 -1
  65. package/dist/integrations/catalog.d.ts +3 -1
  66. package/dist/integrations/catalog.js +8 -2
  67. package/dist/integrations/catalog.js.map +1 -1
  68. package/dist/integrations/config-io.d.ts +45 -4
  69. package/dist/integrations/config-io.js +91 -6
  70. package/dist/integrations/config-io.js.map +1 -1
  71. package/dist/integrations/configure/codex-repair.d.ts +75 -0
  72. package/dist/integrations/configure/codex-repair.js +254 -0
  73. package/dist/integrations/configure/codex-repair.js.map +1 -0
  74. package/dist/integrations/configure/codex.d.ts +48 -10
  75. package/dist/integrations/configure/codex.js +126 -32
  76. package/dist/integrations/configure/codex.js.map +1 -1
  77. package/dist/integrations/configure/registry.d.ts +4 -1
  78. package/dist/integrations/configure/registry.js +1 -0
  79. package/dist/integrations/configure/registry.js.map +1 -1
  80. package/dist/models/gguf/kv-cache.d.ts +5 -0
  81. package/dist/models/gguf/kv-cache.js +35 -2
  82. package/dist/models/gguf/kv-cache.js.map +1 -1
  83. package/dist/models/gguf/reader.d.ts +5 -0
  84. package/dist/models/gguf/reader.js +15 -3
  85. package/dist/models/gguf/reader.js.map +1 -1
  86. package/dist/router/resolve.d.ts +3 -2
  87. package/dist/router/resolve.js +3 -1
  88. package/dist/router/resolve.js.map +1 -1
  89. package/dist/runtime/geniex/accelerators.d.ts +20 -0
  90. package/dist/runtime/geniex/accelerators.js +53 -0
  91. package/dist/runtime/geniex/accelerators.js.map +1 -0
  92. package/dist/runtime/geniex/check.d.ts +34 -0
  93. package/dist/runtime/geniex/check.js +117 -0
  94. package/dist/runtime/geniex/check.js.map +1 -0
  95. package/dist/runtime/geniex/chip.d.ts +29 -0
  96. package/dist/runtime/geniex/chip.js +35 -0
  97. package/dist/runtime/geniex/chip.js.map +1 -0
  98. package/dist/runtime/geniex/devices.d.ts +13 -0
  99. package/dist/runtime/geniex/devices.js +32 -0
  100. package/dist/runtime/geniex/devices.js.map +1 -0
  101. package/dist/runtime/geniex/geniex-host.d.ts +17 -0
  102. package/dist/runtime/geniex/geniex-host.js +26 -0
  103. package/dist/runtime/geniex/geniex-host.js.map +1 -0
  104. package/dist/runtime/geniex/host/args.d.ts +56 -0
  105. package/dist/runtime/geniex/host/args.js +115 -0
  106. package/dist/runtime/geniex/host/args.js.map +1 -0
  107. package/dist/runtime/geniex/host/engine.d.ts +76 -0
  108. package/dist/runtime/geniex/host/engine.js +122 -0
  109. package/dist/runtime/geniex/host/engine.js.map +1 -0
  110. package/dist/runtime/geniex/host/ffi-bun.d.ts +15 -0
  111. package/dist/runtime/geniex/host/ffi-bun.js +415 -0
  112. package/dist/runtime/geniex/host/ffi-bun.js.map +1 -0
  113. package/dist/runtime/geniex/host/grammar.d.ts +11 -0
  114. package/dist/runtime/geniex/host/grammar.js +223 -0
  115. package/dist/runtime/geniex/host/grammar.js.map +1 -0
  116. package/dist/runtime/geniex/host/inspect.d.ts +25 -0
  117. package/dist/runtime/geniex/host/inspect.js +177 -0
  118. package/dist/runtime/geniex/host/inspect.js.map +1 -0
  119. package/dist/runtime/geniex/host/library.d.ts +117 -0
  120. package/dist/runtime/geniex/host/library.js +38 -0
  121. package/dist/runtime/geniex/host/library.js.map +1 -0
  122. package/dist/runtime/geniex/host/openai.d.ts +62 -0
  123. package/dist/runtime/geniex/host/openai.js +458 -0
  124. package/dist/runtime/geniex/host/openai.js.map +1 -0
  125. package/dist/runtime/geniex/host/run.d.ts +48 -0
  126. package/dist/runtime/geniex/host/run.js +208 -0
  127. package/dist/runtime/geniex/host/run.js.map +1 -0
  128. package/dist/runtime/geniex/host/server.d.ts +39 -0
  129. package/dist/runtime/geniex/host/server.js +232 -0
  130. package/dist/runtime/geniex/host/server.js.map +1 -0
  131. package/dist/runtime/geniex/host/worker-protocol.d.ts +76 -0
  132. package/dist/runtime/geniex/host/worker-protocol.js +116 -0
  133. package/dist/runtime/geniex/host/worker-protocol.js.map +1 -0
  134. package/dist/runtime/geniex/host/worker-source.generated.d.ts +1 -0
  135. package/dist/runtime/geniex/host/worker-source.generated.js +4 -0
  136. package/dist/runtime/geniex/host/worker-source.generated.js.map +1 -0
  137. package/dist/runtime/geniex/host/worker.d.ts +7 -0
  138. package/dist/runtime/geniex/host/worker.js +19 -0
  139. package/dist/runtime/geniex/host/worker.js.map +1 -0
  140. package/dist/runtime/geniex/host-process.d.ts +48 -0
  141. package/dist/runtime/geniex/host-process.js +104 -0
  142. package/dist/runtime/geniex/host-process.js.map +1 -0
  143. package/dist/runtime/geniex/index.d.ts +11 -0
  144. package/dist/runtime/geniex/index.js +12 -0
  145. package/dist/runtime/geniex/index.js.map +1 -0
  146. package/dist/runtime/geniex/model-yml.d.ts +8 -0
  147. package/dist/runtime/geniex/model-yml.js +98 -0
  148. package/dist/runtime/geniex/model-yml.js.map +1 -0
  149. package/dist/runtime/geniex/runtime.d.ts +94 -0
  150. package/dist/runtime/geniex/runtime.js +366 -0
  151. package/dist/runtime/geniex/runtime.js.map +1 -0
  152. package/dist/runtime/litert-lm/host/openai.d.ts +4 -37
  153. package/dist/runtime/litert-lm/host/openai.js +11 -96
  154. package/dist/runtime/litert-lm/host/openai.js.map +1 -1
  155. package/dist/runtime/litert-lm/host/pool.d.ts +1 -7
  156. package/dist/runtime/litert-lm/host/pool.js +1 -17
  157. package/dist/runtime/litert-lm/host/pool.js.map +1 -1
  158. package/dist/runtime/litert-lm/host/server.js +11 -53
  159. package/dist/runtime/litert-lm/host/server.js.map +1 -1
  160. package/dist/runtime/llamacpp/args.d.ts +5 -0
  161. package/dist/runtime/llamacpp/args.js +2 -0
  162. package/dist/runtime/llamacpp/args.js.map +1 -1
  163. package/dist/runtime/llamacpp/fit-margin.d.ts +44 -0
  164. package/dist/runtime/llamacpp/fit-margin.js +50 -0
  165. package/dist/runtime/llamacpp/fit-margin.js.map +1 -1
  166. package/dist/runtime/llamacpp/load-plan.d.ts +5 -0
  167. package/dist/runtime/llamacpp/load-plan.js +57 -22
  168. package/dist/runtime/llamacpp/load-plan.js.map +1 -1
  169. package/dist/runtime/llamacpp/runtime.d.ts +5 -1
  170. package/dist/runtime/llamacpp/runtime.js +6 -1
  171. package/dist/runtime/llamacpp/runtime.js.map +1 -1
  172. package/dist/runtime/shared/external-sessions.js +1 -0
  173. package/dist/runtime/shared/external-sessions.js.map +1 -1
  174. package/dist/runtime/shared/fifo-lock.d.ts +10 -0
  175. package/dist/runtime/shared/fifo-lock.js +21 -0
  176. package/dist/runtime/shared/fifo-lock.js.map +1 -0
  177. package/dist/runtime/shared/index.d.ts +2 -0
  178. package/dist/runtime/shared/index.js +2 -0
  179. package/dist/runtime/shared/index.js.map +1 -1
  180. package/dist/runtime/shared/openai-sse.d.ts +112 -0
  181. package/dist/runtime/shared/openai-sse.js +178 -0
  182. package/dist/runtime/shared/openai-sse.js.map +1 -0
  183. package/dist/server/clients.d.ts +6 -0
  184. package/dist/server/clients.js +11 -0
  185. package/dist/server/clients.js.map +1 -1
  186. package/dist/server/control/router.js +2 -0
  187. package/dist/server/control/router.js.map +1 -1
  188. package/dist/server/control/routes/geniex.d.ts +7 -0
  189. package/dist/server/control/routes/geniex.js +22 -0
  190. package/dist/server/control/routes/geniex.js.map +1 -0
  191. package/dist/server/control/types.d.ts +11 -1
  192. package/dist/server/control/types.js.map +1 -1
  193. package/dist/server/http.js +2 -0
  194. package/dist/server/http.js.map +1 -1
  195. package/dist/server/public/embedding.d.ts +8 -7
  196. package/dist/server/public/embedding.js +15 -7
  197. package/dist/server/public/embedding.js.map +1 -1
  198. package/dist/server/public/forward.js +23 -6
  199. package/dist/server/public/forward.js.map +1 -1
  200. package/dist/server/public/listing.js +1 -0
  201. package/dist/server/public/listing.js.map +1 -1
  202. package/dist/server/public/responses.js +9 -0
  203. package/dist/server/public/responses.js.map +1 -1
  204. package/dist/server/public/telemetry.d.ts +7 -1
  205. package/dist/server/public/telemetry.js +11 -3
  206. package/dist/server/public/telemetry.js.map +1 -1
  207. package/dist/server/public/trace.d.ts +8 -4
  208. package/dist/server/public/trace.js +15 -7
  209. package/dist/server/public/trace.js.map +1 -1
  210. package/dist/server/public/validate.d.ts +32 -0
  211. package/dist/server/public/validate.js +146 -0
  212. package/dist/server/public/validate.js.map +1 -0
  213. package/dist/settings/schema/geniex.json +63 -0
  214. package/dist/settings/schema/mlx.json +1 -1
  215. package/dist/settings/schema.js +11 -0
  216. package/dist/settings/schema.js.map +1 -1
  217. package/dist/version.d.ts +1 -1
  218. package/dist/version.js +1 -1
  219. package/package.json +7 -2
@@ -0,0 +1,366 @@
1
+ /**
2
+ * The `geniex` provider's sessions (openspec change `add-geniex-runtime`, task 6.3, design D4–D7):
3
+ * one `geniex-host serve` process per model — this very binary in its hidden mode — on the sidecar
4
+ * table Foundry Local and LiteRT-LM use, behind the session gateway the managed engines use.
5
+ *
6
+ * load = model.yml → a bundle is for this chip → the device (settings, else model.yml; a bundle on
7
+ * the NPU only) → the active build → the device is one the build's probe found → the model's
8
+ * facts (`inspect`, cached by path and mtime): a bundle for a newer GenieX? context cut to
9
+ * the model → [GPU claim, for gpu] → host on a random loopback port → readiness line →
10
+ * gateway (key + Host) → session on the gateway's port
11
+ *
12
+ * The host's server has no authentication; the gateway holds the key and lets through only
13
+ * `/v1/chat/completions` and `/v1/models`. The host serves the model under core's id (`--id`).
14
+ */
15
+ import { stat } from 'node:fs/promises';
16
+ import { dirname, join } from 'node:path';
17
+ import { AtomicCoreError, GENIEX_DEVICES } from '../../contracts/index.js';
18
+ import { generateGatewayKey, startManagedGateway } from '../managed-text/index.js';
19
+ import { backendOutputReporter, exitedOnTakenPort, randomFreePort, retryOnTakenPort, SidecarTable, spawnAndAwaitReady, throwIfLoadCancelled, } from '../shared/index.js';
20
+ import { compareVersions } from '../../backend/index.js';
21
+ import { deviceFound, deviceMissingReason } from './devices.js';
22
+ import { GENIEX_POWER_MODES } from './host/library.js';
23
+ import { runGeniexHostInspect } from './host-process.js';
24
+ import { readGeniexBlock } from './model-yml.js';
25
+ /** The settings' `timeout` default, in seconds: opening the file, compiling for the NPU, the server. */
26
+ export const GENIEX_DEFAULT_TIMEOUT_SECS = 600;
27
+ /** What a GenieX session serves (design D6); anything else is refused before it reaches the host. */
28
+ export const GENIEX_ROUTES = [
29
+ { method: 'POST', path: '/v1/chat/completions' },
30
+ { method: 'GET', path: '/v1/models' },
31
+ ];
32
+ /** `device` of the settings when it names one, else `model.yml`'s default. */
33
+ export function launchDevice(settingDevice, block) {
34
+ return GENIEX_DEVICES.some((known) => known === settingDevice)
35
+ ? settingDevice
36
+ : block.backend;
37
+ }
38
+ /** `ctx_len` of the settings (0: the model's own), else `model.yml`'s, cut to the model's maximum. */
39
+ export function engineContext(settingCtx, block, modelMax) {
40
+ const asked = Number(settingCtx) > 0 ? Math.round(Number(settingCtx)) : block.context_length;
41
+ return modelMax !== null ? Math.min(asked, modelMax) : asked;
42
+ }
43
+ const powerMode = (value) => GENIEX_POWER_MODES.some((known) => known === value) ? value : 'burst';
44
+ /** The host's exit codes (`host/run.ts` `EXIT`) as the core's errors. */
45
+ function hostError(exitCode, stderr) {
46
+ const lines = stderr.trim().split('\n');
47
+ // A bind failure sits above Node's stack, outside the last five lines: kept first, the retry reads it.
48
+ const taken = lines.find((line) => exitedOnTakenPort(line));
49
+ const said = [...(taken ? [taken] : []), ...lines.slice(-5).filter((line) => line !== taken)].join('\n');
50
+ const last = stderr.trim().split('\n').at(-1) ?? '';
51
+ let line = {};
52
+ try {
53
+ line = JSON.parse(last);
54
+ }
55
+ catch {
56
+ // Not one of the host's JSON error lines.
57
+ }
58
+ if (exitCode === 6)
59
+ return new AtomicCoreError('GENIEX_MODEL_REQUIRES_NEWER_ENGINE', `This model needs GenieX ${String(line['required'] ?? 'newer')}; update GenieX first.`, said);
60
+ if (exitCode === 7)
61
+ return new AtomicCoreError('GENIEX_VARIANT_UNSUPPORTED', typeof line['message'] === 'string' ? line['message'] : 'This model does not run on its device here.', said);
62
+ return new AtomicCoreError('GENIEX_HOST_ERROR', exitCode === 3
63
+ ? 'The GenieX library does not load on this computer.'
64
+ : 'The GenieX host stopped before the model was ready.', said || `exit code ${String(exitCode)}`);
65
+ }
66
+ export class GeniexRuntime {
67
+ options;
68
+ table;
69
+ emit;
70
+ /** Loads past their GPU claim and not yet a session. */
71
+ claimed = new Map();
72
+ /** `inspect` answers by `<path>|<mtime>`: a model that changed is read again. */
73
+ facts = new Map();
74
+ get registry() {
75
+ return this.options.registry;
76
+ }
77
+ constructor(options) {
78
+ this.options = options;
79
+ this.emit = options.emit ?? (() => { });
80
+ this.table = new SidecarTable({
81
+ provider: 'geniex',
82
+ instanceId: options.instanceId,
83
+ journal: options.journal,
84
+ emit: this.emit,
85
+ engine: 'GenieX',
86
+ unloadGraceMs: 15_000,
87
+ shutdownGraceMs: 5_000,
88
+ describeExit: (exit, stderr) => `The GenieX host exited (${exit.code !== null ? `code ${exit.code}` : `signal ${String(exit.signal)}`})${stderr.trim() ? `: ${stderr.trim().split('\n').slice(-3).join(' ')}` : ''}`,
89
+ });
90
+ }
91
+ list() {
92
+ return this.table.list();
93
+ }
94
+ findSession(modelId) {
95
+ return this.table.findSession(modelId);
96
+ }
97
+ getLoadedModels() {
98
+ return this.table.getLoadedModels();
99
+ }
100
+ isLoading(modelId) {
101
+ return this.table.isLoading(modelId);
102
+ }
103
+ /** A `gpu` session holds every card (the library picks one we cannot name); `npu`, `cpu` and `hybrid` none (design D7). */
104
+ gpuOccupancy() {
105
+ const ready = this.table.getLoadedModels().flatMap((modelId) => {
106
+ const session = this.table.get(modelId);
107
+ return session
108
+ ? [
109
+ {
110
+ model_id: modelId,
111
+ cards: session.extra.device === 'gpu' ? 'all' : [],
112
+ auxiliary: false,
113
+ state: 'ready',
114
+ },
115
+ ]
116
+ : [];
117
+ });
118
+ const loading = [...this.claimed.values()].filter((claim) => !this.table.findSession(claim.model_id));
119
+ return [...ready, ...loading];
120
+ }
121
+ /** What the engine-builds module needs: the load queue, and the builds sessions run from (design D2). */
122
+ engineHost() {
123
+ return {
124
+ exclusive: (fn) => this.table.exclusive(fn),
125
+ inUse: async () => [
126
+ ...new Set(this.table.getLoadedModels().flatMap((modelId) => {
127
+ const build = this.table.get(modelId)?.extra.build;
128
+ return build ? [build] : [];
129
+ })),
130
+ ],
131
+ activate: async (dir) => {
132
+ for (const modelId of this.table.getLoadedModels())
133
+ if (this.table.get(modelId)?.extra.build !== dir)
134
+ await this.unload(modelId);
135
+ },
136
+ };
137
+ }
138
+ routePolicy(modelId) {
139
+ const session = this.table.get(modelId);
140
+ if (!session)
141
+ return undefined;
142
+ return {
143
+ routes: GENIEX_ROUTES,
144
+ tools: session.extra.block.tools,
145
+ structuredOutput: true,
146
+ mapError: () => null,
147
+ contextLength: session.extra.context,
148
+ };
149
+ }
150
+ /** The model's facts, read by this binary's host once per path and modification time. */
151
+ async inspect(path) {
152
+ const mtime = await stat(path).then((s) => s.mtimeMs, () => {
153
+ throw new AtomicCoreError('MODEL_NOT_FOUND', `The model ${path} is missing.`);
154
+ });
155
+ const key = `${path}|${mtime}`;
156
+ const known = this.facts.get(key);
157
+ if (known)
158
+ return known;
159
+ const read = this.options.inspectModel
160
+ ? await this.options.inspectModel(path)
161
+ : await runGeniexHostInspect(this.options.hostCommand, path, {
162
+ env: this.options.baseEnv ?? process.env,
163
+ });
164
+ this.facts.set(key, read);
165
+ return read;
166
+ }
167
+ async load(modelId, opts = {}) {
168
+ this.table.assertRunning();
169
+ return this.table.load(modelId, () => this.start(modelId, opts), opts.signal);
170
+ }
171
+ async start(modelId, opts) {
172
+ throwIfLoadCancelled(opts.signal);
173
+ const registry = this.options.registry;
174
+ const yml = await registry.read(modelId);
175
+ const block = readGeniexBlock(yml);
176
+ if (block.plugin === 'qairt' && block.chip !== this.options.chip)
177
+ throw new AtomicCoreError('GENIEX_VARIANT_UNSUPPORTED', `This AI Hub bundle is built for the Snapdragon ${block.chip ?? 'unknown'}; this computer has the ${this.options.chip}.`);
178
+ const settings = await this.options.readSettings();
179
+ const device = launchDevice(settings['device'], block);
180
+ if (block.plugin === 'qairt' && device !== 'npu')
181
+ throw new AtomicCoreError('GENIEX_VARIANT_UNSUPPORTED', `AI Hub bundles run on the NPU only, not on the ${device}; set the device to NPU in the GenieX settings.`);
182
+ const build = await this.options.resolveBuild();
183
+ if (!build)
184
+ throw new AtomicCoreError('BINARY_NOT_FOUND', 'GenieX is not installed; install it before loading a model.');
185
+ if (!deviceFound(device, build.devices))
186
+ throw new AtomicCoreError('GENIEX_VARIANT_UNSUPPORTED', deviceMissingReason(device), build.devices.join(', ') || 'no devices');
187
+ const { modelPath, mmprojPath: declared } = registry.resolvePaths(yml);
188
+ // The projector: `mmproj_path` of model.yml, else the block's file name beside the model.
189
+ const mmprojPath = declared ?? (block.mmproj ? join(dirname(modelPath), block.mmproj) : undefined);
190
+ const info = await this.inspect(modelPath);
191
+ if (info.kind === 'qairt' &&
192
+ info.min_runtime_version &&
193
+ compareVersions(info.min_runtime_version, build.version) > 0)
194
+ throw new AtomicCoreError('GENIEX_MODEL_REQUIRES_NEWER_ENGINE', `This bundle needs GenieX ${info.min_runtime_version}; the active build is ${build.version}. Update GenieX first.`, info.min_runtime_version);
195
+ const context = engineContext(settings['ctx_len'], block, info.max_context_tokens);
196
+ const timeoutSecs = opts.timeoutSecs ??
197
+ (Number(settings['timeout']) > 0 ? Number(settings['timeout']) : GENIEX_DEFAULT_TIMEOUT_SECS);
198
+ const mode = powerMode(settings['power_mode']);
199
+ if (!(opts.bypassAutoUnload ?? false))
200
+ for (const loaded of this.table.getLoadedModels()) {
201
+ throwIfLoadCancelled(opts.signal);
202
+ await this.unload(loaded);
203
+ }
204
+ this.table.assertRunning();
205
+ throwIfLoadCancelled(opts.signal);
206
+ // GPU residency (design D7): a gpu session holds every card; the NPU, the CPU and hybrid claim nothing.
207
+ const holdsGpu = device === 'gpu';
208
+ const occupancy = {
209
+ model_id: modelId,
210
+ cards: holdsGpu ? 'all' : [],
211
+ auxiliary: false,
212
+ state: 'loading',
213
+ };
214
+ const hold = () => void this.claimed.set(modelId, occupancy);
215
+ try {
216
+ if (holdsGpu && this.options.claimGpu) {
217
+ await this.options.claimGpu({ model_id: modelId, cards: 'all', auxiliary: false }, opts.signal, hold);
218
+ this.table.assertRunning();
219
+ throwIfLoadCancelled(opts.signal);
220
+ }
221
+ hold();
222
+ return await this.startHost(modelId, opts, {
223
+ block,
224
+ device,
225
+ build,
226
+ modelPath,
227
+ mmprojPath,
228
+ context,
229
+ timeoutSecs,
230
+ mode,
231
+ });
232
+ }
233
+ finally {
234
+ if (this.claimed.get(modelId) === occupancy)
235
+ this.claimed.delete(modelId);
236
+ }
237
+ }
238
+ async startHost(modelId, opts, launch) {
239
+ const { block, device, build, modelPath, mmprojPath, context, timeoutSecs, mode } = launch;
240
+ const paths = this.options.layout.provider('geniex');
241
+ const env = {};
242
+ for (const [key, value] of Object.entries(this.options.baseEnv ?? process.env))
243
+ if (value !== undefined)
244
+ env[key] = value;
245
+ const exe = this.options.hostCommand.exe;
246
+ const reportOutput = backendOutputReporter(this.options.backendOutput, this.options.log);
247
+ this.options.log?.('info', `starting the GenieX host for ${modelId} (${block.plugin} on ${device}) from ${build.dir}`);
248
+ // The free-port probe is racy: another process may bind the port before the host does. The host
249
+ // then exits on EADDRINUSE, and is started again on a port picked anew (as llama-server is).
250
+ const { started, hostPort } = await retryOnTakenPort(async () => {
251
+ const hostPort = await randomFreePort(this.table.usedPorts());
252
+ const tmp = join(paths.tmpDir, `${modelId.replace(/[^A-Za-z0-9._-]+/g, '_')}-${hostPort}`);
253
+ const args = [
254
+ ...this.options.hostCommand.args,
255
+ 'serve',
256
+ '--lib',
257
+ build.dir,
258
+ '--engine-version',
259
+ build.version,
260
+ '--model',
261
+ modelPath,
262
+ '--plugin',
263
+ block.plugin,
264
+ '--device',
265
+ device,
266
+ ...(mmprojPath ? ['--mmproj', mmprojPath] : []),
267
+ '--nctx',
268
+ String(context),
269
+ '--max-tokens',
270
+ String(context),
271
+ '--power-mode',
272
+ mode,
273
+ '--port',
274
+ String(hostPort),
275
+ '--tmp',
276
+ tmp,
277
+ '--id',
278
+ modelId,
279
+ ...(block.reasoning ? ['--reasoning'] : []),
280
+ ];
281
+ const started = await (this.options.spawn ?? spawnAndAwaitReady)({ exe, args, env, stdin: 'pipe', platform: process.platform }, {
282
+ timeoutMs: timeoutSecs * 1000,
283
+ signal: this.table.signal,
284
+ ...(opts.signal ? { cancelSignal: opts.signal } : {}),
285
+ streamReadyMarkers: { stdout: ['"ready":true'], stderr: [] },
286
+ timeoutError: (stderr) => new AtomicCoreError('MODEL_LOAD_TIMED_OUT', `The GenieX model did not load within ${timeoutSecs} seconds.`, stderr.trim().split('\n').slice(-5).join('\n')),
287
+ classifyExit: (exit, stderr) => hostError(exit.code, stderr),
288
+ onLine: (stream, line) => {
289
+ if (opts.verbose)
290
+ this.emit('core:log', { level: 'debug', msg: `[geniex/${modelId}][${stream}] ${line}` });
291
+ reportOutput({ provider: 'geniex', model: modelId, stream, line });
292
+ },
293
+ });
294
+ return { started, hostPort };
295
+ }, (error) => error instanceof AtomicCoreError && exitedOnTakenPort(error.details), (attempt) => this.options.log?.('warn', `the GenieX host for ${modelId} found its port taken (attempt ${attempt}); starting it on another`));
296
+ let gateway;
297
+ const apiKey = generateGatewayKey();
298
+ try {
299
+ gateway = await startManagedGateway({
300
+ upstream: { host: '127.0.0.1', port: hostPort },
301
+ apiKey,
302
+ allowedHosts: this.options.trustedHosts,
303
+ routes: GENIEX_ROUTES,
304
+ });
305
+ }
306
+ catch (error) {
307
+ await started.process.terminate(this.table.isClosing ? 0 : 5_000).catch(() => { });
308
+ throw error;
309
+ }
310
+ void started.process.exited.then(() => gateway.close().catch(() => { }));
311
+ try {
312
+ return await this.table.adopt({
313
+ info: {
314
+ pid: started.process.pid,
315
+ port: gateway.port,
316
+ model_id: modelId,
317
+ model_path: modelPath,
318
+ is_embedding: false,
319
+ api_key: apiKey,
320
+ },
321
+ process: started.process,
322
+ exe,
323
+ extra: { build: build.dir, block, device, gateway, context },
324
+ }, opts.signal);
325
+ }
326
+ catch (error) {
327
+ await gateway.close().catch(() => { });
328
+ throw error;
329
+ }
330
+ }
331
+ /** Waits for the host to exit; the gateway goes with it. */
332
+ async unload(modelId) {
333
+ this.table.assertRunning();
334
+ const gateway = this.table.get(modelId)?.extra.gateway;
335
+ const result = await this.table.unload(modelId);
336
+ if (result.success)
337
+ await gateway?.close().catch(() => { });
338
+ return result;
339
+ }
340
+ /** The context is fixed when the model is created: nothing to grow. */
341
+ async autoIncreaseCtx(modelId) {
342
+ return this.table.get(modelId)
343
+ ? { ok: false, reason: 'unsupported' }
344
+ : { ok: false, reason: 'not-loaded' };
345
+ }
346
+ async recreateSession(modelId) {
347
+ this.table.assertRunning();
348
+ if (!this.table.get(modelId))
349
+ return { ok: false, reason: 'not-loaded' };
350
+ await this.unload(modelId);
351
+ return { ok: true, session: await this.load(modelId, { bypassAutoUnload: true }) };
352
+ }
353
+ async shutdown() {
354
+ const gateways = this.table.getLoadedModels().flatMap((id) => {
355
+ const gateway = this.table.get(id)?.extra.gateway;
356
+ return gateway ? [gateway] : [];
357
+ });
358
+ try {
359
+ await this.table.shutdown();
360
+ }
361
+ finally {
362
+ await Promise.all(gateways.map((gateway) => gateway.close().catch(() => { })));
363
+ }
364
+ }
365
+ }
366
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/runtime/geniex/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAa1E,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAYlF,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAEtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAExD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEhD,wGAAwG;AACxG,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAA;AAE9C,qGAAqG;AACrG,MAAM,CAAC,MAAM,aAAa,GAA4B;IACpD,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,sBAAsB,EAAE;IAChD,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE;CACtC,CAAA;AASD,8EAA8E;AAC9E,MAAM,UAAU,YAAY,CAAC,aAAsB,EAAE,KAAqB;IACxE,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,aAAa,CAAC;QAC5D,CAAC,CAAE,aAA8B;QACjC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAA;AACnB,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,aAAa,CAAC,UAAmB,EAAE,KAAqB,EAAE,QAAuB;IAC/F,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAA;IAC5F,OAAO,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AAC9D,CAAC;AAED,MAAM,SAAS,GAAG,CAAC,KAAc,EAAmB,EAAE,CACpD,kBAAkB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,CAAE,KAAyB,CAAC,CAAC,CAAC,OAAO,CAAA;AAoC5F,yEAAyE;AACzE,SAAS,SAAS,CAAC,QAAuB,EAAE,MAAc;IACxD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACvC,uGAAuG;IACvG,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAA;IAC3D,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACxG,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IACnD,IAAI,IAAI,GAA4B,EAAE,CAAA;IACtC,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAA;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,0CAA0C;IAC5C,CAAC;IACD,IAAI,QAAQ,KAAK,CAAC;QAChB,OAAO,IAAI,eAAe,CACxB,oCAAoC,EACpC,2BAA2B,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,wBAAwB,EACtF,IAAI,CACL,CAAA;IACH,IAAI,QAAQ,KAAK,CAAC;QAChB,OAAO,IAAI,eAAe,CACxB,4BAA4B,EAC5B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,6CAA6C,EACrG,IAAI,CACL,CAAA;IACH,OAAO,IAAI,eAAe,CACxB,mBAAmB,EACnB,QAAQ,KAAK,CAAC;QACZ,CAAC,CAAC,oDAAoD;QACtD,CAAC,CAAC,qDAAqD,EACzD,IAAI,IAAI,aAAa,MAAM,CAAC,QAAQ,CAAC,EAAE,CACxC,CAAA;AACH,CAAC;AAED,MAAM,OAAO,aAAa;IAYK;IAXZ,KAAK,CAAkC;IACvC,IAAI,CAAQ;IAC7B,wDAAwD;IACvC,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAA;IAC1D,iFAAiF;IAChE,KAAK,GAAG,IAAI,GAAG,EAA+B,CAAA;IAE/D,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAA;IAC9B,CAAC;IAED,YAA6B,OAA6B;QAA7B,YAAO,GAAP,OAAO,CAAsB;QACxD,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QACtC,IAAI,CAAC,KAAK,GAAG,IAAI,YAAY,CAAqB;YAChD,QAAQ,EAAE,QAAQ;YAClB,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,QAAQ;YAChB,aAAa,EAAE,MAAM;YACrB,eAAe,EAAE,KAAK;YACtB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAC7B,2BAA2B,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,UAAU,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IACnG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EACzE,EAAE;SACL,CAAC,CAAA;IACJ,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAA;IAC1B,CAAC;IAED,WAAW,CAAC,OAAe;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;IACxC,CAAC;IAED,eAAe;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAA;IACrC,CAAC;IAED,SAAS,CAAC,OAAe;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;IACtC,CAAC;IAED,2HAA2H;IAC3H,YAAY;QACV,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,EAAkB,EAAE;YAC7E,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YACvC,OAAO,OAAO;gBACZ,CAAC,CAAC;oBACE;wBACE,QAAQ,EAAE,OAAO;wBACjB,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;wBAClD,SAAS,EAAE,KAAK;wBAChB,KAAK,EAAE,OAAO;qBACf;iBACF;gBACH,CAAC,CAAC,EAAE,CAAA;QACR,CAAC,CAAC,CAAA;QACF,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAA;QACrG,OAAO,CAAC,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC,CAAA;IAC/B,CAAC;IAED,yGAAyG;IACzG,UAAU;QACR,OAAO;YACL,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3C,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC;gBACjB,GAAG,IAAI,GAAG,CACR,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;oBAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,KAAK,CAAA;oBAClD,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;gBAC7B,CAAC,CAAC,CACH;aACF;YACD,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;gBACtB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE;oBAChD,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG;wBAAE,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YAChF,CAAC;SACF,CAAA;IACH,CAAC;IAED,WAAW,CAAC,OAAe;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACvC,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAA;QAC9B,OAAO;YACL,MAAM,EAAE,aAAa;YACrB,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK;YAChC,gBAAgB,EAAE,IAAI;YACtB,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI;YACpB,aAAa,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO;SACrC,CAAA;IACH,CAAC;IAED,yFAAyF;IACzF,KAAK,CAAC,OAAO,CAAC,IAAY;QACxB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CACjC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAChB,GAAG,EAAE;YACH,MAAM,IAAI,eAAe,CAAC,iBAAiB,EAAE,aAAa,IAAI,cAAc,CAAC,CAAA;QAC/E,CAAC,CACF,CAAA;QACD,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,KAAK,EAAE,CAAA;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACjC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAA;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY;YACpC,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC;YACvC,CAAC,CAAC,MAAM,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE;gBACzD,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG;aACzC,CAAC,CAAA;QACN,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QACzB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAe,EAAE,OAAyB,EAAE;QACrD,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAA;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAC/E,CAAC;IAEO,KAAK,CAAC,KAAK,CAAC,OAAe,EAAE,IAAsB;QACzD,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAA;QACtC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACxC,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;QAClC,IAAI,KAAK,CAAC,MAAM,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI;YAC9D,MAAM,IAAI,eAAe,CACvB,4BAA4B,EAC5B,kDAAkD,KAAK,CAAC,IAAI,IAAI,SAAS,2BAA2B,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,CACzH,CAAA;QACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAA;QAClD,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAA;QACtD,IAAI,KAAK,CAAC,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,KAAK;YAC9C,MAAM,IAAI,eAAe,CACvB,4BAA4B,EAC5B,kDAAkD,MAAM,iDAAiD,CAC1G,CAAA;QACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAA;QAC/C,IAAI,CAAC,KAAK;YACR,MAAM,IAAI,eAAe,CACvB,kBAAkB,EAClB,6DAA6D,CAC9D,CAAA;QACH,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC;YACrC,MAAM,IAAI,eAAe,CACvB,4BAA4B,EAC5B,mBAAmB,CAAC,MAAM,CAAC,EAC3B,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,YAAY,CACzC,CAAA;QACH,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;QACtE,0FAA0F;QAC1F,MAAM,UAAU,GAAG,QAAQ,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;QAClG,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QAC1C,IACE,IAAI,CAAC,IAAI,KAAK,OAAO;YACrB,IAAI,CAAC,mBAAmB;YACxB,eAAe,CAAC,IAAI,CAAC,mBAAmB,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;YAE5D,MAAM,IAAI,eAAe,CACvB,oCAAoC,EACpC,4BAA4B,IAAI,CAAC,mBAAmB,yBAAyB,KAAK,CAAC,OAAO,wBAAwB,EAClH,IAAI,CAAC,mBAAmB,CACzB,CAAA;QACH,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAA;QAClF,MAAM,WAAW,GACf,IAAI,CAAC,WAAW;YAChB,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAA;QAC/F,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAA;QAE9C,IAAI,CAAC,CAAC,IAAI,CAAC,gBAAgB,IAAI,KAAK,CAAC;YACnC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE,CAAC;gBAClD,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;gBACjC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;YAC3B,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAA;QAC1B,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAEjC,wGAAwG;QACxG,MAAM,QAAQ,GAAG,MAAM,KAAK,KAAK,CAAA;QACjC,MAAM,SAAS,GAAiB;YAC9B,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;YAC5B,SAAS,EAAE,KAAK;YAChB,KAAK,EAAE,SAAS;SACjB,CAAA;QACD,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;QAC5D,IAAI,CAAC;YACH,IAAI,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACtC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;gBACrG,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAA;gBAC1B,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACnC,CAAC;YACD,IAAI,EAAE,CAAA;YACN,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE;gBACzC,KAAK;gBACL,MAAM;gBACN,KAAK;gBACL,SAAS;gBACT,UAAU;gBACV,OAAO;gBACP,WAAW;gBACX,IAAI;aACL,CAAC,CAAA;QACJ,CAAC;gBAAS,CAAC;YACT,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,SAAS;gBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAC3E,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,SAAS,CACrB,OAAe,EACf,IAAsB,EACtB,MASC;QAED,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,MAAM,CAAA;QAC1F,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;QACpD,MAAM,GAAG,GAA2B,EAAE,CAAA;QACtC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC;YAC5E,IAAI,KAAK,KAAK,SAAS;gBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,CAAA;QACxC,MAAM,YAAY,GAAG,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACxF,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAChB,MAAM,EACN,gCAAgC,OAAO,KAAK,KAAK,CAAC,MAAM,OAAO,MAAM,UAAU,KAAK,CAAC,GAAG,EAAE,CAC3F,CAAA;QACD,gGAAgG;QAChG,6FAA6F;QAC7F,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,gBAAgB,CAClD,KAAK,IAAI,EAAE;YACT,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAA;YAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,mBAAmB,EAAE,GAAG,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAA;YAC1F,MAAM,IAAI,GAAG;gBACX,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI;gBAChC,OAAO;gBACP,OAAO;gBACP,KAAK,CAAC,GAAG;gBACT,kBAAkB;gBAClB,KAAK,CAAC,OAAO;gBACb,SAAS;gBACT,SAAS;gBACT,UAAU;gBACV,KAAK,CAAC,MAAM;gBACZ,UAAU;gBACV,MAAM;gBACN,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/C,QAAQ;gBACR,MAAM,CAAC,OAAO,CAAC;gBACf,cAAc;gBACd,MAAM,CAAC,OAAO,CAAC;gBACf,cAAc;gBACd,IAAI;gBACJ,QAAQ;gBACR,MAAM,CAAC,QAAQ,CAAC;gBAChB,OAAO;gBACP,GAAG;gBACH,MAAM;gBACN,OAAO;gBACP,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;aAC5C,CAAA;YACD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,kBAAkB,CAAC,CAC9D,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,EAC7D;gBACE,SAAS,EAAE,WAAW,GAAG,IAAI;gBAC7B,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;gBACzB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrD,kBAAkB,EAAE,EAAE,MAAM,EAAE,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;gBAC5D,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE,CACvB,IAAI,eAAe,CACjB,sBAAsB,EACtB,wCAAwC,WAAW,WAAW,EAC9D,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAC/C;gBACH,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC;gBAC5D,MAAM,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;oBACvB,IAAI,IAAI,CAAC,OAAO;wBACd,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,OAAO,KAAK,MAAM,KAAK,IAAI,EAAE,EAAE,CAAC,CAAA;oBAC1F,YAAY,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;gBACpE,CAAC;aACF,CACF,CAAA;YACD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAA;QAC9B,CAAC,EACD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,YAAY,eAAe,IAAI,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC,EAC/E,CAAC,OAAO,EAAE,EAAE,CACV,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAChB,MAAM,EACN,uBAAuB,OAAO,kCAAkC,OAAO,2BAA2B,CACnG,CACJ,CAAA;QACD,IAAI,OAAuB,CAAA;QAC3B,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAA;QACnC,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,mBAAmB,CAAC;gBAClC,QAAQ,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC/C,MAAM;gBACN,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY;gBACvC,MAAM,EAAE,aAAa;aACtB,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YACjF,MAAM,KAAK,CAAA;QACb,CAAC;QACD,KAAK,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAA;QACvE,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAC3B;gBACE,IAAI,EAAE;oBACJ,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG;oBACxB,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,QAAQ,EAAE,OAAO;oBACjB,UAAU,EAAE,SAAS;oBACrB,YAAY,EAAE,KAAK;oBACnB,OAAO,EAAE,MAAM;iBAChB;gBACD,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,GAAG;gBACH,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE;aAC7D,EACD,IAAI,CAAC,MAAM,CACZ,CAAA;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YACrC,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;IAED,4DAA4D;IAC5D,KAAK,CAAC,MAAM,CAAC,OAAe;QAC1B,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAA;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,OAAO,CAAA;QACtD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAC/C,IAAI,MAAM,CAAC,OAAO;YAAE,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAC1D,OAAO,MAAM,CAAA;IACf,CAAC;IAED,uEAAuE;IACvE,KAAK,CAAC,eAAe,CAAC,OAAe;QACnC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;YAC5B,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE;YACtC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAA;IACzC,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,OAAe;QACnC,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAA;QAC1B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAA;QACxE,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAC1B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,EAAE,CAAA;IACpF,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;YAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,CAAA;YACjD,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QACjC,CAAC,CAAC,CAAA;QACF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAA;QAC7B,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QAC/E,CAAC;IACH,CAAC;CACF"}
@@ -8,26 +8,10 @@
8
8
  * of and the host adds: `stop` strings, OpenAI's string `arguments`, call ids, `finish_reason`.
9
9
  */
10
10
  import type { LiteRtMessage, LiteRtSampler } from './library.js';
11
- export interface OpenAiErrorBody {
12
- error: {
13
- message: string;
14
- type: string;
15
- param: string | null;
16
- code: string | null;
17
- };
18
- }
19
- /** A request this server answers with an OpenAI-shaped error instead of a completion. */
20
- export declare class OpenAiRequestError extends Error {
21
- readonly status: number;
22
- readonly body: OpenAiErrorBody;
23
- constructor(status: number, message: string, param?: string | null, type?: string, code?: string | null);
24
- }
25
- export interface ModelCaps {
26
- /** The file declares image input. */
27
- vision: boolean;
28
- /** Think unless the request says not to (`model.yml` `reasoning`). */
29
- reasoning: boolean;
30
- }
11
+ import { OpenAiRequestError } from '../../shared/index.js';
12
+ import type { Delta, FinishReason, ModelCaps } from '../../shared/index.js';
13
+ export { OpenAiRequestError };
14
+ export type { Delta, FinishReason, ModelCaps, OpenAiErrorBody } from '../../shared/index.js';
31
15
  export interface ParsedChat {
32
16
  /** Every message but the trailing user message or run of tool results. */
33
17
  history: LiteRtMessage[];
@@ -48,23 +32,6 @@ export interface ParsedChat {
48
32
  }
49
33
  /** A chat completions body, or `OpenAiRequestError` (400) naming the field it cannot serve. */
50
34
  export declare function parseChatRequest(raw: unknown, caps: ModelCaps): ParsedChat;
51
- /** One OpenAI delta (`choices[0].delta`) without the role. */
52
- export type Delta = {
53
- content: string;
54
- } | {
55
- reasoning_content: string;
56
- } | {
57
- tool_calls: Array<{
58
- index: number;
59
- id: string;
60
- type: 'function';
61
- function: {
62
- name: string;
63
- arguments: string;
64
- };
65
- }>;
66
- };
67
- export type FinishReason = 'stop' | 'length' | 'tool_calls';
68
35
  /** Builds one reply from the library's chunks: deltas as they come, the whole message at the end. */
69
36
  export declare class ReplyBuilder {
70
37
  private readonly stops;
@@ -7,19 +7,8 @@
7
7
  * an `arguments` object (one chunk, no deltas), thinking as `channels.thought`. What it has no notion
8
8
  * of and the host adds: `stop` strings, OpenAI's string `arguments`, call ids, `finish_reason`.
9
9
  */
10
- /** A request this server answers with an OpenAI-shaped error instead of a completion. */
11
- export class OpenAiRequestError extends Error {
12
- status;
13
- body;
14
- constructor(status, message, param = null, type = status >= 500 ? 'server_error' : 'invalid_request_error', code = null) {
15
- super(message);
16
- this.status = status;
17
- this.name = 'OpenAiRequestError';
18
- this.body = { error: { message, type, param, code } };
19
- }
20
- }
21
- const invalid = (message, param = null) => new OpenAiRequestError(400, message, param);
22
- const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
10
+ import { DATA_URL_RE, invalidRequest as invalid, isRecord, OpenAiRequestError, parseCommonChatRequest, textOf, } from '../../shared/index.js';
11
+ export { OpenAiRequestError };
23
12
  const text = (value) => ({ type: 'text', text: value });
24
13
  function parseArguments(raw) {
25
14
  if (typeof raw !== 'string')
@@ -41,22 +30,6 @@ function parseToolResponse(content) {
41
30
  return raw;
42
31
  }
43
32
  }
44
- function textOf(content, param) {
45
- if (content == null)
46
- return '';
47
- if (typeof content === 'string')
48
- return content;
49
- if (!Array.isArray(content))
50
- throw invalid(`${param} must be a string or an array of parts`, param);
51
- return content
52
- .map((part) => {
53
- if (isRecord(part) && part['type'] === 'text' && typeof part['text'] === 'string')
54
- return part['text'];
55
- throw invalid(`${param} may hold text parts only`, param);
56
- })
57
- .join('');
58
- }
59
- const DATA_URL_RE = /^data:image\/[a-z0-9.+-]+;base64,([A-Za-z0-9+/=]+)$/i;
60
33
  function userContent(content, caps, param) {
61
34
  if (typeof content === 'string')
62
35
  return [text(content)];
@@ -117,49 +90,11 @@ function convertMessages(raw, caps) {
117
90
  throw invalid(`${param}.role ${JSON.stringify(role)} is not system, developer, user, assistant or tool`, `${param}.role`);
118
91
  });
119
92
  }
120
- function optionalNumber(body, key) {
121
- const value = body[key];
122
- if (value === undefined || value === null)
123
- return undefined;
124
- if (typeof value !== 'number' || !Number.isFinite(value))
125
- throw invalid(`${key} must be a number`, key);
126
- return value;
127
- }
128
- function parseResponseFormat(raw) {
129
- if (raw === undefined || raw === null)
130
- return null;
131
- if (!isRecord(raw))
132
- throw invalid('response_format must be an object', 'response_format');
133
- if (raw['type'] === 'text')
134
- return null;
135
- if (raw['type'] === 'json_object')
136
- return { kind: 'json_schema', value: '{"type":"object"}' };
137
- if (raw['type'] === 'json_schema') {
138
- const schema = isRecord(raw['json_schema']) ? raw['json_schema']['schema'] : undefined;
139
- if (!isRecord(schema))
140
- throw invalid('response_format.json_schema.schema must be a JSON schema', 'response_format');
141
- return { kind: 'json_schema', value: JSON.stringify(schema) };
142
- }
143
- throw invalid(`response_format type ${JSON.stringify(raw['type'])} is not supported`, 'response_format');
144
- }
145
- function parseThinking(body, caps) {
146
- const kwargs = body['chat_template_kwargs'];
147
- if (isRecord(kwargs) && typeof kwargs['enable_thinking'] === 'boolean')
148
- return kwargs['enable_thinking'];
149
- const effort = body['reasoning_effort'];
150
- if (typeof effort === 'string')
151
- return effort !== 'none';
152
- return caps.reasoning;
153
- }
154
93
  /** A chat completions body, or `OpenAiRequestError` (400) naming the field it cannot serve. */
155
94
  export function parseChatRequest(raw, caps) {
156
95
  if (!isRecord(raw))
157
96
  throw invalid('The request body must be a JSON object.');
158
- const n = raw['n'];
159
- if (n !== undefined && n !== null && n !== 1)
160
- throw invalid('Only n: 1 is supported.', 'n');
161
- if (!Array.isArray(raw['messages']) || raw['messages'].length === 0)
162
- throw invalid('messages must be a non-empty array', 'messages');
97
+ const common = parseCommonChatRequest(raw, caps);
163
98
  const messages = convertMessages(raw['messages'], caps);
164
99
  let split = messages.length;
165
100
  while (split > 0 && messages[split - 1]?.['role'] === 'tool')
@@ -169,37 +104,17 @@ export function parseChatRequest(raw, caps) {
169
104
  throw invalid('The last message must be from the user or a tool.', 'messages');
170
105
  split--;
171
106
  }
172
- const toolChoice = raw['tool_choice'];
173
- if (toolChoice !== undefined && toolChoice !== null && toolChoice !== 'auto' && toolChoice !== 'none')
174
- throw invalid('Only tool_choice "auto" and "none" are supported.', 'tool_choice');
175
- const tools = Array.isArray(raw['tools']) && raw['tools'].length > 0 && toolChoice !== 'none' ? raw['tools'] : null;
176
- const streamOptions = raw['stream_options'];
177
- const stop = raw['stop'];
178
- const maxTokens = optionalNumber(raw, 'max_completion_tokens') ?? optionalNumber(raw, 'max_tokens');
179
- const temperature = optionalNumber(raw, 'temperature');
180
- const topP = optionalNumber(raw, 'top_p');
181
- const topK = optionalNumber(raw, 'top_k');
182
- const seed = optionalNumber(raw, 'seed');
183
107
  return {
184
108
  history: messages.slice(0, split),
185
109
  next: messages.slice(split),
186
- tools,
187
- stream: raw['stream'] === true,
188
- includeUsage: isRecord(streamOptions) && streamOptions['include_usage'] === true,
189
- sampler: {
190
- ...(temperature !== undefined ? { temperature } : {}),
191
- ...(topP !== undefined ? { topP } : {}),
192
- ...(topK !== undefined ? { topK: Math.round(topK) } : {}),
193
- ...(seed !== undefined ? { seed: Math.round(seed) } : {}),
194
- },
195
- ...(maxTokens !== undefined ? { maxTokens: Math.max(1, Math.round(maxTokens)) } : {}),
196
- stop: typeof stop === 'string'
197
- ? [stop]
198
- : Array.isArray(stop)
199
- ? stop.filter((s) => typeof s === 'string' && s)
200
- : [],
201
- responseFormat: parseResponseFormat(raw['response_format']),
202
- thinking: parseThinking(raw, caps),
110
+ tools: common.tools,
111
+ stream: common.stream,
112
+ includeUsage: common.includeUsage,
113
+ sampler: common.sampler,
114
+ ...(common.maxTokens !== undefined ? { maxTokens: common.maxTokens } : {}),
115
+ stop: common.stop,
116
+ responseFormat: common.responseFormat,
117
+ thinking: common.thinking,
203
118
  };
204
119
  }
205
120
  /** The library's words for a generation it ended at the token limit; not an error to the client. */