@ponraaj/dimple-sdk 0.0.0-alpha.3 → 0.0.0-alpha.4
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
CHANGED
|
@@ -19,8 +19,10 @@ npm install @ponraaj/dimple-sdk
|
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Runtime dependencies are the only things installed (Effect, libSQL,
|
|
22
|
-
Transformers.js, drizzle) — the workspace internals are
|
|
23
|
-
package
|
|
22
|
+
Transformers.js, drizzle) — the workspace internals (`@dimple/*`) are
|
|
23
|
+
bundled into the package, including fully **self-contained type
|
|
24
|
+
declarations** (the publish build vendors every internal d.ts and rewrites
|
|
25
|
+
the `@dimple/*` specifiers — plain consumers never need the workspace).
|
|
24
26
|
|
|
25
27
|
## Quickstart
|
|
26
28
|
|
|
@@ -80,7 +82,7 @@ Pass a config file path or an inline object:
|
|
|
80
82
|
|
|
81
83
|
```ts
|
|
82
84
|
const dimple = await makeDimple({ config: "./dimple.jsonc" });
|
|
83
|
-
// or
|
|
85
|
+
// or — the inline object mirrors the JSON config exactly (quoted keys):
|
|
84
86
|
const dimple = await makeDimple({
|
|
85
87
|
config: {
|
|
86
88
|
storeUrl: "file:./.dimple/dimple.db",
|
|
@@ -116,8 +118,9 @@ const dimple = await makeDimple({
|
|
|
116
118
|
|
|
117
119
|
### Embedding models
|
|
118
120
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
Two providers — **local** (Transformers.js ONNX, runs on your CPU, no
|
|
122
|
+
keys) and **hosted** (any OpenAI-compatible endpoint, plus native
|
|
123
|
+
provider families):
|
|
121
124
|
|
|
122
125
|
```jsonc
|
|
123
126
|
"embedding": {
|
|
@@ -128,11 +131,32 @@ provider):
|
|
|
128
131
|
{ "id": "bge", "provider": "transformers",
|
|
129
132
|
"model": "Xenova/bge-small-en-v1.5", "dimensions": 384 },
|
|
130
133
|
{ "id": "bge-base", "provider": "transformers",
|
|
131
|
-
"model": "Xenova/bge-base-en-v1.5", "dimensions": 768 }
|
|
134
|
+
"model": "Xenova/bge-base-en-v1.5", "dimensions": 768 },
|
|
135
|
+
{ "id": "gemini", "provider": "openai",
|
|
136
|
+
"model": "gemini-embedding-2", "dimensions": 3072, "apiKey": "…",
|
|
137
|
+
"baseURL": "https://generativelanguage.googleapis.com/v1beta/openai/" },
|
|
138
|
+
{ "id": "openai", "provider": "openai",
|
|
139
|
+
"model": "text-embedding-3-small", "dimensions": 1536, "apiKey": "…" }
|
|
132
140
|
]
|
|
133
141
|
}
|
|
134
142
|
```
|
|
135
143
|
|
|
144
|
+
**Hosted providers** — the config `provider` field selects the family:
|
|
145
|
+
|
|
146
|
+
| `provider` | Models | `baseURL` needed? |
|
|
147
|
+
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
|
|
148
|
+
| `openai` (default) | any OpenAI-compatible endpoint — OpenAI, vLLM, **ollama** (`http://localhost:11434/v1`), Ollama Cloud, LM Studio, Together, Fireworks, Groq, Mistral, … | optional (defaults to OpenAI) — set it for custom endpoints |
|
|
149
|
+
| `google` | `gemini-embedding-001`, `gemini-embedding-2`, `gemini-embedding-2-preview` (native provider) | ❌ no |
|
|
150
|
+
| `cohere` | `embed-english-v3.0`, `embed-multilingual-v3.0`, … (native provider) | ❌ no |
|
|
151
|
+
| `bedrock` | `amazon.titan-embed-text-v2:0`, `amazon.nova-embed-text-v2:0`, `cohere.embed-*` (native provider; AWS creds from env) | ❌ no |
|
|
152
|
+
|
|
153
|
+
`dimensions` is sent as a provider option where the API supports it
|
|
154
|
+
(openai-compatible/`outputDimensionality`/`outputDimension`/titan `dimensions`
|
|
155
|
+
and nova `embeddingDimension`) and ALWAYS enforced on the output.
|
|
156
|
+
Verified end-to-end against real `gemini-embedding-2` (3072-dim), local
|
|
157
|
+
ollama `Qwen3-Embedding-0.6B` (1024-dim), and the openai-compatible
|
|
158
|
+
contract.
|
|
159
|
+
|
|
136
160
|
- `dimensions` must match the model's real output — a mismatch fails typed
|
|
137
161
|
on first use
|
|
138
162
|
- Multiple models coexist: each gets its own vector tables
|
|
@@ -326,6 +350,11 @@ query history, persisted asynchronously (never blocks the query).
|
|
|
326
350
|
| Grammar WASMs | `~/.cache/dimple/tree-sitter/` (downloaded once, offline after) |
|
|
327
351
|
| ONNX model | bun/npm cache (~90 MB, first use) |
|
|
328
352
|
|
|
353
|
+
## Changelog
|
|
354
|
+
|
|
355
|
+
Every release creates a GitHub Release with the per-version changes (the
|
|
356
|
+
tag-based publish workflow): repo → **Releases** page.
|
|
357
|
+
|
|
329
358
|
## Notes
|
|
330
359
|
|
|
331
360
|
- Determinism: same data + same config ⇒ same tree, same clusters, same
|
package/dist/index.js
CHANGED
|
@@ -659,6 +659,7 @@ var EmbeddingModelConfig = Schema6.Struct({
|
|
|
659
659
|
dimensions: Schema6.Number,
|
|
660
660
|
vectorType: Schema6.optional(Schema6.String),
|
|
661
661
|
apiKey: Schema6.optional(Schema6.String),
|
|
662
|
+
baseURL: Schema6.optional(Schema6.String),
|
|
662
663
|
indexConfig: Schema6.optional(IndexConfig),
|
|
663
664
|
device: Schema6.optional(Schema6.Literals([
|
|
664
665
|
"auto",
|
|
@@ -6394,46 +6395,72 @@ var makeTransformersModel = (options = {}) => {
|
|
|
6394
6395
|
embedSingle: impl.embedSingle
|
|
6395
6396
|
};
|
|
6396
6397
|
};
|
|
6397
|
-
// ../embedder/src/
|
|
6398
|
-
import { Effect as Effect33 } from "effect";
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
|
|
6398
|
+
// ../embedder/src/registry.ts
|
|
6399
|
+
import { Effect as Effect33, Layer as Layer12 } from "effect";
|
|
6400
|
+
// ../core/src/hosted-embedding.ts
|
|
6401
|
+
import { embedMany } from "ai";
|
|
6402
|
+
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
|
|
6403
|
+
import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
6404
|
+
import { createCohere } from "@ai-sdk/cohere";
|
|
6405
|
+
import { createAmazonBedrock } from "@ai-sdk/amazon-bedrock";
|
|
6406
|
+
import { Effect as Effect34 } from "effect";
|
|
6407
|
+
var makeHostedEmbeddingModel = (options) => {
|
|
6408
|
+
const provider = options.provider ?? "openai";
|
|
6409
|
+
const model = provider === "google" ? createGoogleGenerativeAI({
|
|
6410
|
+
apiKey: options.apiKey,
|
|
6411
|
+
...options.baseURL !== undefined ? { baseURL: options.baseURL } : {}
|
|
6412
|
+
}).embedding(options.model) : provider === "cohere" ? createCohere({ apiKey: options.apiKey }).embedding(options.model) : provider === "bedrock" ? createAmazonBedrock({
|
|
6413
|
+
...options.apiKey !== undefined ? { apiKey: options.apiKey } : {}
|
|
6414
|
+
}).embedding(options.model) : createOpenAICompatible({
|
|
6415
|
+
name: "openaiCompatible",
|
|
6416
|
+
baseURL: options.baseURL ?? "https://api.openai.com/v1",
|
|
6417
|
+
apiKey: options.apiKey
|
|
6418
|
+
}).embeddingModel(options.model);
|
|
6419
|
+
const providerOptions = (() => {
|
|
6420
|
+
switch (provider) {
|
|
6421
|
+
case "google":
|
|
6422
|
+
return { google: { outputDimensionality: options.dimensions } };
|
|
6423
|
+
case "bedrock":
|
|
6424
|
+
if (options.model.startsWith("amazon.nova")) {
|
|
6425
|
+
return { bedrock: { embeddingDimension: options.dimensions } };
|
|
6416
6426
|
}
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
|
|
6427
|
+
if (options.model.startsWith("cohere.")) {
|
|
6428
|
+
return { bedrock: { inputType: "search_document" } };
|
|
6429
|
+
}
|
|
6430
|
+
return { bedrock: { dimensions: options.dimensions } };
|
|
6431
|
+
case "cohere":
|
|
6432
|
+
return [256, 512, 1024, 1536].includes(options.dimensions) ? { cohere: { inputType: "search_document", outputDimension: options.dimensions } } : { cohere: { inputType: "search_document" } };
|
|
6433
|
+
default:
|
|
6434
|
+
return { openaiCompatible: { dimensions: options.dimensions } };
|
|
6435
|
+
}
|
|
6436
|
+
})();
|
|
6437
|
+
const embed = Effect34.fn("HostedEmbedding.embed")(function* (texts) {
|
|
6438
|
+
const result = yield* Effect34.tryPromise({
|
|
6439
|
+
try: () => embedMany({ model, values: [...texts], providerOptions }),
|
|
6440
|
+
catch: (cause) => new EmbeddingError({ message: `hosted embedMany: ${cause}` })
|
|
6420
6441
|
});
|
|
6421
|
-
|
|
6442
|
+
for (const vector of result.embeddings) {
|
|
6443
|
+
if (vector.length !== options.dimensions) {
|
|
6444
|
+
return yield* new EmbeddingError({
|
|
6445
|
+
message: `hosted embedder dimension mismatch: endpoint returned ${vector.length} dims but config declares ${options.dimensions}`
|
|
6446
|
+
});
|
|
6447
|
+
}
|
|
6448
|
+
}
|
|
6449
|
+
return result.embeddings.map((e) => new Float32Array(e));
|
|
6422
6450
|
});
|
|
6423
|
-
const embedSingle =
|
|
6451
|
+
const embedSingle = Effect34.fn("HostedEmbedding.embedSingle")(function* (text4) {
|
|
6424
6452
|
const results = yield* embed([text4]);
|
|
6425
6453
|
return results[0];
|
|
6426
6454
|
});
|
|
6427
6455
|
return {
|
|
6428
6456
|
modelId: options.modelId,
|
|
6429
|
-
provider
|
|
6457
|
+
provider,
|
|
6430
6458
|
dimensions: options.dimensions,
|
|
6431
6459
|
embed,
|
|
6432
6460
|
embedSingle
|
|
6433
6461
|
};
|
|
6434
6462
|
};
|
|
6435
|
-
|
|
6436
|
-
import { Effect as Effect34, Layer as Layer12 } from "effect";
|
|
6463
|
+
|
|
6437
6464
|
// ../retriever/src/hybrid.ts
|
|
6438
6465
|
import { Context as Context10, Effect as Effect35, Layer as Layer13, Schema as Schema22 } from "effect";
|
|
6439
6466
|
|
|
@@ -6730,9 +6757,9 @@ ${schemaJson}`,
|
|
|
6730
6757
|
return { generateText, generateObject };
|
|
6731
6758
|
};
|
|
6732
6759
|
// ../llm/src/provider.ts
|
|
6733
|
-
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
|
|
6760
|
+
import { createOpenAICompatible as createOpenAICompatible2 } from "@ai-sdk/openai-compatible";
|
|
6734
6761
|
var openAICompatible = (options) => {
|
|
6735
|
-
const provider =
|
|
6762
|
+
const provider = createOpenAICompatible2({
|
|
6736
6763
|
baseURL: options.baseURL,
|
|
6737
6764
|
apiKey: options.apiKey,
|
|
6738
6765
|
name: options.name ?? "openai-compatible"
|
|
@@ -6835,11 +6862,13 @@ var embedderFromConfig = (model) => model.provider === "transformers" ? Effect39
|
|
|
6835
6862
|
...model.pooling !== undefined ? { pooling: model.pooling } : {},
|
|
6836
6863
|
...model.normalize !== undefined ? { normalize: model.normalize } : {},
|
|
6837
6864
|
...model.cacheDir !== undefined ? { cacheDir: model.cacheDir } : {}
|
|
6838
|
-
})) : model.provider === "openai" ? model.apiKey === undefined ? Effect39.fail(new EmbeddingError({ message: `OpenAI model ${model.id} requires an apiKey` })) : Effect39.succeed(
|
|
6865
|
+
})) : model.provider === "openai" ? model.apiKey === undefined ? Effect39.fail(new EmbeddingError({ message: `OpenAI model ${model.id} requires an apiKey` })) : Effect39.succeed(makeHostedEmbeddingModel({
|
|
6839
6866
|
modelId: model.id,
|
|
6840
6867
|
model: model.model,
|
|
6841
6868
|
dimensions: model.dimensions,
|
|
6842
|
-
apiKey: model.apiKey
|
|
6869
|
+
apiKey: model.apiKey,
|
|
6870
|
+
...model.provider !== "openai" ? { provider: model.provider } : {},
|
|
6871
|
+
...model.baseURL !== undefined ? { baseURL: model.baseURL } : {}
|
|
6843
6872
|
})) : Effect39.fail(new EmbeddingError({ message: `Unknown provider: ${model.provider}` }));
|
|
6844
6873
|
var layer13 = (options) => {
|
|
6845
6874
|
const topicConfig = Schema24.decodeUnknownSync(TopicConfig)(options.topics?.config ?? {});
|
|
@@ -13,6 +13,9 @@ export declare const EmbeddingModelConfig: Schema.Struct<{
|
|
|
13
13
|
readonly dimensions: Schema.Number;
|
|
14
14
|
readonly vectorType: Schema.optional<Schema.String>;
|
|
15
15
|
readonly apiKey: Schema.optional<Schema.String>;
|
|
16
|
+
/** Hosted providers: OpenAI-compatible endpoint override (default
|
|
17
|
+
* `https://api.openai.com/v1`). */
|
|
18
|
+
readonly baseURL: Schema.optional<Schema.String>;
|
|
16
19
|
readonly indexConfig: Schema.optional<Schema.Struct<{
|
|
17
20
|
readonly compressNeighbors: Schema.optional<Schema.String>;
|
|
18
21
|
readonly maxNeighbors: Schema.optional<Schema.Number>;
|
|
@@ -39,6 +42,9 @@ export declare const EmbeddingConfig: Schema.Struct<{
|
|
|
39
42
|
readonly dimensions: Schema.Number;
|
|
40
43
|
readonly vectorType: Schema.optional<Schema.String>;
|
|
41
44
|
readonly apiKey: Schema.optional<Schema.String>;
|
|
45
|
+
/** Hosted providers: OpenAI-compatible endpoint override (default
|
|
46
|
+
* `https://api.openai.com/v1`). */
|
|
47
|
+
readonly baseURL: Schema.optional<Schema.String>;
|
|
42
48
|
readonly indexConfig: Schema.optional<Schema.Struct<{
|
|
43
49
|
readonly compressNeighbors: Schema.optional<Schema.String>;
|
|
44
50
|
readonly maxNeighbors: Schema.optional<Schema.Number>;
|
|
@@ -128,6 +134,9 @@ export declare const DimpleConfig: Schema.Struct<{
|
|
|
128
134
|
readonly dimensions: Schema.Number;
|
|
129
135
|
readonly vectorType: Schema.optional<Schema.String>;
|
|
130
136
|
readonly apiKey: Schema.optional<Schema.String>;
|
|
137
|
+
/** Hosted providers: OpenAI-compatible endpoint override (default
|
|
138
|
+
* `https://api.openai.com/v1`). */
|
|
139
|
+
readonly baseURL: Schema.optional<Schema.String>;
|
|
131
140
|
readonly indexConfig: Schema.optional<Schema.Struct<{
|
|
132
141
|
readonly compressNeighbors: Schema.optional<Schema.String>;
|
|
133
142
|
readonly maxNeighbors: Schema.optional<Schema.Number>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type EmbeddingModel } from "./internal/embedder/index.js";
|
|
2
|
+
export interface HostedEmbeddingOptions {
|
|
3
|
+
readonly modelId: string;
|
|
4
|
+
readonly model: string;
|
|
5
|
+
readonly dimensions: number;
|
|
6
|
+
readonly apiKey: string;
|
|
7
|
+
/** The AI SDK provider family — see
|
|
8
|
+
* https://ai-sdk.dev/providers for the full provider list. */
|
|
9
|
+
readonly provider?: "openai" | "google" | "cohere" | "bedrock";
|
|
10
|
+
/** OpenAI-compatible endpoint override — ONLY needed for custom
|
|
11
|
+
* endpoints (vLLM/ollama/…). The preconfigured providers have their
|
|
12
|
+
* base URL baked in. */
|
|
13
|
+
readonly baseURL?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Hosted embeddings — the `ai` SDK IS the implementation (`embedMany`),
|
|
17
|
+
* this adapter only bridges it to the dimple `EmbeddingModel` interface.
|
|
18
|
+
*
|
|
19
|
+
* Provider mapping (config `provider` field):
|
|
20
|
+
* - `"openai"` — openai-compatible provider; `baseURL` defaults to
|
|
21
|
+
* `https://api.openai.com/v1`, override for any compatible endpoint
|
|
22
|
+
* - `"google"` — native `@ai-sdk/google` (gemini-embedding-*), no baseURL
|
|
23
|
+
* - `"cohere"` — native `@ai-sdk/cohere` (embed-*-v3.0), no baseURL
|
|
24
|
+
* - `"bedrock"` — native `@ai-sdk/amazon-bedrock` (titan/nova/cohere
|
|
25
|
+
* models), no baseURL — credentials come from AWS env (or the provider
|
|
26
|
+
* settings)
|
|
27
|
+
*
|
|
28
|
+
* `dimensions` is sent as a provider option where the API supports it
|
|
29
|
+
* (openaiCompatible.dimensions / google.outputDimensionality /
|
|
30
|
+
* cohere.outputDimension) and ALWAYS enforced on the output (some
|
|
31
|
+
* endpoints ignore the option).
|
|
32
|
+
*/
|
|
33
|
+
export declare const makeHostedEmbeddingModel: (options: HostedEmbeddingOptions) => EmbeddingModel;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export { Service as EmbeddingModelRegistry, type Interface as EmbeddingModelRegistryInterface, type EmbeddingModel, EmbeddingError, } from "./provider.ts";
|
|
2
2
|
export { layer as transformersEmbeddingLayer, layerConfig as transformersEmbeddingLayerConfig, makeTransformersModel, } from "./transformers.ts";
|
|
3
|
-
export { makeOpenAIModel } from "./openai.ts";
|
|
4
3
|
export { layer as registryLayer, type ModelSpec } from "./registry.ts";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ponraaj/dimple-sdk",
|
|
3
|
-
"version": "0.0.0-alpha.
|
|
3
|
+
"version": "0.0.0-alpha.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -29,26 +29,19 @@
|
|
|
29
29
|
"typecheck": "tsgo --noEmit"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@ai-sdk/
|
|
32
|
+
"@ai-sdk/amazon-bedrock": "^5.0.46",
|
|
33
|
+
"@ai-sdk/cohere": "^3",
|
|
34
|
+
"@ai-sdk/google": "^2",
|
|
35
|
+
"@ai-sdk/openai-compatible": "^3.0.21",
|
|
33
36
|
"@huggingface/transformers": "^4.2.0",
|
|
34
37
|
"@libsql/client": "^0.17.4",
|
|
35
|
-
"ai": "^
|
|
38
|
+
"ai": "^7.0.50",
|
|
36
39
|
"drizzle-orm": "^1.0.0-rc.4",
|
|
37
40
|
"effect": "4.0.0-beta.103",
|
|
38
41
|
"jsonc-parser": "^3.3.1",
|
|
39
42
|
"web-tree-sitter": "^0.26.9",
|
|
40
43
|
"zod": "^4.4.3"
|
|
41
44
|
},
|
|
42
|
-
"devDependencies": {
|
|
43
|
-
"@dimple/config": "0.0.0-alpha.1",
|
|
44
|
-
"@dimple/core": "0.0.0-alpha.1",
|
|
45
|
-
"@dimple/embedder": "0.0.0-alpha.1",
|
|
46
|
-
"@dimple/extractor": "0.0.0-alpha.1",
|
|
47
|
-
"@dimple/parser": "0.0.0-alpha.1",
|
|
48
|
-
"@dimple/retriever": "0.0.0-alpha.1",
|
|
49
|
-
"@dimple/store": "0.0.0-alpha.1",
|
|
50
|
-
"@dimple/workflow": "0.0.0-alpha.1"
|
|
51
|
-
},
|
|
52
45
|
"peerDependencies": {
|
|
53
46
|
"typescript": "^5"
|
|
54
47
|
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { type EmbeddingModel } from "./provider.ts";
|
|
2
|
-
export interface OpenAIOptions {
|
|
3
|
-
readonly modelId: string;
|
|
4
|
-
readonly model: string;
|
|
5
|
-
readonly dimensions: number;
|
|
6
|
-
readonly apiKey: string;
|
|
7
|
-
}
|
|
8
|
-
export declare const makeOpenAIModel: (options: OpenAIOptions) => EmbeddingModel;
|