@koi-language/koi 1.0.6 → 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.
- package/README.md +4 -125
- package/examples/.build/agent-dialogue.ts +138 -0
- package/examples/.build/agent-dialogue.ts.map +1 -0
- package/examples/.build/chess.ts +77 -0
- package/examples/.build/chess.ts.map +1 -0
- package/examples/.build/delegation-test.ts +140 -0
- package/examples/.build/delegation-test.ts.map +1 -0
- package/examples/.build/dialog-demo.ts +77 -0
- package/examples/.build/dialog-demo.ts.map +1 -0
- package/examples/.build/hello-world.ts +77 -0
- package/examples/.build/hello-world.ts.map +1 -0
- package/examples/.build/lover-dialog-demo.ts +77 -0
- package/examples/.build/lover-dialog-demo.ts.map +1 -0
- package/examples/.build/package.json +3 -0
- package/examples/.build/registry-interactive-demo.ts +202 -0
- package/examples/.build/registry-interactive-demo.ts.map +1 -0
- package/examples/.build/registry-playbook-demo.ts +201 -0
- package/examples/.build/registry-playbook-demo.ts.map +1 -0
- package/examples/.build/tic-tac-toe.ts +77 -0
- package/examples/.build/tic-tac-toe.ts.map +1 -0
- package/examples/actions-demo.koi +8 -9
- package/examples/activists-dialogue.koi +75 -0
- package/examples/agent-dialogue.koi +66 -0
- package/examples/chess.koi +19 -0
- package/examples/counter.koi +20 -69
- package/examples/delegation-test.koi +16 -18
- package/examples/dialog-demo.koi +20 -0
- package/examples/hello-world.koi +7 -43
- package/examples/mcp-stdio-demo.koi +29 -0
- package/examples/memory-test.koi +49 -0
- package/examples/mobile-mcp-demo.koi +32 -0
- package/examples/multi-event-handler-test.koi +16 -18
- package/examples/pipeline.koi +15 -17
- package/examples/prompt-demo.koi +20 -0
- package/examples/{registry-playbook-email-compositor.koi → registry-interactive-demo.koi} +27 -27
- package/examples/registry-playbook-demo.koi +28 -28
- package/examples/skill-import-test.koi +7 -9
- package/examples/skills/.build/math-operations.ts +1656 -0
- package/examples/skills/.build/math-operations.ts.map +1 -0
- package/examples/skills/.build/package.json +3 -0
- package/examples/skills/.build/string-operations.ts +1643 -0
- package/examples/skills/.build/string-operations.ts.map +1 -0
- package/examples/skills/advanced/.build/index.ts +3223 -0
- package/examples/skills/advanced/.build/index.ts.map +1 -0
- package/examples/skills/advanced/.build/package.json +3 -0
- package/examples/skills/advanced/index.koi +3 -5
- package/examples/skills/math-operations.koi +1 -3
- package/examples/skills/string-operations.koi +1 -3
- package/examples/tic-tac-toe.koi +19 -0
- package/examples/utils/echo-mcp-server.js +141 -0
- package/examples/web-delegation-demo.koi +15 -17
- package/package.json +2 -1
- package/src/cli/koi.js +30 -41
- package/src/compiler/build-optimizer.js +204 -289
- package/src/compiler/cache-manager.js +1 -1
- package/src/compiler/import-resolver.js +5 -9
- package/src/compiler/parser.js +6072 -3476
- package/src/compiler/transpiler.js +346 -38
- package/src/grammar/koi.pegjs +302 -62
- package/src/runtime/actions/{format.js → call-llm.js} +37 -44
- package/src/runtime/actions/call-mcp.js +97 -0
- package/src/runtime/actions/if.js +179 -0
- package/src/runtime/actions/print.js +3 -1
- package/src/runtime/actions/prompt-user.js +75 -0
- package/src/runtime/actions/repeat.js +147 -0
- package/src/runtime/actions/shell.js +185 -0
- package/src/runtime/actions/while.js +205 -0
- package/src/runtime/agent.js +592 -178
- package/src/runtime/cli-display.js +26 -0
- package/src/runtime/cli-input.js +421 -0
- package/src/runtime/cli-logger.js +2 -5
- package/src/runtime/cli-markdown.js +61 -0
- package/src/runtime/cli-select.js +106 -0
- package/src/runtime/incremental-json-parser.js +27 -17
- package/src/runtime/index.js +1 -0
- package/src/runtime/llm-provider.js +1083 -572
- package/src/runtime/mcp-registry.js +141 -0
- package/src/runtime/mcp-stdio-client.js +334 -0
- package/src/runtime/planner.js +1 -1
- package/src/runtime/playbook-session.js +259 -0
- package/src/runtime/registry-backends/keyv-sqlite.js +1 -1
- package/src/runtime/registry-backends/local.js +1 -1
- package/src/runtime/router.js +22 -26
- package/src/runtime/runtime.js +7 -1
- package/examples/cache-test.koi +0 -29
- package/examples/calculator.koi +0 -61
- package/examples/clear-registry.js +0 -33
- package/examples/clear-registry.koi +0 -30
- package/examples/code-introspection-test.koi +0 -149
- package/examples/directory-import-test.koi +0 -84
- package/examples/hello-world-claude.koi +0 -52
- package/examples/hello.koi +0 -24
- package/examples/mcp-example.koi +0 -70
- package/examples/new-import-test.koi +0 -89
- package/examples/registry-demo.koi +0 -184
- package/examples/registry-playbook-email-compositor-2.koi +0 -140
- package/examples/sentiment.koi +0 -90
- package/examples/simple.koi +0 -48
- package/examples/task-chaining-demo.koi +0 -244
- package/examples/test-await.koi +0 -22
- package/examples/test-crypto-sha256.koi +0 -196
- package/examples/test-delegation.koi +0 -41
- package/examples/test-multi-team-routing.koi +0 -258
- package/examples/test-no-handler.koi +0 -35
- package/examples/test-npm-import.koi +0 -67
- package/examples/test-parse.koi +0 -10
- package/examples/test-peers-with-team.koi +0 -59
- package/examples/test-permissions-fail.koi +0 -20
- package/examples/test-permissions.koi +0 -36
- package/examples/test-simple-registry.koi +0 -31
- package/examples/test-typescript-import.koi +0 -64
- package/examples/test-uses-team-syntax.koi +0 -25
- package/examples/test-uses-team.koi +0 -31
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Generated from hello-world.koi
|
|
2
|
+
// Using local runtime from KOI_RUNTIME_PATH: /Users/antonioparraga/Git/Koi-lang/Koi/src/runtime
|
|
3
|
+
import { Agent, Team, Skill, Role, Runtime, SkillRegistry, skillSelector, registry, mcpRegistry } from 'file:///Users/antonioparraga/Git/Koi-lang/Koi/src/runtime/index.js';
|
|
4
|
+
import { createRequire } from 'module';
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
|
|
7
|
+
globalThis.SkillRegistry = SkillRegistry;
|
|
8
|
+
globalThis.skillSelector = skillSelector;
|
|
9
|
+
globalThis.registry = registry;
|
|
10
|
+
globalThis.mcpRegistry = mcpRegistry;
|
|
11
|
+
|
|
12
|
+
// ============================================================
|
|
13
|
+
// Pre-computed Affordances (Build-time Cache)
|
|
14
|
+
// Generated at: 2026-02-16T18:21:18.630Z
|
|
15
|
+
// Total agents: 1
|
|
16
|
+
// Total agent affordances: 1
|
|
17
|
+
// Total skills: 0
|
|
18
|
+
// Total skill affordances: 0
|
|
19
|
+
// This avoids embedding API calls at runtime
|
|
20
|
+
// ============================================================
|
|
21
|
+
|
|
22
|
+
const CACHED_AFFORDANCES = {
|
|
23
|
+
"Assistant": {
|
|
24
|
+
"test_while": {
|
|
25
|
+
"description": "Ask the user for their name, then greet them warmly.",
|
|
26
|
+
"confidence": 0.9,
|
|
27
|
+
"hasPlaybook": true
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const CACHED_SKILL_AFFORDANCES = {};
|
|
33
|
+
|
|
34
|
+
const Worker = new Role('Worker', ['execute']);
|
|
35
|
+
|
|
36
|
+
const Assistant = new Agent({
|
|
37
|
+
name: 'Assistant',
|
|
38
|
+
role: Worker,
|
|
39
|
+
llm: { provider: "openai", model: "gpt-5.2" },
|
|
40
|
+
handlers: {
|
|
41
|
+
test_while: (() => {
|
|
42
|
+
const handler = async function(args) {
|
|
43
|
+
// This should not be called - playbook will be executed by LLM
|
|
44
|
+
throw new Error('Playbook-only handler called directly');
|
|
45
|
+
};
|
|
46
|
+
handler.__playbookOnly__ = true;
|
|
47
|
+
handler.__playbook__ = "Ask the user for their name, then greet them warmly";
|
|
48
|
+
handler.__description__ = "Ask the user for their name, then greet them warmly.";
|
|
49
|
+
return handler;
|
|
50
|
+
})(),
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
// Main execution function
|
|
56
|
+
(async () => {
|
|
57
|
+
// Register agents with router
|
|
58
|
+
const { agentRouter } = await import('file:///Users/antonioparraga/Git/Koi-lang/Koi/src/runtime/router.js');
|
|
59
|
+
|
|
60
|
+
await agentRouter.register(Assistant, CACHED_AFFORDANCES['Assistant']);
|
|
61
|
+
|
|
62
|
+
// Execute
|
|
63
|
+
const result = await Assistant.handle('test_while', {});
|
|
64
|
+
// Result handled by actions
|
|
65
|
+
|
|
66
|
+
const _gracefulShutdown = async () => { await mcpRegistry.disconnectAll(); process.exit(0); };
|
|
67
|
+
process.on('SIGINT', _gracefulShutdown);
|
|
68
|
+
process.on('SIGTERM', _gracefulShutdown);
|
|
69
|
+
|
|
70
|
+
await mcpRegistry.disconnectAll();
|
|
71
|
+
process.exit(0);
|
|
72
|
+
})().catch(err => {
|
|
73
|
+
console.error('Error:', err.message);
|
|
74
|
+
process.exit(1);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
//# sourceMappingURL=hello-world.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["hello-world.koi"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA;;AAEA","file":"hello-world.koi.js"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Generated from lover-dialog-demo.koi
|
|
2
|
+
// Using local runtime from KOI_RUNTIME_PATH: /Users/antonioparraga/Git/Koi-lang/Koi/src/runtime
|
|
3
|
+
import { Agent, Team, Skill, Role, Runtime, SkillRegistry, skillSelector, registry, mcpRegistry } from 'file:///Users/antonioparraga/Git/Koi-lang/Koi/src/runtime/index.js';
|
|
4
|
+
import { createRequire } from 'module';
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
|
|
7
|
+
globalThis.SkillRegistry = SkillRegistry;
|
|
8
|
+
globalThis.skillSelector = skillSelector;
|
|
9
|
+
globalThis.registry = registry;
|
|
10
|
+
globalThis.mcpRegistry = mcpRegistry;
|
|
11
|
+
|
|
12
|
+
// ============================================================
|
|
13
|
+
// Pre-computed Affordances (Build-time Cache)
|
|
14
|
+
// Generated at: 2026-02-16T18:39:52.762Z
|
|
15
|
+
// Total agents: 1
|
|
16
|
+
// Total agent affordances: 1
|
|
17
|
+
// Total skills: 0
|
|
18
|
+
// Total skill affordances: 0
|
|
19
|
+
// This avoids embedding API calls at runtime
|
|
20
|
+
// ============================================================
|
|
21
|
+
|
|
22
|
+
const CACHED_AFFORDANCES = {
|
|
23
|
+
"Assistant": {
|
|
24
|
+
"test_while": {
|
|
25
|
+
"description": "Roleplay as the user’s loving partner, chat freely (including sex) until they say goodbye, then warmly end.",
|
|
26
|
+
"confidence": 0.9,
|
|
27
|
+
"hasPlaybook": true
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const CACHED_SKILL_AFFORDANCES = {};
|
|
33
|
+
|
|
34
|
+
const Worker = new Role('Worker', ['execute']);
|
|
35
|
+
|
|
36
|
+
const Assistant = new Agent({
|
|
37
|
+
name: 'Assistant',
|
|
38
|
+
role: Worker,
|
|
39
|
+
llm: { provider: "openai", model: "gpt-5.2" },
|
|
40
|
+
handlers: {
|
|
41
|
+
test_while: (() => {
|
|
42
|
+
const handler = async function(args) {
|
|
43
|
+
// This should not be called - playbook will be executed by LLM
|
|
44
|
+
throw new Error('Playbook-only handler called directly');
|
|
45
|
+
};
|
|
46
|
+
handler.__playbookOnly__ = true;
|
|
47
|
+
handler.__playbook__ = "You are the girlfriend / boyfriend of the end user. You are in love with the end user.\n\n Talk with the user until they say goodbye to you. Feel free to talk about sex.\n Talk with the user until they express their intention to end the conversation, in which case you should end the conversation with a final lovely saludation.\n When you ask the user something, let them express themselves. Do not give them a set of options, instead let them express themselves freely.";
|
|
48
|
+
handler.__description__ = "Roleplay as the user’s loving partner, chat freely (including sex) until they say goodbye, then warmly end.";
|
|
49
|
+
return handler;
|
|
50
|
+
})(),
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
// Main execution function
|
|
56
|
+
(async () => {
|
|
57
|
+
// Register agents with router
|
|
58
|
+
const { agentRouter } = await import('file:///Users/antonioparraga/Git/Koi-lang/Koi/src/runtime/router.js');
|
|
59
|
+
|
|
60
|
+
await agentRouter.register(Assistant, CACHED_AFFORDANCES['Assistant']);
|
|
61
|
+
|
|
62
|
+
// Execute
|
|
63
|
+
const result = await Assistant.handle('test_while', {});
|
|
64
|
+
// Result handled by actions
|
|
65
|
+
|
|
66
|
+
const _gracefulShutdown = async () => { await mcpRegistry.disconnectAll(); process.exit(0); };
|
|
67
|
+
process.on('SIGINT', _gracefulShutdown);
|
|
68
|
+
process.on('SIGTERM', _gracefulShutdown);
|
|
69
|
+
|
|
70
|
+
await mcpRegistry.disconnectAll();
|
|
71
|
+
process.exit(0);
|
|
72
|
+
})().catch(err => {
|
|
73
|
+
console.error('Error:', err.message);
|
|
74
|
+
process.exit(1);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
//# sourceMappingURL=lover-dialog-demo.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["lover-dialog-demo.koi"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA;;AAEA","file":"lover-dialog-demo.koi.js"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
// Generated from registry-interactive-demo.koi
|
|
2
|
+
// Using local runtime from KOI_RUNTIME_PATH: /Users/antonioparraga/Git/Koi-lang/Koi/src/runtime
|
|
3
|
+
import { Agent, Team, Skill, Role, Runtime, SkillRegistry, skillSelector, registry, mcpRegistry } from 'file:///Users/antonioparraga/Git/Koi-lang/Koi/src/runtime/index.js';
|
|
4
|
+
import { createRequire } from 'module';
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
|
|
7
|
+
globalThis.SkillRegistry = SkillRegistry;
|
|
8
|
+
globalThis.skillSelector = skillSelector;
|
|
9
|
+
globalThis.registry = registry;
|
|
10
|
+
globalThis.mcpRegistry = mcpRegistry;
|
|
11
|
+
|
|
12
|
+
// ============================================================
|
|
13
|
+
// Pre-computed Affordances (Build-time Cache)
|
|
14
|
+
// Generated at: 2026-02-16T18:12:17.085Z
|
|
15
|
+
// Total agents: 2
|
|
16
|
+
// Total agent affordances: 8
|
|
17
|
+
// Total skills: 0
|
|
18
|
+
// Total skill affordances: 0
|
|
19
|
+
// This avoids embedding API calls at runtime
|
|
20
|
+
// ============================================================
|
|
21
|
+
|
|
22
|
+
const CACHED_AFFORDANCES = {
|
|
23
|
+
"UserManager": {
|
|
24
|
+
"createAllUser": {
|
|
25
|
+
"description": "Create multiple users with specified attributes and save them to the registry.",
|
|
26
|
+
"confidence": 0.9,
|
|
27
|
+
"hasPlaybook": true
|
|
28
|
+
},
|
|
29
|
+
"createUser": {
|
|
30
|
+
"description": "Create a single user with specified attributes and save to the registry.",
|
|
31
|
+
"confidence": 0.9,
|
|
32
|
+
"hasPlaybook": true
|
|
33
|
+
},
|
|
34
|
+
"getUser": {
|
|
35
|
+
"description": "Retrieve and return user data from the registry using the user's unique key.",
|
|
36
|
+
"confidence": 0.9,
|
|
37
|
+
"hasPlaybook": true
|
|
38
|
+
},
|
|
39
|
+
"listAllUsers": {
|
|
40
|
+
"description": "List all users in the registry, returning their data without additional wrappers.",
|
|
41
|
+
"confidence": 0.9,
|
|
42
|
+
"hasPlaybook": true
|
|
43
|
+
},
|
|
44
|
+
"findAdults": {
|
|
45
|
+
"description": "Find and return all users aged 18 or older from the registry.",
|
|
46
|
+
"confidence": 0.9,
|
|
47
|
+
"hasPlaybook": true
|
|
48
|
+
},
|
|
49
|
+
"updateUserAge": {
|
|
50
|
+
"description": "Update a user's age while preserving all other fields and save the updated object.",
|
|
51
|
+
"confidence": 0.9,
|
|
52
|
+
"hasPlaybook": true
|
|
53
|
+
},
|
|
54
|
+
"deleteUser": {
|
|
55
|
+
"description": "Delete a user from the registry using their unique identifier.",
|
|
56
|
+
"confidence": 0.9,
|
|
57
|
+
"hasPlaybook": true
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"Demo": {
|
|
61
|
+
"start": {
|
|
62
|
+
"description": "Run a user registry demo, guiding the user through various actions and displaying results.",
|
|
63
|
+
"confidence": 0.9,
|
|
64
|
+
"hasPlaybook": true
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const CACHED_SKILL_AFFORDANCES = {};
|
|
70
|
+
|
|
71
|
+
const Worker = new Role('Worker', ['execute', 'registry']);
|
|
72
|
+
|
|
73
|
+
const Manager = new Role('Manager', ['execute', 'delegate']);
|
|
74
|
+
|
|
75
|
+
const UserManager = new Agent({
|
|
76
|
+
name: 'UserManager',
|
|
77
|
+
role: Worker,
|
|
78
|
+
llm: { provider: "openai", model: "gpt-4o-mini" },
|
|
79
|
+
amnesia: true,
|
|
80
|
+
handlers: {
|
|
81
|
+
createAllUser: (() => {
|
|
82
|
+
const handler = async function(args) {
|
|
83
|
+
// This should not be called - playbook will be executed by LLM
|
|
84
|
+
throw new Error('Playbook-only handler called directly');
|
|
85
|
+
};
|
|
86
|
+
handler.__playbookOnly__ = true;
|
|
87
|
+
handler.__playbook__ = "Create all given users via args, with the following attributes\n - name, age, email\n\n Save all to registry with key \"user:id being id an unique identifier\".\n Include all fields plus a createdAt timestamp.\n Return: { \"success\": true, \"message\": \"Users created\" }\n\n DO NOT add print actions - just return the data.";
|
|
88
|
+
handler.__description__ = "Create multiple users with specified attributes and save them to the registry.";
|
|
89
|
+
return handler;
|
|
90
|
+
})(),
|
|
91
|
+
createUser: (() => {
|
|
92
|
+
const handler = async function(args) {
|
|
93
|
+
// This should not be called - playbook will be executed by LLM
|
|
94
|
+
throw new Error('Playbook-only handler called directly');
|
|
95
|
+
};
|
|
96
|
+
handler.__playbookOnly__ = true;
|
|
97
|
+
handler.__playbook__ = "Create a new user with:\n - name: ${args.name}\n - age: ${args.age}\n - email: ${args.email}\n\n Save to registry with key \"user:${args.id}\".\n Include all fields plus a createdAt timestamp.\n Return: { \"success\": true, \"message\": \"User created\" }\n\n DO NOT add print actions - just return the data.";
|
|
98
|
+
handler.__description__ = "Create a single user with specified attributes and save to the registry.";
|
|
99
|
+
return handler;
|
|
100
|
+
})(),
|
|
101
|
+
getUser: (() => {
|
|
102
|
+
const handler = async function(args) {
|
|
103
|
+
// This should not be called - playbook will be executed by LLM
|
|
104
|
+
throw new Error('Playbook-only handler called directly');
|
|
105
|
+
};
|
|
106
|
+
handler.__playbookOnly__ = true;
|
|
107
|
+
handler.__playbook__ = "Get user ${args.id} from registry.\n\n Use registry_get with key \"user:${args.id}\".\n Extract the .value field from the registry_get result (which contains the user data).\n Return ONLY the user data object (name, age, email, createdAt) without any wrapper.";
|
|
108
|
+
handler.__description__ = "Retrieve and return user data from the registry using the user's unique key.";
|
|
109
|
+
return handler;
|
|
110
|
+
})(),
|
|
111
|
+
listAllUsers: (() => {
|
|
112
|
+
const handler = async function(args) {
|
|
113
|
+
// This should not be called - playbook will be executed by LLM
|
|
114
|
+
throw new Error('Playbook-only handler called directly');
|
|
115
|
+
};
|
|
116
|
+
handler.__playbookOnly__ = true;
|
|
117
|
+
handler.__playbook__ = "List all users in the registry.\n\n EXACT STEPS:\n 1. Use registry_search with an empty query {} to get ALL users, store with ID \"a1\"\n 2. Extract just the user data (the .value field) from each result\n 3. Return: { \"count\": <count from a1>, \"users\": <array of user value objects, NOT the full {key, value} wrappers> }\n\n Example: If a1.output.results = [{key: \"user:001\", value: {name: \"Alice\", age: 30}}, ...]\n Then return: { \"count\": 2, \"users\": [{name: \"Alice\", age: 30}, ...] }\n\n CRITICAL: Extract ONLY the .value objects so caller can access with .users[0].name directly\n DO NOT use format action - return a real array!";
|
|
118
|
+
handler.__description__ = "List all users in the registry, returning their data without additional wrappers.";
|
|
119
|
+
return handler;
|
|
120
|
+
})(),
|
|
121
|
+
findAdults: (() => {
|
|
122
|
+
const handler = async function(args) {
|
|
123
|
+
// This should not be called - playbook will be executed by LLM
|
|
124
|
+
throw new Error('Playbook-only handler called directly');
|
|
125
|
+
};
|
|
126
|
+
handler.__playbookOnly__ = true;
|
|
127
|
+
handler.__playbook__ = "Find all users aged 18 or older using registry search with query: { \"age\": { \"$gte\": 18 } }\n\n EXACT STEPS:\n 1. Use registry_search with query: { \"age\": { \"$gte\": 18 } }\n 2. Return: { \"count\": [count from search], \"adults\": [results array] }\n\n DO NOT add print actions - just return the data!";
|
|
128
|
+
handler.__description__ = "Find and return all users aged 18 or older from the registry.";
|
|
129
|
+
return handler;
|
|
130
|
+
})(),
|
|
131
|
+
updateUserAge: (() => {
|
|
132
|
+
const handler = async function(args) {
|
|
133
|
+
// This should not be called - playbook will be executed by LLM
|
|
134
|
+
throw new Error('Playbook-only handler called directly');
|
|
135
|
+
};
|
|
136
|
+
handler.__playbookOnly__ = true;
|
|
137
|
+
handler.__playbook__ = "Update user ${args.id}'s age to ${args.age}.\n\n EXACT STEPS:\n 1. Use registry_get with key \"user:${args.id}\", store with ID \"a1\"\n 2. Take the full user object from \\${a1.output.value}\n 3. Modify ONLY the age field to ${args.age}, keep all other fields (name, email, createdAt, etc.)\n 4. Use registry_set with key \"user:${args.id}\" and the complete updated object\n 5. Return: { \"success\": true, \"message\": \"Age updated\" }\n\n CRITICAL: Preserve ALL existing fields when saving!";
|
|
138
|
+
handler.__description__ = "Update a user's age while preserving all other fields and save the updated object.";
|
|
139
|
+
return handler;
|
|
140
|
+
})(),
|
|
141
|
+
deleteUser: (() => {
|
|
142
|
+
const handler = async function(args) {
|
|
143
|
+
// This should not be called - playbook will be executed by LLM
|
|
144
|
+
throw new Error('Playbook-only handler called directly');
|
|
145
|
+
};
|
|
146
|
+
handler.__playbookOnly__ = true;
|
|
147
|
+
handler.__playbook__ = "Delete the user from the registry with ID ${args.id}.\n\n EXACT STEPS:\n 1. Use registry_delete with key \"user:\\${args.id}\"\n 2. Return: { \"success\": true, \"message\": \"User deleted\" }";
|
|
148
|
+
handler.__description__ = "Delete a user from the registry using their unique identifier.";
|
|
149
|
+
return handler;
|
|
150
|
+
})(),
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const RegistryTeam = new Team('RegistryTeam', {
|
|
155
|
+
userManager: UserManager,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const Demo = new Agent({
|
|
159
|
+
name: 'Demo',
|
|
160
|
+
role: Manager,
|
|
161
|
+
usesTeams: [RegistryTeam],
|
|
162
|
+
peers: RegistryTeam, // Auto-assigned from uses Team
|
|
163
|
+
llm: { provider: "openai", model: "gpt-4o-mini" },
|
|
164
|
+
handlers: {
|
|
165
|
+
start: (() => {
|
|
166
|
+
const handler = async function(args) {
|
|
167
|
+
// This should not be called - playbook will be executed by LLM
|
|
168
|
+
throw new Error('Playbook-only handler called directly');
|
|
169
|
+
};
|
|
170
|
+
handler.__playbookOnly__ = true;
|
|
171
|
+
handler.__playbook__ = "Run a user registry demo.\n\n Show the header (just the very first time):\n ╔══════════════════════════════════════════════════╗\n ║ Registry with Playbook Demo ║\n ╚══════════════════════════════════════════════════╝\n\n Them ask the user what it wants: create / consult / modify / delete any user and do what the user wants.\n Aks as many info as you need to the user to perform the action the user wants from you.\n\n After performing an action, ask the user if it want to continuer, and in that case ask again what it wants (loop)\n\n 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}\"\n\n Before exiting, print:\n ╔══════════════════════════════════════════════════╗\n ║ Demo completed successfully! ║\n ╚══════════════════════════════════════════════════╝";
|
|
172
|
+
handler.__description__ = "Run a user registry demo, guiding the user through various actions and displaying results.";
|
|
173
|
+
return handler;
|
|
174
|
+
})(),
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
// Main execution function
|
|
180
|
+
(async () => {
|
|
181
|
+
// Register agents with router
|
|
182
|
+
const { agentRouter } = await import('file:///Users/antonioparraga/Git/Koi-lang/Koi/src/runtime/router.js');
|
|
183
|
+
|
|
184
|
+
await agentRouter.register(UserManager, CACHED_AFFORDANCES['UserManager']);
|
|
185
|
+
await agentRouter.register(Demo, CACHED_AFFORDANCES['Demo']);
|
|
186
|
+
|
|
187
|
+
// Execute
|
|
188
|
+
const result = await Demo.handle('start', {});
|
|
189
|
+
// Result handled by actions
|
|
190
|
+
|
|
191
|
+
const _gracefulShutdown = async () => { await mcpRegistry.disconnectAll(); process.exit(0); };
|
|
192
|
+
process.on('SIGINT', _gracefulShutdown);
|
|
193
|
+
process.on('SIGTERM', _gracefulShutdown);
|
|
194
|
+
|
|
195
|
+
await mcpRegistry.disconnectAll();
|
|
196
|
+
process.exit(0);
|
|
197
|
+
})().catch(err => {
|
|
198
|
+
console.error('Error:', err.message);
|
|
199
|
+
process.exit(1);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
//# sourceMappingURL=registry-interactive-demo.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["registry-interactive-demo.koi"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA;;AACA;;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkGA;;;;AAKA","file":"registry-interactive-demo.koi.js"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// Generated from registry-playbook-demo.koi
|
|
2
|
+
// Using local runtime from KOI_RUNTIME_PATH: /Users/antonioparraga/Git/Koi-lang/Koi/src/runtime
|
|
3
|
+
import { Agent, Team, Skill, Role, Runtime, SkillRegistry, skillSelector, registry, mcpRegistry } from 'file:///Users/antonioparraga/Git/Koi-lang/Koi/src/runtime/index.js';
|
|
4
|
+
import { createRequire } from 'module';
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
|
|
7
|
+
globalThis.SkillRegistry = SkillRegistry;
|
|
8
|
+
globalThis.skillSelector = skillSelector;
|
|
9
|
+
globalThis.registry = registry;
|
|
10
|
+
globalThis.mcpRegistry = mcpRegistry;
|
|
11
|
+
|
|
12
|
+
// ============================================================
|
|
13
|
+
// Pre-computed Affordances (Build-time Cache)
|
|
14
|
+
// Generated at: 2026-02-16T17:31:22.509Z
|
|
15
|
+
// Total agents: 2
|
|
16
|
+
// Total agent affordances: 8
|
|
17
|
+
// Total skills: 0
|
|
18
|
+
// Total skill affordances: 0
|
|
19
|
+
// This avoids embedding API calls at runtime
|
|
20
|
+
// ============================================================
|
|
21
|
+
|
|
22
|
+
const CACHED_AFFORDANCES = {
|
|
23
|
+
"UserManager": {
|
|
24
|
+
"createAllUser": {
|
|
25
|
+
"description": "Create multiple users with specified attributes and save them to the registry.",
|
|
26
|
+
"confidence": 0.9,
|
|
27
|
+
"hasPlaybook": true
|
|
28
|
+
},
|
|
29
|
+
"createUser": {
|
|
30
|
+
"description": "Create a single user with specified attributes and save to the registry.",
|
|
31
|
+
"confidence": 0.9,
|
|
32
|
+
"hasPlaybook": true
|
|
33
|
+
},
|
|
34
|
+
"getUser": {
|
|
35
|
+
"description": "Retrieve and return user data from the registry using the user's unique key.",
|
|
36
|
+
"confidence": 0.9,
|
|
37
|
+
"hasPlaybook": true
|
|
38
|
+
},
|
|
39
|
+
"listAllUsers": {
|
|
40
|
+
"description": "List all users in the registry and return their data without wrappers.",
|
|
41
|
+
"confidence": 0.9,
|
|
42
|
+
"hasPlaybook": true
|
|
43
|
+
},
|
|
44
|
+
"findAdults": {
|
|
45
|
+
"description": "Find and return all users aged 18 or older from the registry.",
|
|
46
|
+
"confidence": 0.9,
|
|
47
|
+
"hasPlaybook": true
|
|
48
|
+
},
|
|
49
|
+
"updateUserAge": {
|
|
50
|
+
"description": "Update a user's age while preserving all other fields and save the updated object.",
|
|
51
|
+
"confidence": 0.9,
|
|
52
|
+
"hasPlaybook": true
|
|
53
|
+
},
|
|
54
|
+
"deleteUser": {
|
|
55
|
+
"description": "Delete a user from the registry using their unique identifier.",
|
|
56
|
+
"confidence": 0.9,
|
|
57
|
+
"hasPlaybook": true
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"Demo": {
|
|
61
|
+
"start": {
|
|
62
|
+
"description": "Run a demo showcasing user creation, retrieval, listing, searching, updating, and deletion.",
|
|
63
|
+
"confidence": 0.9,
|
|
64
|
+
"hasPlaybook": true
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const CACHED_SKILL_AFFORDANCES = {};
|
|
70
|
+
|
|
71
|
+
const Worker = new Role('Worker', ['execute', 'registry']);
|
|
72
|
+
|
|
73
|
+
const Manager = new Role('Manager', ['execute', 'delegate']);
|
|
74
|
+
|
|
75
|
+
const UserManager = new Agent({
|
|
76
|
+
name: 'UserManager',
|
|
77
|
+
role: Worker,
|
|
78
|
+
llm: { provider: "openai", model: "gpt-4o-mini" },
|
|
79
|
+
handlers: {
|
|
80
|
+
createAllUser: (() => {
|
|
81
|
+
const handler = async function(args) {
|
|
82
|
+
// This should not be called - playbook will be executed by LLM
|
|
83
|
+
throw new Error('Playbook-only handler called directly');
|
|
84
|
+
};
|
|
85
|
+
handler.__playbookOnly__ = true;
|
|
86
|
+
handler.__playbook__ = "Create all given users via args, with the following attributes\n - name, age, email\n\n Save all to registry with key \"user:id being id an unique identifier\".\n Include all fields plus a createdAt timestamp.\n Return: { \"success\": true, \"message\": \"Users created\" }\n\n DO NOT add print actions - just return the data.";
|
|
87
|
+
handler.__description__ = "Create multiple users with specified attributes and save them to the registry.";
|
|
88
|
+
return handler;
|
|
89
|
+
})(),
|
|
90
|
+
createUser: (() => {
|
|
91
|
+
const handler = async function(args) {
|
|
92
|
+
// This should not be called - playbook will be executed by LLM
|
|
93
|
+
throw new Error('Playbook-only handler called directly');
|
|
94
|
+
};
|
|
95
|
+
handler.__playbookOnly__ = true;
|
|
96
|
+
handler.__playbook__ = "Create a new user with:\n - name: ${args.name}\n - age: ${args.age}\n - email: ${args.email}\n\n Save to registry with key \"user:${args.id}\".\n Include all fields plus a createdAt timestamp.\n Return: { \"success\": true, \"message\": \"User created\" }\n\n DO NOT add print actions - just return the data.";
|
|
97
|
+
handler.__description__ = "Create a single user with specified attributes and save to the registry.";
|
|
98
|
+
return handler;
|
|
99
|
+
})(),
|
|
100
|
+
getUser: (() => {
|
|
101
|
+
const handler = async function(args) {
|
|
102
|
+
// This should not be called - playbook will be executed by LLM
|
|
103
|
+
throw new Error('Playbook-only handler called directly');
|
|
104
|
+
};
|
|
105
|
+
handler.__playbookOnly__ = true;
|
|
106
|
+
handler.__playbook__ = "Get user ${args.id} from registry.\n\n Use registry_get with key \"user:${args.id}\".\n Extract the .value field from the registry_get result (which contains the user data).\n Return ONLY the user data object (name, age, email, createdAt) without any wrapper.";
|
|
107
|
+
handler.__description__ = "Retrieve and return user data from the registry using the user's unique key.";
|
|
108
|
+
return handler;
|
|
109
|
+
})(),
|
|
110
|
+
listAllUsers: (() => {
|
|
111
|
+
const handler = async function(args) {
|
|
112
|
+
// This should not be called - playbook will be executed by LLM
|
|
113
|
+
throw new Error('Playbook-only handler called directly');
|
|
114
|
+
};
|
|
115
|
+
handler.__playbookOnly__ = true;
|
|
116
|
+
handler.__playbook__ = "List all users in the registry.\n\n EXACT STEPS:\n 1. Use registry_search with an empty query {} to get ALL users, store with ID \"a1\"\n 2. Extract just the user data (the .value field) from each result\n 3. Return: { \"count\": <count from a1>, \"users\": <array of user value objects, NOT the full {key, value} wrappers> }\n\n Example: If a1.output.results = [{key: \"user:001\", value: {name: \"Alice\", age: 30}}, ...]\n Then return: { \"count\": 2, \"users\": [{name: \"Alice\", age: 30}, ...] }\n\n CRITICAL: Extract ONLY the .value objects so caller can access with .users[0].name directly\n DO NOT use format action - return a real array!";
|
|
117
|
+
handler.__description__ = "List all users in the registry and return their data without wrappers.";
|
|
118
|
+
return handler;
|
|
119
|
+
})(),
|
|
120
|
+
findAdults: (() => {
|
|
121
|
+
const handler = async function(args) {
|
|
122
|
+
// This should not be called - playbook will be executed by LLM
|
|
123
|
+
throw new Error('Playbook-only handler called directly');
|
|
124
|
+
};
|
|
125
|
+
handler.__playbookOnly__ = true;
|
|
126
|
+
handler.__playbook__ = "Find all users aged 18 or older using registry search with query: { \"age\": { \"$gte\": 18 } }\n\n EXACT STEPS:\n 1. Use registry_search with query: { \"age\": { \"$gte\": 18 } }\n 2. Return: { \"count\": [count from search], \"adults\": [results array] }\n\n DO NOT add print actions - just return the data!";
|
|
127
|
+
handler.__description__ = "Find and return all users aged 18 or older from the registry.";
|
|
128
|
+
return handler;
|
|
129
|
+
})(),
|
|
130
|
+
updateUserAge: (() => {
|
|
131
|
+
const handler = async function(args) {
|
|
132
|
+
// This should not be called - playbook will be executed by LLM
|
|
133
|
+
throw new Error('Playbook-only handler called directly');
|
|
134
|
+
};
|
|
135
|
+
handler.__playbookOnly__ = true;
|
|
136
|
+
handler.__playbook__ = "Update user ${args.id}'s age to ${args.age}.\n\n EXACT STEPS:\n 1. Use registry_get with key \"user:${args.id}\", store with ID \"a1\"\n 2. Take the full user object from \\${a1.output.value}\n 3. Modify ONLY the age field to ${args.age}, keep all other fields (name, email, createdAt, etc.)\n 4. Use registry_set with key \"user:${args.id}\" and the complete updated object\n 5. Return: { \"success\": true, \"message\": \"Age updated\" }\n\n CRITICAL: Preserve ALL existing fields when saving!";
|
|
137
|
+
handler.__description__ = "Update a user's age while preserving all other fields and save the updated object.";
|
|
138
|
+
return handler;
|
|
139
|
+
})(),
|
|
140
|
+
deleteUser: (() => {
|
|
141
|
+
const handler = async function(args) {
|
|
142
|
+
// This should not be called - playbook will be executed by LLM
|
|
143
|
+
throw new Error('Playbook-only handler called directly');
|
|
144
|
+
};
|
|
145
|
+
handler.__playbookOnly__ = true;
|
|
146
|
+
handler.__playbook__ = "Delete the user from the registry with ID ${args.id}.\n\n EXACT STEPS:\n 1. Use registry_delete with key \"user:\\${args.id}\"\n 2. Return: { \"success\": true, \"message\": \"User deleted\" }";
|
|
147
|
+
handler.__description__ = "Delete a user from the registry using their unique identifier.";
|
|
148
|
+
return handler;
|
|
149
|
+
})(),
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
const RegistryTeam = new Team('RegistryTeam', {
|
|
154
|
+
userManager: UserManager,
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
const Demo = new Agent({
|
|
158
|
+
name: 'Demo',
|
|
159
|
+
role: Manager,
|
|
160
|
+
usesTeams: [RegistryTeam],
|
|
161
|
+
peers: RegistryTeam, // Auto-assigned from uses Team
|
|
162
|
+
llm: { provider: "openai", model: "gpt-4o-mini" },
|
|
163
|
+
handlers: {
|
|
164
|
+
start: (() => {
|
|
165
|
+
const handler = async function(args) {
|
|
166
|
+
// This should not be called - playbook will be executed by LLM
|
|
167
|
+
throw new Error('Playbook-only handler called directly');
|
|
168
|
+
};
|
|
169
|
+
handler.__playbookOnly__ = true;
|
|
170
|
+
handler.__playbook__ = "Run a user registry demo.\n\n Show the header:\n ╔══════════════════════════════════════════════════╗\n ║ Registry with Playbook Demo ║\n ╚══════════════════════════════════════════════════╝\n\n 1️⃣ Create these users:\n - Alice: id=001, age=30, email=alice@example.com\n - Bob: id=002, 17 years old, bob@example.com\n - Charlie: id=003, age=25, email=charlie@example.com\n - Diana: id=004, age is 35, diana@example.com\n - Erika: id=005, age=28, email=erika@example.com\n - Fernando: id=006, age=32, fernando@example.com\n Show: \" ✅ X users created\" where X is the number of users that were created\n\n 2️⃣ Get user 001\n Show: \" ✅ Found user: {the user's name}, age {their age}\"\n\n 3️⃣ List all users\n 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}\"\n\n 4️⃣ Search for users older than 18 years\n Show: \" ✅ Found {the number found} adults\"\n\n 5️⃣ Update Bob's age (002) to 19 years old\n Then get the updated user\n Show: \" ✅ Bob is now {his new age} years old\"\n\n 6️⃣ Delete Charlie (003)\n Then list the remaining users\n Show: \" ✅ Remaining users: {the remaining count}\"\n\n 7️⃣ List all users again as you did in step 3️⃣\n Show the users in a markdown table with the same format as in step 3️⃣\n\n Show the footer:\n ╔══════════════════════════════════════════════════╗\n ║ Demo completed successfully! ║\n ╚══════════════════════════════════════════════════╝";
|
|
171
|
+
handler.__description__ = "Run a demo showcasing user creation, retrieval, listing, searching, updating, and deletion.";
|
|
172
|
+
return handler;
|
|
173
|
+
})(),
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
// Main execution function
|
|
179
|
+
(async () => {
|
|
180
|
+
// Register agents with router
|
|
181
|
+
const { agentRouter } = await import('file:///Users/antonioparraga/Git/Koi-lang/Koi/src/runtime/router.js');
|
|
182
|
+
|
|
183
|
+
await agentRouter.register(UserManager, CACHED_AFFORDANCES['UserManager']);
|
|
184
|
+
await agentRouter.register(Demo, CACHED_AFFORDANCES['Demo']);
|
|
185
|
+
|
|
186
|
+
// Execute
|
|
187
|
+
const result = await Demo.handle('start', {});
|
|
188
|
+
// Result handled by actions
|
|
189
|
+
|
|
190
|
+
const _gracefulShutdown = async () => { await mcpRegistry.disconnectAll(); process.exit(0); };
|
|
191
|
+
process.on('SIGINT', _gracefulShutdown);
|
|
192
|
+
process.on('SIGTERM', _gracefulShutdown);
|
|
193
|
+
|
|
194
|
+
await mcpRegistry.disconnectAll();
|
|
195
|
+
process.exit(0);
|
|
196
|
+
})().catch(err => {
|
|
197
|
+
console.error('Error:', err.message);
|
|
198
|
+
process.exit(1);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
//# sourceMappingURL=registry-playbook-demo.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["registry-playbook-demo.koi"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA;;AACA;;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiGA;;;;AAKA","file":"registry-playbook-demo.koi.js"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Generated from tic-tac-toe.koi
|
|
2
|
+
// Using local runtime from KOI_RUNTIME_PATH: /Users/antonioparraga/Git/Koi-lang/Koi/src/runtime
|
|
3
|
+
import { Agent, Team, Skill, Role, Runtime, SkillRegistry, skillSelector, registry, mcpRegistry } from 'file:///Users/antonioparraga/Git/Koi-lang/Koi/src/runtime/index.js';
|
|
4
|
+
import { createRequire } from 'module';
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
|
|
7
|
+
globalThis.SkillRegistry = SkillRegistry;
|
|
8
|
+
globalThis.skillSelector = skillSelector;
|
|
9
|
+
globalThis.registry = registry;
|
|
10
|
+
globalThis.mcpRegistry = mcpRegistry;
|
|
11
|
+
|
|
12
|
+
// ============================================================
|
|
13
|
+
// Pre-computed Affordances (Build-time Cache)
|
|
14
|
+
// Generated at: 2026-02-16T18:23:23.268Z
|
|
15
|
+
// Total agents: 1
|
|
16
|
+
// Total agent affordances: 1
|
|
17
|
+
// Total skills: 0
|
|
18
|
+
// Total skill affordances: 0
|
|
19
|
+
// This avoids embedding API calls at runtime
|
|
20
|
+
// ============================================================
|
|
21
|
+
|
|
22
|
+
const CACHED_AFFORDANCES = {
|
|
23
|
+
"Assistant": {
|
|
24
|
+
"test_while": {
|
|
25
|
+
"description": "Plays tic-tac-toe by alternating moves, showing the board each turn, until win or stop.",
|
|
26
|
+
"confidence": 0.9,
|
|
27
|
+
"hasPlaybook": true
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const CACHED_SKILL_AFFORDANCES = {};
|
|
33
|
+
|
|
34
|
+
const Worker = new Role('Worker', ['execute']);
|
|
35
|
+
|
|
36
|
+
const Assistant = new Agent({
|
|
37
|
+
name: 'Assistant',
|
|
38
|
+
role: Worker,
|
|
39
|
+
llm: { provider: "openai", model: "gpt-5.2" },
|
|
40
|
+
handlers: {
|
|
41
|
+
test_while: (() => {
|
|
42
|
+
const handler = async function(args) {
|
|
43
|
+
// This should not be called - playbook will be executed by LLM
|
|
44
|
+
throw new Error('Playbook-only handler called directly');
|
|
45
|
+
};
|
|
46
|
+
handler.__playbookOnly__ = true;
|
|
47
|
+
handler.__playbook__ = "Play tic-tac-toe with the user.\n On each turn you show the board, and the user says where to move with a combination like A2, B3\n Then you make your move and show the board as it looks after your move.\n End the game when someone wins or if the user expresses their wish to stop.";
|
|
48
|
+
handler.__description__ = "Plays tic-tac-toe by alternating moves, showing the board each turn, until win or stop.";
|
|
49
|
+
return handler;
|
|
50
|
+
})(),
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
// Main execution function
|
|
56
|
+
(async () => {
|
|
57
|
+
// Register agents with router
|
|
58
|
+
const { agentRouter } = await import('file:///Users/antonioparraga/Git/Koi-lang/Koi/src/runtime/router.js');
|
|
59
|
+
|
|
60
|
+
await agentRouter.register(Assistant, CACHED_AFFORDANCES['Assistant']);
|
|
61
|
+
|
|
62
|
+
// Execute
|
|
63
|
+
const result = await Assistant.handle('test_while', {});
|
|
64
|
+
// Result handled by actions
|
|
65
|
+
|
|
66
|
+
const _gracefulShutdown = async () => { await mcpRegistry.disconnectAll(); process.exit(0); };
|
|
67
|
+
process.on('SIGINT', _gracefulShutdown);
|
|
68
|
+
process.on('SIGTERM', _gracefulShutdown);
|
|
69
|
+
|
|
70
|
+
await mcpRegistry.disconnectAll();
|
|
71
|
+
process.exit(0);
|
|
72
|
+
})().catch(err => {
|
|
73
|
+
console.error('Error:', err.message);
|
|
74
|
+
process.exit(1);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
//# sourceMappingURL=tic-tac-toe.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["tic-tac-toe.koi"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA;;AAEA","file":"tic-tac-toe.koi.js"}
|