language-operator 0.1.46 → 0.1.47
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/.claude/commands/task.md +10 -0
- data/Gemfile.lock +1 -1
- data/components/agent/.rubocop.yml +1 -0
- data/components/agent/Dockerfile +43 -0
- data/components/agent/Dockerfile.dev +38 -0
- data/components/agent/Gemfile +15 -0
- data/components/agent/Makefile +67 -0
- data/components/agent/bin/langop-agent +140 -0
- data/components/agent/config/config.yaml +47 -0
- data/components/base/Dockerfile +34 -0
- data/components/base/Makefile +42 -0
- data/components/base/entrypoint.sh +12 -0
- data/components/base/gem-credentials +2 -0
- data/components/tool/.gitignore +10 -0
- data/components/tool/.rubocop.yml +19 -0
- data/components/tool/.yardopts +7 -0
- data/components/tool/Dockerfile +44 -0
- data/components/tool/Dockerfile.dev +39 -0
- data/components/tool/Gemfile +18 -0
- data/components/tool/Makefile +77 -0
- data/components/tool/README.md +145 -0
- data/components/tool/config.ru +4 -0
- data/components/tool/examples/calculator.rb +63 -0
- data/components/tool/examples/example_tool.rb +190 -0
- data/components/tool/lib/langop/dsl.rb +20 -0
- data/components/tool/server.rb +7 -0
- data/lib/language_operator/agent/task_executor.rb +39 -7
- data/lib/language_operator/cli/commands/agent.rb +0 -3
- data/lib/language_operator/cli/commands/system.rb +1 -0
- data/lib/language_operator/cli/formatters/log_formatter.rb +19 -67
- data/lib/language_operator/cli/formatters/log_style.rb +151 -0
- data/lib/language_operator/cli/formatters/progress_formatter.rb +10 -6
- data/lib/language_operator/logger.rb +3 -8
- data/lib/language_operator/templates/agent_synthesis.tmpl +35 -28
- 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/version.rb +1 -1
- data/synth/001/README.md +72 -0
- data/synth/001/output.log +13 -13
- data/synth/002/Makefile +12 -0
- data/synth/002/README.md +287 -0
- data/synth/002/agent.rb +23 -0
- data/synth/002/agent.txt +1 -0
- data/synth/002/output.log +22 -0
- metadata +33 -3
- data/synth/Makefile +0 -39
- data/synth/README.md +0 -342
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative '../helpers/pastel_helper'
|
|
4
|
+
require_relative 'log_style'
|
|
4
5
|
require 'json'
|
|
5
6
|
require 'time'
|
|
6
7
|
|
|
@@ -108,12 +109,12 @@ module LanguageOperator
|
|
|
108
109
|
emoji_or_text = Regexp.last_match(1)
|
|
109
110
|
rest = Regexp.last_match(2)
|
|
110
111
|
|
|
111
|
-
# Check if first part is an emoji (common log emojis -
|
|
112
|
+
# Check if first part is an emoji (common log emojis - LogStyle standard)
|
|
112
113
|
if emoji_or_text =~ /[☰☢⚠✗✔✅]/
|
|
113
|
-
|
|
114
|
+
level_sym = LogStyle.emoji_to_level(emoji_or_text)
|
|
114
115
|
# Message already has emoji, just format rest without adding another icon
|
|
115
116
|
message_text, metadata = extract_metadata(rest)
|
|
116
|
-
color =
|
|
117
|
+
color = LogStyle.color(level_sym)
|
|
117
118
|
formatted = pastel.send(color, "#{emoji_or_text} #{message_text}")
|
|
118
119
|
formatted += " #{format_metadata(metadata)}" if metadata
|
|
119
120
|
formatted
|
|
@@ -163,38 +164,21 @@ module LanguageOperator
|
|
|
163
164
|
|
|
164
165
|
# Determine icon and color based on message content
|
|
165
166
|
def determine_icon_and_color(message, level)
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
when /error|fail|✗|❌/i
|
|
182
|
-
['✗', :red]
|
|
183
|
-
when /warn|⚠/i
|
|
184
|
-
['⚠', :yellow]
|
|
185
|
-
else
|
|
186
|
-
# Default based on level
|
|
187
|
-
case level&.upcase
|
|
188
|
-
when 'ERROR'
|
|
189
|
-
['✗', :red]
|
|
190
|
-
when 'WARN'
|
|
191
|
-
['⚠', :yellow]
|
|
192
|
-
when 'DEBUG'
|
|
193
|
-
['☢', :dim]
|
|
194
|
-
else
|
|
195
|
-
['☰', :white]
|
|
196
|
-
end
|
|
197
|
-
end
|
|
167
|
+
# Detect level from message content
|
|
168
|
+
detected_level = LogStyle.detect_level_from_message(message)
|
|
169
|
+
|
|
170
|
+
# Use detected level unless explicitly overridden
|
|
171
|
+
level_sym = if detected_level == :info
|
|
172
|
+
level&.downcase&.to_sym || :info
|
|
173
|
+
else
|
|
174
|
+
detected_level
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Get icon and color from LogStyle
|
|
178
|
+
icon = LogStyle.icon(level_sym)
|
|
179
|
+
color = LogStyle.color(level_sym)
|
|
180
|
+
|
|
181
|
+
[icon, color]
|
|
198
182
|
end
|
|
199
183
|
|
|
200
184
|
# Format metadata hash
|
|
@@ -245,38 +229,6 @@ module LanguageOperator
|
|
|
245
229
|
def format_time(time)
|
|
246
230
|
pastel.dim(time.strftime('%H:%M:%S'))
|
|
247
231
|
end
|
|
248
|
-
|
|
249
|
-
# Convert emoji to log level
|
|
250
|
-
def emoji_to_level(emoji)
|
|
251
|
-
case emoji
|
|
252
|
-
when 'ℹ️', 'ℹ', '☰'
|
|
253
|
-
'INFO'
|
|
254
|
-
when '🔍', '☢'
|
|
255
|
-
'DEBUG'
|
|
256
|
-
when '⚠️', '⚠'
|
|
257
|
-
'WARN'
|
|
258
|
-
when '❌', '✗'
|
|
259
|
-
'ERROR'
|
|
260
|
-
when '✓', '✔', '✅'
|
|
261
|
-
'INFO'
|
|
262
|
-
else
|
|
263
|
-
'INFO'
|
|
264
|
-
end
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
# Determine color from log level
|
|
268
|
-
def determine_color_from_level(level)
|
|
269
|
-
case level&.upcase
|
|
270
|
-
when 'ERROR'
|
|
271
|
-
:red
|
|
272
|
-
when 'WARN'
|
|
273
|
-
:yellow
|
|
274
|
-
when 'DEBUG'
|
|
275
|
-
:dim
|
|
276
|
-
else
|
|
277
|
-
:white
|
|
278
|
-
end
|
|
279
|
-
end
|
|
280
232
|
end
|
|
281
233
|
end
|
|
282
234
|
end
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LanguageOperator
|
|
4
|
+
module CLI
|
|
5
|
+
module Formatters
|
|
6
|
+
# Centralized configuration for log level icons and colors
|
|
7
|
+
#
|
|
8
|
+
# Single source of truth for all logging/notification output across the codebase.
|
|
9
|
+
# This ensures consistent styling and makes it easy to customize icons and colors
|
|
10
|
+
# for all log levels in one place.
|
|
11
|
+
#
|
|
12
|
+
# @example Using LogStyle with Pastel
|
|
13
|
+
# pastel = Pastel.new
|
|
14
|
+
# puts LogStyle.format(:success, "Operation completed", pastel)
|
|
15
|
+
# # => "\e[32m✔ Operation completed\e[0m"
|
|
16
|
+
#
|
|
17
|
+
# @example Getting icon and color separately
|
|
18
|
+
# icon = LogStyle.icon(:error) # => "✗"
|
|
19
|
+
# color = LogStyle.color(:error) # => :red
|
|
20
|
+
#
|
|
21
|
+
class LogStyle
|
|
22
|
+
# Style configuration for each log level
|
|
23
|
+
# @return [Hash] Mapping of log levels to icon and color
|
|
24
|
+
STYLES = {
|
|
25
|
+
debug: { icon: '☢', color: :dim },
|
|
26
|
+
info: { icon: '⚬', color: :cyan },
|
|
27
|
+
success: { icon: '✔', color: :green },
|
|
28
|
+
warn: { icon: '⚠', color: :yellow },
|
|
29
|
+
error: { icon: '✗', color: :red }
|
|
30
|
+
}.freeze
|
|
31
|
+
|
|
32
|
+
class << self
|
|
33
|
+
# Format a message with icon and color for the given log level
|
|
34
|
+
#
|
|
35
|
+
# @param level [Symbol] Log level (:debug, :info, :success, :warn, :error)
|
|
36
|
+
# @param message [String] Message to format
|
|
37
|
+
# @param pastel [Pastel] Pastel instance for applying colors
|
|
38
|
+
# @return [String] Formatted message with icon and color
|
|
39
|
+
def format(level, message, pastel)
|
|
40
|
+
style = STYLES[level] || STYLES[:info]
|
|
41
|
+
icon = style[:icon]
|
|
42
|
+
color = style[:color]
|
|
43
|
+
|
|
44
|
+
pastel.send(color, "#{icon} #{message}")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Get the icon for a log level
|
|
48
|
+
#
|
|
49
|
+
# @param level [Symbol] Log level
|
|
50
|
+
# @return [String] Icon character
|
|
51
|
+
def icon(level)
|
|
52
|
+
STYLES.dig(level, :icon) || STYLES[:info][:icon]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Get the color for a log level
|
|
56
|
+
#
|
|
57
|
+
# @param level [Symbol] Log level
|
|
58
|
+
# @return [Symbol] Color name (e.g., :red, :green)
|
|
59
|
+
def color(level)
|
|
60
|
+
STYLES.dig(level, :color) || STYLES[:info][:color]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Get a styled icon with ANSI color codes embedded
|
|
64
|
+
#
|
|
65
|
+
# @param level [Symbol] Log level
|
|
66
|
+
# @param pastel [Pastel] Pastel instance for applying colors
|
|
67
|
+
# @return [String] Colored icon with ANSI escape codes
|
|
68
|
+
def styled_icon(level, pastel)
|
|
69
|
+
style = STYLES[level] || STYLES[:info]
|
|
70
|
+
pastel.send(style[:color], style[:icon])
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Detect log level from message content
|
|
74
|
+
#
|
|
75
|
+
# Useful for inferring log level from message text when not explicitly provided.
|
|
76
|
+
#
|
|
77
|
+
# @param message [String] Message text to analyze
|
|
78
|
+
# @return [Symbol] Detected log level
|
|
79
|
+
def detect_level_from_message(message)
|
|
80
|
+
case message
|
|
81
|
+
when /error|fail|✗|❌/i
|
|
82
|
+
:error
|
|
83
|
+
when /warn|⚠/i
|
|
84
|
+
:warn
|
|
85
|
+
when /completed|finished|success|✔|✅/i
|
|
86
|
+
:success
|
|
87
|
+
when /debug|☢/i
|
|
88
|
+
:debug
|
|
89
|
+
else
|
|
90
|
+
:info
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Convert emoji to log level symbol
|
|
95
|
+
#
|
|
96
|
+
# @param emoji [String] Emoji character
|
|
97
|
+
# @return [Symbol] Log level symbol
|
|
98
|
+
def emoji_to_level(emoji)
|
|
99
|
+
case emoji
|
|
100
|
+
when /[☰ℹ]/
|
|
101
|
+
:info
|
|
102
|
+
when /[☢🔍]/
|
|
103
|
+
:debug
|
|
104
|
+
when /⚠/
|
|
105
|
+
:warn
|
|
106
|
+
when /[✗❌]/
|
|
107
|
+
:error
|
|
108
|
+
when /[✔✅]/
|
|
109
|
+
:success
|
|
110
|
+
else
|
|
111
|
+
:info
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Get ANSI color code for a level (for Logger compatibility)
|
|
116
|
+
#
|
|
117
|
+
# @param level [Symbol, String] Log level
|
|
118
|
+
# @return [String] ANSI escape code with icon and color
|
|
119
|
+
def ansi_icon(level)
|
|
120
|
+
level_sym = level.to_s.downcase.to_sym
|
|
121
|
+
style = STYLES[level_sym] || STYLES[:info]
|
|
122
|
+
icon = style[:icon]
|
|
123
|
+
color_code = ansi_color_code(style[:color])
|
|
124
|
+
|
|
125
|
+
"#{color_code}#{icon}\e[0m"
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
private
|
|
129
|
+
|
|
130
|
+
# Get ANSI color code for a color name
|
|
131
|
+
def ansi_color_code(color)
|
|
132
|
+
case color
|
|
133
|
+
when :dim
|
|
134
|
+
"\e[1;90m"
|
|
135
|
+
when :cyan
|
|
136
|
+
"\e[1;36m"
|
|
137
|
+
when :green
|
|
138
|
+
"\e[1;32m"
|
|
139
|
+
when :yellow
|
|
140
|
+
"\e[1;33m"
|
|
141
|
+
when :red
|
|
142
|
+
"\e[1;31m"
|
|
143
|
+
else
|
|
144
|
+
"\e[0m"
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'tty-spinner'
|
|
4
4
|
require_relative '../helpers/pastel_helper'
|
|
5
|
+
require_relative 'log_style'
|
|
5
6
|
|
|
6
7
|
module LanguageOperator
|
|
7
8
|
module CLI
|
|
@@ -12,7 +13,8 @@ module LanguageOperator
|
|
|
12
13
|
include Helpers::PastelHelper
|
|
13
14
|
|
|
14
15
|
def with_spinner(message, success_msg: nil, &block)
|
|
15
|
-
|
|
16
|
+
success_icon = LogStyle.styled_icon(:success, pastel)
|
|
17
|
+
spinner = TTY::Spinner.new(":spinner #{message}...", format: :dots, success_mark: success_icon)
|
|
16
18
|
spinner.auto_spin
|
|
17
19
|
|
|
18
20
|
result = block.call
|
|
@@ -28,23 +30,25 @@ module LanguageOperator
|
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
def success(message)
|
|
31
|
-
puts
|
|
33
|
+
puts LogStyle.format(:success, message, pastel)
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
def error(message)
|
|
35
|
-
puts
|
|
37
|
+
puts LogStyle.format(:error, message, pastel)
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
def info(message)
|
|
39
|
-
|
|
41
|
+
icon = LogStyle.styled_icon(:info, pastel)
|
|
42
|
+
puts "#{icon} #{pastel.dim(message)}"
|
|
40
43
|
end
|
|
41
44
|
|
|
42
45
|
def debug(message)
|
|
43
|
-
|
|
46
|
+
icon = LogStyle.styled_icon(:debug, pastel)
|
|
47
|
+
puts "#{icon} #{pastel.dim(message)}"
|
|
44
48
|
end
|
|
45
49
|
|
|
46
50
|
def warn(message)
|
|
47
|
-
puts "#{pastel.yellow.bold(
|
|
51
|
+
puts "#{pastel.yellow.bold(LogStyle.icon(:warn))} #{message}"
|
|
48
52
|
end
|
|
49
53
|
end
|
|
50
54
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'logger'
|
|
4
|
+
require_relative 'cli/formatters/log_style'
|
|
4
5
|
|
|
5
6
|
module LanguageOperator
|
|
6
7
|
# Structured logger with configurable output formats and levels
|
|
@@ -22,13 +23,6 @@ module LanguageOperator
|
|
|
22
23
|
'ERROR' => ::Logger::ERROR
|
|
23
24
|
}.freeze
|
|
24
25
|
|
|
25
|
-
LEVEL_EMOJI = {
|
|
26
|
-
'DEBUG' => "\e[1;90m☢\e[0m", # Bold gray radioactive symbol
|
|
27
|
-
'INFO' => "\e[1;36m☰\e[0m", # Bold cyan trigram
|
|
28
|
-
'WARN' => "\e[1;33m⚠\e[0m", # Bold yellow warning
|
|
29
|
-
'ERROR' => "\e[1;31m✗\e[0m" # Bold red cross
|
|
30
|
-
}.freeze
|
|
31
|
-
|
|
32
26
|
attr_reader :logger, :format, :show_timing
|
|
33
27
|
|
|
34
28
|
def initialize(component: 'Langop', format: nil, level: nil)
|
|
@@ -115,7 +109,8 @@ module LanguageOperator
|
|
|
115
109
|
end
|
|
116
110
|
|
|
117
111
|
def format_pretty(severity, message, **metadata)
|
|
118
|
-
|
|
112
|
+
level_sym = severity.to_s.downcase.to_sym
|
|
113
|
+
emoji = CLI::Formatters::LogStyle.ansi_icon(level_sym)
|
|
119
114
|
parts = [emoji, message]
|
|
120
115
|
|
|
121
116
|
metadata_str = format_metadata(**metadata)
|
|
@@ -177,44 +177,42 @@ end
|
|
|
177
177
|
|
|
178
178
|
## Your Task: Generate DSL v1 Agent
|
|
179
179
|
|
|
180
|
-
Using the
|
|
180
|
+
Using the THREE CONCRETE EXAMPLES above (daily-report, code-reviewer, data-pipeline) as reference patterns, generate WORKING Ruby DSL code for the agent described in the user instructions.
|
|
181
181
|
|
|
182
|
-
|
|
182
|
+
**CRITICAL REQUIREMENTS:**
|
|
183
|
+
- DO NOT output placeholder text like "Brief description extracted from instructions" or "CRON_EXPRESSION"
|
|
184
|
+
- DO NOT output generic names like `:task_name` or `param_name`
|
|
185
|
+
- DO NOT copy the template structure below - USE THE WORKING EXAMPLES ABOVE
|
|
186
|
+
- Generate ACTUAL, FUNCTIONAL code that implements the user's request
|
|
187
|
+
- Use SPECIFIC task names, descriptions, and logic based on the user instructions
|
|
188
|
+
|
|
189
|
+
The code structure should follow this pattern (with ACTUAL content, not placeholders):
|
|
190
|
+
|
|
191
|
+
```
|
|
183
192
|
require 'language_operator'
|
|
184
193
|
|
|
185
194
|
agent "{{.AgentName}}" do
|
|
186
|
-
description "
|
|
195
|
+
description "<ACTUAL description based on user instructions>"
|
|
187
196
|
{{.PersonaSection}}{{.ScheduleSection}}
|
|
188
|
-
#
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
inputs: { param_name: 'type' },
|
|
197
|
-
outputs: { result_name: 'type' }
|
|
198
|
-
|
|
199
|
-
# For symbolic tasks (when logic is simple/deterministic), use code blocks:
|
|
200
|
-
# task :task_name do |inputs|
|
|
201
|
-
# { result: inputs[:param] * 2 }
|
|
202
|
-
# end
|
|
203
|
-
|
|
204
|
-
# REQUIRED: main block defines execution flow
|
|
197
|
+
# Define specific tasks needed for this agent
|
|
198
|
+
task :<ACTUAL_task_name>,
|
|
199
|
+
instructions: "<ACTUAL description of what this specific task does>",
|
|
200
|
+
inputs: { <actual_param>: '<actual_type>' },
|
|
201
|
+
outputs: { <actual_result>: '<actual_type>' }
|
|
202
|
+
|
|
203
|
+
# Add more tasks as needed based on user instructions
|
|
204
|
+
|
|
205
205
|
main do |inputs|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
result2 # Return final result
|
|
206
|
+
# ACTUAL execution flow implementing the user's request
|
|
207
|
+
result = execute_task(:<ACTUAL_task_name>, inputs: { <actual_param>: <actual_value> })
|
|
208
|
+
result
|
|
210
209
|
end
|
|
211
210
|
|
|
212
211
|
{{.ConstraintsSection}}
|
|
213
212
|
|
|
214
|
-
# Output handling
|
|
215
213
|
output do |outputs|
|
|
216
|
-
#
|
|
217
|
-
puts
|
|
214
|
+
# ACTUAL output handling for this specific agent
|
|
215
|
+
puts outputs.inspect
|
|
218
216
|
end
|
|
219
217
|
end
|
|
220
218
|
```
|
|
@@ -231,7 +229,7 @@ end
|
|
|
231
229
|
**Rules:**
|
|
232
230
|
1. Generate ONLY the Ruby code within triple-backticks, no explanations before or after
|
|
233
231
|
{{.ScheduleRules}}
|
|
234
|
-
3. Break down instructions into
|
|
232
|
+
3. Break down the user's instructions into SPECIFIC tasks with type-safe contracts
|
|
235
233
|
4. REQUIRED: Always include a `main` block that calls tasks via `execute_task()`
|
|
236
234
|
5. For simple deterministic tasks, use symbolic code blocks (do |inputs| ... end)
|
|
237
235
|
6. For complex/creative tasks, use neural tasks with instructions
|
|
@@ -240,4 +238,13 @@ end
|
|
|
240
238
|
9. Type schemas are REQUIRED for all tasks (inputs/outputs hashes)
|
|
241
239
|
10. Use the agent name: "{{.AgentName}}"
|
|
242
240
|
|
|
241
|
+
**CRITICAL - VERIFY BEFORE OUTPUTTING:**
|
|
242
|
+
- ✓ Did you read and understand the USER INSTRUCTIONS above?
|
|
243
|
+
- ✓ Does your code IMPLEMENT those specific instructions?
|
|
244
|
+
- ✓ Are all task names, descriptions, and logic SPECIFIC to the user's request?
|
|
245
|
+
- ✓ Did you AVOID outputting placeholders like "task_name" or "CRON_EXPRESSION"?
|
|
246
|
+
- ✓ Does the code actually DO what the user asked for?
|
|
247
|
+
|
|
248
|
+
If you cannot answer YES to all of the above, re-read the user instructions and generate FUNCTIONAL code.
|
|
249
|
+
|
|
243
250
|
Generate the code now:
|
|
@@ -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.47",
|
|
7
7
|
"type": "object",
|
|
8
8
|
"properties": {
|
|
9
9
|
"name": {
|
data/synth/001/README.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# 001 - Minimal Viable Synthesis
|
|
2
|
+
|
|
3
|
+
## Instructions
|
|
4
|
+
|
|
5
|
+
"Say something in your logs"
|
|
6
|
+
|
|
7
|
+
## Significance
|
|
8
|
+
|
|
9
|
+
This is the **foundational validation** of the DSL v1 architecture. It proves that the entire synthesis pipeline works end-to-end with the simplest possible agent.
|
|
10
|
+
|
|
11
|
+
Think of this as the "Hello World" of organic function synthesis - before we can validate learning, progressive synthesis, or neural task execution, we must first prove we can synthesize and execute *anything at all*.
|
|
12
|
+
|
|
13
|
+
## What This Demonstrates
|
|
14
|
+
|
|
15
|
+
### 1. Basic Synthesis Flow Works
|
|
16
|
+
- **Natural language → Agent code generation** - The synthesis template can produce valid Ruby DSL
|
|
17
|
+
- **Go operator synthesis** - The operator's synthesis controller generates executable code
|
|
18
|
+
- **ConfigMap storage** - Synthesized code is stored and mounted correctly
|
|
19
|
+
|
|
20
|
+
### 2. DSL v1 Core Primitives
|
|
21
|
+
- **`task` definition** - Symbolic task with explicit implementation block
|
|
22
|
+
- **`main` block** - Explicit entry point with imperative control flow
|
|
23
|
+
- **`execute_task`** - Task invocation mechanism works
|
|
24
|
+
- **`output` block** - Result handling and processing
|
|
25
|
+
|
|
26
|
+
### 3. Ruby Runtime Execution
|
|
27
|
+
- **DSL parsing** - Ruby gem can load and parse synthesized agents
|
|
28
|
+
- **Task execution** - `TaskExecutor` can execute symbolic tasks
|
|
29
|
+
- **Agent lifecycle** - Agent runs to completion successfully
|
|
30
|
+
|
|
31
|
+
### 4. Symbolic Task Execution
|
|
32
|
+
```ruby
|
|
33
|
+
task :generate_log_message do |_inputs|
|
|
34
|
+
{ message: 'Test agent is saying hello!' }
|
|
35
|
+
end
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
This is a **symbolic organic function** - explicit code implementation with a stable contract:
|
|
39
|
+
- **Contract**: `outputs: { message: 'string' }`
|
|
40
|
+
- **Implementation**: Returns hard-coded message
|
|
41
|
+
- **Caller**: `main` block calls via `execute_task(:generate_log_message)`
|
|
42
|
+
|
|
43
|
+
## Why This Matters
|
|
44
|
+
|
|
45
|
+
### Validates the Foundation
|
|
46
|
+
Before building complex features (learning, neural execution, re-synthesis), we must prove the basic pipeline works:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
User Instruction
|
|
50
|
+
↓
|
|
51
|
+
Synthesis (Go operator)
|
|
52
|
+
↓
|
|
53
|
+
ConfigMap (agent.rb)
|
|
54
|
+
↓
|
|
55
|
+
Ruby Runtime Execution
|
|
56
|
+
↓
|
|
57
|
+
Output
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Establishes DSL v1 Baseline
|
|
61
|
+
This test uses the **new DSL v1 model** (task/main) rather than the old workflow/step model. It proves:
|
|
62
|
+
- ✅ `task` replaces `step`
|
|
63
|
+
- ✅ `main` replaces implicit `workflow`
|
|
64
|
+
- ✅ Imperative control flow works
|
|
65
|
+
- ✅ Organic function abstraction is viable
|
|
66
|
+
|
|
67
|
+
### No Neural Complexity Yet
|
|
68
|
+
By using a **purely symbolic task**, this test isolates synthesis validation from LLM execution complexity:
|
|
69
|
+
- No LLM API calls to fail
|
|
70
|
+
- No neural task instruction parsing
|
|
71
|
+
- No MCP server connections
|
|
72
|
+
- Just pure: synthesize → execute → output
|
data/synth/001/output.log
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
[1;36m
|
|
3
|
-
[1;36m
|
|
4
|
-
[1;36m
|
|
5
|
-
[1;36m
|
|
6
|
-
[1;36m
|
|
7
|
-
[1;36m
|
|
8
|
-
[1;36m
|
|
9
|
-
[1;36m
|
|
10
|
-
[1;36m
|
|
11
|
-
[1;36m
|
|
12
|
-
[1;36m·[0m Main block execution completed (result={message: "Test agent is saying hello!"})
|
|
1
|
+
[1;36m⚬[0m OpenTelemetry disabled
|
|
2
|
+
[1;36m⚬[0m Configuring LLM (provider=openai_compatible, model=mistralai/magistral-small-2509, timeout=300)
|
|
3
|
+
[1;36m⚬[0m LLM configuration complete
|
|
4
|
+
[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 Executing main block (agent=test-agent, task_count=1)
|
|
7
|
+
[1;36m⚬[0m Executing main block (inputs_keys=[])
|
|
8
|
+
[1;36m⚬[0m Executing task (task=generate_log_message, type=symbolic, timeout=30.0, max_retries=3)
|
|
9
|
+
[1;36m⚬[0m Main execution (0.0s)
|
|
10
|
+
[1;36m⚬[0m Main block completed
|
|
11
|
+
[1;36m⚬[0m Main block execution completed (result={message: "Test agent is saying hello!"})
|
|
13
12
|
Test agent is saying hello!
|
|
14
|
-
[32m
|
|
13
|
+
[32m✔ Agent completed successfully[0m
|
|
14
|
+
|
|
15
15
|
|
data/synth/002/Makefile
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
.PHONY: synthesize exec help
|
|
2
|
+
|
|
3
|
+
help:
|
|
4
|
+
@echo "Synthesis Test Targets:"
|
|
5
|
+
@echo " make synthesize - Generate agent.rb using default model"
|
|
6
|
+
@echo " make exec - Execute agent.rb locally with bundle exec"
|
|
7
|
+
|
|
8
|
+
synthesize:
|
|
9
|
+
cat agent.txt | bundle exec ../../bin/aictl system synthesize --raw | tee agent.rb
|
|
10
|
+
|
|
11
|
+
exec:
|
|
12
|
+
cat agent.rb | bundle exec ../../bin/aictl system exec | tee output.log
|