Implementation Plan: Issue #589 - Wire WebToolsConfig to Web Search/Fetch Tools
Status: Draft
Research Doc: .docs/research-issue-589.md
Author: Claude Code
Date: 2026-03-11
Estimated Effort: 4-6 hours
Overview
Summary
Wire the existing WebToolsConfig through to WebSearchTool and WebFetchTool so that configuration file settings for search provider and fetch mode are respected. Maintain backward compatibility with environment variable fallback.
Approach
Add from_config() constructor methods to both tools that accept &WebToolsConfig, modify create_default_registry() to accept an optional config parameter, and update the call site in main.rs to pass the loaded configuration.
Scope
In Scope:
- Add
from_config()toWebSearchToolwith provider selection logic - Add
from_config()toWebFetchToolwith mode selection - Modify
create_default_registry()signature to acceptOption<&WebToolsConfig> - Update
main.rsto pass config when creating the registry - Align provider names in config docs with implementation
- Add unit tests for new methods
- Add integration test for config wiring
Out of Scope:
- Adding new search providers (Brave, Searxng, Google)
- Hot-reloading of tool configuration
- Per-session tool configuration overrides
- Configuration validation beyond basic provider name matching
Avoid At All Cost (from 5/25 analysis):
- Breaking changes to existing
new()constructors - Complex provider registration/management systems
- Async initialization of tools (keep it simple/synchronous)
- Feature flags for provider selection (use config instead)
Architecture
Component Diagram
βββββββββββββββββββ βββββββββββββββββββββββ ββββββββββββββββββββ
β Config File ββββββΆβ Config::load() ββββββΆβ main.rs β
β (web_tools) β β (WebToolsConfig) β β (pass to tools) β
βββββββββββββββββββ βββββββββββββββββββββββ ββββββββββ¬ββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β create_default_registry() β
β βββββββββββββββββββββββ βββββββββββββββββββββββ β
β β WebSearchTool β β WebFetchTool β β
β β ::from_config() β β ::from_config() β β
β β β β β β
β β - search_provider β β - fetch_mode β β
β β - env fallback β β - env fallback β β
β βββββββββββββββββββββββ βββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββData Flow
main.rs
β
ββββΆ Load Config (from file + env)
β
ββββΆ create_default_registry(config.web_tools.as_ref())
β β
β ββββΆ WebSearchTool::from_config(config)
β β ββββΆ Check config.search_provider
β β ββββΆ Fall back to env vars (EXA_API_KEY, KIMI_API_KEY)
β β ββββΆ Return configured provider
β β
β ββββΆ WebFetchTool::from_config(config)
β ββββΆ Check config.fetch_mode
β ββββΆ Fall back to "raw"
β ββββΆ Return configured tool
β
ββββΆ Registry ready for useKey Design Decisions
| Decision | Rationale | Alternatives Rejected |
|----------|-----------|----------------------|
| Keep new() as env-only fallback | Backward compatibility - existing code continues to work | Removing new() would break API |
| from_config() takes Option<&WebToolsConfig> | Handles case where config is not available | Requiring &WebToolsConfig would force caller to construct dummy config |
| Provider selection by name string | Simple matching, easy to extend | Enum-based selection would require config changes |
| Update config docs to match impl | Less code, less confusion than name mapping | Name mapping adds unnecessary complexity |
Eliminated Options (Essentialism)
| Option Rejected | Why Rejected | Risk of Including | |-----------------|--------------|-------------------| | Provider name mapping (brave->exa) | Adds code complexity for little value | Maintenance burden, confusion about which names work | | Async tool initialization | Tools don't need async for init | Unnecessary complexity, compat issues | | Builder pattern for tools | Overkill for two config fields | API surface expansion, more code to maintain | | Trait-based provider registration | Too complex for current needs | Premature abstraction |
Simplicity Check
What if this could be easy?
The simplest design is:
- Add a constructor that takes config
- If config has a value, use it
- Otherwise, fall back to env vars (existing behavior)
- Update the registry creation to pass config through
This is exactly what this plan implements. No traits, no builders, no async - just straightforward wiring of existing config to existing tools.
File Changes
Modified Files
| File | Changes |
|------|---------|
| crates/terraphim_tinyclaw/src/tools/web.rs | Add from_config() to WebSearchTool and WebFetchTool |
| crates/terraphim_tinyclaw/src/tools/mod.rs | Update create_default_registry() signature |
| crates/terraphim_tinyclaw/src/main.rs | Pass config to create_default_registry() |
| crates/terraphim_tinyclaw/src/config.rs | Update WebToolsConfig doc comments for provider names |
No New Files
This change modifies existing files only.
No Deleted Files
API Design
Public Functions - WebSearchTool
Public Functions - WebFetchTool
Modified Function - create_default_registry
/// Creates the default tool registry with all standard tools.
///
/// # Arguments
/// * `sessions` - Optional session manager for session-aware tools
/// * `web_tools_config` - Optional web tools configuration
;Updated Config Documentation
Test Strategy
Unit Tests
| Test | Location | Purpose |
|------|----------|---------|
| test_web_search_from_config_exa | tools/web.rs | Verify exa provider selection from config |
| test_web_search_from_config_kimi | tools/web.rs | Verify kimi_search provider selection from config |
| test_web_search_from_config_fallback | tools/web.rs | Verify env fallback when config is None |
| test_web_search_from_config_unknown | tools/web.rs | Verify behavior with unknown provider name |
| test_web_fetch_from_config_raw | tools/web.rs | Verify raw mode selection from config |
| test_web_fetch_from_config_readability | tools/web.rs | Verify readability mode selection from config |
| test_web_fetch_from_config_fallback | tools/web.rs | Verify default when config is None |
Integration Tests
| Test | Location | Purpose |
|------|----------|---------|
| test_config_wired_to_tools | tests/config_wiring.rs | End-to-end test that config values reach tools |
// Integration test outline
Doc Tests
Add doc test examples to from_config() methods showing usage.
Implementation Steps
Step 1: Update WebToolsConfig Documentation
Files: crates/terraphim_tinyclaw/src/config.rs
Description: Update doc comments to match actual provider names
Tests: N/A (documentation only)
Estimated: 15 minutes
// Change from:
/// Web search provider ("brave", "searxng", "google").
// To:
/// Web search provider ("exa", "kimi_search").Step 2: Add from_config() to WebSearchTool
Files: crates/terraphim_tinyclaw/src/tools/web.rs
Description: Implement config-based constructor with provider selection
Tests: Unit tests for provider selection and fallback
Estimated: 1 hour
Step 3: Add from_config() to WebFetchTool
Files: crates/terraphim_tinyclaw/src/tools/web.rs
Description: Implement config-based constructor with mode selection
Tests: Unit tests for mode selection and fallback
Dependencies: Step 2
Estimated: 45 minutes
Step 4: Update create_default_registry Signature
Files: crates/terraphim_tinyclaw/src/tools/mod.rs
Description: Add web_tools_config parameter and use it when creating tools
Tests: Update existing tests to pass None for new parameter
Dependencies: Step 2, Step 3
Estimated: 30 minutes
Step 5: Update main.rs Call Site
Files: crates/terraphim_tinyclaw/src/main.rs
Description: Pass config.web_tools reference when creating registry
Tests: Manual verification that config is wired
Dependencies: Step 4
Estimated: 15 minutes
// Change from:
let tools = new;
// To:
let web_tools_config = config.as_ref.and_then;
let tools = new;Step 6: Add Unit Tests
Files: crates/terraphim_tinyclaw/src/tools/web.rs (in #[cfg(test)] module)
Description: Add comprehensive tests for new constructors
Tests: 6-7 new unit tests
Dependencies: Step 2, Step 3
Estimated: 1 hour
Step 7: Add Integration Test
Files: crates/terraphim_tinyclaw/tests/config_wiring.rs (new file)
Description: End-to-end test verifying config reaches tools
Tests: 1 integration test
Dependencies: Step 4
Estimated: 45 minutes
Step 8: Run Full Test Suite
Files: N/A
Description: Verify no regressions
Tests: cargo test -p terraphim_tinyclaw
Dependencies: All previous steps
Estimated: 15 minutes
Rollback Plan
If issues discovered:
- Revert changes to
web.rs,mod.rs,main.rs,config.rs - Restore original
create_default_registry(Some(sessions.clone()))call in main.rs - Verify tests pass:
cargo test -p terraphim_tinyclaw
No feature flags required - the change is purely additive to the API.
Dependencies
No New Dependencies
This change uses existing crates only.
No Dependency Updates
Performance Considerations
Expected Performance
| Metric | Target | Current | |--------|--------|---------| | Tool initialization | < 1ms | ~0.5ms | | Config lookup overhead | < 0.1ms | N/A (new) |
No Benchmarks Required
This is a simple wiring change with minimal overhead.
Open Items
| Item | Status | Owner | |------|--------|-------| | Confirm env var precedence (config vs env) | Needs Decision | Engineering | | Verify integration test approach | Pending | Engineering |
Approval Checklist
- [ ] Technical review complete
- [ ] Test strategy approved
- [ ] Backward compatibility verified
- [ ] Human approval received
Appendix: Provider Name Decision
Decision: Update config docs to match implementation ("exa", "kimi_search")
Rationale:
- Simplest solution - just documentation change
- No code complexity added
- Users can see actual available providers
- When new providers are added, just update docs
Rejected: Name mapping
- Adds unnecessary code complexity
- Creates confusion about "which name is canonical"
- More code to maintain and test