openvibers/openvibe.contracts Commits

0.225.0: the Search Fabric (search.fabric.query; search.fabric-request@1, search.fabric-result@1 with route.explain and cited answers, search.provider-offer@1) (#233)

OP OpenVibers committed 16 days ago · 6a575c6612 · 60 files, +7507 −78

Changes

ddiff --git a/CHANGELOG.md b/CHANGELOG.md
iindex 69aec16b..2e3024b5 100644
---- a/CHANGELOG.md
++++ b/CHANGELOG.md
@@@ -4,6 +4,40 @@ All notable changes to `openvibe-contracts`. Releases are git tags (`vX.Y.Z`) th
from `https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/<tag>`. Before v0.30.0,
the notes were in the tag and commit messages (`git tag -n1`).
++## 0.225.0 — 2026-10-28
++
++- **The Search Fabric** (plan 2026-10-28 §4.5; the owner, 10-28: "a shared sdk/api enabled multi purpose search system
++ for OpenVibe to reuse across sites and more"): one search over several scopes, routed the cheapest way that answers.
++ - **`search.fabric.query`** (public, owned by `search`): `POST /api/v1/query` (or `GET /api/v1/query?q=&scopes=`), and
++ `GET /api/v1/query/providers`. It is the SDK's `createSearchClient().query()` and the MCP tool `openvibe.search`.
++ - **`search.fabric-request@1`:**
++ - `q` and `scopes`: `network`, `mine`, `web`, and `news`, `images`, `video`, `products`, `people`, `places`,
++ `code` (accepted now; v1 answers them as network results by kind);
++ - `filters` (owner, type, lang, site);
++ - `freshness`;
++ - `depth`: `quick` reads only the indexes and caches, `standard` climbs the provider ladder until a step
++ answers, `deep` asks every step;
++ - `answer`, `limit` and `cursor`.
++ - **`search.fabric-result@1`:**
++ - `results`, each with its scope and kind (a document in Search's index, or a web page with its provider,
++ URL, date and when it was read);
++ - `groups` (counts per scope) and `citations`;
++ - an optional `answer`. It is labelled "Written by AI from these sources" and is never without citations.
++ - `route.explain`: step by step, what was asked, what answered, from the cache or not, why a step was
++ skipped, and what it cost.
++
++ The query is never echoed (the `?q=` rule).
++ - **`search.provider-offer@1`:** a web provider as the ladder and Route see it. It gives the scopes, the price
++ per call, whether the provider has its own index, availability (balance, key, rate limit, daily cap),
++ latency, answered rate and terms.
++ - **Who may use what:**
++ - anonymous callers get network results, plus web results from the open index and the cache;
++ - a signed-in person, or a first-party service, also reaches the paid providers within OpenVibe's daily caps;
++ - `mine` needs a person;
++ - providers never receive an account identifier.
++
++ Fixtures, valid and invalid, for all three schemas.
++
## 0.224.0 — 2026-10-28
- **A `crawl` source type for OpenVibe.Sources** (the owner, 2026-10-28: "aggregate all websites and select deals on all
ddiff --git a/contracts/catalog.json b/contracts/catalog.json
iindex 95d7a641..1abaed8a 100644
---- a/contracts/catalog.json
++++ b/contracts/catalog.json
@@@ -266,6 +266,33 @@
"compatibility": "backward",
"status": "active"
},
++ {
++ "id": "search.fabric-request",
++ "version": "1.0.0",
++ "owner": "search",
++ "schema": "search/fabric-request.v1.json",
++ "visibility": "public",
++ "compatibility": "backward",
++ "status": "active"
++ },
++ {
++ "id": "search.fabric-result",
++ "version": "1.0.0",
++ "owner": "search",
++ "schema": "search/fabric-result.v1.json",
++ "visibility": "public",
++ "compatibility": "backward",
++ "status": "active"
++ },
++ {
++ "id": "search.provider-offer",
++ "version": "1.0.0",
++ "owner": "search",
++ "schema": "search/provider-offer.v1.json",
++ "visibility": "public",
++ "compatibility": "backward",
++ "status": "active"
++ },
{
"id": "search.write-result",
"version": "1.0.0",
ddiff --git a/contracts/search/fabric-request.v1.json b/contracts/search/fabric-request.v1.json
nnew file mode 100644
iindex 00000000..57c920b1
---- /dev/null
++++ b/contracts/search/fabric-request.v1.json
@@@ -0,0 +1,104 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/search/fabric-request.v1.json",
++ "title": "SearchFabricRequest",
++ "description": "search.fabric-request@1: the body of POST /api/v1/query (or the query string of GET /api/v1/query, scopes comma-separated), capability search.fabric.query. One search over several scopes, routed the cheapest way that answers (plan 2026-10-28 \u00a74.5). network: Search's own index, permission-aware exactly as search.query.run; mine: the caller's own private documents (a signed-in person, or a service with X-OV-Subject); web: OpenVibe's open index first, then paid providers in a ladder, each result keeping its provider, date and URL. Providers never receive an account identifier. A scope the caller may not use (mine without a person; web's paid providers for an anonymous caller, who gets cached and open-index results only) is reported in route.explain, never an error. The other scopes are facets of the same indexes and are accepted for forward compatibility; v1 answers them as network results filtered by kind.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "q"
++ ],
++ "properties": {
++ "q": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 200,
++ "description": "What to find."
++ },
++ "scopes": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 10,
++ "uniqueItems": true,
++ "items": {
++ "enum": [
++ "network",
++ "mine",
++ "web",
++ "news",
++ "images",
++ "video",
++ "products",
++ "people",
++ "places",
++ "code"
++ ]
++ },
++ "default": [
++ "network"
++ ],
++ "description": "Where to look; results are grouped by scope. Default: network."
++ },
++ "filters": {
++ "type": "object",
++ "additionalProperties": false,
++ "description": "Narrow the network and mine scopes (never widen what the caller may see).",
++ "properties": {
++ "owner": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_-]{0,31}$"
++ },
++ "type": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_-]{0,31}$"
++ },
++ "lang": {
++ "type": "string",
++ "pattern": "^[a-zA-Z]{2,3}(-[A-Za-z0-9]{2,8})*$"
++ },
++ "site": {
++ "type": "string",
++ "maxLength": 253,
++ "pattern": "^[a-z0-9.-]+$",
++ "description": "web: results from this host only."
++ }
++ }
++ },
++ "freshness": {
++ "enum": [
++ "any",
++ "day",
++ "week",
++ "month",
++ "year"
++ ],
++ "default": "any",
++ "description": "How recent results must be, where the source dates them."
++ },
++ "depth": {
++ "enum": [
++ "quick",
++ "standard",
++ "deep"
++ ],
++ "default": "standard",
++ "description": "quick: indexes and caches only (no paid provider); standard: the ladder until a step answers; deep: every step, merged."
++ },
++ "answer": {
++ "type": "boolean",
++ "default": false,
++ "description": "Ask for a short cited answer written by AI from the results. Never without citations; labelled AI. A deployment may decline (answer: null, with the reason in route.explain)."
++ },
++ "limit": {
++ "type": "integer",
++ "minimum": 1,
++ "maximum": 50,
++ "default": 20
++ },
++ "cursor": {
++ "type": "string",
++ "maxLength": 512,
++ "description": "next_cursor of the previous page (network and mine only)."
++ }
++ }
++}
ddiff --git a/contracts/search/fabric-result.v1.json b/contracts/search/fabric-result.v1.json
nnew file mode 100644
iindex 00000000..7f09d3be
---- /dev/null
++++ b/contracts/search/fabric-result.v1.json
@@@ -0,0 +1,296 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/search/fabric-result.v1.json",
++ "title": "SearchFabricResult",
++ "description": "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).",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "results",
++ "groups",
++ "route",
++ "next_cursor"
++ ],
++ "properties": {
++ "results": {
++ "type": "array",
++ "maxItems": 100,
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "scope",
++ "kind",
++ "title",
++ "url"
++ ],
++ "properties": {
++ "scope": {
++ "enum": [
++ "network",
++ "mine",
++ "web",
++ "news",
++ "images",
++ "video",
++ "products",
++ "people",
++ "places",
++ "code"
++ ]
++ },
++ "kind": {
++ "enum": [
++ "document",
++ "page"
++ ],
++ "description": "document: in Search's index (owner, type, id set); page: a web page (provider set)."
++ },
++ "title": {
++ "type": "string",
++ "maxLength": 300
++ },
++ "url": {
++ "type": "string",
++ "maxLength": 2048,
++ "format": "uri"
++ },
++ "snippet": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 600,
++ "description": "Plain text; never HTML."
++ },
++ "site": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 253
++ },
++ "image": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 2048
++ },
++ "published_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 40
++ },
++ "retrieved_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 40,
++ "description": "When a web page was read (by the provider or the open index)."
++ },
++ "provider": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 40,
++ "description": "page: who found it (open_index, deepseek, wikipedia, brave, \u2026)."
++ },
++ "owner": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 32
++ },
++ "type": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 32
++ },
++ "id": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 200
++ },
++ "score": {
++ "type": [
++ "number",
++ "null"
++ ],
++ "description": "Rank within its scope (higher first); not comparable across scopes."
++ }
++ }
++ }
++ },
++ "groups": {
++ "type": "object",
++ "additionalProperties": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "description": "How many results each scope gave on this page."
++ },
++ "answer": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "required": [
++ "text",
++ "citations",
++ "label"
++ ],
++ "properties": {
++ "text": {
++ "type": "string",
++ "maxLength": 2000
++ },
++ "citations": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 20,
++ "items": {
++ "type": "integer",
++ "minimum": 1
++ }
++ },
++ "label": {
++ "const": "Written by AI from these sources"
++ }
++ }
++ },
++ "citations": {
++ "type": "array",
++ "maxItems": 20,
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "n",
++ "url",
++ "title"
++ ],
++ "properties": {
++ "n": {
++ "type": "integer",
++ "minimum": 1
++ },
++ "url": {
++ "type": "string",
++ "maxLength": 2048
++ },
++ "title": {
++ "type": "string",
++ "maxLength": 300
++ },
++ "provider": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 40
++ },
++ "retrieved_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 40
++ }
++ }
++ }
++ },
++ "route": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "explain",
++ "cost_usd"
++ ],
++ "properties": {
++ "explain": {
++ "type": "array",
++ "maxItems": 20,
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "scope",
++ "step",
++ "ok"
++ ],
++ "properties": {
++ "scope": {
++ "enum": [
++ "network",
++ "mine",
++ "web",
++ "news",
++ "images",
++ "video",
++ "products",
++ "people",
++ "places",
++ "code"
++ ]
++ },
++ "step": {
++ "type": "string",
++ "maxLength": 40,
++ "description": "index, open_index, cache, deepseek, wikipedia, \u2026"
++ },
++ "ok": {
++ "type": "boolean"
++ },
++ "count": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "ms": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "cached": {
++ "type": "boolean"
++ },
++ "cost_usd": {
++ "type": "number",
++ "minimum": 0
++ },
++ "skipped": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 160,
++ "description": "Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down)."
++ }
++ }
++ }
++ },
++ "cost_usd": {
++ "type": "number",
++ "minimum": 0,
++ "description": "What this query cost OpenVibe (paid provider calls; cached answers cost 0)."
++ }
++ }
++ },
++ "next_cursor": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 512
++ }
++ }
++}
ddiff --git a/contracts/search/provider-offer.v1.json b/contracts/search/provider-offer.v1.json
nnew file mode 100644
iindex 00000000..d7b63d64
---- /dev/null
++++ b/contracts/search/provider-offer.v1.json
@@@ -0,0 +1,103 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/search/provider-offer.v1.json",
++ "title": "SearchProviderOffer",
++ "description": "search.provider-offer@1: one web search provider as the Search Fabric's ladder and Route see it (GET /api/v1/query/providers, capability search.fabric.query): what it covers, what it costs, whether it is usable now and how it has answered. Prices are the vendor's published ones as of checked_at; nothing here is a secret.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "provider",
++ "scopes",
++ "price_usd_per_call",
++ "available",
++ "checked_at"
++ ],
++ "properties": {
++ "provider": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_]{1,39}$"
++ },
++ "name": {
++ "type": "string",
++ "maxLength": 80
++ },
++ "scopes": {
++ "type": "array",
++ "minItems": 1,
++ "items": {
++ "enum": [
++ "network",
++ "mine",
++ "web",
++ "news",
++ "images",
++ "video",
++ "products",
++ "people",
++ "places",
++ "code"
++ ]
++ }
++ },
++ "price_usd_per_call": {
++ "type": "number",
++ "minimum": 0
++ },
++ "independent_index": {
++ "type": "boolean",
++ "description": "Searches its own crawl rather than reselling another engine's."
++ },
++ "available": {
++ "type": "boolean",
++ "description": "Configured and not standing down (balance, key, rate limit, daily cap)."
++ },
++ "reason": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 160
++ },
++ "daily_cap": {
++ "type": [
++ "integer",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "used_today": {
++ "type": [
++ "integer",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "latency_ms_p50": {
++ "type": [
++ "integer",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "answered_rate": {
++ "type": [
++ "number",
++ "null"
++ ],
++ "minimum": 0,
++ "maximum": 1,
++ "description": "Share of calls in the last day that returned at least one result."
++ },
++ "terms_url": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 2048
++ },
++ "checked_at": {
++ "type": "string",
++ "maxLength": 40
++ }
++ }
++}
ddiff --git a/fixtures/search.fabric-request/invalid/empty-q.json b/fixtures/search.fabric-request/invalid/empty-q.json
nnew file mode 100644
iindex 00000000..0f636225
---- /dev/null
++++ b/fixtures/search.fabric-request/invalid/empty-q.json
@@@ -0,0 +1,3 @@
++{
++ "q": ""
++}
ddiff --git a/fixtures/search.fabric-request/invalid/limit-too-big.json b/fixtures/search.fabric-request/invalid/limit-too-big.json
nnew file mode 100644
iindex 00000000..3944c49e
---- /dev/null
++++ b/fixtures/search.fabric-request/invalid/limit-too-big.json
@@@ -0,0 +1,4 @@
++{
++ "q": "x",
++ "limit": 500
++}
ddiff --git a/fixtures/search.fabric-request/invalid/unknown-scope.json b/fixtures/search.fabric-request/invalid/unknown-scope.json
nnew file mode 100644
iindex 00000000..8cf6a95c
---- /dev/null
++++ b/fixtures/search.fabric-request/invalid/unknown-scope.json
@@@ -0,0 +1,6 @@
++{
++ "q": "x",
++ "scopes": [
++ "everything"
++ ]
++}
ddiff --git a/fixtures/search.fabric-request/valid/mine-filtered.json b/fixtures/search.fabric-request/valid/mine-filtered.json
nnew file mode 100644
iindex 00000000..9d36d2e8
---- /dev/null
++++ b/fixtures/search.fabric-request/valid/mine-filtered.json
@@@ -0,0 +1,12 @@
++{
++ "q": "notes",
++ "scopes": [
++ "mine"
++ ],
++ "filters": {
++ "owner": "community",
++ "type": "paste"
++ },
++ "answer": false,
++ "depth": "quick"
++}
ddiff --git a/fixtures/search.fabric-request/valid/minimal.json b/fixtures/search.fabric-request/valid/minimal.json
nnew file mode 100644
iindex 00000000..f0518662
---- /dev/null
++++ b/fixtures/search.fabric-request/valid/minimal.json
@@@ -0,0 +1,3 @@
++{
++ "q": "lofi streams"
++}
ddiff --git a/fixtures/search.fabric-request/valid/network-and-web.json b/fixtures/search.fabric-request/valid/network-and-web.json
nnew file mode 100644
iindex 00000000..a4e3b117
---- /dev/null
++++ b/fixtures/search.fabric-request/valid/network-and-web.json
@@@ -0,0 +1,10 @@
++{
++ "q": "surf_utopia world record",
++ "scopes": [
++ "network",
++ "web"
++ ],
++ "freshness": "month",
++ "depth": "standard",
++ "limit": 10
++}
ddiff --git a/fixtures/search.fabric-result/invalid/answer-without-citations.json b/fixtures/search.fabric-result/invalid/answer-without-citations.json
nnew file mode 100644
iindex 00000000..104b7f02
---- /dev/null
++++ b/fixtures/search.fabric-result/invalid/answer-without-citations.json
@@@ -0,0 +1,14 @@
++{
++ "results": [],
++ "groups": {},
++ "answer": {
++ "text": "Trust me.",
++ "citations": [],
++ "label": "Written by AI from these sources"
++ },
++ "route": {
++ "explain": [],
++ "cost_usd": 0
++ },
++ "next_cursor": null
++}
ddiff --git a/fixtures/search.fabric-result/invalid/html-in-kind.json b/fixtures/search.fabric-result/invalid/html-in-kind.json
nnew file mode 100644
iindex 00000000..08ec1b4e
---- /dev/null
++++ b/fixtures/search.fabric-result/invalid/html-in-kind.json
@@@ -0,0 +1,16 @@
++{
++ "results": [
++ {
++ "scope": "web",
++ "kind": "html",
++ "title": "x",
++ "url": "https://x.org/"
++ }
++ ],
++ "groups": {},
++ "route": {
++ "explain": [],
++ "cost_usd": 0
++ },
++ "next_cursor": null
++}
ddiff --git a/fixtures/search.fabric-result/valid/mixed.json b/fixtures/search.fabric-result/valid/mixed.json
nnew file mode 100644
iindex 00000000..bffa3a75
---- /dev/null
++++ b/fixtures/search.fabric-result/valid/mixed.json
@@@ -0,0 +1,88 @@
++{
++ "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\u2026",
++ "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
++}
ddiff --git a/fixtures/search.fabric-result/valid/with-answer.json b/fixtures/search.fabric-result/valid/with-answer.json
nnew file mode 100644
iindex 00000000..9ffd6689
---- /dev/null
++++ b/fixtures/search.fabric-result/valid/with-answer.json
@@@ -0,0 +1,43 @@
++{
++ "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
++}
ddiff --git a/fixtures/search.provider-offer/invalid/negative-price.json b/fixtures/search.provider-offer/invalid/negative-price.json
nnew file mode 100644
iindex 00000000..c77adc22
---- /dev/null
++++ b/fixtures/search.provider-offer/invalid/negative-price.json
@@@ -0,0 +1,9 @@
++{
++ "provider": "x",
++ "scopes": [
++ "web"
++ ],
++ "price_usd_per_call": -1,
++ "available": true,
++ "checked_at": "2026-10-28T11:00:00Z"
++}
ddiff --git a/fixtures/search.provider-offer/valid/deepseek.json b/fixtures/search.provider-offer/valid/deepseek.json
nnew file mode 100644
iindex 00000000..e4a56aca
---- /dev/null
++++ b/fixtures/search.provider-offer/valid/deepseek.json
@@@ -0,0 +1,18 @@
++{
++ "provider": "deepseek",
++ "name": "DeepSeek Search",
++ "scopes": [
++ "web",
++ "news"
++ ],
++ "price_usd_per_call": 0.00075,
++ "independent_index": false,
++ "available": true,
++ "reason": null,
++ "daily_cap": 1500,
++ "used_today": 212,
++ "latency_ms_p50": 1380,
++ "answered_rate": 0.97,
++ "terms_url": "https://api-docs.deepseek.com/guides/search",
++ "checked_at": "2026-10-28T11:00:00Z"
++}
ddiff --git a/generated/json-schema/bundle.json b/generated/json-schema/bundle.json
iindex 79fd8523..2c61d17f 100644
---- a/generated/json-schema/bundle.json
++++ b/generated/json-schema/bundle.json
@@@ -3664,6 +3664,524 @@
}
}
},
++ "search.fabric-request": {
++ "version": "1.0.0",
++ "owner": "search",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/search/fabric-request.v1.json",
++ "title": "SearchFabricRequest",
++ "description": "search.fabric-request@1: the body of POST /api/v1/query (or the query string of GET /api/v1/query, scopes comma-separated), capability search.fabric.query. One search over several scopes, routed the cheapest way that answers (plan 2026-10-28 §4.5). network: Search's own index, permission-aware exactly as search.query.run; mine: the caller's own private documents (a signed-in person, or a service with X-OV-Subject); web: OpenVibe's open index first, then paid providers in a ladder, each result keeping its provider, date and URL. Providers never receive an account identifier. A scope the caller may not use (mine without a person; web's paid providers for an anonymous caller, who gets cached and open-index results only) is reported in route.explain, never an error. The other scopes are facets of the same indexes and are accepted for forward compatibility; v1 answers them as network results filtered by kind.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "q"
++ ],
++ "properties": {
++ "q": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 200,
++ "description": "What to find."
++ },
++ "scopes": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 10,
++ "uniqueItems": true,
++ "items": {
++ "enum": [
++ "network",
++ "mine",
++ "web",
++ "news",
++ "images",
++ "video",
++ "products",
++ "people",
++ "places",
++ "code"
++ ]
++ },
++ "default": [
++ "network"
++ ],
++ "description": "Where to look; results are grouped by scope. Default: network."
++ },
++ "filters": {
++ "type": "object",
++ "additionalProperties": false,
++ "description": "Narrow the network and mine scopes (never widen what the caller may see).",
++ "properties": {
++ "owner": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_-]{0,31}$"
++ },
++ "type": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_-]{0,31}$"
++ },
++ "lang": {
++ "type": "string",
++ "pattern": "^[a-zA-Z]{2,3}(-[A-Za-z0-9]{2,8})*$"
++ },
++ "site": {
++ "type": "string",
++ "maxLength": 253,
++ "pattern": "^[a-z0-9.-]+$",
++ "description": "web: results from this host only."
++ }
++ }
++ },
++ "freshness": {
++ "enum": [
++ "any",
++ "day",
++ "week",
++ "month",
++ "year"
++ ],
++ "default": "any",
++ "description": "How recent results must be, where the source dates them."
++ },
++ "depth": {
++ "enum": [
++ "quick",
++ "standard",
++ "deep"
++ ],
++ "default": "standard",
++ "description": "quick: indexes and caches only (no paid provider); standard: the ladder until a step answers; deep: every step, merged."
++ },
++ "answer": {
++ "type": "boolean",
++ "default": false,
++ "description": "Ask for a short cited answer written by AI from the results. Never without citations; labelled AI. A deployment may decline (answer: null, with the reason in route.explain)."
++ },
++ "limit": {
++ "type": "integer",
++ "minimum": 1,
++ "maximum": 50,
++ "default": 20
++ },
++ "cursor": {
++ "type": "string",
++ "maxLength": 512,
++ "description": "next_cursor of the previous page (network and mine only)."
++ }
++ }
++ }
++ },
++ "search.fabric-result": {
++ "version": "1.0.0",
++ "owner": "search",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/search/fabric-result.v1.json",
++ "title": "SearchFabricResult",
++ "description": "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).",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "results",
++ "groups",
++ "route",
++ "next_cursor"
++ ],
++ "properties": {
++ "results": {
++ "type": "array",
++ "maxItems": 100,
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "scope",
++ "kind",
++ "title",
++ "url"
++ ],
++ "properties": {
++ "scope": {
++ "enum": [
++ "network",
++ "mine",
++ "web",
++ "news",
++ "images",
++ "video",
++ "products",
++ "people",
++ "places",
++ "code"
++ ]
++ },
++ "kind": {
++ "enum": [
++ "document",
++ "page"
++ ],
++ "description": "document: in Search's index (owner, type, id set); page: a web page (provider set)."
++ },
++ "title": {
++ "type": "string",
++ "maxLength": 300
++ },
++ "url": {
++ "type": "string",
++ "maxLength": 2048,
++ "format": "uri"
++ },
++ "snippet": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 600,
++ "description": "Plain text; never HTML."
++ },
++ "site": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 253
++ },
++ "image": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 2048
++ },
++ "published_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 40
++ },
++ "retrieved_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 40,
++ "description": "When a web page was read (by the provider or the open index)."
++ },
++ "provider": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 40,
++ "description": "page: who found it (open_index, deepseek, wikipedia, brave, …)."
++ },
++ "owner": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 32
++ },
++ "type": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 32
++ },
++ "id": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 200
++ },
++ "score": {
++ "type": [
++ "number",
++ "null"
++ ],
++ "description": "Rank within its scope (higher first); not comparable across scopes."
++ }
++ }
++ }
++ },
++ "groups": {
++ "type": "object",
++ "additionalProperties": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "description": "How many results each scope gave on this page."
++ },
++ "answer": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "required": [
++ "text",
++ "citations",
++ "label"
++ ],
++ "properties": {
++ "text": {
++ "type": "string",
++ "maxLength": 2000
++ },
++ "citations": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 20,
++ "items": {
++ "type": "integer",
++ "minimum": 1
++ }
++ },
++ "label": {
++ "const": "Written by AI from these sources"
++ }
++ }
++ },
++ "citations": {
++ "type": "array",
++ "maxItems": 20,
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "n",
++ "url",
++ "title"
++ ],
++ "properties": {
++ "n": {
++ "type": "integer",
++ "minimum": 1
++ },
++ "url": {
++ "type": "string",
++ "maxLength": 2048
++ },
++ "title": {
++ "type": "string",
++ "maxLength": 300
++ },
++ "provider": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 40
++ },
++ "retrieved_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 40
++ }
++ }
++ }
++ },
++ "route": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "explain",
++ "cost_usd"
++ ],
++ "properties": {
++ "explain": {
++ "type": "array",
++ "maxItems": 20,
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "scope",
++ "step",
++ "ok"
++ ],
++ "properties": {
++ "scope": {
++ "enum": [
++ "network",
++ "mine",
++ "web",
++ "news",
++ "images",
++ "video",
++ "products",
++ "people",
++ "places",
++ "code"
++ ]
++ },
++ "step": {
++ "type": "string",
++ "maxLength": 40,
++ "description": "index, open_index, cache, deepseek, wikipedia, …"
++ },
++ "ok": {
++ "type": "boolean"
++ },
++ "count": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "ms": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "cached": {
++ "type": "boolean"
++ },
++ "cost_usd": {
++ "type": "number",
++ "minimum": 0
++ },
++ "skipped": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 160,
++ "description": "Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down)."
++ }
++ }
++ }
++ },
++ "cost_usd": {
++ "type": "number",
++ "minimum": 0,
++ "description": "What this query cost OpenVibe (paid provider calls; cached answers cost 0)."
++ }
++ }
++ },
++ "next_cursor": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 512
++ }
++ }
++ }
++ },
++ "search.provider-offer": {
++ "version": "1.0.0",
++ "owner": "search",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/search/provider-offer.v1.json",
++ "title": "SearchProviderOffer",
++ "description": "search.provider-offer@1: one web search provider as the Search Fabric's ladder and Route see it (GET /api/v1/query/providers, capability search.fabric.query): what it covers, what it costs, whether it is usable now and how it has answered. Prices are the vendor's published ones as of checked_at; nothing here is a secret.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "provider",
++ "scopes",
++ "price_usd_per_call",
++ "available",
++ "checked_at"
++ ],
++ "properties": {
++ "provider": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_]{1,39}$"
++ },
++ "name": {
++ "type": "string",
++ "maxLength": 80
++ },
++ "scopes": {
++ "type": "array",
++ "minItems": 1,
++ "items": {
++ "enum": [
++ "network",
++ "mine",
++ "web",
++ "news",
++ "images",
++ "video",
++ "products",
++ "people",
++ "places",
++ "code"
++ ]
++ }
++ },
++ "price_usd_per_call": {
++ "type": "number",
++ "minimum": 0
++ },
++ "independent_index": {
++ "type": "boolean",
++ "description": "Searches its own crawl rather than reselling another engine's."
++ },
++ "available": {
++ "type": "boolean",
++ "description": "Configured and not standing down (balance, key, rate limit, daily cap)."
++ },
++ "reason": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 160
++ },
++ "daily_cap": {
++ "type": [
++ "integer",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "used_today": {
++ "type": [
++ "integer",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "latency_ms_p50": {
++ "type": [
++ "integer",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "answered_rate": {
++ "type": [
++ "number",
++ "null"
++ ],
++ "minimum": 0,
++ "maximum": 1,
++ "description": "Share of calls in the last day that returned at least one result."
++ },
++ "terms_url": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 2048
++ },
++ "checked_at": {
++ "type": "string",
++ "maxLength": 40
++ }
++ }
++ }
++ },
"search.write-result": {
"version": "1.0.0",
"owner": "search",
ddiff --git a/generated/openapi/actor.json b/generated/openapi/actor.json
iindex 9f6bd791..71cabef9 100644
---- a/generated/openapi/actor.json
++++ b/generated/openapi/actor.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Actor API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/ai.json b/generated/openapi/ai.json
iindex 49a4edff..ffe5b807 100644
---- a/generated/openapi/ai.json
++++ b/generated/openapi/ai.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.AI API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/billing.json b/generated/openapi/billing.json
iindex 9da82699..cbb6fc3a 100644
---- a/generated/openapi/billing.json
++++ b/generated/openapi/billing.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Billing API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/blog.json b/generated/openapi/blog.json
iindex c1dac6df..c4b49feb 100644
---- a/generated/openapi/blog.json
++++ b/generated/openapi/blog.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Blog API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/bot.json b/generated/openapi/bot.json
iindex 6587e159..d8583884 100644
---- a/generated/openapi/bot.json
++++ b/generated/openapi/bot.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Bot API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/chat.json b/generated/openapi/chat.json
iindex 4930958f..70726c79 100644
---- a/generated/openapi/chat.json
++++ b/generated/openapi/chat.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Chat API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/codes.json b/generated/openapi/codes.json
iindex de880542..7460a646 100644
---- a/generated/openapi/codes.json
++++ b/generated/openapi/codes.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Codes API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/community.json b/generated/openapi/community.json
iindex 77866580..13f8ea7c 100644
---- a/generated/openapi/community.json
++++ b/generated/openapi/community.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Community API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/coupons.json b/generated/openapi/coupons.json
iindex 2dac4bf5..3442b6a5 100644
---- a/generated/openapi/coupons.json
++++ b/generated/openapi/coupons.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Coupons API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/deals.json b/generated/openapi/deals.json
iindex a9bf600a..f471e73f 100644
---- a/generated/openapi/deals.json
++++ b/generated/openapi/deals.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Deals API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/events.json b/generated/openapi/events.json
iindex f292864c..2299f083 100644
---- a/generated/openapi/events.json
++++ b/generated/openapi/events.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Events API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/food.json b/generated/openapi/food.json
iindex acaf2a32..8112de85 100644
---- a/generated/openapi/food.json
++++ b/generated/openapi/food.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Food API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/games.json b/generated/openapi/games.json
iindex 6f874c59..322a48c2 100644
---- a/generated/openapi/games.json
++++ b/generated/openapi/games.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Games API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/host.json b/generated/openapi/host.json
iindex eb82c4e8..998d3f73 100644
---- a/generated/openapi/host.json
++++ b/generated/openapi/host.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Host API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/index.json b/generated/openapi/index.json
iindex 4bcf549a..ed20386b 100644
---- a/generated/openapi/index.json
++++ b/generated/openapi/index.json
@@@ -180,8 +180,8 @@
"service": "search",
"name": "OpenVibe.Search",
"origin": "https://search.openvibe.network",
-- "operations": 8,
-- "capabilities": 3
++ "operations": 11,
++ "capabilities": 4
},
{
"service": "services",
ddiff --git a/generated/openapi/inventory.json b/generated/openapi/inventory.json
iindex 6f9d0136..2eb430b9 100644
---- a/generated/openapi/inventory.json
++++ b/generated/openapi/inventory.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Inventory API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/live.json b/generated/openapi/live.json
iindex 78f67acf..1faac94b 100644
---- a/generated/openapi/live.json
++++ b/generated/openapi/live.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Live API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/media-hub.json b/generated/openapi/media-hub.json
iindex cd8e9015..f0ef7b62 100644
---- a/generated/openapi/media-hub.json
++++ b/generated/openapi/media-hub.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.MediaHub API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.MediaHub as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/media.json b/generated/openapi/media.json
iindex 1e41e2a8..2929150b 100644
---- a/generated/openapi/media.json
++++ b/generated/openapi/media.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Media API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/network.json b/generated/openapi/network.json
iindex 4dc30435..388de344 100644
---- a/generated/openapi/network.json
++++ b/generated/openapi/network.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Network API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/news.json b/generated/openapi/news.json
iindex 437ddcf8..e449b930 100644
---- a/generated/openapi/news.json
++++ b/generated/openapi/news.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.News API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/openre.json b/generated/openapi/openre.json
iindex 460f209c..209a53c2 100644
---- a/generated/openapi/openre.json
++++ b/generated/openapi/openre.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenRestream API",
-- "version": "0.224.0",
-- "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/play.json b/generated/openapi/play.json
iindex 6476887d..a24e6d02 100644
---- a/generated/openapi/play.json
++++ b/generated/openapi/play.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Play API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Play as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/quest.json b/generated/openapi/quest.json
iindex 8761218f..9ceef6b2 100644
---- a/generated/openapi/quest.json
++++ b/generated/openapi/quest.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Quest API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Quest as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/reviews.json b/generated/openapi/reviews.json
iindex e3177856..2ba4a375 100644
---- a/generated/openapi/reviews.json
++++ b/generated/openapi/reviews.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Reviews API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/run.json b/generated/openapi/run.json
iindex 2105e3e9..2a846c39 100644
---- a/generated/openapi/run.json
++++ b/generated/openapi/run.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Run API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/search.json b/generated/openapi/search.json
iindex 14827ade..c4e7b783 100644
---- a/generated/openapi/search.json
++++ b/generated/openapi/search.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Search API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
@@@ -502,6 +502,438 @@
}
}
},
++ "/api/v1/query": {
++ "get": {
++ "operationId": "get_api_v1_query",
++ "summary": "One search over several scopes (plan 2026-10-28 §4.5, the Search Fabric): network (Search's index, permission-aware as search.query.run), mine (the person's own private documents), web (OpenVibe's ope",
++ "description": "**search.fabric.query** (public): One search over several scopes (plan 2026-10-28 §4.5, the Search Fabric): network (Search's index, permission-aware as search.query.run), mine (the person's own private documents), web (OpenVibe's open index, then paid providers in a ladder, cached), with route.explain saying what answered and what it cost. Anonymous callers get network results and web results from the open index and the cache; a signed-in person or a first-party service (X-OV-Subject for mine) also reaches paid providers within OpenVibe's daily caps. Providers never receive an account identifier. The same operation is the SDK's createSearchClient().query() and the MCP tool openvibe.search.",
++ "tags": [
++ "search.fabric"
++ ],
++ "x-openvibe-capabilities": [
++ "search.fabric.query"
++ ],
++ "x-openvibe-visibility": [
++ "public"
++ ],
++ "x-openvibe-quota-class": "search-query",
++ "security": [
++ {
++ "openvibeToken": [
++ "search.fabric.query"
++ ]
++ }
++ ],
++ "x-openvibe-input": {
++ "$ref": "#/components/schemas/search.fabric-request.v1"
++ },
++ "parameters": [
++ {
++ "name": "q",
++ "in": "query",
++ "required": true,
++ "schema": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 200,
++ "description": "What to find."
++ },
++ "description": "What to find."
++ },
++ {
++ "name": "scopes",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 10,
++ "uniqueItems": true,
++ "items": {
++ "enum": [
++ "network",
++ "mine",
++ "web",
++ "news",
++ "images",
++ "video",
++ "products",
++ "people",
++ "places",
++ "code"
++ ]
++ },
++ "default": [
++ "network"
++ ],
++ "description": "Where to look; results are grouped by scope. Default: network."
++ },
++ "description": "Where to look; results are grouped by scope. Default: network."
++ },
++ {
++ "name": "filters",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "object",
++ "additionalProperties": false,
++ "description": "Narrow the network and mine scopes (never widen what the caller may see).",
++ "properties": {
++ "owner": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_-]{0,31}$"
++ },
++ "type": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_-]{0,31}$"
++ },
++ "lang": {
++ "type": "string",
++ "pattern": "^[a-zA-Z]{2,3}(-[A-Za-z0-9]{2,8})*$"
++ },
++ "site": {
++ "type": "string",
++ "maxLength": 253,
++ "pattern": "^[a-z0-9.-]+$",
++ "description": "web: results from this host only."
++ }
++ }
++ },
++ "description": "Narrow the network and mine scopes (never widen what the caller may see)."
++ },
++ {
++ "name": "freshness",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "enum": [
++ "any",
++ "day",
++ "week",
++ "month",
++ "year"
++ ],
++ "default": "any",
++ "description": "How recent results must be, where the source dates them."
++ },
++ "description": "How recent results must be, where the source dates them."
++ },
++ {
++ "name": "depth",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "enum": [
++ "quick",
++ "standard",
++ "deep"
++ ],
++ "default": "standard",
++ "description": "quick: indexes and caches only (no paid provider); standard: the ladder until a step answers; deep: every step, merged."
++ },
++ "description": "quick: indexes and caches only (no paid provider); standard: the ladder until a step answers; deep: every step, merged."
++ },
++ {
++ "name": "answer",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "boolean",
++ "default": false,
++ "description": "Ask for a short cited answer written by AI from the results. Never without citations; labelled AI. A deployment may decline (answer: null, with the reason in route.explain)."
++ },
++ "description": "Ask for a short cited answer written by AI from the results. Never without citations; labelled AI. A deployment may decline (answer: null, with the reason in route.explain)."
++ },
++ {
++ "name": "limit",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "integer",
++ "minimum": 1,
++ "maximum": 50,
++ "default": 20
++ }
++ },
++ {
++ "name": "cursor",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "string",
++ "maxLength": 512,
++ "description": "next_cursor of the previous page (network and mine only)."
++ },
++ "description": "next_cursor of the previous page (network and mine only)."
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/search.fabric-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ },
++ "post": {
++ "operationId": "post_api_v1_query",
++ "summary": "One search over several scopes (plan 2026-10-28 §4.5, the Search Fabric): network (Search's index, permission-aware as search.query.run), mine (the person's own private documents), web (OpenVibe's ope",
++ "description": "**search.fabric.query** (public): One search over several scopes (plan 2026-10-28 §4.5, the Search Fabric): network (Search's index, permission-aware as search.query.run), mine (the person's own private documents), web (OpenVibe's open index, then paid providers in a ladder, cached), with route.explain saying what answered and what it cost. Anonymous callers get network results and web results from the open index and the cache; a signed-in person or a first-party service (X-OV-Subject for mine) also reaches paid providers within OpenVibe's daily caps. Providers never receive an account identifier. The same operation is the SDK's createSearchClient().query() and the MCP tool openvibe.search.",
++ "tags": [
++ "search.fabric"
++ ],
++ "x-openvibe-capabilities": [
++ "search.fabric.query"
++ ],
++ "x-openvibe-visibility": [
++ "public"
++ ],
++ "x-openvibe-quota-class": "search-query",
++ "security": [
++ {
++ "openvibeToken": [
++ "search.fabric.query"
++ ]
++ }
++ ],
++ "requestBody": {
++ "required": false,
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/search.fabric-request.v1"
++ }
++ }
++ }
++ },
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/search.fabric-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
++ "/api/v1/query/providers": {
++ "get": {
++ "operationId": "get_api_v1_query_providers",
++ "summary": "One search over several scopes (plan 2026-10-28 §4.5, the Search Fabric): network (Search's index, permission-aware as search.query.run), mine (the person's own private documents), web (OpenVibe's ope",
++ "description": "**search.fabric.query** (public): One search over several scopes (plan 2026-10-28 §4.5, the Search Fabric): network (Search's index, permission-aware as search.query.run), mine (the person's own private documents), web (OpenVibe's open index, then paid providers in a ladder, cached), with route.explain saying what answered and what it cost. Anonymous callers get network results and web results from the open index and the cache; a signed-in person or a first-party service (X-OV-Subject for mine) also reaches paid providers within OpenVibe's daily caps. Providers never receive an account identifier. The same operation is the SDK's createSearchClient().query() and the MCP tool openvibe.search.",
++ "tags": [
++ "search.fabric"
++ ],
++ "x-openvibe-capabilities": [
++ "search.fabric.query"
++ ],
++ "x-openvibe-visibility": [
++ "public"
++ ],
++ "x-openvibe-quota-class": "search-query",
++ "security": [
++ {
++ "openvibeToken": [
++ "search.fabric.query"
++ ]
++ }
++ ],
++ "x-openvibe-input": {
++ "$ref": "#/components/schemas/search.fabric-request.v1"
++ },
++ "parameters": [
++ {
++ "name": "q",
++ "in": "query",
++ "required": true,
++ "schema": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 200,
++ "description": "What to find."
++ },
++ "description": "What to find."
++ },
++ {
++ "name": "scopes",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 10,
++ "uniqueItems": true,
++ "items": {
++ "enum": [
++ "network",
++ "mine",
++ "web",
++ "news",
++ "images",
++ "video",
++ "products",
++ "people",
++ "places",
++ "code"
++ ]
++ },
++ "default": [
++ "network"
++ ],
++ "description": "Where to look; results are grouped by scope. Default: network."
++ },
++ "description": "Where to look; results are grouped by scope. Default: network."
++ },
++ {
++ "name": "filters",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "object",
++ "additionalProperties": false,
++ "description": "Narrow the network and mine scopes (never widen what the caller may see).",
++ "properties": {
++ "owner": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_-]{0,31}$"
++ },
++ "type": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_-]{0,31}$"
++ },
++ "lang": {
++ "type": "string",
++ "pattern": "^[a-zA-Z]{2,3}(-[A-Za-z0-9]{2,8})*$"
++ },
++ "site": {
++ "type": "string",
++ "maxLength": 253,
++ "pattern": "^[a-z0-9.-]+$",
++ "description": "web: results from this host only."
++ }
++ }
++ },
++ "description": "Narrow the network and mine scopes (never widen what the caller may see)."
++ },
++ {
++ "name": "freshness",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "enum": [
++ "any",
++ "day",
++ "week",
++ "month",
++ "year"
++ ],
++ "default": "any",
++ "description": "How recent results must be, where the source dates them."
++ },
++ "description": "How recent results must be, where the source dates them."
++ },
++ {
++ "name": "depth",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "enum": [
++ "quick",
++ "standard",
++ "deep"
++ ],
++ "default": "standard",
++ "description": "quick: indexes and caches only (no paid provider); standard: the ladder until a step answers; deep: every step, merged."
++ },
++ "description": "quick: indexes and caches only (no paid provider); standard: the ladder until a step answers; deep: every step, merged."
++ },
++ {
++ "name": "answer",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "boolean",
++ "default": false,
++ "description": "Ask for a short cited answer written by AI from the results. Never without citations; labelled AI. A deployment may decline (answer: null, with the reason in route.explain)."
++ },
++ "description": "Ask for a short cited answer written by AI from the results. Never without citations; labelled AI. A deployment may decline (answer: null, with the reason in route.explain)."
++ },
++ {
++ "name": "limit",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "integer",
++ "minimum": 1,
++ "maximum": 50,
++ "default": 20
++ }
++ },
++ {
++ "name": "cursor",
++ "in": "query",
++ "required": false,
++ "schema": {
++ "type": "string",
++ "maxLength": 512,
++ "description": "next_cursor of the previous page (network and mine only)."
++ },
++ "description": "next_cursor of the previous page (network and mine only)."
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/search.fabric-result.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
"/api/v1/search": {
"get": {
"operationId": "get_api_v1_search",
@@@ -865,6 +1297,402 @@
}
]
},
++ "search.fabric-request.v1": {
++ "title": "SearchFabricRequest",
++ "description": "search.fabric-request@1: the body of POST /api/v1/query (or the query string of GET /api/v1/query, scopes comma-separated), capability search.fabric.query. One search over several scopes, routed the cheapest way that answers (plan 2026-10-28 §4.5). network: Search's own index, permission-aware exactly as search.query.run; mine: the caller's own private documents (a signed-in person, or a service with X-OV-Subject); web: OpenVibe's open index first, then paid providers in a ladder, each result keeping its provider, date and URL. Providers never receive an account identifier. A scope the caller may not use (mine without a person; web's paid providers for an anonymous caller, who gets cached and open-index results only) is reported in route.explain, never an error. The other scopes are facets of the same indexes and are accepted for forward compatibility; v1 answers them as network results filtered by kind.",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "q"
++ ],
++ "properties": {
++ "q": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 200,
++ "description": "What to find."
++ },
++ "scopes": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 10,
++ "uniqueItems": true,
++ "items": {
++ "enum": [
++ "network",
++ "mine",
++ "web",
++ "news",
++ "images",
++ "video",
++ "products",
++ "people",
++ "places",
++ "code"
++ ]
++ },
++ "default": [
++ "network"
++ ],
++ "description": "Where to look; results are grouped by scope. Default: network."
++ },
++ "filters": {
++ "type": "object",
++ "additionalProperties": false,
++ "description": "Narrow the network and mine scopes (never widen what the caller may see).",
++ "properties": {
++ "owner": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_-]{0,31}$"
++ },
++ "type": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_-]{0,31}$"
++ },
++ "lang": {
++ "type": "string",
++ "pattern": "^[a-zA-Z]{2,3}(-[A-Za-z0-9]{2,8})*$"
++ },
++ "site": {
++ "type": "string",
++ "maxLength": 253,
++ "pattern": "^[a-z0-9.-]+$",
++ "description": "web: results from this host only."
++ }
++ }
++ },
++ "freshness": {
++ "enum": [
++ "any",
++ "day",
++ "week",
++ "month",
++ "year"
++ ],
++ "default": "any",
++ "description": "How recent results must be, where the source dates them."
++ },
++ "depth": {
++ "enum": [
++ "quick",
++ "standard",
++ "deep"
++ ],
++ "default": "standard",
++ "description": "quick: indexes and caches only (no paid provider); standard: the ladder until a step answers; deep: every step, merged."
++ },
++ "answer": {
++ "type": "boolean",
++ "default": false,
++ "description": "Ask for a short cited answer written by AI from the results. Never without citations; labelled AI. A deployment may decline (answer: null, with the reason in route.explain)."
++ },
++ "limit": {
++ "type": "integer",
++ "minimum": 1,
++ "maximum": 50,
++ "default": 20
++ },
++ "cursor": {
++ "type": "string",
++ "maxLength": 512,
++ "description": "next_cursor of the previous page (network and mine only)."
++ }
++ }
++ },
++ "search.fabric-result.v1": {
++ "title": "SearchFabricResult",
++ "description": "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).",
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "results",
++ "groups",
++ "route",
++ "next_cursor"
++ ],
++ "properties": {
++ "results": {
++ "type": "array",
++ "maxItems": 100,
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "scope",
++ "kind",
++ "title",
++ "url"
++ ],
++ "properties": {
++ "scope": {
++ "enum": [
++ "network",
++ "mine",
++ "web",
++ "news",
++ "images",
++ "video",
++ "products",
++ "people",
++ "places",
++ "code"
++ ]
++ },
++ "kind": {
++ "enum": [
++ "document",
++ "page"
++ ],
++ "description": "document: in Search's index (owner, type, id set); page: a web page (provider set)."
++ },
++ "title": {
++ "type": "string",
++ "maxLength": 300
++ },
++ "url": {
++ "type": "string",
++ "maxLength": 2048,
++ "format": "uri"
++ },
++ "snippet": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 600,
++ "description": "Plain text; never HTML."
++ },
++ "site": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 253
++ },
++ "image": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 2048
++ },
++ "published_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 40
++ },
++ "retrieved_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 40,
++ "description": "When a web page was read (by the provider or the open index)."
++ },
++ "provider": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 40,
++ "description": "page: who found it (open_index, deepseek, wikipedia, brave, …)."
++ },
++ "owner": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 32
++ },
++ "type": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 32
++ },
++ "id": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 200
++ },
++ "score": {
++ "type": [
++ "number",
++ "null"
++ ],
++ "description": "Rank within its scope (higher first); not comparable across scopes."
++ }
++ }
++ }
++ },
++ "groups": {
++ "type": "object",
++ "additionalProperties": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "description": "How many results each scope gave on this page."
++ },
++ "answer": {
++ "type": [
++ "object",
++ "null"
++ ],
++ "additionalProperties": false,
++ "required": [
++ "text",
++ "citations",
++ "label"
++ ],
++ "properties": {
++ "text": {
++ "type": "string",
++ "maxLength": 2000
++ },
++ "citations": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 20,
++ "items": {
++ "type": "integer",
++ "minimum": 1
++ }
++ },
++ "label": {
++ "const": "Written by AI from these sources"
++ }
++ }
++ },
++ "citations": {
++ "type": "array",
++ "maxItems": 20,
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "n",
++ "url",
++ "title"
++ ],
++ "properties": {
++ "n": {
++ "type": "integer",
++ "minimum": 1
++ },
++ "url": {
++ "type": "string",
++ "maxLength": 2048
++ },
++ "title": {
++ "type": "string",
++ "maxLength": 300
++ },
++ "provider": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 40
++ },
++ "retrieved_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 40
++ }
++ }
++ }
++ },
++ "route": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "explain",
++ "cost_usd"
++ ],
++ "properties": {
++ "explain": {
++ "type": "array",
++ "maxItems": 20,
++ "items": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "scope",
++ "step",
++ "ok"
++ ],
++ "properties": {
++ "scope": {
++ "enum": [
++ "network",
++ "mine",
++ "web",
++ "news",
++ "images",
++ "video",
++ "products",
++ "people",
++ "places",
++ "code"
++ ]
++ },
++ "step": {
++ "type": "string",
++ "maxLength": 40,
++ "description": "index, open_index, cache, deepseek, wikipedia, …"
++ },
++ "ok": {
++ "type": "boolean"
++ },
++ "count": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "ms": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "cached": {
++ "type": "boolean"
++ },
++ "cost_usd": {
++ "type": "number",
++ "minimum": 0
++ },
++ "skipped": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 160,
++ "description": "Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down)."
++ }
++ }
++ }
++ },
++ "cost_usd": {
++ "type": "number",
++ "minimum": 0,
++ "description": "What this query cost OpenVibe (paid provider calls; cached answers cost 0)."
++ }
++ }
++ },
++ "next_cursor": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "maxLength": 512
++ }
++ }
++ },
"search.index-document.v1": {
"title": "IndexDocument",
"description": "What an owning service tells OpenVibe.Search about one of its resources (roadmap §15.12, §4.2 A). The owner stays the source of truth; Search keeps a revision-ordered, permission-aware copy for discovery. A document with deleted=true is a tombstone: it removes the resource from every result and wins over any upsert with the same or an older revision.",
ddiff --git a/generated/openapi/services.json b/generated/openapi/services.json
iindex 24d5f491..37d91016 100644
---- a/generated/openapi/services.json
++++ b/generated/openapi/services.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Services API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/sources.json b/generated/openapi/sources.json
iindex 658f5da6..5ce266ed 100644
---- a/generated/openapi/sources.json
++++ b/generated/openapi/sources.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Sources API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/space.json b/generated/openapi/space.json
iindex 27d0051f..2896c7da 100644
---- a/generated/openapi/space.json
++++ b/generated/openapi/space.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Space API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Space as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/tips.json b/generated/openapi/tips.json
iindex 0d5daa77..c9759891 100644
---- a/generated/openapi/tips.json
++++ b/generated/openapi/tips.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Tips API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/tools.json b/generated/openapi/tools.json
iindex 6b7ef632..af6f2bfb 100644
---- a/generated/openapi/tools.json
++++ b/generated/openapi/tools.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Tools API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/trade.json b/generated/openapi/trade.json
iindex eebb999b..dff05a6a 100644
---- a/generated/openapi/trade.json
++++ b/generated/openapi/trade.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Trade API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/vip.json b/generated/openapi/vip.json
iindex fa604144..20369038 100644
---- a/generated/openapi/vip.json
++++ b/generated/openapi/vip.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.VIP API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/watch.json b/generated/openapi/watch.json
iindex 5a1bde75..156f0102 100644
---- a/generated/openapi/watch.json
++++ b/generated/openapi/watch.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Watch API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/wiki.json b/generated/openapi/wiki.json
iindex 712b6f1a..dc069d47 100644
---- a/generated/openapi/wiki.json
++++ b/generated/openapi/wiki.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Wiki API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/work.json b/generated/openapi/work.json
iindex 7ff12902..c1eac995 100644
---- a/generated/openapi/work.json
++++ b/generated/openapi/work.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Work API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Work as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/zone.json b/generated/openapi/zone.json
iindex adb425ae..6dfa8bea 100644
---- a/generated/openapi/zone.json
++++ b/generated/openapi/zone.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Zone API",
-- "version": "0.224.0",
-- "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.224.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.225.0",
++ "description": "Routes of OpenVibe.Zone as the OpenVibe contracts describe them (openvibe-contracts 0.225.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/typescript/index.d.ts b/generated/typescript/index.d.ts
iindex 1866f250..d2a510c8 100644
---- a/generated/typescript/index.d.ts
++++ b/generated/typescript/index.d.ts
@@@ -6134,6 +6134,5275 @@ export interface SearchQueryResult {
};
}
++/** [email protected] (owner: search) */
++/**
++ * search.fabric-request@1: the body of POST /api/v1/query (or the query string of GET /api/v1/query, scopes comma-separated), capability search.fabric.query. One search over several scopes, routed the cheapest way that answers (plan 2026-10-28 §4.5). network: Search's own index, permission-aware exactly as search.query.run; mine: the caller's own private documents (a signed-in person, or a service with X-OV-Subject); web: OpenVibe's open index first, then paid providers in a ladder, each result keeping its provider, date and URL. Providers never receive an account identifier. A scope the caller may not use (mine without a person; web's paid providers for an anonymous caller, who gets cached and open-index results only) is reported in route.explain, never an error. The other scopes are facets of the same indexes and are accepted for forward compatibility; v1 answers them as network results filtered by kind.
++ */
++export interface SearchFabricRequest {
++ /**
++ * What to find.
++ */
++ q: string;
++ /**
++ * Where to look; results are grouped by scope. Default: network.
++ *
++ * @minItems 1
++ * @maxItems 10
++ */
++ scopes?:
++ | ["network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code"]
++ | [
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code"
++ ]
++ | [
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code"
++ ]
++ | [
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code"
++ ]
++ | [
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code"
++ ]
++ | [
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code"
++ ]
++ | [
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code"
++ ]
++ | [
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code"
++ ]
++ | [
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code"
++ ]
++ | [
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code"
++ ];
++ /**
++ * Narrow the network and mine scopes (never widen what the caller may see).
++ */
++ filters?: {
++ owner?: string;
++ type?: string;
++ lang?: string;
++ /**
++ * web: results from this host only.
++ */
++ site?: string;
++ };
++ /**
++ * How recent results must be, where the source dates them.
++ */
++ freshness?: "any" | "day" | "week" | "month" | "year";
++ /**
++ * quick: indexes and caches only (no paid provider); standard: the ladder until a step answers; deep: every step, merged.
++ */
++ depth?: "quick" | "standard" | "deep";
++ /**
++ * Ask for a short cited answer written by AI from the results. Never without citations; labelled AI. A deployment may decline (answer: null, with the reason in route.explain).
++ */
++ answer?: boolean;
++ limit?: number;
++ /**
++ * next_cursor of the previous page (network and mine only).
++ */
++ cursor?: string;
++}
++
++/** [email protected] (owner: search) */
++/**
++ * 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).
++ */
++export interface SearchFabricResult {
++ /**
++ * @maxItems 100
++ */
++ results: {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * document: in Search's index (owner, type, id set); page: a web page (provider set).
++ */
++ kind: "document" | "page";
++ title: string;
++ url: string;
++ /**
++ * Plain text; never HTML.
++ */
++ snippet?: string | null;
++ site?: string | null;
++ image?: string | null;
++ published_at?: string | null;
++ /**
++ * When a web page was read (by the provider or the open index).
++ */
++ retrieved_at?: string | null;
++ /**
++ * page: who found it (open_index, deepseek, wikipedia, brave, …).
++ */
++ provider?: string | null;
++ owner?: string | null;
++ type?: string | null;
++ id?: string | null;
++ /**
++ * Rank within its scope (higher first); not comparable across scopes.
++ */
++ score?: number | null;
++ }[];
++ /**
++ * How many results each scope gave on this page.
++ */
++ groups: {
++ [k: string]: number | undefined;
++ };
++ answer?: {
++ text: string;
++ /**
++ * @minItems 1
++ * @maxItems 20
++ */
++ citations:
++ | [number]
++ | [number, number]
++ | [number, number, number]
++ | [number, number, number, number]
++ | [number, number, number, number, number]
++ | [number, number, number, number, number, number]
++ | [number, number, number, number, number, number, number]
++ | [number, number, number, number, number, number, number, number]
++ | [number, number, number, number, number, number, number, number, number]
++ | [number, number, number, number, number, number, number, number, number, number]
++ | [number, number, number, number, number, number, number, number, number, number, number]
++ | [number, number, number, number, number, number, number, number, number, number, number, number]
++ | [number, number, number, number, number, number, number, number, number, number, number, number, number]
++ | [number, number, number, number, number, number, number, number, number, number, number, number, number, number]
++ | [
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number
++ ]
++ | [
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number
++ ]
++ | [
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number
++ ]
++ | [
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number
++ ]
++ | [
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number
++ ]
++ | [
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number,
++ number
++ ];
++ label: "Written by AI from these sources";
++ } | null;
++ /**
++ * @maxItems 20
++ */
++ citations?:
++ | []
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ]
++ | [
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ },
++ {
++ n: number;
++ url: string;
++ title: string;
++ provider?: string | null;
++ retrieved_at?: string | null;
++ }
++ ];
++ route: {
++ /**
++ * @maxItems 20
++ */
++ explain:
++ | []
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ]
++ | [
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ },
++ {
++ scope: "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code";
++ /**
++ * index, open_index, cache, deepseek, wikipedia, …
++ */
++ step: string;
++ ok: boolean;
++ count?: number;
++ ms?: number;
++ cached?: boolean;
++ cost_usd?: number;
++ /**
++ * Why the step did not run (not allowed for this caller, quick depth, an earlier step answered, provider standing down).
++ */
++ skipped?: string | null;
++ }
++ ];
++ /**
++ * What this query cost OpenVibe (paid provider calls; cached answers cost 0).
++ */
++ cost_usd: number;
++ };
++ next_cursor: string | null;
++}
++
++/** [email protected] (owner: search) */
++/**
++ * search.provider-offer@1: one web search provider as the Search Fabric's ladder and Route see it (GET /api/v1/query/providers, capability search.fabric.query): what it covers, what it costs, whether it is usable now and how it has answered. Prices are the vendor's published ones as of checked_at; nothing here is a secret.
++ */
++export interface SearchProviderOffer {
++ provider: string;
++ name?: string;
++ /**
++ * @minItems 1
++ */
++ scopes: [
++ "network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code",
++ ...("network" | "mine" | "web" | "news" | "images" | "video" | "products" | "people" | "places" | "code")[]
++ ];
++ price_usd_per_call: number;
++ /**
++ * Searches its own crawl rather than reselling another engine's.
++ */
++ independent_index?: boolean;
++ /**
++ * Configured and not standing down (balance, key, rate limit, daily cap).
++ */
++ available: boolean;
++ reason?: string | null;
++ daily_cap?: number | null;
++ used_today?: number | null;
++ latency_ms_p50?: number | null;
++ /**
++ * Share of calls in the last day that returned at least one result.
++ */
++ answered_rate?: number | null;
++ terms_url?: string | null;
++ checked_at: string;
++}
++
/** [email protected] (owner: search) */
/**
* search.write-result@1: the answer of PUT /api/v1/documents/:owner/:type/:id (search.document.write). applied: stored (or a tombstone recorded); unchanged: the same revision with the same content. A revision older than the stored one is a 409 problem search.stale_revision; the same revision with different content is 409 search.revision_conflict.
ddiff --git a/manifests/capabilities/search.fabric.query.json b/manifests/capabilities/search.fabric.query.json
nnew file mode 100644
iindex 00000000..257d2dcc
---- /dev/null
++++ b/manifests/capabilities/search.fabric.query.json
@@@ -0,0 +1,23 @@
++{
++ "id": "search.fabric.query",
++ "version": "1.0",
++ "owner": "search",
++ "status": "active",
++ "visibility": "public",
++ "description": "One search over several scopes (plan 2026-10-28 \u00a74.5, the Search Fabric): network (Search's index, permission-aware as search.query.run), mine (the person's own private documents), web (OpenVibe's open index, then paid providers in a ladder, cached), with route.explain saying what answered and what it cost. Anonymous callers get network results and web results from the open index and the cache; a signed-in person or a first-party service (X-OV-Subject for mine) also reaches paid providers within OpenVibe's daily caps. Providers never receive an account identifier. The same operation is the SDK's createSearchClient().query() and the MCP tool openvibe.search.",
++ "permissions": [
++ "search:read"
++ ],
++ "resourceConstraints": [
++ "none"
++ ],
++ "quotaClass": "search-query",
++ "events": [],
++ "implementedBy": [
++ "POST /api/v1/query",
++ "GET /api/v1/query",
++ "GET /api/v1/query/providers"
++ ],
++ "inputSchema": "search.fabric-request@1",
++ "outputSchema": "search.fabric-result@1"
++}
ddiff --git a/manifests/services/search.json b/manifests/services/search.json
iindex 0f760c8f..64a4cb3b 100644
---- a/manifests/services/search.json
++++ b/manifests/services/search.json
@@@ -21,6 +21,7 @@
},
"capabilities": [
"search.document.write",
++ "search.fabric.query",
"search.query.delegate",
"search.query.run"
],
@@@ -73,7 +74,7 @@
],
"window": "automatic only while ovhost waits for readiness after the restart (30 s in host.example.json); manual afterwards, as long as no blocker applies",
"blockers": {
-- "none": "the schema code only adds (CREATE … IF NOT EXISTS, ADD COLUMN; no DROP, RENAME or table rebuild), which an older release ignores"
++ "none": "the schema code only adds (CREATE \u2026 IF NOT EXISTS, ADD COLUMN; no DROP, RENAME or table rebuild), which an older release ignores"
}
},
"contracts": {
ddiff --git a/package.json b/package.json
iindex 4086c483..a6d78efb 100644
---- a/package.json
++++ b/package.json
@@@ -1,6 +1,6 @@
{
"name": "openvibe-contracts",
-- "version": "0.224.0",
++ "version": "0.225.0",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"main": "index.js",
"types": "generated/typescript/index.d.ts",