language-operator 0.1.53 → 0.1.54
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/Gemfile.lock +1 -1
- data/lib/language_operator/templates/agent_synthesis.tmpl +62 -3
- 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/002/README.md +20 -147
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cc9f8e717ca6bd8f00386094494b88f2f2e3050239b9d476ba9519868d82df58
|
|
4
|
+
data.tar.gz: b15364fd16e4a9793263a8d861999d3c0a9188c2db3c6122176462a6b934c753
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 62729e36597f476b960c64b589a2e426ef5fe54f51e7db91d0ab91cdbc05a916fc000bc94c1e828e9839e2f6bff95a31f42f3c330006a008bc9c1e2a2fd63e03
|
|
7
|
+
data.tar.gz: a5472ea444b2d6bf58316c638b03b22365bd51e6b635a3eb3b2cb2d458a540e802def9e7d86243ec72bf958924b1c4441485ea8cf9121c7d96647a9bf046cec9
|
data/Gemfile.lock
CHANGED
|
@@ -77,8 +77,8 @@ This is attempt {{.AttemptNumber}} of {{.MaxAttempts}}. The user is counting on
|
|
|
77
77
|
|
|
78
78
|
**Runtime Context:**
|
|
79
79
|
- All agent messages and output are automatically logged to stdout
|
|
80
|
-
- Agents have access to a workspace directory for file operations
|
|
81
80
|
- LLM responses are captured and available in agent execution context
|
|
81
|
+
- File operations should use neural tasks that delegate to the workspace tool (see examples below)
|
|
82
82
|
|
|
83
83
|
## DSL v1 Reference Examples
|
|
84
84
|
|
|
@@ -174,16 +174,72 @@ agent "data-pipeline" do
|
|
|
174
174
|
|
|
175
175
|
main do |inputs|
|
|
176
176
|
extracted = execute_task(:extract_data, inputs: inputs)
|
|
177
|
-
transformed = execute_task(:transform_data, inputs:
|
|
177
|
+
transformed = execute_task(:transform_data, inputs: transformed)
|
|
178
178
|
result = execute_task(:load_data, inputs: transformed)
|
|
179
179
|
result
|
|
180
180
|
end
|
|
181
181
|
end
|
|
182
182
|
```
|
|
183
183
|
|
|
184
|
+
### Example 4: Stateful Agent with Workspace File Operations
|
|
185
|
+
```ruby
|
|
186
|
+
require 'language_operator'
|
|
187
|
+
|
|
188
|
+
agent "story-builder" do
|
|
189
|
+
description "Build a story one sentence at a time"
|
|
190
|
+
mode :scheduled
|
|
191
|
+
schedule "0 * * * *"
|
|
192
|
+
|
|
193
|
+
# Neural task - LLM reads file using workspace tool
|
|
194
|
+
task :read_existing_story,
|
|
195
|
+
instructions: "Read the story.txt file from workspace. If it doesn't exist, return empty string. Return the content and count of sentences.",
|
|
196
|
+
inputs: {},
|
|
197
|
+
outputs: { content: 'string', sentence_count: 'integer' }
|
|
198
|
+
|
|
199
|
+
# Neural task - LLM generates creative continuation
|
|
200
|
+
task :generate_next_sentence,
|
|
201
|
+
instructions: "Generate exactly one new sentence to continue this story. Maintain consistent tone and style. Only output the new sentence.",
|
|
202
|
+
inputs: { existing_content: 'string' },
|
|
203
|
+
outputs: { sentence: 'string' }
|
|
204
|
+
|
|
205
|
+
# Neural task - LLM writes file using workspace tool
|
|
206
|
+
task :append_to_story,
|
|
207
|
+
instructions: "Append the new sentence to story.txt in workspace. If the file has existing content, add a newline first.",
|
|
208
|
+
inputs: { sentence: 'string' },
|
|
209
|
+
outputs: { success: 'boolean', total_sentences: 'integer' }
|
|
210
|
+
|
|
211
|
+
main do |inputs|
|
|
212
|
+
# Read current state from workspace
|
|
213
|
+
story_data = execute_task(:read_existing_story)
|
|
214
|
+
|
|
215
|
+
# Generate new content based on what exists
|
|
216
|
+
new_sentence = execute_task(:generate_next_sentence,
|
|
217
|
+
inputs: { existing_content: story_data[:content] })
|
|
218
|
+
|
|
219
|
+
# Persist to workspace for next run
|
|
220
|
+
result = execute_task(:append_to_story,
|
|
221
|
+
inputs: { sentence: new_sentence[:sentence] })
|
|
222
|
+
|
|
223
|
+
{ sentence: new_sentence[:sentence], total: result[:total_sentences] }
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
output do |outputs|
|
|
227
|
+
puts "Added sentence: #{outputs[:sentence]}"
|
|
228
|
+
puts "Story now has #{outputs[:total]} sentences"
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**File Operations Best Practices:**
|
|
234
|
+
- **NEVER** use direct Ruby file operations (`File.read`, `File.write`, `File.open`, `Dir.pwd`, etc.) in agent code
|
|
235
|
+
- **ALWAYS** delegate file operations to neural tasks with clear natural language instructions
|
|
236
|
+
- File operations require the LLM to reason about paths, content, and state - use the workspace tool via neural tasks
|
|
237
|
+
- The workspace tool provides: `read_file`, `write_file`, `list_directory`, `create_directory`, `get_file_info`, `search_files`
|
|
238
|
+
- Example pattern: `task :read_data, instructions: "read data.json from workspace and parse it", inputs: {}, outputs: { data: 'hash' }`
|
|
239
|
+
|
|
184
240
|
## Your Task: Generate DSL v1 Agent
|
|
185
241
|
|
|
186
|
-
Using the
|
|
242
|
+
Using the FOUR CONCRETE EXAMPLES above (daily-report, code-reviewer, data-pipeline, story-builder) as reference patterns, generate WORKING Ruby DSL code for the agent described in the user instructions.
|
|
187
243
|
|
|
188
244
|
**CRITICAL REQUIREMENTS:**
|
|
189
245
|
- DO NOT output placeholder text like "Brief description extracted from instructions" or "CRON_EXPRESSION"
|
|
@@ -250,6 +306,9 @@ end
|
|
|
250
306
|
- ✓ Are all task names, descriptions, and logic SPECIFIC to the user's request?
|
|
251
307
|
- ✓ Did you AVOID outputting placeholders like "task_name" or "CRON_EXPRESSION"?
|
|
252
308
|
- ✓ Does the code actually DO what the user asked for?
|
|
309
|
+
- ✓ Did you use NEURAL TASKS (not symbolic code blocks) for all file operations?
|
|
310
|
+
- ✓ Did you NEVER use File.read, File.write, Dir.pwd, or other direct file APIs?
|
|
311
|
+
- ✓ For workspace operations, did you write clear instructions for the LLM to use the workspace tool?
|
|
253
312
|
|
|
254
313
|
If you cannot answer YES to all of the above, re-read the user instructions and generate FUNCTIONAL code.
|
|
255
314
|
|
|
@@ -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.54",
|
|
7
7
|
"type": "object",
|
|
8
8
|
"properties": {
|
|
9
9
|
"name": {
|
data/synth/002/README.md
CHANGED
|
@@ -36,16 +36,24 @@ mode :scheduled
|
|
|
36
36
|
schedule "*/10 * * * *" # Every 10 minutes
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
Validates that agents can run on a schedule using
|
|
39
|
+
Validates that agents can run on a schedule using Kubernetes CronJobs:
|
|
40
40
|
- ✅ **Mode dispatch** - Runtime recognizes `:scheduled` mode
|
|
41
|
-
- ✅ **Cron parsing** - Schedule expression is
|
|
42
|
-
- ✅ **
|
|
43
|
-
- ✅ **
|
|
41
|
+
- ✅ **Cron parsing** - Schedule expression is used by Kubernetes CronJob
|
|
42
|
+
- ✅ **Kubernetes-native** - CronJob creates pods on schedule
|
|
43
|
+
- ✅ **Execute once and exit** - Each pod runs the task once, then terminates
|
|
44
|
+
- ✅ **Repeated execution** - Kubernetes creates new pods per schedule
|
|
44
45
|
|
|
45
46
|
### 3. Complete Neural Execution Flow
|
|
46
47
|
```
|
|
47
48
|
┌─────────────────────────────────────────────────────────┐
|
|
48
|
-
│
|
|
49
|
+
│ Kubernetes CronJob Triggers (every 10 minutes) │
|
|
50
|
+
│ Creates new pod for this execution │
|
|
51
|
+
└────────────────────┬────────────────────────────────────┘
|
|
52
|
+
│
|
|
53
|
+
▼
|
|
54
|
+
┌─────────────────────────────────────────────────────────┐
|
|
55
|
+
│ Pod Starts → Agent Runtime Loads │
|
|
56
|
+
│ Mode: scheduled → Execute once and exit │
|
|
49
57
|
└────────────────────┬────────────────────────────────────┘
|
|
50
58
|
│
|
|
51
59
|
▼
|
|
@@ -75,6 +83,12 @@ Validates that agents can run on a schedule using cron syntax:
|
|
|
75
83
|
┌─────────────────────────────────────────────────────────┐
|
|
76
84
|
│ Output Block Processes Result │
|
|
77
85
|
│ puts outputs[:fortune] │
|
|
86
|
+
└────────────────────┬────────────────────────────────────┘
|
|
87
|
+
│
|
|
88
|
+
▼
|
|
89
|
+
┌─────────────────────────────────────────────────────────┐
|
|
90
|
+
│ Agent Exits → Pod Terminates │
|
|
91
|
+
│ Kubernetes waits for next cron schedule │
|
|
78
92
|
└─────────────────────────────────────────────────────────┘
|
|
79
93
|
```
|
|
80
94
|
|
|
@@ -133,100 +147,6 @@ This test proves the foundation for learning:
|
|
|
133
147
|
|
|
134
148
|
**The critical insight**: Because `execute_task(:generate_fortune)` works the same whether the task is neural or symbolic, we can replace implementations without breaking the `main` block.
|
|
135
149
|
|
|
136
|
-
### No Other Framework Can Do This
|
|
137
|
-
|
|
138
|
-
| Framework | Neural Execution | Symbolic Execution | Transparent Evolution |
|
|
139
|
-
|-----------|-----------------|-------------------|---------------------|
|
|
140
|
-
| **Language Operator** | ✅ Instructions-based tasks | ✅ Code blocks | ✅ Contract abstraction |
|
|
141
|
-
| LangChain | ❌ Chains are static | ✅ Python code | ❌ No abstraction |
|
|
142
|
-
| AutoGen | ✅ Conversational | ❌ No symbolic optimization | ❌ No contracts |
|
|
143
|
-
| CrewAI | ✅ Agents with prompts | ❌ No learning | ❌ No abstraction |
|
|
144
|
-
|
|
145
|
-
## What It Doesn't Test
|
|
146
|
-
|
|
147
|
-
This test intentionally **does not** validate:
|
|
148
|
-
- ❌ Learning/re-synthesis (future tests)
|
|
149
|
-
- ❌ MCP tool integration in neural tasks (future tests)
|
|
150
|
-
- ❌ Complex multi-task workflows (future tests)
|
|
151
|
-
- ❌ Error recovery and re-synthesis (future tests)
|
|
152
|
-
- ❌ Hybrid neural-symbolic agents (future tests)
|
|
153
|
-
|
|
154
|
-
## Success Criteria
|
|
155
|
-
|
|
156
|
-
✅ **Agent synthesizes with neural task** - Instructions-based task definition works
|
|
157
|
-
✅ **Scheduled mode activates** - Agent runs on cron schedule
|
|
158
|
-
✅ **Neural task executes** - LLM is invoked with instructions
|
|
159
|
-
✅ **Output schema validated** - LLM response matches `{ fortune: 'string' }`
|
|
160
|
-
✅ **Output appears** - Fortune is logged to stdout
|
|
161
|
-
✅ **Repeated execution** - Agent runs multiple times (every 10 minutes)
|
|
162
|
-
|
|
163
|
-
## Connection to DSL v1 Proposal
|
|
164
|
-
|
|
165
|
-
From [dsl-v1.md](../requirements/proposals/dsl-v1.md):
|
|
166
|
-
|
|
167
|
-
> **Critical Property:** The caller cannot tell which implementation is used. The contract is the interface.
|
|
168
|
-
|
|
169
|
-
This test proves that property works in practice:
|
|
170
|
-
|
|
171
|
-
**Contract (Stable):**
|
|
172
|
-
```ruby
|
|
173
|
-
task :generate_fortune,
|
|
174
|
-
inputs: {},
|
|
175
|
-
outputs: { fortune: 'string' }
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
**Implementation (Neural - for now):**
|
|
179
|
-
```ruby
|
|
180
|
-
instructions: "Generate a random fortune for the user"
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
**Caller (Unaware):**
|
|
184
|
-
```ruby
|
|
185
|
-
main do |inputs|
|
|
186
|
-
fortune_data = execute_task(:generate_fortune) # Works regardless of implementation
|
|
187
|
-
{ fortune: fortune_data[:fortune] }
|
|
188
|
-
end
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
The `main` block doesn't know (and doesn't care) whether `:generate_fortune` is neural or symbolic. This is the **organic function abstraction** that enables real-time synthesis and learning.
|
|
192
|
-
|
|
193
|
-
## Running the Test
|
|
194
|
-
|
|
195
|
-
```bash
|
|
196
|
-
# Execute the synthesized agent
|
|
197
|
-
ruby synth/002/agent.rb
|
|
198
|
-
|
|
199
|
-
# Expected behavior:
|
|
200
|
-
# - Agent starts in scheduled mode
|
|
201
|
-
# - Every 10 minutes, generates and prints a fortune
|
|
202
|
-
# - Runs continuously until stopped
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
## What Success Looks Like
|
|
206
|
-
|
|
207
|
-
```
|
|
208
|
-
[INFO] Loading agent: test-agent
|
|
209
|
-
[INFO] Mode: scheduled (*/10 * * * *)
|
|
210
|
-
[INFO] Scheduler started
|
|
211
|
-
[INFO] Executing main block (scheduled trigger)
|
|
212
|
-
[INFO] Executing task: generate_fortune (neural)
|
|
213
|
-
[INFO] Calling LLM with instructions: "Generate a random fortune for the user"
|
|
214
|
-
[INFO] LLM returned: {:fortune=>"A journey of a thousand miles begins with a single step."}
|
|
215
|
-
[INFO] Validating output schema: { fortune: 'string' } ✓
|
|
216
|
-
[INFO] Task returned: {:fortune=>"A journey of a thousand miles begins with a single step."}
|
|
217
|
-
[INFO] Processing output
|
|
218
|
-
A journey of a thousand miles begins with a single step.
|
|
219
|
-
[INFO] Agent execution complete, waiting for next schedule
|
|
220
|
-
[INFO] Next run: 2025-11-16 14:20:00
|
|
221
|
-
...
|
|
222
|
-
[INFO] Executing main block (scheduled trigger)
|
|
223
|
-
[INFO] Executing task: generate_fortune (neural)
|
|
224
|
-
[INFO] Calling LLM with instructions: "Generate a random fortune for the user"
|
|
225
|
-
[INFO] LLM returned: {:fortune=>"Fortune favors the bold."}
|
|
226
|
-
[INFO] Validating output schema: { fortune: 'string' } ✓
|
|
227
|
-
Fortune favors the bold.
|
|
228
|
-
```
|
|
229
|
-
|
|
230
150
|
## The Organic Function In Action
|
|
231
151
|
|
|
232
152
|
**What makes this revolutionary:**
|
|
@@ -237,51 +157,4 @@ Fortune favors the bold.
|
|
|
237
157
|
4. **Learning Ready**: After N runs, system can observe patterns and synthesize symbolic implementation
|
|
238
158
|
5. **Zero Breaking Changes**: When re-synthesized, `main` block never changes
|
|
239
159
|
|
|
240
|
-
**This is what "living code" means**: Code that starts neural (flexible, works immediately) and becomes symbolic (fast, cheap) through observation, all while maintaining a stable contract.
|
|
241
|
-
|
|
242
|
-
---
|
|
243
|
-
|
|
244
|
-
**Status**: ✅ VALIDATED - Neural organic functions work
|
|
245
|
-
|
|
246
|
-
**Next**: Test 003+ will validate learning, re-synthesis, and progressive neural→symbolic evolution
|
|
247
|
-
|
|
248
|
-
---
|
|
249
|
-
|
|
250
|
-
## Technical Deep Dive
|
|
251
|
-
|
|
252
|
-
### How Neural Execution Works
|
|
253
|
-
|
|
254
|
-
When `execute_task(:generate_fortune)` is called:
|
|
255
|
-
|
|
256
|
-
1. **Task Lookup**: Runtime finds task definition in agent
|
|
257
|
-
2. **Type Check**: Task has `instructions`, no code block → Neural execution
|
|
258
|
-
3. **Prompt Construction**:
|
|
259
|
-
```
|
|
260
|
-
You are an AI agent executing a task.
|
|
261
|
-
|
|
262
|
-
Task: generate_fortune
|
|
263
|
-
Instructions: Generate a random fortune for the user
|
|
264
|
-
|
|
265
|
-
Inputs: {}
|
|
266
|
-
|
|
267
|
-
You must return a response matching this schema:
|
|
268
|
-
{ fortune: 'string' }
|
|
269
|
-
|
|
270
|
-
[Available tools if any MCP servers connected]
|
|
271
|
-
```
|
|
272
|
-
4. **LLM Invocation**: Send prompt to configured LLM (via `ruby_llm`)
|
|
273
|
-
5. **Response Parsing**: Extract structured output from LLM response
|
|
274
|
-
6. **Schema Validation**: Ensure response matches `{ fortune: 'string' }`
|
|
275
|
-
7. **Return**: Validated output returned to caller
|
|
276
|
-
|
|
277
|
-
### What This Enables Later
|
|
278
|
-
|
|
279
|
-
Once this works, the learning system can:
|
|
280
|
-
|
|
281
|
-
1. **Observe Execution**: Collect OpenTelemetry traces showing what the LLM did
|
|
282
|
-
2. **Detect Patterns**: Analyze if LLM behavior is deterministic
|
|
283
|
-
3. **Synthesize Code**: Generate symbolic implementation from observed pattern
|
|
284
|
-
4. **Re-Deploy**: Update ConfigMap with learned code
|
|
285
|
-
5. **Transparent Evolution**: `main` block continues working identically
|
|
286
|
-
|
|
287
|
-
**This test proves step 1 works** (neural execution). Future tests prove steps 2-5.
|
|
160
|
+
**This is what "living code" means**: Code that starts neural (flexible, works immediately) and becomes symbolic (fast, cheap) through observation, all while maintaining a stable contract.
|