Persistent learning with auto-scored confidence levels.
@dataclass
class KnowledgeEntry:
id: int # Unique ID
insight: str # The knowledge itself
category: str # Type: hyperparameter, architecture, training_dynamics, data, methodology
tags: List[str] # For querying
confidence: ConfidenceLevel # Auto-scored: low, medium, high, very_high
status: KnowledgeStatus # active, outdated, questioned
source_task_ids: List[int] # Which tasks generated this
experiments_supporting: int # Evidence count
experiments_contradicting: int # Counter-evidence count
created_at: datetime
last_updated: datetime
evidence: Dict # Supporting information
conditions: Optional[str] # When this appliescreate() - Create new knowledge entry
entry = store.create(
insight: str, # Required: The knowledge
category: str, # Required: Category type
tags: List[str], # Required: Tags for querying
source_task_ids: List[int], # Required: Source tasks
experiments_supporting: int, # Required: Supporting experiments
experiments_contradicting: int = 0, # Optional: Counter-experiments
conditions: Optional[str] = None, # Optional: When it applies
key_commits: Optional[List[str]] = None # Optional: Git commits
) -> KnowledgeEntryquery() - Find knowledge entries
results = store.query(
tags: Optional[List[str]] = None, # Filter by tags (OR logic)
category: Optional[str] = None, # Filter by category
min_confidence: Optional[str] = None, # Min confidence: low, medium, high
status: Optional[str] = None, # Filter by status: active, outdated, questioned
) -> List[KnowledgeEntry]get() - Get entry by ID
entry = store.get(entry_id: int) -> Optional[KnowledgeEntry]mark_outdated() - Mark entry as outdated
store.mark_outdated(entry_id: int, replaced_by: int)mark_questioned() - Flag entry for validation
store.mark_questioned(entry_id: int, reason: str)cleanup_old_entries() - Remove unvalidated old entries
removed = store.cleanup_old_entries(days: int = 30) -> intstats() - Get store statistics
stats = store.stats() -> Dict[str, Any]
# Returns: {total_entries, by_confidence, by_category, by_status}External event monitoring and auto-task creation.
start() - Begin polling triggers in background thread
daemon.start()stop() - Graceful shutdown
daemon.stop()add_trigger() - Register a new trigger
daemon.add_trigger(config: Dict[str, Any])
# Config includes: id, name, type, source, filter, action, enabled, poll_interval_minuteslist_triggers() - Get all triggers
triggers = daemon.list_triggers() -> List[Dict[str, Any]]enable_trigger() - Resume monitoring
daemon.enable_trigger(trigger_id: int)disable_trigger() - Pause monitoring
daemon.disable_trigger(trigger_id: int)stats() - Get daemon statistics
stats = daemon.stats() -> Dict[str, Any]
# Returns: {total_triggers, enabled, fired_today, last_check}- RSS: Feed monitoring (requires source.url)
- Schedule: Cron-like scheduling (requires source.cron)
- Webhook: External event receiver
- File: File system monitoring
- Sensor: Hardware sensor thresholds
Multi-channel notification delivery.
create() - Create and optionally deliver notification
notif = nm.create(
title: str, # Required: Short title
body: str, # Required: Message body
severity: str = "important", # info, important, urgent
source: str = "system", # Where it came from
tags: List[str] = [], # For filtering
auto_deliver: bool = True, # Send immediately?
) -> Notificationdeliver() - Send notification to all channels
success = nm.deliver(notification_id: int) -> boolget_unread() - Get undelivered notifications
notifs = nm.get_unread() -> List[Notification]delete() - Remove notification
nm.delete(notification_id: int)stats() - Get notification statistics
stats = nm.stats() -> Dict[str, Any]
# Returns: {total_notifications, unread, by_severity, by_source}notifications:
external_channels:
- type: webhook
url: https://example.com/notify
headers: {Authorization: "Bearer token"}
- type: email
smtp_host: smtp.example.com
sender: autoclaw@example.com
recipients: [captain@example.com]
- type: command
command: "ntfy -p high '{{title}}'"
- type: file
path: /var/log/autoclaw/notifications.logResume long-running tasks seamlessly.
create() - Start new generation tracking
handoff = hm.create(task_id: int, generation: int) -> ContextHandoffsave() - Persist handoff to disk
hm.save(handoff: ContextHandoff)
# Saves to: data/handoffs/task{id}/gen{generation}/state.yaml
# Creates symlink: data/handoffs/task{id}/CURRENT -> gen{generation}load() - Load specific generation
handoff = hm.load(task_id: int, generation: int) -> Optional[ContextHandoff]get_current() - Get latest generation
handoff = hm.get_current(task_id: int) -> Optional[ContextHandoff]list_generations() - Get all generations for task
gens = hm.list_generations(task_id: int) -> List[int]should_handoff() - Check if context full
yes = hm.should_handoff(context_tokens_used: int, context_limit: int = 8000) -> bool
# Returns True if tokens_used > 75% of limitgenerate_summary_for_context() - Create LLM-readable summary
summary = hm.generate_summary_for_context(handoff: ContextHandoff) -> str
# Condensed description for next context windowDurable SQLite-backed inter-agent communication.
publish() - Queue message
msg_id = bus.publish(Message(
from_agent: str, # Sender agent ID
to_agent: str, # Recipient: agent_id | any_role | broadcast
type: str, # Message type
payload: Dict[str, Any], # Data
priority: int = 5, # 1-10, lower = higher
tags: List[str] = [], # For filtering
expires_in_hours: Optional[float] = None,
)) -> int # Returns message IDreceive() - Get pending messages
messages = bus.receive(
agent_id: str, # Receiving agent
roles: List[str] = [], # Roles to filter on
limit: int = 10, # Max messages
status: str = "pending", # Filter by status
) -> List[Message]complete() - Mark message processed
bus.complete(message_id: int)fail() - Mark message failed
bus.fail(message_id: int, error_message: str)
# Moves to dead_letters tablemark_processing() - Update processing status
bus.mark_processing(message_id: int)subscribe() - Watch message types
def handler(msg: Message): ...
bus.subscribe("message_type", handler)get_queue_depths() - Get queue statistics
depths = bus.get_queue_depths() -> Dict[str, int]
# Returns: {by_agent: {agent_id: count}, by_status: {status: count}}All agents inherit from this.
class MyAgent(BaseAgent):
ROLE = "my_role" # Set this in subclass
def get_capabilities(self) -> List[str]:
"""Return list of capabilities."""
return ["capability_1", "capability_2"]
def process_message(self, message: Message) -> Optional[Message]:
"""Process incoming message, return reply (optional)."""
...
def idle_work(self):
"""Called when no messages pending."""
# Optional: implement periodic work
time.sleep(5)publish() - Send message to other agent
msg_id = self.publish(
to_agent: str,
msg_type: str,
payload: Dict[str, Any],
priority: Optional[int] = None,
parent_id: Optional[int] = None,
tags: Optional[List[str]] = None,
expires_in_hours: Optional[float] = None,
) -> intreply() - Send reply to original sender
msg_id = self.reply(
original: Message,
msg_type: str,
payload: Dict[str, Any],
) -> intcheck_rate_limit() - Check if can use resource
ok = self.check_rate_limit("llm_call" or "web_search") -> boolrequest_research() - Ask researcher agent
msg_id = self.request_research(
topic: str,
context: Optional[str] = None,
priority: int = 5,
) -> intrequest_training_data() - Ask teacher agent
msg_id = self.request_training_data(
topic: str,
source_text: str,
n_examples: int = 20,
priority: int = 6,
) -> intsubmit_knowledge() - Add to knowledge store
msg_id = self.submit_knowledge(
insight: str,
category: str,
tags: List[str],
confidence: str = "medium",
evidence: Optional[Dict] = None,
) -> intLearn which research directions are most productive.
compute_priority_adjustment() - Boost for high-value directions
boost = scheduler.compute_priority_adjustment(task) -> float
# Returns 0.0-2.0 boost based on direction's learned valueupdate_from_task_result() - Learn from outcomes
scheduler.update_from_task_result(
task,
findings: List[str],
success_rate: float = 1.0,
compute_hours: float = 0.1,
num_knowledge_entries: int = 0,
)suggest_research_directions() - Recommend directions
suggestions = scheduler.suggest_research_directions(num_suggestions: int = 3) -> List[Dict]
# Returns: [{direction, estimated_value, mean_value, uncertainty, roi, rationale}, ...]stats() - Get scheduler statistics
stats = scheduler.stats() -> Dict[str, Any]Safe exploration in isolated sandboxes.
create() - Start sandbox exploration
flow = manager.create(
title: str,
description: Optional[str] = None,
parent_task_id: Optional[int] = None,
budget_gb: float = 10.0,
budget_hours: float = 4.0,
max_experiments: int = 20,
) -> FlowStateTaskrecord_experiment() - Log experiment results
ok = manager.record_experiment(
task_id: str,
success: bool,
result_summary: str = "",
) -> boolpromote_findings() - Move to main knowledge
knowledge_ids = manager.promote_findings(
task_id: str,
findings: List[str],
confidence: str = "medium",
validation_task_ids: Optional[List[int]] = None,
) -> List[int]discard() - Abandon sandbox
manager.discard(task_id: str)cleanup_old_sandboxes() - Remove old completed
manager.cleanup_old_sandboxes(days: int = 7)stats() - Get sandbox statistics
stats = manager.stats() -> Dict[str, Any]Robust error handling with recovery.
@retry - Automatic retry with exponential backoff
@retry(max_attempts=3, retryable_exceptions=(IOError, TimeoutError))
def fetch_data():
...@handle_error - Graceful error handling
@handle_error("component_name", "operation", default_return=[])
def dangerous_operation():
...breaker = CircuitBreaker("api_name", failure_threshold=5)
if breaker.is_available():
try:
result = api_call()
breaker.record_success()
except Exception:
breaker.record_failure()
# Get status
status = breaker.status()# Core system
crew:
name: "AutoClaw"
personality: "balanced"
# LLM
llm:
provider: "anthropic"
model: "claude-opus-4-6"
api_key: "${ANTHROPIC_API_KEY}"
# Knowledge store
knowledge:
max_entries: 500
cleanup_days: 30 # Remove unvalidated old entries
# Triggers
triggers:
enabled: true
default_poll_minutes: 30
# Notifications
notifications:
external_channels: [] # See channel definitions above
# Experiments
experiments:
time_budget_seconds: 300
git_commit_each: false
keep_checkpoints: "best_only"
# Adaptive scheduling
adaptive:
enabled: true
thompson_samples_per_decision: 100
# Flowstate
flowstate:
enabled: true
default_budget_gb: 10.0
default_budget_hours: 4.0
# Hardware
hardware:
profile: null # Auto-detect if not set# 1. Run experiments and get findings
findings = ["Finding 1", "Finding 2"]
# 2. Create knowledge from findings
di = get_daemon_integration()
di.create_knowledge_from_findings(task, findings, experiments_run=10)
# 3. Future planning uses knowledge
hints = di.enhance_experiment_planning(task)
params = di.refine_parameters_with_knowledge(task, params)# Coordinator orchestrates workflow
coordinator = CoordinatorAgent("coordinator_1")
# 1. Request research
researcher_msg_id = coordinator.request_research(
"transformer attention mechanisms"
)
# 2. Ask teacher to generate training data
# (would receive researcher results first)
teacher_msg_id = coordinator.request_training_data(
"attention mechanisms",
source_text=researcher_findings,
n_examples=50
)manager = get_flowstate_manager()
# Start risky exploration
flow = manager.create("Explore mixed precision")
# Run experiments (results isolated)
manager.record_experiment(flow.id, success=True, "Good results!")
# If promising, promote to main knowledge
if flow.experiments_successful > 5:
manager.promote_findings(
flow.id,
findings=flow.findings,
validation_task_ids=[1, 2, 3]
)All components use consistent error handling:
- Retry: Transient errors are retried with backoff
- Circuit Break: External API failures are rate-limited
- Graceful Degrade: Core functions return defaults on error
- Notify: Critical errors alert the captain
- Audit: All errors logged for analysis
# Use error auditor to analyze issues
auditor = get_error_auditor()
stats = auditor.get_stats()
hotspots = auditor.get_hotspots(top_n=5)