Skip to content

feat: GitHunter toolset and forensic trace system#2

Merged
bordumb merged 13 commits intomainfrom
fn-2
Jan 24, 2026
Merged

feat: GitHunter toolset and forensic trace system#2
bordumb merged 13 commits intomainfrom
fn-2

Conversation

@bordumb
Copy link
Contributor

@bordumb bordumb commented Jan 24, 2026

Summary

  • GitHunter Toolset (fn-2): Complete Bond integration for GitHunter adapter with PydanticAI Tool wrappers for repository search, file content retrieval, and commit history
  • Forensic Trace System (fn-3): Full trace persistence and replay capabilities for capturing all 8 StreamHandlers events and replaying them step-by-step like a debugger

Changes

GitHunter Toolset

  • Add _models.py with request models (SearchRequest, ContentRequest, CommitRequest)
  • Add tools.py with create_githunter_toolset() factory
  • Export from bond.tools.githunter
  • 25 unit tests for tool functions

Trace System

  • TraceEvent and TraceMeta dataclasses for event capture
  • TraceStorageProtocol for pluggable storage backends
  • JSONFileTraceStore for file-based persistence
  • create_capture_handlers() factory for recording
  • TraceReplayer with step/seek/iterate navigation
  • 62 unit tests covering all components
  • API documentation and architecture docs

Test plan

  • All 87 new tests pass (pytest tests/unit/)
  • uv run ruff check passes
  • uv run mypy src/bond/ passes
  • mkdocs build --strict passes

🤖 Generated with Claude Code

bordumb and others added 10 commits January 24, 2026 16:45
Add Pydantic request models for GitHunter toolset:
- BlameLineRequest for blame_line tool
- FindPRDiscussionRequest for find_pr_discussion tool
- GetExpertsRequest for get_file_experts tool
- Error model for union return types

All models use Annotated[..., Field(...)] pattern with validators.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add tools.py with PydanticAI tool wrappers for GitHunter:
- blame_line: Get blame info for a specific line
- find_pr_discussion: Find PR discussion for a commit
- get_file_experts: Get file experts by commit frequency

All tools use RunContext[GitHunterProtocol] for dependency injection
and catch GitHunterError to return Error model.

Exports githunter_toolset for BondAgent integration.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive tests for GitHunter tool functions:
- TestBlameLine: success, file not found, line out of range, repo not found
- TestFindPRDiscussion: success, None case, rate limited, repo not found
- TestGetFileExperts: success, empty list, repo not found, file not found

Includes MockGitHunter implementing GitHunterProtocol for testing.
All 13 tests pass with mypy and ruff checks.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update __init__.py to export:
- githunter_toolset for BondAgent integration
- BlameLineRequest, FindPRDiscussionRequest, GetExpertsRequest
- Error model for union return types

Add GitHunter section to docs/api/tools.md with:
- Protocol documentation
- Type documentation (BlameResult, FileExpert, PRDiscussion, AuthorProfile)
- Request model documentation
- Toolset documentation

Verified:
- Imports work: from bond.tools.githunter import githunter_toolset
- mkdocs build --strict passes
- All 51 GitHunter tests pass

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create src/bond/trace/ module with:
- TraceEvent: Frozen dataclass for all 8 StreamHandlers callbacks
- TraceMeta: Metadata for trace listing without loading events
- TraceStorageProtocol: @runtime_checkable interface for backends

Event types: block_start, block_end, text_delta, thinking_delta,
tool_call_delta, tool_execute, tool_result, complete

Both models have to_dict/from_dict for JSON serialization.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add JSONFileTraceStore implementing TraceStorageProtocol:
- Stores events as newline-delimited JSON ({trace_id}.json)
- Stores metadata separately ({trace_id}.meta.json)
- Supports save_event, finalize_trace, load_trace, list_traces, delete_trace
- AsyncIterator for memory-efficient trace loading

Dependencies:
- Add aiofiles>=24.0.0 for async file operations
- Add types-aiofiles>=24.0.0 for mypy stubs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add create_capture_handlers() that wires all 8 StreamHandlers callbacks
to record TraceEvents with sequence numbers for ordering.

Features:
- Auto-generates trace_id UUID if not provided
- Uses monotonic clock for relative timestamps
- Sync callbacks schedule async saves via event loop
- finalize_capture() helper marks trace complete/failed

Pattern follows create_websocket_handlers() from utils.py.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add TraceReplayer class with:
- Async iteration support (async for event in replayer)
- Manual stepping: step(), step_back()
- Position seeking: seek(position), reset()
- Properties: position, total_events, current()

Events loaded on-demand and cached for stepping operations.
Fix protocol: load_trace is async generator, not async function.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add comprehensive unit tests for trace module (62 tests):
  - test_models.py: TraceEvent/TraceMeta serialization
  - test_json_store.py: JSONFileTraceStore operations
  - test_capture.py: create_capture_handlers factory
  - test_replay.py: TraceReplayer navigation
- Export trace types from bond package __init__.py
- Add docs/api/trace.md with API reference
- Add Trace Persistence section to docs/architecture.md
- Add trace to mkdocs.yml navigation

Closes fn-3.5

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All fn-3 tasks complete. Forensic Features epic finished.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@bordumb bordumb self-assigned this Jan 24, 2026
bordumb and others added 3 commits January 24, 2026 17:23
- Add proper ```python and ```json fencing to all Example: sections
  in docstrings so mkdocstrings renders them with syntax highlighting
- Fix Message Types section in utils.py to use ```json block
- Create docs/guides/githunter.md with usage guide for GitHunter toolset
- Add Guides section to mkdocs.yml navigation

Files fixed:
- src/bond/utils.py (3 sections)
- src/bond/trace/capture.py (2 examples)
- src/bond/trace/backends/json_file.py (1 example)
- src/bond/tools/githunter/tools.py (3 examples)
- src/bond/tools/schema/tools.py (4 examples)
- src/bond/tools/memory/tools.py (4 examples)
- src/bond/tools/memory/backends/pgvector.py (1 example)
- src/bond/tools/memory/backends/qdrant.py (1 example)
- src/bond/tools/memory/backends/__init__.py (1 example)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add .pre-commit-config.yaml with hooks for:
  - ruff format --check (matches CI lint job)
  - ruff check (matches CI lint job)
  - mypy (matches CI typecheck job)
- Add pre-commit>=3.5.0 to dev dependencies
- Fix ruff format issues in 5 files
- Fix unused imports in test_json_store.py

Install: uv run pre-commit install
Run manually: uv run pre-commit run --all-files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace frozen dataclasses with Pydantic BaseModel for unified serialization
with the Memory subsystem. This removes manual to_dict/from_dict methods in
favor of Pydantic's model_dump/model_validate methods.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@bordumb bordumb merged commit c4b42c1 into main Jan 24, 2026
5 checks passed
@bordumb bordumb deleted the fn-2 branch January 24, 2026 17:40
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