@koi-language/koi 1.0.0

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 (85) hide show
  1. package/QUICKSTART.md +89 -0
  2. package/README.md +545 -0
  3. package/examples/actions-demo.koi +177 -0
  4. package/examples/cache-test.koi +29 -0
  5. package/examples/calculator.koi +61 -0
  6. package/examples/clear-registry.js +33 -0
  7. package/examples/clear-registry.koi +30 -0
  8. package/examples/code-introspection-test.koi +149 -0
  9. package/examples/counter.koi +132 -0
  10. package/examples/delegation-test.koi +52 -0
  11. package/examples/directory-import-test.koi +84 -0
  12. package/examples/hello-world-claude.koi +52 -0
  13. package/examples/hello-world.koi +52 -0
  14. package/examples/hello.koi +24 -0
  15. package/examples/mcp-example.koi +70 -0
  16. package/examples/multi-event-handler-test.koi +144 -0
  17. package/examples/new-import-test.koi +89 -0
  18. package/examples/pipeline.koi +162 -0
  19. package/examples/registry-demo.koi +184 -0
  20. package/examples/registry-playbook-demo.koi +162 -0
  21. package/examples/registry-playbook-email-compositor-2.koi +140 -0
  22. package/examples/registry-playbook-email-compositor.koi +140 -0
  23. package/examples/sentiment.koi +90 -0
  24. package/examples/simple.koi +48 -0
  25. package/examples/skill-import-test.koi +76 -0
  26. package/examples/skills/advanced/index.koi +95 -0
  27. package/examples/skills/math-operations.koi +69 -0
  28. package/examples/skills/string-operations.koi +56 -0
  29. package/examples/task-chaining-demo.koi +244 -0
  30. package/examples/test-await.koi +22 -0
  31. package/examples/test-crypto-sha256.koi +196 -0
  32. package/examples/test-delegation.koi +41 -0
  33. package/examples/test-multi-team-routing.koi +258 -0
  34. package/examples/test-no-handler.koi +35 -0
  35. package/examples/test-npm-import.koi +67 -0
  36. package/examples/test-parse.koi +10 -0
  37. package/examples/test-peers-with-team.koi +59 -0
  38. package/examples/test-permissions-fail.koi +20 -0
  39. package/examples/test-permissions.koi +36 -0
  40. package/examples/test-simple-registry.koi +31 -0
  41. package/examples/test-typescript-import.koi +64 -0
  42. package/examples/test-uses-team-syntax.koi +25 -0
  43. package/examples/test-uses-team.koi +31 -0
  44. package/examples/utils/calculator.test.ts +144 -0
  45. package/examples/utils/calculator.ts +56 -0
  46. package/examples/utils/math-helpers.js +50 -0
  47. package/examples/utils/math-helpers.ts +55 -0
  48. package/examples/web-delegation-demo.koi +165 -0
  49. package/package.json +78 -0
  50. package/src/cli/koi.js +793 -0
  51. package/src/compiler/build-optimizer.js +447 -0
  52. package/src/compiler/cache-manager.js +274 -0
  53. package/src/compiler/import-resolver.js +369 -0
  54. package/src/compiler/parser.js +7542 -0
  55. package/src/compiler/transpiler.js +1105 -0
  56. package/src/compiler/typescript-transpiler.js +148 -0
  57. package/src/grammar/koi.pegjs +767 -0
  58. package/src/runtime/action-registry.js +172 -0
  59. package/src/runtime/actions/call-skill.js +45 -0
  60. package/src/runtime/actions/format.js +115 -0
  61. package/src/runtime/actions/print.js +42 -0
  62. package/src/runtime/actions/registry-delete.js +37 -0
  63. package/src/runtime/actions/registry-get.js +37 -0
  64. package/src/runtime/actions/registry-keys.js +33 -0
  65. package/src/runtime/actions/registry-search.js +34 -0
  66. package/src/runtime/actions/registry-set.js +50 -0
  67. package/src/runtime/actions/return.js +31 -0
  68. package/src/runtime/actions/send-message.js +58 -0
  69. package/src/runtime/actions/update-state.js +36 -0
  70. package/src/runtime/agent.js +1368 -0
  71. package/src/runtime/cli-logger.js +205 -0
  72. package/src/runtime/incremental-json-parser.js +201 -0
  73. package/src/runtime/index.js +33 -0
  74. package/src/runtime/llm-provider.js +1372 -0
  75. package/src/runtime/mcp-client.js +1171 -0
  76. package/src/runtime/planner.js +273 -0
  77. package/src/runtime/registry-backends/keyv-sqlite.js +215 -0
  78. package/src/runtime/registry-backends/local.js +260 -0
  79. package/src/runtime/registry.js +162 -0
  80. package/src/runtime/role.js +14 -0
  81. package/src/runtime/router.js +395 -0
  82. package/src/runtime/runtime.js +113 -0
  83. package/src/runtime/skill-selector.js +173 -0
  84. package/src/runtime/skill.js +25 -0
  85. package/src/runtime/team.js +162 -0
@@ -0,0 +1,84 @@
1
+ // ============================================================
2
+ // Directory Import Test
3
+ // Tests importing from directories (looks for index.koi)
4
+ // ============================================================
5
+
6
+ package "demo.koi.directory"
7
+
8
+ // Import from directory - automatically finds index.koi
9
+ import "./skills/advanced"
10
+
11
+ role Worker { can work }
12
+
13
+ // Agent that uses skills from the directory import
14
+ Agent StatisticsProcessor : Worker {
15
+ llm default = { provider: "openai", model: "gpt-4o-mini", temperature: 0.1, max_tokens: 300 }
16
+ uses Skill StatisticalAnalysis
17
+
18
+ on process(args: Json) {
19
+ playbook """
20
+ Process statistical analysis for: ${JSON.stringify(args)}
21
+
22
+ Pass the "numbers" array to the tool and return the result.
23
+ """
24
+ }
25
+ }
26
+
27
+ Team WorkerTeam {
28
+ processor = StatisticsProcessor
29
+ analyzer = DataAnalyzer // Agent from the imported directory
30
+ }
31
+
32
+ // Demo runner
33
+ Agent DemoRunner : Worker {
34
+ uses Team WorkerTeam
35
+
36
+ on runTest(args: Json) {
37
+ console.log("╔════════════════════════════════════════════╗")
38
+ console.log("║ Directory Import Test ║")
39
+ console.log("║ import \"./skills/advanced\" ║")
40
+ console.log("╚════════════════════════════════════════════╝\n")
41
+
42
+ // Test 1: Calculate mean using skill directly
43
+ console.log("📋 Test 1: Calculate mean of [10, 20, 30, 40, 50]")
44
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
45
+
46
+ const meanResult =
47
+ await send peers.event("process").role(Worker).any()({
48
+ operation: "mean",
49
+ numbers: [10, 20, 30, 40, 50]
50
+ }) timeout 10s
51
+
52
+ console.log("Result:", JSON.stringify(meanResult, null, 2))
53
+
54
+ // Test 2: Calculate median
55
+ console.log("\n📋 Test 2: Calculate median of [1, 3, 5, 7, 9, 11]")
56
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
57
+
58
+ const medianResult =
59
+ await send peers.event("process").role(Worker).any()({
60
+ operation: "median",
61
+ numbers: [1, 3, 5, 7, 9, 11]
62
+ }) timeout 10s
63
+
64
+ console.log("Result:", JSON.stringify(medianResult, null, 2))
65
+
66
+ // Test 3: Use the imported DataAnalyzer agent
67
+ console.log("\n📋 Test 3: Full analysis using DataAnalyzer agent!!!!")
68
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
69
+
70
+ const analysisResult =
71
+ await send peers.event("analyze").role(DataScientist).any()({
72
+ numbers: [15, 25, 35, 45, 55, 65, 75]
73
+ }) timeout 10s
74
+
75
+ console.log("Result:", JSON.stringify(analysisResult, null, 2))
76
+
77
+ return {
78
+ success: true,
79
+ tests_completed: 3
80
+ }
81
+ }
82
+ }
83
+
84
+ run DemoRunner.runTest({})
@@ -0,0 +1,52 @@
1
+ // ============================================================
2
+ // Koi — Hello World with Claude
3
+ // Using Anthropic's Claude instead of OpenAI
4
+ // ============================================================
5
+
6
+ package "demo.koi.helloworld.claude"
7
+
8
+ role Worker { can execute }
9
+
10
+ // Agent with playbook using Claude
11
+ Agent Greeter : Worker {
12
+ llm default = { provider: "anthropic", model: "claude-3-5-haiku-20241022", temperature: 0.7, max_tokens: 200 }
13
+
14
+ on greet(args: Json) {
15
+ playbook """
16
+ You are a friendly greeter. Generate a warm, creative greeting for the person whose name is in args.name.
17
+
18
+ Return a JSON object with this exact structure:
19
+ {
20
+ "greeting": "Your creative greeting here",
21
+ "language": "english",
22
+ "style": "friendly"
23
+ }
24
+
25
+ Make the greeting unique and warm, but keep it under 50 words.
26
+ """
27
+ }
28
+ }
29
+
30
+ Team HelloTeam {
31
+ greeter = Greeter
32
+ }
33
+
34
+ // Orchestrator with procedural code
35
+ Agent Orchestrator : Worker {
36
+ uses Team HelloTeam
37
+
38
+ on start(args: Json) {
39
+ const name = args.name
40
+
41
+ const result =
42
+ await send peers.event("greet").role(Worker).any()({ name: name }) timeout 30s
43
+
44
+ return {
45
+ success: true,
46
+ name: name,
47
+ response: result
48
+ }
49
+ }
50
+ }
51
+
52
+ run Orchestrator.start({ name: "World" })
@@ -0,0 +1,52 @@
1
+ // ============================================================
2
+ // Koi — Hello World with LLM Playbook
3
+ // Simple example showing playbook execution with real LLM
4
+ // ============================================================
5
+
6
+ package "demo.koi.helloworld"
7
+
8
+ role Worker { can execute }
9
+
10
+ // Agent with playbook only (will execute with LLM)
11
+ Agent Greeter : Worker {
12
+ llm default = { provider: "openai", model: "gpt-4o-mini", temperature: 0.7, max_tokens: 200 }
13
+
14
+ on greet(args: Json) {
15
+ playbook """
16
+ You are a friendly greeter. Generate a warm, creative greeting for the person whose name is in args.name.
17
+
18
+ Return a JSON object with this exact structure:
19
+ {
20
+ "greeting": "Your creative greeting here",
21
+ "language": "english",
22
+ "style": "friendly"
23
+ }
24
+
25
+ Make the greeting unique and warm, but keep it under 50 words.
26
+ """
27
+ }
28
+ }
29
+
30
+ Team HelloTeam {
31
+ greeter = Greeter
32
+ }
33
+
34
+ // Orchestrator with procedural code
35
+ Agent Orchestrator : Worker {
36
+ uses Team HelloTeam
37
+
38
+ on start(args: Json) {
39
+ const name = args.name
40
+
41
+ const result =
42
+ await send peers.event("greet").role(Worker).any()({ name: name }) timeout 30s
43
+
44
+ return {
45
+ success: true,
46
+ name: name,
47
+ response: result
48
+ }
49
+ }
50
+ }
51
+
52
+ run Orchestrator.start({ name: "World" })
@@ -0,0 +1,24 @@
1
+ // Minimal test
2
+ package "test"
3
+
4
+ role Worker { can execute }
5
+
6
+ Agent Test : Worker {
7
+ on test(args: Json) {
8
+ return { ok: true }
9
+ }
10
+ }
11
+
12
+ Team T {
13
+ t = Test
14
+ }
15
+
16
+ Agent Orch : Worker {
17
+ uses Team T
18
+ on start(args: Json) {
19
+ const r = await send peers.event("test").role(Worker).any()({}) timeout 2s
20
+ return r
21
+ }
22
+ }
23
+
24
+ run Orch.start({})
@@ -0,0 +1,70 @@
1
+ // ============================================================
2
+ // Koi — MCP (Model Context Protocol) Example
3
+ // Demonstrates using MCP addresses to reference remote agents
4
+ // ============================================================
5
+
6
+ package "demo.koi.mcp"
7
+
8
+ role Worker { can execute }
9
+ role Lead { can delegate }
10
+
11
+ // Local agent
12
+ Agent LocalProcessor : Worker {
13
+ on process(args: Json) {
14
+ const data = args.data
15
+ const processed = "LOCAL: " + data
16
+ return { result: processed, source: "local" }
17
+ }
18
+ }
19
+
20
+ // Team with both local and remote (MCP) agents
21
+ Team HybridTeam {
22
+ // Regular local agent
23
+ local = LocalProcessor
24
+
25
+ // Remote agents via MCP addresses
26
+ // Format: mcp://server/path
27
+ remote1 = mcp://agent.local/processor
28
+ remote2 = mcp://service.local/analyzer
29
+ }
30
+
31
+ // Orchestrator that uses both local and remote agents
32
+ Agent Orchestrator : Lead {
33
+ uses Team HybridTeam
34
+
35
+ on start(args: Json) {
36
+ const data = args.data
37
+
38
+ // This will try local first, then MCP agents
39
+ const result =
40
+ await send peers.event("process").role(Worker).any()({ data: data }) timeout 10s
41
+
42
+ return {
43
+ success: true,
44
+ result: result
45
+ }
46
+ }
47
+
48
+ on processAll(args: Json) {
49
+ const data = args.data
50
+
51
+ // Process with ALL agents (local + MCP)
52
+ const results =
53
+ await send peers.event("process").role(Worker).all()({ data: data }) timeout 15s
54
+
55
+ return {
56
+ success: true,
57
+ count: 3,
58
+ results: results
59
+ }
60
+ }
61
+ }
62
+
63
+ // Example with MCP skill reference
64
+ Team DistributedTeam {
65
+ orchestrator = Orchestrator
66
+ // Reference a remote skill
67
+ sentiment = mcp://skills.local/sentiment-analysis
68
+ }
69
+
70
+ run Orchestrator.start({ data: "Hello from Koi with MCP support!" })
@@ -0,0 +1,144 @@
1
+ package "demo.multi.event"
2
+
3
+ role Calculator { can calculate }
4
+ role Coordinator { can coordinate }
5
+
6
+ // Agent con múltiples event handlers
7
+ // Cada handler tiene su propio affordance (del playbook)
8
+ Agent StatisticsCalculator : Calculator {
9
+ llm default = {
10
+ provider: "openai",
11
+ model: "gpt-4o-mini",
12
+ temperature: 0.1
13
+ }
14
+
15
+ // Event handler para calcular media
16
+ on mean(args: Json) {
17
+ playbook """
18
+ Calculate the arithmetic mean (average) of the numbers: ${JSON.stringify(args.numbers)}
19
+
20
+ Sum all numbers and divide by the count.
21
+ IMPORTANT: Actually perform the calculation and return ONLY: { "operation": "mean", "result": <numeric_value> }
22
+ """
23
+ }
24
+
25
+ // Event handler para calcular mediana
26
+ on median(args: Json) {
27
+ playbook """
28
+ Calculate the median (middle value) of ${JSON.stringify(args.numbers)}
29
+
30
+ Sort numbers, find middle. If even count, average two middle values.
31
+ Return: { "operation": "median", "result": <numeric_value> }
32
+ """
33
+ }
34
+
35
+ // Event handler para calcular desviación estándar
36
+ on stddev(args: Json) {
37
+ playbook """
38
+ Calculate the standard deviation for ${JSON.stringify(args.numbers)}
39
+
40
+ DO NOT return a plan. Perform the actual calculation and return only the result.
41
+ Formula: sqrt(sum((x - mean)²) / n)
42
+ Return ONLY: { "operation": "stddev", "result": <numeric_result> }
43
+ """
44
+ }
45
+ }
46
+
47
+ Team CalculatorTeam {
48
+ calculator = StatisticsCalculator
49
+ }
50
+
51
+ // Orchestrator que decide qué evento enviar basándose en la intención
52
+ Agent Orchestrator : Coordinator {
53
+ llm default = {
54
+ provider: "openai",
55
+ model: "gpt-4o-mini",
56
+ temperature: 0.1
57
+ }
58
+
59
+ uses Team CalculatorTeam
60
+
61
+ on process(args: Json) {
62
+ playbook """
63
+ Process this statistical request: ${JSON.stringify(args)}
64
+
65
+ You have access to Calculator agents with these event handlers:
66
+ - "mean" event: Calculate arithmetic mean/average
67
+ - "median" event: Calculate median (middle value)
68
+ - "stddev" event: Calculate standard deviation (measure of spread)
69
+
70
+ Based on the user's request description in "operation", determine which statistical calculation is needed.
71
+ Then delegate by returning an action:
72
+
73
+ {
74
+ "actions": [
75
+ {
76
+ "title": "Calculating <operation>",
77
+ "intent": "<choose: calculate mean | calculate median | calculate standard deviation>",
78
+ "data": { "numbers": ${JSON.stringify(args.numbers)} }
79
+ }
80
+ ]
81
+ }
82
+
83
+ The system will route to the appropriate event handler based on the intent.
84
+ """
85
+ }
86
+ }
87
+
88
+ Team OrchestratorTeam {
89
+ orchestrator = Orchestrator
90
+ }
91
+
92
+ Agent Main : Coordinator {
93
+ uses Team OrchestratorTeam
94
+
95
+ on start(args: Json) {
96
+ console.log("╔════════════════════════════════════════════╗")
97
+ console.log("║ Multi Event Handler Test ║")
98
+ console.log("║ Semantic routing to event handlers ║")
99
+ console.log("╚════════════════════════════════════════════╝\n")
100
+
101
+ // Test 1: Request mean calculation
102
+ console.log("📋 Test 1: Calculate average of numbers")
103
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
104
+
105
+ const meanResult =
106
+ await send peers.event("process").role(Coordinator).any()({
107
+ operation: "calculate the average",
108
+ numbers: [10, 20, 30, 40, 50]
109
+ }) timeout 30s
110
+
111
+ console.log("Result:", JSON.stringify(meanResult, null, 2))
112
+
113
+ // Test 2: Request median calculation
114
+ console.log("\n📋 Test 2: Find the middle value")
115
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
116
+
117
+ const medianResult =
118
+ await send peers.event("process").role(Coordinator).any()({
119
+ operation: "find the middle value",
120
+ numbers: [1, 3, 5, 7, 9, 11]
121
+ }) timeout 30s
122
+
123
+ console.log("Result:", JSON.stringify(medianResult, null, 2))
124
+
125
+ // Test 3: Request standard deviation
126
+ console.log("\n📋 Test 3: Calculate spread of data")
127
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
128
+
129
+ const stddevResult =
130
+ await send peers.event("process").role(Coordinator).any()({
131
+ operation: "measure how spread out the numbers are",
132
+ numbers: [10, 20, 30, 40, 50]
133
+ }) timeout 30s
134
+
135
+ console.log("Result:", JSON.stringify(stddevResult, null, 2))
136
+
137
+ return {
138
+ success: true,
139
+ tests_completed: 3
140
+ }
141
+ }
142
+ }
143
+
144
+ run Main.start({})
@@ -0,0 +1,89 @@
1
+ // ============================================================
2
+ // New Import System Test
3
+ // Tests the new simplified import syntax
4
+ // ============================================================
5
+
6
+ package "demo.koi.new.import"
7
+
8
+ // New import syntax - imports everything (Skills, Agents, Roles, Teams)
9
+ import "./skills/math-operations.koi"
10
+ import "@koi-lang/common-skills"
11
+
12
+ role Worker { can work }
13
+
14
+ // Agent that uses imported skills from both local and npm package
15
+ Agent DataProcessor : Worker {
16
+ llm default = { provider: "openai", model: "gpt-4o-mini", temperature: 0.1, max_tokens: 300 }
17
+ // Comma-separated syntax (cleaner!)
18
+ uses Skill MathOperations, DataValidation, DataTransformation
19
+
20
+ on process(args: Json) {
21
+ playbook """
22
+ Process the request: ${JSON.stringify(args)}
23
+
24
+ Use the available tools (math, validation, transformation) to complete the task.
25
+ Return the result as JSON.
26
+ """
27
+ }
28
+ }
29
+
30
+ Team WorkerTeam {
31
+ processor = DataProcessor
32
+ // Also use the imported EmailValidator agent
33
+ emailValidator = EmailValidator
34
+ }
35
+
36
+ // Demo runner
37
+ Agent DemoRunner : Worker {
38
+ uses Team WorkerTeam
39
+
40
+ on runTest(args: Json) {
41
+ console.log("╔════════════════════════════════════════════╗")
42
+ console.log("║ New Import System Test ║")
43
+ console.log("║ Local files + npm packages ║")
44
+ console.log("╚════════════════════════════════════════════╝\n")
45
+
46
+ // Test 1: Use local skill (math)
47
+ console.log("📋 Test 1: Math operation from local skill")
48
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
49
+
50
+ const mathResult =
51
+ await send peers.event("process").role(Worker).any()({
52
+ operation: "add",
53
+ a: 15,
54
+ b: 27
55
+ }) timeout 10s
56
+
57
+ console.log("Result:", JSON.stringify(mathResult, null, 2))
58
+
59
+ // Test 2: Use npm package skill (validation)
60
+ console.log("\n📋 Test 2: Email validation from npm package")
61
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
62
+
63
+ const validationResult =
64
+ await send peers.event("process").role(Worker).any()({
65
+ operation: "validateEmail",
66
+ email: "test@example.com"
67
+ }) timeout 10s
68
+
69
+ console.log("Result:", JSON.stringify(validationResult, null, 2))
70
+
71
+ // Test 3: Use imported agent directly
72
+ console.log("\n📋 Test 3: Using imported EmailValidator agent")
73
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
74
+
75
+ const agentResult =
76
+ await send peers.event("validate").role(Validator).any()({
77
+ email: "invalid-email"
78
+ }) timeout 10s
79
+
80
+ console.log("Result:", JSON.stringify(agentResult, null, 2))
81
+
82
+ return {
83
+ success: true,
84
+ tests_completed: 3
85
+ }
86
+ }
87
+ }
88
+
89
+ run DemoRunner.runTest({})
@@ -0,0 +1,162 @@
1
+ // ============================================================
2
+ // Koi — Data Pipeline Example
3
+ // Shows multi-stage data processing
4
+ // ============================================================
5
+
6
+ package "demo.koi.pipeline"
7
+
8
+ role Worker { can execute }
9
+ role Reviewer { can critique }
10
+ role Lead { can delegate }
11
+
12
+ Agent Extractor : Worker {
13
+ llm default = { provider: "openai", model: "gpt-4o-mini", temperature: 0.3, max_tokens: 300 }
14
+
15
+ on extract(args: Json) {
16
+ playbook """
17
+ You are a data extraction specialist. Extract and structure the raw input data from args.raw.
18
+
19
+ Your task:
20
+ 1. Parse the raw input text
21
+ 2. Identify key information (content, metadata, timestamp)
22
+ 3. Calculate the text length
23
+ 4. Structure it into a clean data object
24
+
25
+ Return ONLY this exact JSON structure (no markdown, no explanations):
26
+ {
27
+ "extracted": true,
28
+ "data": {
29
+ "text": "the raw text content",
30
+ "length": 42,
31
+ "timestamp": "2026-01-21"
32
+ }
33
+ }
34
+
35
+ Use the current date for timestamp. Be precise and thorough.
36
+ """
37
+ }
38
+ }
39
+
40
+ Agent Transformer : Worker {
41
+ llm default = { provider: "openai", model: "gpt-4o-mini", temperature: 0.3, max_tokens: 300 }
42
+
43
+ on transform(args: Json) {
44
+ playbook """
45
+ You are a data transformation specialist. Transform the extracted data from args.data into an enriched format.
46
+
47
+ Your task:
48
+ 1. Take the extracted data (text, length, timestamp)
49
+ 2. Apply business rules and enrichments
50
+ 3. Add a "processed_at" field with the timestamp
51
+ 4. Mark the data as enriched
52
+
53
+ Return ONLY this exact JSON structure (no markdown, no explanations):
54
+ {
55
+ "transformed": true,
56
+ "data": {
57
+ "text": "the original text",
58
+ "length": 42,
59
+ "enriched": true,
60
+ "processed_at": "timestamp from args.data"
61
+ }
62
+ }
63
+
64
+ Preserve all original data fields while adding enrichment.
65
+ """
66
+ }
67
+ }
68
+
69
+ Agent Validator : Reviewer {
70
+ llm default = { provider: "openai", model: "gpt-4o-mini", temperature: 0.1, max_tokens: 200 }
71
+
72
+ on validate(args: Json) {
73
+ playbook """
74
+ You are a data quality validator. Validate that the transformed data in args.data meets quality requirements.
75
+
76
+ Your validation rules:
77
+ 1. Check that "enriched" field is true
78
+ 2. Ensure all required fields are present (text, length, enriched, processed_at)
79
+ 3. Verify data types are correct
80
+ 4. Check that text is not empty and length is positive
81
+
82
+ Return ONLY this exact JSON structure (no markdown, no explanations):
83
+ {
84
+ "valid": true,
85
+ "message": "Data passes validation"
86
+ }
87
+
88
+ OR if validation fails:
89
+ {
90
+ "valid": false,
91
+ "message": "Specific reason for failure"
92
+ }
93
+
94
+ Be strict but fair in validation.
95
+ """
96
+ }
97
+ }
98
+
99
+ Agent Loader : Worker {
100
+ llm default = { provider: "openai", model: "gpt-4o-mini", temperature: 0.2, max_tokens: 250 }
101
+
102
+ on load(args: Json) {
103
+ playbook """
104
+ You are a data loading specialist. Load the validated data from args.data into the final destination.
105
+
106
+ Your task:
107
+ 1. Take the validated data
108
+ 2. Prepare it for storage in the database
109
+ 3. Return metadata about the load operation
110
+ 4. Include the full data in the response
111
+
112
+ Return ONLY this exact JSON structure (no markdown, no explanations):
113
+ {
114
+ "loaded": true,
115
+ "records": 1,
116
+ "destination": "database",
117
+ "data": { ...the full data from args.data... }
118
+ }
119
+
120
+ Confirm successful loading with appropriate metadata.
121
+ """
122
+ }
123
+ }
124
+
125
+ Team Pipeline {
126
+ extractor = Extractor
127
+ transformer = Transformer
128
+ validator = Validator
129
+ loader = Loader
130
+ }
131
+
132
+ Agent Orchestrator : Lead {
133
+ uses Team Pipeline
134
+
135
+ on start(args: Json) {
136
+ const raw = args.input
137
+
138
+ const extracted =
139
+ await send peers.event("extract").role(Worker).any()({ raw: raw }) timeout 5s
140
+
141
+ const transformed =
142
+ await send peers.event("transform").role(Worker).any()({ data: extracted.data }) timeout 5s
143
+
144
+ const validation =
145
+ await send peers.event("validate").role(Reviewer).any()({ data: transformed.data }) timeout 5s
146
+
147
+ if validation.valid == false {
148
+ return { ok: false, error: validation.message }
149
+ }
150
+
151
+ const loaded =
152
+ await send peers.event("load").role(Worker).any()({ data: transformed.data }) timeout 5s
153
+
154
+ return {
155
+ ok: true,
156
+ pipeline: "complete",
157
+ result: loaded
158
+ }
159
+ }
160
+ }
161
+
162
+ run Orchestrator.start({ input: "Sample data to process through pipeline" })