@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,84 +0,0 @@
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({})
@@ -1,52 +0,0 @@
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" })
@@ -1,24 +0,0 @@
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({})
@@ -1,70 +0,0 @@
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!" })
@@ -1,89 +0,0 @@
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({})
@@ -1,184 +0,0 @@
1
- // Registry Demo - Shared data store between agents
2
- package "registry.demo"
3
-
4
- role Worker { can execute }
5
-
6
- // Agent that writes data to the registry
7
- Agent Writer : Worker {
8
- on saveUser(args: Json) {
9
- const userId = args.id
10
- const userData = {
11
- name: args.name,
12
- age: args.age,
13
- email: args.email,
14
- createdAt: Date.now()
15
- }
16
-
17
- await registry.set("user:" + userId, userData)
18
-
19
- console.log("✅ Saved user:", userId)
20
- return { saved: true, userId: userId }
21
- }
22
-
23
- on saveConfig(args: Json) {
24
- await registry.set("config:app", {
25
- theme: args.theme || "dark",
26
- language: args.language || "en",
27
- notifications: args.notifications !== false
28
- })
29
-
30
- console.log("✅ Saved config")
31
- return { saved: true }
32
- }
33
- }
34
-
35
- // Agent that reads data from the registry
36
- Agent Reader : Worker {
37
- on getUser(args: Json) {
38
- const userId = args.id
39
- const user = await registry.get("user:" + userId)
40
-
41
- if (!user) {
42
- console.log("❌ User not found:", userId)
43
- return { found: false, userId: userId }
44
- }
45
-
46
- console.log("📖 Retrieved user:", user.name)
47
- return { found: true, user: user }
48
- }
49
-
50
- on getConfig(args: Json) {
51
- const config = await registry.get("config:app")
52
-
53
- if (!config) {
54
- console.log("⚙️ No config found, using defaults")
55
- return { found: false, config: null }
56
- }
57
-
58
- console.log("⚙️ Retrieved config:", JSON.stringify(config))
59
- return { found: true, config: config }
60
- }
61
-
62
- on listUsers(args: Json) {
63
- const userKeys = await registry.keys("user:")
64
- console.log("📋 Found", userKeys.length, "users")
65
-
66
- const users = []
67
- for (const key of userKeys) {
68
- const user = await registry.get(key)
69
- users.push({ id: key.replace("user:", ""), ...user })
70
- }
71
-
72
- return { count: users.length, users: users }
73
- }
74
- }
75
-
76
- // Agent that searches the registry
77
- Agent Searcher : Worker {
78
- on findAdults(args: Json) {
79
- const results = await registry.search({
80
- age: { $gte: 18 }
81
- })
82
-
83
- console.log("🔍 Found", results.length, "adults")
84
-
85
- const adults = results.map(r => ({
86
- id: r.key.replace("user:", ""),
87
- ...r.value
88
- }))
89
-
90
- return { count: adults.length, adults: adults }
91
- }
92
-
93
- on findByName(args: Json) {
94
- const results = await registry.search({
95
- name: { $regex: args.pattern }
96
- })
97
-
98
- console.log("🔍 Found", results.length, "matching users")
99
-
100
- const matches = results.map(r => ({
101
- id: r.key.replace("user:", ""),
102
- ...r.value
103
- }))
104
-
105
- return { count: matches.length, matches: matches }
106
- }
107
- }
108
-
109
- // Orchestrator that coordinates the demo
110
- Agent Demo : Worker {
111
- on start(args: Json) {
112
- console.log("═════════════════════════════════════════════")
113
- console.log(" Registry Demo - Shared Data Store")
114
- console.log("═════════════════════════════════════════════")
115
- console.log("")
116
-
117
- // 1. Save some users
118
- console.log("1️⃣ Saving users...")
119
- await Writer.handle("saveUser", { id: "001", name: "Alice", age: 30, email: "alice@example.com" })
120
- await Writer.handle("saveUser", { id: "002", name: "Bob", age: 25, email: "bob@example.com" })
121
- await Writer.handle("saveUser", { id: "003", name: "Charlie", age: 17, email: "charlie@example.com" })
122
- await Writer.handle("saveUser", { id: "004", name: "Diana", age: 35, email: "diana@example.com" })
123
- console.log("")
124
-
125
- // 2. Save config
126
- console.log("2️⃣ Saving config...")
127
- await Writer.handle("saveConfig", { theme: "light", language: "es", notifications: true })
128
- console.log("")
129
-
130
- // 3. Read individual user
131
- console.log("3️⃣ Reading user...")
132
- const userResult = await Reader.handle("getUser", { id: "001" })
133
- console.log(" User:", JSON.stringify(userResult.user, null, 2))
134
- console.log("")
135
-
136
- // 4. Read config
137
- console.log("4️⃣ Reading config...")
138
- const configResult = await Reader.handle("getConfig", {})
139
- console.log(" Config:", JSON.stringify(configResult.config, null, 2))
140
- console.log("")
141
-
142
- // 5. List all users
143
- console.log("5️⃣ Listing all users...")
144
- const listResult = await Reader.handle("listUsers", {})
145
- for (const user of listResult.users) {
146
- console.log(" -", user.name, "(" + user.age + " years old)")
147
- }
148
- console.log("")
149
-
150
- // 6. Search for adults
151
- console.log("6️⃣ Searching for adults (age >= 18)...")
152
- const adultsResult = await Searcher.handle("findAdults", {})
153
- for (const adult of adultsResult.adults) {
154
- console.log(" -", adult.name, "(" + adult.age + " years old)")
155
- }
156
- console.log("")
157
-
158
- // 7. Search by name pattern
159
- console.log("7️⃣ Searching for names containing 'a'...")
160
- const searchResult = await Searcher.handle("findByName", { pattern: "a" })
161
- for (const match of searchResult.matches) {
162
- console.log(" -", match.name)
163
- }
164
- console.log("")
165
-
166
- // 8. Show stats
167
- console.log("8️⃣ Registry stats...")
168
- const stats = await registry.stats()
169
- console.log(" Backend:", stats.backend)
170
- console.log(" Entries:", stats.count)
171
- console.log(" File:", stats.file)
172
- console.log(" Size:", stats.size, "bytes")
173
- console.log("")
174
-
175
- console.log("═════════════════════════════════════════════")
176
- console.log(" Demo Complete!")
177
- console.log(" Data persisted to:", stats.file)
178
- console.log("═════════════════════════════════════════════")
179
-
180
- return { success: true }
181
- }
182
- }
183
-
184
- run Demo.start({})
@@ -1,140 +0,0 @@
1
- // Registry with Natural Language Playbooks Demo
2
- // Shows how agents can use registry operations naturally in playbooks
3
- package "registry.playbook.demo"
4
-
5
- role Worker { can execute, can registry }
6
- role Manager { can execute, can delegate }
7
-
8
- // Agent that uses natural language to interact with registry
9
- Agent UserManager : Worker {
10
- llm default = { provider: "openai", model: "gpt-4o-mini" }
11
-
12
- on createUser(args: Json) {
13
- playbook """
14
- Create a new user with ALL fields from args:
15
- - name: ${args.name}
16
- - age: ${args.age}
17
- - email: ${args.email}
18
- - birthdate: ${args.birthdate} (if provided)
19
- - id: ${args.id}
20
-
21
- Save to registry with key "user:${args.id}".
22
- CRITICAL: Include ALL fields from args (name, age, email, birthdate, id) plus a createdAt timestamp.
23
- Return: { "success": true, "message": "User created" }
24
-
25
- DO NOT add print actions - just return the data.
26
- """
27
- }
28
-
29
- on getUser(args: Json) {
30
- playbook """
31
- Get user ${args.id} from registry.
32
-
33
- Use registry_get with key "user:${args.id}".
34
- Extract the .value field from the registry_get result (which contains the user data).
35
- Return ONLY the user data object (name, age, email, createdAt) without any wrapper.
36
- """
37
- }
38
-
39
- on listAllUsers(args: Json) {
40
- playbook """
41
- List all users in the registry.
42
-
43
- EXACT STEPS:
44
- 1. Use registry_search with an empty query {} to get ALL users, store with ID "a1"
45
- 2. Extract just the user data (the .value field) from each result
46
- 3. Return: { "count": <count from a1>, "users": <array of user value objects, NOT the full {key, value} wrappers> }
47
-
48
- Example: If a1.output.results = [{key: "user:001", value: {name: "Alice", age: 30}}, ...]
49
- Then return: { "count": 2, "users": [{name: "Alice", age: 30}, ...] }
50
-
51
- CRITICAL: Extract ONLY the .value objects so caller can access with .users[0].name directly
52
- DO NOT use format action - return a real array!
53
- """
54
- }
55
-
56
- on findAdults(args: Json) {
57
- playbook """
58
- Find all users aged 18 or older using registry search with query: { "age": { "$gte": 18 } }
59
-
60
- EXACT STEPS:
61
- 1. Use registry_search with query: { "age": { "$gte": 18 } }
62
- 2. Return: { "count": [count from search], "adults": [results array] }
63
-
64
- DO NOT add print actions - just return the data!
65
- """
66
- }
67
-
68
- on updateUserAge(args: Json) {
69
- playbook """
70
- Update user ${args.id}'s age to ${args.age}.
71
-
72
- EXACT STEPS:
73
- 1. Use registry_get with key "user:${args.id}", store with ID "a1"
74
- 2. Take the full user object from \${a1.output.value}
75
- 3. Modify ONLY the age field to ${args.age}, keep all other fields (name, email, createdAt, etc.)
76
- 4. Use registry_set with key "user:${args.id}" and the complete updated object
77
- 5. Return: { "success": true, "message": "Age updated" }
78
-
79
- CRITICAL: Preserve ALL existing fields when saving!
80
- """
81
- }
82
-
83
- on deleteUser(args: Json) {
84
- playbook """
85
- Borra el usuario del registro con ID ${args.id}.
86
-
87
- EXACT STEPS:
88
- 1. Use registry_delete with key "user:\${args.id}"
89
- 2. Return: { "success": true, "message": "User deleted" }
90
- """
91
- }
92
- }
93
-
94
- // Team that groups our agents
95
- Team RegistryTeam {
96
- userManager = UserManager
97
- }
98
-
99
- // Orchestrator - uses playbook, router finds UserManager automatically!
100
- Agent Demo : Manager {
101
- llm default = { provider: "openai", model: "gpt-4o-mini" }
102
- uses Team RegistryTeam
103
-
104
- on start(args: Json) {
105
- //SUPER IMPORTANT: DO NOT CHANGE THE FOLLOWING PROMPT AT ALL!!!!!!
106
- playbook """
107
- Ejecuta un demo del registro de usuarios.
108
-
109
- Muestra el header:
110
- ╔══════════════════════════════════════════════════╗
111
- ║ Registry with Playbook Demo ║
112
- ╚══════════════════════════════════════════════════╝
113
-
114
- 1️⃣ Crea estos usuarios:
115
- - Alice: id=001, birthdate=1985-12-05, email=alice@example.com
116
- - Bob: id=002, fecha de nacimiento: 12 de abril de 2001, bob@example.com
117
- - Moema: id=003, birth date: 1992 enero 29, email=charlie@example.com
118
- - Diana: id=004, birthdate: 12 del 12 del 12, diana@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) <nombre persona>,
124
-
125
- Como sabemos que usted tiene {x} años, le queremos dar la enhorabuena!
126
-
127
- Atentamente,
128
- La empresa!!
129
-
130
- Muestra cada correo que escribieste.
131
-
132
- Muestra el footer:
133
- ╔══════════════════════════════════════════════════╗
134
- ║ Demo completed successfully! ║
135
- ╚══════════════════════════════════════════════════╝
136
- """
137
- }
138
- }
139
-
140
- run Demo.start({})