Deterministic vs Non-Deterministic Tool Usage
Some tools always produce the same output for the same inputs (deterministic); others do not.
Task
Build ToolClassifier that:
- Registers tools with a determinism flag.
- Caches results of deterministic tools by content-hash.
- Always re-executes non-deterministic tools.
- Returns
{'result': Any, 'cached': bool, 'deterministic': bool}.
Constraints
- Non-deterministic tools NEVER use cache.
- Cache key: sha256(JSON of name + sorted kwargs).
- Calling an unknown tool raises
KeyError.
Examples
Example 1:
Input:
tc.register('add', lambda **k: k['a']+k['b'], True)
tc.call('add', a=2, b=3)
tc.call('add', a=2, b=3)Output:
{'result': 5, 'cached': True, 'deterministic': True}Explanation: Second call with same args returns from cache.
Starter Code
from typing import Any, Dict, Callable
import hashlib, json
class ToolClassifier:
def __init__(self):
self.registry: Dict[str, dict] = {}
self.cache: Dict[str, Any] = {}
def register(self, name: str, fn: Callable, deterministic: bool) -> None:
pass
def call(self, name: str, **kwargs) -> Dict:
# Returns {'result': Any, 'cached': bool, 'deterministic': bool}
pass
def _cache_key(self, name: str, kwargs: Dict) -> str:
data = json.dumps({'tool': name, 'args': kwargs}, sort_keys=True)
return hashlib.sha256(data.encode()).hexdigest()
Python3
ReadyLines: 1Characters: 0
Ready