language-operator 0.1.31 → 0.1.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -8
  3. data/CHANGELOG.md +14 -0
  4. data/CI_STATUS.md +56 -0
  5. data/Gemfile.lock +2 -2
  6. data/Makefile +22 -6
  7. data/lib/language_operator/agent/base.rb +10 -6
  8. data/lib/language_operator/agent/executor.rb +19 -97
  9. data/lib/language_operator/agent/safety/ast_validator.rb +62 -43
  10. data/lib/language_operator/agent/safety/safe_executor.rb +27 -2
  11. data/lib/language_operator/agent/scheduler.rb +60 -0
  12. data/lib/language_operator/agent/task_executor.rb +548 -0
  13. data/lib/language_operator/agent.rb +90 -27
  14. data/lib/language_operator/cli/base_command.rb +117 -0
  15. data/lib/language_operator/cli/commands/agent.rb +339 -407
  16. data/lib/language_operator/cli/commands/cluster.rb +274 -290
  17. data/lib/language_operator/cli/commands/install.rb +110 -119
  18. data/lib/language_operator/cli/commands/model.rb +284 -184
  19. data/lib/language_operator/cli/commands/persona.rb +218 -284
  20. data/lib/language_operator/cli/commands/quickstart.rb +4 -5
  21. data/lib/language_operator/cli/commands/status.rb +31 -35
  22. data/lib/language_operator/cli/commands/system.rb +221 -233
  23. data/lib/language_operator/cli/commands/tool.rb +356 -422
  24. data/lib/language_operator/cli/commands/use.rb +19 -22
  25. data/lib/language_operator/cli/helpers/resource_dependency_checker.rb +0 -18
  26. data/lib/language_operator/cli/wizards/quickstart_wizard.rb +0 -1
  27. data/lib/language_operator/client/config.rb +20 -21
  28. data/lib/language_operator/config.rb +115 -3
  29. data/lib/language_operator/constants.rb +54 -0
  30. data/lib/language_operator/dsl/agent_context.rb +7 -7
  31. data/lib/language_operator/dsl/agent_definition.rb +111 -26
  32. data/lib/language_operator/dsl/config.rb +30 -66
  33. data/lib/language_operator/dsl/main_definition.rb +114 -0
  34. data/lib/language_operator/dsl/schema.rb +84 -43
  35. data/lib/language_operator/dsl/task_definition.rb +315 -0
  36. data/lib/language_operator/dsl.rb +0 -1
  37. data/lib/language_operator/instrumentation/task_tracer.rb +285 -0
  38. data/lib/language_operator/logger.rb +4 -4
  39. data/lib/language_operator/synthesis_test_harness.rb +324 -0
  40. data/lib/language_operator/templates/examples/agent_synthesis.tmpl +26 -8
  41. data/lib/language_operator/templates/schema/CHANGELOG.md +26 -0
  42. data/lib/language_operator/templates/schema/agent_dsl_openapi.yaml +1 -1
  43. data/lib/language_operator/templates/schema/agent_dsl_schema.json +84 -42
  44. data/lib/language_operator/type_coercion.rb +250 -0
  45. data/lib/language_operator/ux/base.rb +81 -0
  46. data/lib/language_operator/ux/concerns/README.md +155 -0
  47. data/lib/language_operator/ux/concerns/headings.rb +90 -0
  48. data/lib/language_operator/ux/concerns/input_validation.rb +146 -0
  49. data/lib/language_operator/ux/concerns/provider_helpers.rb +167 -0
  50. data/lib/language_operator/ux/create_agent.rb +252 -0
  51. data/lib/language_operator/ux/create_model.rb +267 -0
  52. data/lib/language_operator/ux/quickstart.rb +594 -0
  53. data/lib/language_operator/version.rb +1 -1
  54. data/lib/language_operator.rb +2 -0
  55. data/requirements/ARCHITECTURE.md +1 -0
  56. data/requirements/SCRATCH.md +153 -0
  57. data/requirements/dsl.md +0 -0
  58. data/requirements/features +1 -0
  59. data/requirements/personas +1 -0
  60. data/requirements/proposals +1 -0
  61. data/requirements/tasks/iterate.md +14 -15
  62. data/requirements/tasks/optimize.md +13 -4
  63. data/synth/001/Makefile +90 -0
  64. data/synth/001/agent.rb +26 -0
  65. data/synth/001/agent.yaml +7 -0
  66. data/synth/001/output.log +44 -0
  67. data/synth/Makefile +39 -0
  68. data/synth/README.md +342 -0
  69. metadata +37 -10
  70. data/lib/language_operator/dsl/workflow_definition.rb +0 -259
  71. data/test_agent_dsl.rb +0 -108
data/synth/README.md ADDED
@@ -0,0 +1,342 @@
1
+ # Synthesis Test Suite
2
+
3
+ This directory contains a test suite for validating agent code synthesis locally without requiring a Kubernetes cluster.
4
+
5
+ ## Purpose
6
+
7
+ The synthesis test suite allows you to:
8
+
9
+ 1. **Test synthesis locally** - Generate Ruby DSL code from LanguageAgent YAML specs
10
+ 2. **Compare models** - See how different LLMs (Claude, GPT-4) synthesize the same agent
11
+ 3. **Iterate quickly** - Test template/prompt changes without deploying to K8s
12
+ 4. **Build regression tests** - Verify synthesis quality doesn't degrade
13
+ 5. **Debug synthesis issues** - Identify and fix problems in the synthesis pipeline
14
+
15
+ ## Directory Structure
16
+
17
+ ```
18
+ synth/
19
+ ├── Makefile # Top-level test runner
20
+ ├── README.md # This file
21
+ └── 001/ # Test case: "hello-world"
22
+ ├── agent.yaml # Input: LanguageAgent spec
23
+ ├── agent.rb # Output: Generated code (default model)
24
+ ├── agent.sonnet.rb # Output: Claude Sonnet
25
+ ├── agent.gpt-4.rb # Output: GPT-4
26
+ └── Makefile # Test-specific targets
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ ### Prerequisites
32
+
33
+ **Option 1: Local OpenAI-Compatible Endpoint (Recommended)**
34
+
35
+ Use a local LLM server (LMStudio, vLLM, Ollama with OpenAI adapter, etc.):
36
+
37
+ ```bash
38
+ export SYNTHESIS_ENDPOINT="http://192.168.68.54:1234/v1"
39
+ export SYNTHESIS_API_KEY="dummy" # Optional, defaults to "dummy"
40
+ export SYNTHESIS_MODEL="mistralai/magistral-small-2509" # Or your quantized model
41
+ ```
42
+
43
+ **Option 2: Cloud API Keys**
44
+
45
+ ```bash
46
+ export ANTHROPIC_API_KEY="sk-ant-..." # For Claude
47
+ export OPENAI_API_KEY="sk-..." # For GPT-4
48
+ ```
49
+
50
+ The harness prioritizes `SYNTHESIS_ENDPOINT` if set, allowing you to test on quantized local models before hitting cloud APIs.
51
+
52
+ ### Run a Test
53
+
54
+ ```bash
55
+ # Run synthesis for test 001
56
+ cd synth/001
57
+ make synthesize
58
+
59
+ # View the generated code
60
+ cat agent.rb
61
+
62
+ # Execute the agent locally
63
+ make run
64
+
65
+ # Clean up
66
+ make clean
67
+ ```
68
+
69
+ ### Compare Models
70
+
71
+ ```bash
72
+ cd synth/001
73
+
74
+ # Generate with all models
75
+ make synthesize-all
76
+
77
+ # Compare outputs
78
+ make compare
79
+
80
+ # Or manually inspect
81
+ cat agent.sonnet.rb
82
+ cat agent.gpt-4.rb
83
+ ```
84
+
85
+ ## Test Case Format
86
+
87
+ Each test case is a numbered directory (`001`, `002`, etc.) containing:
88
+
89
+ ### agent.yaml
90
+
91
+ A LanguageAgent CRD spec:
92
+
93
+ ```yaml
94
+ apiVersion: langop.io/v1alpha1
95
+ kind: LanguageAgent
96
+ metadata:
97
+ name: hello-world
98
+ spec:
99
+ instructions: |
100
+ Say something in your logs
101
+ # Optional: toolRefs, modelRefs, personaRefs, etc.
102
+ ```
103
+
104
+ ### Expected Output
105
+
106
+ The synthesis process should generate a Ruby file like:
107
+
108
+ ```ruby
109
+ require 'language_operator'
110
+
111
+ agent "hello-world" do
112
+ description "Say something in your logs"
113
+ mode :autonomous
114
+ objectives [
115
+ "Log a message to the console"
116
+ ]
117
+ constraints do
118
+ max_iterations 1
119
+ timeout "30s"
120
+ end
121
+ end
122
+ ```
123
+
124
+ ## Makefile Targets
125
+
126
+ ### In Test Directory (`synth/001/`)
127
+
128
+ | Target | Description |
129
+ |--------|-------------|
130
+ | `make synthesize` | Generate `agent.rb` with default model |
131
+ | `make synthesize-sonnet` | Generate `agent.sonnet.rb` with Claude |
132
+ | `make synthesize-gpt-4` | Generate `agent.gpt-4.rb` with GPT-4 |
133
+ | `make synthesize-all` | Generate for all configured models |
134
+ | `make run` | Execute the synthesized `agent.rb` locally |
135
+ | `make validate` | Validate Ruby syntax of `agent.rb` |
136
+ | `make clean` | Remove all generated `.rb` files |
137
+ | `make compare` | Diff outputs from different models |
138
+
139
+ ### Top-Level (`synth/`)
140
+
141
+ | Target | Description |
142
+ |--------|-------------|
143
+ | `make test` | Run default synthesis for all tests |
144
+ | `make test-all` | Run synthesis with all models |
145
+ | `make clean` | Clean all test artifacts |
146
+ | `make list` | List available test cases |
147
+
148
+ ## How It Works
149
+
150
+ ### Synthesis Flow
151
+
152
+ 1. **Load agent.yaml** - Parse LanguageAgent spec
153
+ 2. **Extract fields** - Get instructions, tools, models, persona
154
+ 3. **Build prompt** - Fill synthesis template with extracted data
155
+ 4. **Call LLM** - Send prompt to Claude/GPT-4
156
+ 5. **Extract code** - Parse Ruby code from markdown response
157
+ 6. **Validate** - Check syntax and security (AST validation)
158
+ 7. **Write output** - Save to `agent.rb` or model-specific file
159
+
160
+ ### Implementation
161
+
162
+ The test harness is implemented in:
163
+
164
+ ```
165
+ lib/language_operator/synthesis_test_harness.rb
166
+ ```
167
+
168
+ It replicates the Go operator's synthesis logic but runs locally in Ruby.
169
+
170
+ ## Adding New Test Cases
171
+
172
+ 1. Create a new directory:
173
+ ```bash
174
+ mkdir synth/002
175
+ ```
176
+
177
+ 2. Copy the Makefile template:
178
+ ```bash
179
+ cp synth/001/Makefile synth/002/
180
+ ```
181
+
182
+ 3. Create `agent.yaml`:
183
+ ```yaml
184
+ apiVersion: langop.io/v1alpha1
185
+ kind: LanguageAgent
186
+ metadata:
187
+ name: my-test-agent
188
+ spec:
189
+ instructions: |
190
+ Your test instructions here
191
+ ```
192
+
193
+ 4. Run synthesis:
194
+ ```bash
195
+ cd synth/002
196
+ make synthesize
197
+ ```
198
+
199
+ 5. Update top-level Makefile to include new test
200
+
201
+ ## Example Test Cases
202
+
203
+ ### 001 - Hello World
204
+ **Instructions**: "Say something in your logs"
205
+ **Expected**: Simple autonomous agent with single objective
206
+
207
+ ### 002 - Scheduled Agent (Future)
208
+ **Instructions**: "Check website daily at noon"
209
+ **Expected**: Scheduled agent with cron expression
210
+
211
+ ### 003 - Reactive Webhook (Future)
212
+ **Instructions**: "When webhook received, send email"
213
+ **Expected**: Reactive agent with webhook definition
214
+
215
+ ### 004 - Multi-Step Workflow (Future)
216
+ **Instructions**: "Fetch data from API, analyze it, save results"
217
+ **Expected**: Agent with workflow steps and dependencies
218
+
219
+ ## Relationship to `aictl system test-synthesis`
220
+
221
+ The `aictl system test-synthesis` command provides similar functionality but with different interface:
222
+
223
+ ```bash
224
+ # CLI-based (existing command)
225
+ aictl system test-synthesis --instructions "Say something in your logs"
226
+
227
+ # YAML-based (this test suite)
228
+ cd synth/001 && make synthesize
229
+ ```
230
+
231
+ **Benefits of YAML test suite:**
232
+ - ✅ Version controlled test cases
233
+ - ✅ Easy to compare model outputs side-by-side
234
+ - ✅ Repeatable regression testing
235
+ - ✅ Can specify full LanguageAgent spec (tools, models, etc.)
236
+
237
+ **Benefits of CLI command:**
238
+ - ✅ Quick one-off testing
239
+ - ✅ No file management
240
+ - ✅ Integrated with aictl workflow
241
+
242
+ Both are valuable for different use cases!
243
+
244
+ ## Troubleshooting
245
+
246
+ ### API Key Not Found
247
+
248
+ ```
249
+ Error: No API key found. Set either:
250
+ SYNTHESIS_ENDPOINT (for local/OpenAI-compatible)
251
+ ANTHROPIC_API_KEY (for Claude)
252
+ OPENAI_API_KEY (for GPT)
253
+ ```
254
+
255
+ **Solution**: Set environment variables:
256
+ ```bash
257
+ # For local endpoint (recommended)
258
+ export SYNTHESIS_ENDPOINT="http://localhost:1234/v1"
259
+ export SYNTHESIS_MODEL="your-model-name"
260
+
261
+ # OR for cloud APIs
262
+ export ANTHROPIC_API_KEY="sk-ant-..."
263
+ export OPENAI_API_KEY="sk-..."
264
+ ```
265
+
266
+ ### Synthesis Failed
267
+
268
+ ```
269
+ Error: LLM call failed: ...
270
+ ```
271
+
272
+ **Solution**: Check:
273
+ - API key is valid
274
+ - Network connectivity
275
+ - Model name is correct
276
+ - LLM service is available
277
+
278
+ ### Validation Failed
279
+
280
+ ```
281
+ Error: Security validation failed
282
+ ```
283
+
284
+ **Solution**: The generated code contains dangerous methods. This is a synthesis quality issue - the template needs improvement or the LLM hallucinated unsafe code.
285
+
286
+ ### Empty Output
287
+
288
+ ```
289
+ Error: Empty code generated
290
+ ```
291
+
292
+ **Solution**: The LLM didn't return code in the expected format. Check the prompt and template.
293
+
294
+ ## Development Workflow
295
+
296
+ ### Iterate on Template Changes
297
+
298
+ 1. Edit template: `lib/language_operator/templates/examples/agent_synthesis.tmpl`
299
+ 2. Test locally: `cd synth/001 && make clean && make synthesize`
300
+ 3. Review output: `cat agent.rb`
301
+ 4. Repeat until satisfied
302
+ 5. Copy to operator: Update Go operator's embedded template
303
+
304
+ ### Test DSL Changes
305
+
306
+ 1. Add new DSL feature to schema
307
+ 2. Update template to show example of new feature
308
+ 3. Create test case exercising new feature
309
+ 4. Run synthesis: `make synthesize`
310
+ 5. Verify generated code uses new feature correctly
311
+
312
+ ## Future Enhancements
313
+
314
+ - [ ] Automated comparison with expected output (golden files)
315
+ - [ ] CI/CD integration (run on every PR)
316
+ - [ ] Metrics tracking (synthesis quality over time)
317
+ - [ ] More test cases covering all DSL features
318
+ - [ ] Support for additional models (Gemini, etc.)
319
+ - [ ] Template A/B testing (compare different prompt versions)
320
+
321
+ ## Related Commands
322
+
323
+ ```bash
324
+ # View DSL schema
325
+ aictl system schema
326
+
327
+ # View synthesis template
328
+ aictl system synthesis-template
329
+
330
+ # Validate template
331
+ aictl system validate_template
332
+
333
+ # Test synthesis (CLI)
334
+ aictl system test-synthesis --instructions "..."
335
+ ```
336
+
337
+ ## Questions?
338
+
339
+ See the main project documentation:
340
+ - [Agent DSL Reference](../docs/dsl/agent-reference.md)
341
+ - [Best Practices](../docs/dsl/best-practices.md)
342
+ - [CLAUDE.md](../CLAUDE.md) - AI context document
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.31
4
+ version: 0.1.35
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Ryan
@@ -108,33 +108,33 @@ dependencies:
108
108
  - !ruby/object:Gem::Version
109
109
  version: '2.0'
110
110
  - !ruby/object:Gem::Dependency
111
- name: rufus-scheduler
111
+ name: parallel
112
112
  requirement: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: '3.9'
116
+ version: '1.26'
117
117
  type: :runtime
118
118
  prerelease: false
119
119
  version_requirements: !ruby/object:Gem::Requirement
120
120
  requirements:
121
121
  - - "~>"
122
122
  - !ruby/object:Gem::Version
123
- version: '3.9'
123
+ version: '1.26'
124
124
  - !ruby/object:Gem::Dependency
125
- name: parser
125
+ name: rufus-scheduler
126
126
  requirement: !ruby/object:Gem::Requirement
127
127
  requirements:
128
128
  - - "~>"
129
129
  - !ruby/object:Gem::Version
130
- version: '3.0'
130
+ version: '3.9'
131
131
  type: :runtime
132
132
  prerelease: false
133
133
  version_requirements: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
- version: '3.0'
137
+ version: '3.9'
138
138
  - !ruby/object:Gem::Dependency
139
139
  name: k8s-ruby
140
140
  requirement: !ruby/object:Gem::Requirement
@@ -397,6 +397,7 @@ extra_rdoc_files: []
397
397
  files:
398
398
  - ".rubocop.yml"
399
399
  - CHANGELOG.md
400
+ - CI_STATUS.md
400
401
  - Gemfile
401
402
  - Gemfile.lock
402
403
  - LICENSE
@@ -430,9 +431,11 @@ files:
430
431
  - lib/language_operator/agent/safety/rate_limiter.rb
431
432
  - lib/language_operator/agent/safety/safe_executor.rb
432
433
  - lib/language_operator/agent/scheduler.rb
434
+ - lib/language_operator/agent/task_executor.rb
433
435
  - lib/language_operator/agent/telemetry.rb
434
436
  - lib/language_operator/agent/web_server.rb
435
437
  - lib/language_operator/agent/webhook_authenticator.rb
438
+ - lib/language_operator/cli/base_command.rb
436
439
  - lib/language_operator/cli/commands/agent.rb
437
440
  - lib/language_operator/cli/commands/cluster.rb
438
441
  - lib/language_operator/cli/commands/install.rb
@@ -472,6 +475,7 @@ files:
472
475
  - lib/language_operator/config/cluster_config.rb
473
476
  - lib/language_operator/config/tool_patterns.yaml
474
477
  - lib/language_operator/config/tool_registry.rb
478
+ - lib/language_operator/constants.rb
475
479
  - lib/language_operator/dsl.rb
476
480
  - lib/language_operator/dsl/adapter.rb
477
481
  - lib/language_operator/dsl/agent_context.rb
@@ -482,22 +486,25 @@ files:
482
486
  - lib/language_operator/dsl/execution_context.rb
483
487
  - lib/language_operator/dsl/helpers.rb
484
488
  - lib/language_operator/dsl/http.rb
489
+ - lib/language_operator/dsl/main_definition.rb
485
490
  - lib/language_operator/dsl/mcp_server_definition.rb
486
491
  - lib/language_operator/dsl/parameter_definition.rb
487
492
  - lib/language_operator/dsl/registry.rb
488
493
  - lib/language_operator/dsl/schema.rb
489
494
  - lib/language_operator/dsl/shell.rb
495
+ - lib/language_operator/dsl/task_definition.rb
490
496
  - lib/language_operator/dsl/tool_definition.rb
491
497
  - lib/language_operator/dsl/webhook_authentication.rb
492
498
  - lib/language_operator/dsl/webhook_definition.rb
493
- - lib/language_operator/dsl/workflow_definition.rb
494
499
  - lib/language_operator/errors.rb
500
+ - lib/language_operator/instrumentation/task_tracer.rb
495
501
  - lib/language_operator/kubernetes/client.rb
496
502
  - lib/language_operator/kubernetes/resource_builder.rb
497
503
  - lib/language_operator/loggable.rb
498
504
  - lib/language_operator/logger.rb
499
505
  - lib/language_operator/retry.rb
500
506
  - lib/language_operator/retryable.rb
507
+ - lib/language_operator/synthesis_test_harness.rb
501
508
  - lib/language_operator/templates/README.md
502
509
  - lib/language_operator/templates/examples/agent_synthesis.tmpl
503
510
  - lib/language_operator/templates/examples/persona_distillation.tmpl
@@ -506,13 +513,33 @@ files:
506
513
  - lib/language_operator/templates/schema/agent_dsl_openapi.yaml
507
514
  - lib/language_operator/templates/schema/agent_dsl_schema.json
508
515
  - lib/language_operator/tool_loader.rb
516
+ - lib/language_operator/type_coercion.rb
517
+ - lib/language_operator/ux/base.rb
518
+ - lib/language_operator/ux/concerns/README.md
519
+ - lib/language_operator/ux/concerns/headings.rb
520
+ - lib/language_operator/ux/concerns/input_validation.rb
521
+ - lib/language_operator/ux/concerns/provider_helpers.rb
522
+ - lib/language_operator/ux/create_agent.rb
523
+ - lib/language_operator/ux/create_model.rb
524
+ - lib/language_operator/ux/quickstart.rb
509
525
  - lib/language_operator/validators.rb
510
526
  - lib/language_operator/version.rb
527
+ - requirements/ARCHITECTURE.md
528
+ - requirements/SCRATCH.md
529
+ - requirements/dsl.md
530
+ - requirements/features
531
+ - requirements/personas
532
+ - requirements/proposals
511
533
  - requirements/tasks/challenge.md
512
534
  - requirements/tasks/iterate.md
513
535
  - requirements/tasks/optimize.md
514
536
  - requirements/tasks/tag.md
515
- - test_agent_dsl.rb
537
+ - synth/001/Makefile
538
+ - synth/001/agent.rb
539
+ - synth/001/agent.yaml
540
+ - synth/001/output.log
541
+ - synth/Makefile
542
+ - synth/README.md
516
543
  homepage: https://github.com/language-operator/language-operator
517
544
  licenses:
518
545
  - FSL-1.1-Apache-2.0
@@ -528,7 +555,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
528
555
  requirements:
529
556
  - - ">="
530
557
  - !ruby/object:Gem::Version
531
- version: 3.2.0
558
+ version: 3.4.0
532
559
  required_rubygems_version: !ruby/object:Gem::Requirement
533
560
  requirements:
534
561
  - - ">="