Skip to content

refactor: add registry-backed tool dispatch spine with decorator plugin tests#14

Open
iamthehobbit wants to merge 7 commits intoShinMegamiBoson:mainfrom
iamthehobbit:op-pr1-registry-spine
Open

refactor: add registry-backed tool dispatch spine with decorator plugin tests#14
iamthehobbit wants to merge 7 commits intoShinMegamiBoson:mainfrom
iamthehobbit:op-pr1-registry-spine

Conversation

@iamthehobbit
Copy link

Summary

This PR introduces a registry-backed tool dispatch foundation and migrates tool handling incrementally while preserving legacy fallback behavior.

It also adds substantial test coverage for the new registry/decorator migration layer.

What’s included

  • Adds ToolRegistry scaffold (agent/tool_registry.py)
  • Moves tool definition filtering/export path to registry-backed flow (with compatibility preserved)
  • Introduces registry-first dispatch (with legacy fallback retained)
  • Adds decorator-collected built-in plugin registration for migrated tools
  • Expands tests for:
    • registry behavior
    • built-in plugin parity
    • registry-first/fallback dispatch behavior
    • tool definition filtering invariants

Tests Added / Coverage

  • tests/test_tool_registry.py (new)
    • duplicate registration behavior
    • handler registration errors
    • try_invoke() handled/unhandled contract
    • decorator metadata/schema copy behavior
  • tests/test_builtin_tool_plugins.py (new)
    • built-in plugin count/name parity with tool definitions
    • metadata/schema parity checks
  • tests/test_engine.py
    • registry-first dispatch precedence
    • legacy fallback when registry returns unhandled
    • injected registry seam coverage
  • tests/test_tool_defs.py
    • filtering mode combinations and mutation isolation

Why

This creates the extension seam needed for external tool plugins while minimizing regression risk:

  • same tool surface
  • same fallback behavior
  • improved internal structure and coverage

Risk / compatibility

  • No intended user-facing behavior changes
  • Legacy dispatch fallback remains in place during migration

ShinMegamiBoson and others added 7 commits February 21, 2026 19:58
… and tests

New data sources cataloged with fetch scripts and validation tests:
- FEC federal campaign finance (API + bulk)
- USASpending.gov federal contracts (API)
- SAM.gov contractor registrations (API)
- SEC EDGAR public company filings (API)
- FDIC BankFind institution data (API)
- ProPublica Nonprofit Explorer / IRS 990 (API)
- Senate lobbying disclosures LD-1/LD-2 (bulk XML)
- EPA ECHO enforcement & compliance (API)
- OSHA inspection data (API)
- OFAC SDN sanctions list (bulk CSV)
- ICIJ Offshore Leaks database (bulk CSV)
- US Census Bureau ACS (API)

All scripts use Python stdlib only. 104 new tests pass (18 skip
without API keys or network). Wiki index updated with new categories.
- Replace _ThinkingDisplay with _ActivityDisplay supporting three modes:
  thinking (cyan), streaming response (green), tool execution (yellow)
- Auto-transition from thinking→streaming on first text delta
- Show step counter (Step N/max) in activity spinner
- Show tool name and key argument during tool execution
- Add engine cancellation via threading.Event (_cancel flag)
- Run agent in background thread so user can type next question
- Queue typed input during agent execution (FIFO)
- ESC key binding cancels the running agent
- Add 13 tests covering ActivityDisplay, cancellation, and queuing
Extends ToolResult with optional ImageData payload and adds a read_image
tool that reads PNG/JPEG/GIF/WebP files, base64-encodes them, and passes
them through to the model layer in provider-specific formats (Anthropic
content blocks, OpenAI data URI in user messages).
Add 5 reusable analysis scripts:
- quickstart_investigation.py: starter template for investigations
- scripts/entity_resolution.py: entity linking pipeline
- scripts/cross_link_analysis.py: cross-referencing engine
- scripts/build_findings_json.py: report synthesis utility
- scripts/timing_analysis.py: statistical timing correlation

Fix TUI flicker by making _ActivityDisplay a Rich renderable (__rich__
protocol) so Live's 8fps auto-refresh polls state instead of feed()
forcing update() on every token delta.
Tell the agent about replay.jsonl, events.jsonl, and state.json in its
session directory so it can read its own prior transcripts and recall
earlier work within a session.
…ape sequences

Root cause: prompt_toolkit's patch_stdout() wraps sys.stdout with StdoutProxy
which corrupts Rich's ANSI escape sequences — replacing ESC bytes (0x1b) with
'?' (0x3f). This caused raw escape codes like ?[2K?[1A?[2K to appear as
visible text instead of being interpreted by the terminal.

Fix: scope patch_stdout() to only wrap session.prompt(), not the entire main
loop. During agent execution, Rich's Live writes directly to the real stdout
with correct escape sequences. Also remove the secondary prompt loop (which
compounded the issue) and switch cancellation from ESC to Ctrl+C.

Verified via PTY test: 36 correct ESC sequences, 0 corrupted (was 0/16).
@iamthehobbit
Copy link
Author

This PR is part of a tested integration series. Suggested review/merge order: #14 -> #16 -> #15 -> #17.\n\nI had to open all PRs against (GitHub would not allow stacked upstream PR bases using fork-only branches), so later PRs may include overlapping context if viewed standalone.

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.

2 participants