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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 362d72d195bf272f98204cba33e7f8bf6513c7544a6bf6d6369c2ef1b9cfe793
4
- data.tar.gz: d75edb537a7bec08fbba3a6b96dc05e9ecdbf62d7e80b9d33176f365623f4542
3
+ metadata.gz: cc9f8e717ca6bd8f00386094494b88f2f2e3050239b9d476ba9519868d82df58
4
+ data.tar.gz: b15364fd16e4a9793263a8d861999d3c0a9188c2db3c6122176462a6b934c753
5
5
  SHA512:
6
- metadata.gz: 7c3c378dfb4a013a1590b7c3295ad7f948a74d076f9ae38e50d587c7dfc26f254669c2586ff02aaa6fd8f1c5b933d67f627d7777f950f5bcacf59575b56c6da1
7
- data.tar.gz: 7f956e31db63897853f31d237181c54f85b6c352d350ce4d3347bffaec0d4aaca7d2a2082b9c0092bd0f7972938271d9309e85ecb835679fca9e19008ec6dc2f
6
+ metadata.gz: 62729e36597f476b960c64b589a2e426ef5fe54f51e7db91d0ab91cdbc05a916fc000bc94c1e828e9839e2f6bff95a31f42f3c330006a008bc9c1e2a2fd63e03
7
+ data.tar.gz: a5472ea444b2d6bf58316c638b03b22365bd51e6b635a3eb3b2cb2d458a540e802def9e7d86243ec72bf958924b1c4441485ea8cf9121c7d96647a9bf046cec9
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- language-operator (0.1.53)
4
+ language-operator (0.1.54)
5
5
  faraday (~> 2.0)
6
6
  k8s-ruby (~> 0.17)
7
7
  mcp (~> 0.4)
@@ -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: extracted)
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 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.
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
 
@@ -2,7 +2,7 @@
2
2
  :openapi: 3.0.3
3
3
  :info:
4
4
  :title: Language Operator Agent API
5
- :version: 0.1.53
5
+ :version: 0.1.54
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.53",
6
+ "version": "0.1.54",
7
7
  "type": "object",
8
8
  "properties": {
9
9
  "name": {
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LanguageOperator
4
- VERSION = '0.1.53'
4
+ VERSION = '0.1.54'
5
5
  end
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 cron syntax:
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 parsed correctly
42
- - ✅ **Scheduler integration** - `rufus-scheduler` integration works
43
- - ✅ **Repeated execution** - Agent runs multiple times automatically
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
- Scheduler Triggers (every 10 minutes)
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.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: language-operator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.53
4
+ version: 0.1.54
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Ryan