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.
- checksums.yaml +4 -4
- data/.plan.md +127 -0
- data/.rspec +3 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +4 -1
- data/Makefile +34 -80
- data/components/agent/Gemfile +1 -1
- data/docs/cheat-sheet.md +173 -0
- data/lib/language_operator/agent/base.rb +10 -1
- data/lib/language_operator/agent/event_config.rb +172 -0
- data/lib/language_operator/agent/safety/ast_validator.rb +1 -1
- data/lib/language_operator/agent/safety/safe_executor.rb +5 -1
- data/lib/language_operator/agent/task_executor.rb +87 -7
- data/lib/language_operator/agent/telemetry.rb +25 -3
- data/lib/language_operator/agent/web_server.rb +6 -9
- data/lib/language_operator/cli/commands/agent/base.rb +15 -17
- data/lib/language_operator/cli/commands/agent/learning.rb +156 -37
- data/lib/language_operator/cli/commands/cluster.rb +2 -2
- data/lib/language_operator/cli/commands/status.rb +2 -2
- data/lib/language_operator/cli/commands/system/synthesize.rb +1 -1
- data/lib/language_operator/cli/formatters/value_formatter.rb +1 -1
- data/lib/language_operator/cli/helpers/ux_helper.rb +3 -4
- data/lib/language_operator/config.rb +3 -3
- data/lib/language_operator/constants/kubernetes_labels.rb +2 -2
- data/lib/language_operator/dsl/task_definition.rb +18 -7
- data/lib/language_operator/instrumentation/task_tracer.rb +44 -3
- data/lib/language_operator/kubernetes/client.rb +111 -0
- data/lib/language_operator/templates/schema/CHANGELOG.md +28 -0
- data/lib/language_operator/templates/schema/agent_dsl_openapi.yaml +1 -1
- data/lib/language_operator/templates/schema/agent_dsl_schema.json +1 -1
- data/lib/language_operator/type_coercion.rb +22 -8
- data/lib/language_operator/version.rb +1 -1
- data/synth/002/agent.rb +23 -12
- data/synth/002/output.log +88 -15
- data/synth/003/Makefile +5 -2
- data/synth/004/Makefile +54 -0
- data/synth/004/README.md +281 -0
- data/synth/004/instructions.txt +1 -0
- 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**
|
|
@@ -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.
|
|
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
|
-
#
|
|
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',
|
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
|
|
6
|
-
description
|
|
3
|
+
agent "s002" do
|
|
4
|
+
description "Tell me a fortune every 10 minutes"
|
|
5
|
+
|
|
7
6
|
mode :scheduled
|
|
8
|
-
schedule
|
|
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 :
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
16
|
-
|
|
25
|
+
constraints do
|
|
26
|
+
max_iterations 999999
|
|
27
|
+
timeout "10m"
|
|
17
28
|
end
|
|
18
29
|
|
|
19
30
|
output do |outputs|
|
|
20
|
-
puts outputs[:
|
|
31
|
+
puts outputs[:message]
|
|
21
32
|
end
|
|
22
33
|
end
|
data/synth/002/output.log
CHANGED
|
@@ -1,21 +1,94 @@
|
|
|
1
|
+
[36m⚬[0m [2mStreaming logs for agent 's002'...[0m
|
|
2
|
+
|
|
3
|
+
[1;36m⚬[0m Language Operator v0.1.61
|
|
1
4
|
[1;36m⚬[0m OpenTelemetry disabled
|
|
2
|
-
[1;36m⚬[0m Configuring LLM (provider=openai_compatible, model=
|
|
5
|
+
[1;36m⚬[0m Configuring LLM (provider=openai_compatible, model=qwen3-coder:30b, timeout=300)
|
|
3
6
|
[1;36m⚬[0m LLM configuration complete
|
|
4
7
|
[1;36m⚬[0m No MCP servers configured, agent will run without tools
|
|
5
|
-
[1;36m⚬[0m Chat session initialized (with_tools=false)
|
|
6
|
-
[1;36m⚬[0m
|
|
8
|
+
[1;36m⚬[0m Chat session initialized (with_tools=false, total_tools=0)
|
|
9
|
+
[1;36m⚬[0m Agent running in scheduled mode - executing once (agent_name=s002, dsl_version=v1)
|
|
10
|
+
[1;36m⚬[0m Executing main block (agent=s002, task_count=2)
|
|
7
11
|
[1;36m⚬[0m Executing main block (inputs_keys=[])
|
|
8
|
-
[1;36m⚬[0m
|
|
9
|
-
[1;36m⚬[0m
|
|
10
|
-
[1;36m⚬[0m
|
|
11
|
-
[1;36m⚬[0m
|
|
12
|
-
[1;36m⚬[0m
|
|
13
|
-
|
|
14
|
-
[1;36m⚬[0m
|
|
15
|
-
[1;36m⚬[0m
|
|
12
|
+
[1;36m⚬[0m Sending prompt to LLM (task=generate_fortune, prompt_length=632, available_tools=[])
|
|
13
|
+
[1;36m⚬[0m LLM response received, extracting content (task=generate_fortune, response_class=RubyLLM::Message, has_tool_calls=, tool_call_count=0)
|
|
14
|
+
[1;36m⚬[0m Neural task response received (task=generate_fortune, response_length=563)
|
|
15
|
+
[1;36m⚬[0m Parsing neural task response (task=generate_fortune)
|
|
16
|
+
[1;36m⚬[0m 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
|
+
[1;36m⚬[0m Response parsed successfully (task=generate_fortune, output_keys=[:fortune])
|
|
19
|
+
[1;36m⚬[0m Validating task outputs (task=generate_fortune)
|
|
20
|
+
[1;36m⚬[0m Sending prompt to LLM (task=format_output, prompt_length=918, available_tools=[])
|
|
21
|
+
[1;36m⚬[0m LLM response received, extracting content (task=format_output, response_class=RubyLLM::Message, has_tool_calls=, tool_call_count=0)
|
|
22
|
+
[1;36m⚬[0m Neural task response received (task=format_output, response_length=583)
|
|
23
|
+
[1;36m⚬[0m Parsing neural task response (task=format_output)
|
|
24
|
+
[1;36m⚬[0m 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
|
+
[1;36m⚬[0m Response parsed successfully (task=format_output, output_keys=[:message])
|
|
27
|
+
[1;36m⚬[0m Validating task outputs (task=format_output)
|
|
28
|
+
[1;36m⚬[0m Main execution (13.01s)
|
|
16
29
|
[1;36m⚬[0m Main block completed
|
|
17
|
-
[1;36m⚬[0m Main block execution completed (result={
|
|
18
|
-
Your
|
|
19
|
-
[
|
|
20
|
-
|
|
30
|
+
[1;36m⚬[0m 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
|
+
[1;36m⚬[0m Scheduled execution completed - exiting (agent_name=s002)
|
|
33
|
+
[1;36m⚬[0m Language Operator v0.1.61
|
|
34
|
+
[1;36m⚬[0m OpenTelemetry disabled
|
|
35
|
+
[1;36m⚬[0m Configuring LLM (provider=openai_compatible, model=qwen3-coder:30b, timeout=300)
|
|
36
|
+
[1;36m⚬[0m LLM configuration complete
|
|
37
|
+
[1;36m⚬[0m No MCP servers configured, agent will run without tools
|
|
38
|
+
[1;36m⚬[0m Chat session initialized (with_tools=false, total_tools=0)
|
|
39
|
+
[1;36m⚬[0m Agent running in scheduled mode - executing once (agent_name=s002, dsl_version=v1)
|
|
40
|
+
[1;36m⚬[0m Executing main block (agent=s002, task_count=2)
|
|
41
|
+
[1;36m⚬[0m Executing main block (inputs_keys=[])
|
|
42
|
+
[1;36m⚬[0m Sending prompt to LLM (task=generate_fortune, prompt_length=632, available_tools=[])
|
|
43
|
+
[1;36m⚬[0m LLM response received, extracting content (task=generate_fortune, response_class=RubyLLM::Message, has_tool_calls=, tool_call_count=0)
|
|
44
|
+
[1;36m⚬[0m Neural task response received (task=generate_fortune, response_length=707)
|
|
45
|
+
[1;36m⚬[0m Parsing neural task response (task=generate_fortune)
|
|
46
|
+
[1;36m⚬[0m 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
|
+
[1;36m⚬[0m Response parsed successfully (task=generate_fortune, output_keys=[:fortune])
|
|
49
|
+
[1;36m⚬[0m Validating task outputs (task=generate_fortune)
|
|
50
|
+
[1;36m⚬[0m Sending prompt to LLM (task=format_output, prompt_length=893, available_tools=[])
|
|
51
|
+
[1;36m⚬[0m LLM response received, extracting content (task=format_output, response_class=RubyLLM::Message, has_tool_calls=, tool_call_count=0)
|
|
52
|
+
[1;36m⚬[0m Neural task response received (task=format_output, response_length=745)
|
|
53
|
+
[1;36m⚬[0m Parsing neural task response (task=format_output)
|
|
54
|
+
[1;36m⚬[0m 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
|
+
[1;36m⚬[0m Response parsed successfully (task=format_output, output_keys=[:message])
|
|
57
|
+
[1;36m⚬[0m Validating task outputs (task=format_output)
|
|
58
|
+
[1;36m⚬[0m Main execution (12.698s)
|
|
59
|
+
[1;36m⚬[0m Main block completed
|
|
60
|
+
[1;36m⚬[0m 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
|
+
[1;36m⚬[0m Scheduled execution completed - exiting (agent_name=s002)
|
|
65
|
+
[1;36m⚬[0m Language Operator v0.1.61
|
|
66
|
+
[1;36m⚬[0m OpenTelemetry disabled
|
|
67
|
+
[1;36m⚬[0m Configuring LLM (provider=openai_compatible, model=qwen3-coder:30b, timeout=300)
|
|
68
|
+
[1;36m⚬[0m LLM configuration complete
|
|
69
|
+
[1;36m⚬[0m No MCP servers configured, agent will run without tools
|
|
70
|
+
[1;36m⚬[0m Chat session initialized (with_tools=false, total_tools=0)
|
|
71
|
+
[1;36m⚬[0m Agent running in scheduled mode - executing once (agent_name=s002, dsl_version=v1)
|
|
72
|
+
[1;36m⚬[0m Executing main block (agent=s002, task_count=2)
|
|
73
|
+
[1;36m⚬[0m Executing main block (inputs_keys=[])
|
|
74
|
+
[1;36m⚬[0m Sending prompt to LLM (task=generate_fortune, prompt_length=632, available_tools=[])
|
|
75
|
+
[1;36m⚬[0m LLM response received, extracting content (task=generate_fortune, response_class=RubyLLM::Message, has_tool_calls=, tool_call_count=0)
|
|
76
|
+
[1;36m⚬[0m Neural task response received (task=generate_fortune, response_length=591)
|
|
77
|
+
[1;36m⚬[0m Parsing neural task response (task=generate_fortune)
|
|
78
|
+
[1;36m⚬[0m 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
|
+
[1;36m⚬[0m Response parsed successfully (task=generate_fortune, output_keys=[:fortune])
|
|
81
|
+
[1;36m⚬[0m Validating task outputs (task=generate_fortune)
|
|
82
|
+
[1;36m⚬[0m Sending prompt to LLM (task=format_output, prompt_length=877, available_tools=[])
|
|
83
|
+
[1;36m⚬[0m LLM response received, extracting content (task=format_output, response_class=RubyLLM::Message, has_tool_calls=, tool_call_count=0)
|
|
84
|
+
[1;36m⚬[0m Neural task response received (task=format_output, response_length=491)
|
|
85
|
+
[1;36m⚬[0m Parsing neural task response (task=format_output)
|
|
86
|
+
[1;36m⚬[0m 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
|
+
[1;36m⚬[0m Response parsed successfully (task=format_output, output_keys=[:message])
|
|
89
|
+
[1;36m⚬[0m Validating task outputs (task=format_output)
|
|
90
|
+
[1;36m⚬[0m Main execution (12.256s)
|
|
91
|
+
[1;36m⚬[0m Main block completed
|
|
92
|
+
[1;36m⚬[0m 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
|
+
[1;36m⚬[0m 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
|
-
|
|
21
|
-
|
|
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)
|
data/synth/004/Makefile
ADDED
|
@@ -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
|
data/synth/004/README.md
ADDED
|
@@ -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
|