@askdkc/kiokuko 0.2.6 → 0.2.8
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.ja.md +18 -0
- package/README.ko.md +17 -0
- package/README.md +23 -0
- package/README.zh-CN.md +16 -0
- package/dist/akinator/agent-task.d.ts +5 -0
- package/dist/akinator/agent-task.d.ts.map +1 -1
- package/dist/akinator/agent-task.js +98 -28
- package/dist/akinator/agent-task.js.map +1 -1
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +94 -8
- package/dist/cli.js.map +1 -1
- package/dist/commands/doctor.d.ts +4 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +46 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/embeddings.d.ts +26 -0
- package/dist/commands/embeddings.d.ts.map +1 -0
- package/dist/commands/embeddings.js +190 -0
- package/dist/commands/embeddings.js.map +1 -0
- package/dist/commands/import.d.ts.map +1 -1
- package/dist/commands/import.js +7 -0
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/use.d.ts.map +1 -1
- package/dist/commands/use.js +22 -8
- package/dist/commands/use.js.map +1 -1
- package/dist/config/paths.d.ts +5 -0
- package/dist/config/paths.d.ts.map +1 -1
- package/dist/config/paths.js +34 -0
- package/dist/config/paths.js.map +1 -1
- package/dist/context/broker.d.ts +3 -1
- package/dist/context/broker.d.ts.map +1 -1
- package/dist/context/broker.js +11 -7
- package/dist/context/broker.js.map +1 -1
- package/dist/context/delivery.d.ts.map +1 -1
- package/dist/context/delivery.js +5 -3
- package/dist/context/delivery.js.map +1 -1
- package/dist/context/ranking.d.ts +1 -1
- package/dist/context/ranking.d.ts.map +1 -1
- package/dist/context/ranking.js +1 -0
- package/dist/context/ranking.js.map +1 -1
- package/dist/context/scoped-broker.d.ts +4 -3
- package/dist/context/scoped-broker.d.ts.map +1 -1
- package/dist/context/scoped-broker.js +45 -7
- package/dist/context/scoped-broker.js.map +1 -1
- package/dist/context/selection-state.d.ts +12 -0
- package/dist/context/selection-state.d.ts.map +1 -1
- package/dist/context/selection-state.js +117 -7
- package/dist/context/selection-state.js.map +1 -1
- package/dist/db/capabilities.d.ts +8 -0
- package/dist/db/capabilities.d.ts.map +1 -1
- package/dist/db/capabilities.js +14 -0
- package/dist/db/capabilities.js.map +1 -1
- package/dist/db/connection.d.ts +7 -0
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +56 -0
- package/dist/db/connection.js.map +1 -1
- package/dist/db/migrate.d.ts.map +1 -1
- package/dist/db/migrate.js +3 -0
- package/dist/db/migrate.js.map +1 -1
- package/dist/embedding/backend.d.ts +27 -0
- package/dist/embedding/backend.d.ts.map +1 -0
- package/dist/embedding/backend.js +67 -0
- package/dist/embedding/backend.js.map +1 -0
- package/dist/embedding/config.d.ts +10 -0
- package/dist/embedding/config.d.ts.map +1 -0
- package/dist/embedding/config.js +142 -0
- package/dist/embedding/config.js.map +1 -0
- package/dist/embedding/diagnostics.d.ts +34 -0
- package/dist/embedding/diagnostics.d.ts.map +1 -0
- package/dist/embedding/diagnostics.js +263 -0
- package/dist/embedding/diagnostics.js.map +1 -0
- package/dist/embedding/document.d.ts +20 -0
- package/dist/embedding/document.d.ts.map +1 -0
- package/dist/embedding/document.js +122 -0
- package/dist/embedding/document.js.map +1 -0
- package/dist/embedding/javascript-backend.d.ts +11 -0
- package/dist/embedding/javascript-backend.d.ts.map +1 -0
- package/dist/embedding/javascript-backend.js +164 -0
- package/dist/embedding/javascript-backend.js.map +1 -0
- package/dist/embedding/jobs.d.ts +67 -0
- package/dist/embedding/jobs.d.ts.map +1 -0
- package/dist/embedding/jobs.js +259 -0
- package/dist/embedding/jobs.js.map +1 -0
- package/dist/embedding/local-model-loader.d.ts +24 -0
- package/dist/embedding/local-model-loader.d.ts.map +1 -0
- package/dist/embedding/local-model-loader.js +64 -0
- package/dist/embedding/local-model-loader.js.map +1 -0
- package/dist/embedding/local-transformers-provider.d.ts +17 -0
- package/dist/embedding/local-transformers-provider.d.ts.map +1 -0
- package/dist/embedding/local-transformers-provider.js +54 -0
- package/dist/embedding/local-transformers-provider.js.map +1 -0
- package/dist/embedding/model-download.d.ts +32 -0
- package/dist/embedding/model-download.d.ts.map +1 -0
- package/dist/embedding/model-download.js +41 -0
- package/dist/embedding/model-download.js.map +1 -0
- package/dist/embedding/model-installation.d.ts +17 -0
- package/dist/embedding/model-installation.d.ts.map +1 -0
- package/dist/embedding/model-installation.js +71 -0
- package/dist/embedding/model-installation.js.map +1 -0
- package/dist/embedding/model-manifest.d.ts +18 -0
- package/dist/embedding/model-manifest.d.ts.map +1 -0
- package/dist/embedding/model-manifest.js +86 -0
- package/dist/embedding/model-manifest.js.map +1 -0
- package/dist/embedding/openai-compatible-provider.d.ts +24 -0
- package/dist/embedding/openai-compatible-provider.d.ts.map +1 -0
- package/dist/embedding/openai-compatible-provider.js +330 -0
- package/dist/embedding/openai-compatible-provider.js.map +1 -0
- package/dist/embedding/presets/local-small.d.ts +8 -0
- package/dist/embedding/presets/local-small.d.ts.map +1 -0
- package/dist/embedding/presets/local-small.js +67 -0
- package/dist/embedding/presets/local-small.js.map +1 -0
- package/dist/embedding/presets/manifest.d.ts +27 -0
- package/dist/embedding/presets/manifest.d.ts.map +1 -0
- package/dist/embedding/presets/manifest.js +5 -0
- package/dist/embedding/presets/manifest.js.map +1 -0
- package/dist/embedding/profile.d.ts +10 -0
- package/dist/embedding/profile.d.ts.map +1 -0
- package/dist/embedding/profile.js +67 -0
- package/dist/embedding/profile.js.map +1 -0
- package/dist/embedding/provider.d.ts +13 -0
- package/dist/embedding/provider.d.ts.map +1 -0
- package/dist/embedding/provider.js +17 -0
- package/dist/embedding/provider.js.map +1 -0
- package/dist/embedding/query-cache.d.ts +45 -0
- package/dist/embedding/query-cache.d.ts.map +1 -0
- package/dist/embedding/query-cache.js +181 -0
- package/dist/embedding/query-cache.js.map +1 -0
- package/dist/embedding/runtime.d.ts +14 -0
- package/dist/embedding/runtime.d.ts.map +1 -0
- package/dist/embedding/runtime.js +407 -0
- package/dist/embedding/runtime.js.map +1 -0
- package/dist/embedding/settings.d.ts +6 -0
- package/dist/embedding/settings.d.ts.map +1 -0
- package/dist/embedding/settings.js +69 -0
- package/dist/embedding/settings.js.map +1 -0
- package/dist/embedding/setup-lock.d.ts +7 -0
- package/dist/embedding/setup-lock.d.ts.map +1 -0
- package/dist/embedding/setup-lock.js +35 -0
- package/dist/embedding/setup-lock.js.map +1 -0
- package/dist/embedding/setup-service.d.ts +53 -0
- package/dist/embedding/setup-service.d.ts.map +1 -0
- package/dist/embedding/setup-service.js +184 -0
- package/dist/embedding/setup-service.js.map +1 -0
- package/dist/embedding/sqlite-vec-backend.d.ts +9 -0
- package/dist/embedding/sqlite-vec-backend.d.ts.map +1 -0
- package/dist/embedding/sqlite-vec-backend.js +106 -0
- package/dist/embedding/sqlite-vec-backend.js.map +1 -0
- package/dist/embedding/sqlite-vec-loader.d.ts +17 -0
- package/dist/embedding/sqlite-vec-loader.d.ts.map +1 -0
- package/dist/embedding/sqlite-vec-loader.js +51 -0
- package/dist/embedding/sqlite-vec-loader.js.map +1 -0
- package/dist/embedding/store.d.ts +66 -0
- package/dist/embedding/store.d.ts.map +1 -0
- package/dist/embedding/store.js +490 -0
- package/dist/embedding/store.js.map +1 -0
- package/dist/embedding/types.d.ts +126 -0
- package/dist/embedding/types.d.ts.map +1 -0
- package/dist/embedding/types.js +2 -0
- package/dist/embedding/types.js.map +1 -0
- package/dist/embedding/vector.d.ts +9 -0
- package/dist/embedding/vector.d.ts.map +1 -0
- package/dist/embedding/vector.js +90 -0
- package/dist/embedding/vector.js.map +1 -0
- package/dist/embedding/worker.d.ts +23 -0
- package/dist/embedding/worker.d.ts.map +1 -0
- package/dist/embedding/worker.js +84 -0
- package/dist/embedding/worker.js.map +1 -0
- package/dist/enno-oduno/schemas.d.ts +2 -2
- package/dist/ledger/checkpoint-contract.d.ts +2 -2
- package/dist/mcp/bounded-stdio-transport.d.ts +3 -0
- package/dist/mcp/bounded-stdio-transport.d.ts.map +1 -1
- package/dist/mcp/bounded-stdio-transport.js +15 -3
- package/dist/mcp/bounded-stdio-transport.js.map +1 -1
- package/dist/mcp/request-deadline.d.ts +51 -0
- package/dist/mcp/request-deadline.d.ts.map +1 -0
- package/dist/mcp/request-deadline.js +155 -0
- package/dist/mcp/request-deadline.js.map +1 -0
- package/dist/mcp/runtime-owner.d.ts +27 -0
- package/dist/mcp/runtime-owner.d.ts.map +1 -0
- package/dist/mcp/runtime-owner.js +129 -0
- package/dist/mcp/runtime-owner.js.map +1 -0
- package/dist/mcp/server.d.ts +11 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +83 -22
- package/dist/mcp/server.js.map +1 -1
- package/dist/memory/checkpoint-contract.d.ts +3 -3
- package/dist/memory/entries.d.ts.map +1 -1
- package/dist/memory/entries.js +13 -0
- package/dist/memory/entries.js.map +1 -1
- package/dist/memory/federated-retrieval.d.ts +3 -2
- package/dist/memory/federated-retrieval.d.ts.map +1 -1
- package/dist/memory/federated-retrieval.js +112 -31
- package/dist/memory/federated-retrieval.js.map +1 -1
- package/dist/memory/hybrid-retrieval.d.ts +9 -2
- package/dist/memory/hybrid-retrieval.d.ts.map +1 -1
- package/dist/memory/hybrid-retrieval.js +60 -13
- package/dist/memory/hybrid-retrieval.js.map +1 -1
- package/dist/memory/retrieval.d.ts +4 -3
- package/dist/memory/retrieval.d.ts.map +1 -1
- package/dist/memory/retrieval.js +6 -6
- package/dist/memory/retrieval.js.map +1 -1
- package/dist/memory/scoped-memory.d.ts +3 -2
- package/dist/memory/scoped-memory.d.ts.map +1 -1
- package/dist/memory/scoped-memory.js +7 -3
- package/dist/memory/scoped-memory.js.map +1 -1
- package/dist/server/agent-application.js +1 -1
- package/dist/server/agent-application.js.map +1 -1
- package/dist/server/http.d.ts +17 -1
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +79 -13
- package/dist/server/http.js.map +1 -1
- package/dist/skills/discovery-service.d.ts.map +1 -1
- package/dist/skills/discovery-service.js +10 -8
- package/dist/skills/discovery-service.js.map +1 -1
- package/dist/skills/find.d.ts +1 -0
- package/dist/skills/find.d.ts.map +1 -1
- package/dist/skills/find.js +1 -0
- package/dist/skills/find.js.map +1 -1
- package/dist/skills/materialization-authority.d.ts +1 -1
- package/dist/skills/materialization-authority.d.ts.map +1 -1
- package/dist/skills/materialization-authority.js +2 -2
- package/dist/skills/materialization-authority.js.map +1 -1
- package/dist/skills/providers/skills-sh-compat.d.ts.map +1 -1
- package/dist/skills/providers/skills-sh-compat.js +4 -2
- package/dist/skills/providers/skills-sh-compat.js.map +1 -1
- package/dist/skills/providers/skills-sh-v1.d.ts +2 -2
- package/dist/skills/providers/skills-sh-v1.d.ts.map +1 -1
- package/dist/skills/providers/skills-sh-v1.js +22 -4
- package/dist/skills/providers/skills-sh-v1.js.map +1 -1
- package/dist/skills/source/github-fetcher.d.ts.map +1 -1
- package/dist/skills/source/github-fetcher.js +8 -4
- package/dist/skills/source/github-fetcher.js.map +1 -1
- package/dist/skills/types.d.ts +3 -2
- package/dist/skills/types.d.ts.map +1 -1
- package/docs/agent-file.md +72 -0
- package/docs/agent-gateway.md +104 -0
- package/docs/architecture.md +12 -0
- package/docs/cli-contract.md +13 -0
- package/docs/client-compatibility.md +298 -0
- package/docs/database.md +11 -0
- package/docs/execution-ledger.md +89 -0
- package/docs/release-notes-0.1.18.md +103 -0
- package/docs/retrieval-evaluation.md +10 -0
- package/docs/security.md +11 -0
- package/docs/sqlite-driver-adr.md +8 -0
- package/migrations/021_semantic_embeddings.sql +122 -0
- package/migrations/022_embedding_setup_v2.sql +236 -0
- package/migrations/down/021_semantic_embeddings.sql +17 -0
- package/migrations/down/022_embedding_setup_v2.sql +133 -0
- package/package.json +10 -1
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { KiokukoError } from '../errors.js';
|
|
2
|
+
import { parseEmbeddingConfig, isEnabledEmbeddingConfig } from './config.js';
|
|
3
|
+
import { embeddingProfileId, createEmbeddingProfile } from './profile.js';
|
|
4
|
+
import { readActiveEmbeddingProfile, readEmbeddingRuntimeState } from './store.js';
|
|
5
|
+
import { decodeVector, hashVectorBytes } from './vector.js';
|
|
6
|
+
import { readPersistedEmbeddingSettings } from './settings.js';
|
|
7
|
+
const EMBEDDING_TABLES = [
|
|
8
|
+
'embedding_profiles',
|
|
9
|
+
'embedding_runtime',
|
|
10
|
+
'entry_embeddings',
|
|
11
|
+
'embedding_jobs',
|
|
12
|
+
'query_embeddings',
|
|
13
|
+
];
|
|
14
|
+
const EMBEDDING_INDEXES = [
|
|
15
|
+
'idx_entry_embeddings_profile_revision',
|
|
16
|
+
'idx_embedding_jobs_claim',
|
|
17
|
+
'idx_query_embeddings_lru',
|
|
18
|
+
];
|
|
19
|
+
function countRows(database, sql, ...parameters) {
|
|
20
|
+
return Number(database.prepare(sql).get(...parameters)?.count ?? 0);
|
|
21
|
+
}
|
|
22
|
+
function objectNames(database, kind) {
|
|
23
|
+
return new Set(database.prepare(`
|
|
24
|
+
SELECT name FROM sqlite_schema WHERE type = ? AND name IS NOT NULL
|
|
25
|
+
`).all(kind).map((row) => row.name));
|
|
26
|
+
}
|
|
27
|
+
function configuredBackend(config, backend) {
|
|
28
|
+
if (config.mode === 'off')
|
|
29
|
+
return { id: null, version: null };
|
|
30
|
+
if (backend !== undefined)
|
|
31
|
+
return { id: backend.id, version: backend.id === 'sqlite-vec' ? 'v0.1.9' : null };
|
|
32
|
+
if (config.vectorBackend === 'sqlite-vec')
|
|
33
|
+
return { id: 'sqlite-vec', version: 'v0.1.9' };
|
|
34
|
+
return { id: 'javascript', version: null };
|
|
35
|
+
}
|
|
36
|
+
function emptyStatus(config, backend) {
|
|
37
|
+
const selectedBackend = configuredBackend(config, backend);
|
|
38
|
+
return {
|
|
39
|
+
mode: config.mode,
|
|
40
|
+
activeProfileId: null,
|
|
41
|
+
providerKind: config.mode === 'off' ? null : config.provider,
|
|
42
|
+
model: config.model ?? null,
|
|
43
|
+
dimensions: config.dimensions ?? null,
|
|
44
|
+
distanceMetric: config.mode === 'off' ? null : 'cosine',
|
|
45
|
+
distanceCeiling: config.distanceCeiling ?? null,
|
|
46
|
+
backend: selectedBackend.id,
|
|
47
|
+
backendVersion: selectedBackend.version,
|
|
48
|
+
eligibleEntries: 0,
|
|
49
|
+
readyVectors: 0,
|
|
50
|
+
staleVectors: 0,
|
|
51
|
+
missingVectors: 0,
|
|
52
|
+
pendingJobs: 0,
|
|
53
|
+
leasedJobs: 0,
|
|
54
|
+
failedJobs: 0,
|
|
55
|
+
blockedJobs: 0,
|
|
56
|
+
coverageRatio: 0,
|
|
57
|
+
queryCacheRows: 0,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function activeStatus(database, config, active, backend) {
|
|
61
|
+
const selectedBackend = configuredBackend(config, backend);
|
|
62
|
+
const eligibleEntries = countRows(database, 'SELECT COUNT(*) AS count FROM entries');
|
|
63
|
+
if (active === null) {
|
|
64
|
+
return { ...emptyStatus(config, backend), eligibleEntries, missingVectors: eligibleEntries };
|
|
65
|
+
}
|
|
66
|
+
const readyVectors = countRows(database, `
|
|
67
|
+
SELECT COUNT(*) AS count
|
|
68
|
+
FROM entry_embeddings AS ee
|
|
69
|
+
JOIN entries AS e ON e.id = ee.entry_id
|
|
70
|
+
JOIN entry_revisions AS r ON r.entry_id = e.id AND r.revision = e.current_revision
|
|
71
|
+
WHERE ee.profile_id = ?
|
|
72
|
+
AND ee.revision = e.current_revision
|
|
73
|
+
AND ee.content_hash = r.content_hash
|
|
74
|
+
`, active.profileId);
|
|
75
|
+
const totalVectors = countRows(database, 'SELECT COUNT(*) AS count FROM entry_embeddings WHERE profile_id = ?', active.profileId);
|
|
76
|
+
const jobs = new Map(database.prepare(`
|
|
77
|
+
SELECT state, COUNT(*) AS count
|
|
78
|
+
FROM embedding_jobs
|
|
79
|
+
WHERE profile_id = ?
|
|
80
|
+
GROUP BY state
|
|
81
|
+
`).all(active.profileId).map((row) => [row.state, Number(row.count)]));
|
|
82
|
+
const selected = {
|
|
83
|
+
pending: jobs.get('pending') ?? 0,
|
|
84
|
+
leased: jobs.get('leased') ?? 0,
|
|
85
|
+
failed: jobs.get('failed') ?? 0,
|
|
86
|
+
blocked: jobs.get('blocked') ?? 0,
|
|
87
|
+
};
|
|
88
|
+
const queryCacheRows = countRows(database, 'SELECT COUNT(*) AS count FROM query_embeddings WHERE profile_id = ?', active.profileId);
|
|
89
|
+
return {
|
|
90
|
+
mode: config.mode,
|
|
91
|
+
activeProfileId: active.profileId,
|
|
92
|
+
providerKind: active.identity.providerKind,
|
|
93
|
+
model: active.identity.schemaVersion === 2 ? active.identity.sourceModel : active.identity.model,
|
|
94
|
+
dimensions: active.identity.dimensions,
|
|
95
|
+
distanceMetric: active.identity.distanceMetric,
|
|
96
|
+
distanceCeiling: active.identity.distanceCeiling,
|
|
97
|
+
backend: selectedBackend.id,
|
|
98
|
+
backendVersion: selectedBackend.version,
|
|
99
|
+
eligibleEntries,
|
|
100
|
+
readyVectors,
|
|
101
|
+
staleVectors: Math.max(0, totalVectors - readyVectors),
|
|
102
|
+
missingVectors: Math.max(0, eligibleEntries - readyVectors),
|
|
103
|
+
pendingJobs: selected.pending,
|
|
104
|
+
leasedJobs: selected.leased,
|
|
105
|
+
failedJobs: selected.failed,
|
|
106
|
+
blockedJobs: selected.blocked,
|
|
107
|
+
coverageRatio: eligibleEntries === 0 ? 0 : readyVectors / eligibleEntries,
|
|
108
|
+
queryCacheRows,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
export function readEmbeddingStatus(database, config = readPersistedEmbeddingSettings(database), backend) {
|
|
112
|
+
const runtime = readEmbeddingRuntimeState(database);
|
|
113
|
+
const active = readActiveEmbeddingProfile(database);
|
|
114
|
+
if (active !== null && runtime.activeProfileId !== active.profile.profileId) {
|
|
115
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Embedding runtime active profile is inconsistent');
|
|
116
|
+
}
|
|
117
|
+
return activeStatus(database, config, active?.profile ?? null, backend);
|
|
118
|
+
}
|
|
119
|
+
function inspectVectors(database) {
|
|
120
|
+
let findings = 0;
|
|
121
|
+
const rows = database.prepare(`
|
|
122
|
+
SELECT entry_id, profile_id, dimensions, embedding, vector_hash
|
|
123
|
+
FROM entry_embeddings
|
|
124
|
+
ORDER BY profile_id ASC, entry_id ASC
|
|
125
|
+
`).all();
|
|
126
|
+
for (const row of rows) {
|
|
127
|
+
try {
|
|
128
|
+
if (typeof row.profile_id !== 'string' || typeof row.dimensions !== 'number' || typeof row.vector_hash !== 'string') {
|
|
129
|
+
findings += 1;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const bytes = row.embedding instanceof Uint8Array ? row.embedding : null;
|
|
133
|
+
if (bytes === null || bytes.byteLength !== row.dimensions * 4 || hashVectorBytes(bytes) !== row.vector_hash) {
|
|
134
|
+
findings += 1;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
decodeVector(bytes, row.dimensions, row.vector_hash);
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
findings += 1;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return findings;
|
|
144
|
+
}
|
|
145
|
+
function inspectQueryCache(database) {
|
|
146
|
+
let findings = 0;
|
|
147
|
+
const rows = database.prepare(`
|
|
148
|
+
SELECT profile_id, dimensions, embedding, vector_hash
|
|
149
|
+
FROM query_embeddings
|
|
150
|
+
ORDER BY profile_id ASC, query_hash ASC
|
|
151
|
+
`).all();
|
|
152
|
+
for (const row of rows) {
|
|
153
|
+
try {
|
|
154
|
+
if (typeof row.dimensions !== 'number' || typeof row.vector_hash !== 'string' || !(row.embedding instanceof Uint8Array)) {
|
|
155
|
+
findings += 1;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
decodeVector(row.embedding, row.dimensions, row.vector_hash);
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
findings += 1;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return findings;
|
|
165
|
+
}
|
|
166
|
+
function inspectJobReferences(database) {
|
|
167
|
+
return countRows(database, `
|
|
168
|
+
SELECT COUNT(*) AS count
|
|
169
|
+
FROM embedding_jobs AS j
|
|
170
|
+
LEFT JOIN entries AS e ON e.id = j.entry_id
|
|
171
|
+
LEFT JOIN entry_revisions AS r ON r.entry_id = j.entry_id AND r.revision = j.revision
|
|
172
|
+
WHERE e.id IS NULL OR r.entry_id IS NULL
|
|
173
|
+
OR (j.state = 'leased' AND (j.lease_id IS NULL OR j.lease_expires_at IS NULL))
|
|
174
|
+
OR (j.state <> 'leased' AND (j.lease_id IS NOT NULL OR j.lease_expires_at IS NOT NULL))
|
|
175
|
+
`);
|
|
176
|
+
}
|
|
177
|
+
function inspectConfiguration(database, config, active, backend) {
|
|
178
|
+
if (config.mode === 'off')
|
|
179
|
+
return 0;
|
|
180
|
+
let findings = 0;
|
|
181
|
+
if (active === null || !isEnabledEmbeddingConfig(config))
|
|
182
|
+
findings += 1;
|
|
183
|
+
else {
|
|
184
|
+
try {
|
|
185
|
+
if (embeddingProfileId(createEmbeddingProfile(config).identity) !== active.profile.profileId)
|
|
186
|
+
findings += 1;
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
findings += 1;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (config.vectorBackend === 'sqlite-vec' && backend?.id !== 'sqlite-vec')
|
|
193
|
+
findings += 1;
|
|
194
|
+
return findings;
|
|
195
|
+
}
|
|
196
|
+
function safeConfig(environment) {
|
|
197
|
+
try {
|
|
198
|
+
return { config: parseEmbeddingConfig(environment), invalid: false };
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
return { invalid: true };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
function isEmbeddingConfig(value) {
|
|
205
|
+
return typeof value.mode === 'string' && typeof value.provider === 'string'
|
|
206
|
+
&& typeof value.allowRemote === 'boolean' && typeof value.vectorBackend === 'string'
|
|
207
|
+
&& typeof value.timeoutMs === 'number' && typeof value.batchSize === 'number';
|
|
208
|
+
}
|
|
209
|
+
export function inspectEmbeddingHealth(database, environment = readPersistedEmbeddingSettings(database), backend) {
|
|
210
|
+
const parsed = isEmbeddingConfig(environment)
|
|
211
|
+
? { config: environment, invalid: false }
|
|
212
|
+
: safeConfig(environment);
|
|
213
|
+
const config = (isEmbeddingConfig(environment) ? environment : parsed.config) ?? {
|
|
214
|
+
mode: 'off',
|
|
215
|
+
provider: 'openai-compatible',
|
|
216
|
+
allowRemote: false,
|
|
217
|
+
vectorBackend: 'auto',
|
|
218
|
+
timeoutMs: 30_000,
|
|
219
|
+
batchSize: 16,
|
|
220
|
+
};
|
|
221
|
+
let status = emptyStatus(config, backend);
|
|
222
|
+
let findings = parsed.invalid ? 1 : 0;
|
|
223
|
+
const tables = objectNames(database, 'table');
|
|
224
|
+
const indexes = objectNames(database, 'index');
|
|
225
|
+
const triggers = objectNames(database, 'trigger');
|
|
226
|
+
findings += EMBEDDING_TABLES.filter((name) => !tables.has(name)).length;
|
|
227
|
+
findings += EMBEDDING_INDEXES.filter((name) => !indexes.has(name)).length;
|
|
228
|
+
if (!triggers.has('embedding_profiles_immutable_update'))
|
|
229
|
+
findings += 1;
|
|
230
|
+
try {
|
|
231
|
+
const runtime = readEmbeddingRuntimeState(database);
|
|
232
|
+
const active = readActiveEmbeddingProfile(database);
|
|
233
|
+
status = activeStatus(database, config, active?.profile ?? null, backend);
|
|
234
|
+
findings += inspectConfiguration(database, config, active, backend);
|
|
235
|
+
findings += inspectVectors(database);
|
|
236
|
+
findings += inspectQueryCache(database);
|
|
237
|
+
findings += inspectJobReferences(database);
|
|
238
|
+
const runtimeRows = countRows(database, 'SELECT COUNT(*) AS count FROM embedding_runtime');
|
|
239
|
+
if (runtimeRows !== 1)
|
|
240
|
+
findings += 1;
|
|
241
|
+
const stale = countRows(database, `
|
|
242
|
+
SELECT COUNT(*) AS count
|
|
243
|
+
FROM entry_embeddings AS ee
|
|
244
|
+
JOIN entries AS e ON e.id = ee.entry_id
|
|
245
|
+
JOIN entry_revisions AS r ON r.entry_id = e.id AND r.revision = e.current_revision
|
|
246
|
+
WHERE ee.revision != e.current_revision OR ee.content_hash != r.content_hash
|
|
247
|
+
`);
|
|
248
|
+
if (stale !== status.staleVectors)
|
|
249
|
+
findings += 1;
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
findings += 1;
|
|
253
|
+
}
|
|
254
|
+
return {
|
|
255
|
+
status,
|
|
256
|
+
check: {
|
|
257
|
+
ok: findings === 0,
|
|
258
|
+
count: findings,
|
|
259
|
+
detail: parsed.invalid ? `findings=${findings}, configuration=invalid` : `findings=${findings}, mode=${config.mode}, backend=${status.backend ?? 'disabled'}`,
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../src/embedding/diagnostics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type JsonObject, type EntryKind } from '../serialization/validate.js';
|
|
2
|
+
import type { EmbeddingDocument } from './types.js';
|
|
3
|
+
export declare const EMBEDDING_DOCUMENT_TEMPLATE_VERSION: 1;
|
|
4
|
+
export declare const EMBEDDING_DOCUMENT_TEMPLATE_VERSION_V2: 2;
|
|
5
|
+
export declare const EMBEDDING_INPUT_CONTRACT: "e5-query-passage-v1";
|
|
6
|
+
export declare const MAX_EMBEDDING_DOCUMENT_BYTES: number;
|
|
7
|
+
export declare const BODY_TRUNCATION_MARKER: "[body truncated]";
|
|
8
|
+
export interface EmbeddingDocumentInput {
|
|
9
|
+
readonly kind: EntryKind;
|
|
10
|
+
readonly title: string;
|
|
11
|
+
readonly summary: string | null;
|
|
12
|
+
readonly body: string;
|
|
13
|
+
readonly tags: readonly string[];
|
|
14
|
+
readonly scope: JsonObject;
|
|
15
|
+
}
|
|
16
|
+
export declare function buildEmbeddingDocument(input: EmbeddingDocumentInput): EmbeddingDocument;
|
|
17
|
+
/** Build the provider-neutral v2 memory representation for E5 models. */
|
|
18
|
+
export declare function buildCanonicalEmbeddingDocument(input: EmbeddingDocumentInput): EmbeddingDocument;
|
|
19
|
+
export declare function renderEmbeddingProviderInput(canonicalText: string, prefix?: string): string;
|
|
20
|
+
//# sourceMappingURL=document.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/embedding/document.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoC,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAGjH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,eAAO,MAAM,mCAAmC,EAAG,CAAU,CAAC;AAC9D,eAAO,MAAM,sCAAsC,EAAG,CAAU,CAAC;AACjE,eAAO,MAAM,wBAAwB,EAAG,qBAA8B,CAAC;AACvE,eAAO,MAAM,4BAA4B,QAAY,CAAC;AACtD,eAAO,MAAM,sBAAsB,EAAG,kBAA2B,CAAC;AAElE,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAmDD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,sBAAsB,GAAG,iBAAiB,CA6CvF;AAED,yEAAyE;AACzE,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,sBAAsB,GAAG,iBAAiB,CAUhG;AAED,wBAAgB,4BAA4B,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,SAAc,GAAG,MAAM,CAKhG"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { TextDecoder, TextEncoder } from 'node:util';
|
|
3
|
+
import { KiokukoError } from '../errors.js';
|
|
4
|
+
import { canonicalJson, canonicalTagOrder } from '../serialization/validate.js';
|
|
5
|
+
import { findSecret } from '../memory/secrets.js';
|
|
6
|
+
import { validateApplicability, validateSignals } from '../memory/structured-memory.js';
|
|
7
|
+
export const EMBEDDING_DOCUMENT_TEMPLATE_VERSION = 1;
|
|
8
|
+
export const EMBEDDING_DOCUMENT_TEMPLATE_VERSION_V2 = 2;
|
|
9
|
+
export const EMBEDDING_INPUT_CONTRACT = 'e5-query-passage-v1';
|
|
10
|
+
export const MAX_EMBEDDING_DOCUMENT_BYTES = 32 * 1024;
|
|
11
|
+
export const BODY_TRUNCATION_MARKER = '[body truncated]';
|
|
12
|
+
const encoder = new TextEncoder();
|
|
13
|
+
const decoder = new TextDecoder('utf-8', { fatal: true });
|
|
14
|
+
function invalid(message) {
|
|
15
|
+
throw new KiokukoError('VALIDATION_ERROR', message);
|
|
16
|
+
}
|
|
17
|
+
function normalizeText(value, field) {
|
|
18
|
+
const normalized = value.normalize('NFKC').replaceAll('\r\n', '\n').replaceAll('\r', '\n');
|
|
19
|
+
if (/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/u.test(normalized))
|
|
20
|
+
invalid(`${field} contains a forbidden control character`);
|
|
21
|
+
return normalized;
|
|
22
|
+
}
|
|
23
|
+
function normalizedTagList(tags) {
|
|
24
|
+
for (const tag of tags) {
|
|
25
|
+
if (typeof tag !== 'string' || tag.trim().length === 0 || tag.length > 200)
|
|
26
|
+
invalid('Embedding document tags are invalid');
|
|
27
|
+
}
|
|
28
|
+
return canonicalTagOrder(tags.map((tag) => normalizeText(tag, 'tag')));
|
|
29
|
+
}
|
|
30
|
+
function structuredScope(scope) {
|
|
31
|
+
const candidate = scope;
|
|
32
|
+
if (candidate.schemaVersion !== 2 && candidate.schemaVersion !== 3)
|
|
33
|
+
return { applicability: {}, signals: {} };
|
|
34
|
+
const applicability = candidate.applicability === undefined ? {} : validateApplicability(candidate.applicability);
|
|
35
|
+
const signals = candidate.signals === undefined ? {} : validateSignals(candidate.signals);
|
|
36
|
+
return {
|
|
37
|
+
applicability: applicability,
|
|
38
|
+
signals: signals,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function truncateUtf8(value, maxBytes) {
|
|
42
|
+
if (encoder.encode(value).byteLength <= maxBytes)
|
|
43
|
+
return value;
|
|
44
|
+
const bytes = encoder.encode(value);
|
|
45
|
+
let end = Math.min(bytes.byteLength, maxBytes);
|
|
46
|
+
while (end > 0) {
|
|
47
|
+
try {
|
|
48
|
+
return decoder.decode(bytes.subarray(0, end));
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
end -= 1;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return '';
|
|
55
|
+
}
|
|
56
|
+
function documentHash(bytes) {
|
|
57
|
+
return createHash('sha256').update(bytes).digest('hex');
|
|
58
|
+
}
|
|
59
|
+
export function buildEmbeddingDocument(input) {
|
|
60
|
+
if (input.kind !== 'fact' && input.kind !== 'decision' && input.kind !== 'lesson' && input.kind !== 'preference' && input.kind !== 'reference') {
|
|
61
|
+
invalid('Embedding document kind is invalid');
|
|
62
|
+
}
|
|
63
|
+
const title = normalizeText(input.title, 'title').trim();
|
|
64
|
+
const summary = input.summary === null ? '' : normalizeText(input.summary, 'summary').trim();
|
|
65
|
+
const body = normalizeText(input.body, 'body');
|
|
66
|
+
const tags = normalizedTagList(input.tags);
|
|
67
|
+
const { applicability, signals } = structuredScope(input.scope);
|
|
68
|
+
const metadataText = [
|
|
69
|
+
'kiokuko-memory-v1',
|
|
70
|
+
`kind: ${input.kind}`,
|
|
71
|
+
`title: ${title}`,
|
|
72
|
+
`summary: ${summary}`,
|
|
73
|
+
'tags:',
|
|
74
|
+
...tags.map((tag) => `- ${tag}`),
|
|
75
|
+
'applicability:',
|
|
76
|
+
canonicalJson(applicability),
|
|
77
|
+
'signals:',
|
|
78
|
+
canonicalJson(signals),
|
|
79
|
+
'body:',
|
|
80
|
+
].join('\n') + '\n';
|
|
81
|
+
const metadataBytes = encoder.encode(metadataText);
|
|
82
|
+
if (metadataBytes.byteLength >= MAX_EMBEDDING_DOCUMENT_BYTES) {
|
|
83
|
+
invalid('Embedding document metadata exceeds the byte limit');
|
|
84
|
+
}
|
|
85
|
+
const bodyBytes = encoder.encode(body);
|
|
86
|
+
let text = metadataText + body;
|
|
87
|
+
let truncated = false;
|
|
88
|
+
if (metadataBytes.byteLength + bodyBytes.byteLength > MAX_EMBEDDING_DOCUMENT_BYTES) {
|
|
89
|
+
const marker = `\n${BODY_TRUNCATION_MARKER}`;
|
|
90
|
+
const markerBytes = encoder.encode(marker);
|
|
91
|
+
const available = MAX_EMBEDDING_DOCUMENT_BYTES - metadataBytes.byteLength - markerBytes.byteLength;
|
|
92
|
+
if (available < 0)
|
|
93
|
+
invalid('Embedding document metadata exceeds the byte limit');
|
|
94
|
+
text = metadataText + truncateUtf8(body, available) + marker;
|
|
95
|
+
truncated = true;
|
|
96
|
+
}
|
|
97
|
+
const bytes = encoder.encode(text);
|
|
98
|
+
const secretFinding = findSecret(text);
|
|
99
|
+
if (secretFinding !== undefined) {
|
|
100
|
+
throw new KiokukoError('SECURITY_REJECTION', 'Embedding document resembles a secret and was not sent');
|
|
101
|
+
}
|
|
102
|
+
return Object.freeze({ text, bytes, documentHash: documentHash(bytes), truncated });
|
|
103
|
+
}
|
|
104
|
+
/** Build the provider-neutral v2 memory representation for E5 models. */
|
|
105
|
+
export function buildCanonicalEmbeddingDocument(input) {
|
|
106
|
+
const document = buildEmbeddingDocument(input);
|
|
107
|
+
const text = document.text.replace(/^kiokuko-memory-v1\n/u, 'kiokuko-memory-v2\n');
|
|
108
|
+
const bytes = encoder.encode(text);
|
|
109
|
+
return Object.freeze({
|
|
110
|
+
text,
|
|
111
|
+
bytes,
|
|
112
|
+
documentHash: documentHash(bytes),
|
|
113
|
+
truncated: document.truncated,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
export function renderEmbeddingProviderInput(canonicalText, prefix = 'passage: ') {
|
|
117
|
+
if (typeof canonicalText !== 'string' || canonicalText.length === 0 || prefix !== 'passage: ') {
|
|
118
|
+
invalid('Embedding provider document input is invalid');
|
|
119
|
+
}
|
|
120
|
+
return `${prefix}${canonicalText}`;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=document.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document.js","sourceRoot":"","sources":["../../src/embedding/document.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SqliteDatabase } from '../db/adapter.js';
|
|
2
|
+
import type { VectorHit, VectorSearchBackend, VectorSearchInput } from './types.js';
|
|
3
|
+
export declare const JAVASCRIPT_BACKEND_ID = "javascript";
|
|
4
|
+
export declare const MAX_JAVASCRIPT_BACKEND_ENTRIES = 10000;
|
|
5
|
+
export declare const MAX_VECTOR_SEARCH_LIMIT = 120;
|
|
6
|
+
export declare class JavaScriptVectorSearchBackend implements VectorSearchBackend {
|
|
7
|
+
readonly id = "javascript";
|
|
8
|
+
search(database: SqliteDatabase, input: VectorSearchInput): VectorHit[];
|
|
9
|
+
}
|
|
10
|
+
export declare const createJavaScriptVectorSearchBackend: () => VectorSearchBackend;
|
|
11
|
+
//# sourceMappingURL=javascript-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"javascript-backend.d.ts","sourceRoot":"","sources":["../../src/embedding/javascript-backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAa,MAAM,kBAAkB,CAAC;AAIlE,OAAO,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpF,eAAO,MAAM,qBAAqB,eAAe,CAAC;AAClD,eAAO,MAAM,8BAA8B,QAAS,CAAC;AACrD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAqH3C,qBAAa,6BAA8B,YAAW,mBAAmB;IACvE,QAAQ,CAAC,EAAE,gBAAyB;IAEpC,MAAM,CAAC,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,iBAAiB,GAAG,SAAS,EAAE;CAgDxE;AAED,eAAO,MAAM,mCAAmC,QAAO,mBAA0D,CAAC"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { KiokukoError } from '../errors.js';
|
|
2
|
+
import { requireWorkspace } from '../serialization/validate.js';
|
|
3
|
+
import { decodeVector, cosineDistance, normalizeVector } from './vector.js';
|
|
4
|
+
export const JAVASCRIPT_BACKEND_ID = 'javascript';
|
|
5
|
+
export const MAX_JAVASCRIPT_BACKEND_ENTRIES = 10_000;
|
|
6
|
+
export const MAX_VECTOR_SEARCH_LIMIT = 120;
|
|
7
|
+
function invalid(message) {
|
|
8
|
+
throw new KiokukoError('VALIDATION_ERROR', message);
|
|
9
|
+
}
|
|
10
|
+
function integrity(message) {
|
|
11
|
+
throw new KiokukoError('INTEGRITY_ERROR', message);
|
|
12
|
+
}
|
|
13
|
+
function entryId(value) {
|
|
14
|
+
if (typeof value !== 'string' || value.length === 0 || value.length > 512 || /[\u0000-\u001f\u007f]/u.test(value)) {
|
|
15
|
+
integrity('Stored vector entry ID is invalid');
|
|
16
|
+
}
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
function searchInput(input) {
|
|
20
|
+
if (typeof input.profileId !== 'string' || !/^[0-9a-f]{64}$/u.test(input.profileId))
|
|
21
|
+
invalid('profileId is invalid');
|
|
22
|
+
if (!Number.isSafeInteger(input.dimensions) || input.dimensions < 2 || input.dimensions > 8192)
|
|
23
|
+
invalid('dimensions is invalid');
|
|
24
|
+
if (!Number.isFinite(input.distanceCeiling) || input.distanceCeiling <= 0 || input.distanceCeiling >= 2)
|
|
25
|
+
invalid('distanceCeiling is invalid');
|
|
26
|
+
if (!Number.isSafeInteger(input.limit) || input.limit < 1 || input.limit > MAX_VECTOR_SEARCH_LIMIT)
|
|
27
|
+
invalid('limit is invalid');
|
|
28
|
+
const workspace = input.workspace === undefined ? undefined : requireWorkspace(input.workspace);
|
|
29
|
+
const excludedWorkspaces = input.excludedWorkspaces === undefined
|
|
30
|
+
? []
|
|
31
|
+
: [...new Set(input.excludedWorkspaces.map((value) => requireWorkspace(value)))];
|
|
32
|
+
return {
|
|
33
|
+
profileId: input.profileId,
|
|
34
|
+
dimensions: input.dimensions,
|
|
35
|
+
queryVector: normalizeVector(input.queryVector, input.dimensions),
|
|
36
|
+
distanceCeiling: input.distanceCeiling,
|
|
37
|
+
workspace,
|
|
38
|
+
excludedWorkspaces,
|
|
39
|
+
limit: input.limit,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function worse(left, right) {
|
|
43
|
+
return left.distance > right.distance || left.distance === right.distance && left.entryId > right.entryId;
|
|
44
|
+
}
|
|
45
|
+
function better(left, right) {
|
|
46
|
+
return left.distance < right.distance || left.distance === right.distance && left.entryId < right.entryId;
|
|
47
|
+
}
|
|
48
|
+
class WorstFirstHeap {
|
|
49
|
+
limit;
|
|
50
|
+
#items = [];
|
|
51
|
+
constructor(limit) {
|
|
52
|
+
this.limit = limit;
|
|
53
|
+
}
|
|
54
|
+
add(hit) {
|
|
55
|
+
if (this.#items.length < this.limit) {
|
|
56
|
+
this.#items.push(hit);
|
|
57
|
+
this.siftUp(this.#items.length - 1);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const worst = this.#items[0];
|
|
61
|
+
if (worst === undefined || !better(hit, worst))
|
|
62
|
+
return;
|
|
63
|
+
this.#items[0] = hit;
|
|
64
|
+
this.siftDown(0);
|
|
65
|
+
}
|
|
66
|
+
values() {
|
|
67
|
+
return [...this.#items].sort((left, right) => better(left, right) ? -1 : better(right, left) ? 1 : 0);
|
|
68
|
+
}
|
|
69
|
+
siftUp(start) {
|
|
70
|
+
let child = start;
|
|
71
|
+
while (child > 0) {
|
|
72
|
+
const parent = Math.floor((child - 1) / 2);
|
|
73
|
+
const parentValue = this.#items[parent];
|
|
74
|
+
const childValue = this.#items[child];
|
|
75
|
+
if (parentValue === undefined || childValue === undefined || !worse(childValue, parentValue))
|
|
76
|
+
break;
|
|
77
|
+
this.#items[parent] = childValue;
|
|
78
|
+
this.#items[child] = parentValue;
|
|
79
|
+
child = parent;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
siftDown(start) {
|
|
83
|
+
let parent = start;
|
|
84
|
+
for (;;) {
|
|
85
|
+
const left = parent * 2 + 1;
|
|
86
|
+
const right = left + 1;
|
|
87
|
+
let largest = parent;
|
|
88
|
+
const leftValue = this.#items[left];
|
|
89
|
+
const rightValue = this.#items[right];
|
|
90
|
+
const largestValue = this.#items[largest];
|
|
91
|
+
if (leftValue !== undefined && largestValue !== undefined && worse(leftValue, largestValue))
|
|
92
|
+
largest = left;
|
|
93
|
+
const candidate = this.#items[largest];
|
|
94
|
+
if (rightValue !== undefined && candidate !== undefined && worse(rightValue, candidate))
|
|
95
|
+
largest = right;
|
|
96
|
+
if (largest === parent)
|
|
97
|
+
return;
|
|
98
|
+
const parentValue = this.#items[parent];
|
|
99
|
+
const replacement = this.#items[largest];
|
|
100
|
+
if (parentValue === undefined || replacement === undefined)
|
|
101
|
+
return;
|
|
102
|
+
this.#items[parent] = replacement;
|
|
103
|
+
this.#items[largest] = parentValue;
|
|
104
|
+
parent = largest;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
export class JavaScriptVectorSearchBackend {
|
|
109
|
+
id = JAVASCRIPT_BACKEND_ID;
|
|
110
|
+
search(database, input) {
|
|
111
|
+
const normalized = searchInput(input);
|
|
112
|
+
const clauses = [
|
|
113
|
+
'ee.profile_id = ?',
|
|
114
|
+
'ee.dimensions = ?',
|
|
115
|
+
'ee.revision = e.current_revision',
|
|
116
|
+
'ee.content_hash = r.content_hash',
|
|
117
|
+
];
|
|
118
|
+
const parameters = [normalized.profileId, normalized.dimensions];
|
|
119
|
+
if (normalized.workspace !== undefined) {
|
|
120
|
+
clauses.push('e.workspace = ?');
|
|
121
|
+
parameters.push(normalized.workspace);
|
|
122
|
+
}
|
|
123
|
+
if (normalized.excludedWorkspaces.length > 0) {
|
|
124
|
+
clauses.push(`e.workspace NOT IN (${normalized.excludedWorkspaces.map(() => '?').join(', ')})`);
|
|
125
|
+
parameters.push(...normalized.excludedWorkspaces);
|
|
126
|
+
}
|
|
127
|
+
parameters.push(MAX_JAVASCRIPT_BACKEND_ENTRIES + 1);
|
|
128
|
+
const rows = database.prepare(`
|
|
129
|
+
SELECT ee.entry_id, ee.dimensions, ee.embedding, ee.vector_hash
|
|
130
|
+
FROM entry_embeddings AS ee
|
|
131
|
+
JOIN entries AS e ON e.id = ee.entry_id
|
|
132
|
+
JOIN entry_revisions AS r
|
|
133
|
+
ON r.entry_id = e.id AND r.revision = e.current_revision
|
|
134
|
+
WHERE ${clauses.join(' AND ')}
|
|
135
|
+
ORDER BY ee.entry_id ASC
|
|
136
|
+
LIMIT ?
|
|
137
|
+
`).all(...parameters);
|
|
138
|
+
if (rows.length > MAX_JAVASCRIPT_BACKEND_ENTRIES) {
|
|
139
|
+
throw new KiokukoError('BACKPRESSURE', 'JavaScript vector search corpus exceeds its safety bound');
|
|
140
|
+
}
|
|
141
|
+
const heap = new WorstFirstHeap(normalized.limit);
|
|
142
|
+
for (const row of rows) {
|
|
143
|
+
const id = entryId(row.entry_id);
|
|
144
|
+
if (typeof row.dimensions !== 'number' || row.dimensions !== normalized.dimensions)
|
|
145
|
+
integrity('Stored vector dimensions do not match the search profile');
|
|
146
|
+
const vectorHash = typeof row.vector_hash === 'string' ? row.vector_hash : integrity('Stored vector hash is invalid');
|
|
147
|
+
let vector;
|
|
148
|
+
try {
|
|
149
|
+
vector = decodeVector(row.embedding, normalized.dimensions, vectorHash);
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
integrity('Stored vector is invalid');
|
|
153
|
+
}
|
|
154
|
+
const distance = cosineDistance(normalized.queryVector, vector);
|
|
155
|
+
if (!Number.isFinite(distance))
|
|
156
|
+
integrity('Vector distance is invalid');
|
|
157
|
+
if (distance <= normalized.distanceCeiling)
|
|
158
|
+
heap.add({ entryId: id, distance });
|
|
159
|
+
}
|
|
160
|
+
return heap.values();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
export const createJavaScriptVectorSearchBackend = () => new JavaScriptVectorSearchBackend();
|
|
164
|
+
//# sourceMappingURL=javascript-backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"javascript-backend.js","sourceRoot":"","sources":["../../src/embedding/javascript-backend.ts"],"names":[],"mappings":"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"}
|