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

FieldTypeRequiredDescriptionConstraints
resultsarray of objectyes
  • maxItems 100
  • items: no other fields
results[].scopeenumyes
  • one of "network", "mine", "web", "news", "images", "video", "products", "people", "places", "code"
results[].kindenumyesdocument: in Search's index (owner, type, id set); page: a web page (provider set).
  • one of "document", "page"
results[].titlestringyes
  • maxLength 300
results[].urlstringyes
  • format uri
  • maxLength 2048
results[].snippetstring | nullPlain text; never HTML.
  • maxLength 600
results[].sitestring | null
  • maxLength 253
results[].imagestring | null
  • maxLength 2048
results[].published_atstring | null
  • maxLength 40
results[].retrieved_atstring | nullWhen a web page was read (by the provider or the open index).
  • maxLength 40
results[].providerstring | nullpage: who found it (open_index, deepseek, wikipedia, brave, …).
  • maxLength 40
results[].ownerstring | null
  • maxLength 32
results[].typestring | null
  • maxLength 32
results[].idstring | null
  • maxLength 200
results[].scorenumber | nullRank within its scope (higher first); not comparable across scopes.
results[].ranksobject1-based position in the keyword and vector top-100 lists; null when absent from that list.
  • no other fields
results[].ranks.keywordinteger | nullyes
  • minimum 1
results[].ranks.vectorinteger | nullyes
  • minimum 1
groupsobjectyesHow many results each scope gave on this page.
answerobject | null
citationsarray of object
  • maxItems 20
  • items: no other fields
citations[].nintegeryes
  • minimum 1
citations[].urlstringyes
  • maxLength 2048
citations[].titlestringyes
  • maxLength 300
citations[].providerstring | null
  • maxLength 40
citations[].retrieved_atstring | null
  • maxLength 40
routeobjectyes
  • no other fields
route.explainarray of objectyes
  • maxItems 20
  • items: no other fields
route.explain[].scopeenumyes
  • one of "network", "mine", "web", "news", "images", "video", "products", "people", "places", "code"
route.explain[].stepstringyesindex, open_index, cache, deepseek, wikipedia, …
  • maxLength 40
route.explain[].okbooleanyes
route.explain[].countinteger
  • minimum 0
route.explain[].msinteger
  • minimum 0
route.explain[].cachedboolean
route.explain[].cost_usdnumber
  • minimum 0
route.explain[].skippedstring | nullWhy the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
  • maxLength 160
route.explain[].rankingenum
  • one of "hybrid", "keyword"
route.explain[].reasonenum
  • one of "no_vectors", "ai_unavailable", "short_query"
route.cost_usdnumberyesWhat this query cost OpenVibe (paid provider calls; cached answers cost 0).
  • minimum 0
next_cursorstring | nullyes
  • maxLength 512

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 }] }