@kadi.build/core 0.0.1-alpha.1 → 0.0.1-alpha.11

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 (199) hide show
  1. package/README.md +361 -230
  2. package/dist/abilities/AbilityCache.d.ts +242 -0
  3. package/dist/abilities/AbilityCache.d.ts.map +1 -0
  4. package/dist/abilities/AbilityCache.js +285 -0
  5. package/dist/abilities/AbilityCache.js.map +1 -0
  6. package/dist/abilities/AbilityContext.d.ts +215 -0
  7. package/dist/abilities/AbilityContext.d.ts.map +1 -0
  8. package/dist/abilities/AbilityContext.js +36 -0
  9. package/dist/abilities/AbilityContext.js.map +1 -0
  10. package/dist/abilities/AbilityLoader.d.ts +203 -0
  11. package/dist/abilities/AbilityLoader.d.ts.map +1 -0
  12. package/dist/abilities/AbilityLoader.js +343 -0
  13. package/dist/abilities/AbilityLoader.js.map +1 -0
  14. package/dist/abilities/AbilityProxy.d.ts +496 -0
  15. package/dist/abilities/AbilityProxy.d.ts.map +1 -0
  16. package/dist/abilities/AbilityProxy.js +551 -0
  17. package/dist/abilities/AbilityProxy.js.map +1 -0
  18. package/dist/abilities/AbilityValidator.d.ts +172 -0
  19. package/dist/abilities/AbilityValidator.d.ts.map +1 -0
  20. package/dist/abilities/AbilityValidator.js +253 -0
  21. package/dist/abilities/AbilityValidator.js.map +1 -0
  22. package/dist/abilities/index.d.ts +26 -0
  23. package/dist/abilities/index.d.ts.map +1 -0
  24. package/dist/abilities/index.js +23 -0
  25. package/dist/abilities/index.js.map +1 -0
  26. package/dist/abilities/types.d.ts +223 -0
  27. package/dist/abilities/types.d.ts.map +1 -0
  28. package/dist/abilities/types.js +10 -0
  29. package/dist/abilities/types.js.map +1 -0
  30. package/dist/api/index.d.ts +92 -0
  31. package/dist/api/index.d.ts.map +1 -0
  32. package/dist/api/index.js +124 -0
  33. package/dist/api/index.js.map +1 -0
  34. package/dist/broker/BrokerConnection.d.ts +253 -0
  35. package/dist/broker/BrokerConnection.d.ts.map +1 -0
  36. package/dist/broker/BrokerConnection.js +434 -0
  37. package/dist/broker/BrokerConnection.js.map +1 -0
  38. package/dist/broker/BrokerConnectionManager.d.ts +216 -0
  39. package/dist/broker/BrokerConnectionManager.d.ts.map +1 -0
  40. package/dist/broker/BrokerConnectionManager.js +305 -0
  41. package/dist/broker/BrokerConnectionManager.js.map +1 -0
  42. package/dist/broker/BrokerProtocol.d.ts +280 -0
  43. package/dist/broker/BrokerProtocol.d.ts.map +1 -0
  44. package/dist/broker/BrokerProtocol.js +466 -0
  45. package/dist/broker/BrokerProtocol.js.map +1 -0
  46. package/dist/broker/index.d.ts +9 -0
  47. package/dist/broker/index.d.ts.map +1 -0
  48. package/dist/broker/index.js +9 -0
  49. package/dist/broker/index.js.map +1 -0
  50. package/dist/client/KadiClient.d.ts +459 -0
  51. package/dist/client/KadiClient.d.ts.map +1 -0
  52. package/dist/client/KadiClient.js +902 -0
  53. package/dist/client/KadiClient.js.map +1 -0
  54. package/dist/client/index.d.ts +7 -0
  55. package/dist/client/index.d.ts.map +1 -0
  56. package/dist/client/index.js +7 -0
  57. package/dist/client/index.js.map +1 -0
  58. package/dist/config/ConfigLoader.d.ts +138 -0
  59. package/dist/config/ConfigLoader.d.ts.map +1 -0
  60. package/dist/config/ConfigLoader.js +226 -0
  61. package/dist/config/ConfigLoader.js.map +1 -0
  62. package/dist/config/ConfigResolver.d.ts +135 -0
  63. package/dist/config/ConfigResolver.d.ts.map +1 -0
  64. package/dist/config/ConfigResolver.js +282 -0
  65. package/dist/config/ConfigResolver.js.map +1 -0
  66. package/dist/config/index.d.ts +8 -0
  67. package/dist/config/index.d.ts.map +1 -0
  68. package/dist/config/index.js +8 -0
  69. package/dist/config/index.js.map +1 -0
  70. package/dist/errors/index.d.ts +9 -0
  71. package/dist/errors/index.d.ts.map +1 -0
  72. package/dist/errors/index.js +8 -0
  73. package/dist/errors/index.js.map +1 -0
  74. package/dist/events/EventHub.d.ts +172 -0
  75. package/dist/events/EventHub.d.ts.map +1 -0
  76. package/dist/events/EventHub.js +333 -0
  77. package/dist/events/EventHub.js.map +1 -0
  78. package/dist/events/index.d.ts +7 -0
  79. package/dist/events/index.d.ts.map +1 -0
  80. package/dist/events/index.js +7 -0
  81. package/dist/events/index.js.map +1 -0
  82. package/dist/index.d.ts +50 -0
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +67 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/messages/index.d.ts +33 -0
  87. package/dist/messages/index.d.ts.map +1 -0
  88. package/dist/messages/index.js +33 -0
  89. package/dist/messages/index.js.map +1 -0
  90. package/dist/schemas/index.d.ts +22 -0
  91. package/dist/schemas/index.d.ts.map +1 -0
  92. package/dist/schemas/index.js +27 -0
  93. package/dist/schemas/index.js.map +1 -0
  94. package/dist/schemas/kadi-extensions.d.ts +231 -0
  95. package/dist/schemas/kadi-extensions.d.ts.map +1 -0
  96. package/dist/schemas/kadi-extensions.js +14 -0
  97. package/dist/schemas/kadi-extensions.js.map +1 -0
  98. package/dist/schemas/mcp/schema.d.ts +1399 -0
  99. package/dist/schemas/mcp/schema.d.ts.map +1 -0
  100. package/dist/schemas/mcp/schema.js +53 -0
  101. package/dist/schemas/mcp/schema.js.map +1 -0
  102. package/dist/schemas/mcp/version.d.ts +37 -0
  103. package/dist/schemas/mcp/version.d.ts.map +1 -0
  104. package/dist/schemas/mcp/version.js +39 -0
  105. package/dist/schemas/mcp/version.js.map +1 -0
  106. package/dist/schemas/schema-builders.d.ts +178 -0
  107. package/dist/schemas/schema-builders.d.ts.map +1 -0
  108. package/dist/schemas/schema-builders.js +258 -0
  109. package/dist/schemas/schema-builders.js.map +1 -0
  110. package/dist/schemas/zod-helpers.d.ts +129 -0
  111. package/dist/schemas/zod-helpers.d.ts.map +1 -0
  112. package/dist/schemas/zod-helpers.js +225 -0
  113. package/dist/schemas/zod-helpers.js.map +1 -0
  114. package/dist/schemas/zod-to-json-schema.d.ts +159 -0
  115. package/dist/schemas/zod-to-json-schema.d.ts.map +1 -0
  116. package/dist/schemas/zod-to-json-schema.js +154 -0
  117. package/dist/schemas/zod-to-json-schema.js.map +1 -0
  118. package/dist/tools/ToolRegistry.d.ts +256 -0
  119. package/dist/tools/ToolRegistry.d.ts.map +1 -0
  120. package/dist/tools/ToolRegistry.js +340 -0
  121. package/dist/tools/ToolRegistry.js.map +1 -0
  122. package/dist/tools/index.d.ts +7 -0
  123. package/dist/tools/index.d.ts.map +1 -0
  124. package/dist/tools/index.js +7 -0
  125. package/dist/tools/index.js.map +1 -0
  126. package/dist/transports/BrokerTransport.d.ts +151 -0
  127. package/dist/transports/BrokerTransport.d.ts.map +1 -0
  128. package/dist/transports/BrokerTransport.js +261 -0
  129. package/dist/transports/BrokerTransport.js.map +1 -0
  130. package/dist/transports/NativeTransport.d.ts +178 -0
  131. package/dist/transports/NativeTransport.d.ts.map +1 -0
  132. package/dist/transports/NativeTransport.js +397 -0
  133. package/dist/transports/NativeTransport.js.map +1 -0
  134. package/dist/transports/StdioTransport.d.ts +250 -0
  135. package/dist/transports/StdioTransport.d.ts.map +1 -0
  136. package/dist/transports/StdioTransport.js +487 -0
  137. package/dist/transports/StdioTransport.js.map +1 -0
  138. package/dist/transports/index.d.ts +10 -0
  139. package/dist/transports/index.d.ts.map +1 -0
  140. package/dist/transports/index.js +9 -0
  141. package/dist/transports/index.js.map +1 -0
  142. package/dist/types/broker.d.ts +279 -0
  143. package/dist/types/broker.d.ts.map +1 -0
  144. package/dist/types/broker.js +19 -0
  145. package/dist/types/broker.js.map +1 -0
  146. package/dist/types/config.d.ts +325 -0
  147. package/dist/types/config.d.ts.map +1 -0
  148. package/dist/types/config.js +17 -0
  149. package/dist/types/config.js.map +1 -0
  150. package/dist/types/errors.d.ts +178 -0
  151. package/dist/types/errors.d.ts.map +1 -0
  152. package/dist/types/errors.js +165 -0
  153. package/dist/types/errors.js.map +1 -0
  154. package/dist/types/events.d.ts +210 -0
  155. package/dist/types/events.d.ts.map +1 -0
  156. package/dist/types/events.js +8 -0
  157. package/dist/types/events.js.map +1 -0
  158. package/dist/types/index.d.ts +34 -0
  159. package/dist/types/index.d.ts.map +1 -0
  160. package/dist/types/index.js +21 -0
  161. package/dist/types/index.js.map +1 -0
  162. package/dist/types/protocol.d.ts +48 -0
  163. package/dist/types/protocol.d.ts.map +1 -0
  164. package/dist/types/protocol.js +11 -0
  165. package/dist/types/protocol.js.map +1 -0
  166. package/dist/types/tools.d.ts +67 -0
  167. package/dist/types/tools.d.ts.map +1 -0
  168. package/dist/types/tools.js +16 -0
  169. package/dist/types/tools.js.map +1 -0
  170. package/dist/types/transport.d.ts +250 -0
  171. package/dist/types/transport.d.ts.map +1 -0
  172. package/dist/types/transport.js +18 -0
  173. package/dist/types/transport.js.map +1 -0
  174. package/dist/types/zod-tools.d.ts +198 -0
  175. package/dist/types/zod-tools.d.ts.map +1 -0
  176. package/dist/types/zod-tools.js +14 -0
  177. package/dist/types/zod-tools.js.map +1 -0
  178. package/dist/utils/StdioMessageReader.d.ts +122 -0
  179. package/dist/utils/StdioMessageReader.d.ts.map +1 -0
  180. package/dist/utils/StdioMessageReader.js +209 -0
  181. package/dist/utils/StdioMessageReader.js.map +1 -0
  182. package/dist/utils/StdioMessageWriter.d.ts +104 -0
  183. package/dist/utils/StdioMessageWriter.d.ts.map +1 -0
  184. package/dist/utils/StdioMessageWriter.js +162 -0
  185. package/dist/utils/StdioMessageWriter.js.map +1 -0
  186. package/dist/validation/SchemaValidator.d.ts +208 -0
  187. package/dist/validation/SchemaValidator.d.ts.map +1 -0
  188. package/dist/validation/SchemaValidator.js +411 -0
  189. package/dist/validation/SchemaValidator.js.map +1 -0
  190. package/dist/validation/index.d.ts +11 -0
  191. package/dist/validation/index.d.ts.map +1 -0
  192. package/dist/validation/index.js +10 -0
  193. package/dist/validation/index.js.map +1 -0
  194. package/package.json +70 -5
  195. package/agent.json +0 -18
  196. package/broker.js +0 -214
  197. package/index.js +0 -370
  198. package/ipc.js +0 -220
  199. package/ipcInterfaces/pythonAbilityIPC.py +0 -177
package/README.md CHANGED
@@ -1,306 +1,437 @@
1
1
  # @kadi.build/core
2
2
 
3
- ---
4
-
5
- The `@kadi.build/core` module is a comprehensive toolkit for developers integrating with the KADI infrastructure. This module simplifies tasks such as managing `agent.json` files, spawning processes, interacting with brokers, and handling interprocess communication (IPC).
6
-
7
- ## Features
3
+ > Framework for building distributed abilities with multiple transport protocols
8
4
 
9
- - **Agent JSON Management**: Manage configurations for tools, agents, or systems using KADI.
10
- - **Process Management**: Support launching and managing subprocesses.
11
- - **Multi-Broker Support**: Dynamic broker selection and management with environment/runtime configuration.
12
- - **Broker Interaction**: Facilitate communications with WebSocket brokers.
13
- - **IPC Support**: Tools for interprocess communication across various programming languages.
5
+ [![npm version](https://img.shields.io/npm/v/@kadi.build/core.svg)](https://www.npmjs.com/package/@kadi.build/core)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
14
7
 
15
8
  ## Installation
16
9
 
17
- Install `@kadi.build/core` using npm:
18
-
19
10
  ```bash
20
11
  npm install @kadi.build/core
21
12
  ```
22
13
 
23
- ## Documentation
14
+ ## Quick Start
24
15
 
25
- ### Agent JSON Functions
16
+ ### Creating an Ability
26
17
 
27
- - **`getAbilityJSON(abilityName, abilityVersion)`**: Retrieves the `agent.json` for a specified ability.
28
- - **`getAbilityJSONPath(abilityName, abilityVersion)`**: Provides the file path to the `agent.json` for a specific ability.
29
- - **`getAbilityVersionFromArray(abilities, name)`**: Searches ability array provided, and returns the version number for name provided.
30
- - **`getAbilitiesDir()`**: Returns the directory path where abilities are stored.
31
- - **`getProjectJSON()`**: Fetches the `agent.json` for the current project.
32
- - **`getProjectJSONPath()`**: Gets the file path for the project's `agent.json`.
33
- - **`getKadiCoreJSON()`**: Retrieves the `agent.json` for the Kadi core.
34
- - **`getKadiCoreJSONPath()`**: Provides the file path to the Kadi core's `agent.json`.
35
- - **`getKadiJSON()`**: Fetches the `agent.json` for the Kadi system.
36
- - **`getKadiJSONPath()`**: Returns the file path for the Kadi system's `agent.json`.
18
+ ```javascript
19
+ import { KadiClient, z } from '@kadi.build/core';
37
20
 
38
- ### Broker Management Functions
21
+ const ability = new KadiClient({
22
+ name: 'math-ability',
23
+ version: '1.0.0'
24
+ });
39
25
 
40
- The broker management system allows dynamic selection from multiple configured brokers defined in `agent.json`:
26
+ // Register tool with Zod schemas (recommended)
27
+ ability.registerTool({
28
+ name: 'add',
29
+ description: 'Add two numbers',
30
+ input: z.object({
31
+ a: z.number().describe('First number'),
32
+ b: z.number().describe('Second number')
33
+ }),
34
+ output: z.object({
35
+ result: z.number().describe('Sum of a and b')
36
+ })
37
+ }, async ({ a, b }) => {
38
+ return { result: a + b };
39
+ });
41
40
 
42
- ```json
43
- {
44
- "brokers": {
45
- "local": "ws://127.0.0.1:8080",
46
- "remote": "ws://production.example.com:8080",
47
- "staging": "ws://staging.example.com:8080"
48
- }
49
- }
41
+ // Start serving (native, stdio, or broker)
42
+ await ability.serve('stdio');
50
43
  ```
51
44
 
52
- Available functions:
45
+ ### Loading and Using Abilities
46
+
47
+ ```javascript
48
+ import { loadAbility } from '@kadi.build/core';
53
49
 
54
- - **`KADI_BROKERS`**: Object containing all configured brokers with their parsed URLs.
55
- - **`KADI_BROKER_URL`**: Default broker URL (first one defined, for backward compatibility).
56
- - **`getBrokerUrl(brokerName)`**: Get URL for a specific broker by name. Returns `null` if not found.
57
- - **`getBrokerNames()`**: Get array of all available broker names.
58
- - **`setActiveBroker(brokerName)`**: Set the active broker for the session. Returns `true` if successful.
59
- - **`getActiveBrokerName()`**: Get the name of the currently active broker.
60
- - **`getActiveBrokerUrl()`**: Get the URL of the currently active broker.
61
- - **`getDefaultBrokerName()`**: Get the name of the default broker (first one defined).
62
- - **`selectBrokerFromEnv()`**: Set active broker from `KADI_BROKER` environment variable.
50
+ const math = await loadAbility('math-ability', 'stdio');
51
+ const result = await math.add({ a: 5, b: 3 });
52
+ console.log(result); // { result: 8 }
53
+ ```
63
54
 
64
- ### Process Management Functions
55
+ ## Tool Registration (Three Ways)
65
56
 
66
- - **`runExecCommand(name, version, command)`**: Executes a command for initializing abilities.
67
- - **`runSpawnCommand(name, version, command)`**: Uses `spawn` to execute commands for subprocesses.
57
+ ### 1. With Zod Schemas (Recommended)
68
58
 
69
- ## Usage Examples
59
+ Zod provides type-safe schemas with 70% less code than JSON Schema:
70
60
 
71
61
  ```javascript
72
- import {
73
- getProjectJSON,
74
- runExecCommand,
75
- IPCManager,
76
- Broker
77
- } from '@kadi.build/core';
78
-
79
- async function setupProject() {
80
- const projectConfig = getProjectJSON();
81
- console.log(projectConfig);
82
-
83
- await runExecCommand('example', '1.0', 'npm install');
84
-
85
- // Broker management examples
86
- console.log('Available brokers:', getBrokerNames());
87
- console.log('All brokers:', KADI_BROKERS);
88
-
89
- // Set active broker
90
- setActiveBroker('remote');
91
- console.log('Active broker:', getActiveBrokerUrl());
92
-
93
- // IPC setup
94
- const ipc = new IPCManager();
95
- ipc.createInstance('python', 'pythonScript.py', 'pythonInstance');
96
-
97
- // Traditional broker setup
98
- Broker.addBroker('ws://example.com', 'exampleBroker');
99
- let broker = Broker.getBroker('default');
100
- console.log(`Connected to ${broker.url}`);
101
- broker.send(
102
- BrokerMessageBuilder.setup(
103
- 'TestAgent',
104
- 'A Broker Testing Agent',
105
- null,
106
- null
107
- )
108
- );
109
- }
62
+ import { KadiClient, z } from '@kadi.build/core';
63
+
64
+ const ability = new KadiClient({ name: 'example' });
65
+
66
+ ability.registerTool({
67
+ name: 'processData',
68
+ description: 'Process user data',
69
+ version: '1.0.0',
70
+ input: z.object({
71
+ name: z.string().min(1).describe('User name'),
72
+ age: z.number().int().positive().optional().describe('User age'),
73
+ tags: z.array(z.string()).describe('User tags')
74
+ }),
75
+ output: z.object({
76
+ processed: z.boolean(),
77
+ data: z.record(z.unknown())
78
+ })
79
+ }, async (params) => {
80
+ // Automatic validation of inputs and outputs
81
+ return {
82
+ processed: true,
83
+ data: params
84
+ };
85
+ });
110
86
  ```
111
87
 
112
- ### Broker Functions
88
+ ### 2. With createTool() Helper
113
89
 
114
- - **`Broker`**: Manages interactions with broker systems.
115
- - **`IBroker`**: Broker instance interface with methods to manage its lifecycle and communications.
116
- - **`BrokerMessageBuilder`**: Assists in constructing messages for broker communication.
90
+ For advanced use cases with runtime validation:
117
91
 
118
- ## Broker Functions
92
+ ```javascript
93
+ import { createTool, z } from '@kadi.build/core';
94
+
95
+ const { definition, handler } = createTool({
96
+ name: 'convert',
97
+ description: 'Convert units',
98
+ input: z.object({
99
+ value: z.number(),
100
+ from: z.enum(['km', 'miles']),
101
+ to: z.enum(['km', 'miles'])
102
+ }),
103
+ output: z.object({
104
+ result: z.number(),
105
+ unit: z.string()
106
+ }),
107
+ handler: async ({ value, from, to }) => {
108
+ // Your logic here
109
+ return { result: value * 1.6, unit: to };
110
+ }
111
+ });
119
112
 
120
- The Broker system facilitates interaction between different agents and services within the Kadi environment.
113
+ ability.registerTool(definition, handler);
114
+ ```
121
115
 
122
- ### `Broker` Interface
116
+ ### 3. With JSON Schema (Backward Compatible)
123
117
 
124
- - **`addBroker(url, name = 'default')`**: Adds a new broker connection. If a broker with the same name exists, it will be reused.
125
- - **`disconnect(name = 'default')`**: Disconnects the broker specified by the name.
126
- - **`deleteBroker(name = 'default')`**: Deletes the broker specified by the name and closes its connection.
127
- - **`send(message, brokerName = 'default')`**: Sends a message through the broker specified by the name.
128
- - **`addEventListener(event, listener, brokerName = 'default')`**: Adds an event listener to the specified broker.
129
- - **`removeEventListener(event, listener, brokerName = 'default')`**: Removes an event listener from the specified broker.
130
- - **`removeAllListeners(brokerName = 'default')`**: Removes all event listeners from the specified broker.
131
- - **`getBroker(brokerName = 'default')`**: Retrieves a broker instance by name.
118
+ Traditional approach still supported:
132
119
 
133
- ### `IBroker` Instance
120
+ ```javascript
121
+ ability.registerTool({
122
+ name: 'greet',
123
+ description: 'Greet someone',
124
+ inputSchema: {
125
+ type: 'object',
126
+ properties: {
127
+ name: { type: 'string', description: 'Name to greet' }
128
+ },
129
+ required: ['name']
130
+ },
131
+ outputSchema: {
132
+ type: 'object',
133
+ properties: {
134
+ greeting: { type: 'string' }
135
+ }
136
+ }
137
+ }, async ({ name }) => {
138
+ return { greeting: `Hello, ${name}!` };
139
+ });
140
+ ```
134
141
 
135
- This class extends `EventEmitter` and manages individual broker connections:
142
+ ## Migration from JSON Schema to Zod
136
143
 
137
- - **`constructor(url, name)`**: Initializes a new broker connection.
138
- - **`send(message)`**: Sends a message through the WebSocket connection.
139
- - **`getConnectedAgents()`**: Retrieves a list of currently connected agents.
144
+ **Before (JSON Schema):**
145
+ ```javascript
146
+ // 64 lines of boilerplate
147
+ ability.registerTool({
148
+ name: 'deployToAkash',
149
+ description: 'Deploy to Akash Network',
150
+ inputSchema: {
151
+ type: 'object',
152
+ properties: {
153
+ profile: {
154
+ type: 'string',
155
+ description: 'Deployment profile name'
156
+ },
157
+ dryRun: {
158
+ type: 'boolean',
159
+ description: 'Preview without deploying',
160
+ default: false
161
+ },
162
+ verbose: {
163
+ type: 'boolean',
164
+ description: 'Enable verbose output',
165
+ default: false
166
+ }
167
+ },
168
+ required: ['profile']
169
+ },
170
+ outputSchema: {
171
+ type: 'object',
172
+ properties: {
173
+ success: { type: 'boolean' },
174
+ dseq: { type: 'string' },
175
+ services: {
176
+ type: 'array',
177
+ items: { type: 'string' }
178
+ }
179
+ }
180
+ }
181
+ }, handler);
182
+ ```
140
183
 
141
- ### `BrokerMessageBuilder`
184
+ **After (Zod):**
185
+ ```javascript
186
+ // 15 lines - clean and type-safe!
187
+ ability.registerTool({
188
+ name: 'deployToAkash',
189
+ description: 'Deploy to Akash Network',
190
+ input: z.object({
191
+ profile: z.string().describe('Deployment profile name'),
192
+ dryRun: z.boolean().default(false).describe('Preview without deploying'),
193
+ verbose: z.boolean().default(false).describe('Enable verbose output')
194
+ }),
195
+ output: z.object({
196
+ success: z.boolean(),
197
+ dseq: z.string(),
198
+ services: z.array(z.string())
199
+ })
200
+ }, handler);
201
+ ```
142
202
 
143
- Utility class for constructing broker messages:
203
+ **Result: 77% less code!**
144
204
 
145
- - **`create_message(type, data)`**: Creates a JSON string with the specified type and data.
146
- - **`message(to, content)`**: Constructs a message directed to a specific peer.
147
- - **`setup(name, description, limit, uuid)`**: Creates a setup message for registering the broker.
148
- - **`suspend()`**: Constructs a suspend message.
149
- - **`finish()`**: Constructs a finish message.
150
- - **`list()`**: Constructs a list message to request a list of connected agents.
205
+ ## Transport Protocols
151
206
 
152
- ### IPC Functions
207
+ KADI supports three transport protocols for different use cases:
153
208
 
154
- - **`IPCMessageBuilder`**: Constructs messages for IPC interactions.
155
- - **`IPCManager`**: Manages setup and lifecycle of IPC connections.
156
- - **`IAbilityIPC`**: Represents an IPC ability instance with methods to manage its lifecycle and communications.
209
+ ### Native (In-Process)
210
+ ```javascript
211
+ const ability = await loadAbility('my-ability', 'native');
212
+ // Direct function calls, zero IPC overhead
213
+ ```
157
214
 
158
- ### `IPCManager`
215
+ ### Stdio (Child Process)
216
+ ```javascript
217
+ const ability = await loadAbility('my-ability', 'stdio');
218
+ // JSON-RPC over stdin/stdout, language-agnostic
219
+ ```
159
220
 
160
- Manages the lifecycle and setup of interprocess communications.
221
+ ### Broker (Distributed)
222
+ ```javascript
223
+ const ability = await loadAbility('my-ability', 'broker', {
224
+ brokerUrl: 'ws://localhost:8080',
225
+ networks: ['global']
226
+ });
227
+ // WebSocket-based distributed communication
228
+ ```
161
229
 
162
- - **`createInstance(language, commandString, name = 'default')`**: Creates and manages a new IPC instance for the specified language.
163
- - **`getInstance(name)`**: Retrieves an existing IPC instance by name.
164
- - **`shutdownInstance(name)`**: Shuts down an existing IPC instance by name.
230
+ ## Events
165
231
 
166
- ### `IAbilityIPC` Instance
232
+ Publish and subscribe to events across all protocols:
167
233
 
168
- Manages an individual interprocess communication instance:
234
+ ```javascript
235
+ // Publishing events
236
+ ability.registerTool({
237
+ name: 'process',
238
+ input: z.object({ data: z.string() }),
239
+ output: z.object({ result: z.string() })
240
+ }, async (params) => {
241
+ // Publish progress events
242
+ await ability.publishEvent('process.started', { data: params.data });
243
+
244
+ const result = await doWork(params.data);
245
+
246
+ await ability.publishEvent('process.completed', { result });
247
+ return { result };
248
+ });
169
249
 
170
- - **`start()`**: Starts the child process associated with this IPC instance.
171
- - **`launch()`**: Sends the launch command to the associated process.
172
- - **`sendMessage(message)`**: Sends a JSON-formatted message to the child process.
173
- - **`shutdown()`**: Sends a shutdown command to the child process and terminates it.
250
+ // Subscribing to events
251
+ ability.subscribeToEvent('process.*', (data) => {
252
+ console.log('Process event:', data);
253
+ });
254
+ ```
174
255
 
175
- ### `IPCMessageBuilder`
256
+ ## Broker Mode
176
257
 
177
- Utility class for constructing IPC messages:
258
+ Connect to KADI broker for distributed communication:
178
259
 
179
- - **`createMessage(type, contents)`**: Creates a JSON string with the specified type and contents.
180
- - **`launch(commandString)`**: Constructs a launch message with the specified command string.
181
- - **`shutdown()`**: Constructs a shutdown message.
182
- - **`message(content)`**: Constructs a general message with the specified content.
260
+ ```javascript
261
+ const client = new KadiClient({
262
+ name: 'my-agent',
263
+ role: 'agent',
264
+ brokers: {
265
+ dev: 'ws://localhost:8080',
266
+ prod: 'ws://prod.example.com:8080'
267
+ },
268
+ defaultBroker: 'dev',
269
+ networks: ['global']
270
+ });
183
271
 
184
- ## Usage Examples
272
+ // Register tools
273
+ client.registerTool({
274
+ name: 'greet',
275
+ input: z.object({ name: z.string() }),
276
+ output: z.object({ greeting: z.string() })
277
+ }, async ({ name }) => {
278
+ return { greeting: `Hello, ${name}!` };
279
+ });
280
+
281
+ // Connect to broker
282
+ await client.serve('broker');
283
+
284
+ // Call remote tools
285
+ const result = await client.callTool('translator', 'translate', {
286
+ text: 'Hello',
287
+ to: 'es'
288
+ });
289
+ ```
185
290
 
186
- Here's how you might use the IPC and Broker functionalities:
291
+ ## API Reference
187
292
 
188
- ### Interacting with IPC
293
+ ### KadiClient
294
+
295
+ Main class for all KADI operations:
189
296
 
190
297
  ```javascript
191
- console.log('Starting IPC Ability Interface test...');
192
-
193
- // Create Python IPC instance
194
- const pythonIPC = IPCManager.createInstance(
195
- 'python',
196
- 'echo "Hello, World!"',
197
- 'pythonTest'
198
- );
199
-
200
- pythonIPC.on('error', (error) => {
201
- console.error('Handled Python Error:', error);
202
- // Consider appropriate error handling or recovery actions here
298
+ const client = new KadiClient({
299
+ name: 'my-ability',
300
+ version: '1.0.0',
301
+ role: 'ability', // 'agent' or 'ability'
302
+ brokers: { /* broker configs */ },
303
+ defaultBroker: 'dev',
304
+ networks: ['global']
203
305
  });
306
+ ```
204
307
 
205
- pythonIPC.on('critical-error', (error) => {
206
- console.error('Critical Error from Python:', error);
207
- // Handle critical errors, potentially restarting the process or alerting administrators
208
- });
308
+ **Methods:**
309
+ - `registerTool(definition, handler)` - Register a tool
310
+ - `serve(mode)` - Start serving ('native', 'stdio', 'broker')
311
+ - `callTool(agent, tool, params)` - Call remote tool
312
+ - `publishEvent(name, data)` - Publish event
313
+ - `subscribeToEvent(pattern, callback)` - Subscribe to events
314
+ - `loadAbility(name, protocol, options)` - Load another ability
209
315
 
210
- pythonIPC.on('message', (msg) => {
211
- console.log('Message from Python:', msg);
212
- });
316
+ ### loadAbility
213
317
 
214
- pythonIPC.on('broker', (msg) => {
215
- console.log('Broker message from Python:', msg);
216
- });
318
+ Load an ability by name and protocol:
217
319
 
218
- pythonIPC.on('shutdown', () => {
219
- console.log('Python IPC has shut down.');
320
+ ```javascript
321
+ const ability = await loadAbility('ability-name', 'protocol', {
322
+ brokerUrl: 'ws://localhost:8080',
323
+ networks: ['global']
220
324
  });
325
+ ```
326
+
327
+ ### createTool
328
+
329
+ Helper for creating tools with validation:
330
+
331
+ ```javascript
332
+ import { createTool, z } from '@kadi.build/core';
221
333
 
222
- Broker.addBroker('http://your.broker.com', 'default');
223
- let brk = Broker.getBroker('default');
224
- broker = brk;
225
-
226
- pythonIPC.attachBroker(brk);
227
-
228
- brk.on('open', function open() {
229
- console.log(`Connected to ${brk.url}`);
230
- const jsonObject = BrokerMessageBuilder.setup(
231
- 'TestAgent',
232
- 'A Broker Testing Agent',
233
- null,
234
- null
235
- );
236
- brk.send(jsonObject);
334
+ const { definition, handler } = createTool({
335
+ name: 'toolName',
336
+ input: z.object({ /* ... */ }),
337
+ output: z.object({ /* ... */ }),
338
+ handler: async (params) => { /* ... */ }
237
339
  });
340
+ ```
238
341
 
239
- brk.on('message', function incoming(data) {
240
- let msg = JSON.parse(data);
241
- if (msg.type == 'setup') {
242
- (async () => {
243
- try {
244
- await GetLLMProxy();
245
- } catch (error) {
246
- console.error('Error during GetLLMProxy:', error.message);
247
- }
248
- })();
342
+ ## Common Patterns
343
+
344
+ ### Error Handling
345
+
346
+ ```javascript
347
+ ability.registerTool({
348
+ name: 'riskyOperation',
349
+ input: z.object({ data: z.string() }),
350
+ output: z.object({
351
+ success: z.boolean(),
352
+ result: z.string().optional(),
353
+ error: z.string().optional()
354
+ })
355
+ }, async (params) => {
356
+ try {
357
+ const result = await performOperation(params.data);
358
+ return { success: true, result };
359
+ } catch (error) {
360
+ await ability.publishEvent('operation.error', {
361
+ error: error.message,
362
+ params
363
+ });
364
+ return { success: false, error: error.message };
249
365
  }
250
- // console.log('Received:', formatJSON(data));
251
366
  });
367
+ ```
252
368
 
253
- brk.on('error', function error(error) {
254
- console.error('WebSocket error:', error);
255
- });
369
+ ### Health Check
256
370
 
257
- brk.on('close', function close() {
258
- console.log('Disconnected from the server');
259
- process.exit(0); // Exit the process when the WebSocket connection is closed
371
+ ```javascript
372
+ ability.registerTool({
373
+ name: 'health',
374
+ input: z.object({}),
375
+ output: z.object({
376
+ status: z.string(),
377
+ uptime: z.number(),
378
+ memory: z.record(z.number())
379
+ })
380
+ }, async () => {
381
+ return {
382
+ status: 'healthy',
383
+ uptime: process.uptime(),
384
+ memory: process.memoryUsage()
385
+ };
260
386
  });
387
+ ```
261
388
 
262
- // Send launch command
389
+ ## Environment Variables
263
390
 
264
- //Utilize log files
265
- // pythonIPC.sendMessage(IPCMessageBuilder.launch(pythonIPC.commandString, process.cwd() + "/logs"));
391
+ ```bash
392
+ # Protocol selection
393
+ KADI_PROTOCOL=stdio
266
394
 
267
- //No log files created
268
- pythonIPC.sendMessage(IPCMessageBuilder.launch(pythonIPC.commandString));
395
+ # Broker configuration
396
+ KADI_BROKER_URL=ws://localhost:8080
397
+ KADI_AGENT_SCOPE=project-123
269
398
  ```
270
399
 
271
- ### Handling IPC
400
+ ## Debug Mode
272
401
 
273
- ```javascript
274
- const ipcManager = new IPCManager();
275
- const ipcInstance = ipcManager.createInstance('node', 'app.js', 'nodeApp');
276
- ipcInstance.on('message', (message) => console.log(message));
402
+ ```bash
403
+ DEBUG=kadi:* node index.js
277
404
  ```
278
405
 
406
+ ## Troubleshooting
407
+
408
+ ### Broker Connection Failures
409
+
410
+ - Verify broker URL is correct
411
+ - Check network connectivity
412
+ - Ensure broker is running
413
+
414
+ ### Events Not Arriving
415
+
416
+ - Subscribe BEFORE triggering events
417
+ - Verify pattern matching
418
+ - Check that publisher and subscriber are on same network
419
+
420
+ ### Type Errors with Zod
421
+
422
+ - Ensure Zod schemas match handler types
423
+ - Use `z.infer<typeof schema>` for TypeScript types
424
+ - Check that all required fields are provided
425
+
426
+ ## License
427
+
428
+ MIT
429
+
430
+ ## Related Projects
431
+
432
+ - [@kadi.build/cli](https://gitlab.com/humin-game-lab/kadi/kadi) - Command-line interface
433
+ - [@kadi.build/broker](https://gitlab.com/humin-game-lab/kadi/kadi-broker) - KADI broker
434
+
279
435
  ---
280
436
 
281
- ## TODO:
282
-
283
- - Once @kadi.build/core and dependencies are done, @kadi.build/cli (and all commands), need to be rewritten, using the @kadi.build/core module. this will be v1.0 release
284
-
285
- * [ ] add getConnectedAgents to the Broker, it should call the IBroker method
286
-
287
- * [x] add key to IBroker object
288
- * [ ] IBroker on 'message' should listen for setup event, and update teh uuid and key for the IBroker object
289
-
290
- * [ ] Extract Broker and IPC to their own node module and host on npm
291
- * [x] Publish @kadi.build/core to npm
292
- * [x] Setup of python environment needs to happen once an IPC Inteface is created
293
- This include setting up the virtual environment and installing the required packages
294
- * [x] Add method to IPCManger to set IPCInterfaces from agent.json. If IPCManger has empty list, it thorws an error that no IAbilityIPC's can be created. IPCManger passes the proper interface command to IAbilityIPC on creation from this list, IAbilityIPC does not need access directly to agent.json. Controlling app can update this list anytime a new IAbilityInterface is created, allowing the agent.json to be updated during runtime.
295
- * [x] Need to adapt ipc.js to read from the @kadi.build/core folder when trying to open IPC instances, instead of project folder. @kadi.build/core should be in the npm_modules folder (when deployed)
296
- * [x] The test code needs to fully test the IPCManger interface, and not just the IPCAbility
297
- * [x] If node fails, we need to make sure python IPC interface and child processes also close out.
298
- * [x] Add buffer to error handeling in IAbilityIPC, mimic same process used in std input
299
- * [x] Verify if Python IAbilityIPC needs to utilize buffering, and node passing '\n' at end of jso
300
- * [x] Setup passthrough for broker messages to/from Language IPC interface
301
- * [x] Add broker message builder/parser in python IAbilityIPC
302
- * [x] Update BrokerMessageBuilder to use same format at IPCMessageBuilder
303
- * [x] Update Broker so it extends EventEmitter, rather than have a property of event emitter (similar to IAbilityIPC)
304
- * [x] update python IAbility so that it creates a timestamped command_output.log file, new file for each run, in the project root directory... not the @kadi.build/core directory
305
- * [x] Comment out debug messages
306
- * [x] Add ability to allow for launched process to be piped to event handler (launch command should default to process, but allow user to set flag that will save all outputs to file in the event handler)
437
+ Built with ❤️ by the KADI team