fix(agent): ground the tools the chat agent reasons with - #198
Merged
Conversation
Staging transcripts from 2026-08-13 showed the agent failing in ways users could see: searches returning nothing for content that existed, a schema summary that hid the field being asked about, duplicate and junk media uploads, silent no-op saves reported as successes, and tool errors indistinguishable from results at the protocol layer. brain_search - token-scored matching over entry string values replaces the contiguous substring match over JSON.stringify — a query spanning two fields (title + description) now finds the entry; results are ranked before the limit cut (5 of 7 staging searches returned zero results and pushed the agent into full-model dumps and a wrong-entry pick) Schema summary - formatFieldDef names subfields at the depth cap instead of dropping them — object → array → items chains rendered as 'array (items: object)', which taught the agent that deep cards had no image field upload_media - our own delivery URL resolves to the existing asset instead of being re-ingested as a duplicate with a uuid filename; a stale/invented own URL errors instead of laundering through a refetch - the inline fetch (no size cap, no quota) is replaced with the shared fetchRemoteMedia + plan-aware variants + storage reservation, matching the MCP media facet Media lookups - new findMediaAssetByPath (both DB providers) + getAssetByPath on the media provider: the storage path's uuid names the file, not the row, so path-in-hand lookups could not go through getAsset — the UI save route's usage tracking searched by filename and never matched No-op saves - a plan byte-identical to contentrain returns unchanged:true without creating a branch, an empty commit, or a merge cycle (each no-op previously cost the full ~18s write round and polluted history) Tool errors - tool_result blocks carry isError, mapped to Anthropic's is_error; every executor error previously looked like a success at the protocol layer, blinding both the model and error telemetry
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Neden
13 Ağustos staging konuşmalarında ajanın kullanıcıya görünen hataları tek tek bu tool katmanına indi: var olan içeriği bulamayan arama (7 sorgunun 5'i boş), sorulan alanı gizleyen şema özeti, kütüphaneye kopya/çöp medya yüklemeleri, başarı gibi raporlanan sessiz no-op save'ler ve protokol katmanında başarıdan ayırt edilemeyen tool hataları.
Ne değişti
JSON.stringifyüzerinde bitişik substring eşleşmesi yerine entry string değerleri üzerinde token-bazlı skorlama; iki alana yayılan sorgular (title + description) artık eşleşiyor, sonuçlar limitten önce skora göre sıralanıyorformatFieldDefdepth cap'te alt alan adlarını düşürmek yerine{title, image, cta_label}biçiminde listeliyor —object → array → itemszincirindeki image alanı ajana görünmez değildi artıkdeduplicated: true); çözülemeyen kendi-URL referansı hata (uydurma UUID'yi CDN refetch'iyle aklamak yok); inline fetch (boyut sınırsız, kotasız) yerine paylaşılanfetchRemoteMedia+ plan-farkında varyantlar + storage rezervasyonu (MCP media facet paritesi)findMediaAssetByPath(iki DB provider) +MediaProvider.getAssetByPath— path'teki uuid dosyayı adlandırıyor, satırı değil; UI save route'unun usage tracking'i filename araması yüzünden hiç eşleşmiyorduunchanged: truedönüyor (her no-op ~18 sn'lik tam yazma turuna ve boş merge tarihçesine mal oluyordu)isErrortaşıyor, Anthropicis_error'a map'leniyor — hata telemetrisi artık kör değilTest
pnpm testtam süit yeşil (150 dosya / 1298 test); yeni birimler: brain-search skorlama (staging regresyonu fixture'ları), no-op tespiti,ownMediaStoragePath,is_errormap'i, depth-cap şema regresyonu🤖 Generated with Claude Code