@ponraaj/dimple-sdk 0.0.0-alpha.7 → 0.0.0-alpha.9
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/README.md +19 -18
- package/dist/dimple.d.ts +10 -0
- package/dist/index.js +1329 -786
- package/dist/internal/embedder/auto-install.d.ts +8 -33
- package/dist/internal/installer/index.d.ts +26 -0
- package/dist/internal/store/db-backend.d.ts +21 -2
- package/dist/internal/store/service.d.ts +36 -2
- package/dist/internal/store/topics/routing.d.ts +33 -0
- package/dist/internal/workflow/signals.d.ts +20 -0
- package/package.json +1 -1
|
@@ -1,35 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
* installs). When the config declares a `transformers` provider model,
|
|
7
|
-
* the intent is explicit — so the FIRST local-embed use installs the
|
|
8
|
-
* package automatically with the project's own package manager, instead
|
|
9
|
-
* of failing with a manual step.
|
|
10
|
-
*
|
|
11
|
-
* Safety notes:
|
|
12
|
-
* - The install is scoped to the detected project root (the manifest's
|
|
13
|
-
* directory) and uses the manager the project already uses.
|
|
14
|
-
* - EVERY install runs `--ignore-scripts` (npm/pnpm/yarn) or bun's
|
|
15
|
-
* default script-blocking — verified harmless: the onnxruntime-node
|
|
16
|
-
* binaries ship in the package; its postinstall is not required for
|
|
17
|
-
* embedding, and sharp is never loaded for text embeddings.
|
|
18
|
-
* - Failure (offline, restricted env) is a typed EmbeddingError with the
|
|
19
|
-
* manual command — never a crash.
|
|
20
|
-
*/
|
|
21
|
-
export type PackageManager = "bun" | "npm" | "pnpm" | "yarn";
|
|
22
|
-
export interface InstallTarget {
|
|
23
|
-
readonly pm: PackageManager;
|
|
24
|
-
readonly root: string;
|
|
25
|
-
}
|
|
26
|
-
/** Detect the project's package manager by walking UP from `cwd` for a
|
|
27
|
-
* lockfile (bun.lock/bun.lockb → bun, package-lock.json → npm,
|
|
28
|
-
* pnpm-lock.yaml → pnpm, yarn.lock → yarn). Falls back to bun + cwd. */
|
|
29
|
-
export declare const detectPackageManager: (cwd: string) => InstallTarget;
|
|
30
|
-
/** The install argv for a manager. `--ignore-scripts` on npm/pnpm/yarn:
|
|
31
|
-
* the blocked postinstalls are proven unnecessary for embedding (bun
|
|
32
|
-
* blocks them by default already). */
|
|
1
|
+
import { type PackageManager } from "./internal/installer/index.js";
|
|
2
|
+
export type { InstallTarget, PackageManager } from "./internal/installer/index.js";
|
|
3
|
+
export { detectPackageManager } from "./internal/installer/index.js";
|
|
4
|
+
/** The install argv for a manager with the transformers package (kept for
|
|
5
|
+
* callers/tests that assert the shape). */
|
|
33
6
|
export declare const installCommand: (pm: PackageManager) => readonly [string, ...string[]];
|
|
34
|
-
/**
|
|
7
|
+
/** Install transformers at the project root detected from `cwd`. The
|
|
8
|
+
* shared installer kills the child on timeout and dedups concurrent
|
|
9
|
+
* first-use installs; failures reject with the manual command. */
|
|
35
10
|
export declare const installTransformers: (cwd: string) => Promise<void>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type PackageManager = "bun" | "npm" | "pnpm" | "yarn";
|
|
2
|
+
export interface InstallTarget {
|
|
3
|
+
readonly pm: PackageManager;
|
|
4
|
+
readonly root: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class InstallerError extends Error {
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
/** Detect the project's package manager by walking UP from `cwd` for a
|
|
10
|
+
* lockfile. NO lockfile → npm (the most universal — a bun fallback broke
|
|
11
|
+
* Node-only machines with ENOENT). */
|
|
12
|
+
export declare const detectPackageManager: (cwd: string) => InstallTarget;
|
|
13
|
+
/** The executable name for a manager. win32 ships `.cmd` shims for
|
|
14
|
+
* npm/pnpm/yarn — the bare names fail with ENOENT. */
|
|
15
|
+
export declare const resolveExecutable: (pm: PackageManager, platform?: NodeJS.Platform) => string;
|
|
16
|
+
/** The base install argv for a manager. Scripts are skipped everywhere;
|
|
17
|
+
* pnpm at a workspace root additionally gets `-w`. */
|
|
18
|
+
export declare const installArgs: (pm: PackageManager, packages: readonly string[], root: string) => string[];
|
|
19
|
+
export interface InstallOptions {
|
|
20
|
+
readonly cwd?: string;
|
|
21
|
+
/** Hard deadline; the child is SIGKILLed when it trips (default 5 min). */
|
|
22
|
+
readonly timeoutMs?: number;
|
|
23
|
+
/** Injectable for tests (defaults to process.platform). */
|
|
24
|
+
readonly platform?: NodeJS.Platform;
|
|
25
|
+
}
|
|
26
|
+
export declare const installOptionalPeers: (packages: readonly string[], opts?: InstallOptions) => Promise<void>;
|
|
@@ -84,8 +84,12 @@ export interface Interface {
|
|
|
84
84
|
readonly listIsolatedMemories: (limit: number, modelKey?: string) => Effect.Effect<readonly Record<string, unknown>[], StoreError>;
|
|
85
85
|
readonly db: DrizzleDB;
|
|
86
86
|
readonly tables: StoreTables;
|
|
87
|
-
readonly ftsSearch: (query: string, namespace: string, limit: number, topicKeys?: ReadonlyArray<string>, modelKey?: string, contentType?: string | ReadonlyArray<string
|
|
88
|
-
|
|
87
|
+
readonly ftsSearch: (query: string, namespace: string, limit: number, topicKeys?: ReadonlyArray<string>, modelKey?: string, contentType?: string | ReadonlyArray<string>,
|
|
88
|
+
/** Include the 384-float `embedding` blob per row (default false —
|
|
89
|
+
* search results never need vectors; write paths read them via
|
|
90
|
+
* fetchMemoryVectors). */
|
|
91
|
+
includeEmbedding?: boolean) => Effect.Effect<readonly Record<string, unknown>[], StoreError>;
|
|
92
|
+
readonly vectorSearch: (query: ReadonlyArray<number>, namespace: string, limit: number, model: EmbeddingModelConfig, topicKeys?: ReadonlyArray<string>, contentType?: string | ReadonlyArray<string>, includeEmbedding?: boolean) => Effect.Effect<readonly Record<string, unknown>[], StoreError>;
|
|
89
93
|
readonly sweep: (namespace: string) => Effect.Effect<SweepResult, StoreError>;
|
|
90
94
|
/** The DB's tables + columns (`dimple db-schema` surface). */
|
|
91
95
|
readonly listSchema: () => Effect.Effect<ReadonlyArray<{
|
|
@@ -109,11 +113,26 @@ export interface Interface {
|
|
|
109
113
|
readonly graphNeighbors: (kind: "memory" | "topic" | "concept", id: string, opts?: GraphNeighborsOptions) => Effect.Effect<readonly Record<string, unknown>[], StoreError>;
|
|
110
114
|
readonly ensureVectorTable: (model: EmbeddingModelConfig) => Effect.Effect<void, StoreError>;
|
|
111
115
|
readonly insertVector: (memoryId: string, vector: ReadonlyArray<number>, model: EmbeddingModelConfig) => Effect.Effect<void, StoreError>;
|
|
116
|
+
/** Batch variant of `insertVector` — one multi-row statement (bulk
|
|
117
|
+
* ingest: per-memory statements dominate the write path). */
|
|
118
|
+
readonly insertVectors: (entries: ReadonlyArray<{
|
|
119
|
+
readonly memoryId: string;
|
|
120
|
+
readonly vector: ReadonlyArray<number>;
|
|
121
|
+
}>, model: EmbeddingModelConfig) => Effect.Effect<void, StoreError>;
|
|
112
122
|
readonly deleteVector: (memoryId: string, dimensions: number) => Effect.Effect<void, StoreError>;
|
|
113
123
|
readonly ensureTopicVectorTable: (model: EmbeddingModelConfig) => Effect.Effect<void, StoreError>;
|
|
114
124
|
readonly upsertTopicVector: (topicKey: string, sumVector: ReadonlyArray<number>, model: EmbeddingModelConfig) => Effect.Effect<void, StoreError>;
|
|
125
|
+
/** Batch variant of `upsertTopicVector` — one multi-row statement (the
|
|
126
|
+
* bulk-routing path: sequential per-key upserts dominate batch ingest). */
|
|
127
|
+
readonly upsertTopicVectors: (entries: ReadonlyArray<{
|
|
128
|
+
readonly topicKey: string;
|
|
129
|
+
readonly sumVector: ReadonlyArray<number>;
|
|
130
|
+
}>, model: EmbeddingModelConfig) => Effect.Effect<void, StoreError>;
|
|
115
131
|
readonly deleteTopicVectors: (model: EmbeddingModelConfig) => Effect.Effect<void, StoreError>;
|
|
116
132
|
readonly fetchTopicVectors: (model: EmbeddingModelConfig) => Effect.Effect<ReadonlyArray<TopicVectorRow>, StoreError>;
|
|
133
|
+
/** Single-row variant — the forget path's per-ancestor maintenance
|
|
134
|
+
* re-read the WHOLE table per level before (O(depth × N) decodes). */
|
|
135
|
+
readonly fetchTopicVector: (topicKey: string, model: EmbeddingModelConfig) => Effect.Effect<TopicVectorRow | undefined, StoreError>;
|
|
117
136
|
readonly fetchMemoryVectors: (memoryIds: ReadonlyArray<string>, model: EmbeddingModelConfig) => Effect.Effect<ReadonlyArray<MemoryVectorRow>, StoreError>;
|
|
118
137
|
readonly listMemoryIds: (model: EmbeddingModelConfig) => Effect.Effect<ReadonlyArray<string>, StoreError>;
|
|
119
138
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Context, Effect } from "effect";
|
|
2
|
-
import type { MemoryUnit, MemoryEvent, WriteMemoryInput, SweepResult, Concept } from "./models.ts";
|
|
2
|
+
import type { MemoryUnit, MemoryEvent, WriteMemoryInput, SweepResult, Concept, ScoredMemory } from "./models.ts";
|
|
3
3
|
import type { StoreError, NotFound, DuplicateActiveKey } from "./error.ts";
|
|
4
4
|
import type { TopicError } from "./topics/errors.ts";
|
|
5
5
|
import type { MaintenanceOutcome, RebalanceOutcome } from "./topics/maintenance.ts";
|
|
@@ -65,6 +65,11 @@ export interface ExplainResult {
|
|
|
65
65
|
}
|
|
66
66
|
export interface Interface {
|
|
67
67
|
readonly write: (input: WriteMemoryInput) => Effect.Effect<MemoryUnit, StoreError | DuplicateActiveKey>;
|
|
68
|
+
/** Bulk write: batch insert in ONE transaction (all-or-nothing; a
|
|
69
|
+
* duplicate logical key fails the whole batch with DuplicateActiveKey).
|
|
70
|
+
* The per-write graph candidate scan is NOT part of this — pair with
|
|
71
|
+
* `updateEmbedding(..., { scanCandidates: false })` for bulk ingest. */
|
|
72
|
+
readonly writeMany: (inputs: readonly WriteMemoryInput[]) => Effect.Effect<readonly MemoryUnit[], StoreError | DuplicateActiveKey>;
|
|
68
73
|
/** Upsert for the index path — the identity rule (same logical key ⇒
|
|
69
74
|
* confirmed `memory_supersedes`) made reachable for ACTIVE keys: demote
|
|
70
75
|
* the active holder of the key (if any), write the new unit, and link
|
|
@@ -105,6 +110,10 @@ export interface Interface {
|
|
|
105
110
|
readonly contentType?: string | ReadonlyArray<string>;
|
|
106
111
|
/** `false` suppresses the per-leg audit row (fused-row callers). */
|
|
107
112
|
readonly audit?: boolean;
|
|
113
|
+
/** Include the 384-float embedding on results (default false). */
|
|
114
|
+
readonly includeEmbedding?: boolean;
|
|
115
|
+
/** `false` skips the per-leg graph augmentation (fused-row callers). */
|
|
116
|
+
readonly augment?: boolean;
|
|
108
117
|
}) => Effect.Effect<ReadonlyArray<AugmentedMemory>, StoreError>;
|
|
109
118
|
readonly searchVector: (query: ReadonlyArray<number>, namespace: string, limit: number, opts?: {
|
|
110
119
|
readonly topicKeys?: ReadonlyArray<string>;
|
|
@@ -115,7 +124,16 @@ export interface Interface {
|
|
|
115
124
|
readonly contentType?: string | ReadonlyArray<string>;
|
|
116
125
|
/** `false` suppresses the per-leg audit row (fused-row callers). */
|
|
117
126
|
readonly audit?: boolean;
|
|
127
|
+
/** Include the 384-float embedding on results (default false). */
|
|
128
|
+
readonly includeEmbedding?: boolean;
|
|
129
|
+
/** `false` skips the per-leg graph augmentation (fused-row callers). */
|
|
130
|
+
readonly augment?: boolean;
|
|
118
131
|
}) => Effect.Effect<ReadonlyArray<AugmentedMemory>, StoreError>;
|
|
132
|
+
/** One-pass graph augmentation over an already-ranked result set (the
|
|
133
|
+
* hybrid path: the per-leg augment passes are skipped and the FUSED set
|
|
134
|
+
* gets one edge fetch + one concept fetch instead of two of each over
|
|
135
|
+
* 2× the rows). */
|
|
136
|
+
readonly augmentSearchResults: (results: ReadonlyArray<ScoredMemory>) => Effect.Effect<ReadonlyArray<AugmentedMemory>, StoreError>;
|
|
119
137
|
/** The DB's tables + columns (`dimple db-schema` surface). */
|
|
120
138
|
readonly listSchema: () => Effect.Effect<ReadonlyArray<{
|
|
121
139
|
readonly table: string;
|
|
@@ -139,7 +157,23 @@ export interface Interface {
|
|
|
139
157
|
readonly forget: (id: string) => Effect.Effect<void, NotFound | StoreError>;
|
|
140
158
|
readonly sweep: (namespace: string) => Effect.Effect<SweepResult, StoreError>;
|
|
141
159
|
readonly events: (memoryId: string) => Effect.Effect<readonly MemoryEvent[], StoreError>;
|
|
142
|
-
readonly updateEmbedding: (id: string, embedding: ReadonlyArray<number>, model: string
|
|
160
|
+
readonly updateEmbedding: (id: string, embedding: ReadonlyArray<number>, model: string, options?: {
|
|
161
|
+
readonly scanCandidates?: boolean;
|
|
162
|
+
}) => Effect.Effect<void, NotFound | StoreError>;
|
|
163
|
+
/** Bulk variant of `updateEmbedding` — the writeMany path. One
|
|
164
|
+
* transaction for all memory updates + events, batch vector insert,
|
|
165
|
+
* and `routeInsertMany` (tree read once, all insertions computed in
|
|
166
|
+
* memory, one transaction). For NEW memories: the idempotent re-embed
|
|
167
|
+
* decrement is deliberately NOT part of the batch (use
|
|
168
|
+
* `updateEmbedding` for re-embedding existing routed memories).
|
|
169
|
+
* `scanCandidates` defaults to false-ish via the config: it runs only
|
|
170
|
+
* when explicitly requested AND `graph.enabled` is not false. */
|
|
171
|
+
readonly updateEmbeddingMany: (entries: ReadonlyArray<{
|
|
172
|
+
readonly id: string;
|
|
173
|
+
readonly embedding: ReadonlyArray<number>;
|
|
174
|
+
}>, model: string, options?: {
|
|
175
|
+
readonly scanCandidates?: boolean;
|
|
176
|
+
}) => Effect.Effect<void, StoreError>;
|
|
143
177
|
readonly findStale: (model: string) => Effect.Effect<readonly string[], StoreError>;
|
|
144
178
|
readonly createConcept: (name: string, embedding: ReadonlyArray<number>) => Effect.Effect<Concept, StoreError>;
|
|
145
179
|
readonly getConcept: (id: string) => Effect.Effect<Concept, NotFound | StoreError>;
|
|
@@ -88,3 +88,36 @@ export declare const routeInsert: (memoryId: string, vector: ReadonlyArray<numbe
|
|
|
88
88
|
topicKey: string;
|
|
89
89
|
overflow: boolean;
|
|
90
90
|
}, TopicError | StoreError, DbBackend>;
|
|
91
|
+
/**
|
|
92
|
+
* Batch routing — the bulk-ingest path (`Store.updateEmbeddingMany`).
|
|
93
|
+
*
|
|
94
|
+
* Sequential `routeInsert` re-reads the WHOLE tree (all topics, all
|
|
95
|
+
* relations, all centroid sum-vectors) and commits its own transaction
|
|
96
|
+
* PER UNIT — measured ~42 ms/unit under bulk ingest, dominating the
|
|
97
|
+
* write path. This variant:
|
|
98
|
+
*
|
|
99
|
+
* 1. Reads the tree structure + sum-vectors ONCE.
|
|
100
|
+
* 2. Routes every entry against an IN-MEMORY mirror of the tree state,
|
|
101
|
+
* applying each unit's CF updates locally before the next descent —
|
|
102
|
+
* so the descents are bit-identical to sequential routeInsert calls
|
|
103
|
+
* against the DB (same reads, same writes, same order).
|
|
104
|
+
* 3. Applies ALL membership inserts + topic CF updates in ONE
|
|
105
|
+
* transaction (per-topic deltas accumulated in memory).
|
|
106
|
+
* 4. Writes the derived sum vectors in ONE batched upsert (backend
|
|
107
|
+
* `upsertTopicVectors`), still after commit (backend not
|
|
108
|
+
* transaction-aware — see module docs).
|
|
109
|
+
*
|
|
110
|
+
* Contract differences vs sequential: all-or-nothing (a validation
|
|
111
|
+
* failure or structural corruption rejects the whole batch), and the
|
|
112
|
+
* batch does NOT handle re-embedding (no membership decrement path) —
|
|
113
|
+
* it is for NEW memories; re-embedding existing ones goes through
|
|
114
|
+
* `routeInsert`/`Store.updateEmbedding`.
|
|
115
|
+
*/
|
|
116
|
+
export declare const routeInsertMany: (entries: readonly {
|
|
117
|
+
readonly memoryId: string;
|
|
118
|
+
readonly vector: ReadonlyArray<number>;
|
|
119
|
+
}[], model: EmbeddingModelConfig, config: TopicConfig) => Effect.Effect<readonly {
|
|
120
|
+
readonly memoryId: string;
|
|
121
|
+
readonly topicKey: string;
|
|
122
|
+
readonly overflow: boolean;
|
|
123
|
+
}[], TopicError | StoreError, DbBackend>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-process execution-completion signals — the event side of `Runtime.wait`.
|
|
3
|
+
*
|
|
4
|
+
* `wait` used to poll the persisted `${jobId}/result` key every 250ms. The
|
|
5
|
+
* engine knows the exact completion moment, so it now notifies a per-
|
|
6
|
+
* executionId set of Deferreds; `wait` races the signal against its poll
|
|
7
|
+
* interval (the poll stays as the fallback for cross-process waits, where
|
|
8
|
+
* the completing engine lives in another process).
|
|
9
|
+
*
|
|
10
|
+
* Plain module-level Map — no Effect service: the signal is a fire-and-
|
|
11
|
+
* forget wakeup, and the subscribers are runtime-layer Deferreds. Cleanup
|
|
12
|
+
* on unsubscribe keeps the map from leaking job ids.
|
|
13
|
+
*/
|
|
14
|
+
import { Deferred } from "effect";
|
|
15
|
+
/** Subscribe to one execution's completion. */
|
|
16
|
+
export declare const onExecutionDone: (executionId: string, deferred: Deferred.Deferred<void>) => void;
|
|
17
|
+
/** Unsubscribe (wait's finally — the poll fallback may still be running). */
|
|
18
|
+
export declare const offExecutionDone: (executionId: string, deferred: Deferred.Deferred<void>) => void;
|
|
19
|
+
/** Fire every subscriber's deferred (the engine's completion tap). */
|
|
20
|
+
export declare const notifyExecutionDone: (executionId: string) => void;
|