@ponraaj/dimple-sdk 0.0.0-alpha.12 → 0.0.0-alpha.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/errors.js CHANGED
@@ -840,6 +840,43 @@ var IndexConfig = Schema8.Struct({
840
840
  maxNeighbors: Schema8.optional(Schema8.Number),
841
841
  searchL: Schema8.optional(Schema8.Number)
842
842
  });
843
+ var ThreadCount = Schema8.Number.pipe(Schema8.refine((n) => Number.isInteger(n) && n >= 0 && n <= 1024, {
844
+ identifier: "ThreadCount"
845
+ }));
846
+ var SessionOptions = Schema8.Struct({
847
+ intraOpNumThreads: Schema8.optional(ThreadCount),
848
+ interOpNumThreads: Schema8.optional(ThreadCount),
849
+ executionMode: Schema8.optional(Schema8.Literals(["sequential", "parallel"])),
850
+ graphOptimizationLevel: Schema8.optional(Schema8.Literals(["disabled", "basic", "extended", "all", "layout"])),
851
+ enableCpuMemArena: Schema8.optional(Schema8.Boolean),
852
+ enableMemPattern: Schema8.optional(Schema8.Boolean),
853
+ gpuMemLimit: Schema8.optional(Schema8.Number),
854
+ arenaExtendStrategy: Schema8.optional(Schema8.Literals([0, 1]))
855
+ });
856
+ var mergeSessionOptions = (global, model) => {
857
+ const pick = (key) => model?.[key] ?? global?.[key];
858
+ const intraOpNumThreads = pick("intraOpNumThreads");
859
+ const interOpNumThreads = pick("interOpNumThreads");
860
+ const executionMode = pick("executionMode");
861
+ const graphOptimizationLevel = pick("graphOptimizationLevel");
862
+ const enableCpuMemArena = pick("enableCpuMemArena");
863
+ const enableMemPattern = pick("enableMemPattern");
864
+ const gpuMemLimit = pick("gpuMemLimit");
865
+ const arenaExtendStrategy = pick("arenaExtendStrategy");
866
+ const empty = intraOpNumThreads === undefined && interOpNumThreads === undefined && executionMode === undefined && graphOptimizationLevel === undefined && enableCpuMemArena === undefined && enableMemPattern === undefined && gpuMemLimit === undefined && arenaExtendStrategy === undefined;
867
+ if (empty)
868
+ return;
869
+ return {
870
+ ...intraOpNumThreads !== undefined ? { intraOpNumThreads } : undefined,
871
+ ...interOpNumThreads !== undefined ? { interOpNumThreads } : undefined,
872
+ ...executionMode !== undefined ? { executionMode } : undefined,
873
+ ...graphOptimizationLevel !== undefined ? { graphOptimizationLevel } : undefined,
874
+ ...enableCpuMemArena !== undefined ? { enableCpuMemArena } : undefined,
875
+ ...enableMemPattern !== undefined ? { enableMemPattern } : undefined,
876
+ ...gpuMemLimit !== undefined ? { gpuMemLimit } : undefined,
877
+ ...arenaExtendStrategy !== undefined ? { arenaExtendStrategy } : undefined
878
+ };
879
+ };
843
880
  var EmbeddingModelConfig = Schema8.Struct({
844
881
  id: Schema8.String,
845
882
  provider: Schema8.String,
@@ -877,14 +914,13 @@ var EmbeddingModelConfig = Schema8.Struct({
877
914
  pooling: Schema8.optional(Schema8.Literals(["mean", "cls", "none"])),
878
915
  normalize: Schema8.optional(Schema8.Boolean),
879
916
  cacheDir: Schema8.optional(Schema8.String),
880
- sessionOptions: Schema8.optional(Schema8.Struct({
881
- gpuMemLimit: Schema8.optional(Schema8.Number),
882
- arenaExtendStrategy: Schema8.optional(Schema8.Literals([0, 1]))
883
- })),
917
+ sessionOptions: Schema8.optional(SessionOptions),
918
+ wasm: Schema8.optional(Schema8.Struct({ numThreads: Schema8.optional(ThreadCount) })),
884
919
  autoInstall: Schema8.optional(Schema8.Boolean)
885
920
  });
886
921
  var EmbeddingConfig = Schema8.Struct({
887
922
  defaultModel: Schema8.String,
923
+ sessionOptions: Schema8.optional(SessionOptions),
888
924
  models: Schema8.Array(EmbeddingModelConfig)
889
925
  });
890
926
  var MaxAttempts = Schema8.Number.pipe(Schema8.refine((n) => Number.isInteger(n) && n > 0 && n <= 100, {
@@ -7423,16 +7459,32 @@ var importFromDisk = () => new Promise((resolve, reject) => {
7423
7459
  reject(cause);
7424
7460
  }
7425
7461
  });
7426
- var buildSessionOptions = (opts) => ({
7427
- executionProviders: [
7428
- {
7429
- name: "cuda",
7430
- device_id: 0,
7431
- ...opts.gpuMemLimit !== undefined ? { gpu_mem_limit: opts.gpuMemLimit } : undefined,
7432
- ...opts.arenaExtendStrategy !== undefined ? { arena_extend_strategy: opts.arenaExtendStrategy } : undefined
7433
- }
7434
- ]
7435
- });
7462
+ var buildSessionOptions = (opts) => {
7463
+ const cuda = opts.gpuMemLimit !== undefined || opts.arenaExtendStrategy !== undefined;
7464
+ return {
7465
+ enableCpuMemArena: opts.enableCpuMemArena ?? false,
7466
+ ...opts.intraOpNumThreads !== undefined ? { intraOpNumThreads: opts.intraOpNumThreads } : undefined,
7467
+ ...opts.interOpNumThreads !== undefined ? { interOpNumThreads: opts.interOpNumThreads } : undefined,
7468
+ ...opts.executionMode !== undefined ? { executionMode: opts.executionMode } : undefined,
7469
+ ...opts.graphOptimizationLevel !== undefined ? { graphOptimizationLevel: opts.graphOptimizationLevel } : undefined,
7470
+ ...opts.enableMemPattern !== undefined ? { enableMemPattern: opts.enableMemPattern } : undefined,
7471
+ ...cuda ? {
7472
+ executionProviders: [
7473
+ {
7474
+ name: "cuda",
7475
+ device_id: 0,
7476
+ ...opts.gpuMemLimit !== undefined ? { gpu_mem_limit: opts.gpuMemLimit } : undefined,
7477
+ ...opts.arenaExtendStrategy !== undefined ? { arena_extend_strategy: opts.arenaExtendStrategy } : undefined
7478
+ }
7479
+ ]
7480
+ } : undefined
7481
+ };
7482
+ };
7483
+ var applyWasmOptions = (env, wasm) => {
7484
+ if (wasm?.numThreads === undefined)
7485
+ return;
7486
+ env.backends.onnx.wasm.numThreads = wasm.numThreads;
7487
+ };
7436
7488
  var defaults2 = {
7437
7489
  modelId: "Xenova/all-MiniLM-L6-v2",
7438
7490
  device: "cpu",
@@ -7474,13 +7526,11 @@ var make6 = (options) => {
7474
7526
  }));
7475
7527
  if (options.cacheDir)
7476
7528
  transformers.env.cacheDir = options.cacheDir;
7529
+ applyWasmOptions(transformers.env, options.wasm);
7477
7530
  pipe = yield* Effect32.tryPromise(() => transformers.pipeline("feature-extraction", options.modelId ?? defaults2.modelId, {
7478
7531
  device: options.device ?? defaults2.device,
7479
7532
  dtype: options.dtype ?? defaults2.dtype,
7480
- session_options: {
7481
- enableCpuMemArena: false,
7482
- ...options.sessionOptions !== undefined ? buildSessionOptions(options.sessionOptions) : undefined
7483
- }
7533
+ session_options: buildSessionOptions(options.sessionOptions ?? {})
7484
7534
  })).pipe(Effect32.mapError((cause) => new EmbeddingError({ message: `load model: ${cause}` })));
7485
7535
  return pipe;
7486
7536
  });
@@ -8002,7 +8052,8 @@ var embedderFromConfig = (model) => model.provider === "transformers" ? Effect39
8002
8052
  ...model.normalize !== undefined ? { normalize: model.normalize } : undefined,
8003
8053
  ...model.cacheDir !== undefined ? { cacheDir: model.cacheDir } : undefined,
8004
8054
  ...model.autoInstall !== undefined ? { autoInstall: model.autoInstall } : undefined,
8005
- ...model.sessionOptions !== undefined ? { sessionOptions: model.sessionOptions } : undefined
8055
+ ...model.sessionOptions !== undefined ? { sessionOptions: model.sessionOptions } : undefined,
8056
+ ...model.wasm !== undefined ? { wasm: model.wasm } : undefined
8006
8057
  })) : model.provider === "openai" ? model.apiKey === undefined ? Effect39.fail(new EmbeddingError({ message: `OpenAI model ${model.id} requires an apiKey` })) : Effect39.succeed(makeHostedEmbeddingModel({
8007
8058
  modelId: model.id,
8008
8059
  model: model.model,
@@ -8174,6 +8225,13 @@ var layerConfig7 = (options) => Layer15.unwrap(Effect39.gen(function* () {
8174
8225
  });
8175
8226
  }
8176
8227
  const llm = cfg.config.llm;
8228
+ const models2 = embedding.models.map((model) => {
8229
+ const sessionOptions = mergeSessionOptions(embedding.sessionOptions, model.sessionOptions);
8230
+ return {
8231
+ ...model,
8232
+ ...sessionOptions !== undefined ? { sessionOptions } : undefined
8233
+ };
8234
+ });
8177
8235
  return layer13({
8178
8236
  storeUrl: cfg.config.storeUrl,
8179
8237
  ...cfg.config.defaultK !== undefined ? { defaultK: cfg.config.defaultK } : undefined,
@@ -8181,7 +8239,7 @@ var layerConfig7 = (options) => Layer15.unwrap(Effect39.gen(function* () {
8181
8239
  ...cfg.config.defaultTtlSecs !== undefined ? { defaultTtlSecs: cfg.config.defaultTtlSecs } : undefined,
8182
8240
  jobsUrl,
8183
8241
  ...options?.migrationFolder !== undefined ? { migrationFolder: options.migrationFolder } : undefined,
8184
- models: embedding.models,
8242
+ models: models2,
8185
8243
  defaultModelId: embedding.defaultModel,
8186
8244
  embedderFor: embedderFromConfig,
8187
8245
  ...cfg.config.topics !== undefined ? { topics: { config: cfg.config.topics } } : undefined,
package/dist/index.js CHANGED
@@ -840,6 +840,43 @@ var IndexConfig = Schema8.Struct({
840
840
  maxNeighbors: Schema8.optional(Schema8.Number),
841
841
  searchL: Schema8.optional(Schema8.Number)
842
842
  });
843
+ var ThreadCount = Schema8.Number.pipe(Schema8.refine((n) => Number.isInteger(n) && n >= 0 && n <= 1024, {
844
+ identifier: "ThreadCount"
845
+ }));
846
+ var SessionOptions = Schema8.Struct({
847
+ intraOpNumThreads: Schema8.optional(ThreadCount),
848
+ interOpNumThreads: Schema8.optional(ThreadCount),
849
+ executionMode: Schema8.optional(Schema8.Literals(["sequential", "parallel"])),
850
+ graphOptimizationLevel: Schema8.optional(Schema8.Literals(["disabled", "basic", "extended", "all", "layout"])),
851
+ enableCpuMemArena: Schema8.optional(Schema8.Boolean),
852
+ enableMemPattern: Schema8.optional(Schema8.Boolean),
853
+ gpuMemLimit: Schema8.optional(Schema8.Number),
854
+ arenaExtendStrategy: Schema8.optional(Schema8.Literals([0, 1]))
855
+ });
856
+ var mergeSessionOptions = (global, model) => {
857
+ const pick = (key) => model?.[key] ?? global?.[key];
858
+ const intraOpNumThreads = pick("intraOpNumThreads");
859
+ const interOpNumThreads = pick("interOpNumThreads");
860
+ const executionMode = pick("executionMode");
861
+ const graphOptimizationLevel = pick("graphOptimizationLevel");
862
+ const enableCpuMemArena = pick("enableCpuMemArena");
863
+ const enableMemPattern = pick("enableMemPattern");
864
+ const gpuMemLimit = pick("gpuMemLimit");
865
+ const arenaExtendStrategy = pick("arenaExtendStrategy");
866
+ const empty = intraOpNumThreads === undefined && interOpNumThreads === undefined && executionMode === undefined && graphOptimizationLevel === undefined && enableCpuMemArena === undefined && enableMemPattern === undefined && gpuMemLimit === undefined && arenaExtendStrategy === undefined;
867
+ if (empty)
868
+ return;
869
+ return {
870
+ ...intraOpNumThreads !== undefined ? { intraOpNumThreads } : undefined,
871
+ ...interOpNumThreads !== undefined ? { interOpNumThreads } : undefined,
872
+ ...executionMode !== undefined ? { executionMode } : undefined,
873
+ ...graphOptimizationLevel !== undefined ? { graphOptimizationLevel } : undefined,
874
+ ...enableCpuMemArena !== undefined ? { enableCpuMemArena } : undefined,
875
+ ...enableMemPattern !== undefined ? { enableMemPattern } : undefined,
876
+ ...gpuMemLimit !== undefined ? { gpuMemLimit } : undefined,
877
+ ...arenaExtendStrategy !== undefined ? { arenaExtendStrategy } : undefined
878
+ };
879
+ };
843
880
  var EmbeddingModelConfig = Schema8.Struct({
844
881
  id: Schema8.String,
845
882
  provider: Schema8.String,
@@ -877,14 +914,13 @@ var EmbeddingModelConfig = Schema8.Struct({
877
914
  pooling: Schema8.optional(Schema8.Literals(["mean", "cls", "none"])),
878
915
  normalize: Schema8.optional(Schema8.Boolean),
879
916
  cacheDir: Schema8.optional(Schema8.String),
880
- sessionOptions: Schema8.optional(Schema8.Struct({
881
- gpuMemLimit: Schema8.optional(Schema8.Number),
882
- arenaExtendStrategy: Schema8.optional(Schema8.Literals([0, 1]))
883
- })),
917
+ sessionOptions: Schema8.optional(SessionOptions),
918
+ wasm: Schema8.optional(Schema8.Struct({ numThreads: Schema8.optional(ThreadCount) })),
884
919
  autoInstall: Schema8.optional(Schema8.Boolean)
885
920
  });
886
921
  var EmbeddingConfig = Schema8.Struct({
887
922
  defaultModel: Schema8.String,
923
+ sessionOptions: Schema8.optional(SessionOptions),
888
924
  models: Schema8.Array(EmbeddingModelConfig)
889
925
  });
890
926
  var MaxAttempts = Schema8.Number.pipe(Schema8.refine((n) => Number.isInteger(n) && n > 0 && n <= 100, {
@@ -7423,16 +7459,32 @@ var importFromDisk = () => new Promise((resolve, reject) => {
7423
7459
  reject(cause);
7424
7460
  }
7425
7461
  });
7426
- var buildSessionOptions = (opts) => ({
7427
- executionProviders: [
7428
- {
7429
- name: "cuda",
7430
- device_id: 0,
7431
- ...opts.gpuMemLimit !== undefined ? { gpu_mem_limit: opts.gpuMemLimit } : undefined,
7432
- ...opts.arenaExtendStrategy !== undefined ? { arena_extend_strategy: opts.arenaExtendStrategy } : undefined
7433
- }
7434
- ]
7435
- });
7462
+ var buildSessionOptions = (opts) => {
7463
+ const cuda = opts.gpuMemLimit !== undefined || opts.arenaExtendStrategy !== undefined;
7464
+ return {
7465
+ enableCpuMemArena: opts.enableCpuMemArena ?? false,
7466
+ ...opts.intraOpNumThreads !== undefined ? { intraOpNumThreads: opts.intraOpNumThreads } : undefined,
7467
+ ...opts.interOpNumThreads !== undefined ? { interOpNumThreads: opts.interOpNumThreads } : undefined,
7468
+ ...opts.executionMode !== undefined ? { executionMode: opts.executionMode } : undefined,
7469
+ ...opts.graphOptimizationLevel !== undefined ? { graphOptimizationLevel: opts.graphOptimizationLevel } : undefined,
7470
+ ...opts.enableMemPattern !== undefined ? { enableMemPattern: opts.enableMemPattern } : undefined,
7471
+ ...cuda ? {
7472
+ executionProviders: [
7473
+ {
7474
+ name: "cuda",
7475
+ device_id: 0,
7476
+ ...opts.gpuMemLimit !== undefined ? { gpu_mem_limit: opts.gpuMemLimit } : undefined,
7477
+ ...opts.arenaExtendStrategy !== undefined ? { arena_extend_strategy: opts.arenaExtendStrategy } : undefined
7478
+ }
7479
+ ]
7480
+ } : undefined
7481
+ };
7482
+ };
7483
+ var applyWasmOptions = (env, wasm) => {
7484
+ if (wasm?.numThreads === undefined)
7485
+ return;
7486
+ env.backends.onnx.wasm.numThreads = wasm.numThreads;
7487
+ };
7436
7488
  var defaults2 = {
7437
7489
  modelId: "Xenova/all-MiniLM-L6-v2",
7438
7490
  device: "cpu",
@@ -7474,13 +7526,11 @@ var make6 = (options) => {
7474
7526
  }));
7475
7527
  if (options.cacheDir)
7476
7528
  transformers.env.cacheDir = options.cacheDir;
7529
+ applyWasmOptions(transformers.env, options.wasm);
7477
7530
  pipe = yield* Effect32.tryPromise(() => transformers.pipeline("feature-extraction", options.modelId ?? defaults2.modelId, {
7478
7531
  device: options.device ?? defaults2.device,
7479
7532
  dtype: options.dtype ?? defaults2.dtype,
7480
- session_options: {
7481
- enableCpuMemArena: false,
7482
- ...options.sessionOptions !== undefined ? buildSessionOptions(options.sessionOptions) : undefined
7483
- }
7533
+ session_options: buildSessionOptions(options.sessionOptions ?? {})
7484
7534
  })).pipe(Effect32.mapError((cause) => new EmbeddingError({ message: `load model: ${cause}` })));
7485
7535
  return pipe;
7486
7536
  });
@@ -8002,7 +8052,8 @@ var embedderFromConfig = (model) => model.provider === "transformers" ? Effect39
8002
8052
  ...model.normalize !== undefined ? { normalize: model.normalize } : undefined,
8003
8053
  ...model.cacheDir !== undefined ? { cacheDir: model.cacheDir } : undefined,
8004
8054
  ...model.autoInstall !== undefined ? { autoInstall: model.autoInstall } : undefined,
8005
- ...model.sessionOptions !== undefined ? { sessionOptions: model.sessionOptions } : undefined
8055
+ ...model.sessionOptions !== undefined ? { sessionOptions: model.sessionOptions } : undefined,
8056
+ ...model.wasm !== undefined ? { wasm: model.wasm } : undefined
8006
8057
  })) : model.provider === "openai" ? model.apiKey === undefined ? Effect39.fail(new EmbeddingError({ message: `OpenAI model ${model.id} requires an apiKey` })) : Effect39.succeed(makeHostedEmbeddingModel({
8007
8058
  modelId: model.id,
8008
8059
  model: model.model,
@@ -8174,6 +8225,13 @@ var layerConfig7 = (options) => Layer15.unwrap(Effect39.gen(function* () {
8174
8225
  });
8175
8226
  }
8176
8227
  const llm = cfg.config.llm;
8228
+ const models2 = embedding.models.map((model) => {
8229
+ const sessionOptions = mergeSessionOptions(embedding.sessionOptions, model.sessionOptions);
8230
+ return {
8231
+ ...model,
8232
+ ...sessionOptions !== undefined ? { sessionOptions } : undefined
8233
+ };
8234
+ });
8177
8235
  return layer13({
8178
8236
  storeUrl: cfg.config.storeUrl,
8179
8237
  ...cfg.config.defaultK !== undefined ? { defaultK: cfg.config.defaultK } : undefined,
@@ -8181,7 +8239,7 @@ var layerConfig7 = (options) => Layer15.unwrap(Effect39.gen(function* () {
8181
8239
  ...cfg.config.defaultTtlSecs !== undefined ? { defaultTtlSecs: cfg.config.defaultTtlSecs } : undefined,
8182
8240
  jobsUrl,
8183
8241
  ...options?.migrationFolder !== undefined ? { migrationFolder: options.migrationFolder } : undefined,
8184
- models: embedding.models,
8242
+ models: models2,
8185
8243
  defaultModelId: embedding.defaultModel,
8186
8244
  embedderFor: embedderFromConfig,
8187
8245
  ...cfg.config.topics !== undefined ? { topics: { config: cfg.config.topics } } : undefined,
@@ -1,4 +1,4 @@
1
- export { DimpleConfig, EmbeddingModelConfig, EmbeddingConfig, IndexConfig, JobsConfig, TopicsConfig, } from "./schema.ts";
2
- export type { DimpleConfig as DimpleConfigType, EmbeddingModelConfig as EmbeddingModelConfigType, EmbeddingConfig as EmbeddingConfigType, IndexConfig as IndexConfigType, JobsConfig as JobsConfigType, TopicsConfig as TopicsConfigType, } from "./schema.ts";
1
+ export { DimpleConfig, EmbeddingModelConfig, EmbeddingConfig, IndexConfig, JobsConfig, TopicsConfig, SessionOptions, mergeSessionOptions, } from "./schema.ts";
2
+ export type { DimpleConfig as DimpleConfigType, EmbeddingModelConfig as EmbeddingModelConfigType, EmbeddingConfig as EmbeddingConfigType, IndexConfig as IndexConfigType, JobsConfig as JobsConfigType, TopicsConfig as TopicsConfigType, SessionOptions as SessionOptionsType, } from "./schema.ts";
3
3
  export { Service, layer, configured as configConfigured, node as configNode } from "./service.ts";
4
4
  export { loadConfig, loadConfigFromFile } from "./loader.ts";
@@ -6,6 +6,30 @@ export declare const IndexConfig: Schema.Struct<{
6
6
  }>;
7
7
  export interface IndexConfig extends Schema.Schema.Type<typeof IndexConfig> {
8
8
  }
9
+ /** ONNX Runtime session options — one shared shape for the global default
10
+ * (`embedding.sessionOptions`) and the per-model override, so parallel
11
+ * ingest workers can split cores between processes. The CUDA keys stay flat
12
+ * (not nested under an EP name) for backward compatibility with the
13
+ * existing single-purpose configs. */
14
+ export declare const SessionOptions: Schema.Struct<{
15
+ readonly intraOpNumThreads: Schema.optional<Schema.refine<number, Schema.Number>>;
16
+ readonly interOpNumThreads: Schema.optional<Schema.refine<number, Schema.Number>>;
17
+ readonly executionMode: Schema.optional<Schema.Literals<readonly ["sequential", "parallel"]>>;
18
+ readonly graphOptimizationLevel: Schema.optional<Schema.Literals<readonly ["disabled", "basic", "extended", "all", "layout"]>>;
19
+ readonly enableCpuMemArena: Schema.optional<Schema.Boolean>;
20
+ readonly enableMemPattern: Schema.optional<Schema.Boolean>;
21
+ readonly gpuMemLimit: Schema.optional<Schema.Number>;
22
+ readonly arenaExtendStrategy: Schema.optional<Schema.Literals<readonly [0, 1]>>;
23
+ }>;
24
+ export interface SessionOptions extends Schema.Schema.Type<typeof SessionOptions> {
25
+ }
26
+ /** Precedence: built-in defaults → `embedding.sessionOptions` → the model
27
+ * block, merged FIELD BY FIELD, so a model can override one key while
28
+ * inheriting the rest. `??` only falls through on an ABSENT field, which
29
+ * keeps `false`/`0` model values overriding a global `true`/non-zero.
30
+ * `undefined` when both sides are absent — the embedder then forwards no
31
+ * session options at all. */
32
+ export declare const mergeSessionOptions: (global: SessionOptions | undefined, model: SessionOptions | undefined) => SessionOptions | undefined;
9
33
  export declare const EmbeddingModelConfig: Schema.Struct<{
10
34
  readonly id: Schema.String;
11
35
  readonly provider: Schema.String;
@@ -30,17 +54,32 @@ export declare const EmbeddingModelConfig: Schema.Struct<{
30
54
  readonly pooling: Schema.optional<Schema.Literals<readonly ["mean", "cls", "none"]>>;
31
55
  readonly normalize: Schema.optional<Schema.Boolean>;
32
56
  readonly cacheDir: Schema.optional<Schema.String>;
33
- /** ONNX Runtime CUDA session options — the verified fix for GPUs with
34
- * limited VRAM (≤8GB): ORT's default arena is unbounded and grows by
35
- * powers of two, so batch inference OOMs mid-run and poisons the
36
- * process for later queries. `gpuMemLimit` caps the arena (bytes);
37
- * `arenaExtendStrategy` picks the growth policy (0 = kNextPowerOfTwo,
38
- * 1 = kSameAsRequested). CPU / ample-VRAM GPUs are unaffected (ORT
39
- * defaults preserved when absent). */
57
+ /** ONNX Runtime session options — `intraOpNumThreads` /
58
+ * `interOpNumThreads` (0 = runtime default, else the per-session thread
59
+ * count), `executionMode`, `graphOptimizationLevel`,
60
+ * `enableCpuMemArena`, `enableMemPattern`, plus the CUDA pair: the
61
+ * verified fix for GPUs with limited VRAM (≤8GB), where ORT's default
62
+ * arena is unbounded and grows by powers of two, so batch inference OOMs
63
+ * mid-run and poisons the process for later queries. `gpuMemLimit` caps
64
+ * the arena (bytes); `arenaExtendStrategy` picks the growth policy
65
+ * (0 = kNextPowerOfTwo, 1 = kSameAsRequested). CPU / ample-VRAM GPUs are
66
+ * unaffected (ORT defaults preserved when absent). Merged over
67
+ * `embedding.sessionOptions` field by field. */
40
68
  readonly sessionOptions: Schema.optional<Schema.Struct<{
69
+ readonly intraOpNumThreads: Schema.optional<Schema.refine<number, Schema.Number>>;
70
+ readonly interOpNumThreads: Schema.optional<Schema.refine<number, Schema.Number>>;
71
+ readonly executionMode: Schema.optional<Schema.Literals<readonly ["sequential", "parallel"]>>;
72
+ readonly graphOptimizationLevel: Schema.optional<Schema.Literals<readonly ["disabled", "basic", "extended", "all", "layout"]>>;
73
+ readonly enableCpuMemArena: Schema.optional<Schema.Boolean>;
74
+ readonly enableMemPattern: Schema.optional<Schema.Boolean>;
41
75
  readonly gpuMemLimit: Schema.optional<Schema.Number>;
42
76
  readonly arenaExtendStrategy: Schema.optional<Schema.Literals<readonly [0, 1]>>;
43
77
  }>>;
78
+ /** ONNX Runtime WASM backend — its own thread knob, which intra-op
79
+ * threads do NOT reach. */
80
+ readonly wasm: Schema.optional<Schema.Struct<{
81
+ readonly numThreads: Schema.optional<Schema.refine<number, Schema.Number>>;
82
+ }>>;
44
83
  /** First-use auto-install of the optional `@huggingface/transformers`
45
84
  * peer (default true) — the package is installed with the project's
46
85
  * own package manager on the first local-embed use (scripts skipped,
@@ -52,6 +91,19 @@ export interface EmbeddingModelConfig extends Schema.Schema.Type<typeof Embeddin
52
91
  }
53
92
  export declare const EmbeddingConfig: Schema.Struct<{
54
93
  readonly defaultModel: Schema.String;
94
+ /** Session options every model inherits unless its own block overrides a
95
+ * field — the single knob for splitting cores across parallel ingest
96
+ * workers. */
97
+ readonly sessionOptions: Schema.optional<Schema.Struct<{
98
+ readonly intraOpNumThreads: Schema.optional<Schema.refine<number, Schema.Number>>;
99
+ readonly interOpNumThreads: Schema.optional<Schema.refine<number, Schema.Number>>;
100
+ readonly executionMode: Schema.optional<Schema.Literals<readonly ["sequential", "parallel"]>>;
101
+ readonly graphOptimizationLevel: Schema.optional<Schema.Literals<readonly ["disabled", "basic", "extended", "all", "layout"]>>;
102
+ readonly enableCpuMemArena: Schema.optional<Schema.Boolean>;
103
+ readonly enableMemPattern: Schema.optional<Schema.Boolean>;
104
+ readonly gpuMemLimit: Schema.optional<Schema.Number>;
105
+ readonly arenaExtendStrategy: Schema.optional<Schema.Literals<readonly [0, 1]>>;
106
+ }>>;
55
107
  readonly models: Schema.$Array<Schema.Struct<{
56
108
  readonly id: Schema.String;
57
109
  readonly provider: Schema.String;
@@ -76,17 +128,32 @@ export declare const EmbeddingConfig: Schema.Struct<{
76
128
  readonly pooling: Schema.optional<Schema.Literals<readonly ["mean", "cls", "none"]>>;
77
129
  readonly normalize: Schema.optional<Schema.Boolean>;
78
130
  readonly cacheDir: Schema.optional<Schema.String>;
79
- /** ONNX Runtime CUDA session options — the verified fix for GPUs with
80
- * limited VRAM (≤8GB): ORT's default arena is unbounded and grows by
81
- * powers of two, so batch inference OOMs mid-run and poisons the
82
- * process for later queries. `gpuMemLimit` caps the arena (bytes);
83
- * `arenaExtendStrategy` picks the growth policy (0 = kNextPowerOfTwo,
84
- * 1 = kSameAsRequested). CPU / ample-VRAM GPUs are unaffected (ORT
85
- * defaults preserved when absent). */
131
+ /** ONNX Runtime session options — `intraOpNumThreads` /
132
+ * `interOpNumThreads` (0 = runtime default, else the per-session thread
133
+ * count), `executionMode`, `graphOptimizationLevel`,
134
+ * `enableCpuMemArena`, `enableMemPattern`, plus the CUDA pair: the
135
+ * verified fix for GPUs with limited VRAM (≤8GB), where ORT's default
136
+ * arena is unbounded and grows by powers of two, so batch inference OOMs
137
+ * mid-run and poisons the process for later queries. `gpuMemLimit` caps
138
+ * the arena (bytes); `arenaExtendStrategy` picks the growth policy
139
+ * (0 = kNextPowerOfTwo, 1 = kSameAsRequested). CPU / ample-VRAM GPUs are
140
+ * unaffected (ORT defaults preserved when absent). Merged over
141
+ * `embedding.sessionOptions` field by field. */
86
142
  readonly sessionOptions: Schema.optional<Schema.Struct<{
143
+ readonly intraOpNumThreads: Schema.optional<Schema.refine<number, Schema.Number>>;
144
+ readonly interOpNumThreads: Schema.optional<Schema.refine<number, Schema.Number>>;
145
+ readonly executionMode: Schema.optional<Schema.Literals<readonly ["sequential", "parallel"]>>;
146
+ readonly graphOptimizationLevel: Schema.optional<Schema.Literals<readonly ["disabled", "basic", "extended", "all", "layout"]>>;
147
+ readonly enableCpuMemArena: Schema.optional<Schema.Boolean>;
148
+ readonly enableMemPattern: Schema.optional<Schema.Boolean>;
87
149
  readonly gpuMemLimit: Schema.optional<Schema.Number>;
88
150
  readonly arenaExtendStrategy: Schema.optional<Schema.Literals<readonly [0, 1]>>;
89
151
  }>>;
152
+ /** ONNX Runtime WASM backend — its own thread knob, which intra-op
153
+ * threads do NOT reach. */
154
+ readonly wasm: Schema.optional<Schema.Struct<{
155
+ readonly numThreads: Schema.optional<Schema.refine<number, Schema.Number>>;
156
+ }>>;
90
157
  /** First-use auto-install of the optional `@huggingface/transformers`
91
158
  * peer (default true) — the package is installed with the project's
92
159
  * own package manager on the first local-embed use (scripts skipped,
@@ -161,6 +228,19 @@ export declare const DimpleConfig: Schema.Struct<{
161
228
  readonly storeUrl: Schema.String;
162
229
  readonly embedding: Schema.optional<Schema.Struct<{
163
230
  readonly defaultModel: Schema.String;
231
+ /** Session options every model inherits unless its own block overrides a
232
+ * field — the single knob for splitting cores across parallel ingest
233
+ * workers. */
234
+ readonly sessionOptions: Schema.optional<Schema.Struct<{
235
+ readonly intraOpNumThreads: Schema.optional<Schema.refine<number, Schema.Number>>;
236
+ readonly interOpNumThreads: Schema.optional<Schema.refine<number, Schema.Number>>;
237
+ readonly executionMode: Schema.optional<Schema.Literals<readonly ["sequential", "parallel"]>>;
238
+ readonly graphOptimizationLevel: Schema.optional<Schema.Literals<readonly ["disabled", "basic", "extended", "all", "layout"]>>;
239
+ readonly enableCpuMemArena: Schema.optional<Schema.Boolean>;
240
+ readonly enableMemPattern: Schema.optional<Schema.Boolean>;
241
+ readonly gpuMemLimit: Schema.optional<Schema.Number>;
242
+ readonly arenaExtendStrategy: Schema.optional<Schema.Literals<readonly [0, 1]>>;
243
+ }>>;
164
244
  readonly models: Schema.$Array<Schema.Struct<{
165
245
  readonly id: Schema.String;
166
246
  readonly provider: Schema.String;
@@ -185,17 +265,32 @@ export declare const DimpleConfig: Schema.Struct<{
185
265
  readonly pooling: Schema.optional<Schema.Literals<readonly ["mean", "cls", "none"]>>;
186
266
  readonly normalize: Schema.optional<Schema.Boolean>;
187
267
  readonly cacheDir: Schema.optional<Schema.String>;
188
- /** ONNX Runtime CUDA session options — the verified fix for GPUs with
189
- * limited VRAM (≤8GB): ORT's default arena is unbounded and grows by
190
- * powers of two, so batch inference OOMs mid-run and poisons the
191
- * process for later queries. `gpuMemLimit` caps the arena (bytes);
192
- * `arenaExtendStrategy` picks the growth policy (0 = kNextPowerOfTwo,
193
- * 1 = kSameAsRequested). CPU / ample-VRAM GPUs are unaffected (ORT
194
- * defaults preserved when absent). */
268
+ /** ONNX Runtime session options — `intraOpNumThreads` /
269
+ * `interOpNumThreads` (0 = runtime default, else the per-session thread
270
+ * count), `executionMode`, `graphOptimizationLevel`,
271
+ * `enableCpuMemArena`, `enableMemPattern`, plus the CUDA pair: the
272
+ * verified fix for GPUs with limited VRAM (≤8GB), where ORT's default
273
+ * arena is unbounded and grows by powers of two, so batch inference OOMs
274
+ * mid-run and poisons the process for later queries. `gpuMemLimit` caps
275
+ * the arena (bytes); `arenaExtendStrategy` picks the growth policy
276
+ * (0 = kNextPowerOfTwo, 1 = kSameAsRequested). CPU / ample-VRAM GPUs are
277
+ * unaffected (ORT defaults preserved when absent). Merged over
278
+ * `embedding.sessionOptions` field by field. */
195
279
  readonly sessionOptions: Schema.optional<Schema.Struct<{
280
+ readonly intraOpNumThreads: Schema.optional<Schema.refine<number, Schema.Number>>;
281
+ readonly interOpNumThreads: Schema.optional<Schema.refine<number, Schema.Number>>;
282
+ readonly executionMode: Schema.optional<Schema.Literals<readonly ["sequential", "parallel"]>>;
283
+ readonly graphOptimizationLevel: Schema.optional<Schema.Literals<readonly ["disabled", "basic", "extended", "all", "layout"]>>;
284
+ readonly enableCpuMemArena: Schema.optional<Schema.Boolean>;
285
+ readonly enableMemPattern: Schema.optional<Schema.Boolean>;
196
286
  readonly gpuMemLimit: Schema.optional<Schema.Number>;
197
287
  readonly arenaExtendStrategy: Schema.optional<Schema.Literals<readonly [0, 1]>>;
198
288
  }>>;
289
+ /** ONNX Runtime WASM backend — its own thread knob, which intra-op
290
+ * threads do NOT reach. */
291
+ readonly wasm: Schema.optional<Schema.Struct<{
292
+ readonly numThreads: Schema.optional<Schema.refine<number, Schema.Number>>;
293
+ }>>;
199
294
  /** First-use auto-install of the optional `@huggingface/transformers`
200
295
  * peer (default true) — the package is installed with the project's
201
296
  * own package manager on the first local-embed use (scripts skipped,
@@ -1,3 +1,3 @@
1
1
  export { Service as EmbeddingModelRegistry, type Interface as EmbeddingModelRegistryInterface, type EmbeddingModel, EmbeddingError, } from "./provider.ts";
2
- export { layer as transformersEmbeddingLayer, layerConfig as transformersEmbeddingLayerConfig, makeTransformersModel, buildSessionOptions, } from "./transformers.ts";
2
+ export { layer as transformersEmbeddingLayer, layerConfig as transformersEmbeddingLayerConfig, makeTransformersModel, buildSessionOptions, applyWasmOptions, type SessionOptions, type TransformersEnv, type WasmOptions, } from "./transformers.ts";
3
3
  export { layer as registryLayer, configured as registryConfigured, type ModelSpec, } from "./registry.ts";
@@ -1,16 +1,42 @@
1
1
  import { Config, Layer } from "effect";
2
2
  import { Service, type EmbeddingModel } from "./provider.ts";
3
+ /** Mirror of transformers.js's `env` — `backends.onnx` is a shallow copy of
4
+ * ORT's env object, so `.wasm` is the LIVE nested object the runtime reads
5
+ * at session creation (hence assignable before the pipeline is built). */
6
+ export interface TransformersEnv {
7
+ cacheDir?: string;
8
+ backends: {
9
+ onnx: {
10
+ wasm: OrtWasmEnvFlags;
11
+ };
12
+ };
13
+ }
14
+ /** The ORT wasm env knobs dimple sets — `numThreads` is the wasm backend's
15
+ * own thread count (0 = system-determined, 1 = no worker threads), read
16
+ * when the session is created. */
17
+ export interface OrtWasmEnvFlags {
18
+ numThreads?: number;
19
+ }
20
+ /** Per-model wasm backend options. */
21
+ export interface WasmOptions {
22
+ readonly numThreads?: number | undefined;
23
+ }
3
24
  /** Mirror of transformers.js's `DeviceType` (the config schema carries the
4
25
  * same literals) — kept local so the optional peer's types never appear
5
26
  * in this module's surface. */
6
27
  type DeviceType = "auto" | "gpu" | "cpu" | "wasm" | "webgpu" | "cuda" | "dml" | "coreml" | "webnn";
7
28
  /** The ORT session-options shape transformers.js forwards to
8
- * onnxruntime-node (executionProviders with a bounded CUDA arena). */
29
+ * onnxruntime-node/web unchanged (ORT reads camelCase JS keys out of the
30
+ * snake_case `session_options` bag). Thread counts and the arena/pattern
31
+ * switches are what let parallel dimple processes split cores instead of
32
+ * each taking one thread per physical core. */
9
33
  interface OrtSessionOptions {
10
- /** ORT JS session options are camelCase; transformers.js reads them from
11
- * a snake_case `session_options` bag. The CPU arena pre-allocates and
12
- * holds memory across runs (onnxruntime#11627). */
13
34
  readonly enableCpuMemArena?: boolean;
35
+ readonly intraOpNumThreads?: number;
36
+ readonly interOpNumThreads?: number;
37
+ readonly executionMode?: "sequential" | "parallel";
38
+ readonly graphOptimizationLevel?: "disabled" | "basic" | "extended" | "all" | "layout";
39
+ readonly enableMemPattern?: boolean;
14
40
  readonly executionProviders?: readonly [
15
41
  {
16
42
  readonly name: string;
@@ -20,13 +46,30 @@ interface OrtSessionOptions {
20
46
  }
21
47
  ];
22
48
  }
23
- /** Map the focused dimple-level pair to ORT's snake_case session keys.
24
- * Both fields absent → `undefined`, so the caller can skip the whole
25
- * sessionOptions (ORT defaults preserved). */
26
- export declare const buildSessionOptions: (opts: {
49
+ /** ONNX Runtime session options — a structural mirror of `@dimple/config`'s
50
+ * `SessionOptions` (the embedder does not depend on config; the config
51
+ * schema carries the same field names). */
52
+ export interface SessionOptions {
53
+ readonly intraOpNumThreads?: number | undefined;
54
+ readonly interOpNumThreads?: number | undefined;
55
+ readonly executionMode?: "sequential" | "parallel" | undefined;
56
+ readonly graphOptimizationLevel?: "disabled" | "basic" | "extended" | "all" | "layout" | undefined;
57
+ readonly enableCpuMemArena?: boolean | undefined;
58
+ readonly enableMemPattern?: boolean | undefined;
27
59
  readonly gpuMemLimit?: number | undefined;
28
60
  readonly arenaExtendStrategy?: 0 | 1 | undefined;
29
- }) => OrtSessionOptions;
61
+ }
62
+ /** Map the dimple-level session options to ORT's session keys. Absent
63
+ * fields are omitted, so ORT keeps its own default; `enableCpuMemArena`
64
+ * always lands because it has a dimple default (bulk ingest does not need
65
+ * the arena). The CUDA execution provider is emitted ONLY when a CUDA key
66
+ * is present — injecting it unconditionally would pin every CPU-only model
67
+ * to a CUDA EP the runtime may not have. */
68
+ export declare const buildSessionOptions: (opts: SessionOptions) => OrtSessionOptions;
69
+ /** Map the wasm block onto transformers' ORT env, BEFORE the session is
70
+ * created — the wasm backend reads `numThreads` from its env, not from the
71
+ * session options, so `intraOpNumThreads` does not reach it. */
72
+ export declare const applyWasmOptions: (env: TransformersEnv, wasm: WasmOptions | undefined) => void;
30
73
  interface TransformersOptions {
31
74
  readonly modelId?: string;
32
75
  readonly device?: DeviceType;
@@ -34,16 +77,17 @@ interface TransformersOptions {
34
77
  readonly pooling?: "mean" | "cls" | "none";
35
78
  readonly normalize?: boolean;
36
79
  readonly cacheDir?: string;
37
- /** ONNX Runtime CUDA session options — the verified fix for GPUs with
38
- * limited VRAM (≤8GB): ORT's default arena is unbounded (grows by
39
- * powers of two), so batch inference OOMs mid-run and leaves the
40
- * process unable to allocate even a cublas handle afterwards. Forwarded
41
- * to the pipeline's `session_options`; absent = ORT defaults (CPU and
42
- * ample-VRAM GPUs unaffected). */
43
- readonly sessionOptions?: {
44
- readonly gpuMemLimit?: number | undefined;
45
- readonly arenaExtendStrategy?: 0 | 1 | undefined;
46
- };
80
+ /** ONNX Runtime session options — thread counts, arena/pattern switches,
81
+ * execution mode, graph optimization, and the CUDA pair (the verified fix
82
+ * for GPUs with limited VRAM (≤8GB): ORT's default arena is unbounded
83
+ * (grows by powers of two), so batch inference OOMs mid-run and leaves
84
+ * the process unable to allocate even a cublas handle afterwards).
85
+ * Forwarded to the pipeline's `session_options`; absent fields keep ORT's
86
+ * own defaults. */
87
+ readonly sessionOptions?: SessionOptions;
88
+ /** ONNX Runtime WASM backend options — applied to the ORT env before the
89
+ * session is created. */
90
+ readonly wasm?: WasmOptions;
47
91
  /** Declared output dimension — validated against the model's actual
48
92
  * output on first embed (a mismatch fails typed, precisely). */
49
93
  readonly dimensions?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ponraaj/dimple-sdk",
3
- "version": "0.0.0-alpha.12",
3
+ "version": "0.0.0-alpha.13",
4
4
  "private": false,
5
5
  "description": "Local-first memory for AI agents: durable text and code memories with hybrid semantic and lexical retrieval.",
6
6
  "keywords": [