@ponraaj/dimple-sdk 0.0.0-alpha.8 → 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 +5 -5
- package/dist/dimple.d.ts +4 -0
- package/dist/index.js +1155 -754
- package/dist/internal/store/db-backend.d.ts +21 -2
- package/dist/internal/store/service.d.ts +28 -1
- package/dist/internal/store/topics/routing.d.ts +33 -0
- package/dist/internal/workflow/signals.d.ts +20 -0
- package/package.json +1 -1
|
@@ -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";
|
|
@@ -110,6 +110,10 @@ export interface Interface {
|
|
|
110
110
|
readonly contentType?: string | ReadonlyArray<string>;
|
|
111
111
|
/** `false` suppresses the per-leg audit row (fused-row callers). */
|
|
112
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;
|
|
113
117
|
}) => Effect.Effect<ReadonlyArray<AugmentedMemory>, StoreError>;
|
|
114
118
|
readonly searchVector: (query: ReadonlyArray<number>, namespace: string, limit: number, opts?: {
|
|
115
119
|
readonly topicKeys?: ReadonlyArray<string>;
|
|
@@ -120,7 +124,16 @@ export interface Interface {
|
|
|
120
124
|
readonly contentType?: string | ReadonlyArray<string>;
|
|
121
125
|
/** `false` suppresses the per-leg audit row (fused-row callers). */
|
|
122
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;
|
|
123
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>;
|
|
124
137
|
/** The DB's tables + columns (`dimple db-schema` surface). */
|
|
125
138
|
readonly listSchema: () => Effect.Effect<ReadonlyArray<{
|
|
126
139
|
readonly table: string;
|
|
@@ -147,6 +160,20 @@ export interface Interface {
|
|
|
147
160
|
readonly updateEmbedding: (id: string, embedding: ReadonlyArray<number>, model: string, options?: {
|
|
148
161
|
readonly scanCandidates?: boolean;
|
|
149
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>;
|
|
150
177
|
readonly findStale: (model: string) => Effect.Effect<readonly string[], StoreError>;
|
|
151
178
|
readonly createConcept: (name: string, embedding: ReadonlyArray<number>) => Effect.Effect<Concept, StoreError>;
|
|
152
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;
|