@gmickel/gno 1.18.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 +5 -3
- package/assets/skill/SKILL.md +27 -0
- package/package.json +2 -1
- 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/get.ts +64 -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/trace.ts +200 -0
- package/src/cli/commands/vsearch.ts +75 -53
- package/src/cli/program.ts +255 -0
- package/src/config/index.ts +9 -0
- package/src/config/retrieval-traces.ts +56 -0
- package/src/config/types.ts +4 -0
- package/src/core/context-compiler.ts +11 -4
- 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/mcp/tools/context.ts +59 -8
- package/src/mcp/tools/get.ts +35 -1
- package/src/mcp/tools/index.ts +74 -0
- package/src/mcp/tools/query.ts +95 -64
- package/src/mcp/tools/search.ts +36 -13
- package/src/mcp/tools/trace.ts +143 -0
- package/src/mcp/tools/vsearch.ts +71 -38
- 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/context-capsule.ts +67 -8
- package/src/serve/public/app.tsx +12 -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 +10 -0
- package/src/serve/public/pages/TraceHistory.tsx +478 -0
- package/src/serve/public/pages/trace-history-detail.tsx +224 -0
- package/src/serve/retrieval-trace.ts +28 -0
- package/src/serve/routes/api.ts +366 -72
- package/src/serve/routes/traces.ts +156 -0
- package/src/serve/server.ts +87 -2
- 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 +153 -1
- 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/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,
|
|
@@ -96,6 +111,10 @@ export const MCP_WRITE_TOOL_NAMES = new Set([
|
|
|
96
111
|
"gno_rename_note",
|
|
97
112
|
"gno_move_note",
|
|
98
113
|
"gno_duplicate_note",
|
|
114
|
+
"gno_trace_label",
|
|
115
|
+
"gno_trace_export",
|
|
116
|
+
"gno_trace_delete",
|
|
117
|
+
"gno_trace_purge",
|
|
99
118
|
]);
|
|
100
119
|
|
|
101
120
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -563,6 +582,12 @@ const getInputSchema = z.object({
|
|
|
563
582
|
.boolean()
|
|
564
583
|
.default(true)
|
|
565
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"),
|
|
566
591
|
});
|
|
567
592
|
|
|
568
593
|
const multiGetInputSchema = z.object({
|
|
@@ -847,9 +872,16 @@ export async function runTool<T>(
|
|
|
847
872
|
const modelLease = ctx.acquireModelLease?.();
|
|
848
873
|
try {
|
|
849
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;
|
|
850
879
|
return {
|
|
851
880
|
content: [{ type: "text", text: formatText(data) }],
|
|
852
881
|
structuredContent: data as { [x: string]: unknown },
|
|
882
|
+
...(traceMetadata
|
|
883
|
+
? { _meta: { gno: { retrievalTrace: traceMetadata } } }
|
|
884
|
+
: {}),
|
|
853
885
|
};
|
|
854
886
|
} catch (e) {
|
|
855
887
|
// Exception firewall: never throw, always return isError
|
|
@@ -995,6 +1027,20 @@ export function registerTools(server: McpServer, ctx: ToolContext): void {
|
|
|
995
1027
|
(args) => handleStatus(args, ctx)
|
|
996
1028
|
);
|
|
997
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
|
+
|
|
998
1044
|
server.tool(
|
|
999
1045
|
"gno_list_tags",
|
|
1000
1046
|
"List all tags with document counts. Use prefix to filter hierarchical tags (e.g. 'project/').",
|
|
@@ -1052,6 +1098,34 @@ export function registerTools(server: McpServer, ctx: ToolContext): void {
|
|
|
1052
1098
|
);
|
|
1053
1099
|
|
|
1054
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
|
+
|
|
1055
1129
|
server.tool(
|
|
1056
1130
|
"gno_capture",
|
|
1057
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.",
|
package/src/mcp/tools/query.ts
CHANGED
|
@@ -26,6 +26,15 @@ import {
|
|
|
26
26
|
normalizeContentTypes,
|
|
27
27
|
} from "../../config";
|
|
28
28
|
import { resolveDepthPolicy } from "../../core/depth-policy";
|
|
29
|
+
import {
|
|
30
|
+
finishRetrievalTraceAfterError,
|
|
31
|
+
retrievalTraceFilters,
|
|
32
|
+
startRetrievalTraceRequest,
|
|
33
|
+
} from "../../core/retrieval-trace-request";
|
|
34
|
+
import {
|
|
35
|
+
attachRetrievalTraceMetadata,
|
|
36
|
+
type RetrievalTraceSession,
|
|
37
|
+
} from "../../core/retrieval-trace-session";
|
|
29
38
|
import { normalizeStructuredQueryInput } from "../../core/structured-query";
|
|
30
39
|
import { LlmAdapter } from "../../llm/nodeLlamaCpp/adapter";
|
|
31
40
|
import { resolveDownloadPolicy } from "../../llm/policy";
|
|
@@ -195,26 +204,79 @@ export function handleQuery(
|
|
|
195
204
|
: undefined;
|
|
196
205
|
|
|
197
206
|
const preset = getActivePreset(ctx.config);
|
|
198
|
-
const llm = new LlmAdapter(ctx.config);
|
|
199
|
-
|
|
200
|
-
// Resolve download policy from env (MCP has no CLI flags)
|
|
201
|
-
const policy = resolveDownloadPolicy(process.env, {});
|
|
202
|
-
|
|
203
|
-
// Non-TTY progress for MCP (periodic lines to stderr, not \r)
|
|
204
|
-
const downloadProgress = createNonTtyProgressRenderer();
|
|
205
207
|
|
|
206
208
|
let embedPort: EmbeddingPort | null = null;
|
|
207
209
|
let expandPort: GenerationPort | null = null;
|
|
208
210
|
let rerankPort: RerankPort | null = null;
|
|
209
211
|
let vectorIndex: VectorIndexPort | null = null;
|
|
212
|
+
let traceSession: RetrievalTraceSession | undefined;
|
|
210
213
|
const embedUri = resolveModelUri(
|
|
211
214
|
ctx.config,
|
|
212
215
|
"embed",
|
|
213
216
|
undefined,
|
|
214
217
|
args.collection
|
|
215
218
|
);
|
|
219
|
+
const hasStructuredModes = Boolean(queryModes?.length);
|
|
220
|
+
const depthPolicy = resolveDepthPolicy({
|
|
221
|
+
presetId: preset.id,
|
|
222
|
+
fast: args.fast,
|
|
223
|
+
thorough: args.thorough,
|
|
224
|
+
expand: args.expand,
|
|
225
|
+
rerank: args.rerank,
|
|
226
|
+
candidateLimit: args.candidateLimit,
|
|
227
|
+
hasStructuredModes,
|
|
228
|
+
});
|
|
229
|
+
const { noExpand, noRerank } = depthPolicy;
|
|
230
|
+
const expandUri =
|
|
231
|
+
!noExpand && !hasStructuredModes
|
|
232
|
+
? resolveModelUri(ctx.config, "expand", undefined, args.collection)
|
|
233
|
+
: undefined;
|
|
234
|
+
const rerankUri = !noRerank
|
|
235
|
+
? resolveModelUri(ctx.config, "rerank", undefined, args.collection)
|
|
236
|
+
: undefined;
|
|
237
|
+
const options = {
|
|
238
|
+
limit: args.limit ?? 5,
|
|
239
|
+
minScore: args.minScore,
|
|
240
|
+
collection: args.collection,
|
|
241
|
+
queryLanguageHint: args.lang,
|
|
242
|
+
intent: args.intent,
|
|
243
|
+
candidateLimit: depthPolicy.candidateLimit,
|
|
244
|
+
exclude: args.exclude,
|
|
245
|
+
since: args.since,
|
|
246
|
+
until: args.until,
|
|
247
|
+
categories: args.categories,
|
|
248
|
+
author: args.author,
|
|
249
|
+
noExpand,
|
|
250
|
+
noRerank,
|
|
251
|
+
graph: args.graph === true,
|
|
252
|
+
noGraph: args.noGraph || args.fast,
|
|
253
|
+
queryModes,
|
|
254
|
+
tagsAll: normalizeTagFilters(args.tagsAll),
|
|
255
|
+
tagsAny: normalizeTagFilters(args.tagsAny),
|
|
256
|
+
};
|
|
216
257
|
|
|
217
258
|
try {
|
|
259
|
+
const traceStart = await startRetrievalTraceRequest({
|
|
260
|
+
store: ctx.store,
|
|
261
|
+
config: ctx.config,
|
|
262
|
+
query: queryText,
|
|
263
|
+
filters: retrievalTraceFilters(options),
|
|
264
|
+
pipeline: "hybrid",
|
|
265
|
+
indexName: ctx.indexName,
|
|
266
|
+
modelUris: [embedUri, expandUri, rerankUri].filter(
|
|
267
|
+
(value): value is string => Boolean(value)
|
|
268
|
+
),
|
|
269
|
+
});
|
|
270
|
+
if (!traceStart.ok) throw new Error(traceStart.error.message);
|
|
271
|
+
traceSession = traceStart.value ?? undefined;
|
|
272
|
+
const llm = new LlmAdapter(ctx.config);
|
|
273
|
+
|
|
274
|
+
// Resolve download policy from env (MCP has no CLI flags)
|
|
275
|
+
const policy = resolveDownloadPolicy(process.env, {});
|
|
276
|
+
|
|
277
|
+
// Non-TTY progress for MCP (periodic lines to stderr, not \r)
|
|
278
|
+
const downloadProgress = createNonTtyProgressRenderer();
|
|
279
|
+
|
|
218
280
|
// Create embedding port (for vector search) - optional
|
|
219
281
|
const embedResult = await llm.createEmbeddingPort(embedUri, {
|
|
220
282
|
policy,
|
|
@@ -224,41 +286,23 @@ export function handleQuery(
|
|
|
224
286
|
embedPort = embedResult.value;
|
|
225
287
|
}
|
|
226
288
|
|
|
227
|
-
const hasStructuredModes = Boolean(queryModes?.length);
|
|
228
|
-
const depthPolicy = resolveDepthPolicy({
|
|
229
|
-
presetId: preset.id,
|
|
230
|
-
fast: args.fast,
|
|
231
|
-
thorough: args.thorough,
|
|
232
|
-
expand: args.expand,
|
|
233
|
-
rerank: args.rerank,
|
|
234
|
-
candidateLimit: args.candidateLimit,
|
|
235
|
-
hasStructuredModes,
|
|
236
|
-
});
|
|
237
|
-
const { noExpand, noRerank } = depthPolicy;
|
|
238
|
-
|
|
239
289
|
// Create expansion port - optional
|
|
240
|
-
if (
|
|
241
|
-
const genResult = await llm.createExpansionPort(
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
onProgress: (progress) => downloadProgress("expand", progress),
|
|
246
|
-
}
|
|
247
|
-
);
|
|
290
|
+
if (expandUri) {
|
|
291
|
+
const genResult = await llm.createExpansionPort(expandUri, {
|
|
292
|
+
policy,
|
|
293
|
+
onProgress: (progress) => downloadProgress("expand", progress),
|
|
294
|
+
});
|
|
248
295
|
if (genResult.ok) {
|
|
249
296
|
expandPort = genResult.value;
|
|
250
297
|
}
|
|
251
298
|
}
|
|
252
299
|
|
|
253
300
|
// Create rerank port - optional
|
|
254
|
-
if (
|
|
255
|
-
const rerankResult = await llm.createRerankPort(
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
onProgress: (progress) => downloadProgress("rerank", progress),
|
|
260
|
-
}
|
|
261
|
-
);
|
|
301
|
+
if (rerankUri) {
|
|
302
|
+
const rerankResult = await llm.createRerankPort(rerankUri, {
|
|
303
|
+
policy,
|
|
304
|
+
onProgress: (progress) => downloadProgress("rerank", progress),
|
|
305
|
+
});
|
|
262
306
|
if (rerankResult.ok) {
|
|
263
307
|
rerankPort = rerankResult.value;
|
|
264
308
|
}
|
|
@@ -289,28 +333,9 @@ export function handleQuery(
|
|
|
289
333
|
rerankPort,
|
|
290
334
|
};
|
|
291
335
|
|
|
292
|
-
// Note: per spec, lang is a "hint" for query, not a filter
|
|
293
|
-
// Pass as queryLanguageHint to affect expansion prompt selection
|
|
294
|
-
// but NOT retrieval filtering (that would be options.lang)
|
|
295
336
|
const result = await searchHybrid(deps, queryText, {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
collection: args.collection,
|
|
299
|
-
queryLanguageHint: args.lang, // Affects expansion prompt, not retrieval
|
|
300
|
-
intent: args.intent,
|
|
301
|
-
candidateLimit: depthPolicy.candidateLimit,
|
|
302
|
-
exclude: args.exclude,
|
|
303
|
-
since: args.since,
|
|
304
|
-
until: args.until,
|
|
305
|
-
categories: args.categories,
|
|
306
|
-
author: args.author,
|
|
307
|
-
noExpand,
|
|
308
|
-
noRerank,
|
|
309
|
-
graph: args.graph === true,
|
|
310
|
-
noGraph: args.noGraph || args.fast,
|
|
311
|
-
queryModes,
|
|
312
|
-
tagsAll: normalizeTagFilters(args.tagsAll),
|
|
313
|
-
tagsAny: normalizeTagFilters(args.tagsAny),
|
|
337
|
+
...options,
|
|
338
|
+
traceSession,
|
|
314
339
|
});
|
|
315
340
|
|
|
316
341
|
if (!result.ok) {
|
|
@@ -320,15 +345,21 @@ export function handleQuery(
|
|
|
320
345
|
// Enrich with absPath
|
|
321
346
|
const enrichedResults = enrichWithAbsPath(result.value.results, ctx);
|
|
322
347
|
|
|
323
|
-
return
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
348
|
+
return attachRetrievalTraceMetadata(
|
|
349
|
+
{
|
|
350
|
+
...result.value,
|
|
351
|
+
results: enrichedResults,
|
|
352
|
+
meta: {
|
|
353
|
+
...result.value.meta,
|
|
354
|
+
// Add queryLanguage hint if provided
|
|
355
|
+
...(args.lang ? { queryLanguage: args.lang } : {}),
|
|
356
|
+
},
|
|
330
357
|
},
|
|
331
|
-
|
|
358
|
+
traceSession
|
|
359
|
+
);
|
|
360
|
+
} catch (cause) {
|
|
361
|
+
await finishRetrievalTraceAfterError(traceSession, cause);
|
|
362
|
+
throw cause;
|
|
332
363
|
} finally {
|
|
333
364
|
if (embedPort) {
|
|
334
365
|
await embedPort.dispose();
|
package/src/mcp/tools/search.ts
CHANGED
|
@@ -6,10 +6,17 @@
|
|
|
6
6
|
|
|
7
7
|
import { join as pathJoin } from "node:path";
|
|
8
8
|
|
|
9
|
+
import type { RetrievalTraceSession } from "../../core/retrieval-trace-session";
|
|
9
10
|
import type { SearchResult, SearchResults } from "../../pipeline/types";
|
|
10
11
|
import type { ToolContext } from "../server";
|
|
11
12
|
|
|
12
13
|
import { decorateUriForIndex, parseUri } from "../../app/constants";
|
|
14
|
+
import {
|
|
15
|
+
finishRetrievalTraceAfterError,
|
|
16
|
+
retrievalTraceFilters,
|
|
17
|
+
startRetrievalTraceRequest,
|
|
18
|
+
} from "../../core/retrieval-trace-request";
|
|
19
|
+
import { attachRetrievalTraceMetadata } from "../../core/retrieval-trace-session";
|
|
13
20
|
import { searchBm25 } from "../../pipeline/search";
|
|
14
21
|
import { normalizeTagFilters, runTool, type ToolResult } from "./index";
|
|
15
22
|
|
|
@@ -106,7 +113,7 @@ export function handleSearch(
|
|
|
106
113
|
}
|
|
107
114
|
}
|
|
108
115
|
|
|
109
|
-
const
|
|
116
|
+
const options = {
|
|
110
117
|
limit: args.limit ?? 5,
|
|
111
118
|
minScore: args.minScore,
|
|
112
119
|
collection: args.collection,
|
|
@@ -119,19 +126,35 @@ export function handleSearch(
|
|
|
119
126
|
author: args.author,
|
|
120
127
|
tagsAll: normalizeTagFilters(args.tagsAll),
|
|
121
128
|
tagsAny: normalizeTagFilters(args.tagsAny),
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
if (!result.ok) {
|
|
125
|
-
throw new Error(result.error.message);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Enrich with absPath
|
|
129
|
-
const enrichedResults = enrichWithAbsPath(result.value.results, ctx);
|
|
130
|
-
|
|
131
|
-
return {
|
|
132
|
-
...result.value,
|
|
133
|
-
results: enrichedResults,
|
|
134
129
|
};
|
|
130
|
+
let traceSession: RetrievalTraceSession | undefined;
|
|
131
|
+
try {
|
|
132
|
+
const traceStart = await startRetrievalTraceRequest({
|
|
133
|
+
store: ctx.store,
|
|
134
|
+
config: ctx.config,
|
|
135
|
+
query: args.query,
|
|
136
|
+
filters: retrievalTraceFilters(options),
|
|
137
|
+
pipeline: "bm25",
|
|
138
|
+
indexName: ctx.indexName,
|
|
139
|
+
});
|
|
140
|
+
if (!traceStart.ok) throw new Error(traceStart.error.message);
|
|
141
|
+
traceSession = traceStart.value ?? undefined;
|
|
142
|
+
const result = await searchBm25(ctx.store, args.query, {
|
|
143
|
+
...options,
|
|
144
|
+
traceSession,
|
|
145
|
+
});
|
|
146
|
+
if (!result.ok) throw new Error(result.error.message);
|
|
147
|
+
return attachRetrievalTraceMetadata(
|
|
148
|
+
{
|
|
149
|
+
...result.value,
|
|
150
|
+
results: enrichWithAbsPath(result.value.results, ctx),
|
|
151
|
+
},
|
|
152
|
+
traceSession
|
|
153
|
+
);
|
|
154
|
+
} catch (cause) {
|
|
155
|
+
await finishRetrievalTraceAfterError(traceSession, cause);
|
|
156
|
+
throw cause;
|
|
157
|
+
}
|
|
135
158
|
},
|
|
136
159
|
formatSearchResults
|
|
137
160
|
);
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/** MCP tools for explicit local retrieval-trace management. */
|
|
2
|
+
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
RetrievalTraceExportRequest,
|
|
7
|
+
RetrievalTraceLabelRequest,
|
|
8
|
+
} from "../../core/retrieval-trace-management";
|
|
9
|
+
import type { StoreResult } from "../../store/types";
|
|
10
|
+
import type { ToolContext } from "../server";
|
|
11
|
+
|
|
12
|
+
import { withWriteLock } from "../../core/file-lock";
|
|
13
|
+
import { RetrievalTraceManagementService } from "../../core/retrieval-trace-management";
|
|
14
|
+
import { runTool, type ToolResult } from "./index";
|
|
15
|
+
|
|
16
|
+
export const traceListInputSchema = z.object({
|
|
17
|
+
limit: z.number().int().min(1).max(1000).default(50),
|
|
18
|
+
cursor: z.string().min(1).max(512).optional(),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export const traceShowInputSchema = z.object({
|
|
22
|
+
traceId: z.string().min(1).max(128),
|
|
23
|
+
detailLimit: z.number().int().min(1).max(5000).default(500),
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export const traceLabelInputSchema = z.object({
|
|
27
|
+
traceId: z.string().min(1).max(128),
|
|
28
|
+
label: z.enum(["relevant", "irrelevant", "missing_expected"]),
|
|
29
|
+
targetRef: z.string().min(1).max(4096),
|
|
30
|
+
targetKind: z.enum(["document", "chunk", "span"]).optional(),
|
|
31
|
+
startLine: z.number().int().positive().optional(),
|
|
32
|
+
endLine: z.number().int().positive().optional(),
|
|
33
|
+
sourceHash: z
|
|
34
|
+
.string()
|
|
35
|
+
.regex(/^[a-f0-9]{64}$/)
|
|
36
|
+
.optional(),
|
|
37
|
+
docid: z.string().min(1).max(256).optional(),
|
|
38
|
+
idempotencyKey: z.string().min(1).max(256).optional(),
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export const traceExportInputSchema = z.object({
|
|
42
|
+
traceIds: z.array(z.string().min(1).max(128)).min(1).max(1000),
|
|
43
|
+
format: z.literal("agentic-receipt").default("agentic-receipt"),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export const traceDeleteInputSchema = z.object({
|
|
47
|
+
traceId: z.string().min(1).max(128),
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export const tracePurgeInputSchema = z.object({
|
|
51
|
+
confirm: z.literal(true),
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const unwrap = <T>(result: StoreResult<T>): T => {
|
|
55
|
+
if (result.ok) return result.value;
|
|
56
|
+
throw new Error(`${result.error.code}: ${result.error.message}`);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const jsonText = (value: unknown): string => JSON.stringify(value, null, 2);
|
|
60
|
+
|
|
61
|
+
const writeDisabled = (): never => {
|
|
62
|
+
throw new Error(
|
|
63
|
+
"WRITE_DISABLED: Trace mutations require gateway.enableWrite or --mcp-enable-write"
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const handleTraceList = (
|
|
68
|
+
args: z.infer<typeof traceListInputSchema>,
|
|
69
|
+
ctx: ToolContext
|
|
70
|
+
): Promise<ToolResult> =>
|
|
71
|
+
runTool(
|
|
72
|
+
ctx,
|
|
73
|
+
"gno_trace_list",
|
|
74
|
+
async () =>
|
|
75
|
+
unwrap(await new RetrievalTraceManagementService(ctx.store).list(args)),
|
|
76
|
+
jsonText
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
export const handleTraceShow = (
|
|
80
|
+
args: z.infer<typeof traceShowInputSchema>,
|
|
81
|
+
ctx: ToolContext
|
|
82
|
+
): Promise<ToolResult> =>
|
|
83
|
+
runTool(
|
|
84
|
+
ctx,
|
|
85
|
+
"gno_trace_show",
|
|
86
|
+
async () =>
|
|
87
|
+
unwrap(
|
|
88
|
+
await new RetrievalTraceManagementService(ctx.store).show(
|
|
89
|
+
args.traceId,
|
|
90
|
+
{ detailLimit: args.detailLimit }
|
|
91
|
+
)
|
|
92
|
+
),
|
|
93
|
+
jsonText
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const runTraceWrite = <T>(
|
|
97
|
+
ctx: ToolContext,
|
|
98
|
+
name: string,
|
|
99
|
+
operation: (
|
|
100
|
+
service: RetrievalTraceManagementService
|
|
101
|
+
) => Promise<StoreResult<T>>
|
|
102
|
+
): Promise<ToolResult> =>
|
|
103
|
+
runTool(
|
|
104
|
+
ctx,
|
|
105
|
+
name,
|
|
106
|
+
async () => {
|
|
107
|
+
if (!ctx.enableWrite) return writeDisabled();
|
|
108
|
+
return withWriteLock(ctx.writeLockPath, async () =>
|
|
109
|
+
unwrap(await operation(new RetrievalTraceManagementService(ctx.store)))
|
|
110
|
+
);
|
|
111
|
+
},
|
|
112
|
+
jsonText
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
export const handleTraceLabel = (
|
|
116
|
+
args: z.infer<typeof traceLabelInputSchema>,
|
|
117
|
+
ctx: ToolContext
|
|
118
|
+
): Promise<ToolResult> =>
|
|
119
|
+
runTraceWrite(ctx, "gno_trace_label", (service) =>
|
|
120
|
+
service.label(args as RetrievalTraceLabelRequest)
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
export const handleTraceExport = (
|
|
124
|
+
args: z.infer<typeof traceExportInputSchema>,
|
|
125
|
+
ctx: ToolContext
|
|
126
|
+
): Promise<ToolResult> =>
|
|
127
|
+
runTraceWrite(ctx, "gno_trace_export", (service) =>
|
|
128
|
+
service.export(args as RetrievalTraceExportRequest)
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
export const handleTraceDelete = (
|
|
132
|
+
args: z.infer<typeof traceDeleteInputSchema>,
|
|
133
|
+
ctx: ToolContext
|
|
134
|
+
): Promise<ToolResult> =>
|
|
135
|
+
runTraceWrite(ctx, "gno_trace_delete", (service) =>
|
|
136
|
+
service.delete(args.traceId)
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
export const handleTracePurge = (
|
|
140
|
+
_args: z.infer<typeof tracePurgeInputSchema>,
|
|
141
|
+
ctx: ToolContext
|
|
142
|
+
): Promise<ToolResult> =>
|
|
143
|
+
runTraceWrite(ctx, "gno_trace_purge", (service) => service.purge());
|