Skip to main content
Glama

Filter financial news

alphai_news_search
Read-onlyIdempotent

Search financial news by text or structured filters. Inspect query_interpretation and search_match: broadened results match only some terms; unresolved mode is a general-feed fallback. Explicit tickers/category are hard filters. query/q cannot use sort='ingested'. Default order without query is newest publication first. In ingested mode, collapse_stories=true returns story roots and source counts, not later member updates. For tickerless macro use categories or alphai_macro. Crypto uses -USD; bare stock/ETF symbols keep their equity meaning. Use detail='compact' for headlines, sources, times, tickers, scores and story/search metadata without summary, analysis or SEC detail blocks. Expand uids with alphai_article. detail='full' is default; selection, order, cursors and page metadata are identical. In ingested mode, prime may be partial/empty and starts at the feed head. Resume until empty success; short pages can continue. Empty pages still spend quota: back off after one and filter (min_relevance, symbol). Errors are JSON: delta_scan_incomplete means use extra.next_cursor with unchanged filters/sort; delta_candidates_changed means retry the original request.

Tool call template

This tool declares no required parameters. Add optional parameters from the input schema as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {},
    "name": "alphai_news_search"
  }
}

Input Schema

NameRequiredDescriptionDefault
qNoAlias for query.
itemNo8-K item code (e.g. '5.02', '8.01', '1.01'): keep only 8-K filings carrying it — any item of the filing. Implies source_type=['sec_form8k']; any other source_type is an error.
sortNopublished (default): newest first, next_cursor pages into older history. ingested: delta polling — rows in the order they became available, ascending; next_cursor is always returned (empty items = caught up, keep the cursor and poll later); time_published is not monotonic within a page. A cursor only works with the sort mode that issued it. With ingested, to_date must not be in the past.
limitNoAlias for page_size.
queryNoFull-text query over article titles, named entities and summaries (company names, people, topics, tickers), up to 200 characters; how it was read comes back in query_interpretation.
cursorNoOpaque cursor from a prior next_cursor.
detailNofull (default): existing item format. compact: headlines, sources, times, tickers, scores and story/search metadata without summary or analysis. Prefer compact for polling; alphai_article(uid) expands an item.full
tickersNoRestrict to news mentioning these tickers (up to 50 symbols; duplicates are ignored).
to_dateNoNews on/before this ISO time (UTC if naive). A bare date (2026-06-01) covers that WHOLE day, so from_date=to_date=<day> returns the day — same reading as REST /api/news/.
categoryNoRestrict to one news category.
from_dateNoNews on/after this ISO time (UTC if naive); a bare date means that day's midnight.
page_sizeNoItems/page; capped at 20 Free/Basic, 50 Pro.
source_typeNoRestrict to these ingest sources (OR): gdelt = press coverage, sec_form4 = insider transactions, sec_form8k = 8-K current reports, sec_form6k = foreign issuers' 6-K earnings releases.
min_relevanceNoMinimum AI relevance score, 1-10. Default 4 leaves out low-relevance items; 1-3 adds them.
collapse_storiesNoCollapse coverage of the same event — syndicated reprints and independently written articles — to one representative per story and populate story_id/sources_count/sources (default false).

Output Schema

NameRequiredDescriptionDefault
countNo
itemsNo
delistedNo
renamed_toNo
next_cursorNo
ticker_noteNo
unknown_tickerNo
query_interpretationNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedInput schema / properties / category / anyOf
      Previous value: -[
      -  {
      -    "description": "Article category assigned by the enricher. Must match the backend.",
      -    "enum": [
      -      "earnings",
      -      "mergers_acquisitions",
      -      "regulation",
      -      "macro_economy",
      -      "sector_analysis",
      -      "market_movers",
      -      "technology",
      -      "commodities",
      -      "crypto",
      -      "ipo",
      -      "geopolitics",
      -      "insider",
      -      "corporate_actions",
      -      "other"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "description": "The article's news category, one of 14.",
      +    "enum": [
      +      "earnings",
      +      "mergers_acquisitions",
      +      "regulation",
      +      "macro_economy",
      +      "sector_analysis",
      +      "market_movers",
      +      "technology",
      +      "commodities",
      +      "crypto",
      +      "ipo",
      +      "geopolitics",
      +      "insider",
      +      "corporate_actions",
      +      "other"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedOutput schema / properties / query_interpretation / anyOf
      Previous value: -[
      -  {
      -    "description": "How ``alphai_news_search`` read a free-text ``query`` — the echo that makes\na resolver miss legible. Before it, a query read as the wrong company or\ndiscarded entirely came back indistinguishable from a hit\n(issues/2026-08-16-freetext-query-resolves-jane-street-to-janl.md).\n\n``mode``: ``searched`` — the text search served the items\n(``NEWS_SEARCH_MODE=on``, the normal state since 2026-09-23): ``search``\nsays what selected them, ``tickers``/``category`` only say what the words\nwere ALSO read as (reference, never a filter) and ``ignored_terms`` is\nempty, because nothing was ignored — the whole text was searched. Before\nthis (review finding 1a/1b, 2026-09-23) the text path echoed the\nresolver's ``resolved`` + its ``ignored_terms`` next to a ``search`` block\nwhose ``terms`` were those very words, and a read category looked applied\nwhile nothing but the text filtered the items. The resolver modes describe\nthe fallback when the text search is switched off: ``resolved`` — at least\none query word became a filter that is applied to the items;\n``overridden`` — the query resolved, but explicit ``tickers``/``category``\nreplaced every filter it produced; ``unresolved`` — no query word matched a\nticker, company name or topic word, so the items are NOT matches for the\nquery (``note`` says what they are instead). ``ignored_terms`` then lists\nthe content words that matched nothing; stopwords are dropped silently.\n``note`` is one or two plain sentences an agent can act on, same role as\n``ticker_note``.",
      -    "properties": {
      -      "category": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null
      -      },
      -      "category_term": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null
      -      },
      -      "ignored_terms": {
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "mode": {
      -        "enum": [
      -          "searched",
      -          "resolved",
      -          "overridden",
      -          "unresolved"
      -        ],
      -        "type": "string"
      -      },
      -      "note": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "search": {
      -        "anyOf": [
      -          {
      -            "description": "How the text search read the query (docs/HYBRID_NEWS_SEARCH_PLAN.md\nstep 2): ``strict`` = every term required; ``broadened`` = fewer strict\nmatches than the threshold, so the most common words were dropped first\nand every item carries at least two of the terms; ``no_match``;\n``no_terms``. ``sort`` is ``published`` when every term is a very common\nword (newest matches, not best). ``terms`` are the normalized words that\nwere searched. ``required_terms`` is filled only when the search reports\nwhich words every broadened row had to carry (the current engine does\nnot) — ``search_match.terms_matched`` on each item is the count to trust.\n``matched`` is the engine's capped estimate of matching rows, counted\nbefore the visibility strip, never a global total. Which engine answered is NOT part of\nthe contract: it goes to the search log (``ranking_version``). The\n``engine`` field that shipped with 1.41.0 was read by an external review\nas an implementation leak, and it was one — a client has no action on\n\"meilisearch\" (issues/2026-09-23-news-search-review-triage.md).",
      -            "properties": {
      -              "matched": {
      -                "default": 0,
      -                "type": "integer"
      -              },
      -              "mode": {
      -                "enum": [
      -                  "strict",
      -                  "broadened",
      -                  "no_match",
      -                  "no_terms"
      -                ],
      -                "type": "string"
      -              },
      -              "optional_terms": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "required_terms": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "sort": {
      -                "enum": [
      -                  "relevance",
      -                  "published"
      -                ],
      -                "type": "string"
      -              },
      -              "terms": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "window_from": {
      -                "anyOf": [
      -                  {
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "default": null
      -              }
      -            },
      -            "required": [
      -              "mode",
      -              "sort"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null
      -      },
      -      "tickers": {
      -        "items": {
      -          "description": "One ticker a free-text ``query`` resolved to (docs/HYBRID_NEWS_SEARCH_PLAN.md\nstep 1). ``name`` is the issuer's registered name, so an agent can see that\n\"PMI\" was read as Picard Medical rather than the ISM purchasing-managers\nindex; ``term`` is the query word that produced it (share-class siblings\ninherit the seed word's term).",
      -          "properties": {
      -            "name": {
      -              "anyOf": [
      -                {
      -                  "type": "string"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ],
      -              "default": null
      -            },
      -            "term": {
      -              "type": "string"
      -            },
      -            "ticker": {
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "ticker",
      -            "term"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      }
      -    },
      -    "required": [
      -      "mode"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "description": "How ``alphai_news_search`` read a free-text ``query``, so that a query read\nas the wrong company, or not matched at all, is visible instead of looking\nlike a hit.\n\n``mode``: ``searched`` — the text search served the items: ``search`` says\nwhat selected them, ``tickers``/``category`` only say what the words were\nALSO read as (reference, never a filter) and ``ignored_terms`` is empty,\nbecause the whole text was searched. The other modes apply when the text\nsearch is unavailable and the query is resolved to filters instead:\n``resolved`` — at least\none query word became a filter that is applied to the items;\n``overridden`` — the query resolved, but explicit ``tickers``/``category``\nreplaced every filter it produced; ``unresolved`` — no query word matched a\nticker, company name or topic word, so the items are NOT matches for the\nquery (``note`` says what they are instead). ``ignored_terms`` then lists\nthe content words that matched nothing; stopwords are dropped silently.\n``note`` is one or two plain sentences an agent can act on, same role as\n``ticker_note``.",
      +    "properties": {
      +      "category": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "category_term": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "ignored_terms": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "mode": {
      +        "enum": [
      +          "searched",
      +          "resolved",
      +          "overridden",
      +          "unresolved"
      +        ],
      +        "type": "string"
      +      },
      +      "note": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "search": {
      +        "anyOf": [
      +          {
      +            "description": "How the text search read the query. ``mode``: ``strict`` = every term\nrequired; ``broadened`` = too few strict matches, so the most common words\nwere dropped first and every item carries at least two of the terms;\n``no_match``; ``no_terms``. ``sort`` is ``published`` when every term is a\nvery common word (newest matches, not best). ``terms`` are the normalized\nwords that were searched. ``required_terms`` lists the words every\nbroadened item had to carry, when the search reports them;\n``search_match.terms_matched`` on each item is the count to trust.\n``matched`` is a capped estimate of matching items, counted before the\nfeed's own filters, never a global total.",
      +            "properties": {
      +              "matched": {
      +                "default": 0,
      +                "type": "integer"
      +              },
      +              "mode": {
      +                "enum": [
      +                  "strict",
      +                  "broadened",
      +                  "no_match",
      +                  "no_terms"
      +                ],
      +                "type": "string"
      +              },
      +              "optional_terms": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "required_terms": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "sort": {
      +                "enum": [
      +                  "relevance",
      +                  "published"
      +                ],
      +                "type": "string"
      +              },
      +              "terms": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "window_from": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              }
      +            },
      +            "required": [
      +              "mode",
      +              "sort"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "tickers": {
      +        "items": {
      +          "description": "One ticker a free-text ``query`` resolved to. ``name`` is the issuer's registered name, so an agent can see that\n\"PMI\" was read as Picard Medical rather than the ISM purchasing-managers\nindex; ``term`` is the query word that produced it (share-class siblings\ninherit the seed word's term).",
      +          "properties": {
      +            "name": {
      +              "anyOf": [
      +                {
      +                  "type": "string"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ],
      +              "default": null
      +            },
      +            "term": {
      +              "type": "string"
      +            },
      +            "ticker": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "ticker",
      +            "term"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "mode"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  2. Changed1 schema field changed
    • changedOutput schema / properties / query_interpretation / anyOf
      Previous value: -[
      -  {
      -    "description": "How ``alphai_news_search`` read a free-text ``query`` — the echo that makes\na resolver miss legible. Before it, a query read as the wrong company or\ndiscarded entirely came back indistinguishable from a hit\n(issues/2026-08-16-freetext-query-resolves-jane-street-to-janl.md).\n\n``mode``: ``searched`` — the text search served the items\n(``NEWS_SEARCH_MODE=on``, the normal state since 2026-09-23): ``search``\nsays what selected them, ``tickers``/``category`` only say what the words\nwere ALSO read as (reference, never a filter) and ``ignored_terms`` is\nempty, because nothing was ignored — the whole text was searched. Before\nthis (review finding 1a/1b, 2026-09-23) the text path echoed the\nresolver's ``resolved`` + its ``ignored_terms`` next to a ``search`` block\nwhose ``terms`` were those very words, and a read category looked applied\nwhile nothing but the text filtered the items. The resolver modes describe\nthe fallback when the text search is switched off: ``resolved`` — at least\none query word became a filter that is applied to the items;\n``overridden`` — the query resolved, but explicit ``tickers``/``category``\nreplaced every filter it produced; ``unresolved`` — no query word matched a\nticker, company name or topic word, so the items are NOT matches for the\nquery (``note`` says what they are instead). ``ignored_terms`` then lists\nthe content words that matched nothing; stopwords are dropped silently.\n``note`` is one or two plain sentences an agent can act on, same role as\n``ticker_note``.",
      -    "properties": {
      -      "category": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null
      -      },
      -      "category_term": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null
      -      },
      -      "ignored_terms": {
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "mode": {
      -        "enum": [
      -          "searched",
      -          "resolved",
      -          "overridden",
      -          "unresolved"
      -        ],
      -        "type": "string"
      -      },
      -      "note": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "search": {
      -        "anyOf": [
      -          {
      -            "description": "How the text search read the query (docs/HYBRID_NEWS_SEARCH_PLAN.md\nstep 2): ``strict`` = every term required; ``broadened`` = fewer strict\nmatches than the threshold, so the most common words were dropped first\nand every item carries at least two of the terms; ``no_match``;\n``no_terms``. ``sort`` is ``published`` when every term is a very common\nword (newest matches, not best). ``terms`` are the normalized words that\nwere searched. ``required_terms`` is filled only when the search reports\nwhich words every broadened row had to carry (the Postgres path does, the\nengine does not) — ``search_match.terms_matched`` on each item is the\ncount to trust. ``matched`` counts the visible matches inside the bounded\ncandidate set, never a global total. Which engine answered is NOT part of\nthe contract: it goes to the search log (``ranking_version``). The\n``engine`` field that shipped with 1.41.0 was read by an external review\nas an implementation leak, and it was one — a client has no action on\n\"meilisearch\" (issues/2026-09-23-news-search-review-triage.md).",
      -            "properties": {
      -              "matched": {
      -                "default": 0,
      -                "type": "integer"
      -              },
      -              "mode": {
      -                "enum": [
      -                  "strict",
      -                  "broadened",
      -                  "no_match",
      -                  "no_terms"
      -                ],
      -                "type": "string"
      -              },
      -              "optional_terms": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "required_terms": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "sort": {
      -                "enum": [
      -                  "relevance",
      -                  "published"
      -                ],
      -                "type": "string"
      -              },
      -              "terms": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "window_from": {
      -                "anyOf": [
      -                  {
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "default": null
      -              }
      -            },
      -            "required": [
      -              "mode",
      -              "sort"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null
      -      },
      -      "tickers": {
      -        "items": {
      -          "description": "One ticker a free-text ``query`` resolved to (docs/HYBRID_NEWS_SEARCH_PLAN.md\nstep 1). ``name`` is the issuer's registered name, so an agent can see that\n\"PMI\" was read as Picard Medical rather than the ISM purchasing-managers\nindex; ``term`` is the query word that produced it (share-class siblings\ninherit the seed word's term).",
      -          "properties": {
      -            "name": {
      -              "anyOf": [
      -                {
      -                  "type": "string"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ],
      -              "default": null
      -            },
      -            "term": {
      -              "type": "string"
      -            },
      -            "ticker": {
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "ticker",
      -            "term"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      }
      -    },
      -    "required": [
      -      "mode"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "description": "How ``alphai_news_search`` read a free-text ``query`` — the echo that makes\na resolver miss legible. Before it, a query read as the wrong company or\ndiscarded entirely came back indistinguishable from a hit\n(issues/2026-08-16-freetext-query-resolves-jane-street-to-janl.md).\n\n``mode``: ``searched`` — the text search served the items\n(``NEWS_SEARCH_MODE=on``, the normal state since 2026-09-23): ``search``\nsays what selected them, ``tickers``/``category`` only say what the words\nwere ALSO read as (reference, never a filter) and ``ignored_terms`` is\nempty, because nothing was ignored — the whole text was searched. Before\nthis (review finding 1a/1b, 2026-09-23) the text path echoed the\nresolver's ``resolved`` + its ``ignored_terms`` next to a ``search`` block\nwhose ``terms`` were those very words, and a read category looked applied\nwhile nothing but the text filtered the items. The resolver modes describe\nthe fallback when the text search is switched off: ``resolved`` — at least\none query word became a filter that is applied to the items;\n``overridden`` — the query resolved, but explicit ``tickers``/``category``\nreplaced every filter it produced; ``unresolved`` — no query word matched a\nticker, company name or topic word, so the items are NOT matches for the\nquery (``note`` says what they are instead). ``ignored_terms`` then lists\nthe content words that matched nothing; stopwords are dropped silently.\n``note`` is one or two plain sentences an agent can act on, same role as\n``ticker_note``.",
      +    "properties": {
      +      "category": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "category_term": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "ignored_terms": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "mode": {
      +        "enum": [
      +          "searched",
      +          "resolved",
      +          "overridden",
      +          "unresolved"
      +        ],
      +        "type": "string"
      +      },
      +      "note": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "search": {
      +        "anyOf": [
      +          {
      +            "description": "How the text search read the query (docs/HYBRID_NEWS_SEARCH_PLAN.md\nstep 2): ``strict`` = every term required; ``broadened`` = fewer strict\nmatches than the threshold, so the most common words were dropped first\nand every item carries at least two of the terms; ``no_match``;\n``no_terms``. ``sort`` is ``published`` when every term is a very common\nword (newest matches, not best). ``terms`` are the normalized words that\nwere searched. ``required_terms`` is filled only when the search reports\nwhich words every broadened row had to carry (the current engine does\nnot) — ``search_match.terms_matched`` on each item is the count to trust.\n``matched`` is the engine's capped estimate of matching rows, counted\nbefore the visibility strip, never a global total. Which engine answered is NOT part of\nthe contract: it goes to the search log (``ranking_version``). The\n``engine`` field that shipped with 1.41.0 was read by an external review\nas an implementation leak, and it was one — a client has no action on\n\"meilisearch\" (issues/2026-09-23-news-search-review-triage.md).",
      +            "properties": {
      +              "matched": {
      +                "default": 0,
      +                "type": "integer"
      +              },
      +              "mode": {
      +                "enum": [
      +                  "strict",
      +                  "broadened",
      +                  "no_match",
      +                  "no_terms"
      +                ],
      +                "type": "string"
      +              },
      +              "optional_terms": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "required_terms": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "sort": {
      +                "enum": [
      +                  "relevance",
      +                  "published"
      +                ],
      +                "type": "string"
      +              },
      +              "terms": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "window_from": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              }
      +            },
      +            "required": [
      +              "mode",
      +              "sort"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "tickers": {
      +        "items": {
      +          "description": "One ticker a free-text ``query`` resolved to (docs/HYBRID_NEWS_SEARCH_PLAN.md\nstep 1). ``name`` is the issuer's registered name, so an agent can see that\n\"PMI\" was read as Picard Medical rather than the ISM purchasing-managers\nindex; ``term`` is the query word that produced it (share-class siblings\ninherit the seed word's term).",
      +          "properties": {
      +            "name": {
      +              "anyOf": [
      +                {
      +                  "type": "string"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ],
      +              "default": null
      +            },
      +            "term": {
      +              "type": "string"
      +            },
      +            "ticker": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "ticker",
      +            "term"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "mode"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  3. Changed1 schema field changed
    • changedInput schema / properties / collapse_stories / description
      Previous value: -"Collapse syndicated reprints to one representative per story and populate story_id/sources_count/sources (default false)."New value: +"Collapse coverage of the same event — syndicated reprints and independently written articles — to one representative per story and populate story_id/sources_count/sources (default false)."
  4. Changed1 schema field changed
    • changedInput schema / properties / min_relevance / description
      Previous value: -"Minimum AI relevance score, 1-10."New value: +"Minimum AI relevance score, 1-10. Default 4 leaves out low-relevance items; 1-3 adds them."
  5. Changed1 schema field changed
    • changedInput schema / properties / sort / description
      Previous value: -"published (default): newest first, next_cursor pages into older history. ingested: delta polling — rows in the order they became available, ascending; next_cursor is always returned (empty items = caught up, keep the cursor and poll later); time_published is not monotonic within a page. A cursor only works with the sort mode that issued it."New value: +"published (default): newest first, next_cursor pages into older history. ingested: delta polling — rows in the order they became available, ascending; next_cursor is always returned (empty items = caught up, keep the cursor and poll later); time_published is not monotonic within a page. A cursor only works with the sort mode that issued it. With ingested, to_date must not be in the past."
  6. Changed5 schema fields changed
    • addedInput schema / properties / detail
      Added value: +{
      +  "default": "full",
      +  "description": "full (default): existing item format. compact: headlines, sources, times, tickers, scores and story/search metadata without summary or analysis. Prefer compact for polling; alphai_article(uid) expands an item.",
      +  "enum": [
      +    "full",
      +    "compact"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / items / items / anyOf
      Added value: +[
      +  {
      +    "properties": {
      +      "analysis": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "actionability": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              },
      +              "alternative_perspectives": {
      +                "anyOf": [
      +                  {
      +                    "properties": {
      +                      "contrarian_view": {
      +                        "anyOf": [
      +                          {
      +                            "type": "string"
      +                          },
      +                          {
      +                            "type": "null"
      +                          }
      +                        ],
      +                        "default": null
      +                      },
      +                      "overlooked_factors": {
      +                        "anyOf": [
      +                          {
      +                            "type": "string"
      +                          },
      +                          {
      +                            "type": "null"
      +                          }
      +                        ],
      +                        "default": null
      +                      }
      +                    },
      +                    "type": "object"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              },
      +              "background_context": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              },
      +              "indirect_market_effects": {
      +                "anyOf": [
      +                  {
      +                    "properties": {
      +                      "global_market_relevance": {
      +                        "anyOf": [
      +                          {
      +                            "type": "string"
      +                          },
      +                          {
      +                            "type": "null"
      +                          }
      +                        ],
      +                        "default": null
      +                      },
      +                      "regional_market_impact": {
      +                        "anyOf": [
      +                          {
      +                            "type": "string"
      +                          },
      +                          {
      +                            "type": "null"
      +                          }
      +                        ],
      +                        "default": null
      +                      },
      +                      "sector_implications": {
      +                        "anyOf": [
      +                          {
      +                            "type": "string"
      +                          },
      +                          {
      +                            "type": "null"
      +                          }
      +                        ],
      +                        "default": null
      +                      }
      +                    },
      +                    "type": "object"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              },
      +              "information_novelty": {
      +                "anyOf": [
      +                  {
      +                    "type": "integer"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              },
      +              "key_entities": {
      +                "items": {
      +                  "properties": {
      +                    "description": {
      +                      "default": "",
      +                      "type": "string"
      +                    },
      +                    "entity_type": {
      +                      "default": "",
      +                      "type": "string"
      +                    },
      +                    "name": {
      +                      "default": "",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "market_relevance_summary": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              },
      +              "market_sentiment_alignment": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              },
      +              "ticker_analysis": {
      +                "items": {
      +                  "properties": {
      +                    "confidence": {
      +                      "anyOf": [
      +                        {
      +                          "type": "string"
      +                        },
      +                        {
      +                          "type": "null"
      +                        }
      +                      ],
      +                      "default": null
      +                    },
      +                    "price_impact_prediction": {
      +                      "anyOf": [
      +                        {
      +                          "type": "string"
      +                        },
      +                        {
      +                          "type": "null"
      +                        }
      +                      ],
      +                      "default": null
      +                    },
      +                    "reasoning": {
      +                      "anyOf": [
      +                        {
      +                          "type": "string"
      +                        },
      +                        {
      +                          "type": "null"
      +                        }
      +                      ],
      +                      "default": null
      +                    },
      +                    "relevance_context": {
      +                      "anyOf": [
      +                        {
      +                          "type": "string"
      +                        },
      +                        {
      +                          "type": "null"
      +                        }
      +                      ],
      +                      "default": null
      +                    },
      +                    "sentiment": {
      +                      "anyOf": [
      +                        {
      +                          "type": "string"
      +                        },
      +                        {
      +                          "type": "null"
      +                        }
      +                      ],
      +                      "default": null
      +                    },
      +                    "ticker": {
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "ticker"
      +                  ],
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "timing_relevance": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "banner_image": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "category": {
      +        "type": "string"
      +      },
      +      "created_at": {
      +        "type": "string"
      +      },
      +      "earnings": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": true,
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "filing": {
      +        "anyOf": [
      +          {
      +            "description": "Structured SEC 8-K filing block (``source_type == \"sec_form8k\"`` items on\nthe news tools).\n\nA read-only projection of the 8-K sidecar\n(``apps.data.models.EightKEventModel``) — same fields and semantics as the\nREST ``/api/news/`` block (openapi.yaml: ``EightKFiling``): ``items`` is\nevery item code the filing carries (the ``item`` filter matches any of\nthem; empty for a header-only filing), ``primary_item`` the one that drove\nthe category, ``accession_number`` the id to cite, ``filed_at`` EDGAR's\nacceptance time, ``event_date`` the filing's own date of report and\n``exhibit_url`` the press-release exhibit the summary was built from.\nDates are ISO strings like the insider block; empty sidecar strings are\n``null``, never ``\"\"``.",
      +            "properties": {
      +              "accession_number": {
      +                "type": "string"
      +              },
      +              "event_date": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              },
      +              "exhibit_url": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              },
      +              "filed_at": {
      +                "type": "string"
      +              },
      +              "items": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "primary_item": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              }
      +            },
      +            "required": [
      +              "items",
      +              "accession_number",
      +              "filed_at"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "insider": {
      +        "anyOf": [
      +          {
      +            "description": "Structured SEC Form 4 event block (``alphai_insider_news`` items only).\n\nAggregate of the news row's whole transaction group — same semantics as the\nREST ``/api/news/insider/`` block (openapi.yaml: ``InsiderEvent``): shares and\nvalue are GROUP sums (a 10b5-1 ladder is one event), ``avg_price_usd`` is\nvalue-weighted over priced tranches, ``is_10b5_1`` is the group OR, the\nlast fill dates the event. ``side`` is the signal label: buy (P) / sell (S)\n/ other (everything else, incl. D — sale to issuer, a buyback/redemption,\nnot an open-market disposition); the raw ``transaction_code`` rides along.\nMoney/share fields are decimal STRINGS (\"25000\", \"187.32\") — flat, precise,\nschema-simple; null when the filing prices no tranche.\n\n``filed_at`` is when EDGAR accepted the filing and ``late_filing`` marks the\nones that missed the SEC's two-business-day deadline; the rule lives in\n``_is_late_filing`` in ``repository.py`` (ported from the backend's\n``apps.insider.services.filing_lateness``). Field reference for both\nsurfaces: ``backend/openapi.yaml`` (``InsiderEvent``).",
      +            "properties": {
      +              "avg_price_usd": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              },
      +              "filed_at": {
      +                "type": "string"
      +              },
      +              "insider_name": {
      +                "type": "string"
      +              },
      +              "insider_title": {
      +                "type": "string"
      +              },
      +              "is_10b5_1": {
      +                "type": "boolean"
      +              },
      +              "is_director": {
      +                "type": "boolean"
      +              },
      +              "is_officer": {
      +                "type": "boolean"
      +              },
      +              "is_ten_percent_owner": {
      +                "type": "boolean"
      +              },
      +              "late_filing": {
      +                "type": "boolean"
      +              },
      +              "shares": {
      +                "type": "string"
      +              },
      +              "side": {
      +                "type": "string"
      +              },
      +              "total_value_usd": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              },
      +              "transaction_code": {
      +                "type": "string"
      +              },
      +              "transaction_date": {
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "side",
      +              "transaction_code",
      +              "shares",
      +              "is_10b5_1",
      +              "insider_name",
      +              "insider_title",
      +              "is_officer",
      +              "is_director",
      +              "is_ten_percent_owner",
      +              "transaction_date",
      +              "filed_at",
      +              "late_filing"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "ownership_form": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "read_time_minutes": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "relevance_score": {
      +        "type": "integer"
      +      },
      +      "search_match": {
      +        "anyOf": [
      +          {
      +            "description": "Per-item evidence from the text path: ``score`` orders the page (cover\ndensity × recency; comparable within one response, not a probability),\n``terms_matched`` is set in broadened mode, ``context`` marks the matched\nwords in the summary with ``**``.",
      +            "properties": {
      +              "context": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              },
      +              "score": {
      +                "type": "number"
      +              },
      +              "terms_matched": {
      +                "anyOf": [
      +                  {
      +                    "type": "integer"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              }
      +            },
      +            "required": [
      +              "score"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "source": {
      +        "type": "string"
      +      },
      +      "source_domain": {
      +        "type": "string"
      +      },
      +      "source_type": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "sources": {
      +        "anyOf": [
      +          {
      +            "items": {
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "sources_count": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "story_id": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "summary": {
      +        "type": "string"
      +      },
      +      "tickers": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "time_published": {
      +        "type": "string"
      +      },
      +      "title": {
      +        "type": "string"
      +      },
      +      "uid": {
      +        "type": "string"
      +      },
      +      "url": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "uid",
      +      "title",
      +      "url",
      +      "source",
      +      "source_domain",
      +      "summary",
      +      "category",
      +      "relevance_score",
      +      "time_published",
      +      "created_at"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "description": "Opt-in feed projection. Expand ``uid`` with ``alphai_article``.\n\nOnly the two scalar analysis signals survive, at the top level. Summary,\nanalysis prose, images and SEC detail blocks are absent, not truncated.\nSearch evidence and Form 4 ownership remain so triage keeps its meaning.",
      +    "properties": {
      +      "actionability": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "category": {
      +        "type": "string"
      +      },
      +      "created_at": {
      +        "type": "string"
      +      },
      +      "information_novelty": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "ownership_form": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "relevance_score": {
      +        "type": "integer"
      +      },
      +      "search_match": {
      +        "anyOf": [
      +          {
      +            "description": "Per-item evidence from the text path: ``score`` orders the page (cover\ndensity × recency; comparable within one response, not a probability),\n``terms_matched`` is set in broadened mode, ``context`` marks the matched\nwords in the summary with ``**``.",
      +            "properties": {
      +              "context": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              },
      +              "score": {
      +                "type": "number"
      +              },
      +              "terms_matched": {
      +                "anyOf": [
      +                  {
      +                    "type": "integer"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              }
      +            },
      +            "required": [
      +              "score"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "source": {
      +        "type": "string"
      +      },
      +      "source_domain": {
      +        "type": "string"
      +      },
      +      "source_type": {
      +        "type": "string"
      +      },
      +      "sources": {
      +        "anyOf": [
      +          {
      +            "items": {
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "sources_count": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "story_id": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "tickers": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "time_published": {
      +        "type": "string"
      +      },
      +      "title": {
      +        "type": "string"
      +      },
      +      "uid": {
      +        "type": "string"
      +      },
      +      "url": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "uid",
      +      "title",
      +      "url",
      +      "source",
      +      "source_domain",
      +      "source_type",
      +      "time_published",
      +      "created_at",
      +      "tickers",
      +      "category",
      +      "relevance_score",
      +      "actionability",
      +      "information_novelty",
      +      "story_id",
      +      "sources_count",
      +      "sources",
      +      "ownership_form",
      +      "search_match"
      +    ],
      +    "type": "object"
      +  }
      +]
    • removedOutput schema / properties / items / items / properties
      Removed value: -{
      -  "analysis": {
      -    "anyOf": [
      -      {
      -        "properties": {
      -          "actionability": {
      -            "anyOf": [
      -              {
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "default": null
      -          },
      -          "alternative_perspectives": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "contrarian_view": {
      -                    "anyOf": [
      -                      {
      -                        "type": "string"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "default": null
      -                  },
      -                  "overlooked_factors": {
      -                    "anyOf": [
      -                      {
      -                        "type": "string"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "default": null
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "default": null
      -          },
      -          "background_context": {
      -            "anyOf": [
      -              {
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "default": null
      -          },
      -          "indirect_market_effects": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "global_market_relevance": {
      -                    "anyOf": [
      -                      {
      -                        "type": "string"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "default": null
      -                  },
      -                  "regional_market_impact": {
      -                    "anyOf": [
      -                      {
      -                        "type": "string"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "default": null
      -                  },
      -                  "sector_implications": {
      -                    "anyOf": [
      -                      {
      -                        "type": "string"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "default": null
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "default": null
      -          },
      -          "information_novelty": {
      -            "anyOf": [
      -              {
      -                "type": "integer"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "default": null
      -          },
      -          "key_entities": {
      -            "items": {
      -              "properties": {
      -                "description": {
      -                  "default": "",
      -                  "type": "string"
      -                },
      -                "entity_type": {
      -                  "default": "",
      -                  "type": "string"
      -                },
      -                "name": {
      -                  "default": "",
      -                  "type": "string"
      -                }
      -              },
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "market_relevance_summary": {
      -            "anyOf": [
      -              {
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "default": null
      -          },
      -          "market_sentiment_alignment": {
      -            "anyOf": [
      -              {
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "default": null
      -          },
      -          "ticker_analysis": {
      -            "items": {
      -              "properties": {
      -                "confidence": {
      -                  "anyOf": [
      -                    {
      -                      "type": "string"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ],
      -                  "default": null
      -                },
      -                "price_impact_prediction": {
      -                  "anyOf": [
      -                    {
      -                      "type": "string"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ],
      -                  "default": null
      -                },
      -                "reasoning": {
      -                  "anyOf": [
      -                    {
      -                      "type": "string"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ],
      -                  "default": null
      -                },
      -                "relevance_context": {
      -                  "anyOf": [
      -                    {
      -                      "type": "string"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ],
      -                  "default": null
      -                },
      -                "sentiment": {
      -                  "anyOf": [
      -                    {
      -                      "type": "string"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ],
      -                  "default": null
      -                },
      -                "ticker": {
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "ticker"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "timing_relevance": {
      -            "anyOf": [
      -              {
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "default": null
      -          }
      -        },
      -        "type": "object"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "default": null
      -  },
      -  "banner_image": {
      -    "anyOf": [
      -      {
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "default": null
      -  },
      -  "category": {
      -    "type": "string"
      -  },
      -  "created_at": {
      -    "type": "string"
      -  },
      -  "earnings": {
      -    "anyOf": [
      -      {
      -        "additionalProperties": true,
      -        "type": "object"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "default": null
      -  },
      -  "filing": {
      -    "anyOf": [
      -      {
      -        "description": "Structured SEC 8-K filing block (``source_type == \"sec_form8k\"`` items on\nthe news tools).\n\nA read-only projection of the 8-K sidecar\n(``apps.data.models.EightKEventModel``) — same fields and semantics as the\nREST ``/api/news/`` block (openapi.yaml: ``EightKFiling``): ``items`` is\nevery item code the filing carries (the ``item`` filter matches any of\nthem; empty for a header-only filing), ``primary_item`` the one that drove\nthe category, ``accession_number`` the id to cite, ``filed_at`` EDGAR's\nacceptance time, ``event_date`` the filing's own date of report and\n``exhibit_url`` the press-release exhibit the summary was built from.\nDates are ISO strings like the insider block; empty sidecar strings are\n``null``, never ``\"\"``.",
      -        "properties": {
      -          "accession_number": {
      -            "type": "string"
      -          },
      -          "event_date": {
      -            "anyOf": [
      -              {
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "default": null
      -          },
      -          "exhibit_url": {
      -            "anyOf": [
      -              {
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "default": null
      -          },
      -          "filed_at": {
      -            "type": "string"
      -          },
      -          "items": {
      -            "items": {
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "primary_item": {
      -            "anyOf": [
      -              {
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "default": null
      -          }
      -        },
      -        "required": [
      -          "items",
      -          "accession_number",
      -          "filed_at"
      -        ],
      -        "type": "object"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "default": null
      -  },
      -  "insider": {
      -    "anyOf": [
      -      {
      -        "description": "Structured SEC Form 4 event block (``alphai_insider_news`` items only).\n\nAggregate of the news row's whole transaction group — same semantics as the\nREST ``/api/news/insider/`` block (openapi.yaml: ``InsiderEvent``): shares and\nvalue are GROUP sums (a 10b5-1 ladder is one event), ``avg_price_usd`` is\nvalue-weighted over priced tranches, ``is_10b5_1`` is the group OR, the\nlast fill dates the event. ``side`` is the signal label: buy (P) / sell (S)\n/ other (everything else, incl. D — sale to issuer, a buyback/redemption,\nnot an open-market disposition); the raw ``transaction_code`` rides along.\nMoney/share fields are decimal STRINGS (\"25000\", \"187.32\") — flat, precise,\nschema-simple; null when the filing prices no tranche.\n\n``filed_at`` is when EDGAR accepted the filing and ``late_filing`` marks the\nones that missed the SEC's two-business-day deadline; the rule lives in\n``_is_late_filing`` in ``repository.py`` (ported from the backend's\n``apps.insider.services.filing_lateness``). Field reference for both\nsurfaces: ``backend/openapi.yaml`` (``InsiderEvent``).",
      -        "properties": {
      -          "avg_price_usd": {
      -            "anyOf": [
      -              {
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "default": null
      -          },
      -          "filed_at": {
      -            "type": "string"
      -          },
      -          "insider_name": {
      -            "type": "string"
      -          },
      -          "insider_title": {
      -            "type": "string"
      -          },
      -          "is_10b5_1": {
      -            "type": "boolean"
      -          },
      -          "is_director": {
      -            "type": "boolean"
      -          },
      -          "is_officer": {
      -            "type": "boolean"
      -          },
      -          "is_ten_percent_owner": {
      -            "type": "boolean"
      -          },
      -          "late_filing": {
      -            "type": "boolean"
      -          },
      -          "shares": {
      -            "type": "string"
      -          },
      -          "side": {
      -            "type": "string"
      -          },
      -          "total_value_usd": {
      -            "anyOf": [
      -              {
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "default": null
      -          },
      -          "transaction_code": {
      -            "type": "string"
      -          },
      -          "transaction_date": {
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "side",
      -          "transaction_code",
      -          "shares",
      -          "is_10b5_1",
      -          "insider_name",
      -          "insider_title",
      -          "is_officer",
      -          "is_director",
      -          "is_ten_percent_owner",
      -          "transaction_date",
      -          "filed_at",
      -          "late_filing"
      -        ],
      -        "type": "object"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "default": null
      -  },
      -  "ownership_form": {
      -    "anyOf": [
      -      {
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "default": null
      -  },
      -  "read_time_minutes": {
      -    "anyOf": [
      -      {
      -        "type": "integer"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "default": null
      -  },
      -  "relevance_score": {
      -    "type": "integer"
      -  },
      -  "search_match": {
      -    "anyOf": [
      -      {
      -        "description": "Per-item evidence from the text path: ``score`` orders the page (cover\ndensity × recency; comparable within one response, not a probability),\n``terms_matched`` is set in broadened mode, ``context`` marks the matched\nwords in the summary with ``**``.",
      -        "properties": {
      -          "context": {
      -            "anyOf": [
      -              {
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "default": null
      -          },
      -          "score": {
      -            "type": "number"
      -          },
      -          "terms_matched": {
      -            "anyOf": [
      -              {
      -                "type": "integer"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "default": null
      -          }
      -        },
      -        "required": [
      -          "score"
      -        ],
      -        "type": "object"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "default": null
      -  },
      -  "source": {
      -    "type": "string"
      -  },
      -  "source_domain": {
      -    "type": "string"
      -  },
      -  "source_type": {
      -    "default": "",
      -    "type": "string"
      -  },
      -  "sources": {
      -    "anyOf": [
      -      {
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "default": null
      -  },
      -  "sources_count": {
      -    "anyOf": [
      -      {
      -        "type": "integer"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "default": null
      -  },
      -  "story_id": {
      -    "anyOf": [
      -      {
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "default": null
      -  },
      -  "summary": {
      -    "type": "string"
      -  },
      -  "tickers": {
      -    "items": {
      -      "type": "string"
      -    },
      -    "type": "array"
      -  },
      -  "time_published": {
      -    "type": "string"
      -  },
      -  "title": {
      -    "type": "string"
      -  },
      -  "uid": {
      -    "type": "string"
      -  },
      -  "url": {
      -    "type": "string"
      -  }
      -}
    • removedOutput schema / properties / items / items / required
      Removed value: -[
      -  "uid",
      -  "title",
      -  "url",
      -  "source",
      -  "source_domain",
      -  "summary",
      -  "category",
      -  "relevance_score",
      -  "time_published",
      -  "created_at"
      -]
    • removedOutput schema / properties / items / items / type
      Removed value: -"object"
  7. Changed6 schema fields changed
    • changedInput schema / properties / cursor / anyOf
      Previous value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "maxLength": 1024,
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / q / anyOf
      Previous value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "maxLength": 200,
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / query / anyOf
      Previous value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "maxLength": 200,
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / query / description
      Previous value: -"Full-text query over article titles, named entities and summaries (company names, people, topics, tickers); how it was read comes back in query_interpretation."New value: +"Full-text query over article titles, named entities and summaries (company names, people, topics, tickers), up to 200 characters; how it was read comes back in query_interpretation."
    • changedInput schema / properties / tickers / anyOf
      Previous value: -[
      -  {
      -    "items": {
      -      "type": "string"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "items": {
      +      "maxLength": 16,
      +      "pattern": "^[A-Za-z0-9.\\-]+$",
      +      "type": "string"
      +    },
      +    "maxItems": 50,
      +    "type": "array"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / tickers / description
      Previous value: -"Restrict to news mentioning these tickers."New value: +"Restrict to news mentioning these tickers (up to 50 symbols; duplicates are ignored)."
  8. Changed2 schema fields changed
    • changedInput schema / properties / query / description
      Previous value: -"Free-text query (company names / tickers / topic words) resolved to ticker + category filters; how it was read comes back in query_interpretation."New value: +"Full-text query over article titles, named entities and summaries (company names, people, topics, tickers); how it was read comes back in query_interpretation."
    • changedOutput schema / properties / query_interpretation / anyOf
      Previous value: -[
      -  {
      -    "description": "How ``alphai_news_search`` read a free-text ``query`` — the echo that makes\na resolver miss legible. Before it, a query read as the wrong company or\ndiscarded entirely came back indistinguishable from a hit\n(issues/2026-08-16-freetext-query-resolves-jane-street-to-janl.md).\n\n``mode``: ``resolved`` — at least one query word became a filter that is\napplied to the items; ``overridden`` — the query resolved, but explicit\n``tickers``/``category`` replaced every filter it produced; ``unresolved`` —\nno query word matched a ticker, company name or topic word, so the items\nare NOT matches for the query (``note`` says what they are instead).\n``ignored_terms`` lists the content words that matched nothing; stopwords\nare dropped silently. ``note`` is one or two plain sentences an agent can act\non, same role as ``ticker_note``.",
      -    "properties": {
      -      "category": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null
      -      },
      -      "category_term": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null
      -      },
      -      "ignored_terms": {
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "mode": {
      -        "enum": [
      -          "resolved",
      -          "overridden",
      -          "unresolved"
      -        ],
      -        "type": "string"
      -      },
      -      "note": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "search": {
      -        "anyOf": [
      -          {
      -            "description": "How the text search read the query (docs/HYBRID_NEWS_SEARCH_PLAN.md\nstep 2): ``strict`` = every term required; ``broadened`` = fewer strict\nmatches than the threshold, so any rare term plus at least two of the\nterms; ``no_match``; ``no_terms``. ``sort`` is ``published`` when every\nterm is a very common word (newest matches, not best). ``terms`` are the\nnormalized (stemmed) lexemes the index holds. ``matched`` counts the\nvisible matches inside the bounded candidate set, never a global total.",
      -            "properties": {
      -              "engine": {
      -                "default": "postgres",
      -                "enum": [
      -                  "postgres",
      -                  "meilisearch"
      -                ],
      -                "type": "string"
      -              },
      -              "matched": {
      -                "default": 0,
      -                "type": "integer"
      -              },
      -              "mode": {
      -                "enum": [
      -                  "strict",
      -                  "broadened",
      -                  "no_match",
      -                  "no_terms"
      -                ],
      -                "type": "string"
      -              },
      -              "optional_terms": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "required_terms": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "sort": {
      -                "enum": [
      -                  "relevance",
      -                  "published"
      -                ],
      -                "type": "string"
      -              },
      -              "terms": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "window_from": {
      -                "anyOf": [
      -                  {
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "default": null
      -              }
      -            },
      -            "required": [
      -              "mode",
      -              "sort"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "default": null
      -      },
      -      "tickers": {
      -        "items": {
      -          "description": "One ticker a free-text ``query`` resolved to (docs/HYBRID_NEWS_SEARCH_PLAN.md\nstep 1). ``name`` is the issuer's registered name, so an agent can see that\n\"PMI\" was read as Picard Medical rather than the ISM purchasing-managers\nindex; ``term`` is the query word that produced it (share-class siblings\ninherit the seed word's term).",
      -          "properties": {
      -            "name": {
      -              "anyOf": [
      -                {
      -                  "type": "string"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ],
      -              "default": null
      -            },
      -            "term": {
      -              "type": "string"
      -            },
      -            "ticker": {
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "ticker",
      -            "term"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      }
      -    },
      -    "required": [
      -      "mode"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "description": "How ``alphai_news_search`` read a free-text ``query`` — the echo that makes\na resolver miss legible. Before it, a query read as the wrong company or\ndiscarded entirely came back indistinguishable from a hit\n(issues/2026-08-16-freetext-query-resolves-jane-street-to-janl.md).\n\n``mode``: ``searched`` — the text search served the items\n(``NEWS_SEARCH_MODE=on``, the normal state since 2026-09-23): ``search``\nsays what selected them, ``tickers``/``category`` only say what the words\nwere ALSO read as (reference, never a filter) and ``ignored_terms`` is\nempty, because nothing was ignored — the whole text was searched. Before\nthis (review finding 1a/1b, 2026-09-23) the text path echoed the\nresolver's ``resolved`` + its ``ignored_terms`` next to a ``search`` block\nwhose ``terms`` were those very words, and a read category looked applied\nwhile nothing but the text filtered the items. The resolver modes describe\nthe fallback when the text search is switched off: ``resolved`` — at least\none query word became a filter that is applied to the items;\n``overridden`` — the query resolved, but explicit ``tickers``/``category``\nreplaced every filter it produced; ``unresolved`` — no query word matched a\nticker, company name or topic word, so the items are NOT matches for the\nquery (``note`` says what they are instead). ``ignored_terms`` then lists\nthe content words that matched nothing; stopwords are dropped silently.\n``note`` is one or two plain sentences an agent can act on, same role as\n``ticker_note``.",
      +    "properties": {
      +      "category": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "category_term": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "ignored_terms": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "mode": {
      +        "enum": [
      +          "searched",
      +          "resolved",
      +          "overridden",
      +          "unresolved"
      +        ],
      +        "type": "string"
      +      },
      +      "note": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "search": {
      +        "anyOf": [
      +          {
      +            "description": "How the text search read the query (docs/HYBRID_NEWS_SEARCH_PLAN.md\nstep 2): ``strict`` = every term required; ``broadened`` = fewer strict\nmatches than the threshold, so the most common words were dropped first\nand every item carries at least two of the terms; ``no_match``;\n``no_terms``. ``sort`` is ``published`` when every term is a very common\nword (newest matches, not best). ``terms`` are the normalized words that\nwere searched. ``required_terms`` is filled only when the search reports\nwhich words every broadened row had to carry (the Postgres path does, the\nengine does not) — ``search_match.terms_matched`` on each item is the\ncount to trust. ``matched`` counts the visible matches inside the bounded\ncandidate set, never a global total. Which engine answered is NOT part of\nthe contract: it goes to the search log (``ranking_version``). The\n``engine`` field that shipped with 1.41.0 was read by an external review\nas an implementation leak, and it was one — a client has no action on\n\"meilisearch\" (issues/2026-09-23-news-search-review-triage.md).",
      +            "properties": {
      +              "matched": {
      +                "default": 0,
      +                "type": "integer"
      +              },
      +              "mode": {
      +                "enum": [
      +                  "strict",
      +                  "broadened",
      +                  "no_match",
      +                  "no_terms"
      +                ],
      +                "type": "string"
      +              },
      +              "optional_terms": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "required_terms": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "sort": {
      +                "enum": [
      +                  "relevance",
      +                  "published"
      +                ],
      +                "type": "string"
      +              },
      +              "terms": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "window_from": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              }
      +            },
      +            "required": [
      +              "mode",
      +              "sort"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null
      +      },
      +      "tickers": {
      +        "items": {
      +          "description": "One ticker a free-text ``query`` resolved to (docs/HYBRID_NEWS_SEARCH_PLAN.md\nstep 1). ``name`` is the issuer's registered name, so an agent can see that\n\"PMI\" was read as Picard Medical rather than the ISM purchasing-managers\nindex; ``term`` is the query word that produced it (share-class siblings\ninherit the seed word's term).",
      +          "properties": {
      +            "name": {
      +              "anyOf": [
      +                {
      +                  "type": "string"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ],
      +              "default": null
      +            },
      +            "term": {
      +              "type": "string"
      +            },
      +            "ticker": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "ticker",
      +            "term"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "mode"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  9. Changed3 schema fields changed
    • changedInput schema / properties / query / description
      Previous value: -"Free-text query (company names / tickers / topic words) resolved to ticker + category filters."New value: +"Free-text query (company names / tickers / topic words) resolved to ticker + category filters; how it was read comes back in query_interpretation."
    • addedOutput schema / properties / items / items / properties / search_match
      Added value: +{
      +  "anyOf": [
      +    {
      +      "description": "Per-item evidence from the text path: ``score`` orders the page (cover\ndensity × recency; comparable within one response, not a probability),\n``terms_matched`` is set in broadened mode, ``context`` marks the matched\nwords in the summary with ``**``.",
      +      "properties": {
      +        "context": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null
      +        },
      +        "score": {
      +          "type": "number"
      +        },
      +        "terms_matched": {
      +          "anyOf": [
      +            {
      +              "type": "integer"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null
      +        }
      +      },
      +      "required": [
      +        "score"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null
      +}
    • addedOutput schema / properties / query_interpretation
      Added value: +{
      +  "anyOf": [
      +    {
      +      "description": "How ``alphai_news_search`` read a free-text ``query`` — the echo that makes\na resolver miss legible. Before it, a query read as the wrong company or\ndiscarded entirely came back indistinguishable from a hit\n(issues/2026-08-16-freetext-query-resolves-jane-street-to-janl.md).\n\n``mode``: ``resolved`` — at least one query word became a filter that is\napplied to the items; ``overridden`` — the query resolved, but explicit\n``tickers``/``category`` replaced every filter it produced; ``unresolved`` —\nno query word matched a ticker, company name or topic word, so the items\nare NOT matches for the query (``note`` says what they are instead).\n``ignored_terms`` lists the content words that matched nothing; stopwords\nare dropped silently. ``note`` is one or two plain sentences an agent can act\non, same role as ``ticker_note``.",
      +      "properties": {
      +        "category": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null
      +        },
      +        "category_term": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null
      +        },
      +        "ignored_terms": {
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "mode": {
      +          "enum": [
      +            "resolved",
      +            "overridden",
      +            "unresolved"
      +          ],
      +          "type": "string"
      +        },
      +        "note": {
      +          "default": "",
      +          "type": "string"
      +        },
      +        "search": {
      +          "anyOf": [
      +            {
      +              "description": "How the text search read the query (docs/HYBRID_NEWS_SEARCH_PLAN.md\nstep 2): ``strict`` = every term required; ``broadened`` = fewer strict\nmatches than the threshold, so any rare term plus at least two of the\nterms; ``no_match``; ``no_terms``. ``sort`` is ``published`` when every\nterm is a very common word (newest matches, not best). ``terms`` are the\nnormalized (stemmed) lexemes the index holds. ``matched`` counts the\nvisible matches inside the bounded candidate set, never a global total.",
      +              "properties": {
      +                "engine": {
      +                  "default": "postgres",
      +                  "enum": [
      +                    "postgres",
      +                    "meilisearch"
      +                  ],
      +                  "type": "string"
      +                },
      +                "matched": {
      +                  "default": 0,
      +                  "type": "integer"
      +                },
      +                "mode": {
      +                  "enum": [
      +                    "strict",
      +                    "broadened",
      +                    "no_match",
      +                    "no_terms"
      +                  ],
      +                  "type": "string"
      +                },
      +                "optional_terms": {
      +                  "items": {
      +                    "type": "string"
      +                  },
      +                  "type": "array"
      +                },
      +                "required_terms": {
      +                  "items": {
      +                    "type": "string"
      +                  },
      +                  "type": "array"
      +                },
      +                "sort": {
      +                  "enum": [
      +                    "relevance",
      +                    "published"
      +                  ],
      +                  "type": "string"
      +                },
      +                "terms": {
      +                  "items": {
      +                    "type": "string"
      +                  },
      +                  "type": "array"
      +                },
      +                "window_from": {
      +                  "anyOf": [
      +                    {
      +                      "type": "string"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ],
      +                  "default": null
      +                }
      +              },
      +              "required": [
      +                "mode",
      +                "sort"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null
      +        },
      +        "tickers": {
      +          "items": {
      +            "description": "One ticker a free-text ``query`` resolved to (docs/HYBRID_NEWS_SEARCH_PLAN.md\nstep 1). ``name`` is the issuer's registered name, so an agent can see that\n\"PMI\" was read as Picard Medical rather than the ISM purchasing-managers\nindex; ``term`` is the query word that produced it (share-class siblings\ninherit the seed word's term).",
      +            "properties": {
      +              "name": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "default": null
      +              },
      +              "term": {
      +                "type": "string"
      +              },
      +              "ticker": {
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "ticker",
      +              "term"
      +            ],
      +            "type": "object"
      +          },
      +          "type": "array"
      +        }
      +      },
      +      "required": [
      +        "mode"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null
      +}
  10. Changed3 schema fields changed
    • addedInput schema / properties / item
      Added value: +{
      +  "anyOf": [
      +    {
      +      "pattern": "^\\d\\.\\d{2}$",
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "8-K item code (e.g. '5.02', '8.01', '1.01'): keep only 8-K filings carrying it — any item of the filing. Implies source_type=['sec_form8k']; any other source_type is an error."
      +}
    • addedInput schema / properties / source_type
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "description": "Ingestion source of a news row.",
      +        "enum": [
      +          "alpha_vantage",
      +          "gdelt",
      +          "sec_form4",
      +          "sec_form8k",
      +          "sec_form6k"
      +        ],
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Restrict to these ingest sources (OR): gdelt = press coverage, sec_form4 = insider transactions, sec_form8k = 8-K current reports, sec_form6k = foreign issuers' 6-K earnings releases."
      +}
    • addedOutput schema / properties / items / items / properties / filing
      Added value: +{
      +  "anyOf": [
      +    {
      +      "description": "Structured SEC 8-K filing block (``source_type == \"sec_form8k\"`` items on\nthe news tools).\n\nA read-only projection of the 8-K sidecar\n(``apps.data.models.EightKEventModel``) — same fields and semantics as the\nREST ``/api/news/`` block (openapi.yaml: ``EightKFiling``): ``items`` is\nevery item code the filing carries (the ``item`` filter matches any of\nthem; empty for a header-only filing), ``primary_item`` the one that drove\nthe category, ``accession_number`` the id to cite, ``filed_at`` EDGAR's\nacceptance time, ``event_date`` the filing's own date of report and\n``exhibit_url`` the press-release exhibit the summary was built from.\nDates are ISO strings like the insider block; empty sidecar strings are\n``null``, never ``\"\"``.",
      +      "properties": {
      +        "accession_number": {
      +          "type": "string"
      +        },
      +        "event_date": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null
      +        },
      +        "exhibit_url": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null
      +        },
      +        "filed_at": {
      +          "type": "string"
      +        },
      +        "items": {
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "primary_item": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null
      +        }
      +      },
      +      "required": [
      +        "items",
      +        "accession_number",
      +        "filed_at"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null
      +}
  11. Changed12 schema fields changed
    • changedInput schema / properties / from_date / description
      Previous value: -"News on/after this ISO time (UTC if naive)."New value: +"News on/after this ISO time (UTC if naive); a bare date means that day's midnight."
    • changedInput schema / properties / page_size / description
      Previous value: -"Items/page; capped at 10 Basic / 50 Pro."New value: +"Items/page; capped at 20 Free/Basic, 50 Pro."
    • addedInput schema / properties / sort
      Added value: +{
      +  "anyOf": [
      +    {
      +      "enum": [
      +        "published",
      +        "ingested"
      +      ],
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "published (default): newest first, next_cursor pages into older history. ingested: delta polling — rows in the order they became available, ascending; next_cursor is always returned (empty items = caught up, keep the cursor and poll later); time_published is not monotonic within a page. A cursor only works with the sort mode that issued it."
      +}
    • changedInput schema / properties / to_date / description
      Previous value: -"News on/before this ISO time (UTC if naive)."New value: +"News on/before this ISO time (UTC if naive). A bare date (2026-06-01) covers that WHOLE day, so from_date=to_date=<day> returns the day — same reading as REST /api/news/."
    • addedOutput schema / properties / delisted
      Added value: +{
      +  "default": false,
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / items / items / properties / created_at
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / items / items / properties / earnings
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": true,
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null
      +}
    • addedOutput schema / properties / items / items / properties / insider
      Added value: +{
      +  "anyOf": [
      +    {
      +      "description": "Structured SEC Form 4 event block (``alphai_insider_news`` items only).\n\nAggregate of the news row's whole transaction group — same semantics as the\nREST ``/api/news/insider/`` block (openapi.yaml: ``InsiderEvent``): shares and\nvalue are GROUP sums (a 10b5-1 ladder is one event), ``avg_price_usd`` is\nvalue-weighted over priced tranches, ``is_10b5_1`` is the group OR, the\nlast fill dates the event. ``side`` is the signal label: buy (P) / sell (S)\n/ other (everything else, incl. D — sale to issuer, a buyback/redemption,\nnot an open-market disposition); the raw ``transaction_code`` rides along.\nMoney/share fields are decimal STRINGS (\"25000\", \"187.32\") — flat, precise,\nschema-simple; null when the filing prices no tranche.\n\n``filed_at`` is when EDGAR accepted the filing and ``late_filing`` marks the\nones that missed the SEC's two-business-day deadline; the rule lives in\n``_is_late_filing`` in ``repository.py`` (ported from the backend's\n``apps.insider.services.filing_lateness``). Field reference for both\nsurfaces: ``backend/openapi.yaml`` (``InsiderEvent``).",
      +      "properties": {
      +        "avg_price_usd": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null
      +        },
      +        "filed_at": {
      +          "type": "string"
      +        },
      +        "insider_name": {
      +          "type": "string"
      +        },
      +        "insider_title": {
      +          "type": "string"
      +        },
      +        "is_10b5_1": {
      +          "type": "boolean"
      +        },
      +        "is_director": {
      +          "type": "boolean"
      +        },
      +        "is_officer": {
      +          "type": "boolean"
      +        },
      +        "is_ten_percent_owner": {
      +          "type": "boolean"
      +        },
      +        "late_filing": {
      +          "type": "boolean"
      +        },
      +        "shares": {
      +          "type": "string"
      +        },
      +        "side": {
      +          "type": "string"
      +        },
      +        "total_value_usd": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null
      +        },
      +        "transaction_code": {
      +          "type": "string"
      +        },
      +        "transaction_date": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "side",
      +        "transaction_code",
      +        "shares",
      +        "is_10b5_1",
      +        "insider_name",
      +        "insider_title",
      +        "is_officer",
      +        "is_director",
      +        "is_ten_percent_owner",
      +        "transaction_date",
      +        "filed_at",
      +        "late_filing"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null
      +}
    • addedOutput schema / properties / items / items / properties / source_type
      Added value: +{
      +  "default": "",
      +  "type": "string"
      +}
    • changedOutput schema / properties / items / items / required
      Previous value: -[
      -  "uid",
      -  "title",
      -  "url",
      -  "source",
      -  "source_domain",
      -  "summary",
      -  "category",
      -  "relevance_score",
      -  "time_published"
      -]New value: +[
      +  "uid",
      +  "title",
      +  "url",
      +  "source",
      +  "source_domain",
      +  "summary",
      +  "category",
      +  "relevance_score",
      +  "time_published",
      +  "created_at"
      +]
    • addedOutput schema / properties / renamed_to
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null
      +}
    • addedOutput schema / properties / ticker_note
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null
      +}
  12. Changed4 schema fields changed
    • addedInput schema / properties / limit
      Added value: +{
      +  "anyOf": [
      +    {
      +      "maximum": 50,
      +      "minimum": 1,
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Alias for page_size."
      +}
    • changedInput schema / properties / page_size / description
      Previous value: -"Items/page. 10 Basic / 50 Pro (tools.bulk)."New value: +"Items/page; capped at 10 Basic / 50 Pro."
    • addedInput schema / properties / q
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Alias for query."
      +}
    • addedInput schema / properties / query
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Free-text query (company names / tickers / topic words) resolved to ticker + category filters."
      +}
  13. Changed1 schema field changed
    • removedInput schema / properties / q
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Free-text query; tokens AND-matched in title/summary."
      -}
  14. First observed

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only, open-world, idempotent, non-destructive behavior, and the description adds substantial operational detail beyond that: query interpretation, hard filters, ingested-mode pagination semantics, quota behavior on empty pages, story collapsing, and structured error handling. No annotation contradiction is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but front-loaded with the core purpose and then organized by operational concern. Some sentences are run-on and repeat schema details such as the default detail mode and default ordering, but most of the content earns its place given the tool's 15-parameter complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the 15-parameter schema, full schema description coverage, and an output schema, the description supplies the missing operational context an agent needs: query interpretation, hard-filter rules, pagination/resume behavior, quota cautions, detail modes, and error recovery. Nothing essential for correct invocation appears to be missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds cross-parameter meaning such as query/q not allowing sort='ingested', explicit tickers/category acting as hard filters, crypto symbol formatting, and collapse_stories behavior in ingested mode. It does not add semantics for every one of the 15 parameters, but it meaningfully supplements the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Search financial news') plus the two supported modes: text or structured filters. It also distinguishes itself from related tools by routing tickerless macro searches to categories or alphai_macro and uid expansion to alphai_article.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-to-use guidance and alternatives: use detail='compact' for polling, alphai_article to expand uids, alphai_macro or categories for tickerless macro, and crypto symbols as <SYM>-USD. It also explains hard-filter behavior for tickers/category and the sort restriction for query/q.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.