agentic 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/.agentic.yml +2 -0
  3. data/.architecture/decisions/ArchitecturalFeatureBuilder.md +136 -0
  4. data/.architecture/decisions/ArchitectureConsiderations.md +200 -0
  5. data/.architecture/decisions/adr_001_observer_pattern_implementation.md +196 -0
  6. data/.architecture/decisions/adr_002_plan_orchestrator.md +320 -0
  7. data/.architecture/decisions/adr_003_plan_orchestrator_interface.md +179 -0
  8. data/.architecture/decisions/adrs/ADR-001-dependency-management.md +147 -0
  9. data/.architecture/decisions/adrs/ADR-002-system-boundaries.md +162 -0
  10. data/.architecture/decisions/adrs/ADR-003-content-safety.md +158 -0
  11. data/.architecture/decisions/adrs/ADR-004-agent-permissions.md +161 -0
  12. data/.architecture/decisions/adrs/ADR-005-adaptation-engine.md +127 -0
  13. data/.architecture/decisions/adrs/ADR-006-extension-system.md +273 -0
  14. data/.architecture/decisions/adrs/ADR-007-learning-system.md +156 -0
  15. data/.architecture/decisions/adrs/ADR-008-prompt-generation.md +325 -0
  16. data/.architecture/decisions/adrs/ADR-009-task-failure-handling.md +353 -0
  17. data/.architecture/decisions/adrs/ADR-010-task-input-handling.md +251 -0
  18. data/.architecture/decisions/adrs/ADR-011-task-observable-pattern.md +391 -0
  19. data/.architecture/decisions/adrs/ADR-012-task-output-handling.md +205 -0
  20. data/.architecture/decisions/adrs/ADR-013-architecture-alignment.md +211 -0
  21. data/.architecture/decisions/adrs/ADR-014-agent-capability-registry.md +80 -0
  22. data/.architecture/decisions/adrs/ADR-015-persistent-agent-store.md +100 -0
  23. data/.architecture/decisions/adrs/ADR-016-agent-assembly-engine.md +117 -0
  24. data/.architecture/decisions/adrs/ADR-017-streaming-observability.md +171 -0
  25. data/.architecture/decisions/capability_tools_distinction.md +150 -0
  26. data/.architecture/decisions/cli_command_structure.md +61 -0
  27. data/.architecture/implementation/agent_self_assembly_implementation.md +267 -0
  28. data/.architecture/implementation/agent_self_assembly_summary.md +138 -0
  29. data/.architecture/members.yml +187 -0
  30. data/.architecture/planning/self_implementation_exercise.md +295 -0
  31. data/.architecture/planning/session_compaction_rule.md +43 -0
  32. data/.architecture/planning/streaming_observability_feature.md +223 -0
  33. data/.architecture/principles.md +151 -0
  34. data/.architecture/recalibration/0-2-0.md +92 -0
  35. data/.architecture/recalibration/agent_self_assembly.md +238 -0
  36. data/.architecture/recalibration/cli_command_structure.md +91 -0
  37. data/.architecture/recalibration/implementation_roadmap_0-2-0.md +301 -0
  38. data/.architecture/recalibration/progress_tracking_0-2-0.md +114 -0
  39. data/.architecture/recalibration_process.md +127 -0
  40. data/.architecture/reviews/0-2-0.md +181 -0
  41. data/.architecture/reviews/cli_command_duplication.md +98 -0
  42. data/.architecture/templates/adr.md +105 -0
  43. data/.architecture/templates/implementation_roadmap.md +125 -0
  44. data/.architecture/templates/progress_tracking.md +89 -0
  45. data/.architecture/templates/recalibration_plan.md +70 -0
  46. data/.architecture/templates/version_comparison.md +124 -0
  47. data/.claude/settings.local.json +13 -0
  48. data/.claude-sessions/001-task-class-architecture-implementation.md +129 -0
  49. data/.claude-sessions/002-plan-orchestrator-interface-review.md +105 -0
  50. data/.claude-sessions/architecture-governance-implementation.md +37 -0
  51. data/.claude-sessions/architecture-review-session.md +27 -0
  52. data/ArchitecturalFeatureBuilder.md +136 -0
  53. data/ArchitectureConsiderations.md +229 -0
  54. data/CHANGELOG.md +57 -2
  55. data/CLAUDE.md +111 -0
  56. data/CONTRIBUTING.md +286 -0
  57. data/MAINTAINING.md +301 -0
  58. data/README.md +582 -28
  59. data/docs/agent_capabilities_api.md +259 -0
  60. data/docs/artifact_extension_points.md +757 -0
  61. data/docs/artifact_generation_architecture.md +323 -0
  62. data/docs/artifact_implementation_plan.md +596 -0
  63. data/docs/artifact_integration_points.md +345 -0
  64. data/docs/artifact_verification_strategies.md +581 -0
  65. data/docs/streaming_observability_architecture.md +510 -0
  66. data/exe/agentic +6 -1
  67. data/lefthook.yml +5 -0
  68. data/lib/agentic/adaptation_engine.rb +124 -0
  69. data/lib/agentic/agent.rb +181 -4
  70. data/lib/agentic/agent_assembly_engine.rb +442 -0
  71. data/lib/agentic/agent_capability_registry.rb +260 -0
  72. data/lib/agentic/agent_config.rb +63 -0
  73. data/lib/agentic/agent_specification.rb +46 -0
  74. data/lib/agentic/capabilities/examples.rb +530 -0
  75. data/lib/agentic/capabilities.rb +14 -0
  76. data/lib/agentic/capability_provider.rb +146 -0
  77. data/lib/agentic/capability_specification.rb +118 -0
  78. data/lib/agentic/cli/agent.rb +31 -0
  79. data/lib/agentic/cli/capabilities.rb +191 -0
  80. data/lib/agentic/cli/config.rb +134 -0
  81. data/lib/agentic/cli/execution_observer.rb +796 -0
  82. data/lib/agentic/cli.rb +1068 -0
  83. data/lib/agentic/default_agent_provider.rb +35 -0
  84. data/lib/agentic/errors/llm_error.rb +184 -0
  85. data/lib/agentic/execution_plan.rb +53 -0
  86. data/lib/agentic/execution_result.rb +91 -0
  87. data/lib/agentic/expected_answer_format.rb +46 -0
  88. data/lib/agentic/extension/domain_adapter.rb +109 -0
  89. data/lib/agentic/extension/plugin_manager.rb +163 -0
  90. data/lib/agentic/extension/protocol_handler.rb +116 -0
  91. data/lib/agentic/extension.rb +45 -0
  92. data/lib/agentic/factory_methods.rb +9 -1
  93. data/lib/agentic/generation_stats.rb +61 -0
  94. data/lib/agentic/learning/README.md +84 -0
  95. data/lib/agentic/learning/capability_optimizer.rb +613 -0
  96. data/lib/agentic/learning/execution_history_store.rb +251 -0
  97. data/lib/agentic/learning/pattern_recognizer.rb +500 -0
  98. data/lib/agentic/learning/strategy_optimizer.rb +706 -0
  99. data/lib/agentic/learning.rb +131 -0
  100. data/lib/agentic/llm_assisted_composition_strategy.rb +188 -0
  101. data/lib/agentic/llm_client.rb +215 -15
  102. data/lib/agentic/llm_config.rb +65 -1
  103. data/lib/agentic/llm_response.rb +163 -0
  104. data/lib/agentic/logger.rb +1 -1
  105. data/lib/agentic/observable.rb +51 -0
  106. data/lib/agentic/persistent_agent_store.rb +385 -0
  107. data/lib/agentic/plan_execution_result.rb +129 -0
  108. data/lib/agentic/plan_orchestrator.rb +464 -0
  109. data/lib/agentic/plan_orchestrator_config.rb +57 -0
  110. data/lib/agentic/retry_config.rb +63 -0
  111. data/lib/agentic/retry_handler.rb +125 -0
  112. data/lib/agentic/structured_outputs.rb +1 -1
  113. data/lib/agentic/task.rb +193 -0
  114. data/lib/agentic/task_definition.rb +39 -0
  115. data/lib/agentic/task_execution_result.rb +92 -0
  116. data/lib/agentic/task_failure.rb +66 -0
  117. data/lib/agentic/task_output_schemas.rb +112 -0
  118. data/lib/agentic/task_planner.rb +54 -19
  119. data/lib/agentic/task_result.rb +48 -0
  120. data/lib/agentic/ui.rb +244 -0
  121. data/lib/agentic/verification/critic_framework.rb +116 -0
  122. data/lib/agentic/verification/llm_verification_strategy.rb +60 -0
  123. data/lib/agentic/verification/schema_verification_strategy.rb +47 -0
  124. data/lib/agentic/verification/verification_hub.rb +62 -0
  125. data/lib/agentic/verification/verification_result.rb +50 -0
  126. data/lib/agentic/verification/verification_strategy.rb +26 -0
  127. data/lib/agentic/version.rb +1 -1
  128. data/lib/agentic.rb +74 -2
  129. data/plugins/README.md +41 -0
  130. metadata +245 -6
@@ -0,0 +1,251 @@
1
+ # Task Input Handling
2
+
3
+ ## Overview
4
+
5
+ This document specifies the architecture for handling task inputs within the Agentic framework, addressing how inputs are structured, validated, and utilized. Task inputs serve as the foundation for successful task execution, provide context, and enable effective task chaining.
6
+
7
+ ## Core Principles
8
+
9
+ 1. **Consistency**: Task inputs follow standardized formats for interoperability
10
+ 2. **Contextual Awareness**: Inputs include relevant context from the overall plan
11
+ 3. **Validation**: Inputs undergo validation before task execution
12
+ 4. **Transformation**: Outputs from previous tasks can be transformed into inputs for subsequent tasks
13
+ 5. **Dependency Management**: Inputs clearly express dependencies on other tasks
14
+
15
+ ## Input Structure
16
+
17
+ Task inputs should adhere to a consistent structure:
18
+
19
+ ```
20
+ {
21
+ "parameters": {
22
+ // Domain-specific input parameters
23
+ },
24
+ "context": {
25
+ "plan_id": "uuid",
26
+ "goal": "Original goal description",
27
+ "previous_task_outputs": {
28
+ "task_uuid1": { /* Reference to output */ },
29
+ "task_uuid2": { /* Reference to output */ }
30
+ },
31
+ "user_context": {
32
+ // User-specific context
33
+ },
34
+ "environment": {
35
+ // Execution environment information
36
+ }
37
+ },
38
+ "constraints": {
39
+ "time_limit_ms": 60000,
40
+ "token_limit": 8000,
41
+ "required_outputs": ["field1", "field2"]
42
+ },
43
+ "metadata": {
44
+ "created_at": "ISO8601",
45
+ "creator_id": "uuid",
46
+ "version": "1.0",
47
+ "priority": "high"
48
+ }
49
+ }
50
+ ```
51
+
52
+ ## Input Sources
53
+
54
+ Task inputs can originate from several sources:
55
+
56
+ ### 1. Plan Generation
57
+
58
+ The TaskPlanner generates initial inputs based on:
59
+ - The original goal
60
+ - User preferences
61
+ - Domain-specific requirements
62
+ - System configuration
63
+
64
+ Implementation considerations:
65
+ - Input schema derivation from goal analysis
66
+ - Parameter extraction from natural language
67
+ - Constraint identification from system capabilities
68
+ - Context gathering from user information
69
+
70
+ ### 2. Task Chaining
71
+
72
+ Subsequent tasks receive inputs derived from previous task outputs:
73
+
74
+ ```
75
+ TaskA.output → InputTransformer → TaskB.input
76
+ ```
77
+
78
+ Implementation considerations:
79
+ - Output-to-input mapping definitions
80
+ - Schema compatibility verification
81
+ - Selective information transfer
82
+ - Context accumulation or filtering
83
+
84
+ ### 3. Human Intervention
85
+
86
+ Human feedback can modify or augment task inputs:
87
+
88
+ ```
89
+ Task.input → Human Intervention → Modified Task.input
90
+ ```
91
+
92
+ Implementation considerations:
93
+ - User-friendly input editing interface
94
+ - Validation of human-provided inputs
95
+ - Clear indication of human modifications
96
+ - Version tracking of input changes
97
+
98
+ ### 4. Environmental Sources
99
+
100
+ External systems can provide inputs through connectors:
101
+
102
+ ```
103
+ External API → Connector → Input Transformation → Task.input
104
+ ```
105
+
106
+ Implementation considerations:
107
+ - Authentication and authorization
108
+ - Rate limiting and caching
109
+ - Error handling for external dependencies
110
+ - Data sanitization and normalization
111
+
112
+ ## Input Processing Patterns
113
+
114
+ ### 1. Validation and Normalization
115
+
116
+ Inputs undergo validation and normalization before execution:
117
+
118
+ ```
119
+ Raw Input → Schema Validation → Type Conversion → Normalization → Validated Input
120
+ ```
121
+
122
+ Implementation considerations:
123
+ - Schema-based validation using StructuredInputs module
124
+ - Type coercion for compatibility
125
+ - Default value application
126
+ - Required field verification
127
+
128
+ ### 2. Dependency Resolution
129
+
130
+ Inputs with dependencies are resolved before task execution:
131
+
132
+ ```
133
+ Task.input → DependencyResolver → Resolved Task.input
134
+ ```
135
+
136
+ Implementation considerations:
137
+ - Dependency graph traversal
138
+ - Circular dependency detection
139
+ - Parallel resolution of independent dependencies
140
+ - Caching of resolved dependencies
141
+
142
+ ### 3. Context Enhancement
143
+
144
+ Inputs are enhanced with relevant contextual information:
145
+
146
+ ```
147
+ Task.input → ContextEnhancer → Enhanced Task.input
148
+ ```
149
+
150
+ Implementation considerations:
151
+ - Selective context inclusion
152
+ - Privacy-preserving context filtering
153
+ - Context source prioritization
154
+ - Context versioning
155
+
156
+ ### 4. Input Transformation
157
+
158
+ Outputs from previous tasks are transformed into appropriate inputs:
159
+
160
+ ```
161
+ Previous Task Output → OutputToInputTransformer → Current Task Input
162
+ ```
163
+
164
+ Implementation considerations:
165
+ - Transformation rule definitions
166
+ - Field mapping configurations
167
+ - Type conversion handling
168
+ - Aggregation of multiple outputs
169
+
170
+ ## Component Responsibilities
171
+
172
+ ### Task Class
173
+
174
+ - Accept and validate input structure
175
+ - Provide access to input parameters
176
+ - Track input provenance
177
+ - Support input validation
178
+
179
+ ### InputValidator
180
+
181
+ - Verify input against schema
182
+ - Perform type checking and coercion
183
+ - Validate required fields
184
+ - Provide detailed validation errors
185
+
186
+ ### DependencyResolver
187
+
188
+ - Analyze input dependencies
189
+ - Resolve dependencies before execution
190
+ - Detect circular or missing dependencies
191
+ - Handle dependency errors
192
+
193
+ ### ContextManager
194
+
195
+ - Maintain execution context
196
+ - Provide relevant context to tasks
197
+ - Filter sensitive context information
198
+ - Ensure context consistency
199
+
200
+ ### InputTransformer (New Component)
201
+
202
+ - Convert between input/output formats
203
+ - Apply transformation rules
204
+ - Handle type conversions
205
+ - Support custom transformers
206
+
207
+ ### PlanOrchestrator
208
+
209
+ - Coordinate input provision to tasks
210
+ - Manage input flow between tasks
211
+ - Handle input errors and retries
212
+ - Track input state across the plan
213
+
214
+ ## Implementation Approach
215
+
216
+ 1. **Start Simple**: Begin with basic parameter support
217
+ 2. **Add Context**: Incorporate contextual information
218
+ 3. **Implement Validation**: Add schema-based validation
219
+ 4. **Enable Transformation**: Create input transformation capabilities
220
+ 5. **Support Dependencies**: Add dependency resolution
221
+
222
+ ## Development Priorities
223
+
224
+ 1. Define the input schema interface
225
+ 2. Implement input validation in Task
226
+ 3. Create input transformation utilities
227
+ 4. Develop dependency resolution
228
+ 5. Implement context management
229
+ 6. Add human intervention support
230
+
231
+ ## Considerations for Future Extensions
232
+
233
+ 1. **Schema Evolution**: Support versioning of input schemas
234
+ 2. **Smart Defaults**: Intelligent default value generation
235
+ 3. **Input Templates**: Reusable input patterns for common tasks
236
+ 4. **Dynamic Validation**: Context-aware validation rules
237
+ 5. **Input Suggestions**: AI-assisted input completion
238
+
239
+ ## Integration with Output Handling
240
+
241
+ The input and output handling systems are tightly coupled:
242
+
243
+ 1. **Format Compatibility**: Output schema from one task must be compatible with input schema of dependent tasks
244
+ 2. **Transformation Pipeline**: Clear pipeline for output-to-input transformation
245
+ 3. **Metadata Preservation**: Relevant metadata flows from outputs to inputs
246
+ 4. **Validation Chain**: Output validation should inform input validation
247
+ 5. **Contextual Flow**: Context accumulates through the input/output chain
248
+
249
+ ## Conclusion
250
+
251
+ A well-designed task input handling system is foundational to the Agentic framework. By standardizing input formats, supporting validation, enabling transformation, and managing dependencies, the system can ensure tasks receive the appropriate context and data needed for successful execution while maintaining the integrity of the overall plan.
@@ -0,0 +1,391 @@
1
+ # Task Observable Pattern
2
+
3
+ ## Overview
4
+
5
+ This document outlines the architectural design for implementing the Observable pattern in the Agentic task system. It leverages Ruby's built-in Observable module to enable loose coupling between tasks and components that need to react to task state changes.
6
+
7
+ ## Design Decision
8
+
9
+ ### Using Ruby's Standard Observable
10
+
11
+ The Agentic framework will use Ruby's built-in Observable module from the standard library rather than implementing a custom solution. The standard library implementation provides:
12
+
13
+ 1. **Proven Implementation**: Battle-tested code with known behavior
14
+ 2. **Familiarity**: Recognized pattern that Ruby developers understand
15
+ 3. **Lightweight**: Minimal overhead for the functionality provided
16
+ 4. **Maintenance**: Reduces custom code that needs to be maintained
17
+
18
+ ## Implementation Details
19
+
20
+ ### Task Integration
21
+
22
+ ```ruby
23
+ require 'observer'
24
+
25
+ module Agentic
26
+ class Task
27
+ include Observable
28
+
29
+ # ... other attributes and methods ...
30
+
31
+ def perform(agent)
32
+ old_status = @status
33
+ @status = :in_progress
34
+
35
+ # Signal that object state has changed
36
+ changed
37
+ # Notify observers with event type and context
38
+ notify_observers(:status_change, self, old_status, @status)
39
+
40
+ # ... execution logic ...
41
+
42
+ # Status transitions with notifications
43
+ end
44
+
45
+ def retry(agent)
46
+ # Similar pattern with status change notifications
47
+ end
48
+ end
49
+ end
50
+ ```
51
+
52
+ ### Notification Protocol
53
+
54
+ The Observable pattern requires a clear protocol for notifications:
55
+
56
+ 1. **Event Types**: Symbolized event identifiers (e.g., `:status_change`)
57
+ 2. **Event Context**: Relevant objects and data for the event
58
+ 3. **Observer Interface**: Observer must implement `update` method
59
+
60
+ Observer's `update` method signature:
61
+
62
+ ```ruby
63
+ def update(event_type, task, *args)
64
+ # Handle the event based on type and context
65
+ end
66
+ ```
67
+
68
+ Common event types:
69
+
70
+ | Event Type | Description | Arguments |
71
+ |------------|-------------|-----------|
72
+ | `:status_change` | Task status has changed | `task, old_status, new_status` |
73
+ | `:output_available` | Task has produced output | `task, output` |
74
+ | `:failure_occurred` | Task has failed | `task, failure` |
75
+ | `:verification_complete` | Task verification complete | `task, verification_result` |
76
+
77
+ ## Practical Usage Patterns
78
+
79
+ ### 1. Plan Orchestration
80
+
81
+ ```ruby
82
+ class PlanOrchestrator
83
+ def initialize(plan_id)
84
+ @plan_id = plan_id
85
+ @tasks_in_progress = 0
86
+ @task_results = {}
87
+ @dependencies = {}
88
+ end
89
+
90
+ def update(event_type, task, *args)
91
+ case event_type
92
+ when :status_change
93
+ old_status, new_status = args
94
+ handle_status_change(task, old_status, new_status)
95
+ when :failure_occurred
96
+ failure = args.first
97
+ handle_failure(task, failure)
98
+ end
99
+ end
100
+
101
+ def add_task(task, dependencies = [])
102
+ task.add_observer(self)
103
+ @dependencies[task.id] = dependencies
104
+ end
105
+
106
+ private
107
+
108
+ def handle_status_change(task, old_status, new_status)
109
+ # React to status changes
110
+ # Track tasks in progress
111
+ # Execute dependent tasks when appropriate
112
+ end
113
+
114
+ def handle_failure(task, failure)
115
+ # Apply appropriate failure handling strategy
116
+ # Retry, fallback, or human intervention
117
+ end
118
+
119
+ def execute_dependent_tasks(completed_task_id)
120
+ # Find and execute tasks that depend on the completed task
121
+ end
122
+ end
123
+ ```
124
+
125
+ ### 2. Metrics Collection
126
+
127
+ ```ruby
128
+ class MetricsCollector
129
+ def initialize
130
+ @task_timings = {}
131
+ @status_transitions = {}
132
+ end
133
+
134
+ def update(event_type, task, *args)
135
+ if event_type == :status_change
136
+ old_status, new_status = args
137
+
138
+ # Record timestamp of status change
139
+ @status_transitions[task.id] ||= []
140
+ @status_transitions[task.id] << {
141
+ from: old_status,
142
+ to: new_status,
143
+ timestamp: Time.now
144
+ }
145
+
146
+ # Calculate and record timings for completed tasks
147
+ if new_status == :completed
148
+ start_time = find_start_time(task.id)
149
+ @task_timings[task.id] = Time.now - start_time if start_time
150
+ end
151
+ end
152
+ end
153
+
154
+ private
155
+
156
+ def find_start_time(task_id)
157
+ transition = @status_transitions[task_id]&.find { |t| t[:to] == :in_progress }
158
+ transition&.fetch(:timestamp)
159
+ end
160
+ end
161
+ ```
162
+
163
+ ### 3. Human Intervention Portal
164
+
165
+ ```ruby
166
+ class HumanInterventionPortal
167
+ def initialize
168
+ @intervention_requests = {}
169
+ end
170
+
171
+ def update(event_type, task, *args)
172
+ if event_type == :status_change
173
+ old_status, new_status = args
174
+
175
+ if new_status == :failed
176
+ failure = task.failure
177
+
178
+ # Check if this failure requires human intervention
179
+ if requires_human_intervention?(failure)
180
+ request_intervention(task, failure)
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ private
187
+
188
+ def requires_human_intervention?(failure)
189
+ # Logic to determine if human should intervene
190
+ %w[AuthenticationError PermissionDeniedError UnknownDomainError].include?(failure.type)
191
+ end
192
+
193
+ def request_intervention(task, failure)
194
+ @intervention_requests[task.id] = {
195
+ task_id: task.id,
196
+ task_description: task.description,
197
+ failure: failure.to_h,
198
+ timestamp: Time.now,
199
+ status: :pending
200
+ }
201
+
202
+ # Notify human operators
203
+ notify_operators(task)
204
+ end
205
+ end
206
+ ```
207
+
208
+ ## Benefits of Observable Pattern
209
+
210
+ ### 1. Loose Coupling
211
+
212
+ The Observable pattern decouples tasks from components that need to react to task state:
213
+
214
+ ```
215
+ ┌─────────────────┐
216
+ │MetricsCollector │
217
+ └────────┬────────┘
218
+
219
+ ┌─────┐ notify ┌──────┐ │ update
220
+ │Agent│───────────▶ │ Task │◀──┘
221
+ └─────┘ └──────┘
222
+
223
+
224
+ ┌───┴────────────┐
225
+ │PlanOrchestrator│
226
+ └────────────────┘
227
+ ```
228
+
229
+ This enables:
230
+ - Independent development of components
231
+ - Pluggable monitoring and orchestration
232
+ - Testing in isolation
233
+
234
+ ### 2. Flexible Execution Models
235
+
236
+ The Observer pattern supports both:
237
+ - **Synchronous Execution**: Direct response to events
238
+ - **Asynchronous Execution**: Event queues with background processing
239
+
240
+ This enables evolution of the execution model without changing the Task interface.
241
+
242
+ ### 3. Simplified Extensibility
243
+
244
+ New functionality can be added by implementing new observers:
245
+
246
+ ```ruby
247
+ # Add execution logging without modifying Task
248
+ class TaskLogger
249
+ def update(event_type, task, *args)
250
+ if event_type == :status_change
251
+ old_status, new_status = args
252
+ Agentic.logger.info("Task #{task.id} transitioned from #{old_status} to #{new_status}")
253
+ end
254
+ end
255
+ end
256
+
257
+ # Usage:
258
+ task = Task.new(...)
259
+ task.add_observer(TaskLogger.new)
260
+ ```
261
+
262
+ ### 4. Enhanced Parallelism
263
+
264
+ Observable pattern enables:
265
+ - Multiple observers processing events in parallel
266
+ - Observer-specific thread pools
267
+ - Backpressure handling per observer
268
+
269
+ ## Implementation Considerations
270
+
271
+ ### 1. Thread Safety
272
+
273
+ Ruby's Observable implementation is not thread-safe by default. In multi-threaded environments:
274
+
275
+ - Consider using a thread-safe observer collection
276
+ - Use synchronization when notifying observers
277
+ - Consider thread-local changed flag
278
+
279
+ Example enhancement:
280
+
281
+ ```ruby
282
+ module ThreadSafeObservable
283
+ include Observable
284
+
285
+ def notify_observers(*args)
286
+ observers = @observer_peers.dup
287
+ observers.each do |observer|
288
+ observer.update(*args)
289
+ end
290
+ end
291
+ end
292
+ ```
293
+
294
+ ### 2. Memory Management
295
+
296
+ Observers create references to the observed objects which may lead to memory leaks:
297
+
298
+ - Ensure observers are properly removed when no longer needed
299
+ - Consider using weak references for long-lived tasks
300
+ - Implement cleanup methods for completed tasks
301
+
302
+ ### 3. Error Handling
303
+
304
+ Observer errors should not affect the observed object:
305
+
306
+ ```ruby
307
+ def notify_observers(*args)
308
+ observers = @observer_peers.dup
309
+ observers.each do |observer|
310
+ begin
311
+ observer.update(*args)
312
+ rescue => e
313
+ Agentic.logger.error("Observer error: #{e.message}")
314
+ end
315
+ end
316
+ end
317
+ ```
318
+
319
+ ## Integration with Larger Architecture
320
+
321
+ ### 1. PlanOrchestrator
322
+
323
+ The PlanOrchestrator becomes an observer of all tasks it manages:
324
+
325
+ ```ruby
326
+ def execute_plan(tasks)
327
+ tasks.each do |task|
328
+ task.add_observer(self)
329
+ # Add other observers as needed
330
+ task.add_observer(MetricsCollector.instance)
331
+ task.add_observer(HumanInterventionPortal.instance)
332
+ end
333
+
334
+ # Start eligible tasks
335
+ start_eligible_tasks(tasks)
336
+ end
337
+ ```
338
+
339
+ ### 2. Verification System
340
+
341
+ Verification can be triggered by task status changes:
342
+
343
+ ```ruby
344
+ class VerificationHub
345
+ def update(event_type, task, *args)
346
+ if event_type == :status_change
347
+ old_status, new_status = args
348
+
349
+ if new_status == :completed
350
+ # Perform verification
351
+ verification_result = verify(task)
352
+
353
+ # Notify observers of verification result
354
+ task.changed
355
+ task.notify_observers(:verification_complete, task, verification_result)
356
+ end
357
+ end
358
+ end
359
+ end
360
+ ```
361
+
362
+ ### 3. Learning System
363
+
364
+ The learning system can observe tasks to gather training data:
365
+
366
+ ```ruby
367
+ class ExecutionHistoryStore
368
+ def update(event_type, task, *args)
369
+ case event_type
370
+ when :status_change
371
+ record_status_change(task, *args)
372
+ when :failure_occurred
373
+ record_failure(task, *args.first)
374
+ when :verification_complete
375
+ record_verification(task, *args.first)
376
+ end
377
+ end
378
+ end
379
+ ```
380
+
381
+ ## Conclusion
382
+
383
+ The Observable pattern provides a robust, flexible foundation for task state management in the Agentic framework. By leveraging Ruby's built-in Observable module, we achieve loose coupling between tasks and the components that react to them, enabling a more extensible and maintainable architecture.
384
+
385
+ This design supports our core architectural goals of:
386
+ - Separation of concerns
387
+ - Extensibility
388
+ - Resilience to failures
389
+ - Flexible execution models
390
+
391
+ The Observable pattern will be particularly valuable as the system grows in complexity, allowing new monitoring, orchestration, and intervention components to be added without modifying the core Task implementation.