Agent Patterns Documentation
This document describes the advanced agent patterns implemented in Peekaboo, inspired by the OpenAI SDK.
#Table of Contents
#Explicit Task Completion
#Problem
Previously, the agent would guess when a task was complete based on:
- Iteration count and content length
- Magic phrases like "task is done"
- Detecting "finishing" tools like
say
This led to premature completion when agents were explaining their plans.
#Solution
Agents now must explicitly signal completion using dedicated tools:
#task_completed Tool
// Agent must call this when done
{
"name": "task_completed",
"arguments": {
"summary": "Converted ODS file to Markdown and sent email with poem",
"success": true,
"next_steps": "Consider installing pandoc for faster conversions"
}
}
#need_more_information Tool
// Agent calls this when blocked
{
"name": "need_more_information",
"arguments": {
"question": "Which email account should I use to send the message?",
"context": "Multiple email accounts are configured"
}
}
#Implementation
- Tools defined in
CompletionTools.swift - System prompt updated to require these tools
- AgentRunner checks for
task_completedtool call - CLI displays completion summary prominently
#Tool Approval Mechanism
#Configuration
let config = ToolApprovalConfig(
requiresApproval: ["shell", "delete_file"],
alwaysApproved: ["screenshot", "list_apps"],
alwaysRejected: ["rm -rf /"],
approvalHandler: InteractiveApprovalHandler()
)
#Interactive Approval
When a tool requires approval:
⚠️ Tool Approval Required
Tool: shell
Arguments: {"command": "rm important-file.txt"}
Context: User requested file deletion
Approve? [y/n/always/never]:
#Approval Results
approved: Allow this executionrejected: Block this executionapprovedAlways: Allow all future calls to this toolrejectedAlways: Block all future calls to this tool
#Lifecycle Hooks
#Events
public enum AgentLifecycleEvent {
case agentStarted(agent: String, context: String?)
case agentEnded(agent: String, output: String?)
case toolStarted(name: String, arguments: String)
case toolEnded(name: String, result: String, success: Bool)
case iterationStarted(number: Int)
case iterationCompleted(number: Int)
case errorOccurred(error: Error, context: String?)
}
#Handlers
#Console Logger
let consoleHandler = ConsoleLifecycleHandler(
verbose: true,
includeTimestamps: true
)
Output:
[14:23:45.123] 🚀 Agent 'Peekaboo Assistant' started
[14:23:45.234] 🔧 Tool 'screenshot' started
[14:23:45.567] 🔧 Tool 'screenshot' ✓
[14:23:46.789] ✅ Agent 'Peekaboo Assistant' completed
#Metrics Collector
let metricsHandler = MetricsLifecycleHandler()
// After execution
let metrics = await metricsHandler.getMetrics()
print("Total tool calls: \(metrics.totalToolCalls)")
print("Average execution time: \(metrics.executionTimes.average)")
#Custom Handlers
actor CustomHandler: AgentLifecycleHandler {
func handle(event: AgentLifecycleEvent) async {
switch event {
case .toolStarted(let name, _) where name == "shell":
// Log shell commands to audit trail
await AuditLog.record("Shell command executed")
default:
break
}
}
}
#Best Practices
#1. Always Use Completion Tools
- Don't rely on heuristics
- Agents must explicitly call
task_completed - Handle
need_more_informationgracefully
#2. Configure Tool Approvals
- Require approval for destructive operations
- Auto-approve read-only operations
- Let users set permanent preferences
#3. Add Lifecycle Handlers
- Use console handler for debugging
- Add metrics handler for performance monitoring
- Create custom handlers for audit trails
#4. Error Handling
- Lifecycle events include error cases
- Tool errors don't stop execution
- Approval rejections are handled gracefully
#Migration Guide
#Updating Existing Agents
- Add completion tools to your tool list
- Update system prompt to mention completion requirement
- Test that agents call
task_completed
#Adding Approvals
- Create
ToolApprovalConfig - Pass to agent during creation
- Implement custom approval handler if needed
#Adding Lifecycle Tracking
- Create handlers for your needs
- Add to
LifecycleManager - Events will automatically flow
#Future Enhancements
- Agent Handoffs: Transfer control between specialized agents
- Guardrails: Input/output validation with tripwires
- Structured Output: Type-safe outputs with schemas
- Persistence: Save and restore approval preferences
- Web UI: Visual approval interface