SearchFabricResult search.fabric-result@1
Generated at from
openvibe-contracts v0.419.0 and
openvibe-sdk v0.161.0.
- Version
- 1.0.0
- Owner
- search
- Visibility
- public
- Status
- active
- Compatibility
- backward
- Schema
https://openvibe.network/contracts/search/fabric-result.v1.json
search.fabric-result@1: the answer of search.fabric.query. results come grouped by scope order (the room's own first when the caller asked for it); every web result keeps its provider, URL and date; route.explain says, step by step, what was asked, what answered, from cache or not, and what it cost. The query is never echoed: a page renders results without writing the query into its HTML (the ?q= rule).
Fields
| Field | Type | Required | Description | Constraints |
|---|---|---|---|---|
results | array of object | yes |
| |
results[].scope | enum | yes |
| |
results[].kind | enum | yes | document: in Search's index (owner, type, id set); page: a web page (provider set). |
|
results[].title | string | yes |
| |
results[].url | string | yes |
| |
results[].snippet | string | null | Plain text; never HTML. |
| |
results[].site | string | null |
| ||
results[].image | string | null |
| ||
results[].published_at | string | null |
| ||
results[].retrieved_at | string | null | When a web page was read (by the provider or the open index). |
| |
results[].provider | string | null | page: who found it (open_index, deepseek, wikipedia, brave, …). |
| |
results[].owner | string | null |
| ||
results[].type | string | null |
| ||
results[].id | string | null |
| ||
results[].score | number | null | Rank within its scope (higher first); not comparable across scopes. | ||
results[].ranks | object | 1-based position in the keyword and vector top-100 lists; null when absent from that list. |
| |
results[].ranks.keyword | integer | null | yes |
| |
results[].ranks.vector | integer | null | yes |
| |
groups | object | yes | How many results each scope gave on this page. | |
answer | object | null | |||
citations | array of object |
| ||
citations[].n | integer | yes |
| |
citations[].url | string | yes |
| |
citations[].title | string | yes |
| |
citations[].provider | string | null |
| ||
citations[].retrieved_at | string | null |
| ||
route | object | yes |
| |
route.explain | array of object | yes |
| |
route.explain[].scope | enum | yes |
| |
route.explain[].step | string | yes | index, open_index, cache, deepseek, wikipedia, … |
|
route.explain[].ok | boolean | yes | ||
route.explain[].count | integer |
| ||
route.explain[].ms | integer |
| ||
route.explain[].cached | boolean | |||
route.explain[].cost_usd | number |
| ||
route.explain[].skipped | string | null | Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down). |
| |
route.explain[].ranking | enum |
| ||
route.explain[].reason | enum |
| ||
route.cost_usd | number | yes | What this query cost OpenVibe (paid provider calls; cached answers cost 0). |
|
next_cursor | string | null | yes |
|
Examples
From the contract's own test fixtures: valid ones validate, rejected ones must fail.
Valid: mixed
{
"results": [
{
"scope": "network",
"kind": "document",
"title": "surf_utopia in 1:02.4",
"url": "https://openvibe.live/clips/482",
"snippet": "A clean line through every stage.",
"site": "openvibe.live",
"image": null,
"published_at": "2026-10-27T21:04:00Z",
"retrieved_at": null,
"provider": null,
"owner": "media-hub",
"type": "clip",
"id": "482",
"score": 0.82
},
{
"scope": "web",
"kind": "page",
"title": "Surf (Counter-Strike) - Wikipedia",
"url": "https://en.wikipedia.org/wiki/Surf_(video_game_mode)",
"snippet": "Surfing is a game mode in Counter-Strike…",
"site": "en.wikipedia.org",
"image": null,
"published_at": null,
"retrieved_at": "2026-10-28T11:20:00Z",
"provider": "wikipedia",
"owner": null,
"type": null,
"id": null,
"score": 0.61
}
],
"groups": {
"network": 1,
"web": 1
},
"answer": null,
"citations": [
{
"n": 1,
"url": "https://en.wikipedia.org/wiki/Surf_(video_game_mode)",
"title": "Surf (Counter-Strike) - Wikipedia",
"provider": "wikipedia",
"retrieved_at": "2026-10-28T11:20:00Z"
}
],
"route": {
"explain": [
{
"scope": "network",
"step": "index",
"ok": true,
"count": 1,
"ms": 18,
"cached": false,
"cost_usd": 0
},
{
"scope": "web",
"step": "open_index",
"ok": true,
"count": 0,
"ms": 9,
"cost_usd": 0
},
{
"scope": "web",
"step": "deepseek",
"ok": true,
"count": 1,
"ms": 1420,
"cached": true,
"cost_usd": 0
},
{
"scope": "web",
"step": "brave",
"ok": false,
"skipped": "an earlier step answered"
}
],
"cost_usd": 0
},
"next_cursor": null
}Valid: with-answer
{
"results": [
{
"scope": "web",
"kind": "page",
"title": "A",
"url": "https://example.org/a",
"provider": "deepseek"
}
],
"groups": {
"web": 1
},
"answer": {
"text": "Surf maps are ramps you slide along [1].",
"citations": [
1
],
"label": "Written by AI from these sources"
},
"citations": [
{
"n": 1,
"url": "https://example.org/a",
"title": "A",
"provider": "deepseek",
"retrieved_at": "2026-10-28T11:20:00Z"
}
],
"route": {
"explain": [
{
"scope": "web",
"step": "deepseek",
"ok": true,
"count": 1,
"cost_usd": 0.00075
}
],
"cost_usd": 0.00075
},
"next_cursor": null
}Rejected: answer-without-citations
{
"results": [],
"groups": {},
"answer": {
"text": "Trust me.",
"citations": [],
"label": "Written by AI from these sources"
},
"route": {
"explain": [],
"cost_usd": 0
},
"next_cursor": null
}Rejected: html-in-kind
{
"results": [
{
"scope": "web",
"kind": "html",
"title": "x",
"url": "https://x.org/"
}
],
"groups": {},
"route": {
"explain": [],
"cost_usd": 0
},
"next_cursor": null
}Validate
const contracts = require('openvibe-contracts');
contracts.validate('search.fabric-result@1', value); // { valid, errors: [{ path, message }] }