@koi-language/koi 1.0.5 → 1.1.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 (113) hide show
  1. package/README.md +4 -125
  2. package/examples/.build/agent-dialogue.ts +138 -0
  3. package/examples/.build/agent-dialogue.ts.map +1 -0
  4. package/examples/.build/chess.ts +77 -0
  5. package/examples/.build/chess.ts.map +1 -0
  6. package/examples/.build/delegation-test.ts +140 -0
  7. package/examples/.build/delegation-test.ts.map +1 -0
  8. package/examples/.build/dialog-demo.ts +77 -0
  9. package/examples/.build/dialog-demo.ts.map +1 -0
  10. package/examples/.build/hello-world.ts +77 -0
  11. package/examples/.build/hello-world.ts.map +1 -0
  12. package/examples/.build/lover-dialog-demo.ts +77 -0
  13. package/examples/.build/lover-dialog-demo.ts.map +1 -0
  14. package/examples/.build/package.json +3 -0
  15. package/examples/.build/registry-interactive-demo.ts +202 -0
  16. package/examples/.build/registry-interactive-demo.ts.map +1 -0
  17. package/examples/.build/registry-playbook-demo.ts +201 -0
  18. package/examples/.build/registry-playbook-demo.ts.map +1 -0
  19. package/examples/.build/tic-tac-toe.ts +77 -0
  20. package/examples/.build/tic-tac-toe.ts.map +1 -0
  21. package/examples/actions-demo.koi +8 -9
  22. package/examples/activists-dialogue.koi +75 -0
  23. package/examples/agent-dialogue.koi +66 -0
  24. package/examples/chess.koi +19 -0
  25. package/examples/counter.koi +20 -69
  26. package/examples/delegation-test.koi +16 -18
  27. package/examples/dialog-demo.koi +20 -0
  28. package/examples/hello-world.koi +7 -43
  29. package/examples/mcp-stdio-demo.koi +29 -0
  30. package/examples/memory-test.koi +49 -0
  31. package/examples/mobile-mcp-demo.koi +32 -0
  32. package/examples/multi-event-handler-test.koi +16 -18
  33. package/examples/pipeline.koi +15 -17
  34. package/examples/prompt-demo.koi +20 -0
  35. package/examples/{registry-playbook-email-compositor.koi → registry-interactive-demo.koi} +27 -27
  36. package/examples/registry-playbook-demo.koi +28 -28
  37. package/examples/skill-import-test.koi +7 -9
  38. package/examples/skills/.build/math-operations.ts +1656 -0
  39. package/examples/skills/.build/math-operations.ts.map +1 -0
  40. package/examples/skills/.build/package.json +3 -0
  41. package/examples/skills/.build/string-operations.ts +1643 -0
  42. package/examples/skills/.build/string-operations.ts.map +1 -0
  43. package/examples/skills/advanced/.build/index.ts +3223 -0
  44. package/examples/skills/advanced/.build/index.ts.map +1 -0
  45. package/examples/skills/advanced/.build/package.json +3 -0
  46. package/examples/skills/advanced/index.koi +3 -5
  47. package/examples/skills/math-operations.koi +1 -3
  48. package/examples/skills/string-operations.koi +1 -3
  49. package/examples/tic-tac-toe.koi +19 -0
  50. package/examples/utils/echo-mcp-server.js +141 -0
  51. package/examples/web-delegation-demo.koi +15 -17
  52. package/package.json +2 -1
  53. package/src/cli/koi.js +30 -41
  54. package/src/compiler/build-optimizer.js +204 -289
  55. package/src/compiler/cache-manager.js +1 -1
  56. package/src/compiler/import-resolver.js +5 -9
  57. package/src/compiler/parser.js +6072 -3476
  58. package/src/compiler/transpiler.js +346 -38
  59. package/src/grammar/koi.pegjs +302 -62
  60. package/src/runtime/actions/{format.js → call-llm.js} +37 -44
  61. package/src/runtime/actions/call-mcp.js +97 -0
  62. package/src/runtime/actions/if.js +179 -0
  63. package/src/runtime/actions/print.js +3 -1
  64. package/src/runtime/actions/prompt-user.js +75 -0
  65. package/src/runtime/actions/repeat.js +147 -0
  66. package/src/runtime/actions/shell.js +185 -0
  67. package/src/runtime/actions/while.js +205 -0
  68. package/src/runtime/agent.js +592 -178
  69. package/src/runtime/cli-display.js +26 -0
  70. package/src/runtime/cli-input.js +421 -0
  71. package/src/runtime/cli-logger.js +2 -5
  72. package/src/runtime/cli-markdown.js +61 -0
  73. package/src/runtime/cli-select.js +106 -0
  74. package/src/runtime/incremental-json-parser.js +51 -17
  75. package/src/runtime/index.js +1 -0
  76. package/src/runtime/llm-provider.js +1083 -572
  77. package/src/runtime/mcp-registry.js +141 -0
  78. package/src/runtime/mcp-stdio-client.js +334 -0
  79. package/src/runtime/planner.js +1 -1
  80. package/src/runtime/playbook-session.js +259 -0
  81. package/src/runtime/registry-backends/keyv-sqlite.js +1 -1
  82. package/src/runtime/registry-backends/local.js +1 -1
  83. package/src/runtime/router.js +22 -26
  84. package/src/runtime/runtime.js +7 -1
  85. package/examples/cache-test.koi +0 -29
  86. package/examples/calculator.koi +0 -61
  87. package/examples/clear-registry.js +0 -33
  88. package/examples/clear-registry.koi +0 -30
  89. package/examples/code-introspection-test.koi +0 -149
  90. package/examples/directory-import-test.koi +0 -84
  91. package/examples/hello-world-claude.koi +0 -52
  92. package/examples/hello.koi +0 -24
  93. package/examples/mcp-example.koi +0 -70
  94. package/examples/new-import-test.koi +0 -89
  95. package/examples/registry-demo.koi +0 -184
  96. package/examples/registry-playbook-email-compositor-2.koi +0 -140
  97. package/examples/sentiment.koi +0 -90
  98. package/examples/simple.koi +0 -48
  99. package/examples/task-chaining-demo.koi +0 -244
  100. package/examples/test-await.koi +0 -22
  101. package/examples/test-crypto-sha256.koi +0 -196
  102. package/examples/test-delegation.koi +0 -41
  103. package/examples/test-multi-team-routing.koi +0 -258
  104. package/examples/test-no-handler.koi +0 -35
  105. package/examples/test-npm-import.koi +0 -67
  106. package/examples/test-parse.koi +0 -10
  107. package/examples/test-peers-with-team.koi +0 -59
  108. package/examples/test-permissions-fail.koi +0 -20
  109. package/examples/test-permissions.koi +0 -36
  110. package/examples/test-simple-registry.koi +0 -31
  111. package/examples/test-typescript-import.koi +0 -64
  112. package/examples/test-uses-team-syntax.koi +0 -25
  113. package/examples/test-uses-team.koi +0 -31
@@ -1,18 +1,16 @@
1
- package "demo.multi.event"
2
-
3
1
  role Calculator { can calculate }
4
- role Coordinator { can coordinate }
2
+ role Coordinator { can coordinate, can delegate }
5
3
 
6
- // Agent con múltiples event handlers
7
- // Cada handler tiene su propio affordance (del playbook)
8
- Agent StatisticsCalculator : Calculator {
4
+ // Agent with multiple event handlers
5
+ // Each handler has its own affordance (from the playbook)
6
+ agent StatisticsCalculator : Calculator {
9
7
  llm default = {
10
8
  provider: "openai",
11
9
  model: "gpt-4o-mini",
12
10
  temperature: 0.1
13
11
  }
14
12
 
15
- // Event handler para calcular media
13
+ // Event handler to calculate the mean
16
14
  on mean(args: Json) {
17
15
  playbook """
18
16
  Calculate the arithmetic mean (average) of the numbers: ${JSON.stringify(args.numbers)}
@@ -22,7 +20,7 @@ Agent StatisticsCalculator : Calculator {
22
20
  """
23
21
  }
24
22
 
25
- // Event handler para calcular mediana
23
+ // Event handler to calculate the median
26
24
  on median(args: Json) {
27
25
  playbook """
28
26
  Calculate the median (middle value) of ${JSON.stringify(args.numbers)}
@@ -32,7 +30,7 @@ Agent StatisticsCalculator : Calculator {
32
30
  """
33
31
  }
34
32
 
35
- // Event handler para calcular desviación estándar
33
+ // Event handler to calculate the standard deviation
36
34
  on stddev(args: Json) {
37
35
  playbook """
38
36
  Calculate the standard deviation for ${JSON.stringify(args.numbers)}
@@ -44,19 +42,19 @@ Agent StatisticsCalculator : Calculator {
44
42
  }
45
43
  }
46
44
 
47
- Team CalculatorTeam {
48
- calculator = StatisticsCalculator
45
+ team CalculatorTeam {
46
+ calculator: StatisticsCalculator
49
47
  }
50
48
 
51
- // Orchestrator que decide qué evento enviar basándose en la intención
52
- Agent Orchestrator : Coordinator {
49
+ // Orchestrator that decides which event to send based on intent
50
+ agent Orchestrator : Coordinator {
53
51
  llm default = {
54
52
  provider: "openai",
55
53
  model: "gpt-4o-mini",
56
54
  temperature: 0.1
57
55
  }
58
56
 
59
- uses Team CalculatorTeam
57
+ uses team CalculatorTeam
60
58
 
61
59
  on process(args: Json) {
62
60
  playbook """
@@ -85,12 +83,12 @@ Agent Orchestrator : Coordinator {
85
83
  }
86
84
  }
87
85
 
88
- Team OrchestratorTeam {
89
- orchestrator = Orchestrator
86
+ team OrchestratorTeam {
87
+ orchestrator: Orchestrator
90
88
  }
91
89
 
92
- Agent Main : Coordinator {
93
- uses Team OrchestratorTeam
90
+ agent Main : Coordinator {
91
+ uses team OrchestratorTeam
94
92
 
95
93
  on start(args: Json) {
96
94
  console.log("╔════════════════════════════════════════════╗")
@@ -3,13 +3,11 @@
3
3
  // Shows multi-stage data processing
4
4
  // ============================================================
5
5
 
6
- package "demo.koi.pipeline"
7
-
8
6
  role Worker { can execute }
9
7
  role Reviewer { can critique }
10
8
  role Lead { can delegate }
11
9
 
12
- Agent Extractor : Worker {
10
+ agent Extractor : Worker {
13
11
  llm default = { provider: "openai", model: "gpt-4o-mini", temperature: 0.3, max_tokens: 300 }
14
12
 
15
13
  on extract(args: Json) {
@@ -37,7 +35,7 @@ Agent Extractor : Worker {
37
35
  }
38
36
  }
39
37
 
40
- Agent Transformer : Worker {
38
+ agent Transformer : Worker {
41
39
  llm default = { provider: "openai", model: "gpt-4o-mini", temperature: 0.3, max_tokens: 300 }
42
40
 
43
41
  on transform(args: Json) {
@@ -66,7 +64,7 @@ Agent Transformer : Worker {
66
64
  }
67
65
  }
68
66
 
69
- Agent Validator : Reviewer {
67
+ agent Validator : Reviewer {
70
68
  llm default = { provider: "openai", model: "gpt-4o-mini", temperature: 0.1, max_tokens: 200 }
71
69
 
72
70
  on validate(args: Json) {
@@ -96,7 +94,7 @@ Agent Validator : Reviewer {
96
94
  }
97
95
  }
98
96
 
99
- Agent Loader : Worker {
97
+ agent Loader : Worker {
100
98
  llm default = { provider: "openai", model: "gpt-4o-mini", temperature: 0.2, max_tokens: 250 }
101
99
 
102
100
  on load(args: Json) {
@@ -122,34 +120,34 @@ Agent Loader : Worker {
122
120
  }
123
121
  }
124
122
 
125
- Team Pipeline {
126
- extractor = Extractor
127
- transformer = Transformer
128
- validator = Validator
129
- loader = Loader
123
+ team Pipeline {
124
+ extractor: Extractor
125
+ transformer: Transformer
126
+ validator: Validator
127
+ loader: Loader
130
128
  }
131
129
 
132
- Agent Orchestrator : Lead {
133
- uses Team Pipeline
130
+ agent Orchestrator : Lead {
131
+ uses team Pipeline
134
132
 
135
133
  on start(args: Json) {
136
134
  const raw = args.input
137
135
 
138
136
  const extracted =
139
- await send peers.event("extract").role(Worker).any()({ raw: raw }) timeout 5s
137
+ await send peers.event("extract").role(Worker).any()({ raw: raw }) timeout 30s
140
138
 
141
139
  const transformed =
142
- await send peers.event("transform").role(Worker).any()({ data: extracted.data }) timeout 5s
140
+ await send peers.event("transform").role(Worker).any()({ data: extracted.data }) timeout 30s
143
141
 
144
142
  const validation =
145
- await send peers.event("validate").role(Reviewer).any()({ data: transformed.data }) timeout 5s
143
+ await send peers.event("validate").role(Reviewer).any()({ data: transformed.data }) timeout 30s
146
144
 
147
145
  if validation.valid == false {
148
146
  return { ok: false, error: validation.message }
149
147
  }
150
148
 
151
149
  const loaded =
152
- await send peers.event("load").role(Worker).any()({ data: transformed.data }) timeout 5s
150
+ await send peers.event("load").role(Worker).any()({ data: transformed.data }) timeout 30s
153
151
 
154
152
  return {
155
153
  ok: true,
@@ -0,0 +1,20 @@
1
+ // Demo: Prompt User Action
2
+ // Shows how agents can ask users for input during execution
3
+
4
+ role Worker { can execute }
5
+
6
+ agent Assistant : Worker {
7
+ llm default = { provider: "openai", model: "gpt-5.2" }
8
+
9
+ on greet(args: Json) {
10
+ playbook """
11
+
12
+ Ask the user for their name, then ask if they want to continue,
13
+ and if they do, ask which color they prefer among yellow, blue, or red, and then ask for their age.
14
+
15
+ Finally, give them a greeting and joke about their age however you like.
16
+ """
17
+ }
18
+ }
19
+
20
+ run Assistant.greet({})
@@ -1,13 +1,26 @@
1
1
  // Registry with Natural Language Playbooks Demo
2
2
  // Shows how agents can use registry operations naturally in playbooks
3
- package "registry.playbook.demo"
4
3
 
5
4
  role Worker { can execute, can registry }
6
5
  role Manager { can execute, can delegate }
7
6
 
8
7
  // Agent that uses natural language to interact with registry
9
- Agent UserManager : Worker {
8
+ agent UserManager : Worker {
10
9
  llm default = { provider: "openai", model: "gpt-4o-mini" }
10
+ amnesia = true
11
+
12
+ on createAllUser(args: Json) {
13
+ playbook """
14
+ Create all given users via args, with the following attributes
15
+ - name, age, email
16
+
17
+ Save all to registry with key "user:id being id an unique identifier".
18
+ Include all fields plus a createdAt timestamp.
19
+ Return: { "success": true, "message": "Users created" }
20
+
21
+ DO NOT add print actions - just return the data.
22
+ """
23
+ }
11
24
 
12
25
  on createUser(args: Json) {
13
26
  playbook """
@@ -80,7 +93,7 @@ Agent UserManager : Worker {
80
93
 
81
94
  on deleteUser(args: Json) {
82
95
  playbook """
83
- Borra el usuario del registro con ID ${args.id}.
96
+ Delete the user from the registry with ID ${args.id}.
84
97
 
85
98
  EXACT STEPS:
86
99
  1. Use registry_delete with key "user:\${args.id}"
@@ -90,46 +103,33 @@ Agent UserManager : Worker {
90
103
  }
91
104
 
92
105
  // Team that groups our agents
93
- Team RegistryTeam {
94
- userManager = UserManager
106
+ team RegistryTeam {
107
+ userManager: UserManager
95
108
  }
96
109
 
97
110
  // Orchestrator - uses playbook, router finds UserManager automatically!
98
- Agent Demo : Manager {
111
+ agent Demo : Manager {
99
112
  llm default = { provider: "openai", model: "gpt-4o-mini" }
100
- uses Team RegistryTeam
113
+ uses team RegistryTeam
101
114
 
102
115
  on start(args: Json) {
103
116
  //SUPER IMPORTANT: DO NOT CHANGE THE FOLLOWING PROMPT AT ALL!!!!!!
104
117
  playbook """
105
- Ejecuta un demo del registro de usuarios.
118
+ Run a user registry demo.
106
119
 
107
- Muestra el header:
120
+ Show the header (just the very first time):
108
121
  ╔══════════════════════════════════════════════════╗
109
122
  ║ Registry with Playbook Demo ║
110
123
  ╚══════════════════════════════════════════════════╝
111
124
 
112
- 1️⃣ Crea estos usuarios:
113
- - Alice: id=001, age=30, email=alice@example.com
114
- - Bob: id=002, de 17 años, bob@example.com
115
- - Charlie: id=003, age=25, email=charlie@example.com
116
- - Diana: id=004, age is 35, diana@example.com
117
- - Erika: id=005, age=28, email=erika@example.com
118
- - Fernando: id=006, age=32, fernando@example.com
119
- Muestra: " ✅ X users created" X es la cantidad de usuarios que se crearon
120
-
121
- 2️⃣ Por cada usuario en la base de datos, escribe este correo:
122
-
123
- Estimado (o Estimada si es chica, deducelo por el nombre),
125
+ Them ask the user what it wants: create / consult / modify / delete any user and do what the user wants.
126
+ Aks as many info as you need to the user to perform the action the user wants from you.
124
127
 
125
- Como sabemos que usted tiene {x} años, le queremos dar la enhorabuena!
126
-
127
- Atentamente,
128
- La empresa!!
128
+ After performing an action, ask the user if it want to continuer, and in that case ask again what it wants (loop)
129
129
 
130
- Muestra cada correo que escribieste.
130
+ If the user wnats to list the users, for each one show in a markdown table: Mr or Ms depending on whether they are male or female (deduce this from the name) and then {the user's name}, age {their age}"
131
131
 
132
- Muestra el footer:
132
+ Before exiting, print:
133
133
  ╔══════════════════════════════════════════════════╗
134
134
  ║ Demo completed successfully! ║
135
135
  ╚══════════════════════════════════════════════════╝
@@ -1,13 +1,13 @@
1
1
  // Registry with Natural Language Playbooks Demo
2
2
  // Shows how agents can use registry operations naturally in playbooks
3
- package "registry.playbook.demo"
4
3
 
5
4
  role Worker { can execute, can registry }
6
5
  role Manager { can execute, can delegate }
7
6
 
8
7
  // Agent that uses natural language to interact with registry
9
- Agent UserManager : Worker {
8
+ agent UserManager : Worker {
10
9
  llm default = { provider: "openai", model: "gpt-4o-mini" }
10
+ amnesia = true
11
11
 
12
12
  on createAllUser(args: Json) {
13
13
  playbook """
@@ -18,7 +18,7 @@ Agent UserManager : Worker {
18
18
  Include all fields plus a createdAt timestamp.
19
19
  Return: { "success": true, "message": "Users created" }
20
20
 
21
- DO NOT add print actions - just return the data.
21
+ DO NOT add print actions - just return the data.
22
22
  """
23
23
  }
24
24
 
@@ -93,7 +93,7 @@ Agent UserManager : Worker {
93
93
 
94
94
  on deleteUser(args: Json) {
95
95
  playbook """
96
- Borra el usuario del registro con ID ${args.id}.
96
+ Delete the user from the registry with ID ${args.id}.
97
97
 
98
98
  EXACT STEPS:
99
99
  1. Use registry_delete with key "user:\${args.id}"
@@ -103,55 +103,55 @@ Agent UserManager : Worker {
103
103
  }
104
104
 
105
105
  // Team that groups our agents
106
- Team RegistryTeam {
107
- userManager = UserManager
106
+ team RegistryTeam {
107
+ userManager: UserManager
108
108
  }
109
109
 
110
110
  // Orchestrator - uses playbook, router finds UserManager automatically!
111
- Agent Demo : Manager {
111
+ agent Demo : Manager {
112
112
  llm default = { provider: "openai", model: "gpt-4o-mini" }
113
- uses Team RegistryTeam
113
+ uses team RegistryTeam
114
114
 
115
115
  on start(args: Json) {
116
116
  //SUPER IMPORTANT: DO NOT CHANGE THE FOLLOWING PROMPT AT ALL!!!!!!
117
117
  playbook """
118
- Ejecuta un demo del registro de usuarios.
118
+ Run a user registry demo.
119
119
 
120
- Muestra el header:
120
+ Show the header:
121
121
  ╔══════════════════════════════════════════════════╗
122
122
  ║ Registry with Playbook Demo ║
123
123
  ╚══════════════════════════════════════════════════╝
124
124
 
125
- 1️⃣ Crea estos usuarios:
125
+ 1️⃣ Create these users:
126
126
  - Alice: id=001, age=30, email=alice@example.com
127
- - Bob: id=002, de 17 años, bob@example.com
127
+ - Bob: id=002, 17 years old, bob@example.com
128
128
  - Charlie: id=003, age=25, email=charlie@example.com
129
129
  - Diana: id=004, age is 35, diana@example.com
130
130
  - Erika: id=005, age=28, email=erika@example.com
131
131
  - Fernando: id=006, age=32, fernando@example.com
132
- Muestra: " ✅ X users created" X es la cantidad de usuarios que se crearon
132
+ Show: " ✅ X users created" where X is the number of users that were created
133
133
 
134
- 2️⃣ Obtén el usuario 001
135
- Muestra: " ✅ Found user: {el nombre del usuario}, age {su edad}"
134
+ 2️⃣ Get user 001
135
+ Show: " ✅ Found user: {the user's name}, age {their age}"
136
136
 
137
- 3️⃣ Lista todos los usuarios
138
- Muestra: " ✅ Found {la cantidad de usuarios} users y luego por cada uno muestra en una tabla en markdown: sr o sra si es chico o chica (esto deducelo por el nombre) y luego {el nombre del usuario}, age {su edad}"
137
+ 3️⃣ List all users
138
+ Show: " ✅ Found {the number of users} users then for each one show in a markdown table: Mr or Ms depending on whether they are male or female (deduce this from the name) and then {the user's name}, age {their age}"
139
139
 
140
- 4️⃣ Busca usuarios mayores de 18 años
141
- Muestra: " ✅ Found {la cantidad encontrada} adults"
140
+ 4️⃣ Search for users older than 18 years
141
+ Show: " ✅ Found {the number found} adults"
142
142
 
143
- 5️⃣ Actualiza la edad de Bob (002) a 19 años
144
- Luego obtén el usuario actualizado
145
- Muestra: " ✅ Bob is now {su nueva edad} years old"
143
+ 5️⃣ Update Bob's age (002) to 19 years old
144
+ Then get the updated user
145
+ Show: " ✅ Bob is now {his new age} years old"
146
146
 
147
- 6️⃣ Elimina a Charlie (003)
148
- Luego lista los usuarios restantes
149
- Muestra: " ✅ Remaining users: {la cantidad restante}"
147
+ 6️⃣ Delete Charlie (003)
148
+ Then list the remaining users
149
+ Show: " ✅ Remaining users: {the remaining count}"
150
150
 
151
- 7️⃣ Vuelve a listar todos los usuarios como lo has hecho en el paso 3️⃣
152
- Muestra los usuarios que hay en la tabla en markdown con el mismo formato que en el paso 3️⃣
151
+ 7️⃣ List all users again as you did in step 3️⃣
152
+ Show the users in a markdown table with the same format as in step 3️⃣
153
153
 
154
- Muestra el footer:
154
+ Show the footer:
155
155
  ╔══════════════════════════════════════════════════╗
156
156
  ║ Demo completed successfully! ║
157
157
  ╚══════════════════════════════════════════════════╝
@@ -3,17 +3,15 @@
3
3
  // Tests importing Skills from external files
4
4
  // ============================================================
5
5
 
6
- package "demo.koi.import"
7
-
8
6
  // Import the Math Operations skill
9
7
  import "./skills/math-operations.koi"
10
8
 
11
- role Calculator { can calculate }
9
+ role Calculator { can execute }
12
10
 
13
11
  // Agent that uses the imported MathOperations skill
14
- Agent MathAgent : Calculator {
12
+ agent MathAgent : Calculator {
15
13
  llm default = { provider: "openai", model: "gpt-4o-mini", temperature: 0.1, max_tokens: 200 }
16
- uses Skill MathOperations
14
+ uses skill MathOperations
17
15
 
18
16
  on calculate(args: Json) {
19
17
  playbook """
@@ -26,13 +24,13 @@ Agent MathAgent : Calculator {
26
24
  }
27
25
 
28
26
  // Create a team
29
- Team MathTeam {
30
- calculator = MathAgent
27
+ team MathTeam {
28
+ calculator: MathAgent
31
29
  }
32
30
 
33
31
  // Demo runner
34
- Agent DemoRunner : Calculator {
35
- uses Team MathTeam
32
+ agent DemoRunner : Calculator {
33
+ uses team MathTeam
36
34
 
37
35
  on runTest(args: Json) {
38
36
  console.log("╔════════════════════════════════════════════╗")