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

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.
@@ -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,
@@ -5,7 +5,7 @@ import { EmbeddingError, type EmbeddingModel } from "../embedder/index.js";
5
5
  import type { LogConfig, Logging } from "../logger/index.js";
6
6
  import { Store, graph, type TopicConfig } from "../store/index.js";
7
7
  import { HybridRetrieval } from "../retriever/index.js";
8
- import { JobRuntime, JobRegistry, type Handler, type JobDefinition } from "../workflow/index.js";
8
+ import { JobRuntime, JobRegistry, QueueStats, type Handler, type JobDefinition } from "../workflow/index.js";
9
9
  /** Topic-tree config (the store's schema, defaults decoded by the layer). */
10
10
  export type { TopicConfig } from "../store/index.js";
11
11
  /** Graph config (the store's schema — `graph.GraphConfig`). */
@@ -71,6 +71,9 @@ export interface Interface {
71
71
  readonly store: Store["Service"];
72
72
  readonly hybrid: HybridRetrieval["Service"];
73
73
  readonly runtime: JobRuntime["Service"];
74
+ /** Pending durable-queue elements per queue — drain visibility for the
75
+ * status surfaces (`dimple health`, `dimple://health`). */
76
+ readonly queueStats: QueueStats["Service"];
74
77
  readonly registry: JobRegistry["Service"];
75
78
  readonly models: ReadonlyMap<string, EmbeddingModelConfig>;
76
79
  readonly defaultModel: EmbeddingModelConfig;
@@ -2,7 +2,7 @@ import { Layer } from "effect";
2
2
  import { Store, DbBackend } from "../store/index.js";
3
3
  import { EmbeddingError, EmbeddingModelRegistry } from "../embedder/index.js";
4
4
  import { HybridRetrieval } from "../retriever/index.js";
5
- import { JobRuntime, JobRegistry } from "../workflow/index.js";
5
+ import { JobRuntime, JobRegistry, QueueStats } from "../workflow/index.js";
6
6
  import { Logging } from "../logger/index.js";
7
7
  import { Service as ConfigService } from "../config/index.js";
8
8
  import type { CoreOptions } from "./core.ts";
@@ -17,7 +17,7 @@ import { Service } from "./core.ts";
17
17
  * service (it runs fibers).
18
18
  */
19
19
  export type CoreGraphServices = Layer.Success<ReturnType<typeof layer>>;
20
- export declare const layer: (options: CoreOptions) => Layer.Layer<import("effect/persistence/PersistedQueue").PersistedQueueFactory | import("effect/persistence/Persistence").Persistence | Logging | DbBackend | JobRuntime | JobRegistry | Store | EmbeddingModelRegistry | HybridRetrieval | Service | import("effect/workflow/WorkflowEngine").WorkflowEngine, CoreConfigError | EmbeddingError | import("../retriever/index.js").HybridError | import("../workflow/index.js").RegistryError | import("effect/sql/SqlError").SqlError | import("../store/index.js").StoreError, never>;
20
+ export declare const layer: (options: CoreOptions) => Layer.Layer<import("effect/persistence/PersistedQueue").PersistedQueueFactory | import("effect/persistence/Persistence").Persistence | Logging | DbBackend | QueueStats | JobRuntime | JobRegistry | Store | EmbeddingModelRegistry | HybridRetrieval | Service | import("effect/workflow/WorkflowEngine").WorkflowEngine, CoreConfigError | EmbeddingError | import("../retriever/index.js").HybridError | import("../workflow/index.js").RegistryError | import("effect/sql/SqlError").SqlError | import("../store/index.js").StoreError, never>;
21
21
  /**
22
22
  * Config-driven variant — the `dimple.jsonc` path (the SDK's
23
23
  * `makeDimple({ config })`): reads the resolved `DimpleConfig` from
@@ -27,4 +27,4 @@ export declare const layer: (options: CoreOptions) => Layer.Layer<import("effect
27
27
  */
28
28
  export declare const layerConfig: (options?: {
29
29
  readonly migrationFolder?: string;
30
- }) => Layer.Layer<import("effect/persistence/PersistedQueue").PersistedQueueFactory | import("effect/persistence/Persistence").Persistence | Logging | DbBackend | JobRuntime | JobRegistry | Store | EmbeddingModelRegistry | HybridRetrieval | Service | import("effect/workflow/WorkflowEngine").WorkflowEngine, CoreConfigError | EmbeddingError | import("../retriever/index.js").HybridError | import("../workflow/index.js").RegistryError | import("effect/sql/SqlError").SqlError | import("../store/index.js").StoreError, ConfigService>;
30
+ }) => Layer.Layer<import("effect/persistence/PersistedQueue").PersistedQueueFactory | import("effect/persistence/Persistence").Persistence | Logging | DbBackend | QueueStats | JobRuntime | JobRegistry | Store | EmbeddingModelRegistry | HybridRetrieval | Service | import("effect/workflow/WorkflowEngine").WorkflowEngine, CoreConfigError | EmbeddingError | import("../retriever/index.js").HybridError | import("../workflow/index.js").RegistryError | import("effect/sql/SqlError").SqlError | import("../store/index.js").StoreError, ConfigService>;
@@ -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;
@@ -102,7 +102,7 @@ export declare const routeInsert: (memoryId: string, vector: ReadonlyArray<numbe
102
102
  * so the descents are bit-identical to sequential routeInsert calls
103
103
  * against the DB (same reads, same writes, same order).
104
104
  * 3. Applies ALL membership inserts + topic CF updates in ONE
105
- * transaction (per-topic deltas accumulated in memory).
105
+ * transaction (per-topic FINAL states accumulated in memory).
106
106
  * 4. Writes the derived sum vectors in ONE batched upsert (backend
107
107
  * `upsertTopicVectors`), still after commit (backend not
108
108
  * transaction-aware — see module docs).
@@ -31,6 +31,7 @@ import { Layer } from "effect";
31
31
  import { WorkflowEngine } from "effect/workflow";
32
32
  import { Persistence as PersistenceNamespace, PersistedQueue } from "effect/persistence";
33
33
  import { SqlError as SqlErrorNamespace } from "effect/sql";
34
+ import { Service as QueueStatsService } from "./stats.ts";
34
35
  type SqlError = SqlErrorNamespace.SqlError;
35
36
  /**
36
37
  * Durable WorkflowEngine layer.
@@ -50,7 +51,7 @@ export declare const layerDurable: Layer.Layer<WorkflowEngine.WorkflowEngine, ne
50
51
  */
51
52
  export declare const libsqlStack: (options: {
52
53
  readonly url: string;
53
- }) => Layer.Layer<PersistedQueue.PersistedQueueFactory | PersistenceNamespace.Persistence, SqlErrorNamespace.SqlError, never>;
54
+ }) => Layer.Layer<PersistedQueue.PersistedQueueFactory | PersistenceNamespace.Persistence | QueueStatsService, SqlErrorNamespace.SqlError, never>;
54
55
  /**
55
56
  * Convenience layer: durable engine + SQL persistence + resume queue + libSQL
56
57
  * client, all sharing one libSQL instance. Surfaces `SqlError` from the
@@ -71,7 +72,7 @@ export declare const layerDurableLibsql: (options: {
71
72
  */
72
73
  export declare const libsqlStackConfigured: (options: {
73
74
  readonly url: string;
74
- }) => import("../core/index.js").LayerProvider<PersistedQueue.PersistedQueueFactory | PersistenceNamespace.Persistence, SqlErrorNamespace.SqlError, undefined>;
75
+ }) => import("../core/index.js").LayerProvider<PersistedQueue.PersistedQueueFactory | PersistenceNamespace.Persistence | QueueStatsService, SqlErrorNamespace.SqlError, undefined>;
75
76
  export declare const layerDurableLibsqlConfigured: (options: {
76
77
  readonly url: string;
77
78
  }) => import("../core/index.js").LayerProvider<WorkflowEngine.WorkflowEngine, SqlErrorNamespace.SqlError, undefined>;
@@ -6,6 +6,7 @@
6
6
  export { JobDefinition, Envelope, TopicSplit, MemoryEmbed, MemoryEmbedBatch, TopicMerge, TopicRebalance, ConceptCluster, MemoryDream, GraphRepair, AuditWrite, type AuditRow, queues, type EnvelopeSchema, } from "./queue.ts";
7
7
  export { Service as JobRuntime, layer as jobRuntimeLayer, configured as jobRuntimeConfigured, node as jobRuntimeNode, type Interface as JobRuntimeInterface, type JobStatus, } from "./runtime.ts";
8
8
  export { layerDurable, layerDurableLibsql, libsqlStackConfigured, layerDurableLibsqlConfigured, } from "./engine.ts";
9
+ export { Service as QueueStats, layer as queueStatsLayer, type Interface as QueueStatsInterface, type QueueStat, } from "./stats.ts";
9
10
  export { Service as JobRegistry, layer as jobRegistryLayer, configured as jobRegistryConfigured, node as jobRegistryNode, JobFailure, type Handler, type JobContext, } from "./registry.ts";
10
11
  export { workerLayer, configured as workersConfigured, inline, processQueues } from "./executor.ts";
11
12
  export { JobsConfig, JobsConfigDefaults, resolveJobsConfig } from "./config.ts";
@@ -56,6 +56,7 @@ import { PersistedQueue, Persistence as PersistenceNamespace } from "effect/pers
56
56
  import { SqlError as SqlErrorNamespace } from "effect/sql";
57
57
  import { type JobDefinition } from "./queue.ts";
58
58
  import { type JobsError } from "./errors.ts";
59
+ import { Service as QueueStatsService } from "./stats.ts";
59
60
  type SqlError = SqlErrorNamespace.SqlError;
60
61
  /**
61
62
  * Lifecycle of a job from the caller's perspective.
@@ -157,7 +158,7 @@ export declare const layer: (defs: readonly JobDefinition.Any[]) => Layer.Layer<
157
158
  */
158
159
  export declare const layerLibsql: (defs: readonly JobDefinition.Any[], options: {
159
160
  readonly url: string;
160
- }) => Layer.Layer<Service | WorkflowEngine.WorkflowEngine | PersistenceNamespace.Persistence | PersistedQueue.PersistedQueueFactory, SqlError>;
161
+ }) => Layer.Layer<Service | WorkflowEngine.WorkflowEngine | PersistenceNamespace.Persistence | PersistedQueue.PersistedQueueFactory | QueueStatsService, SqlError>;
161
162
  /**
162
163
  * OpenCode-style node declaration for {@link layerLibsql}.
163
164
  *
@@ -167,7 +168,7 @@ export declare const layerLibsql: (defs: readonly JobDefinition.Any[], options:
167
168
  */
168
169
  export declare const configured: (defs: readonly JobDefinition.Any[], options: {
169
170
  readonly url: string;
170
- }) => import("../core/index.js").LayerProvider<PersistedQueue.PersistedQueueFactory | PersistenceNamespace.Persistence | Service | WorkflowEngine.WorkflowEngine, SqlErrorNamespace.SqlError, undefined>;
171
+ }) => import("../core/index.js").LayerProvider<PersistedQueue.PersistedQueueFactory | PersistenceNamespace.Persistence | QueueStatsService | Service | WorkflowEngine.WorkflowEngine, SqlErrorNamespace.SqlError, undefined>;
171
172
  /**
172
173
  * The default job-stack node — every built-in definition over the package's
173
174
  * documented jobs database default (`JobsConfigDefaults.dbUrl`,
@@ -175,5 +176,5 @@ export declare const configured: (defs: readonly JobDefinition.Any[], options: {
175
176
  * the `jobs` section omits `dbUrl`. Nothing is connected at import: the
176
177
  * node only holds a lazily-built layer.
177
178
  */
178
- export declare const node: import("../core/index.js").LayerProvider<PersistedQueue.PersistedQueueFactory | PersistenceNamespace.Persistence | Service | WorkflowEngine.WorkflowEngine, SqlErrorNamespace.SqlError, undefined>;
179
+ export declare const node: import("../core/index.js").LayerProvider<PersistedQueue.PersistedQueueFactory | PersistenceNamespace.Persistence | QueueStatsService | Service | WorkflowEngine.WorkflowEngine, SqlErrorNamespace.SqlError, undefined>;
179
180
  export {};
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Queue statistics — drain visibility for the status surfaces.
3
+ *
4
+ * The durable queue's own API (`PersistedQueueStore`: offer/take/cleanup)
5
+ * exposes no count, so pending work is invisible to callers once enqueued:
6
+ * after `memory_index` returns `pendingEmbeddings: N` an agent has no way to
7
+ * ask "how much is still draining?" — it guesses, sleeps, and retries.
8
+ *
9
+ * This service answers that with ONE grouped COUNT over the queue table
10
+ * (`effect_queue`, the table `PersistedQueue.layerStoreSql` creates). Only
11
+ * `state = 'pending'` rows are counted — offered but NOT YET FINISHED.
12
+ * Taking an element does not change its state (it stamps `acquired_at` /
13
+ * `acquired_by`); completion or failure moves it to `completed` / `failed`.
14
+ * So the count is "outstanding work", in-flight included. `completed` rows
15
+ * are dedup records and `failed` rows are dead letters — neither is counted.
16
+ *
17
+ * The internal {@link RESUME_QUEUE} is excluded by design: it carries
18
+ * cross-process wake-up signals for suspended executions, and a signal row
19
+ * outlives the work it points at (the engine resumes in-process too, leaving
20
+ * the durable row pending forever). Counting it would make "is anything
21
+ * still running?" unanswerable — the question this service exists for.
22
+ *
23
+ * It lives beside the stack that owns the queue (the same `SqlClient` the
24
+ * engine and queue store share), so the status surfaces can report drain
25
+ * state without opening a second connection or reaching into `jobs.db`.
26
+ */
27
+ import { Context, Effect, Layer } from "effect";
28
+ import { SqlClient, SqlError as SqlErrorNamespace } from "effect/sql";
29
+ type SqlError = SqlErrorNamespace.SqlError;
30
+ /** Pending elements for one queue (`DurableQueue/<job name>`, `dimple/resume`). */
31
+ export interface QueueStat {
32
+ readonly queue: string;
33
+ readonly pending: number;
34
+ }
35
+ export interface Interface {
36
+ /** Outstanding (offered, not yet finished) elements per queue, queue name
37
+ * ascending. */
38
+ readonly pending: () => Effect.Effect<readonly QueueStat[], SqlError>;
39
+ }
40
+ declare const Service_base: Context.ServiceClass<Service, "@dimple/workflow/QueueStats", Interface>;
41
+ export declare class Service extends Service_base {
42
+ }
43
+ export declare const layer: Layer.Layer<Service, never, SqlClient.SqlClient>;
44
+ export {};
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.14",
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": [