@gmickel/gno 1.17.0 → 1.19.0
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 +18 -4
- package/assets/skill/SKILL.md +44 -1
- package/assets/skill/mcp-reference.md +21 -0
- package/package.json +3 -2
- package/spec/AGENTS.md +83 -0
- package/spec/CLAUDE.md +83 -0
- package/spec/bench-fixture.schema.json +137 -0
- package/spec/cli.md +2894 -0
- package/spec/db/schema.sql +442 -0
- package/spec/evals-agentic.md +510 -0
- package/spec/evals.md +1106 -0
- package/spec/mcp.md +2229 -0
- package/spec/output-schemas/activation-verification.schema.json +515 -0
- package/spec/output-schemas/ask.schema.json +366 -0
- package/spec/output-schemas/backlinks.schema.json +131 -0
- package/spec/output-schemas/bench-result.schema.json +120 -0
- package/spec/output-schemas/capture-receipt.schema.json +143 -0
- package/spec/output-schemas/collection-list.schema.json +45 -0
- package/spec/output-schemas/context-capsule-v1.schema.json +691 -0
- package/spec/output-schemas/context-capsule-verification.schema.json +1338 -0
- package/spec/output-schemas/context-list.schema.json +21 -0
- package/spec/output-schemas/doctor.schema.json +313 -0
- package/spec/output-schemas/error.schema.json +30 -0
- package/spec/output-schemas/expansion.schema.json +37 -0
- package/spec/output-schemas/get.schema.json +140 -0
- package/spec/output-schemas/graph-query.schema.json +99 -0
- package/spec/output-schemas/graph.schema.json +371 -0
- package/spec/output-schemas/links-list.schema.json +186 -0
- package/spec/output-schemas/mcp-add-collection-result.schema.json +23 -0
- package/spec/output-schemas/mcp-capture-result.schema.json +152 -0
- package/spec/output-schemas/mcp-http-error.schema.json +30 -0
- package/spec/output-schemas/mcp-job-list.schema.json +58 -0
- package/spec/output-schemas/mcp-job-status.schema.json +224 -0
- package/spec/output-schemas/mcp-remove-result.schema.json +39 -0
- package/spec/output-schemas/mcp-sync-result.schema.json +41 -0
- package/spec/output-schemas/mcp-tag-result.schema.json +33 -0
- package/spec/output-schemas/models-list.schema.json +93 -0
- package/spec/output-schemas/multi-get.schema.json +103 -0
- package/spec/output-schemas/process-status.schema.json +119 -0
- package/spec/output-schemas/query-diagnose.schema.json +123 -0
- package/spec/output-schemas/resident-status.schema.json +154 -0
- package/spec/output-schemas/retrieval-trace-common.schema.json +492 -0
- package/spec/output-schemas/retrieval-trace-delete.schema.json +16 -0
- package/spec/output-schemas/retrieval-trace-export.schema.json +61 -0
- package/spec/output-schemas/retrieval-trace-filters.schema.json +139 -0
- package/spec/output-schemas/retrieval-trace-judgment.schema.json +15 -0
- package/spec/output-schemas/retrieval-trace-list.schema.json +18 -0
- package/spec/output-schemas/retrieval-trace-payloads.schema.json +178 -0
- package/spec/output-schemas/retrieval-trace-purge.schema.json +31 -0
- package/spec/output-schemas/retrieval-trace-qrels.schema.json +303 -0
- package/spec/output-schemas/retrieval-trace-replay.schema.json +286 -0
- package/spec/output-schemas/retrieval-trace-show.schema.json +69 -0
- package/spec/output-schemas/retrieval-trace-summary.schema.json +65 -0
- package/spec/output-schemas/search-result.schema.json +154 -0
- package/spec/output-schemas/search-results.schema.json +338 -0
- package/spec/output-schemas/similar.schema.json +84 -0
- package/spec/output-schemas/status.schema.json +676 -0
- package/spec/output-schemas/tags-list.schema.json +48 -0
- package/src/app/context-runtime-types.ts +3 -0
- package/src/app/context-runtime.ts +15 -1
- package/src/cli/commands/ask.ts +106 -36
- package/src/cli/commands/context-build.ts +56 -9
- package/src/cli/commands/daemon.ts +69 -2
- package/src/cli/commands/get.ts +64 -3
- package/src/cli/commands/models/pull.ts +13 -3
- package/src/cli/commands/query.ts +62 -23
- package/src/cli/commands/replay.ts +140 -0
- package/src/cli/commands/search.ts +48 -3
- package/src/cli/commands/shared.ts +3 -1
- package/src/cli/commands/status.ts +2 -0
- package/src/cli/commands/trace.ts +200 -0
- package/src/cli/commands/vsearch.ts +75 -53
- package/src/cli/detach.ts +37 -20
- package/src/cli/program.ts +329 -27
- package/src/config/index.ts +12 -0
- package/src/config/retrieval-traces.ts +56 -0
- package/src/config/types.ts +41 -0
- package/src/core/context-compiler.ts +11 -4
- package/src/core/job-manager.ts +19 -0
- package/src/core/mutation-generations.ts +33 -0
- package/src/core/retrieval-qrels.ts +405 -0
- package/src/core/retrieval-replay-candidate.ts +368 -0
- package/src/core/retrieval-replay-types.ts +109 -0
- package/src/core/retrieval-replay-validation.ts +89 -0
- package/src/core/retrieval-replay.ts +441 -0
- package/src/core/retrieval-trace-evidence-origin.ts +175 -0
- package/src/core/retrieval-trace-export.ts +113 -0
- package/src/core/retrieval-trace-filter-normalization.ts +27 -0
- package/src/core/retrieval-trace-filters.ts +19 -0
- package/src/core/retrieval-trace-management-helpers.ts +247 -0
- package/src/core/retrieval-trace-management-types.ts +132 -0
- package/src/core/retrieval-trace-management.ts +422 -0
- package/src/core/retrieval-trace-request.ts +141 -0
- package/src/core/retrieval-trace-session.ts +494 -0
- package/src/core/retrieval-trace.ts +472 -0
- package/src/llm/cache.ts +13 -3
- package/src/llm/nodeLlamaCpp/adapter.ts +10 -1
- package/src/llm/nodeLlamaCpp/lifecycle.ts +71 -0
- package/src/mcp/context.ts +161 -0
- package/src/mcp/http-security.ts +477 -0
- package/src/mcp/http-session.ts +272 -0
- package/src/mcp/http-transport.ts +370 -0
- package/src/mcp/resources/index.ts +141 -134
- package/src/mcp/server.ts +19 -79
- package/src/mcp/tools/add-collection.ts +3 -1
- package/src/mcp/tools/capture.ts +3 -0
- package/src/mcp/tools/clear-collection-embeddings.ts +2 -0
- package/src/mcp/tools/context.ts +68 -16
- package/src/mcp/tools/embed.ts +62 -52
- package/src/mcp/tools/get.ts +35 -1
- package/src/mcp/tools/index-cmd.ts +88 -74
- package/src/mcp/tools/index.ts +96 -2
- package/src/mcp/tools/query.ts +95 -64
- package/src/mcp/tools/remove-collection.ts +2 -0
- package/src/mcp/tools/search.ts +36 -13
- package/src/mcp/tools/status.ts +11 -0
- package/src/mcp/tools/sync.ts +16 -14
- package/src/mcp/tools/trace.ts +143 -0
- package/src/mcp/tools/vsearch.ts +71 -38
- package/src/mcp/tools/workspace-write.ts +7 -3
- package/src/pipeline/answer.ts +167 -26
- package/src/pipeline/graph-retrieval.ts +15 -1
- package/src/pipeline/hybrid.ts +151 -43
- package/src/pipeline/search.ts +36 -3
- package/src/pipeline/trace-metadata.ts +47 -0
- package/src/pipeline/types.ts +43 -0
- package/src/pipeline/vsearch.ts +101 -38
- package/src/sdk/client.ts +380 -71
- package/src/sdk/documents.ts +48 -1
- package/src/sdk/index.ts +17 -0
- package/src/sdk/types.ts +28 -0
- package/src/serve/background-runtime.ts +12 -212
- package/src/serve/context-capsule.ts +67 -8
- package/src/serve/embed-scheduler.ts +74 -43
- package/src/serve/index.ts +9 -0
- package/src/serve/jobs.ts +78 -80
- package/src/serve/public/app.tsx +12 -1
- package/src/serve/public/components/HealthCenter.tsx +74 -1
- package/src/serve/public/globals.built.css +1 -1
- package/src/serve/public/lib/workspace-tabs.ts +2 -0
- package/src/serve/public/pages/Dashboard.tsx +11 -0
- package/src/serve/public/pages/TraceHistory.tsx +478 -0
- package/src/serve/public/pages/trace-history-detail.tsx +224 -0
- package/src/serve/resident-admission.ts +159 -0
- package/src/serve/resident-background-work.ts +39 -0
- package/src/serve/resident-request.ts +55 -0
- package/src/serve/resident-runtime.ts +490 -0
- package/src/serve/resident-status.ts +96 -0
- package/src/serve/retrieval-trace.ts +28 -0
- package/src/serve/routes/api.ts +629 -239
- package/src/serve/routes/mcp.ts +69 -0
- package/src/serve/routes/traces.ts +156 -0
- package/src/serve/server.ts +276 -37
- package/src/serve/status-model.ts +51 -0
- package/src/serve/status.ts +5 -0
- package/src/store/index.ts +31 -0
- package/src/store/migrations/014-retrieval-traces.ts +303 -0
- package/src/store/migrations/index.ts +2 -0
- package/src/store/retrieval-trace-codec.ts +384 -0
- package/src/store/sqlite/adapter.ts +179 -10
- package/src/store/sqlite/retrieval-trace-management-store.ts +341 -0
- package/src/store/sqlite/retrieval-trace-retention.ts +349 -0
- package/src/store/sqlite/retrieval-trace-rows.ts +267 -0
- package/src/store/sqlite/retrieval-trace-store.ts +515 -0
- package/src/store/types.ts +297 -0
- package/src/store/vector/sqlite-vec.ts +76 -1
- package/src/store/vector/types.ts +1 -1
package/src/mcp/tools/embed.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type { ToolContext } from "../server";
|
|
|
9
9
|
import { MCP_ERRORS } from "../../core/errors";
|
|
10
10
|
import { acquireWriteLock, type WriteLockHandle } from "../../core/file-lock";
|
|
11
11
|
import { JobError } from "../../core/job-manager";
|
|
12
|
+
import { recordIndexMutation } from "../../core/mutation-generations";
|
|
12
13
|
import { embedBacklog } from "../../embed";
|
|
13
14
|
import { LlmAdapter } from "../../llm/nodeLlamaCpp/adapter";
|
|
14
15
|
import { resolveModelUri } from "../../llm/registry";
|
|
@@ -81,64 +82,73 @@ export function handleEmbed(
|
|
|
81
82
|
"embed",
|
|
82
83
|
lock,
|
|
83
84
|
async () => {
|
|
84
|
-
|
|
85
|
-
const llm = new LlmAdapter(ctx.config);
|
|
86
|
-
const embedResult = await llm.createEmbeddingPort(modelUri, {
|
|
87
|
-
policy: { offline: true, allowDownload: false },
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
if (!embedResult.ok) {
|
|
91
|
-
throw new Error(
|
|
92
|
-
`MODEL_NOT_FOUND: Embedding model not cached. ` +
|
|
93
|
-
`Model: ${modelUri}. ` +
|
|
94
|
-
`Run 'gno models pull embed' first.`
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const embedPort = embedResult.value;
|
|
99
|
-
|
|
85
|
+
const lease = ctx.acquireModelLease?.();
|
|
100
86
|
try {
|
|
101
|
-
//
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
const dimensions = embedPort.dimensions();
|
|
107
|
-
|
|
108
|
-
// Create vector index port
|
|
109
|
-
const db = ctx.store.getRawDb();
|
|
110
|
-
const vectorResult = await createVectorIndexPort(db, {
|
|
111
|
-
model: modelUri,
|
|
112
|
-
dimensions,
|
|
113
|
-
});
|
|
114
|
-
if (!vectorResult.ok) {
|
|
115
|
-
throw new Error(vectorResult.error.message);
|
|
116
|
-
}
|
|
117
|
-
const vectorIndex = vectorResult.value;
|
|
118
|
-
|
|
119
|
-
// Create stats port for backlog
|
|
120
|
-
const statsPort = createVectorStatsPort(db);
|
|
121
|
-
|
|
122
|
-
// Run embedding
|
|
123
|
-
const result = await embedBacklog({
|
|
124
|
-
statsPort,
|
|
125
|
-
embedPort,
|
|
126
|
-
vectorIndex,
|
|
127
|
-
collection: collection?.name,
|
|
128
|
-
modelUri,
|
|
129
|
-
batchSize: 32,
|
|
87
|
+
// Create LLM adapter with offline policy (fail-fast, no download)
|
|
88
|
+
const llm = new LlmAdapter(ctx.config);
|
|
89
|
+
const embedResult = await llm.createEmbeddingPort(modelUri, {
|
|
90
|
+
policy: { offline: true, allowDownload: false },
|
|
130
91
|
});
|
|
131
92
|
|
|
132
|
-
if (!
|
|
133
|
-
throw new Error(
|
|
93
|
+
if (!embedResult.ok) {
|
|
94
|
+
throw new Error(
|
|
95
|
+
`MODEL_NOT_FOUND: Embedding model not cached. ` +
|
|
96
|
+
`Model: ${modelUri}. ` +
|
|
97
|
+
`Run 'gno models pull embed' first.`
|
|
98
|
+
);
|
|
134
99
|
}
|
|
135
100
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
101
|
+
const embedPort = embedResult.value;
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
// Initialize and get dimensions from port interface
|
|
105
|
+
const initResult = await embedPort.init();
|
|
106
|
+
if (!initResult.ok) {
|
|
107
|
+
throw new Error(initResult.error.message);
|
|
108
|
+
}
|
|
109
|
+
const dimensions = embedPort.dimensions();
|
|
110
|
+
|
|
111
|
+
// Create vector index port
|
|
112
|
+
const db = ctx.store.getRawDb();
|
|
113
|
+
const vectorResult = await createVectorIndexPort(db, {
|
|
114
|
+
model: modelUri,
|
|
115
|
+
dimensions,
|
|
116
|
+
});
|
|
117
|
+
if (!vectorResult.ok) {
|
|
118
|
+
throw new Error(vectorResult.error.message);
|
|
119
|
+
}
|
|
120
|
+
const vectorIndex = vectorResult.value;
|
|
121
|
+
|
|
122
|
+
// Create stats port for backlog
|
|
123
|
+
const statsPort = createVectorStatsPort(db);
|
|
124
|
+
|
|
125
|
+
// Run embedding
|
|
126
|
+
const result = await embedBacklog({
|
|
127
|
+
statsPort,
|
|
128
|
+
embedPort,
|
|
129
|
+
vectorIndex,
|
|
130
|
+
collection: collection?.name,
|
|
131
|
+
modelUri,
|
|
132
|
+
batchSize: 32,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
if (!result.ok) {
|
|
136
|
+
throw new Error(result.error.message);
|
|
137
|
+
}
|
|
138
|
+
recordIndexMutation(
|
|
139
|
+
result.value.embedded,
|
|
140
|
+
ctx.markIndexMutation
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
kind: "embed" as const,
|
|
145
|
+
value: result.value,
|
|
146
|
+
};
|
|
147
|
+
} finally {
|
|
148
|
+
await embedPort.dispose();
|
|
149
|
+
}
|
|
140
150
|
} finally {
|
|
141
|
-
|
|
151
|
+
lease?.release();
|
|
142
152
|
}
|
|
143
153
|
}
|
|
144
154
|
);
|
package/src/mcp/tools/get.ts
CHANGED
|
@@ -16,6 +16,11 @@ import {
|
|
|
16
16
|
} from "../../core/document-capabilities";
|
|
17
17
|
import { resolveEffectiveIndex } from "../../core/indexed-reference";
|
|
18
18
|
import { parseRef } from "../../core/ref-parser";
|
|
19
|
+
import {
|
|
20
|
+
attachRetrievalTraceMetadata,
|
|
21
|
+
evidenceFromExactDocument,
|
|
22
|
+
RetrievalTraceSession,
|
|
23
|
+
} from "../../core/retrieval-trace-session";
|
|
19
24
|
import { openScopedIndexStore } from "../../store/sqlite/scoped-index";
|
|
20
25
|
import { runTool, type ToolResult } from "./index";
|
|
21
26
|
|
|
@@ -24,6 +29,7 @@ interface GetInput {
|
|
|
24
29
|
fromLine?: number;
|
|
25
30
|
lineCount?: number;
|
|
26
31
|
lineNumbers?: boolean;
|
|
32
|
+
traceId?: string;
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
interface GetResponse {
|
|
@@ -165,6 +171,7 @@ export function handleGet(
|
|
|
165
171
|
|
|
166
172
|
// Apply line range if specified
|
|
167
173
|
let content = fullContent;
|
|
174
|
+
let exactContent = fullContent;
|
|
168
175
|
let returnedLines: { start: number; end: number } | undefined;
|
|
169
176
|
|
|
170
177
|
// lineNumbers defaults to true per spec
|
|
@@ -176,12 +183,14 @@ export function handleGet(
|
|
|
176
183
|
if (startLine > totalLines) {
|
|
177
184
|
// Return empty content for out-of-range request
|
|
178
185
|
content = "";
|
|
186
|
+
exactContent = "";
|
|
179
187
|
returnedLines = undefined;
|
|
180
188
|
} else {
|
|
181
189
|
const count = args.lineCount ?? totalLines - startLine + 1;
|
|
182
190
|
const endLine = Math.min(startLine + count - 1, totalLines);
|
|
183
191
|
|
|
184
192
|
const slicedLines = contentLines.slice(startLine - 1, endLine);
|
|
193
|
+
exactContent = slicedLines.join("\n");
|
|
185
194
|
|
|
186
195
|
if (showLineNumbers) {
|
|
187
196
|
content = slicedLines
|
|
@@ -242,7 +251,32 @@ export function handleGet(
|
|
|
242
251
|
}),
|
|
243
252
|
};
|
|
244
253
|
|
|
245
|
-
return response;
|
|
254
|
+
if (!args.traceId) return response;
|
|
255
|
+
const resumed = await RetrievalTraceSession.resume({
|
|
256
|
+
store: scoped.store,
|
|
257
|
+
config: ctx.config.retrievalTraces,
|
|
258
|
+
traceId: args.traceId,
|
|
259
|
+
});
|
|
260
|
+
if (!resumed.ok) throw new Error(resumed.error.message);
|
|
261
|
+
const traceSession = resumed.value;
|
|
262
|
+
if (!traceSession) return response;
|
|
263
|
+
const lines = returnedLines ?? { start: 1, end: totalLines };
|
|
264
|
+
const evidence = evidenceFromExactDocument({
|
|
265
|
+
docid: response.docid,
|
|
266
|
+
uri: response.uri,
|
|
267
|
+
sourceHash: response.source.sourceHash,
|
|
268
|
+
mirrorHash: response.conversion?.mirrorHash,
|
|
269
|
+
content: exactContent,
|
|
270
|
+
startLine: lines.start,
|
|
271
|
+
endLine: lines.end,
|
|
272
|
+
});
|
|
273
|
+
if (evidence) {
|
|
274
|
+
const got = await traceSession.recordEvidence("get", [evidence]);
|
|
275
|
+
if (!got.ok) throw new Error(got.error.message);
|
|
276
|
+
const opened = await traceSession.recordEvidence("open", [evidence]);
|
|
277
|
+
if (!opened.ok) throw new Error(opened.error.message);
|
|
278
|
+
}
|
|
279
|
+
return attachRetrievalTraceMetadata(response, traceSession);
|
|
246
280
|
} finally {
|
|
247
281
|
await scoped.close();
|
|
248
282
|
}
|
|
@@ -10,6 +10,10 @@ import type { ToolContext } from "../server";
|
|
|
10
10
|
import { MCP_ERRORS } from "../../core/errors";
|
|
11
11
|
import { acquireWriteLock, type WriteLockHandle } from "../../core/file-lock";
|
|
12
12
|
import { JobError } from "../../core/job-manager";
|
|
13
|
+
import {
|
|
14
|
+
recordContentMutation,
|
|
15
|
+
recordIndexMutation,
|
|
16
|
+
} from "../../core/mutation-generations";
|
|
13
17
|
import { normalizeCollectionName } from "../../core/validation";
|
|
14
18
|
import { embedBacklog } from "../../embed";
|
|
15
19
|
import { defaultSyncService, withContentTypeRules } from "../../ingestion";
|
|
@@ -115,86 +119,96 @@ export function handleIndex(
|
|
|
115
119
|
"index",
|
|
116
120
|
lock,
|
|
117
121
|
async () => {
|
|
118
|
-
|
|
119
|
-
const syncResult = collection
|
|
120
|
-
? await defaultSyncService
|
|
121
|
-
.syncCollection(collection, ctx.store, options)
|
|
122
|
-
.then((r) => ({
|
|
123
|
-
collections: [r],
|
|
124
|
-
totalDurationMs: r.durationMs,
|
|
125
|
-
totalFilesProcessed: r.filesProcessed,
|
|
126
|
-
totalFilesAdded: r.filesAdded,
|
|
127
|
-
totalFilesUpdated: r.filesUpdated,
|
|
128
|
-
totalFilesErrored: r.filesErrored,
|
|
129
|
-
totalFilesSkipped: r.filesSkipped,
|
|
130
|
-
}))
|
|
131
|
-
: await defaultSyncService.syncAll(
|
|
132
|
-
ctx.collections,
|
|
133
|
-
ctx.store,
|
|
134
|
-
options
|
|
135
|
-
);
|
|
136
|
-
|
|
137
|
-
// Phase 2: Embed
|
|
138
|
-
const llm = new LlmAdapter(ctx.config);
|
|
139
|
-
const embedResult = await llm.createEmbeddingPort(modelUri, {
|
|
140
|
-
policy: { offline: true, allowDownload: false },
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
if (!embedResult.ok) {
|
|
144
|
-
throw new Error(
|
|
145
|
-
`MODEL_NOT_FOUND: Embedding model not cached. ` +
|
|
146
|
-
`Model: ${modelUri}. ` +
|
|
147
|
-
`Run 'gno models pull embed' first.`
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const embedPort = embedResult.value;
|
|
152
|
-
|
|
122
|
+
const lease = ctx.acquireModelLease?.();
|
|
153
123
|
try {
|
|
154
|
-
//
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
embedPort,
|
|
179
|
-
vectorIndex,
|
|
180
|
-
collection: collection?.name,
|
|
181
|
-
modelUri,
|
|
182
|
-
batchSize: 32,
|
|
124
|
+
// Phase 1: Sync
|
|
125
|
+
const syncResult = collection
|
|
126
|
+
? await defaultSyncService
|
|
127
|
+
.syncCollection(collection, ctx.store, options)
|
|
128
|
+
.then((r) => ({
|
|
129
|
+
collections: [r],
|
|
130
|
+
totalDurationMs: r.durationMs,
|
|
131
|
+
totalFilesProcessed: r.filesProcessed,
|
|
132
|
+
totalFilesAdded: r.filesAdded,
|
|
133
|
+
totalFilesUpdated: r.filesUpdated,
|
|
134
|
+
totalFilesErrored: r.filesErrored,
|
|
135
|
+
totalFilesSkipped: r.filesSkipped,
|
|
136
|
+
}))
|
|
137
|
+
: await defaultSyncService.syncAll(
|
|
138
|
+
ctx.collections,
|
|
139
|
+
ctx.store,
|
|
140
|
+
options
|
|
141
|
+
);
|
|
142
|
+
recordContentMutation(syncResult, ctx.markContentMutation);
|
|
143
|
+
|
|
144
|
+
// Phase 2: Embed
|
|
145
|
+
const llm = new LlmAdapter(ctx.config);
|
|
146
|
+
const embedResult = await llm.createEmbeddingPort(modelUri, {
|
|
147
|
+
policy: { offline: true, allowDownload: false },
|
|
183
148
|
});
|
|
184
149
|
|
|
185
|
-
if (!
|
|
186
|
-
throw new Error(
|
|
150
|
+
if (!embedResult.ok) {
|
|
151
|
+
throw new Error(
|
|
152
|
+
`MODEL_NOT_FOUND: Embedding model not cached. ` +
|
|
153
|
+
`Model: ${modelUri}. ` +
|
|
154
|
+
`Run 'gno models pull embed' first.`
|
|
155
|
+
);
|
|
187
156
|
}
|
|
188
157
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
158
|
+
const embedPort = embedResult.value;
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
// Initialize and get dimensions from port interface
|
|
162
|
+
const initResult = await embedPort.init();
|
|
163
|
+
if (!initResult.ok) {
|
|
164
|
+
throw new Error(initResult.error.message);
|
|
165
|
+
}
|
|
166
|
+
const dimensions = embedPort.dimensions();
|
|
167
|
+
|
|
168
|
+
// Create vector index port
|
|
169
|
+
const db = ctx.store.getRawDb();
|
|
170
|
+
const vectorResult = await createVectorIndexPort(db, {
|
|
171
|
+
model: modelUri,
|
|
172
|
+
dimensions,
|
|
173
|
+
});
|
|
174
|
+
if (!vectorResult.ok) {
|
|
175
|
+
throw new Error(vectorResult.error.message);
|
|
176
|
+
}
|
|
177
|
+
const vectorIndex = vectorResult.value;
|
|
178
|
+
|
|
179
|
+
// Create stats port for backlog
|
|
180
|
+
const statsPort = createVectorStatsPort(db);
|
|
181
|
+
|
|
182
|
+
// Run embedding
|
|
183
|
+
const backlogResult = await embedBacklog({
|
|
184
|
+
statsPort,
|
|
185
|
+
embedPort,
|
|
186
|
+
vectorIndex,
|
|
187
|
+
collection: collection?.name,
|
|
188
|
+
modelUri,
|
|
189
|
+
batchSize: 32,
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
if (!backlogResult.ok) {
|
|
193
|
+
throw new Error(backlogResult.error.message);
|
|
194
|
+
}
|
|
195
|
+
recordIndexMutation(
|
|
196
|
+
backlogResult.value.embedded,
|
|
197
|
+
ctx.markIndexMutation
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
kind: "index" as const,
|
|
202
|
+
value: {
|
|
203
|
+
sync: syncResult,
|
|
204
|
+
embed: backlogResult.value,
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
} finally {
|
|
208
|
+
await embedPort.dispose();
|
|
209
|
+
}
|
|
196
210
|
} finally {
|
|
197
|
-
|
|
211
|
+
lease?.release();
|
|
198
212
|
}
|
|
199
213
|
}
|
|
200
214
|
);
|
package/src/mcp/tools/index.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
} from "../../app/context-surface";
|
|
17
17
|
import { CAPTURE_MAX_TEXT_BYTES } from "../../core/capture";
|
|
18
18
|
import { NOTE_PRESETS, type NotePresetId } from "../../core/note-presets";
|
|
19
|
+
import { RETRIEVAL_TRACE_METADATA } from "../../core/retrieval-trace-session";
|
|
19
20
|
import { normalizeTag } from "../../core/tags";
|
|
20
21
|
import { handleAddCollection } from "./add-collection";
|
|
21
22
|
import { handleCapture } from "./capture";
|
|
@@ -42,6 +43,20 @@ import { handleRemoveCollection } from "./remove-collection";
|
|
|
42
43
|
import { handleSearch } from "./search";
|
|
43
44
|
import { handleStatus } from "./status";
|
|
44
45
|
import { handleSync } from "./sync";
|
|
46
|
+
import {
|
|
47
|
+
handleTraceDelete,
|
|
48
|
+
handleTraceExport,
|
|
49
|
+
handleTraceLabel,
|
|
50
|
+
handleTraceList,
|
|
51
|
+
handleTracePurge,
|
|
52
|
+
handleTraceShow,
|
|
53
|
+
traceDeleteInputSchema,
|
|
54
|
+
traceExportInputSchema,
|
|
55
|
+
traceLabelInputSchema,
|
|
56
|
+
traceListInputSchema,
|
|
57
|
+
tracePurgeInputSchema,
|
|
58
|
+
traceShowInputSchema,
|
|
59
|
+
} from "./trace";
|
|
45
60
|
import { handleVsearch } from "./vsearch";
|
|
46
61
|
import {
|
|
47
62
|
handleCreateFolder,
|
|
@@ -83,6 +98,25 @@ export const MCP_TOOL_DESCRIPTIONS = {
|
|
|
83
98
|
"Verify a saved Context Capsule without rebuilding or mutating it. Reports unchanged, stale, missing, reranked, and fingerprint drift states against the active index.",
|
|
84
99
|
} as const;
|
|
85
100
|
|
|
101
|
+
/** Tool names whose execution mutates disk, config, or index state. */
|
|
102
|
+
export const MCP_WRITE_TOOL_NAMES = new Set([
|
|
103
|
+
"gno_capture",
|
|
104
|
+
"gno_add_collection",
|
|
105
|
+
"gno_sync",
|
|
106
|
+
"gno_embed",
|
|
107
|
+
"gno_index",
|
|
108
|
+
"gno_remove_collection",
|
|
109
|
+
"gno_clear_collection_embeddings",
|
|
110
|
+
"gno_create_folder",
|
|
111
|
+
"gno_rename_note",
|
|
112
|
+
"gno_move_note",
|
|
113
|
+
"gno_duplicate_note",
|
|
114
|
+
"gno_trace_label",
|
|
115
|
+
"gno_trace_export",
|
|
116
|
+
"gno_trace_delete",
|
|
117
|
+
"gno_trace_purge",
|
|
118
|
+
]);
|
|
119
|
+
|
|
86
120
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
87
121
|
// Shared Input Schemas
|
|
88
122
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -548,6 +582,12 @@ const getInputSchema = z.object({
|
|
|
548
582
|
.boolean()
|
|
549
583
|
.default(true)
|
|
550
584
|
.describe("Include line numbers in output"),
|
|
585
|
+
traceId: z
|
|
586
|
+
.string()
|
|
587
|
+
.min(1)
|
|
588
|
+
.max(128)
|
|
589
|
+
.optional()
|
|
590
|
+
.describe("Continue an open retrieval trace returned by a search/query"),
|
|
551
591
|
});
|
|
552
592
|
|
|
553
593
|
const multiGetInputSchema = z.object({
|
|
@@ -829,11 +869,19 @@ export async function runTool<T>(
|
|
|
829
869
|
|
|
830
870
|
// Sequential execution via mutex
|
|
831
871
|
const release = await ctx.toolMutex.acquire();
|
|
872
|
+
const modelLease = ctx.acquireModelLease?.();
|
|
832
873
|
try {
|
|
833
|
-
const data = await fn();
|
|
874
|
+
const data = await (ctx.runWithSnapshot?.(fn) ?? fn());
|
|
875
|
+
const traceMetadata =
|
|
876
|
+
data !== null && typeof data === "object"
|
|
877
|
+
? (data as Record<PropertyKey, unknown>)[RETRIEVAL_TRACE_METADATA]
|
|
878
|
+
: undefined;
|
|
834
879
|
return {
|
|
835
880
|
content: [{ type: "text", text: formatText(data) }],
|
|
836
881
|
structuredContent: data as { [x: string]: unknown },
|
|
882
|
+
...(traceMetadata
|
|
883
|
+
? { _meta: { gno: { retrievalTrace: traceMetadata } } }
|
|
884
|
+
: {}),
|
|
837
885
|
};
|
|
838
886
|
} catch (e) {
|
|
839
887
|
// Exception firewall: never throw, always return isError
|
|
@@ -846,6 +894,7 @@ export async function runTool<T>(
|
|
|
846
894
|
structuredContent: parsedError,
|
|
847
895
|
};
|
|
848
896
|
} finally {
|
|
897
|
+
modelLease?.release();
|
|
849
898
|
release();
|
|
850
899
|
}
|
|
851
900
|
}
|
|
@@ -869,8 +918,9 @@ export async function runToolNoMutex<T>(
|
|
|
869
918
|
};
|
|
870
919
|
}
|
|
871
920
|
|
|
921
|
+
const modelLease = ctx.acquireModelLease?.();
|
|
872
922
|
try {
|
|
873
|
-
const data = await fn();
|
|
923
|
+
const data = await (ctx.runWithSnapshot?.(fn) ?? fn());
|
|
874
924
|
return {
|
|
875
925
|
content: [{ type: "text", text: formatText(data) }],
|
|
876
926
|
structuredContent: data as { [x: string]: unknown },
|
|
@@ -885,6 +935,8 @@ export async function runToolNoMutex<T>(
|
|
|
885
935
|
content: [{ type: "text", text: `Error: ${message}` }],
|
|
886
936
|
structuredContent: parsedError,
|
|
887
937
|
};
|
|
938
|
+
} finally {
|
|
939
|
+
modelLease?.release();
|
|
888
940
|
}
|
|
889
941
|
}
|
|
890
942
|
|
|
@@ -975,6 +1027,20 @@ export function registerTools(server: McpServer, ctx: ToolContext): void {
|
|
|
975
1027
|
(args) => handleStatus(args, ctx)
|
|
976
1028
|
);
|
|
977
1029
|
|
|
1030
|
+
server.tool(
|
|
1031
|
+
"gno_trace_list",
|
|
1032
|
+
"List bounded metadata-only summaries of private local retrieval traces. Raw replay queries are omitted from history.",
|
|
1033
|
+
traceListInputSchema.shape,
|
|
1034
|
+
(args) => handleTraceList(args, ctx)
|
|
1035
|
+
);
|
|
1036
|
+
|
|
1037
|
+
server.tool(
|
|
1038
|
+
"gno_trace_show",
|
|
1039
|
+
"Inspect one bounded local retrieval trace. Replay-mode content is returned only for the explicitly requested trace.",
|
|
1040
|
+
traceShowInputSchema.shape,
|
|
1041
|
+
(args) => handleTraceShow(args, ctx)
|
|
1042
|
+
);
|
|
1043
|
+
|
|
978
1044
|
server.tool(
|
|
979
1045
|
"gno_list_tags",
|
|
980
1046
|
"List all tags with document counts. Use prefix to filter hierarchical tags (e.g. 'project/').",
|
|
@@ -1032,6 +1098,34 @@ export function registerTools(server: McpServer, ctx: ToolContext): void {
|
|
|
1032
1098
|
);
|
|
1033
1099
|
|
|
1034
1100
|
if (ctx.enableWrite) {
|
|
1101
|
+
server.tool(
|
|
1102
|
+
"gno_trace_label",
|
|
1103
|
+
"Append an explicit relevant, irrelevant, or missing_expected judgment to a local retrieval trace.",
|
|
1104
|
+
traceLabelInputSchema.shape,
|
|
1105
|
+
(args) => handleTraceLabel(args, ctx)
|
|
1106
|
+
);
|
|
1107
|
+
|
|
1108
|
+
server.tool(
|
|
1109
|
+
"gno_trace_export",
|
|
1110
|
+
"Build a deterministic local agentic receipt from one or more immutable terminal retrieval traces.",
|
|
1111
|
+
traceExportInputSchema.shape,
|
|
1112
|
+
(args) => handleTraceExport(args, ctx)
|
|
1113
|
+
);
|
|
1114
|
+
|
|
1115
|
+
server.tool(
|
|
1116
|
+
"gno_trace_delete",
|
|
1117
|
+
"Delete one private local retrieval trace and all owned receipt records.",
|
|
1118
|
+
traceDeleteInputSchema.shape,
|
|
1119
|
+
(args) => handleTraceDelete(args, ctx)
|
|
1120
|
+
);
|
|
1121
|
+
|
|
1122
|
+
server.tool(
|
|
1123
|
+
"gno_trace_purge",
|
|
1124
|
+
"Purge every private local retrieval trace receipt. Requires confirm=true.",
|
|
1125
|
+
tracePurgeInputSchema.shape,
|
|
1126
|
+
(args) => handleTracePurge(args, ctx)
|
|
1127
|
+
);
|
|
1128
|
+
|
|
1035
1129
|
server.tool(
|
|
1036
1130
|
"gno_capture",
|
|
1037
1131
|
"Create a new document in a collection. Writes to disk. Does NOT auto-embed; run gno_index after to make it searchable via vector search.",
|