You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
tool_registry_debug_e2e_test.py asserts Orchestrator.tool_registry, an attribute that doesn't exist #13037
Discovered while running the baseline test sweep for #13024/#13025/#13026/#13027 (KB-search call-site fixes). Unrelated to those issues -- this file doesn't touch knowledge/, knowledge_base.py, or any KB search path.
Orchestrator (autobot-backend/orchestrator.py:123) has no tool_registry attribute at all -- only self.agent_registry (orchestrator.py:159). The preceding hasattr() check even prints False immediately before the crash, so the test author already knew the attribute might be missing but the script wasn't updated to handle that case gracefully.
This is a stale debug script (last touched only by a repo-wide file-rename and a license-header commit, per git log --follow), not a real regression -- it currently fails on the Dev_new_gui tip with no relation to my in-flight PR.
Suggested fix
Either:
Update the script to reference whatever the orchestrator's actual tool-registry-equivalent attribute is (if one exists elsewhere, e.g. via get_tool_registry() from tools/tool_registry.py), or
If Orchestrator was never meant to hold a tool_registry reference, delete this stale debug script (or gate the crashing line behind the hasattr() check it already computes).
Fixed by PR #13039, merged to Dev_new_gui as a2f788889 (batched with #13013, #13021, #13037 — all three fully delivered, none dropped).
#13013 — wired, not deleted.services/research/models.py:88's truncated_sources was genuinely dead scaffolding (grepped services/research/*.py: zero appenders). The real truncation point already existed at extractor.py:102 (content[:max_content_chars]). It is now recorded by orchestrator._record_truncation_if_needed(), called from _land_page — the one place holding both the budget and the pre-slice markdown. Under the never-delete rule, giving the field a true meaning beat removing it.
#13021 — enforced during streaming, and the severity is latent rather than live. The cap at media/link/pipeline.py:79 (line moved from 67 since #13019/#13022 landed) was declaration-only; _fetch_and_parse's fallback did an unbounded await response.text(...). New _read_bounded_content() streams in 64 KiB chunks — mirroring web_fetch/fetcher.py._fetch_bs4 — and stops requesting chunks once the cap is crossed, so an oversized body is refused mid-stream rather than after being read into memory. Enforcing post-hoc would have defeated the point entirely. The limit is now ssot_config.link_pipeline_max_content_bytes (AUTOBOT_LINK_PIPELINE_MAX_CONTENT_BYTES, default 1 MB) instead of a literal, and a rejection logs distinguishably from a fetch/connection failure.
Honest severity: LinkPipeline/process_url() still has zero production callers (referenced only from api/knowledge_scrape_test.py), so this closes a latent gap, not an active resource-exhaustion incident.
#13037 — larger than filed, and repointed rather than deleted. The assertion at line 25 named Orchestrator.tool_registry, which that class has never had (orchestrator.py:159 — only agent_registry). But the same script also unconditionally referenced available_tools, _execute_planned_action and local_worker, none of which exist either, and git log --follow shows the file untouched but for renames and relicensing since before the #5040 orchestrator consolidation. It was testing an architecture that predates the current one. Rather than delete it, its original intent — prove the tool-dispatch pipeline is wired and can execute a tool — was reconstructed and repointed at the real surface, tools.tool_registry.get_tool_registry() (dispatched from task_handlers/executor.py and api/agent.py), as 3 passing tests.
Verification: 528 passing across services/research/, media/link/, tools/tool_registry*, api/knowledge_scrape_test.py, autobot_shared/ssot_config_test.py and tests/test_startup_imports.py; the #13021 test asserts chunk consumption stays bounded, proving the stream is cut rather than a flag being set after a full read; cp-swapped baseline (never git stash) left startup-import smoke at 350/350 before and after; py_compile / flake8 --max-line-length=120 / black --check --line-length=120 clean on every changed file.
Three pre-existing mock-response builders in pipeline_test.py — shared with PR #13022's SSRF-pinning fixtures — needed .content.iter_chunked() added because the read mechanism changed. No assertions were altered and all still pass.
Activity
fix: wire three declared-but-not-enforced defects (research budget, l…
mrveiss commentedon Jul 30, 2026
Fixed by PR #13039, merged to
Dev_new_guiasa2f788889(batched with #13013, #13021, #13037 — all three fully delivered, none dropped).#13013 — wired, not deleted.
services/research/models.py:88'struncated_sourceswas genuinely dead scaffolding (greppedservices/research/*.py: zero appenders). The real truncation point already existed atextractor.py:102(content[:max_content_chars]). It is now recorded byorchestrator._record_truncation_if_needed(), called from_land_page— the one place holding both thebudgetand the pre-slice markdown. Under the never-delete rule, giving the field a true meaning beat removing it.#13021 — enforced during streaming, and the severity is latent rather than live. The cap at
media/link/pipeline.py:79(line moved from 67 since #13019/#13022 landed) was declaration-only;_fetch_and_parse's fallback did an unboundedawait response.text(...). New_read_bounded_content()streams in 64 KiB chunks — mirroringweb_fetch/fetcher.py._fetch_bs4— and stops requesting chunks once the cap is crossed, so an oversized body is refused mid-stream rather than after being read into memory. Enforcing post-hoc would have defeated the point entirely. The limit is nowssot_config.link_pipeline_max_content_bytes(AUTOBOT_LINK_PIPELINE_MAX_CONTENT_BYTES, default 1 MB) instead of a literal, and a rejection logs distinguishably from a fetch/connection failure.Honest severity:
LinkPipeline/process_url()still has zero production callers (referenced only fromapi/knowledge_scrape_test.py), so this closes a latent gap, not an active resource-exhaustion incident.#13037 — larger than filed, and repointed rather than deleted. The assertion at line 25 named
Orchestrator.tool_registry, which that class has never had (orchestrator.py:159— onlyagent_registry). But the same script also unconditionally referencedavailable_tools,_execute_planned_actionandlocal_worker, none of which exist either, andgit log --followshows the file untouched but for renames and relicensing since before the #5040 orchestrator consolidation. It was testing an architecture that predates the current one. Rather than delete it, its original intent — prove the tool-dispatch pipeline is wired and can execute a tool — was reconstructed and repointed at the real surface,tools.tool_registry.get_tool_registry()(dispatched fromtask_handlers/executor.pyandapi/agent.py), as 3 passing tests.Verification: 528 passing across
services/research/,media/link/,tools/tool_registry*,api/knowledge_scrape_test.py,autobot_shared/ssot_config_test.pyandtests/test_startup_imports.py; the #13021 test asserts chunk consumption stays bounded, proving the stream is cut rather than a flag being set after a full read;cp-swapped baseline (nevergit stash) left startup-import smoke at 350/350 before and after;py_compile/flake8 --max-line-length=120/black --check --line-length=120clean on every changed file.Three pre-existing mock-response builders in
pipeline_test.py— shared with PR #13022's SSRF-pinning fixtures — needed.content.iter_chunked()added because the read mechanism changed. No assertions were altered and all still pass.