Skip to content

fix(api): make api/registry.py report the prefixes the app actually mounts (#15120) - #15132

Merged
mrveiss merged 3 commits into
Dev_new_guifrom
issue-15120-registry-prefix
Aug 28, 2026
Merged

mrveiss merged 3 commits into
Dev_new_guifrom
issue-15120-registry-prefix

Conversation

@mrveiss

@mrveiss mrveiss commented Aug 26, 2026

Copy link
Copy Markdown
Owner

Thinking Path

The issue frames this as one wrong prefix. It is not a style choice which spelling is
real, so I established it empirically before editing either side.

agent_config (underscore) is the served path. Four independent sources agree:

Evidence Kind
autobot-frontend/src/types/generated/api.ts — 11 paths under /api/agent_config/, 0 under /api/agent-config/ CI (regenerated from app.openapi() by the required verify-generated-types)
libs/autobot-sdk-python/autobot_sdk/resources/agents.py:37,44,48 calls /agent_config/agents/... static
repo_tests/sdk_request_url_test.py:149-156 pins /api/agent_config/... unit
An archived probe recorded /api/agent-config/ returning 404 - Endpoint not found historical

So the mount is right and the registry entry is what is wrong. Changing the mount would
have broken the SDK, the generated types and two test files.

There is also no repo-wide convention to follow: the mounts use both spellings
(agent_config, intelligent_agent underscore; research-browser, service-monitor,
system-validation hyphen). That is a second reason not to touch mounts — only to make
the registry report reality.

Writing the guard then showed the defect is ten of thirty-one entries, not one:
six advertise a prefix nothing serves, and four name a module a consolidation deleted.
The worst was api.service_monitor, advertising /api/monitoring — a real prefix
belonging to api.monitoring, so a reader following the registry landed on a live
namespace serving something else.

And the harm the issue predicted had already happened inside the backend:
middleware/llm_awareness_middleware.py:65 had copied the hyphen into its
enable_for_paths default. _should_inject_context is a startswith over that list,
so awareness context was never injected for a router the middleware names
explicitly, silently, since the paths diverged. That is fixed here because it is the
same defect's direct consequence, not a separate concern.

On the #15112 dependency: not needed. That PR's effective_routes traversal
answers a runtime question. Both tables here are source-level data, so the guard reads
them through autobot_shared/api_routing/router_prefixes.py — the single grammar
#12985 established, already merged and already relied on by the blocking api-wiring
gate. No new traversal is written and none of #15112's files are touched, so the
two PRs cannot conflict and neither blocks the other. This also sidesteps the
fastapi-version hazard entirely: nothing here introspects a FastAPI object, so local and
CI resolutions cannot disagree.

What Changed

autobot-backend/api/registry.py — six prefixes corrected to the mounted path:

entry advertised now
agent_config /api/agent-config /api/agent_config
intelligent_agent /api/intelligent-agent /api/intelligent_agent
research_browser /api/research /api/research-browser
service_monitor /api/monitoring /api/service-monitor
system_validation /api/system_validation /api/system-validation
websockets "" /api

…and four module_paths repointed to the module that carries the router today, each
verified against the mount tuples rather than guessed:

entry named now why
batch api.batch api.batch_jobs consolidated by #1287; prefix also corrected to /api/batch-jobs
cache api.cache api.cache_management consolidated by #1286
chat_consolidated api.chat_consolidated api.chat module removed; api.chat mounts at the same /api
infrastructure_monitor api.infrastructure_monitor api.infrastructure module removed; same /api/infrastructure

Dict keys and name= fields are deliberately left alone: they are path-parameter values
for GET /api/registry/router/{router_name}, and none of them is a claim about routing.

autobot-backend/middleware/llm_awareness_middleware.py — enable_for_paths default
/api/intelligent-agent → /api/intelligent_agent. initialization/middleware.py:151
docstring likewise.

New guard repo_tests/registry_prefix_agreement_test.py (6 tests) — three
non-vacuity tests over the enumerations, then: every advertised module exists, every
advertised prefix is a mounted prefix, every advertised router is one the app factory
mounts. Both sides resolve to files through resolve_registry_targets, so a package
entry (api.user_management) lines up with a mount of its submodule
(api.user_management.router).

New test autobot-backend/middleware/llm_awareness_paths_test.py (8 tests) — served
paths must reach the middleware, and paths nothing answers on must not (the contrast, so
a list holding both spellings would not pass).

Verification

All evidence is against the final head, 071b9da6c.

Criterion Evidence Kind
registry reports the mounted prefix registry_prefix_agreement_test.py 6 passed static
next divergence fails CI mutations 1–3 below static
guard fails on an empty enumeration mutation 3: 5 of 6 tests red static
awareness middleware matches served paths llm_awareness_paths_test.py 8 passed unit
mounts unchanged → OpenAPI unchanged no mount site edited; types/generated/api.ts untouched CI (verify-generated-types)

Contrast mutations, each run against the final head and reverted:

  1. Restore prefix="/api/agent-config" →
    AssertionError: api/registry.py advertises prefixes the app does not serve:
    api/agent_config.py: advertised ['/api/agent-config'] but mounted at ['/api/agent_config']
  2. Restore module_path="api.batch" →
    AssertionError: api/registry.py names modules that do not exist: api.batch (advertised at '/api/batch-jobs')
  3. Make the advertised enumeration return empty → 5 of 6 tests fail, including
    AssertionError: only 0 RouterConfig entries parsed out of registry.py; the agreement assertions below would range over almost nothing
    and AssertionError: only 0 files are named by both tables (0 advertised, 290 mounted)
  4. Restore the hyphen in enable_for_paths →
    AssertionError: /api/intelligent_agent/process is mounted and serves POST, but the awareness filter skips it; enable_for_paths=['/api/chat', '/api/llm', '/api/intelligent-agent', '/api/workflow']

Shards (repo_tests/stable_shard.py, --shard-splits 12):
repo_tests/registry_prefix_agreement_test.py → shard 10;
autobot-backend/middleware/llm_awareness_paths_test.py → shard 4.

Not proven here: agents/multi_agent_workflow_validation_test.py:121 probes
/api/intelligent-agent/deploy and /api/research/deploy — both copied from the stale
registry values, and neither endpoint exists under any spelling (the router serves
/process, /system-info, /reload). That is a script probing endpoints that were
never built, a different defect from a misspelled prefix, so it is filed separately
rather than guessed at here.

Model Used

Claude Opus 5 (1M context)

Closes #15120

@github-actions

Copy link
Copy Markdown
Contributor

✅ SSOT Configuration Compliance: Passing

🎉 No new hardcoded values of either class — ssot and other both block.

Known backlog in pipeline-scripts/hardcoded_values_baseline.txt is suppressed and tracked in #14371.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant