TOOLS
Tools System
Tools are one of three capability tiers in Chalie:
-
Innate Skills (
backend/services/innate_skills/) — Built-in cognitive capabilities with direct access to Chalie’s services, database, and memory. Always injected into the LLM context. Examples:recall,memorize,schedule,list,document,find_tools,reflect. -
Tools (
backend/tools/) — First-party capabilities committed to the repo. Simple callable Python modules invoked directly in-process. All metadata declared inToolLibraryService. This document covers these. -
Interfaces (
frontend/_interfaces/) — External third-party integrations that pair with Chalie via the interface protocol. Can expose capabilities and update world state. See 15-INTERFACES.md.
Overview
The tools system provides:
- Direct invocation: First-party tools are called in-process (no subprocess, no IPC)
- Interface tools: External applications can pair with Chalie and expose tool capabilities via the interface protocol
- Configuration Management: Per-tool secrets and credentials stored in SQLite (encrypted)
- Semantic Matching: Tool relevance determined via embedding-based similarity, not regex patterns
- Audit Trail: All tool invocations logged to procedural memory with success/failure and execution time
Architecture
Components
Tool Library Service (backend/services/tool_library_service.py)
- Single source of truth for first-party tool metadata and handlers
- All tool descriptions, parameters, and constraints declared in Python (like innate skills)
- Maps tool names to handler functions imported from
backend/tools/*.py
Tool Registry Service (backend/services/tool_registry_service.py)
- Singleton that loads tools from ToolLibraryService at startup
- Invokes first-party tools directly in-process
- Routes interface tools via HTTP to paired interfaces
- Logs outcomes for feedback/learning
Tool Config Service
- SQLite backend for per-tool configuration
- Stores API keys, credentials, and parameters as key-value pairs
- Secrets are masked in API responses (shows
***instead of actual value)
Tool Profile Service (backend/services/tool_profile_service.py)
- LLM-generated tool capability profiles with triage triggers and usage scenarios
- Powers the
find_toolsinnate skill (semantic search against capability embeddings)
REST API (backend/api/tools.py)
- List tools with status and config schema
- Get/set/delete tool configuration
- Test tool configuration completeness
Tool Interface
All first-party tools expose a single function:
def execute(topic: str, params: dict, config: dict = None, telemetry: dict = None) -> dict
Input parameters:
| Arg | Contents |
|---|---|
topic |
Current conversation topic |
params |
LLM-extracted parameters matching tool schema |
config |
Per-tool config from database (API keys, endpoints) |
telemetry |
Flattened client context (location, time, locale — fields may be null) |
Return dict:
| Key | Description |
|---|---|
text |
Plain text result (optional). If output.synthesize: true, rewritten in Chalie’s voice |
html |
HTML fragment for UI card (optional). Inline CSS only, no JS, no dangerous tags |
title |
Dynamic card title override (optional) |
error |
Error message — if present, triggers fallback and skips text/html |
Using Tools
Configure Tool via REST API
-
List available tools:
curl http://localhost:8081/tools \ -H "Authorization: Bearer YOUR_API_KEY" -
Set configuration (API keys, endpoints):
curl -X PUT http://localhost:8081/tools/my_tool/config \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"api_key": "sk-...", "endpoint": "https://..."}' -
Test configuration:
curl -X POST http://localhost:8081/tools/my_tool/test \ -H "Authorization: Bearer YOUR_API_KEY"Returns
{"ok": true, "message": "Configuration looks complete"}if all required keys are set. -
Get configuration (secrets masked):
curl http://localhost:8081/tools/my_tool/config \ -H "Authorization: Bearer YOUR_API_KEY" -
Delete a config key:
curl -X DELETE http://localhost:8081/tools/my_tool/config/api_key \ -H "Authorization: Bearer YOUR_API_KEY"
Tool Execution Flow
When the LLM decides to use a tool during the unified generation path:
- Discovery — LLM uses the
find_toolsinnate skill to search available tools by capability - Selection — LLM decides which tool to invoke based on capability profiles
- Parameter Extraction — LLM extracts parameters from conversation context
- Configuration Injection — ToolConfigService fetches stored API keys/endpoints
- Direct Invocation — Handler called in-process via
ToolLibraryService.get_handler() - Output Sanitization — Result stripped of action-like patterns, truncated to 3000 chars
- Memory Logging — Outcome (success/failure, execution time) logged to procedural memory
- Integration — Tool output wrapped in
[TOOL:name]...[/TOOL]markers and included in LLM context
Tool Status
Tools have three status values (from API /tools endpoint):
- “system” — Built-in tool with no configuration required
- “available” — Tool discovered but not yet configured (missing required secrets)
- “connected” — Tool fully configured and ready to use
Safety & Constraints
Timeouts
- Default timeout: 9 seconds
- Configurable per tool in
constraints.timeout_seconds - Exceeded timeouts logged as failures in procedural memory
Cost Budgets
Optional per-tool budget tracking (if tool returns budget_remaining field):
- Budget info included in tool output metadata
- Useful for API-based tools (e.g., search engines with rate limits)
Output Sanitization
Tool output is sanitized before integration:
- Removes action-like patterns:
{...}, function calls, ACTION: keywords - Prevents tool output from instructing Chalie to take unintended actions
- Truncated to 3000 characters max
Troubleshooting
Tool Not Appearing in List
- Check the tool has an entry in
TOOL_HANDLERSandTOOL_METADATAinbackend/services/tool_library_service.py - Check the tool module exists:
backend/tools/tool_name.py - Check the module exposes
execute(topic, params, config, telemetry) -> dict - View logs in the
python backend/run.pyconsole output
“Tool not found” Error
Tool name in TOOL_HANDLERS must match the name used in TOOL_METADATA exactly.
Configuration Not Being Used
- Verify config is set:
curl http://localhost:8081/tools/my_tool/config - Test configuration:
curl -X POST http://localhost:8081/tools/my_tool/test - Check required keys are present (marked with
"required": true)
Tool Timeout
- Increase
timeout_secondsinTOOL_METADATAconstraints:"constraints": {"timeout_seconds": 30} - Optimize tool code (database queries, API calls, etc.)
Safety Guardrails
- Kill Switch: Set
tools_enabled: falsein config to disable all tools - Declared Library: Tools are declared in
ToolLibraryService, not discovered by scanning - Single Authority: Procedural memory (reward signal) is single authority for tool retraining
- Data Scope: All tool invocations scoped to topic (no cross-topic leakage)
- Audit Trail: Every invocation logged with topic, success/failure, execution time