language-operator 0.1.63 → 0.1.65

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/.plan.md +127 -0
  3. data/.rspec +3 -0
  4. data/Gemfile +2 -0
  5. data/Gemfile.lock +4 -1
  6. data/Makefile +34 -80
  7. data/components/agent/Gemfile +1 -1
  8. data/docs/cheat-sheet.md +173 -0
  9. data/lib/language_operator/agent/base.rb +10 -1
  10. data/lib/language_operator/agent/event_config.rb +172 -0
  11. data/lib/language_operator/agent/safety/ast_validator.rb +1 -1
  12. data/lib/language_operator/agent/safety/safe_executor.rb +5 -1
  13. data/lib/language_operator/agent/task_executor.rb +87 -7
  14. data/lib/language_operator/agent/telemetry.rb +25 -3
  15. data/lib/language_operator/agent/web_server.rb +6 -9
  16. data/lib/language_operator/cli/commands/agent/base.rb +15 -17
  17. data/lib/language_operator/cli/commands/agent/learning.rb +156 -37
  18. data/lib/language_operator/cli/commands/cluster.rb +2 -2
  19. data/lib/language_operator/cli/commands/status.rb +2 -2
  20. data/lib/language_operator/cli/commands/system/synthesize.rb +1 -1
  21. data/lib/language_operator/cli/formatters/value_formatter.rb +1 -1
  22. data/lib/language_operator/cli/helpers/ux_helper.rb +3 -4
  23. data/lib/language_operator/config.rb +3 -3
  24. data/lib/language_operator/constants/kubernetes_labels.rb +2 -2
  25. data/lib/language_operator/dsl/task_definition.rb +18 -7
  26. data/lib/language_operator/instrumentation/task_tracer.rb +44 -3
  27. data/lib/language_operator/kubernetes/client.rb +111 -0
  28. data/lib/language_operator/templates/schema/CHANGELOG.md +28 -0
  29. data/lib/language_operator/templates/schema/agent_dsl_openapi.yaml +1 -1
  30. data/lib/language_operator/templates/schema/agent_dsl_schema.json +1 -1
  31. data/lib/language_operator/type_coercion.rb +22 -8
  32. data/lib/language_operator/version.rb +1 -1
  33. data/synth/002/agent.rb +23 -12
  34. data/synth/002/output.log +88 -15
  35. data/synth/003/Makefile +5 -2
  36. data/synth/004/Makefile +54 -0
  37. data/synth/004/README.md +281 -0
  38. data/synth/004/instructions.txt +1 -0
  39. metadata +8 -1
@@ -12,6 +12,34 @@ The schema version is tied directly to the gem version and follows [Semantic Ver
12
12
 
13
13
  ## Version History
14
14
 
15
+ ### 0.1.64 (2025-11-27)
16
+
17
+ **Learning Status & Observability Improvements**
18
+
19
+ This release enhances the learning status tracking and observability features for agents.
20
+
21
+ **New Features:**
22
+ - Added semantic OpenTelemetry attributes for learning status tracking
23
+ - Implemented Kubernetes event emission for agent-operator communication
24
+ - Real execution metrics from learning status ConfigMap integration
25
+
26
+ **Improvements:**
27
+ - Enhanced `aictl agent learning-status` command with color-coded boxes and better clarity
28
+ - Changed terminology from "Runs Completed" to "Runs Processed"
29
+ - Improved learning status display formatting with cyan highlighted boxes
30
+ - Restructured learning status into two clear informational boxes
31
+
32
+ **Bug Fixes:**
33
+ - Handle empty string `lastExecution` in ConfigMap data
34
+ - Fixed SigNoz Query Builder v5 select fields usage
35
+ - Fixed K8s::Resource annotations handling in learning status command
36
+ - Resolved hanging tests and improved test output visibility
37
+
38
+ **Test Improvements:**
39
+ - Added comprehensive aictl smoke test playbook
40
+ - Removed obsolete learning adapter specs
41
+ - Fixed OpenTelemetry mocking in task executor event emission test
42
+
15
43
  ### 0.1.34 (2025-11-14)
16
44
 
17
45
  **DSL v1: Task/Main Primitives Added**
@@ -2,7 +2,7 @@
2
2
  :openapi: 3.0.3
3
3
  :info:
4
4
  :title: Language Operator Agent API
5
- :version: 0.1.63
5
+ :version: 0.1.65
6
6
  :description: HTTP API endpoints exposed by Language Operator reactive agents
7
7
  :contact:
8
8
  :name: Language Operator
@@ -3,7 +3,7 @@
3
3
  "$id": "https://github.com/language-operator/language-operator-gem/schema/agent-dsl.json",
4
4
  "title": "Language Operator Agent DSL",
5
5
  "description": "Schema for defining autonomous AI agents using the Language Operator DSL",
6
- "version": "0.1.63",
6
+ "version": "0.1.65",
7
7
  "type": "object",
8
8
  "properties": {
9
9
  "name": {
@@ -19,7 +19,7 @@ module LanguageOperator
19
19
  # - integer: Coerces String, Integer, Float to Integer
20
20
  # - number: Coerces String, Integer, Float to Float
21
21
  # - string: Coerces any value to String via to_s
22
- # - boolean: Coerces String, Boolean to Boolean (explicit values only)
22
+ # - boolean: Coerces String, Integer (0 or 1), Boolean to Boolean (explicit values only)
23
23
  # - array: Strict validation (no coercion)
24
24
  # - hash: Strict validation (no coercion)
25
25
  # - any: No coercion, passes through any value
@@ -32,8 +32,11 @@ module LanguageOperator
32
32
  # @example Boolean coercion
33
33
  # TypeCoercion.coerce("true", "boolean") # => true
34
34
  # TypeCoercion.coerce("1", "boolean") # => true
35
+ # TypeCoercion.coerce(1, "boolean") # => true
36
+ # TypeCoercion.coerce(0, "boolean") # => false
35
37
  # TypeCoercion.coerce("false", "boolean") # => false
36
38
  # TypeCoercion.coerce("maybe", "boolean") # raises ArgumentError
39
+ # TypeCoercion.coerce(2, "boolean") # raises ArgumentError
37
40
  #
38
41
  # @example String coercion (never fails)
39
42
  # TypeCoercion.coerce(:symbol, "string") # => "symbol"
@@ -213,11 +216,11 @@ module LanguageOperator
213
216
 
214
217
  # Coerce value to Boolean
215
218
  #
216
- # Accepts: Boolean, String (explicit values only)
219
+ # Accepts: Boolean, Integer (0 or 1), String (explicit values only)
217
220
  # Coercion: Case-insensitive string matching with optimized pattern lookup
218
- # Truthy: "true", "1", "yes", "t", "y"
219
- # Falsy: "false", "0", "no", "f", "n"
220
- # Errors: Ambiguous values (e.g., "maybe", "unknown")
221
+ # Truthy: "true", "1", "yes", "t", "y", 1 (integer)
222
+ # Falsy: "false", "0", "no", "f", "n", 0 (integer)
223
+ # Errors: Ambiguous values (e.g., "maybe", "unknown"), integers other than 0 or 1
221
224
  #
222
225
  # @param value [Object] Value to coerce
223
226
  # @return [Boolean] Coerced boolean
@@ -227,17 +230,28 @@ module LanguageOperator
227
230
  # coerce_boolean(true) # => true
228
231
  # coerce_boolean("true") # => true
229
232
  # coerce_boolean("1") # => true
233
+ # coerce_boolean(1) # => true
230
234
  # coerce_boolean("yes") # => true
231
235
  # coerce_boolean(false) # => false
232
236
  # coerce_boolean("false") # => false
233
237
  # coerce_boolean("0") # => false
238
+ # coerce_boolean(0) # => false
234
239
  # coerce_boolean("no") # => false
235
240
  # coerce_boolean("maybe") # raises ArgumentError
241
+ # coerce_boolean(2) # raises ArgumentError
236
242
  def self.coerce_boolean(value)
237
243
  # Fast path for already-correct types
238
244
  return value if value.is_a?(TrueClass) || value.is_a?(FalseClass)
239
245
 
240
- # Only allow string values for coercion (not integers or other types)
246
+ # Handle integer 0 and 1 (common in many programming contexts)
247
+ if value.is_a?(Integer)
248
+ return true if value == 1
249
+ return false if value.zero?
250
+
251
+ raise ArgumentError, "Cannot coerce #{value.inspect} to boolean (only 0 and 1 are valid integers)"
252
+ end
253
+
254
+ # Only allow string values for coercion (not floats, symbols, or other types)
241
255
  raise ArgumentError, "Cannot coerce #{value.inspect} to boolean" unless value.is_a?(String)
242
256
 
243
257
  # Optimized pattern matching using pre-compiled arrays
@@ -308,9 +322,9 @@ module LanguageOperator
308
322
  errors: 'Never (everything has to_s)'
309
323
  },
310
324
  'boolean' => {
311
- accepts: 'Boolean, String (explicit values)',
325
+ accepts: 'Boolean, Integer (0 or 1), String (explicit values)',
312
326
  method: 'Pattern matching (true/1/yes/t/y or false/0/no/f/n)',
313
- errors: 'Ambiguous values'
327
+ errors: 'Ambiguous values, integers other than 0 or 1'
314
328
  },
315
329
  'array' => {
316
330
  accepts: 'Array only',
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LanguageOperator
4
- VERSION = '0.1.63'
4
+ VERSION = '0.1.65'
5
5
  end
data/synth/002/agent.rb CHANGED
@@ -1,22 +1,33 @@
1
- # frozen_string_literal: true
2
-
3
1
  require 'language_operator'
4
2
 
5
- agent 'test-agent' do
6
- description 'Tell a fortune every 10 minutes'
3
+ agent "s002" do
4
+ description "Tell me a fortune every 10 minutes"
5
+
7
6
  mode :scheduled
8
- schedule '*/10 * * * *'
7
+ schedule "*/10 * * * *"
8
+
9
+ task :generate_fortune,
10
+ instructions: "Generate a short, positive fortune message. Keep it under 100 words. Make it inspiring and uplifting.",
11
+ inputs: {},
12
+ outputs: { fortune: 'string' }
9
13
 
10
- task :tell_fortune,
11
- instructions: 'Generate a random fortune message',
12
- inputs: {},
13
- outputs: { fortune: 'string' }
14
+ task :format_output,
15
+ instructions: "Format the fortune message into a readable output string with a title 'Your Fortune:'",
16
+ inputs: { fortune: 'string' },
17
+ outputs: { message: 'string' }
18
+
19
+ main do |inputs|
20
+ fortune = execute_task(:generate_fortune)
21
+ output = execute_task(:format_output, inputs: fortune)
22
+ output
23
+ end
14
24
 
15
- main do |_inputs|
16
- execute_task(:tell_fortune)
25
+ constraints do
26
+ max_iterations 999999
27
+ timeout "10m"
17
28
  end
18
29
 
19
30
  output do |outputs|
20
- puts outputs[:fortune]
31
+ puts outputs[:message]
21
32
  end
22
33
  end
data/synth/002/output.log CHANGED
@@ -1,21 +1,94 @@
1
+ ⚬ Streaming logs for agent 's002'...
2
+
3
+ ⚬ Language Operator v0.1.61
1
4
  ⚬ OpenTelemetry disabled
2
- ⚬ Configuring LLM (provider=openai_compatible, model=mistralai/magistral-small-2509, timeout=300)
5
+ ⚬ Configuring LLM (provider=openai_compatible, model=qwen3-coder:30b, timeout=300)
3
6
  ⚬ LLM configuration complete
4
7
  ⚬ No MCP servers configured, agent will run without tools
5
- ⚬ Chat session initialized (with_tools=false)
6
- ⚬ Executing main block (agent=test-agent, task_count=1)
8
+ ⚬ Chat session initialized (with_tools=false, total_tools=0)
9
+ ⚬ Agent running in scheduled mode - executing once (agent_name=s002, dsl_version=v1)
10
+ ⚬ Executing main block (agent=s002, task_count=2)
7
11
  ⚬ Executing main block (inputs_keys=[])
8
- ⚬ Executing task (task=tell_fortune, type=neural, timeout=240.0, max_retries=3)
9
- ⚬ Sending prompt to LLM (task=tell_fortune, prompt_length=417)
10
- ⚬ LLM response received, extracting content (task=tell_fortune)
11
- ⚬ Neural task response received (task=tell_fortune, response_length=3617)
12
- ⚬ Parsing neural task response (task=tell_fortune)
13
- ⚬ Response parsed successfully (task=tell_fortune, output_keys=[:fortune])
14
- ⚬ Validating task outputs (task=tell_fortune)
15
- ⚬ Main execution (33.916s)
12
+ ⚬ Sending prompt to LLM (task=generate_fortune, prompt_length=632, available_tools=[])
13
+ ⚬ LLM response received, extracting content (task=generate_fortune, response_class=RubyLLM::Message, has_tool_calls=, tool_call_count=0)
14
+ ⚬ Neural task response received (task=generate_fortune, response_length=563)
15
+ ⚬ Parsing neural task response (task=generate_fortune)
16
+ ⚬ LLM thinking captured (event=llm_thinking, task=generate_fortune, thinking_steps=1, thinking=["\nI need to generate a short, positive fortune message that is inspiring and uplifting, under 100 words. The message should be meaningful and encourage the reader. I'll create a brief, motivational message about perseverance and positive outcomes.\n\n"], thinking_preview=
17
+ I need to generate a short, positive fortune message that is inspiring and uplifting, under 100 w...)
18
+ ⚬ Response parsed successfully (task=generate_fortune, output_keys=[:fortune])
19
+ ⚬ Validating task outputs (task=generate_fortune)
20
+ ⚬ Sending prompt to LLM (task=format_output, prompt_length=918, available_tools=[])
21
+ ⚬ LLM response received, extracting content (task=format_output, response_class=RubyLLM::Message, has_tool_calls=, tool_call_count=0)
22
+ ⚬ Neural task response received (task=format_output, response_length=583)
23
+ ⚬ Parsing neural task response (task=format_output)
24
+ ⚬ LLM thinking captured (event=llm_thinking, task=format_output, thinking_steps=1, thinking=["\nI need to format the fortune message into a readable output string with the title 'Your Fortune:' as specified. The input fortune message is already provided and needs to be wrapped with the title. I'll create a JSON object with the formatted message.\n\n"], thinking_preview=
25
+ I need to format the fortune message into a readable output string with the title 'Your Fortune:'...)
26
+ ⚬ Response parsed successfully (task=format_output, output_keys=[:message])
27
+ ⚬ Validating task outputs (task=format_output)
28
+ ⚬ Main execution (13.01s)
16
29
  ⚬ Main block completed
17
- ⚬ Main block execution completed (result={fortune: "Your kindness will bring you much happiness."})
18
- Your kindness will bring you much happiness.
19
- ✔ Agent completed successfully
20
-
30
+ ⚬ Main block execution completed (result={message: "Your Fortune: Every challenge you face today is building strength you didn't know you had. Trust the process, believe in yourself, and remember that brighter days are always ahead. Your hard work and dedication will soon bring rewarding results. Keep moving forward with hope and determination."})
31
+ Your Fortune: Every challenge you face today is building strength you didn't know you had. Trust the process, believe in yourself, and remember that brighter days are always ahead. Your hard work and dedication will soon bring rewarding results. Keep moving forward with hope and determination.
32
+ ⚬ Scheduled execution completed - exiting (agent_name=s002)
33
+ ⚬ Language Operator v0.1.61
34
+ ⚬ OpenTelemetry disabled
35
+ ⚬ Configuring LLM (provider=openai_compatible, model=qwen3-coder:30b, timeout=300)
36
+ ⚬ LLM configuration complete
37
+ ⚬ No MCP servers configured, agent will run without tools
38
+ ⚬ Chat session initialized (with_tools=false, total_tools=0)
39
+ ⚬ Agent running in scheduled mode - executing once (agent_name=s002, dsl_version=v1)
40
+ ⚬ Executing main block (agent=s002, task_count=2)
41
+ ⚬ Executing main block (inputs_keys=[])
42
+ ⚬ Sending prompt to LLM (task=generate_fortune, prompt_length=632, available_tools=[])
43
+ ⚬ LLM response received, extracting content (task=generate_fortune, response_class=RubyLLM::Message, has_tool_calls=, tool_call_count=0)
44
+ ⚬ Neural task response received (task=generate_fortune, response_length=707)
45
+ ⚬ Parsing neural task response (task=generate_fortune)
46
+ ⚬ LLM thinking captured (event=llm_thinking, task=generate_fortune, thinking_steps=1, thinking=["\nI need to create a short, positive fortune message that is inspiring and uplifting, under 100 words. The message should be generally encouraging and positive in nature. Let me think of a message that conveys hope, perseverance, or personal growth in a concise way.\n\nI'll create a fortune that emphasizes the power of persistence and believing in oneself - a common theme that's universally uplifting and inspiring.\n"], thinking_preview=
47
+ I need to create a short, positive fortune message that is inspiring and uplifting, under 100 wor...)
48
+ ⚬ Response parsed successfully (task=generate_fortune, output_keys=[:fortune])
49
+ ⚬ Validating task outputs (task=generate_fortune)
50
+ ⚬ Sending prompt to LLM (task=format_output, prompt_length=893, available_tools=[])
51
+ ⚬ LLM response received, extracting content (task=format_output, response_class=RubyLLM::Message, has_tool_calls=, tool_call_count=0)
52
+ ⚬ Neural task response received (task=format_output, response_length=745)
53
+ ⚬ Parsing neural task response (task=format_output)
54
+ ⚬ LLM thinking captured (event=llm_thinking, task=format_output, thinking_steps=1, thinking=["\nI need to format the fortune message into a readable output string with the title 'Your Fortune:' as requested. The fortune message is quite long, so I'll format it nicely with proper spacing and structure. I'll create a formatted string that includes the title and the fortune content.\n\nI'll create a clean, readable format that presents the fortune in an appealing way while keeping it concise and maintaining the inspirational tone.\n"], thinking_preview=
55
+ I need to format the fortune message into a readable output string with the title 'Your Fortune:'...)
56
+ ⚬ Response parsed successfully (task=format_output, output_keys=[:message])
57
+ ⚬ Validating task outputs (task=format_output)
58
+ ⚬ Main execution (12.698s)
59
+ ⚬ Main block completed
60
+ ⚬ Main block execution completed (result={message: "Your Fortune:\n\nEvery challenge you face today is building the strength you'll need for tomorrow. Believe in your ability to grow through difficulties and trust that better days are ahead. You have within you everything you need to succeed and create the life you desire."})
61
+ Your Fortune:
21
62
 
63
+ Every challenge you face today is building the strength you'll need for tomorrow. Believe in your ability to grow through difficulties and trust that better days are ahead. You have within you everything you need to succeed and create the life you desire.
64
+ ⚬ Scheduled execution completed - exiting (agent_name=s002)
65
+ ⚬ Language Operator v0.1.61
66
+ ⚬ OpenTelemetry disabled
67
+ ⚬ Configuring LLM (provider=openai_compatible, model=qwen3-coder:30b, timeout=300)
68
+ ⚬ LLM configuration complete
69
+ ⚬ No MCP servers configured, agent will run without tools
70
+ ⚬ Chat session initialized (with_tools=false, total_tools=0)
71
+ ⚬ Agent running in scheduled mode - executing once (agent_name=s002, dsl_version=v1)
72
+ ⚬ Executing main block (agent=s002, task_count=2)
73
+ ⚬ Executing main block (inputs_keys=[])
74
+ ⚬ Sending prompt to LLM (task=generate_fortune, prompt_length=632, available_tools=[])
75
+ ⚬ LLM response received, extracting content (task=generate_fortune, response_class=RubyLLM::Message, has_tool_calls=, tool_call_count=0)
76
+ ⚬ Neural task response received (task=generate_fortune, response_length=591)
77
+ ⚬ Parsing neural task response (task=generate_fortune)
78
+ ⚬ LLM thinking captured (event=llm_thinking, task=generate_fortune, thinking_steps=1, thinking=["\nI need to create a positive, inspiring fortune message under 100 words. The message should be uplifting and motivational. Let me craft something that feels genuine and encouraging.\n\nThe fortune should be short and impactful, focusing on positivity and inspiration. I'll make sure it's under 100 words as requested.\n"], thinking_preview=
79
+ I need to create a positive, inspiring fortune message under 100 words. The message should be upl...)
80
+ ⚬ Response parsed successfully (task=generate_fortune, output_keys=[:fortune])
81
+ ⚬ Validating task outputs (task=generate_fortune)
82
+ ⚬ Sending prompt to LLM (task=format_output, prompt_length=877, available_tools=[])
83
+ ⚬ LLM response received, extracting content (task=format_output, response_class=RubyLLM::Message, has_tool_calls=, tool_call_count=0)
84
+ ⚬ Neural task response received (task=format_output, response_length=491)
85
+ ⚬ Parsing neural task response (task=format_output)
86
+ ⚬ LLM thinking captured (event=llm_thinking, task=format_output, thinking_steps=1, thinking=["\nI need to format the fortune message with the title 'Your Fortune:' as requested. The message should be properly formatted with this title prefix. I'll create a JSON object with the formatted message.\n"], thinking_preview=
87
+ I need to format the fortune message with the title 'Your Fortune:' as requested. The message sho...)
88
+ ⚬ Response parsed successfully (task=format_output, output_keys=[:message])
89
+ ⚬ Validating task outputs (task=format_output)
90
+ ⚬ Main execution (12.256s)
91
+ ⚬ Main block completed
92
+ ⚬ Main block execution completed (result={message: "Your Fortune: Your kindness creates ripples of joy that extend far beyond what you can see. Every small act of compassion matters, and your positive energy lights up the world around you. Trust in your ability to make a difference, one moment at a time."})
93
+ Your Fortune: Your kindness creates ripples of joy that extend far beyond what you can see. Every small act of compassion matters, and your positive energy lights up the world around you. Trust in your ability to make a difference, one moment at a time.
94
+ ⚬ Scheduled execution completed - exiting (agent_name=s002)
data/synth/003/Makefile CHANGED
@@ -17,8 +17,11 @@ run:
17
17
  code:
18
18
  $(AICTL) code $(AGENT)
19
19
 
20
- optimize:
21
- OTEL_QUERY_ENDPOINT=$(OTEL_QUERY_ENDPOINT) OTEL_QUERY_API_KEY=$(OTEL_QUERY_API_KEY) OTEL_QUERY_BACKEND=$(OTEL_QUERY_BACKEND) $(AICTL) optimize $(AGENT)
20
+ inspect:
21
+ $(AICTL) inspect $(AGENT)
22
+
23
+ learning-status:
24
+ $(AICTL) learning status $(AGENT)
22
25
 
23
26
  logs:
24
27
  $(AICTL) logs $(AGENT)
@@ -0,0 +1,54 @@
1
+ .PHONY: create code logs clean events validate run
2
+
3
+ AGENT := s004
4
+ AICTL := bundle exec ../../bin/aictl agent
5
+ TOOLS := workspace
6
+
7
+ create:
8
+ cat instructions.txt | $(AICTL) create --name $(AGENT) --tools "$(TOOLS)"
9
+
10
+ run:
11
+ @JOB_NAME=$(AGENT)-$(shell date +%s); \
12
+ kubectl create job --from=cronjob/$(AGENT) $$JOB_NAME && \
13
+ trap "kubectl delete job $$JOB_NAME" EXIT; \
14
+ kubectl wait --for=condition=ready pod -l job-name=$$JOB_NAME --timeout=60s && \
15
+ kubectl logs -f job/$$JOB_NAME
16
+
17
+ code:
18
+ $(AICTL) code $(AGENT)
19
+
20
+ inspect:
21
+ $(AICTL) inspect $(AGENT)
22
+
23
+ logs:
24
+ $(AICTL) logs $(AGENT)
25
+
26
+ # Health monitoring specific commands
27
+ events:
28
+ @echo "=== Checking for Task Completion events ===" && \
29
+ kubectl get events -n language-operator --field-selector involvedObject.name=$(AGENT) --sort-by='.lastTimestamp' || \
30
+ echo "No events found - this may indicate observability issues"
31
+
32
+ validate:
33
+ @echo "=== Validating observability infrastructure ===" && \
34
+ echo "1. Checking if agent exists..." && \
35
+ $(AICTL) inspect $(AGENT) && \
36
+ echo "2. Checking recent logs..." && \
37
+ $(AICTL) logs $(AGENT) --tail=20 && \
38
+ echo "3. Checking for events..." && \
39
+ make events && \
40
+ echo "4. Checking CronJob status..." && \
41
+ kubectl get cronjob $(AGENT) -n language-operator
42
+
43
+ health:
44
+ @echo "=== System Health Check Status ===" && \
45
+ echo "Last execution logs:" && \
46
+ $(AICTL) logs $(AGENT) --tail=50 | grep -E "(healthy|error|fail|success|reachable)" || \
47
+ echo "No health status found in recent logs"
48
+
49
+ clean:
50
+ $(AICTL) delete $(AGENT) --force
51
+
52
+ save:
53
+ $(AICTL) code $(AGENT) --raw > agent.rb
54
+ $(AICTL) logs $(AGENT) > output.log
@@ -0,0 +1,281 @@
1
+ # 004 - System Health Monitoring & Observability Validation
2
+
3
+ ## Instructions
4
+
5
+ "Check if the system is healthy every 5 minutes and report any issues"
6
+
7
+ ## Significance
8
+
9
+ This validates observability infrastructure and system self-monitoring capabilities in DSL v1.
10
+
11
+ While tests 001-003 validated synthesis, neural execution, and learning, this test validates that the system can properly observe and report on its own health - including the critical infrastructure required for observability itself.
12
+
13
+ This is the first synthesis test focused on infrastructure resilience and event emission validation.
14
+
15
+ ## What This Demonstrates
16
+
17
+ ### 1. Self-Observability Architecture
18
+
19
+ The synthesized agent should naturally generate tasks that validate:
20
+ - **Kubernetes API connectivity** - Can reach cluster API for event emission
21
+ - **LLM endpoint availability** - Can execute neural tasks
22
+ - **Monitoring system integration** - Can send telemetry data
23
+ - **Event emission functionality** - Task Completion events are generated
24
+ - **Network policy compliance** - Agent can reach required services
25
+
26
+ ### 2. Infrastructure Resilience Testing
27
+
28
+ ```ruby
29
+ # Expected synthesis pattern
30
+ task :check_kubernetes_api,
31
+ instructions: "Test connectivity to Kubernetes API server",
32
+ outputs: { reachable: 'boolean', response_time_ms: 'integer' }
33
+
34
+ task :check_llm_endpoint,
35
+ instructions: "Verify LLM model is responding",
36
+ outputs: { available: 'boolean', model_name: 'string' }
37
+
38
+ task :check_monitoring_system,
39
+ instructions: "Test OpenTelemetry/monitoring endpoint connectivity",
40
+ outputs: { telemetry_working: 'boolean', endpoint: 'string' }
41
+
42
+ task :validate_event_emission,
43
+ instructions: "Ensure task execution events are being emitted properly",
44
+ outputs: { events_working: 'boolean', last_event_time: 'string' }
45
+
46
+ main do |inputs|
47
+ # Systematic health validation
48
+ api_status = execute_task(:check_kubernetes_api)
49
+ llm_status = execute_task(:check_llm_endpoint)
50
+ monitoring_status = execute_task(:check_monitoring_system)
51
+ events_status = execute_task(:validate_event_emission)
52
+
53
+ # Overall health determination and reporting
54
+ overall_healthy = api_status[:reachable] &&
55
+ llm_status[:available] &&
56
+ monitoring_status[:telemetry_working] &&
57
+ events_status[:events_working]
58
+
59
+ {
60
+ healthy: overall_healthy,
61
+ components: {
62
+ kubernetes: api_status,
63
+ llm: llm_status,
64
+ monitoring: monitoring_status,
65
+ events: events_status
66
+ },
67
+ timestamp: Time.now.iso8601
68
+ }
69
+ end
70
+ ```
71
+
72
+ ### 3. Scheduled Health Monitoring
73
+
74
+ ```ruby
75
+ mode :scheduled
76
+ schedule "*/5 * * * *" # Every 5 minutes
77
+ ```
78
+
79
+ Each execution:
80
+ 1. Tests all critical infrastructure components
81
+ 2. Generates multiple Task Completion events (validation target)
82
+ 3. Reports comprehensive health status
83
+ 4. Creates telemetry spans for observability
84
+ 5. Exits and waits for next scheduled run
85
+
86
+ ### 4. Event Emission Validation (Critical)
87
+
88
+ This test specifically validates the Task Completion event infrastructure that was failing due to NetworkPolicy issues. Each health check execution should generate:
89
+
90
+ - **Task Start events** for each health check task
91
+ - **Task Completion events** (success/failure) for each task
92
+ - **OpenTelemetry traces** with health check spans
93
+ - **Agent execution events** for overall run status
94
+
95
+ **Key Validation**: If Task Completion events are missing, the health check itself reports the observability system as unhealthy.
96
+
97
+ ### 5. Meta-Validation Property
98
+
99
+ The test has a beautiful self-validating property:
100
+
101
+ ```
102
+ IF observability infrastructure is broken
103
+ THEN health check cannot report properly
104
+ THEN system correctly reports as unhealthy
105
+ THEREFORE test reveals infrastructure issues
106
+ ```
107
+
108
+ This makes it impossible for observability problems to hide - they become part of the health status.
109
+
110
+ ## Why This Matters
111
+
112
+ ### Fills Critical Testing Gap
113
+
114
+ Current synthesis test coverage:
115
+ - ✅ **001**: Basic synthesis functionality
116
+ - ✅ **002**: Neural task execution + scheduling
117
+ - ✅ **003**: Progressive learning + optimization
118
+ - ✅ **004**: Infrastructure resilience + observability
119
+
120
+ ### Validates Production Readiness
121
+
122
+ Real-world deployments require:
123
+ - **Health monitoring** - System can detect its own problems
124
+ - **Event emission** - Observability data is generated correctly
125
+ - **Network policies** - Security restrictions don't break functionality
126
+ - **Infrastructure dependencies** - All required services are reachable
127
+
128
+ ### Catches Infrastructure Configuration Errors
129
+
130
+ This test would immediately detect:
131
+ - NetworkPolicy blocking Kubernetes API access
132
+ - Broken OpenTelemetry configuration
133
+ - LLM endpoint connectivity issues
134
+ - Missing RBAC permissions for event creation
135
+ - Firewall rules blocking required traffic
136
+
137
+ ### Self-Healing Validation
138
+
139
+ The test validates that agents can:
140
+ - Detect infrastructure problems
141
+ - Report issues clearly
142
+ - Continue functioning despite partial failures
143
+ - Provide actionable diagnostic information
144
+
145
+ ## Real-World Use Cases This Enables
146
+
147
+ ### Cluster Health Monitoring
148
+ ```ruby
149
+ # Production monitoring agent
150
+ "Monitor cluster resources and alert if anything is degraded"
151
+ # → Generates comprehensive cluster health dashboard
152
+ ```
153
+
154
+ ### Service Dependency Validation
155
+ ```ruby
156
+ # Service mesh health checking
157
+ "Test all service connections and report any broken integrations"
158
+ # → Validates microservice communication patterns
159
+ ```
160
+
161
+ ### Infrastructure Compliance Auditing
162
+ ```ruby
163
+ # Security and compliance monitoring
164
+ "Check if all security policies are working correctly"
165
+ # → Validates network policies, RBAC, pod security standards
166
+ ```
167
+
168
+ ### Self-Healing System Validation
169
+ ```ruby
170
+ # Resilience testing
171
+ "Verify the system can recover from common failure scenarios"
172
+ # → Tests automatic recovery mechanisms
173
+ ```
174
+
175
+ ## Expected Synthesis Outcomes
176
+
177
+ ### Neural Phase (Initial Synthesis)
178
+ - **All tasks neural** - Uses LLM to determine health check methods
179
+ - **Flexible validation** - Adapts to different infrastructure configurations
180
+ - **Comprehensive checking** - Tests all critical system components
181
+
182
+ ### Learning Phase (After Pattern Detection)
183
+ - **Deterministic checks become symbolic** - API connectivity, endpoint tests
184
+ - **Complex analysis stays neural** - Overall health determination, anomaly detection
185
+ - **Optimized execution** - Faster, cheaper health checks over time
186
+
187
+ ### Progressive Optimization
188
+ ```ruby
189
+ # Run 1-10: All neural health checks
190
+ # Run 11+: Learned symbolic implementations for standard checks
191
+ # Always: Neural analysis of overall system health patterns
192
+ ```
193
+
194
+ ## Validation Criteria
195
+
196
+ ### Infrastructure Health
197
+ - [ ] Kubernetes API connectivity verified
198
+ - [ ] LLM endpoint responsiveness confirmed
199
+ - [ ] Monitoring system integration working
200
+ - [ ] Network policies allow required access
201
+
202
+ ### Event Emission
203
+ - [ ] Task Completion events generated for each task
204
+ - [ ] Events contain proper metadata and timing
205
+ - [ ] OpenTelemetry traces collected successfully
206
+ - [ ] No event emission timeout errors
207
+
208
+ ### Error Handling
209
+ - [ ] Graceful handling of connectivity failures
210
+ - [ ] Clear reporting of specific issues
211
+ - [ ] Continued operation despite partial failures
212
+ - [ ] Actionable diagnostic information provided
213
+
214
+ ### Schedule Reliability
215
+ - [ ] Executions occur every 5 minutes as scheduled
216
+ - [ ] Consistent performance across runs
217
+ - [ ] Proper cleanup after each execution
218
+ - [ ] No resource leaks or accumulation
219
+
220
+ ## Comparison to Traditional Monitoring
221
+
222
+ ### Traditional Approach (Prometheus/Nagios)
223
+ ```yaml
224
+ # Static configuration, manual setup
225
+ - name: check_api
226
+ command: curl -f https://k8s-api/healthz
227
+ interval: 5m
228
+
229
+ - name: check_llm
230
+ command: curl -f https://llm-endpoint/health
231
+ interval: 5m
232
+ ```
233
+
234
+ ### Language Operator Approach (Organic Functions)
235
+ ```ruby
236
+ # Natural language → comprehensive monitoring
237
+ "Check if the system is healthy every 5 minutes and report any issues"
238
+
239
+ # Synthesizes intelligent monitoring that:
240
+ # - Adapts to infrastructure changes
241
+ # - Learns optimal check patterns
242
+ # - Provides contextual analysis
243
+ # - Integrates with existing observability
244
+ ```
245
+
246
+ ## Files Generated
247
+
248
+ | File | Purpose |
249
+ |------|---------|
250
+ | `instructions.txt` | Single-sentence natural language instruction |
251
+ | `agent.synthesized.rb` | Initial neural health monitoring agent |
252
+ | `Makefile` | Synthesis and execution commands |
253
+ | `output.log` | Health check execution logs |
254
+
255
+ ## Synthesis Commands
256
+
257
+ ```bash
258
+ # Create and deploy health monitoring agent
259
+ make create
260
+
261
+ # Monitor health check execution
262
+ make logs
263
+
264
+ # Check for Task Completion events
265
+ make events
266
+
267
+ # Validate observability infrastructure
268
+ make validate
269
+ ```
270
+
271
+ ## Expected Impact
272
+
273
+ This test validates that Language Operator can synthesize production-ready monitoring infrastructure from a simple natural language instruction, while ensuring the observability systems required for operational visibility are functioning correctly.
274
+
275
+ The zen aspect: A simple request for health monitoring becomes a comprehensive validation of the entire system's ability to observe itself.
276
+
277
+ ## Related Tests
278
+
279
+ - [001 - Minimal Synthesis](../001/README.md) - Basic synthesis validation
280
+ - [002 - Neural Execution](../002/README.md) - Neural task execution + scheduling
281
+ - [003 - Progressive Learning](../003/README.md) - Learning and optimization
@@ -0,0 +1 @@
1
+ Check if the system is healthy every 5 minutes and report any issues