How the chat agent finds sources

The codex/agent-improvements branch gives the main chat agent one new tool, rebuilds the other two, and adds limits on how much research a single answer can do. This page explains what each tool does and how a turn runs.

Branch commit cf2574fc · Prompt platform/main-gemini v28 (label retrieval-v2) · October 2026

A turn at a glance

Resolve nameslookup_catalog turns "Ibn al-Qayyim" or "Sahih al-Bukhari" into catalog IDs.
Searchsearch runs a hybrid query, optionally filtered by those IDs or by an author death-year range.
Read aroundexpand pulls the passages right before and after a promising result.
AnswerWhen the research budget runs out, or step 18 is reached, the model must write its answer from what it has.

Steps 1–3 can repeat and run in any order. Every passage already retrieved in the turn is excluded from later searches, so each call can only bring back new material.

The three tools

lookup_catalog New

Resolves an author, book or genre name to canonical catalog IDs.

lookup_catalog({ kind: "author", query: "ابن القيم" })
→ [{ kind: "author", id: 1234, label: "Ibn Qayyim al-Jawziyya",
     deathYearAH: 751, deathInexactLabel: null, indexed: true }, …]

Illustrative output; the ID is made up.

search Rebuilt

Searches the corpus and returns up to 20 passages.

search({
  query: "الصبر عند المصيبة",
  label: "Patience in hardship",
  filters: { authorIds: [1234], deathYearAH: { lte: 800 } }
})

expand Tightened

Reads the context around a passage the model already has.

Research limits per turn

Before vs after

mainagent-improvements
Toolssearch, expand+ lookup_catalog
Search modeModel picks semantic or keywordAlways hybrid (vector + BM25, fused)
Candidates → delivered50 semantic → rerank → 2024 + 24 → fuse → rerank → 20
Model-set filtersNone (only the user's composer scope)Author / book / genre IDs and death-year range, within the user's scope
Expand window5 each side, any coordinates2 each side, only from retrieved passages
DuplicatesCould resurface across callsExcluded at query time; identical calls memoised
BudgetStep limit only8 calls, 2-strike no-progress stop, synthesis from step 18

Things to know before shipping

Prompt not promoted. The wording that teaches the model these tools is in platform/main-gemini v28 (retrieval-v2). Production still serves v24. Local dev picks up v28 through the latest label. In the admin playground you have to select v28 explicitly; v24 is pinned to the top of the list.
Death-year data. Date-range filters only work once the indexed passages carry author_death_year. The v28 commit note says to promote the prompt only after the manual date backfill, which (per the branch's plan.md) hasn't been run yet.
Settings are a starting point. The 24/20 numbers were not tuned on this branch. The earlier ablation tested 25 per branch, so quality parity for these exact settings hasn't been measured.