@veewo/claw-core 0.1.67 → 0.1.69
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/dist/src/context.d.ts +3 -3
- package/dist/src/context.js +25 -67
- package/dist/src/context.js.map +1 -1
- package/dist/src/embedding-daemon-protocol.d.ts +48 -0
- package/dist/src/embedding-daemon-protocol.js +198 -0
- package/dist/src/embedding-daemon-protocol.js.map +1 -0
- package/dist/src/embedding-daemon.d.ts +1 -0
- package/dist/src/embedding-daemon.js +256 -0
- package/dist/src/embedding-daemon.js.map +1 -0
- package/dist/src/embedding-local-runtime.d.ts +8 -0
- package/dist/src/embedding-local-runtime.js +134 -0
- package/dist/src/embedding-local-runtime.js.map +1 -0
- package/dist/src/embedding-local.d.ts +8 -0
- package/dist/src/embedding-local.js +75 -38
- package/dist/src/embedding-local.js.map +1 -1
- package/dist/src/embedding-worker.js +29 -75
- package/dist/src/embedding-worker.js.map +1 -1
- package/dist/src/errors.d.ts +1 -1
- package/dist/src/errors.js.map +1 -1
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/init.js +3 -0
- package/dist/src/init.js.map +1 -1
- package/dist/src/memory.js +181 -22
- package/dist/src/memory.js.map +1 -1
- package/dist/src/plan-events.d.ts +7 -2
- package/dist/src/plan-events.js +3 -0
- package/dist/src/plan-events.js.map +1 -1
- package/dist/src/plan-templates.js +4 -1
- package/dist/src/plan-templates.js.map +1 -1
- package/dist/src/plan.js +94 -38
- package/dist/src/plan.js.map +1 -1
- package/dist/src/project-check.js +5 -2
- package/dist/src/project-check.js.map +1 -1
- package/dist/src/session-bindings.d.ts +5 -0
- package/dist/src/session-bindings.js +85 -0
- package/dist/src/session-bindings.js.map +1 -0
- package/dist/src/switch-task.js +11 -34
- package/dist/src/switch-task.js.map +1 -1
- package/dist/src/task-layout-migration.d.ts +8 -0
- package/dist/src/task-layout-migration.js +210 -0
- package/dist/src/task-layout-migration.js.map +1 -0
- package/dist/src/task-retention.d.ts +2 -1
- package/dist/src/task-retention.js +60 -27
- package/dist/src/task-retention.js.map +1 -1
- package/dist/src/types.d.ts +16 -6
- package/dist/src/workflow-guidance.config.json +8 -4
- package/dist/src/workflow-guidance.d.ts +1 -1
- package/dist/src/workflow-guidance.js +36 -18
- package/dist/src/workflow-guidance.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import { resolveLocalExecutionDevice, resolveLocalTokenizerMaxLength, runLocalEmbeddingWithFallback, } from "./embedding-local.js";
|
|
6
|
-
import { resolveTransformersModule } from "./embedding-transformers.js";
|
|
7
|
-
const DEFAULT_EMBEDDING_MAX_TOKENS = 2048;
|
|
2
|
+
import { DEFAULT_LOCAL_EMBEDDING_DIMENSIONS, } from "./embedding-defaults.js";
|
|
3
|
+
import { PersistentEmbeddingModelError, requestPersistentEmbedding, } from "./embedding-daemon-protocol.js";
|
|
4
|
+
import { createConfiguredLocalEmbeddingSession, resolveEmbeddingDimensions, } from "./embedding-local-runtime.js";
|
|
8
5
|
async function main() {
|
|
9
6
|
const raw = fs.readFileSync(0, "utf-8").trim();
|
|
10
7
|
if (!raw) {
|
|
@@ -32,6 +29,7 @@ function buildMockOutput(input) {
|
|
|
32
29
|
return {
|
|
33
30
|
dimensions,
|
|
34
31
|
vectors: input.texts.map((text, textIndex) => buildMockVector(text, dimensions, textIndex)),
|
|
32
|
+
runtime: "mock",
|
|
35
33
|
};
|
|
36
34
|
}
|
|
37
35
|
function buildMockVector(text, dimensions, textIndex) {
|
|
@@ -48,44 +46,30 @@ async function buildLocalOutput(input) {
|
|
|
48
46
|
vectors: [],
|
|
49
47
|
};
|
|
50
48
|
}
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
try {
|
|
50
|
+
const persistent = await requestPersistentEmbedding({
|
|
51
|
+
embedding: input.embedding,
|
|
52
|
+
texts: input.texts,
|
|
53
|
+
projectCwd: process.cwd(),
|
|
54
|
+
});
|
|
55
|
+
if (persistent) {
|
|
56
|
+
return { ...persistent, runtime: "persistent_daemon" };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error instanceof PersistentEmbeddingModelError) {
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
// Transport and startup failures fall back to the original one-shot path.
|
|
64
|
+
}
|
|
65
|
+
const session = await createConfiguredLocalEmbeddingSession(input.embedding, process.cwd());
|
|
66
|
+
try {
|
|
67
|
+
const output = await session.run(input.texts);
|
|
68
|
+
return { dimensions: output.dimensions, vectors: output.vectors, runtime: "one_shot" };
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
await session.dispose();
|
|
53
72
|
}
|
|
54
|
-
// Prefer project-local installs when present, then fall back to claw-core's
|
|
55
|
-
// own runtime dependencies for globally installed CLI usage.
|
|
56
|
-
const { createRequire } = await import("node:module");
|
|
57
|
-
const projectRequire = createRequire(process.cwd() + "/");
|
|
58
|
-
const workerRequire = createRequire(import.meta.url);
|
|
59
|
-
const { pipeline, env } = resolveTransformersModule(projectRequire, workerRequire);
|
|
60
|
-
env.allowLocalModels = false;
|
|
61
|
-
const modelId = input.embedding.local?.modelPath?.trim() || input.embedding.model;
|
|
62
|
-
env.cacheDir = resolveLocalEmbeddingCacheDir(modelId, input.embedding.local?.modelCacheDir, {
|
|
63
|
-
cwd: process.cwd(),
|
|
64
|
-
});
|
|
65
|
-
const requestedDevice = resolveLocalExecutionDevice(input.embedding, {
|
|
66
|
-
cudaAvailable: isCudaAvailable(),
|
|
67
|
-
});
|
|
68
|
-
const output = await runLocalEmbeddingWithFallback({
|
|
69
|
-
texts: input.texts,
|
|
70
|
-
dimensions: resolveDimensions(input.embedding, DEFAULT_LOCAL_EMBEDDING_DIMENSIONS),
|
|
71
|
-
requestedDevice,
|
|
72
|
-
createExtractor: async (device) => {
|
|
73
|
-
const extractor = await pipeline("feature-extraction", modelId, {
|
|
74
|
-
device,
|
|
75
|
-
dtype: "fp32",
|
|
76
|
-
session_options: { logSeverityLevel: 3 },
|
|
77
|
-
});
|
|
78
|
-
const safeTokenizerMaxLength = resolveLocalTokenizerMaxLength(extractor.tokenizer?.model_max_length, extractor.model?.config?.max_position_embeddings, DEFAULT_EMBEDDING_MAX_TOKENS);
|
|
79
|
-
if (safeTokenizerMaxLength !== null && extractor.tokenizer) {
|
|
80
|
-
extractor.tokenizer.model_max_length = safeTokenizerMaxLength;
|
|
81
|
-
}
|
|
82
|
-
return extractor;
|
|
83
|
-
},
|
|
84
|
-
});
|
|
85
|
-
return {
|
|
86
|
-
dimensions: output.dimensions,
|
|
87
|
-
vectors: output.vectors,
|
|
88
|
-
};
|
|
89
73
|
}
|
|
90
74
|
async function buildOpenAiOutput(input) {
|
|
91
75
|
if (!input.texts.length) {
|
|
@@ -122,6 +106,7 @@ async function buildOpenAiOutput(input) {
|
|
|
122
106
|
return {
|
|
123
107
|
dimensions,
|
|
124
108
|
vectors,
|
|
109
|
+
runtime: "remote",
|
|
125
110
|
};
|
|
126
111
|
}
|
|
127
112
|
function resolveOpenAiBaseUrl(embedding) {
|
|
@@ -133,39 +118,8 @@ function resolveOpenAiBaseUrl(embedding) {
|
|
|
133
118
|
? configured
|
|
134
119
|
: `${configured.replace(/\/+$/, "")}/embeddings`;
|
|
135
120
|
}
|
|
136
|
-
function isCudaAvailable() {
|
|
137
|
-
try {
|
|
138
|
-
const out = execFileSync("ldconfig", ["-p"], { timeout: 3000, encoding: "utf-8" });
|
|
139
|
-
if (out.includes("libcublasLt.so.12")) {
|
|
140
|
-
return true;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
catch {
|
|
144
|
-
// Ignore.
|
|
145
|
-
}
|
|
146
|
-
for (const envVar of ["CUDA_PATH", "LD_LIBRARY_PATH"]) {
|
|
147
|
-
const value = process.env[envVar];
|
|
148
|
-
if (!value) {
|
|
149
|
-
continue;
|
|
150
|
-
}
|
|
151
|
-
for (const candidate of value.split(":").filter(Boolean)) {
|
|
152
|
-
if (fs.existsSync(path.join(candidate, "lib64", "libcublasLt.so.12")) ||
|
|
153
|
-
fs.existsSync(path.join(candidate, "lib", "libcublasLt.so.12")) ||
|
|
154
|
-
fs.existsSync(path.join(candidate, "libcublasLt.so.12"))) {
|
|
155
|
-
return true;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
161
121
|
function resolveDimensions(embedding, fallback) {
|
|
162
|
-
|
|
163
|
-
return embedding.outputDimensionality;
|
|
164
|
-
}
|
|
165
|
-
if (embedding.provider === "local") {
|
|
166
|
-
return resolveDefaultLocalEmbeddingDimensions(embedding.model);
|
|
167
|
-
}
|
|
168
|
-
return fallback > 0 ? fallback : 1536;
|
|
122
|
+
return resolveEmbeddingDimensions(embedding, fallback);
|
|
169
123
|
}
|
|
170
124
|
main().catch((error) => {
|
|
171
125
|
const message = error instanceof Error ? error.message : "Unknown embedding worker failure.";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedding-worker.js","sourceRoot":"","sources":["../../src/embedding-worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,
|
|
1
|
+
{"version":3,"file":"embedding-worker.js","sourceRoot":"","sources":["../../src/embedding-worker.ts"],"names":[],"mappings":"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"}
|
package/dist/src/errors.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type ClawErrorCode = "PROJECT_ROOT_NOT_FOUND" | "CLAW_DIR_NOT_FOUND" | "PROJECT_ALREADY_INITIALIZED" | "PROJECT_CONFIG_INVALID" | "TASK_NOT_FOUND" | "TASK_NAME_INVALID" | "ACTIVE_PLAN_INVALID" | "ACTIVE_PLAN_MISSING" | "PLAN_NOT_FOUND" | "PLAN_STATUS_INVALID" | "PLAN_STATUS_NOT_SETTABLE" | "PLAN_STATUS_TRANSITION_FORBIDDEN" | "PLAN_STATUS_REOPEN_REQUIRED" | "TASK_STATUS_FORBIDDEN_IN_NON_ACTIVE_PLAN" | "PLAN_WRITE_CONFLICT" | "PLAN_STALE_EDIT" | "RETROSPECTIVE_REQUIRED" | "MEMORY_QUERY_REQUIRED" | "MEMORY_DISABLED" | "MEMORY_STORE_BUSY" | "MEMORY_VECTOR_INDEX_REQUIRED" | "GITNEXUS_REFRESH_FAILED" | "TRUTH_TARGET_INVALID" | "INPUT_REQUIRED";
|
|
1
|
+
export type ClawErrorCode = "PROJECT_ROOT_NOT_FOUND" | "CLAW_DIR_NOT_FOUND" | "PROJECT_ALREADY_INITIALIZED" | "PROJECT_CONFIG_INVALID" | "TASK_NOT_FOUND" | "TASK_NAME_INVALID" | "ACTIVE_PLAN_INVALID" | "ACTIVE_PLAN_MISSING" | "PLAN_NOT_FOUND" | "PLAN_ALREADY_EXISTS" | "PLAN_STATUS_INVALID" | "PLAN_STATUS_NOT_SETTABLE" | "PLAN_STATUS_TRANSITION_FORBIDDEN" | "PLAN_STATUS_REOPEN_REQUIRED" | "TASK_STATUS_FORBIDDEN_IN_NON_ACTIVE_PLAN" | "PLAN_WRITE_CONFLICT" | "PLAN_STALE_EDIT" | "RETROSPECTIVE_REQUIRED" | "MEMORY_QUERY_REQUIRED" | "MEMORY_DISABLED" | "MEMORY_STORE_BUSY" | "MEMORY_VECTOR_INDEX_REQUIRED" | "GITNEXUS_REFRESH_FAILED" | "TRUTH_TARGET_INVALID" | "INPUT_REQUIRED";
|
|
2
2
|
export declare class ClawError extends Error {
|
|
3
3
|
readonly code: ClawErrorCode;
|
|
4
4
|
readonly details: Record<string, unknown> | undefined;
|
package/dist/src/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AA2BA,MAAM,OAAO,SAAU,SAAQ,KAAK;IACzB,IAAI,CAAgB;IACpB,OAAO,CAAsC;IAEtD,YAAY,IAAmB,EAAE,OAAe,EAAE,OAAiC;QACjF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export * from "./memory.js";
|
|
|
6
6
|
export * from "./plan-events.js";
|
|
7
7
|
export * from "./project-check.js";
|
|
8
8
|
export * from "./requirements-gate.js";
|
|
9
|
+
export * from "./session-bindings.js";
|
|
10
|
+
export * from "./task-layout-migration.js";
|
|
9
11
|
export * from "./plan.js";
|
|
10
12
|
export * from "./plan-templates.js";
|
|
11
13
|
export * from "./plan-view.js";
|
package/dist/src/index.js
CHANGED
|
@@ -6,6 +6,8 @@ export * from "./memory.js";
|
|
|
6
6
|
export * from "./plan-events.js";
|
|
7
7
|
export * from "./project-check.js";
|
|
8
8
|
export * from "./requirements-gate.js";
|
|
9
|
+
export * from "./session-bindings.js";
|
|
10
|
+
export * from "./task-layout-migration.js";
|
|
9
11
|
export * from "./plan.js";
|
|
10
12
|
export * from "./plan-templates.js";
|
|
11
13
|
export * from "./plan-view.js";
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,WAAW,CAAC;AAC1B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,WAAW,CAAC;AAC1B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC"}
|
package/dist/src/init.js
CHANGED
|
@@ -4,6 +4,7 @@ import { DEFAULT_LOCAL_EMBEDDING_MODEL, } from "./embedding-defaults.js";
|
|
|
4
4
|
import { ClawError } from "./errors.js";
|
|
5
5
|
import { normalizeTaskName } from "./paths.js";
|
|
6
6
|
import { ensureUtf8Bom } from "./text-encoding.js";
|
|
7
|
+
import { markTaskLayoutMigrationComplete } from "./task-layout-migration.js";
|
|
7
8
|
const CORE_VERSION = readCoreVersion();
|
|
8
9
|
const CLAW_GITIGNORE_BLOCK = [
|
|
9
10
|
"# claw-kit",
|
|
@@ -61,6 +62,8 @@ export function initProject(input) {
|
|
|
61
62
|
ensureDir(truthDir, createdPaths);
|
|
62
63
|
ensureDir(tasksDir, createdPaths);
|
|
63
64
|
ensureDir(knowledgeDir, createdPaths);
|
|
65
|
+
const taskLayoutMarkerPath = markTaskLayoutMigrationComplete(clawDir);
|
|
66
|
+
createdPaths.push(taskLayoutMarkerPath);
|
|
64
67
|
writeFile(projectJsonPath, `${JSON.stringify(projectConfig, null, 2)}\n`, createdPaths);
|
|
65
68
|
writeFile(memoryPath, `# Project Memory\n\n- Project initialized for claw-kit.\n- Use \`claw plan create\` to establish the first task scope.\n`, createdPaths);
|
|
66
69
|
ensureClawGitignoreRules(gitignorePath, createdPaths);
|
package/dist/src/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,6BAA6B,GAC9B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/init.ts"],"names":[],"mappings":"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"}
|
package/dist/src/memory.js
CHANGED
|
@@ -18,6 +18,8 @@ const DEFAULT_EMBEDDING_CHARS_PER_TOKEN = 3;
|
|
|
18
18
|
const DEFAULT_EMBEDDING_TARGET_CHARS = DEFAULT_EMBEDDING_TARGET_TOKENS * DEFAULT_EMBEDDING_CHARS_PER_TOKEN;
|
|
19
19
|
const DEFAULT_EMBEDDING_MAX_CHARS = DEFAULT_EMBEDDING_MAX_TOKENS * DEFAULT_EMBEDDING_CHARS_PER_TOKEN;
|
|
20
20
|
const DEFAULT_MEMORY_SQLITE_BUSY_TIMEOUT_MS = 5000;
|
|
21
|
+
const PROJECT_QUERY_EMBEDDING_CACHE_LIMIT = 128;
|
|
22
|
+
const PROJECT_QUERY_EMBEDDING_CACHE_VERSION = "v1";
|
|
21
23
|
export function buildMemoryIndex(input) {
|
|
22
24
|
const { scope, project, task } = resolveMemoryScope(input);
|
|
23
25
|
if (!isProjectMemoryEnabled(project)) {
|
|
@@ -124,17 +126,27 @@ function syncProjectMemoryIndex(db, sources, embedding, maxFiles) {
|
|
|
124
126
|
deleteDocsById(db, docsToDelete.map((doc) => doc.id));
|
|
125
127
|
if (requiresVectorReset) {
|
|
126
128
|
db.exec("DELETE FROM doc_embeddings;");
|
|
129
|
+
db.exec("DELETE FROM query_embeddings;");
|
|
127
130
|
}
|
|
128
131
|
insertDocs(db, limitedDocsToInsert);
|
|
129
|
-
if (shouldIndexVectors && embedding) {
|
|
130
|
-
indexDocEmbeddings(db, listDocsMissingEmbeddings(db), embedding);
|
|
131
|
-
}
|
|
132
132
|
db.exec("COMMIT");
|
|
133
133
|
}
|
|
134
134
|
catch (error) {
|
|
135
135
|
db.exec("ROLLBACK");
|
|
136
136
|
throw error;
|
|
137
137
|
}
|
|
138
|
+
if (shouldIndexVectors && embedding) {
|
|
139
|
+
const generatedEmbeddings = generateDocEmbeddings(listDocsMissingEmbeddings(db), embedding);
|
|
140
|
+
db.exec("BEGIN");
|
|
141
|
+
try {
|
|
142
|
+
insertDocEmbeddings(db, generatedEmbeddings);
|
|
143
|
+
db.exec("COMMIT");
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
db.exec("ROLLBACK");
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
138
150
|
if (!shouldIndexVectors || !embedding) {
|
|
139
151
|
return {
|
|
140
152
|
vectorIndex: null,
|
|
@@ -192,6 +204,7 @@ function getMetadata(db, key) {
|
|
|
192
204
|
return row?.value ?? null;
|
|
193
205
|
}
|
|
194
206
|
export function searchMemory(input) {
|
|
207
|
+
const startedAt = performance.now();
|
|
195
208
|
if (!input.query.trim()) {
|
|
196
209
|
throw new ClawError("MEMORY_QUERY_REQUIRED", "memory search requires a non-empty query.");
|
|
197
210
|
}
|
|
@@ -215,13 +228,23 @@ export function searchMemory(input) {
|
|
|
215
228
|
}
|
|
216
229
|
return withMemoryDatabase(storePath, "search", "read", (db) => {
|
|
217
230
|
prepareSchema(db);
|
|
218
|
-
const
|
|
231
|
+
const searchResult = scope === "project"
|
|
219
232
|
? searchProjectMemoryHybrid(db, input.query, input.limit ?? 10, project)
|
|
220
|
-
:
|
|
233
|
+
: {
|
|
234
|
+
results: searchTaskMemoryFts(db, input.query, input.limit ?? 10),
|
|
235
|
+
telemetry: {
|
|
236
|
+
route: "task_fts",
|
|
237
|
+
queryEmbedding: "skipped",
|
|
238
|
+
},
|
|
239
|
+
};
|
|
221
240
|
return {
|
|
222
241
|
scope,
|
|
223
242
|
storePath,
|
|
224
|
-
results,
|
|
243
|
+
results: searchResult.results,
|
|
244
|
+
telemetry: {
|
|
245
|
+
...searchResult.telemetry,
|
|
246
|
+
durationMs: Number((performance.now() - startedAt).toFixed(2)),
|
|
247
|
+
},
|
|
225
248
|
};
|
|
226
249
|
});
|
|
227
250
|
}
|
|
@@ -425,6 +448,14 @@ function prepareSchema(db) {
|
|
|
425
448
|
" embedding_json TEXT NOT NULL,",
|
|
426
449
|
" PRIMARY KEY (doc_id, chunk_index)",
|
|
427
450
|
");",
|
|
451
|
+
"CREATE TABLE IF NOT EXISTS query_embeddings (",
|
|
452
|
+
" cache_key TEXT PRIMARY KEY,",
|
|
453
|
+
" embedding_fingerprint TEXT NOT NULL,",
|
|
454
|
+
" query_text TEXT NOT NULL,",
|
|
455
|
+
" dimensions INTEGER NOT NULL,",
|
|
456
|
+
" embedding_json TEXT NOT NULL,",
|
|
457
|
+
" created_at INTEGER NOT NULL",
|
|
458
|
+
");",
|
|
428
459
|
].join("\n"));
|
|
429
460
|
const docsColumns = db.prepare("PRAGMA table_info(docs)").all();
|
|
430
461
|
if (!docsColumns.some((column) => column.name === "content_hash")) {
|
|
@@ -474,12 +505,12 @@ function listFiles(rootDir, matcher) {
|
|
|
474
505
|
function isExternalDocFile(filePath) {
|
|
475
506
|
return /\.md$/i.test(filePath);
|
|
476
507
|
}
|
|
477
|
-
function
|
|
508
|
+
function generateDocEmbeddings(docs, embedding) {
|
|
478
509
|
if (!embedding) {
|
|
479
|
-
return;
|
|
510
|
+
return [];
|
|
480
511
|
}
|
|
481
512
|
if (!canBuildProjectVectors(embedding)) {
|
|
482
|
-
return;
|
|
513
|
+
return [];
|
|
483
514
|
}
|
|
484
515
|
const chunks = docs.flatMap((doc) => chunkMarkdownContent(doc.content).map((chunkText, chunkIndex) => ({
|
|
485
516
|
docId: doc.docId,
|
|
@@ -489,18 +520,24 @@ function indexDocEmbeddings(db, docs, embedding) {
|
|
|
489
520
|
chunkText,
|
|
490
521
|
})));
|
|
491
522
|
if (chunks.length === 0) {
|
|
492
|
-
return;
|
|
523
|
+
return [];
|
|
493
524
|
}
|
|
494
525
|
const output = runEmbeddingWorker({
|
|
495
526
|
embedding,
|
|
496
527
|
texts: chunks.map((chunk) => chunk.chunkText),
|
|
497
528
|
});
|
|
529
|
+
return chunks.map((chunk, index) => ({
|
|
530
|
+
...chunk,
|
|
531
|
+
vector: output.vectors[index] ?? [],
|
|
532
|
+
}));
|
|
533
|
+
}
|
|
534
|
+
function insertDocEmbeddings(db, embeddings) {
|
|
498
535
|
const insertEmbedding = db.prepare([
|
|
499
|
-
"INSERT INTO doc_embeddings (doc_id, chunk_index, source_path, kind, chunk_text, embedding_json)",
|
|
536
|
+
"INSERT OR REPLACE INTO doc_embeddings (doc_id, chunk_index, source_path, kind, chunk_text, embedding_json)",
|
|
500
537
|
"VALUES (?, ?, ?, ?, ?, ?)",
|
|
501
538
|
].join(" "));
|
|
502
|
-
|
|
503
|
-
insertEmbedding.run(
|
|
539
|
+
embeddings.forEach((embedding) => {
|
|
540
|
+
insertEmbedding.run(embedding.docId, embedding.chunkIndex, embedding.sourcePath, embedding.kind, embedding.chunkText, JSON.stringify(embedding.vector));
|
|
504
541
|
});
|
|
505
542
|
}
|
|
506
543
|
function listDocsMissingEmbeddings(db) {
|
|
@@ -710,13 +747,6 @@ function searchProjectMemoryHybrid(db, query, limit, project) {
|
|
|
710
747
|
throw new ClawError("MEMORY_VECTOR_INDEX_REQUIRED", "Project search requires a refreshed vector index. Run `claw search index --refresh` first.");
|
|
711
748
|
}
|
|
712
749
|
const queryIntent = buildProjectQueryIntent(query);
|
|
713
|
-
const queryEmbedding = runEmbeddingWorker({
|
|
714
|
-
embedding,
|
|
715
|
-
texts: [queryIntent.embeddingText || query],
|
|
716
|
-
}).vectors[0];
|
|
717
|
-
if (!queryEmbedding?.length) {
|
|
718
|
-
throw new ClawError("MEMORY_VECTOR_INDEX_REQUIRED", "Unable to generate a query embedding for project search.");
|
|
719
|
-
}
|
|
720
750
|
const candidateLimit = Math.max(limit * PROJECT_SEARCH_CANDIDATE_MULTIPLIER, 40);
|
|
721
751
|
const projectDocs = db
|
|
722
752
|
.prepare("SELECT source_path, kind, content FROM docs")
|
|
@@ -732,6 +762,24 @@ function searchProjectMemoryHybrid(db, query, limit, project) {
|
|
|
732
762
|
]));
|
|
733
763
|
const ftsRows = searchProjectMemoryKeywords(db, query, candidateLimit);
|
|
734
764
|
const signalRows = searchProjectMemorySignals(projectDocs, docSignals, candidateLimit);
|
|
765
|
+
const lexicalFastPath = tryProjectLexicalFastPath({
|
|
766
|
+
query,
|
|
767
|
+
queryIntent,
|
|
768
|
+
docSignals,
|
|
769
|
+
ftsRows,
|
|
770
|
+
signalRows,
|
|
771
|
+
limit,
|
|
772
|
+
});
|
|
773
|
+
if (lexicalFastPath) {
|
|
774
|
+
return {
|
|
775
|
+
results: lexicalFastPath,
|
|
776
|
+
telemetry: {
|
|
777
|
+
route: "lexical_fast_path",
|
|
778
|
+
queryEmbedding: "skipped",
|
|
779
|
+
},
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
const queryEmbedding = resolveProjectQueryEmbedding(db, embedding, queryIntent.embeddingText || query);
|
|
735
783
|
const vectorRows = db
|
|
736
784
|
.prepare([
|
|
737
785
|
"SELECT source_path, kind, chunk_text, embedding_json",
|
|
@@ -748,7 +796,7 @@ function searchProjectMemoryHybrid(db, query, limit, project) {
|
|
|
748
796
|
sourcePath: row.source_path,
|
|
749
797
|
kind: row.kind,
|
|
750
798
|
snippet: buildSnippet(row.chunk_text),
|
|
751
|
-
similarity: cosineSimilarity(queryEmbedding, parseEmbeddingJson(row.embedding_json)),
|
|
799
|
+
similarity: cosineSimilarity(queryEmbedding.vector, parseEmbeddingJson(row.embedding_json)),
|
|
752
800
|
exactBoost: signals?.exactBoost ?? 0,
|
|
753
801
|
};
|
|
754
802
|
})
|
|
@@ -814,7 +862,116 @@ function searchProjectMemoryHybrid(db, query, limit, project) {
|
|
|
814
862
|
signalRank: index + 1,
|
|
815
863
|
});
|
|
816
864
|
});
|
|
817
|
-
return
|
|
865
|
+
return {
|
|
866
|
+
results: rerankProjectSearchCandidates(Array.from(fused.values()), docSignals, limit),
|
|
867
|
+
telemetry: {
|
|
868
|
+
route: "hybrid",
|
|
869
|
+
queryEmbedding: queryEmbedding.cacheHit ? "cache_hit" : "generated",
|
|
870
|
+
...(queryEmbedding.runtime ? { embeddingRuntime: queryEmbedding.runtime } : {}),
|
|
871
|
+
},
|
|
872
|
+
};
|
|
873
|
+
}
|
|
874
|
+
function tryProjectLexicalFastPath(input) {
|
|
875
|
+
const { queryIntent } = input;
|
|
876
|
+
const primaryKeywordStep = buildProjectKeywordSearchPlan(input.query)[0];
|
|
877
|
+
if (queryIntent.strongTerms.length === 0
|
|
878
|
+
|| queryIntent.weakTerms.length > 0
|
|
879
|
+
|| !primaryKeywordStep
|
|
880
|
+
|| primaryKeywordStep.substringTerms.length > 0) {
|
|
881
|
+
return null;
|
|
882
|
+
}
|
|
883
|
+
const fullCoverage = Array.from(input.docSignals.entries()).filter(([, signals]) => signals.strongCoverageRatio === 1);
|
|
884
|
+
const pathMatches = fullCoverage.filter(([, signals]) => signals.fileNameHits >= queryIntent.strongTerms.length
|
|
885
|
+
|| signals.pathHits >= queryIntent.strongTerms.length);
|
|
886
|
+
const phraseMatches = fullCoverage.filter(([, signals]) => signals.phraseMatch);
|
|
887
|
+
const confidentSourcePath = pathMatches.length === 1
|
|
888
|
+
? pathMatches[0]?.[0]
|
|
889
|
+
: phraseMatches.length === 1
|
|
890
|
+
? phraseMatches[0]?.[0]
|
|
891
|
+
: null;
|
|
892
|
+
if (!confidentSourcePath) {
|
|
893
|
+
return null;
|
|
894
|
+
}
|
|
895
|
+
const candidates = new Map();
|
|
896
|
+
input.ftsRows.forEach((row, index) => {
|
|
897
|
+
candidates.set(row.source_path, {
|
|
898
|
+
sourcePath: row.source_path,
|
|
899
|
+
kind: row.kind,
|
|
900
|
+
snippet: row.snippet,
|
|
901
|
+
score: reciprocalRankScore(index + 1, 0.85) + (input.docSignals.get(row.source_path)?.exactBoost ?? 0),
|
|
902
|
+
textRank: index + 1,
|
|
903
|
+
});
|
|
904
|
+
});
|
|
905
|
+
input.signalRows.forEach((row, index) => {
|
|
906
|
+
const existing = candidates.get(row.source_path);
|
|
907
|
+
candidates.set(row.source_path, {
|
|
908
|
+
sourcePath: row.source_path,
|
|
909
|
+
kind: existing?.kind ?? row.kind,
|
|
910
|
+
snippet: existing?.snippet || row.snippet,
|
|
911
|
+
score: (existing?.score ?? 0)
|
|
912
|
+
+ reciprocalRankScore(index + 1, 0.15)
|
|
913
|
+
+ (existing ? 0 : (input.docSignals.get(row.source_path)?.exactBoost ?? 0)),
|
|
914
|
+
textRank: existing?.textRank,
|
|
915
|
+
signalRank: index + 1,
|
|
916
|
+
});
|
|
917
|
+
});
|
|
918
|
+
const confidentCandidate = candidates.get(confidentSourcePath);
|
|
919
|
+
if (!confidentCandidate) {
|
|
920
|
+
return null;
|
|
921
|
+
}
|
|
922
|
+
confidentCandidate.score += 0.1;
|
|
923
|
+
return rerankProjectSearchCandidates(Array.from(candidates.values()), input.docSignals, input.limit);
|
|
924
|
+
}
|
|
925
|
+
function resolveProjectQueryEmbedding(db, embedding, queryText) {
|
|
926
|
+
const normalizedQueryText = queryText.trim().replace(/\s+/g, " ");
|
|
927
|
+
const embeddingFingerprint = createHash("sha256")
|
|
928
|
+
.update(JSON.stringify(embedding))
|
|
929
|
+
.digest("hex");
|
|
930
|
+
const cacheKey = createHash("sha256")
|
|
931
|
+
.update(`${PROJECT_QUERY_EMBEDDING_CACHE_VERSION}\0${embeddingFingerprint}\0${normalizedQueryText}`)
|
|
932
|
+
.digest("hex");
|
|
933
|
+
const cached = db
|
|
934
|
+
.prepare([
|
|
935
|
+
"SELECT dimensions, embedding_json",
|
|
936
|
+
"FROM query_embeddings",
|
|
937
|
+
"WHERE cache_key = ? AND embedding_fingerprint = ? AND query_text = ?",
|
|
938
|
+
].join(" "))
|
|
939
|
+
.get(cacheKey, embeddingFingerprint, normalizedQueryText);
|
|
940
|
+
if (cached) {
|
|
941
|
+
const vector = parseEmbeddingJson(cached.embedding_json);
|
|
942
|
+
if (cached.dimensions > 0 && vector.length === cached.dimensions) {
|
|
943
|
+
return { vector, cacheHit: true };
|
|
944
|
+
}
|
|
945
|
+
db.prepare("DELETE FROM query_embeddings WHERE cache_key = ?").run(cacheKey);
|
|
946
|
+
}
|
|
947
|
+
const generated = runEmbeddingWorker({
|
|
948
|
+
embedding,
|
|
949
|
+
texts: [normalizedQueryText],
|
|
950
|
+
});
|
|
951
|
+
const vector = generated.vectors[0];
|
|
952
|
+
if (!vector?.length) {
|
|
953
|
+
throw new ClawError("MEMORY_VECTOR_INDEX_REQUIRED", "Unable to generate a query embedding for project search.");
|
|
954
|
+
}
|
|
955
|
+
db.prepare([
|
|
956
|
+
"INSERT INTO query_embeddings",
|
|
957
|
+
" (cache_key, embedding_fingerprint, query_text, dimensions, embedding_json, created_at)",
|
|
958
|
+
"VALUES (?, ?, ?, ?, ?, ?)",
|
|
959
|
+
"ON CONFLICT(cache_key) DO UPDATE SET",
|
|
960
|
+
" embedding_fingerprint = excluded.embedding_fingerprint,",
|
|
961
|
+
" query_text = excluded.query_text,",
|
|
962
|
+
" dimensions = excluded.dimensions,",
|
|
963
|
+
" embedding_json = excluded.embedding_json,",
|
|
964
|
+
" created_at = excluded.created_at",
|
|
965
|
+
].join(" ")).run(cacheKey, embeddingFingerprint, normalizedQueryText, vector.length, JSON.stringify(vector), Date.now());
|
|
966
|
+
db.prepare([
|
|
967
|
+
"DELETE FROM query_embeddings",
|
|
968
|
+
"WHERE cache_key IN (",
|
|
969
|
+
" SELECT cache_key FROM query_embeddings",
|
|
970
|
+
" ORDER BY created_at DESC, rowid DESC",
|
|
971
|
+
" LIMIT -1 OFFSET ?",
|
|
972
|
+
")",
|
|
973
|
+
].join(" ")).run(PROJECT_QUERY_EMBEDDING_CACHE_LIMIT);
|
|
974
|
+
return { vector, cacheHit: false, ...(generated.runtime ? { runtime: generated.runtime } : {}) };
|
|
818
975
|
}
|
|
819
976
|
function searchProjectMemoryKeywords(db, query, limit) {
|
|
820
977
|
const plan = buildProjectKeywordSearchPlan(query);
|
|
@@ -1051,6 +1208,8 @@ function buildProjectSearchSignals(input) {
|
|
|
1051
1208
|
strongMatchedTermCount: strongMatchedTerms.size,
|
|
1052
1209
|
fileNameHits,
|
|
1053
1210
|
pathHits,
|
|
1211
|
+
phraseMatch,
|
|
1212
|
+
strongCoverageRatio,
|
|
1054
1213
|
exactBoost: strongMatchedTerms.size * 0.016
|
|
1055
1214
|
+ weakMatchedTerms.size * 0.004
|
|
1056
1215
|
+ coverageRatio * 0.008
|