@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,22 @@
1
+ package "test"
2
+
3
+ role Worker { can execute }
4
+
5
+ Agent A : Worker {
6
+ on test(args: Json) {
7
+ const x = 5
8
+ return { x: x }
9
+ }
10
+ }
11
+
12
+ Team T {
13
+ a = A
14
+ }
15
+
16
+ Agent B : Worker {
17
+ uses Team T
18
+ on start(args: Json) {
19
+ const result = await send peers.event("test").role(Worker).any()({}) timeout 2s
20
+ return result
21
+ }
22
+ }
@@ -0,0 +1,196 @@
1
+ package "test.crypto.sha256"
2
+
3
+ // Import crypto-js from npm for SHA256 hashing
4
+ import "crypto-js"
5
+
6
+ role SecurityAgent { can hash, can verify }
7
+
8
+ Agent HashAgent : SecurityAgent {
9
+ on hashPassword(args: Json) {
10
+ console.log("=".repeat(60))
11
+ console.log("Crypto SHA256 Test - Password Hashing")
12
+ console.log("=".repeat(60))
13
+
14
+ const password = args.password
15
+ console.log("\nOriginal password:", password)
16
+
17
+ // Hash with SHA256 (using chained method syntax)
18
+ const hash = crypto_js.SHA256(password).toString()
19
+ console.log("SHA256 hash:", hash)
20
+
21
+ // Hash with SHA512 for comparison
22
+ const hash512 = crypto_js.SHA512(password).toString()
23
+ console.log("SHA512 hash:", hash512)
24
+
25
+ // Hash with MD5 (less secure, for demonstration)
26
+ const hashMD5 = crypto_js.MD5(password).toString()
27
+ console.log("MD5 hash:", hashMD5)
28
+
29
+ return {
30
+ password: password,
31
+ sha256: hash,
32
+ sha512: hash512,
33
+ md5: hashMD5
34
+ }
35
+ }
36
+
37
+ on verifyHash(args: Json) {
38
+ console.log("\n" + "=".repeat(60))
39
+ console.log("Hash Verification Test")
40
+ console.log("=".repeat(60))
41
+
42
+ const input = args.input
43
+ const expectedHash = args.expectedHash
44
+
45
+ console.log("\nInput:", input)
46
+ console.log("Expected hash:", expectedHash)
47
+
48
+ // Calculate hash (using chained method syntax)
49
+ const calculatedHash = crypto_js.SHA256(input).toString()
50
+ console.log("Calculated hash:", calculatedHash)
51
+
52
+ // Verify
53
+ const isValid = calculatedHash == expectedHash
54
+ console.log("Hash matches:", isValid)
55
+
56
+ return {
57
+ input: input,
58
+ expectedHash: expectedHash,
59
+ calculatedHash: calculatedHash,
60
+ isValid: isValid
61
+ }
62
+ }
63
+
64
+ on hashData(args: Json) {
65
+ console.log("\n" + "=".repeat(60))
66
+ console.log("Data Integrity Test - JSON Hashing")
67
+ console.log("=".repeat(60))
68
+
69
+ const data = args.data
70
+ console.log("\nOriginal data:", JSON.stringify(data))
71
+
72
+ // Convert to JSON string and hash (using chained method syntax)
73
+ const dataString = JSON.stringify(data)
74
+ const hash = crypto_js.SHA256(dataString).toString()
75
+ console.log("SHA256 hash:", hash)
76
+
77
+ // Simulate data tampering
78
+ const tamperedData = { name: data.name, age: 99, email: data.email }
79
+ const tamperedString = JSON.stringify(tamperedData)
80
+ const tamperedHash = crypto_js.SHA256(tamperedString).toString()
81
+ console.log("\nTampered data:", JSON.stringify(tamperedData))
82
+ console.log("Tampered hash:", tamperedHash)
83
+ console.log("Hashes match:", hash == tamperedHash)
84
+
85
+ return {
86
+ original: {
87
+ data: data,
88
+ hash: hash
89
+ },
90
+ tampered: {
91
+ data: tamperedData,
92
+ hash: tamperedHash
93
+ },
94
+ isCompromised: hash != tamperedHash
95
+ }
96
+ }
97
+
98
+ on compareAlgorithms(args: Json) {
99
+ console.log("\n" + "=".repeat(60))
100
+ console.log("Algorithm Comparison Test")
101
+ console.log("=".repeat(60))
102
+
103
+ const text = args.text
104
+ console.log("\nText to hash:", text)
105
+
106
+ // Hash with different algorithms (using chained method syntax)
107
+ const md5 = crypto_js.MD5(text).toString()
108
+ const sha1 = crypto_js.SHA1(text).toString()
109
+ const sha256 = crypto_js.SHA256(text).toString()
110
+ const sha512 = crypto_js.SHA512(text).toString()
111
+ const sha3 = crypto_js.SHA3(text).toString()
112
+
113
+ console.log("\nMD5 (32 chars):", md5)
114
+ console.log("SHA1 (40 chars):", sha1)
115
+ console.log("SHA256 (64 chars):", sha256)
116
+ console.log("SHA512 (128 chars):", sha512)
117
+ console.log("SHA3 (64 chars):", sha3)
118
+
119
+ console.log("\nHash lengths:")
120
+ console.log(" MD5:", md5.length, "characters")
121
+ console.log(" SHA1:", sha1.length, "characters")
122
+ console.log(" SHA256:", sha256.length, "characters")
123
+ console.log(" SHA512:", sha512.length, "characters")
124
+ console.log(" SHA3:", sha3.length, "characters")
125
+
126
+ return {
127
+ text: text,
128
+ hashes: {
129
+ md5: md5,
130
+ sha1: sha1,
131
+ sha256: sha256,
132
+ sha512: sha512,
133
+ sha3: sha3
134
+ }
135
+ }
136
+ }
137
+ }
138
+
139
+ Team HashTeam {
140
+ hasher = HashAgent
141
+ }
142
+
143
+ Agent Coordinator : SecurityAgent {
144
+ uses Team HashTeam
145
+
146
+ on runTests(args: Json) {
147
+ console.log("\n" + "█".repeat(60))
148
+ console.log("█" + " ".repeat(58) + "█")
149
+ console.log("█" + " Crypto-JS SHA256 Integration Test Suite".padEnd(58) + "█")
150
+ console.log("█" + " ".repeat(58) + "█")
151
+ console.log("█".repeat(60))
152
+
153
+ // Test 1: Hash password
154
+ const result1 = await send peers.event("hashPassword").role(SecurityAgent).any()({
155
+ password: "MySecurePassword123!"
156
+ }) timeout 10s
157
+
158
+ // Test 2: Verify hash
159
+ const result2 = await send peers.event("verifyHash").role(SecurityAgent).any()({
160
+ input: "MySecurePassword123!",
161
+ expectedHash: result1.sha256
162
+ }) timeout 10s
163
+
164
+ // Test 3: Hash structured data
165
+ const result3 = await send peers.event("hashData").role(SecurityAgent).any()({
166
+ data: {
167
+ name: "Alice",
168
+ age: 30,
169
+ email: "alice@example.com"
170
+ }
171
+ }) timeout 10s
172
+
173
+ // Test 4: Compare algorithms
174
+ const result4 = await send peers.event("compareAlgorithms").role(SecurityAgent).any()({
175
+ text: "The quick brown fox jumps over the lazy dog"
176
+ }) timeout 10s
177
+
178
+ console.log("\n" + "█".repeat(60))
179
+ console.log("█" + " ".repeat(58) + "█")
180
+ console.log("█" + " All Crypto Tests Completed Successfully!".padEnd(58) + "█")
181
+ console.log("█" + " ".repeat(58) + "█")
182
+ console.log("█".repeat(60))
183
+
184
+ return {
185
+ success: true,
186
+ tests: {
187
+ passwordHashing: result1,
188
+ hashVerification: result2,
189
+ dataIntegrity: result3,
190
+ algorithmComparison: result4
191
+ }
192
+ }
193
+ }
194
+ }
195
+
196
+ run Coordinator.runTests({})
@@ -0,0 +1,41 @@
1
+ // Test delegation with explicit data passing
2
+ package "test.delegation"
3
+
4
+ role Worker { can execute }
5
+
6
+ // Specialist that saves users
7
+ Agent Saver : Worker {
8
+ llm default = { provider: "openai", model: "gpt-4o-mini" }
9
+
10
+ on saveUser(args: Json) {
11
+ playbook """
12
+ Save a user to registry with key "user:${args.id}".
13
+ User data: name="${args.name}", age=${args.age}
14
+
15
+ Return: { "saved": true, "id": "${args.id}", "name": "${args.name}" }
16
+ """
17
+ }
18
+ }
19
+
20
+ // Team containing the saver
21
+ Team SaverTeam {
22
+ saver = Saver
23
+ }
24
+
25
+ // Orchestrator that delegates
26
+ Agent Orchestrator : Worker {
27
+ llm default = { provider: "openai", model: "gpt-4o-mini" }
28
+ uses Team SaverTeam
29
+
30
+ on start(args: Json) {
31
+ playbook """
32
+ Delegate the task of saving a user named "TestUser" with ID "123" and age 25.
33
+
34
+ CRITICAL: Pass data: { "id": "123", "name": "TestUser", "age": 25 }
35
+
36
+ Return the result from the delegation.
37
+ """
38
+ }
39
+ }
40
+
41
+ run Orchestrator.start({})
@@ -0,0 +1,258 @@
1
+ package "test.multi.team.routing"
2
+
3
+ // Test: Multi-team routing with peers() and peers(TeamName)
4
+ // This test validates that:
5
+ // 1. peers.event() broadcasts to all teams
6
+ // 2. peers(TeamName).event() sends only to specific team
7
+ // 3. Multiple teams can coexist and be addressed independently
8
+
9
+ role Worker { can work, can process }
10
+
11
+ // Team A workers
12
+ Agent WorkerA1 : Worker {
13
+ on work(args: Json) {
14
+ return {
15
+ from: "WorkerA1",
16
+ team: "TeamA",
17
+ data: args
18
+ }
19
+ }
20
+
21
+ on process(args: Json) {
22
+ return {
23
+ from: "WorkerA1",
24
+ team: "TeamA",
25
+ operation: "process",
26
+ data: args
27
+ }
28
+ }
29
+ }
30
+
31
+ Agent WorkerA2 : Worker {
32
+ on work(args: Json) {
33
+ return {
34
+ from: "WorkerA2",
35
+ team: "TeamA",
36
+ data: args
37
+ }
38
+ }
39
+
40
+ on process(args: Json) {
41
+ return {
42
+ from: "WorkerA2",
43
+ team: "TeamA",
44
+ operation: "process",
45
+ data: args
46
+ }
47
+ }
48
+ }
49
+
50
+ // Team B workers
51
+ Agent WorkerB1 : Worker {
52
+ on work(args: Json) {
53
+ return {
54
+ from: "WorkerB1",
55
+ team: "TeamB",
56
+ data: args
57
+ }
58
+ }
59
+
60
+ on process(args: Json) {
61
+ return {
62
+ from: "WorkerB1",
63
+ team: "TeamB",
64
+ operation: "process",
65
+ data: args
66
+ }
67
+ }
68
+ }
69
+
70
+ Agent WorkerB2 : Worker {
71
+ on work(args: Json) {
72
+ return {
73
+ from: "WorkerB2",
74
+ team: "TeamB",
75
+ data: args
76
+ }
77
+ }
78
+
79
+ on process(args: Json) {
80
+ return {
81
+ from: "WorkerB2",
82
+ team: "TeamB",
83
+ operation: "process",
84
+ data: args
85
+ }
86
+ }
87
+ }
88
+
89
+ // Team C workers
90
+ Agent WorkerC1 : Worker {
91
+ on work(args: Json) {
92
+ return {
93
+ from: "WorkerC1",
94
+ team: "TeamC",
95
+ data: args
96
+ }
97
+ }
98
+
99
+ on process(args: Json) {
100
+ return {
101
+ from: "WorkerC1",
102
+ team: "TeamC",
103
+ operation: "process",
104
+ data: args
105
+ }
106
+ }
107
+ }
108
+
109
+ // Define three teams
110
+ Team TeamA {
111
+ worker1 = WorkerA1
112
+ worker2 = WorkerA2
113
+ }
114
+
115
+ Team TeamB {
116
+ worker1 = WorkerB1
117
+ worker2 = WorkerB2
118
+ }
119
+
120
+ Team TeamC {
121
+ worker1 = WorkerC1
122
+ }
123
+
124
+ // Coordinator that uses all three teams
125
+ Agent TestCoordinator : Worker {
126
+ uses Team TeamA, TeamB, TeamC
127
+
128
+ on runTests(args: Json) {
129
+ console.log("=".repeat(60))
130
+ console.log("Multi-Team Routing Test Suite")
131
+ console.log("=".repeat(60))
132
+
133
+ // Test 1: Broadcast to all teams (peers.event)
134
+ console.log("\n[TEST 1] Broadcast to all teams with peers.event()")
135
+ console.log("-".repeat(60))
136
+ const result1 = await send peers.event("work").role(Worker).any()({
137
+ test: "broadcast",
138
+ message: "Should reach any team"
139
+ }) timeout 10s
140
+
141
+ console.log("Result:", JSON.stringify(result1, null, 2))
142
+ const test1Pass = result1 && result1.team
143
+ if (test1Pass) {
144
+ console.log("✓ TEST 1 PASSED: Received response from", result1.team)
145
+ } else {
146
+ console.log("✗ TEST 1 FAILED: No response received")
147
+ }
148
+
149
+ // Test 2: Send only to TeamA
150
+ console.log("\n[TEST 2] Send to TeamA only with peers(TeamA).event()")
151
+ console.log("-".repeat(60))
152
+ const result2 = await send peers(TeamA).event("work").role(Worker).any()({
153
+ test: "teamA",
154
+ message: "Should only reach TeamA"
155
+ }) timeout 10s
156
+
157
+ console.log("Result:", JSON.stringify(result2, null, 2))
158
+ const test2Pass = result2 && result2.team == "TeamA"
159
+ if (test2Pass) {
160
+ console.log("✓ TEST 2 PASSED: Correctly routed to TeamA")
161
+ } else {
162
+ console.log("✗ TEST 2 FAILED: Expected team=TeamA, got", result2.team)
163
+ }
164
+
165
+ // Test 3: Send only to TeamB
166
+ console.log("\n[TEST 3] Send to TeamB only with peers(TeamB).event()")
167
+ console.log("-".repeat(60))
168
+ const result3 = await send peers(TeamB).event("work").role(Worker).any()({
169
+ test: "teamB",
170
+ message: "Should only reach TeamB"
171
+ }) timeout 10s
172
+
173
+ console.log("Result:", JSON.stringify(result3, null, 2))
174
+ const test3Pass = result3 && result3.team == "TeamB"
175
+ if (test3Pass) {
176
+ console.log("✓ TEST 3 PASSED: Correctly routed to TeamB")
177
+ } else {
178
+ console.log("✗ TEST 3 FAILED: Expected team=TeamB, got", result3.team)
179
+ }
180
+
181
+ // Test 4: Send only to TeamC
182
+ console.log("\n[TEST 4] Send to TeamC only with peers(TeamC).event()")
183
+ console.log("-".repeat(60))
184
+ const result4 = await send peers(TeamC).event("work").role(Worker).any()({
185
+ test: "teamC",
186
+ message: "Should only reach TeamC"
187
+ }) timeout 10s
188
+
189
+ console.log("Result:", JSON.stringify(result4, null, 2))
190
+ const test4Pass = result4 && result4.team == "TeamC"
191
+ if (test4Pass) {
192
+ console.log("✓ TEST 4 PASSED: Correctly routed to TeamC")
193
+ } else {
194
+ console.log("✗ TEST 4 FAILED: Expected team=TeamC, got", result4.team)
195
+ }
196
+
197
+ // Test 5: Different event to specific team
198
+ console.log("\n[TEST 5] Send 'process' event to TeamA only")
199
+ console.log("-".repeat(60))
200
+ const result5 = await send peers(TeamA).event("process").role(Worker).any()({
201
+ test: "process",
202
+ value: 42
203
+ }) timeout 10s
204
+
205
+ console.log("Result:", JSON.stringify(result5, null, 2))
206
+ const test5Pass = result5 && result5.team == "TeamA" && result5.operation == "process"
207
+ if (test5Pass) {
208
+ console.log("✓ TEST 5 PASSED: Process event routed to TeamA")
209
+ } else {
210
+ console.log("✗ TEST 5 FAILED: Expected TeamA process event")
211
+ }
212
+
213
+ // Test 6: Verify isolation - TeamB should not receive TeamA messages
214
+ console.log("\n[TEST 6] Verify team isolation")
215
+ console.log("-".repeat(60))
216
+ const resultA = await send peers(TeamA).event("work").role(Worker).any()({
217
+ target: "TeamA"
218
+ }) timeout 10s
219
+ const resultB = await send peers(TeamB).event("work").role(Worker).any()({
220
+ target: "TeamB"
221
+ }) timeout 10s
222
+
223
+ console.log("TeamA result:", JSON.stringify(resultA, null, 2))
224
+ console.log("TeamB result:", JSON.stringify(resultB, null, 2))
225
+ const test6Pass = resultA.team == "TeamA" && resultB.team == "TeamB"
226
+ if (test6Pass) {
227
+ console.log("✓ TEST 6 PASSED: Teams are properly isolated")
228
+ } else {
229
+ console.log("✗ TEST 6 FAILED: Team isolation failed")
230
+ }
231
+
232
+ // Summary
233
+ console.log("\n" + "=".repeat(60))
234
+ console.log("Test Summary")
235
+ console.log("=".repeat(60))
236
+ const allPassed = test1Pass && test2Pass && test3Pass && test4Pass && test5Pass && test6Pass
237
+
238
+ if (allPassed) {
239
+ console.log("\n✓ ALL 6 TESTS PASSED!")
240
+ } else {
241
+ console.log("\n✗ SOME TESTS FAILED - See results above")
242
+ }
243
+
244
+ return {
245
+ success: allPassed,
246
+ results: {
247
+ test1: test1Pass,
248
+ test2: test2Pass,
249
+ test3: test3Pass,
250
+ test4: test4Pass,
251
+ test5: test5Pass,
252
+ test6: test6Pass
253
+ }
254
+ }
255
+ }
256
+ }
257
+
258
+ run TestCoordinator.runTests({})
@@ -0,0 +1,35 @@
1
+ // Test: Error when no agent can handle an event
2
+
3
+ package "test.no.handler"
4
+
5
+ role Worker { can execute }
6
+
7
+ Agent SimpleWorker : Worker {
8
+ on doWork(args: Json) {
9
+ playbook """
10
+ Do some work
11
+ Return JSON: { "result": "done" }
12
+ """
13
+ }
14
+ }
15
+
16
+ Team SimpleTeam {
17
+ worker = SimpleWorker
18
+ }
19
+
20
+ Agent Requester : Worker {
21
+ uses Team SimpleTeam
22
+
23
+ on testNoHandler(args: Json) {
24
+ console.log("Testing error when no agent can handle event...")
25
+
26
+ // Try to send an event that no agent in the team can handle
27
+ const result = await send peers.event("nonExistentEvent").any()({
28
+ data: "test"
29
+ }) timeout 5s
30
+
31
+ return result
32
+ }
33
+ }
34
+
35
+ run Requester.testNoHandler({})
@@ -0,0 +1,67 @@
1
+ package "test.npm.import"
2
+
3
+ // Import lodash from node_modules
4
+ import "lodash"
5
+
6
+ role Worker { can work }
7
+
8
+ Agent DataProcessor : Worker {
9
+ on process(args: Json) {
10
+ console.log("=".repeat(60))
11
+ console.log("Testing NPM Package Import (lodash)")
12
+ console.log("=".repeat(60))
13
+
14
+ // Test chunk
15
+ const chunked = lodash.chunk([1, 2, 3, 4, 5, 6, 7, 8], 3)
16
+ console.log("\nTest 1: chunk([1-8], 3) =", JSON.stringify(chunked))
17
+
18
+ // Test uniq
19
+ const unique = lodash.uniq([1, 2, 2, 3, 3, 3, 4, 5, 5])
20
+ console.log("Test 2: uniq([1,2,2,3,3,3,4,5,5]) =", JSON.stringify(unique))
21
+
22
+ // Test pick
23
+ const obj = { a: 1, b: 2, c: 3, d: 4 }
24
+ const picked = lodash.pick(obj, ["a", "c"])
25
+ console.log("Test 3: pick({a:1,b:2,c:3,d:4}, ['a','c']) =", JSON.stringify(picked))
26
+
27
+ // Test sum
28
+ const total = lodash.sum([1, 2, 3, 4, 5])
29
+ console.log("Test 4: sum([1,2,3,4,5]) =", total)
30
+
31
+ // Test mean
32
+ const avg = lodash.mean([10, 20, 30, 40, 50])
33
+ console.log("Test 5: mean([10,20,30,40,50]) =", avg)
34
+
35
+ // Test reverse
36
+ const reversed = lodash.reverse([1, 2, 3, 4, 5])
37
+ console.log("Test 6: reverse([1,2,3,4,5]) =", JSON.stringify(reversed))
38
+
39
+ // Test max
40
+ const maximum = lodash.max([10, 50, 30, 20, 40])
41
+ console.log("Test 7: max([10,50,30,20,40]) =", maximum)
42
+
43
+ // Test min
44
+ const minimum = lodash.min([10, 50, 30, 20, 40])
45
+ console.log("Test 8: min([10,50,30,20,40]) =", minimum)
46
+
47
+ console.log("\n" + "=".repeat(60))
48
+ console.log("All lodash tests completed!")
49
+ console.log("=".repeat(60))
50
+
51
+ return {
52
+ success: true,
53
+ tests: {
54
+ chunked: chunked,
55
+ unique: unique,
56
+ picked: picked,
57
+ sum: total,
58
+ mean: avg,
59
+ reversed: reversed,
60
+ max: maximum,
61
+ min: minimum
62
+ }
63
+ }
64
+ }
65
+ }
66
+
67
+ run DataProcessor.process({})
@@ -0,0 +1,10 @@
1
+ package "test"
2
+
3
+ role Worker { can execute }
4
+
5
+ Agent A : Worker {
6
+ on test(args: Json) {
7
+ const x = 5
8
+ return { x: x }
9
+ }
10
+ }
@@ -0,0 +1,59 @@
1
+ package "test.peers.team"
2
+
3
+ role Worker { can work }
4
+
5
+ Agent WorkerA : Worker {
6
+ on work(args: Json) {
7
+ return { from: "WorkerA", data: args }
8
+ }
9
+ }
10
+
11
+ Agent WorkerB : Worker {
12
+ on work(args: Json) {
13
+ return { from: "WorkerB", data: args }
14
+ }
15
+ }
16
+
17
+ Team TeamA {
18
+ worker = WorkerA
19
+ }
20
+
21
+ Team TeamB {
22
+ worker = WorkerB
23
+ }
24
+
25
+ Agent Coordinator : Worker {
26
+ uses Team TeamA, TeamB
27
+
28
+ on coordinate(args: Json) {
29
+ // Test 1: Send to all teams via common router
30
+ console.log("Test 1: Send to all teams (peers.event)")
31
+ const resultAll = await send peers.event("work").role(Worker).any()({
32
+ message: "to all teams"
33
+ }) timeout 10s
34
+ console.log("Result from all:", JSON.stringify(resultAll))
35
+
36
+ // Test 2: Send only to TeamA
37
+ console.log("\nTest 2: Send to TeamA only (peers(TeamA).event)")
38
+ const resultTeamA = await send peers(TeamA).event("work").role(Worker).any()({
39
+ message: "to TeamA only"
40
+ }) timeout 10s
41
+ console.log("Result from TeamA:", JSON.stringify(resultTeamA))
42
+
43
+ // Test 3: Send only to TeamB
44
+ console.log("\nTest 3: Send to TeamB only (peers(TeamB).event)")
45
+ const resultTeamB = await send peers(TeamB).event("work").role(Worker).any()({
46
+ message: "to TeamB only"
47
+ }) timeout 10s
48
+ console.log("Result from TeamB:", JSON.stringify(resultTeamB))
49
+
50
+ return {
51
+ success: true,
52
+ allTeams: resultAll,
53
+ teamA: resultTeamA,
54
+ teamB: resultTeamB
55
+ }
56
+ }
57
+ }
58
+
59
+ run Coordinator.coordinate({ test: true })