Skip to content

claude-code-chat-browser: Tool dispatch coordination - single authoritative KNOWN_TOOL_TYPES registry#104

Merged
wpak-ai merged 4 commits into
masterfrom
refactor/tool-dispatch-coordination
Jun 30, 2026
Merged

claude-code-chat-browser: Tool dispatch coordination - single authoritative KNOWN_TOOL_TYPES registry#104
wpak-ai merged 4 commits into
masterfrom
refactor/tool-dispatch-coordination

Conversation

@clean6378-max-it

@clean6378-max-it clean6378-max-it commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Closes #99

Summary

Establishes a single authoritative KNOWN_TOOL_TYPES registry in utils/tool_dispatch.py and wires the four dispatch sites that previously shared tool name strings only by convention. Adds tests/test_tool_dispatch_sync.py so CI fails with a clear message when any site drifts.

Sprint item #3 (Tuesday PR 1 of 2). Companion PR #4 will generate static/tool_types.json from KNOWN_TOOL_TYPES.

Problem

Adding a new Claude Code tool type required coordinated edits across:

  • utils/tool_dispatch.py
  • file-activity tracking in utils/jsonl_parser.py
  • utils/md_exporter.py
  • frontend TOOL_USE_RENDERERS in static/js/render/registry.js

There was no compile-time or test-time check that all four were updated together.

Changes

  • utils/tool_dispatch.pyKNOWN_TOOL_TYPE_NAMES / KNOWN_TOOL_TYPES; _FILE_ACTIVITY_HANDLERS and track_tool_file_activity() (one entry per known type, None when there are no side effects)
  • utils/jsonl_parser.py — delegates file activity to track_tool_file_activity(); removes local _track_file_activity
  • utils/md_exporter.py — imports KNOWN_TOOL_TYPES; exports MD_EXPORTER_TOOL_TYPES for sync; labels unknown tool types in the fallback branch
  • tests/test_tool_dispatch_sync.py (new) — asserts KNOWN_TOOL_TYPES matches FILE_ACTIVITY_TOOL_TYPES, MD_EXPORTER_TOOL_TYPES, and frontend TOOL_USE_RENDERERS keys
  • models/tool_results.py — adds AskUserQuestion to ToolNameLiteral (was missing vs frontend)
  • CONTRIBUTING.md — documents the “add a new tool type” procedure

Out of scope

Test plan

  • pytest tests/test_tool_dispatch_sync.py -q
  • pytest -q (417 passed)
  • mypy -p api -p utils -p models
  • mypy tests --config-file mypy-tests.ini --follow-imports skip
  • ruff check on changed files
  • Manual: remove a tool type from TOOL_USE_RENDERERS — confirm sync test fails naming the missing type and site, then revert

Summary by CodeRabbit

  • New Features
    • Added support for an additional assistant tool type to expand compatibility with more tool interactions.
  • Bug Fixes
    • Improved Markdown exports by using clearer labels for tool inputs, distinguishing known versus unknown tool types.
    • Enhanced consistency of tool activity tracking across file, command, and web lookups.
  • Documentation
    • Updated contribution guidance with a coordinated checklist for adding new tool types and keeping dispatch/render support in sync.
  • Tests
    • Added a contract test to detect mismatches in supported tool types across the system.

Adding a Claude Code tool use name required coordinated edits across
tool_dispatch, jsonl_parser file activity, md_exporter, and the frontend
registry with no test-time guard against drift.
Define KNOWN_TOOL_TYPES in utils/tool_dispatch.py, move file-activity
tracking to track_tool_file_activity(), wire md_exporter to the registry,
and add tests/test_tool_dispatch_sync.py to assert all four sites stay
in sync. Document the add-a-tool-type procedure in CONTRIBUTING.md.
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a shared tool-type registry, routes assistant file-activity tracking through it, updates tool-name typing and markdown export, adds a sync test for backend and frontend declarations, and documents the required update steps.

Changes

Tool Type Registry and Sync Enforcement

Layer / File(s) Summary
Registry and activity tracking
utils/tool_dispatch.py
Adds the tool-type addition checklist, _FILE_ACTIVITY_HANDLERS, KNOWN_TOOL_TYPES, and track_tool_file_activity for known tool inputs.
Assistant parsing uses shared tracker
utils/jsonl_parser.py
Imports track_tool_file_activity and replaces the local file-activity call in _process_assistant.
Tool rendering and typing updates
utils/md_exporter.py, models/tool_results.py
Changes the unknown-tool fallback label and adds "AskUserQuestion" to ToolNameLiteral.
Tool-type sync contract test
tests/test_tool_dispatch_sync.py
Parses backend and frontend tool-type declarations and asserts they match KNOWN_TOOL_TYPES.
Tool type addition documentation
CONTRIBUTING.md
Adds the new checklist row and “Adding a new tool type” section.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • timon0305
  • wpak-ai

Poem

🐇 One registry now rings clear,
No wandering tool names here.
The sync test hums, the docs align,
And bunny paws keep strings in line.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.08% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the core change: centralized tool dispatch coordination around KNOWN_TOOL_TYPES.
Linked Issues check ✅ Passed The PR implements the shared KNOWN_TOOL_TYPES registry, updates the dispatch consumers, adds sync tests, and documents the new-tool workflow.
Out of Scope Changes check ✅ Passed The changes stay within tool-dispatch coordination, sync testing, typing, and documentation; no unrelated scope is evident.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/tool-dispatch-coordination

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
utils/md_exporter.py (1)

327-328: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

The known-type "Input" label is currently unreachable.

Every entry in KNOWN_TOOL_TYPES already has a dedicated if/elif branch above, so any name reaching this else is by definition not in KNOWN_TOOL_TYPES. The conditional therefore always yields "Input (unknown tool type)". This is harmless as forward-compat defense, but the "Input" arm only matters if a future known tool lacks an explicit branch — consider a comment to that effect or simplifying.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@utils/md_exporter.py` around lines 327 - 328, The fallback label in the
`md_exporter.py` input-rendering branch is effectively unreachable because all
`KNOWN_TOOL_TYPES` are already handled earlier in the `if/elif` chain. Update
the `label` logic near the `lines.append(...)` path to either simplify it to the
unknown-tool label only, or add a short comment in that branch explaining it is
forward-compatibility for future known tool types without explicit handling.
tests/test_tool_dispatch_sync.py (1)

49-58: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Parser runs at collection time, surfacing failures as a collection error.

_parse_frontend_tool_use_renderers(_FRONTEND_REGISTRY) is evaluated inside the @pytest.mark.parametrize decorator, so a missing/renamed registry.js or a regex miss raises ValueError during collection rather than as a clean test failure. Consider reading/parsing inside the test body (or a fixture) so the contract violation is reported as a failing assertion with the intended diagnostic.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_tool_dispatch_sync.py` around lines 49 - 58, The frontend registry
parsing is happening too early in the test setup, which turns missing or
malformed registry data into a collection error instead of a normal test
failure. Move the `_parse_frontend_tool_use_renderers` call out of the
`@pytest.mark.parametrize` arguments in `test_tool_dispatch_sync` and into the
test body or a fixture, using `_FRONTEND_REGISTRY` there so any parse/contract
violation is reported through an assertion with the intended diagnostic.
utils/tool_dispatch.py (1)

238-251: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: derive the registry from a single source to cut in-file duplication.

KNOWN_TOOL_TYPE_NAMES and the keys of _FILE_ACTIVITY_HANDLERS are two hand-maintained lists in the same module that the sync test forces to be equal. You can make _FILE_ACTIVITY_HANDLERS the single source and derive the others, removing one drift surface (the cross-file md_exporter/frontend checks still hold).

♻️ Possible simplification
-KNOWN_TOOL_TYPE_NAMES: tuple[str, ...] = (
-    "AskUserQuestion",
-    ...
-    "Write",
-)
-KNOWN_TOOL_TYPES: frozenset[str] = frozenset(KNOWN_TOOL_TYPE_NAMES)
+# defined after _FILE_ACTIVITY_HANDLERS below
 FILE_ACTIVITY_TOOL_TYPES: frozenset[str] = frozenset(_FILE_ACTIVITY_HANDLERS)
+KNOWN_TOOL_TYPES: frozenset[str] = FILE_ACTIVITY_TOOL_TYPES
+KNOWN_TOOL_TYPE_NAMES: tuple[str, ...] = tuple(sorted(_FILE_ACTIVITY_HANDLERS))

Also applies to: 288-301

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@utils/tool_dispatch.py` around lines 238 - 251, `KNOWN_TOOL_TYPE_NAMES` is
duplicating the tool registry already maintained in `_FILE_ACTIVITY_HANDLERS`,
so reduce drift by making `_FILE_ACTIVITY_HANDLERS` the single source of truth
and deriving `KNOWN_TOOL_TYPE_NAMES` and `KNOWN_TOOL_TYPES` from its keys.
Update the related registry setup in `tool_dispatch.py` so the sync test still
passes without keeping two hand-maintained lists in parallel, and keep the
existing tool type symbols (`KNOWN_TOOL_TYPE_NAMES`, `KNOWN_TOOL_TYPES`,
`_FILE_ACTIVITY_HANDLERS`) aligned.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CONTRIBUTING.md`:
- Around line 144-153: The new-tool checklist is missing the typed backend
contract update, so extend the `Adding a new tool type` guidance to mention
`models/tool_results.py` and the `ToolNameLiteral`/tool result type definitions
used for `AskUserQuestion`. Update the same checklist section that references
`utils/tool_dispatch.py`, `utils/md_exporter.py`, and
`static/js/render/registry.js` so it also tells contributors to add the new tool
name to the backend type literals and result model, ensuring the guide covers
both runtime dispatch and typed schema changes.

---

Nitpick comments:
In `@tests/test_tool_dispatch_sync.py`:
- Around line 49-58: The frontend registry parsing is happening too early in the
test setup, which turns missing or malformed registry data into a collection
error instead of a normal test failure. Move the
`_parse_frontend_tool_use_renderers` call out of the `@pytest.mark.parametrize`
arguments in `test_tool_dispatch_sync` and into the test body or a fixture,
using `_FRONTEND_REGISTRY` there so any parse/contract violation is reported
through an assertion with the intended diagnostic.

In `@utils/md_exporter.py`:
- Around line 327-328: The fallback label in the `md_exporter.py`
input-rendering branch is effectively unreachable because all `KNOWN_TOOL_TYPES`
are already handled earlier in the `if/elif` chain. Update the `label` logic
near the `lines.append(...)` path to either simplify it to the unknown-tool
label only, or add a short comment in that branch explaining it is
forward-compatibility for future known tool types without explicit handling.

In `@utils/tool_dispatch.py`:
- Around line 238-251: `KNOWN_TOOL_TYPE_NAMES` is duplicating the tool registry
already maintained in `_FILE_ACTIVITY_HANDLERS`, so reduce drift by making
`_FILE_ACTIVITY_HANDLERS` the single source of truth and deriving
`KNOWN_TOOL_TYPE_NAMES` and `KNOWN_TOOL_TYPES` from its keys. Update the related
registry setup in `tool_dispatch.py` so the sync test still passes without
keeping two hand-maintained lists in parallel, and keep the existing tool type
symbols (`KNOWN_TOOL_TYPE_NAMES`, `KNOWN_TOOL_TYPES`, `_FILE_ACTIVITY_HANDLERS`)
aligned.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1b04bcab-9f30-41a5-b8da-51ff257d8225

📥 Commits

Reviewing files that changed from the base of the PR and between bddbda3 and 9104d31.

📒 Files selected for processing (6)
  • CONTRIBUTING.md
  • models/tool_results.py
  • tests/test_tool_dispatch_sync.py
  • utils/jsonl_parser.py
  • utils/md_exporter.py
  • utils/tool_dispatch.py

Comment thread CONTRIBUTING.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@utils/md_exporter.py`:
- Around line 326-327: The fallback in the markdown exporter is mislabeling
known-but-unhandled tool names as “unknown,” which can hide missing renderers.
Update the export logic in md_exporter.py around the Input formatting branch so
it distinguishes truly unknown tool types from names already listed in
MD_EXPORTER_TOOL_TYPES, and change the fallback message to reflect that the tool
is known but lacks a specialized renderer; use the surrounding exporter function
and the MD_EXPORTER_TOOL_TYPES check to locate the branch.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d00a0348-06fe-4be7-abdc-44ea8e2602ae

📥 Commits

Reviewing files that changed from the base of the PR and between 9104d31 and 44d7c6b.

📒 Files selected for processing (5)
  • CONTRIBUTING.md
  • tests/test_tool_dispatch_sync.py
  • utils/jsonl_parser.py
  • utils/md_exporter.py
  • utils/tool_dispatch.py
💤 Files with no reviewable changes (1)
  • utils/jsonl_parser.py
✅ Files skipped from review due to trivial changes (1)
  • CONTRIBUTING.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/test_tool_dispatch_sync.py
  • utils/tool_dispatch.py

Comment thread utils/md_exporter.py Outdated
Comment thread utils/tool_dispatch.py Outdated
Comment thread utils/md_exporter.py Outdated
Comment thread utils/tool_dispatch.py Outdated
Comment thread tests/test_tool_dispatch_sync.py Outdated
Comment thread models/tool_results.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/test_tool_dispatch_sync.py (1)

66-81: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Parse _render_tool_use with ast instead of regex.

This helper is tied to the current source spelling in utils/md_exporter.py — double-quoted if/elif comparisons, elif name in (...), and the next top-level def boundary. A harmless refactor there can make the sync test fail even when the handled tool set is unchanged.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_tool_dispatch_sync.py` around lines 66 - 81, Replace the
regex-based parsing in _parse_md_exporter_tool_use_handlers with AST-based
inspection of utils/md_exporter.py so the test derives handled tool names from
the _render_tool_use function structure rather than source spelling. Locate the
helper by its existing name, parse the module, find the _render_tool_use
definition, and collect names from if/elif comparisons on name (including
membership checks) in a way that is insensitive to quote style, formatting, or
nearby top-level defs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/test_tool_dispatch_sync.py`:
- Around line 66-81: Replace the regex-based parsing in
_parse_md_exporter_tool_use_handlers with AST-based inspection of
utils/md_exporter.py so the test derives handled tool names from the
_render_tool_use function structure rather than source spelling. Locate the
helper by its existing name, parse the module, find the _render_tool_use
definition, and collect names from if/elif comparisons on name (including
membership checks) in a way that is insensitive to quote style, formatting, or
nearby top-level defs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 77148343-a8e3-41b4-b554-a2d09d6cdb36

📥 Commits

Reviewing files that changed from the base of the PR and between 69bdded and d0e6f39.

📒 Files selected for processing (4)
  • CONTRIBUTING.md
  • tests/test_tool_dispatch_sync.py
  • utils/md_exporter.py
  • utils/tool_dispatch.py
💤 Files with no reviewable changes (1)
  • utils/tool_dispatch.py
✅ Files skipped from review due to trivial changes (2)
  • CONTRIBUTING.md
  • utils/md_exporter.py

@timon0305 timon0305 requested a review from wpak-ai June 30, 2026 20:17
@wpak-ai wpak-ai merged commit 7f685e4 into master Jun 30, 2026
16 checks passed
@wpak-ai wpak-ai deleted the refactor/tool-dispatch-coordination branch June 30, 2026 21:10
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.

claude-code-chat-browser: Tool dispatch coordination — single authoritative KNOWN_TOOL_TYPES registry

3 participants