@gmickel/gno 1.26.0 → 1.27.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 +2 -1
- package/assets/skill/SKILL.md +8 -0
- package/browser-extension/artifacts/{gno-browser-clipper-v1.26.0.zip → gno-browser-clipper-v1.27.0.zip} +0 -0
- package/browser-extension/artifacts/gno-browser-clipper-v1.27.0.zip.sha256 +1 -0
- package/browser-extension/dist/manifest.json +1 -1
- package/package.json +1 -1
- package/spec/cli.md +15 -2
- package/spec/evals-agentic.md +17 -0
- package/spec/mcp.md +25 -6
- package/spec/output-schemas/ask.schema.json +3 -0
- package/spec/output-schemas/query-diagnose.schema.json +61 -4
- package/spec/output-schemas/search-results.schema.json +87 -1
- package/spec/output-schemas/status.schema.json +24 -0
- package/spec/project-profile.schema.json +3 -1
- package/src/app/context-runtime-contract.ts +4 -1
- package/src/app/context-runtime-types.ts +2 -0
- package/src/app/context-runtime.ts +26 -0
- package/src/app/verified-ask.ts +6 -1
- package/src/cli/commands/ask.ts +8 -1
- package/src/cli/commands/query.ts +6 -3
- package/src/cli/commands/search.ts +6 -1
- package/src/cli/commands/status.ts +43 -7
- package/src/cli/program.ts +2 -0
- package/src/config/content-types.ts +82 -0
- package/src/config/index.ts +8 -0
- package/src/config/project-profile.ts +8 -1
- package/src/config/types.ts +11 -2
- package/src/core/context-compiler.ts +38 -1
- package/src/core/retrieval-replay-candidate.ts +6 -1
- package/src/ingestion/sync-options.ts +6 -2
- package/src/ingestion/sync.ts +21 -29
- package/src/ingestion/types.ts +1 -1
- package/src/mcp/tools/ask.ts +1 -0
- package/src/mcp/tools/index.ts +4 -0
- package/src/mcp/tools/query.ts +4 -2
- package/src/mcp/tools/search.ts +3 -0
- package/src/mcp/tools/status.ts +4 -0
- package/src/pipeline/content-type-boost.ts +264 -0
- package/src/pipeline/diagnose.ts +46 -19
- package/src/pipeline/explain.ts +15 -2
- package/src/pipeline/hybrid.ts +170 -74
- package/src/pipeline/rerank.ts +45 -15
- package/src/pipeline/search.ts +29 -11
- package/src/pipeline/types.ts +13 -4
- package/src/pipeline/vsearch.ts +30 -10
- package/src/sdk/client.ts +19 -3
- package/src/sdk/index.ts +1 -0
- package/src/sdk/types.ts +21 -5
- package/src/serve/routes/api.ts +17 -3
- package/src/serve/status-model.ts +2 -0
- package/src/serve/status.ts +4 -0
- package/src/store/sqlite/adapter.ts +3 -0
- package/src/store/types.ts +3 -2
- package/browser-extension/artifacts/gno-browser-clipper-v1.26.0.zip.sha256 +0 -1
package/README.md
CHANGED
|
@@ -149,7 +149,8 @@ gno daemon --detach # headless continuous indexing (background; --status / --st
|
|
|
149
149
|
remote fetch, store listing, or Firefox parity is claimed.
|
|
150
150
|
- **Schema-lite content types**: optional `contentTypes` rules map configured
|
|
151
151
|
frontmatter `type` values or path prefixes to canonical `contentType` metadata
|
|
152
|
-
in JSON search/query results
|
|
152
|
+
in JSON search/query results and can apply one bounded, explainable
|
|
153
|
+
`searchBoost` without bypassing hard filters
|
|
153
154
|
- **Publish to [gno.sh](https://gno.sh/publish)**: new `gno publish export` CLI and Web UI action produce a self-contained artifact you upload to the hosted reader — public, secret, invite-only, or locally encrypted before upload
|
|
154
155
|
- **Retrieval Quality Upgrade**: stronger BM25 lexical handling, code-aware chunking, terminal result hyperlinks, and per-collection model overrides
|
|
155
156
|
- **Code Embedding Benchmarks**: new benchmark workflow across canonical, real-GNO, and pinned OSS slices for comparing alternate embedding models
|
package/assets/skill/SKILL.md
CHANGED
|
@@ -122,6 +122,7 @@ Recipe rules:
|
|
|
122
122
|
--line-numbers Include line numbers
|
|
123
123
|
--project-root <path> Trusted local root; repeatable and replaces cwd affinity
|
|
124
124
|
--no-project-affinity Disable trusted local project-aware ranking
|
|
125
|
+
--explain Include retrieval scoring details
|
|
125
126
|
```
|
|
126
127
|
|
|
127
128
|
CLI searches use explicit `--project-root`, the nearest valid compiled project
|
|
@@ -137,6 +138,13 @@ cannot change another repository's fallback. Explain/diagnose identify this
|
|
|
137
138
|
trusted source as `project_profile`; contexts, content types, source metadata,
|
|
138
139
|
and document fields never become project identity.
|
|
139
140
|
|
|
141
|
+
Configured `contentTypes[].searchBoost` is a separate local ranking signal.
|
|
142
|
+
`1` is neutral; `0.5..2` maps to a bounded `-0.05..+0.05` contribution, and
|
|
143
|
+
all auxiliary signals share `±0.08`. It cannot create candidates or bypass hard
|
|
144
|
+
filters. Use `gno query --explain`, `gno ask --explain`, or
|
|
145
|
+
`gno query diagnose` when the ranking effect matters; normal output omits the
|
|
146
|
+
boost receipt.
|
|
147
|
+
|
|
140
148
|
Do not treat MCP/SDK/REST `projectHints` as paths. They are opaque, untrusted,
|
|
141
149
|
limited to 16, never trigger filesystem probing, and currently produce zero
|
|
142
150
|
affinity. Explain uses redacted aliases only. Diagnose preserves exact closed
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3da63d624c5d61f121c5082cd5db2b233e95be5c72beba14f4a3e73a14384e02 gno-browser-clipper-v1.27.0.zip
|
package/package.json
CHANGED
package/spec/cli.md
CHANGED
|
@@ -436,7 +436,14 @@ Zod validates `id`, `prefixes`, `preset`, `graphHints`, `searchBoost`, and
|
|
|
436
436
|
`temporal`, while `preset` remains a permissive string. Post-parse normalization
|
|
437
437
|
warns and drops unknown preset references, dedupes exact duplicate prefixes,
|
|
438
438
|
retains overlapping prefixes, and sorts rules longest-prefix-first. `searchBoost`
|
|
439
|
-
|
|
439
|
+
defaults to neutral `1`, accepts `0.5..2`, and maps one canonical configured
|
|
440
|
+
type to a bounded `-0.05..+0.05` ranking contribution. A frontmatter type ID
|
|
441
|
+
wins over longest-prefix matching; boosts never stack, cannot create
|
|
442
|
+
candidates, never widen retrieval or defer `minScore`, and share the final
|
|
443
|
+
`±0.08` auxiliary cap with project affinity. Hybrid applies the composed score
|
|
444
|
+
to normalized fusion before rerank blending; rerank order and lexical top-hit
|
|
445
|
+
protection remain authoritative.
|
|
446
|
+
`graphHints` is active: ordered hints type
|
|
440
447
|
projected wiki/markdown edges and surface in graph traversal/diagnose metadata.
|
|
441
448
|
|
|
442
449
|
---
|
|
@@ -1203,7 +1210,7 @@ Human-friendly query with citations-first output and optional grounded answer.
|
|
|
1203
1210
|
**Synopsis:**
|
|
1204
1211
|
|
|
1205
1212
|
```bash
|
|
1206
|
-
gno ask <query> [-n <num>] [-c <collection>] [--lang <bcp47>] [--since <date>] [--until <date>] [--category <values>] [--author <text>] [--intent <text>] [--exclude <values>] [--query-mode <mode:text>]... [-C <num>] [--answer|--verify] [--no-answer] [--max-answer-tokens <n>] [--context-budget-tokens <n>] [--context-budget-bytes <n>] [--min-score <score>] [--graph] [--no-expand] [--no-rerank] [--show-sources] [--json|--md]
|
|
1213
|
+
gno ask <query> [-n <num>] [-c <collection>] [--lang <bcp47>] [--since <date>] [--until <date>] [--category <values>] [--author <text>] [--intent <text>] [--exclude <values>] [--query-mode <mode:text>]... [-C <num>] [--answer|--verify] [--no-answer] [--max-answer-tokens <n>] [--context-budget-tokens <n>] [--context-budget-bytes <n>] [--min-score <score>] [--graph] [--no-expand] [--no-rerank] [--explain] [--show-sources] [--json|--md]
|
|
1207
1214
|
```
|
|
1208
1215
|
|
|
1209
1216
|
**Options:**
|
|
@@ -1228,6 +1235,7 @@ gno ask <query> [-n <num>] [-c <collection>] [--lang <bcp47>] [--since <date>] [
|
|
|
1228
1235
|
| `-C, --candidate-limit` | integer | 20 | Max candidates passed to reranking |
|
|
1229
1236
|
| `--no-expand` | boolean | false | Disable query expansion |
|
|
1230
1237
|
| `--no-rerank` | boolean | false | Disable cross-encoder reranking |
|
|
1238
|
+
| `--explain` | boolean | false | Include retrieval scoring details; prints to stderr outside structured output |
|
|
1231
1239
|
| `--show-sources` | boolean | false | Show all retrieved sources (not just cited) |
|
|
1232
1240
|
| `--project-root` | string[] | cwd | Trusted project root; repeatable, replaces default cwd/repository affinity |
|
|
1233
1241
|
| `--no-project-affinity` | boolean | false | Disable project-aware soft ranking; invalid with `--project-root` |
|
|
@@ -1238,6 +1246,11 @@ See [Output Schemas](./output-schemas/ask.schema.json)
|
|
|
1238
1246
|
Notes:
|
|
1239
1247
|
|
|
1240
1248
|
- `meta.answerContext` is optional explain payload for answer source selection.
|
|
1249
|
+
- `meta.explain` is present only with `--explain`. Its optional
|
|
1250
|
+
`contentTypeBoost` result component contains the raw/base score, configured
|
|
1251
|
+
factor, capped and combined contributions, final score, rule source, and full
|
|
1252
|
+
ranking-rules fingerprint. Verified Ask attaches this as a non-canonical
|
|
1253
|
+
sidecar; Capsule identity and bytes do not change.
|
|
1241
1254
|
- `--verify` implies answer generation and cannot be combined with
|
|
1242
1255
|
`--no-answer`. The JSON result adds the closed Capsule, freshness receipt,
|
|
1243
1256
|
four-state per-claim verdicts (`supported`, `contradicted`, `insufficient`,
|
package/spec/evals-agentic.md
CHANGED
|
@@ -26,6 +26,7 @@ evals/agentic/
|
|
|
26
26
|
project-affinity-outcome.ts
|
|
27
27
|
project-affinity-promotion.ts
|
|
28
28
|
project-affinity-runtime.ts
|
|
29
|
+
content-type-boost-promotion.ts
|
|
29
30
|
verified-ask-outcome.ts
|
|
30
31
|
verified-ask-promotion.ts
|
|
31
32
|
demos/context-capsule.ts
|
|
@@ -103,6 +104,22 @@ receipts, and compares the committed artifact with a fresh deterministic
|
|
|
103
104
|
production run. The controlled synthetic lane isolates the score seam and makes
|
|
104
105
|
no general workload superiority claim.
|
|
105
106
|
|
|
107
|
+
## Separate content-type boost promotion
|
|
108
|
+
|
|
109
|
+
The authoritative lane also writes
|
|
110
|
+
`content-type-boost-promotion.json` and `.md`. These 24 before/after receipts
|
|
111
|
+
project the fn-97 production retrieval rankings through the shipped
|
|
112
|
+
content-type ranking seam with no configured rules. Every ordered URI and
|
|
113
|
+
required-evidence receipt must remain byte-identical, with zero accuracy and
|
|
114
|
+
coverage loss. This is backward-compatibility evidence for existing configs,
|
|
115
|
+
not an active-rule quality claim.
|
|
116
|
+
|
|
117
|
+
Active positive/negative factors, keyword stuffing, deterministic ties,
|
|
118
|
+
configured-ID versus prefix conflicts, filter isolation, and project-affinity
|
|
119
|
+
composition are gated separately by the deterministic adversarial pipeline
|
|
120
|
+
suite. Egress policy is not yet an available retrieval capability, so the
|
|
121
|
+
artifact makes no egress-enforcement claim.
|
|
122
|
+
|
|
106
123
|
The first fixture version contains 24 original synthetic tasks and 34 Markdown
|
|
107
124
|
documents under the MIT license. It covers exact identifiers, ambiguity,
|
|
108
125
|
multi-document comparisons, meeting decisions, temporal questions, typed
|
package/spec/mcp.md
CHANGED
|
@@ -216,7 +216,7 @@ Required input:
|
|
|
216
216
|
Optional fields are `collection`, `limit` (default 5), `minScore`, `lang`,
|
|
217
217
|
`intent`, `candidateLimit`, `exclude`, `queryModes`, `tagsAll`, `tagsAny`,
|
|
218
218
|
`since`, `until`, `categories`, `author`, `graph`, `noGraph`, `noRerank`,
|
|
219
|
-
`maxAnswerTokens`, `contextBudgetTokens`, and `contextBudgetBytes`. Input
|
|
219
|
+
`explain`, `maxAnswerTokens`, `contextBudgetTokens`, and `contextBudgetBytes`. Input
|
|
220
220
|
objects are closed.
|
|
221
221
|
`projectHints` is an optional array of at most 16 non-empty caller hints. Hints
|
|
222
222
|
are normalized and deduplicated as opaque values, never resolved against or
|
|
@@ -648,6 +648,11 @@ Hybrid search combining BM25 and vector retrieval with optional expansion and re
|
|
|
648
648
|
"description": "Enable cross-encoder reranking",
|
|
649
649
|
"default": true
|
|
650
650
|
},
|
|
651
|
+
"explain": {
|
|
652
|
+
"type": "boolean",
|
|
653
|
+
"description": "Include deterministic stage and per-result scoring metadata",
|
|
654
|
+
"default": false
|
|
655
|
+
},
|
|
651
656
|
"noGraph": {
|
|
652
657
|
"type": "boolean",
|
|
653
658
|
"description": "Compatibility no-op unless graph is also true",
|
|
@@ -692,6 +697,11 @@ Search result items include `contentType` when available and always include
|
|
|
692
697
|
human-oriented; structured clients should read `structuredContent.results`.
|
|
693
698
|
Structured result items also preserve optional `context` guidance in
|
|
694
699
|
global-to-specific order without changing the result `uri` or `docid`.
|
|
700
|
+
When `explain: true`, `structuredContent.meta.explain` includes deterministic
|
|
701
|
+
stage lines and per-result score receipts. Non-neutral configured content-type
|
|
702
|
+
rules add `contentTypeBoost` with base/raw scores, factor, capped contribution,
|
|
703
|
+
shared auxiliary-cap composition, final score, rule source, and redacted rules
|
|
704
|
+
fingerprint. Normal output omits this sidecar.
|
|
695
705
|
|
|
696
706
|
Compatibility / migration notes:
|
|
697
707
|
|
|
@@ -753,16 +763,17 @@ plus a required `target` reference.
|
|
|
753
763
|
- `target`: URI, `#docid`, or `collection/path` for the document to diagnose.
|
|
754
764
|
- `query`, filters, `queryModes`, `fast`/`thorough`, `graph`, and rerank/expand controls behave like `gno_query`.
|
|
755
765
|
|
|
756
|
-
**Output Schema:** `gno://schemas/query-diagnose@1.
|
|
766
|
+
**Output Schema:** `gno://schemas/query-diagnose@1.2`
|
|
757
767
|
|
|
758
768
|
Structured content includes `schemaVersion`, normalized `query`, `target`
|
|
759
769
|
metadata/status (`not_found`, `inactive`, `no_indexed_content`,
|
|
760
770
|
`filtered_out`, or `diagnosed`), `stages` for BM25/vector/fusion/graph/rerank,
|
|
761
771
|
the selected target `chunk`, and retrieval `meta`.
|
|
762
|
-
MCP inputs are remote and untrusted, so this tool
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
772
|
+
MCP inputs are remote and untrusted, so this tool omits `affinity`, even when
|
|
773
|
+
`projectHints` are supplied. Neutral configurations preserve exact v1.0 bytes;
|
|
774
|
+
an active configured content-type boost emits v1.2 with the same bounded score
|
|
775
|
+
receipt exposed by query explain. The v1.1 affinity-bearing branch remains
|
|
776
|
+
reserved for trusted local CLI diagnose requests.
|
|
766
777
|
|
|
767
778
|
Use when an expected target is missing from `gno_query`, when filters may have
|
|
768
779
|
excluded it, or when an agent needs evidence before raising `candidateLimit`,
|
|
@@ -979,11 +990,19 @@ counters; it never claims attachment to another process.
|
|
|
979
990
|
"totalDocuments": 150,
|
|
980
991
|
"totalChunks": 800,
|
|
981
992
|
"embeddingBacklog": 0,
|
|
993
|
+
"contentTypeBoost": {
|
|
994
|
+
"rulesFingerprint": "<sha256>",
|
|
995
|
+
"rules": [{ "id": "decision", "searchBoost": 2 }]
|
|
996
|
+
},
|
|
982
997
|
"healthy": true
|
|
983
998
|
}
|
|
984
999
|
}
|
|
985
1000
|
```
|
|
986
1001
|
|
|
1002
|
+
`contentTypeBoost` is a redacted ranking-status projection. It exposes only
|
|
1003
|
+
normalized IDs/factors plus the rules fingerprint; path prefixes are never
|
|
1004
|
+
returned.
|
|
1005
|
+
|
|
987
1006
|
---
|
|
988
1007
|
|
|
989
1008
|
### gno_capture
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "gno://schemas/query-diagnose@1.
|
|
3
|
+
"$id": "gno://schemas/query-diagnose@1.2",
|
|
4
4
|
"title": "GNO Query Diagnose",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"required": ["schemaVersion", "query", "target", "stages", "chunk", "meta"],
|
|
7
7
|
"properties": {
|
|
8
|
-
"schemaVersion": { "type": "string", "enum": ["1.0", "1.1"] },
|
|
8
|
+
"schemaVersion": { "type": "string", "enum": ["1.0", "1.1", "1.2"] },
|
|
9
9
|
"query": { "type": "string" },
|
|
10
10
|
"target": {
|
|
11
11
|
"type": "object",
|
|
@@ -160,6 +160,51 @@
|
|
|
160
160
|
},
|
|
161
161
|
"additionalProperties": false
|
|
162
162
|
},
|
|
163
|
+
"contentTypeBoost": {
|
|
164
|
+
"type": "object",
|
|
165
|
+
"required": [
|
|
166
|
+
"baseScore",
|
|
167
|
+
"cappedContribution",
|
|
168
|
+
"combinedAuxiliaryApplied",
|
|
169
|
+
"combinedAuxiliaryCap",
|
|
170
|
+
"combinedAuxiliaryRequested",
|
|
171
|
+
"configuredFactor",
|
|
172
|
+
"contentType",
|
|
173
|
+
"finalScore",
|
|
174
|
+
"rawContribution",
|
|
175
|
+
"rawScore",
|
|
176
|
+
"rawScoreKind",
|
|
177
|
+
"ruleSource",
|
|
178
|
+
"rulesFingerprint"
|
|
179
|
+
],
|
|
180
|
+
"properties": {
|
|
181
|
+
"baseScore": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
182
|
+
"cappedContribution": {
|
|
183
|
+
"type": "number",
|
|
184
|
+
"minimum": -0.05,
|
|
185
|
+
"maximum": 0.05
|
|
186
|
+
},
|
|
187
|
+
"combinedAuxiliaryApplied": {
|
|
188
|
+
"type": "number",
|
|
189
|
+
"minimum": -0.08,
|
|
190
|
+
"maximum": 0.08
|
|
191
|
+
},
|
|
192
|
+
"combinedAuxiliaryCap": { "type": "number", "const": 0.08 },
|
|
193
|
+
"combinedAuxiliaryRequested": { "type": "number" },
|
|
194
|
+
"configuredFactor": { "type": "number", "minimum": 0.5, "maximum": 2 },
|
|
195
|
+
"contentType": { "type": "string" },
|
|
196
|
+
"finalScore": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
197
|
+
"rawContribution": { "type": "number" },
|
|
198
|
+
"rawScore": { "type": "number" },
|
|
199
|
+
"rawScoreKind": {
|
|
200
|
+
"type": "string",
|
|
201
|
+
"enum": ["bm25", "hybrid_blended", "normalized", "vector_distance"]
|
|
202
|
+
},
|
|
203
|
+
"ruleSource": { "type": "string", "enum": ["configured-id", "prefix"] },
|
|
204
|
+
"rulesFingerprint": { "type": "string", "pattern": "^[a-f0-9]{64}$" }
|
|
205
|
+
},
|
|
206
|
+
"additionalProperties": false
|
|
207
|
+
},
|
|
163
208
|
"chunk": {
|
|
164
209
|
"type": "object",
|
|
165
210
|
"required": ["seq", "startLine", "endLine", "language"],
|
|
@@ -199,7 +244,9 @@
|
|
|
199
244
|
"properties": { "schemaVersion": { "const": "1.0" } },
|
|
200
245
|
"required": ["schemaVersion"]
|
|
201
246
|
},
|
|
202
|
-
"then": {
|
|
247
|
+
"then": {
|
|
248
|
+
"properties": { "affinity": false, "contentTypeBoost": false }
|
|
249
|
+
}
|
|
203
250
|
},
|
|
204
251
|
{
|
|
205
252
|
"if": {
|
|
@@ -207,9 +254,19 @@
|
|
|
207
254
|
"required": ["schemaVersion"]
|
|
208
255
|
},
|
|
209
256
|
"then": {
|
|
210
|
-
"properties": { "affinity": {} },
|
|
257
|
+
"properties": { "affinity": {}, "contentTypeBoost": false },
|
|
211
258
|
"required": ["affinity"]
|
|
212
259
|
}
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"if": {
|
|
263
|
+
"properties": { "schemaVersion": { "const": "1.2" } },
|
|
264
|
+
"required": ["schemaVersion"]
|
|
265
|
+
},
|
|
266
|
+
"then": {
|
|
267
|
+
"properties": { "contentTypeBoost": {} },
|
|
268
|
+
"required": ["contentTypeBoost"]
|
|
269
|
+
}
|
|
213
270
|
}
|
|
214
271
|
],
|
|
215
272
|
"additionalProperties": false
|
|
@@ -166,7 +166,78 @@
|
|
|
166
166
|
"type": "string"
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
|
-
}
|
|
169
|
+
},
|
|
170
|
+
"additionalProperties": false
|
|
171
|
+
},
|
|
172
|
+
"contentTypeBoost": {
|
|
173
|
+
"type": "object",
|
|
174
|
+
"required": [
|
|
175
|
+
"baseScore",
|
|
176
|
+
"cappedContribution",
|
|
177
|
+
"combinedAuxiliaryApplied",
|
|
178
|
+
"combinedAuxiliaryCap",
|
|
179
|
+
"combinedAuxiliaryRequested",
|
|
180
|
+
"configuredFactor",
|
|
181
|
+
"contentType",
|
|
182
|
+
"finalScore",
|
|
183
|
+
"rawContribution",
|
|
184
|
+
"rawScore",
|
|
185
|
+
"rawScoreKind",
|
|
186
|
+
"ruleSource",
|
|
187
|
+
"rulesFingerprint"
|
|
188
|
+
],
|
|
189
|
+
"properties": {
|
|
190
|
+
"baseScore": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
191
|
+
"cappedContribution": {
|
|
192
|
+
"type": "number",
|
|
193
|
+
"minimum": -0.05,
|
|
194
|
+
"maximum": 0.05
|
|
195
|
+
},
|
|
196
|
+
"combinedAuxiliaryApplied": {
|
|
197
|
+
"type": "number",
|
|
198
|
+
"minimum": -0.08,
|
|
199
|
+
"maximum": 0.08
|
|
200
|
+
},
|
|
201
|
+
"combinedAuxiliaryCap": { "type": "number", "const": 0.08 },
|
|
202
|
+
"combinedAuxiliaryRequested": { "type": "number" },
|
|
203
|
+
"configuredFactor": { "type": "number", "minimum": 0.5, "maximum": 2 },
|
|
204
|
+
"contentType": { "type": "string" },
|
|
205
|
+
"finalScore": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
206
|
+
"rawContribution": { "type": "number" },
|
|
207
|
+
"rawScore": { "type": "number" },
|
|
208
|
+
"rawScoreKind": {
|
|
209
|
+
"type": "string",
|
|
210
|
+
"enum": ["bm25", "hybrid_blended", "normalized", "vector_distance"]
|
|
211
|
+
},
|
|
212
|
+
"ruleSource": { "type": "string", "enum": ["configured-id", "prefix"] },
|
|
213
|
+
"rulesFingerprint": { "type": "string", "pattern": "^[a-f0-9]{64}$" }
|
|
214
|
+
},
|
|
215
|
+
"additionalProperties": false
|
|
216
|
+
},
|
|
217
|
+
"explainLine": {
|
|
218
|
+
"type": "object",
|
|
219
|
+
"required": ["stage", "message"],
|
|
220
|
+
"properties": {
|
|
221
|
+
"stage": { "type": "string" },
|
|
222
|
+
"message": { "type": "string" }
|
|
223
|
+
},
|
|
224
|
+
"additionalProperties": false
|
|
225
|
+
},
|
|
226
|
+
"explainResult": {
|
|
227
|
+
"type": "object",
|
|
228
|
+
"required": ["rank", "docid", "score"],
|
|
229
|
+
"properties": {
|
|
230
|
+
"rank": { "type": "integer", "minimum": 1 },
|
|
231
|
+
"docid": { "type": "string", "pattern": "^#[a-f0-9]{6,8}$" },
|
|
232
|
+
"score": { "type": "number" },
|
|
233
|
+
"fusionScore": { "type": "number" },
|
|
234
|
+
"bm25Score": { "type": "number" },
|
|
235
|
+
"vecScore": { "type": "number" },
|
|
236
|
+
"rerankScore": { "type": "number" },
|
|
237
|
+
"projectAffinity": { "type": "object" },
|
|
238
|
+
"contentTypeBoost": { "$ref": "#/$defs/contentTypeBoost" }
|
|
239
|
+
},
|
|
240
|
+
"additionalProperties": false
|
|
170
241
|
}
|
|
171
242
|
},
|
|
172
243
|
"properties": {
|
|
@@ -331,6 +402,21 @@
|
|
|
331
402
|
"type": "array",
|
|
332
403
|
"items": { "type": "string" },
|
|
333
404
|
"description": "Tags ANY filter applied (if any)"
|
|
405
|
+
},
|
|
406
|
+
"explain": {
|
|
407
|
+
"type": "object",
|
|
408
|
+
"required": ["lines", "results"],
|
|
409
|
+
"properties": {
|
|
410
|
+
"lines": {
|
|
411
|
+
"type": "array",
|
|
412
|
+
"items": { "$ref": "#/$defs/explainLine" }
|
|
413
|
+
},
|
|
414
|
+
"results": {
|
|
415
|
+
"type": "array",
|
|
416
|
+
"items": { "$ref": "#/$defs/explainResult" }
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
"additionalProperties": false
|
|
334
420
|
}
|
|
335
421
|
}
|
|
336
422
|
}
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"recentErrors",
|
|
16
16
|
"activePreset",
|
|
17
17
|
"capabilities",
|
|
18
|
+
"contentTypeBoost",
|
|
18
19
|
"activation",
|
|
19
20
|
"onboarding",
|
|
20
21
|
"health",
|
|
@@ -136,6 +137,29 @@
|
|
|
136
137
|
}
|
|
137
138
|
}
|
|
138
139
|
},
|
|
140
|
+
"contentTypeBoost": {
|
|
141
|
+
"type": "object",
|
|
142
|
+
"additionalProperties": false,
|
|
143
|
+
"required": ["rulesFingerprint", "rules"],
|
|
144
|
+
"properties": {
|
|
145
|
+
"rulesFingerprint": {
|
|
146
|
+
"type": "string",
|
|
147
|
+
"pattern": "^[a-f0-9]{64}$"
|
|
148
|
+
},
|
|
149
|
+
"rules": {
|
|
150
|
+
"type": "array",
|
|
151
|
+
"items": {
|
|
152
|
+
"type": "object",
|
|
153
|
+
"additionalProperties": false,
|
|
154
|
+
"required": ["id", "searchBoost"],
|
|
155
|
+
"properties": {
|
|
156
|
+
"id": { "type": "string", "minLength": 1 },
|
|
157
|
+
"searchBoost": { "type": "number", "minimum": 0.5, "maximum": 2 }
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
},
|
|
139
163
|
"activation": {
|
|
140
164
|
"type": "object",
|
|
141
165
|
"additionalProperties": false,
|
|
@@ -26,7 +26,10 @@ const fingerprint = (value: unknown): string =>
|
|
|
26
26
|
|
|
27
27
|
export const contextRuntimeConfigFingerprint = (
|
|
28
28
|
deps: Pick<ContextCapsuleRuntimeDeps, "config">
|
|
29
|
-
): string =>
|
|
29
|
+
): string =>
|
|
30
|
+
fingerprint(
|
|
31
|
+
JSON.parse(JSON.stringify(deps.config)) as Record<string, unknown>
|
|
32
|
+
);
|
|
30
33
|
|
|
31
34
|
const configuredContextFingerprint = (
|
|
32
35
|
deps: ContextCapsuleRuntimeDeps
|
|
@@ -55,6 +55,8 @@ export interface ContextCapsuleRuntimeDeps {
|
|
|
55
55
|
projectAffinity?: ProjectAffinityScoringInput;
|
|
56
56
|
/** Optional non-canonical receipt session owned by the calling surface. */
|
|
57
57
|
traceSession?: RetrievalTraceSession;
|
|
58
|
+
/** Internal non-canonical retrieval explanation request. */
|
|
59
|
+
explain?: boolean;
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
export type ContextRuntimeErrorCode =
|
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
ContextCapsuleV1,
|
|
5
5
|
ContextCapsuleVerification,
|
|
6
6
|
} from "../core/context-capsule";
|
|
7
|
+
import type { SearchExplain } from "../pipeline/types";
|
|
7
8
|
import type {
|
|
8
9
|
ContextCapsuleBuildInput,
|
|
9
10
|
ContextCapsuleRuntimeDeps,
|
|
@@ -36,6 +37,19 @@ export type {
|
|
|
36
37
|
} from "./context-runtime-types";
|
|
37
38
|
export { ContextRuntimeError } from "./context-runtime-types";
|
|
38
39
|
|
|
40
|
+
export const CONTEXT_CAPSULE_EXPLAIN_METADATA = Symbol(
|
|
41
|
+
"gno.contextCapsuleExplainMetadata"
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
export const getContextCapsuleExplain = (
|
|
45
|
+
capsule: ContextCapsuleV1
|
|
46
|
+
): SearchExplain | undefined =>
|
|
47
|
+
(
|
|
48
|
+
capsule as ContextCapsuleV1 & {
|
|
49
|
+
[CONTEXT_CAPSULE_EXPLAIN_METADATA]?: SearchExplain;
|
|
50
|
+
}
|
|
51
|
+
)[CONTEXT_CAPSULE_EXPLAIN_METADATA];
|
|
52
|
+
|
|
39
53
|
/** Build one strict Capsule through the shared compiler composition. */
|
|
40
54
|
export const buildContextCapsule = async (
|
|
41
55
|
input: ContextCapsuleBuildInput,
|
|
@@ -72,6 +86,7 @@ export const buildContextCapsule = async (
|
|
|
72
86
|
limit: normalized.limit,
|
|
73
87
|
candidateLimit: normalized.candidateLimit,
|
|
74
88
|
temporalNow: now,
|
|
89
|
+
explain: deps.explain,
|
|
75
90
|
limits: {
|
|
76
91
|
requestedBytes: normalized.budgetBytes,
|
|
77
92
|
requestedTokens: normalized.budgetTokens,
|
|
@@ -134,6 +149,17 @@ export const buildContextCapsule = async (
|
|
|
134
149
|
traceResult.error.cause
|
|
135
150
|
);
|
|
136
151
|
}
|
|
152
|
+
if (plan.explain) {
|
|
153
|
+
Object.defineProperty(
|
|
154
|
+
plan.projection.value,
|
|
155
|
+
CONTEXT_CAPSULE_EXPLAIN_METADATA,
|
|
156
|
+
{
|
|
157
|
+
configurable: true,
|
|
158
|
+
enumerable: false,
|
|
159
|
+
value: plan.explain,
|
|
160
|
+
}
|
|
161
|
+
);
|
|
162
|
+
}
|
|
137
163
|
return plan.projection.value;
|
|
138
164
|
};
|
|
139
165
|
|
package/src/app/verified-ask.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { attachCitationTraceMetadata } from "../pipeline/trace-metadata";
|
|
|
16
16
|
import { CITATION_TRACE_METADATA } from "../pipeline/types";
|
|
17
17
|
import {
|
|
18
18
|
buildContextCapsule,
|
|
19
|
+
getContextCapsuleExplain,
|
|
19
20
|
verifyContextCapsuleRuntime,
|
|
20
21
|
} from "./context-runtime";
|
|
21
22
|
import { contextRuntimeConfigFingerprint } from "./context-runtime-contract";
|
|
@@ -199,7 +200,7 @@ export const buildVerifiedAsk = async (
|
|
|
199
200
|
budgetBytes: options.contextBudgetBytes,
|
|
200
201
|
depthPolicy: "balanced",
|
|
201
202
|
},
|
|
202
|
-
deps
|
|
203
|
+
{ ...deps, explain: options.explain }
|
|
203
204
|
);
|
|
204
205
|
const freshness = await verifyContextCapsuleRuntime(capsule, deps);
|
|
205
206
|
return synthesizeVerifiedAsk(query, options, capsule, freshness, deps);
|
|
@@ -258,6 +259,9 @@ export const synthesizeVerifiedAsk = async (
|
|
|
258
259
|
citationEvidenceIds(verification, new Set(["supported", "contradicted"]))
|
|
259
260
|
);
|
|
260
261
|
await recordRetainedCitations(deps.traceSession, traceCitations);
|
|
262
|
+
const retrievalExplain = options.explain
|
|
263
|
+
? getContextCapsuleExplain(capsule)
|
|
264
|
+
: undefined;
|
|
261
265
|
return {
|
|
262
266
|
query,
|
|
263
267
|
mode: capsule.capabilities.semanticSearch ? "hybrid" : "bm25_only",
|
|
@@ -276,6 +280,7 @@ export const synthesizeVerifiedAsk = async (
|
|
|
276
280
|
exclude: capsule.retrieval.request.exclude,
|
|
277
281
|
answerGenerated: generated.ok,
|
|
278
282
|
totalResults: capsule.evidence.length,
|
|
283
|
+
...(retrievalExplain ? { explain: retrievalExplain } : {}),
|
|
279
284
|
verificationRequested: true,
|
|
280
285
|
abstained: verification.verification.abstained,
|
|
281
286
|
},
|
package/src/cli/commands/ask.ts
CHANGED
|
@@ -48,7 +48,10 @@ export { formatAsk } from "./ask-format";
|
|
|
48
48
|
// Types
|
|
49
49
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
50
50
|
|
|
51
|
-
export type AskCommandOptions = Omit<
|
|
51
|
+
export type AskCommandOptions = Omit<
|
|
52
|
+
AskOptions,
|
|
53
|
+
"contentTypeRules" | "projectAffinity"
|
|
54
|
+
> &
|
|
52
55
|
CliProjectAffinityRequest & {
|
|
53
56
|
/** Override config path */
|
|
54
57
|
configPath?: string;
|
|
@@ -318,6 +321,7 @@ export async function ask(
|
|
|
318
321
|
noExpand: options.noExpand,
|
|
319
322
|
noRerank: options.noRerank,
|
|
320
323
|
candidateLimit: options.candidateLimit,
|
|
324
|
+
explain: options.explain,
|
|
321
325
|
projectAffinity,
|
|
322
326
|
traceSession,
|
|
323
327
|
});
|
|
@@ -397,6 +401,9 @@ export async function ask(
|
|
|
397
401
|
answerGenerated,
|
|
398
402
|
totalResults: results.length,
|
|
399
403
|
answerContext,
|
|
404
|
+
...(options.explain && searchResult.value.meta.explain
|
|
405
|
+
? { explain: searchResult.value.meta.explain }
|
|
406
|
+
: {}),
|
|
400
407
|
},
|
|
401
408
|
};
|
|
402
409
|
|
|
@@ -16,7 +16,7 @@ import type {
|
|
|
16
16
|
import type { HybridSearchOptions, SearchResults } from "../../pipeline/types";
|
|
17
17
|
|
|
18
18
|
import {
|
|
19
|
-
|
|
19
|
+
fingerprintContentTypeMetadataRules,
|
|
20
20
|
normalizeContentTypes,
|
|
21
21
|
} from "../../config";
|
|
22
22
|
import { resolveCliProjectAffinity } from "../../core/project-affinity-surface";
|
|
@@ -48,7 +48,10 @@ import { decorateSearchResultsForIndex, initStore } from "./shared";
|
|
|
48
48
|
// Types
|
|
49
49
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
50
50
|
|
|
51
|
-
export type QueryCommandOptions = Omit<
|
|
51
|
+
export type QueryCommandOptions = Omit<
|
|
52
|
+
HybridSearchOptions,
|
|
53
|
+
"contentTypeRules" | "projectAffinity"
|
|
54
|
+
> &
|
|
52
55
|
CliProjectAffinityRequest & {
|
|
53
56
|
/** Override config path */
|
|
54
57
|
configPath?: string;
|
|
@@ -439,7 +442,7 @@ export async function queryDiagnose(
|
|
|
439
442
|
projectAffinity,
|
|
440
443
|
contentTypeRules,
|
|
441
444
|
contentTypeRulesFingerprint:
|
|
442
|
-
|
|
445
|
+
fingerprintContentTypeMetadataRules(contentTypeRules),
|
|
443
446
|
});
|
|
444
447
|
|
|
445
448
|
if (!result.ok) {
|