@kadi.build/core 0.0.1-alpha.2 → 0.0.1-alpha.3
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 +1145 -216
- package/examples/example-abilities/echo-js/README.md +131 -0
- package/examples/example-abilities/echo-js/agent.json +63 -0
- package/examples/example-abilities/echo-js/package.json +24 -0
- package/examples/example-abilities/echo-js/service.js +43 -0
- package/examples/example-abilities/hash-go/agent.json +53 -0
- package/examples/example-abilities/hash-go/cmd/hash_ability/main.go +340 -0
- package/examples/example-abilities/hash-go/go.mod +3 -0
- package/examples/example-agent/abilities/echo-js/0.0.1/README.md +131 -0
- package/examples/example-agent/abilities/echo-js/0.0.1/agent.json +63 -0
- package/examples/example-agent/abilities/echo-js/0.0.1/package-lock.json +93 -0
- package/examples/example-agent/abilities/echo-js/0.0.1/package.json +24 -0
- package/examples/example-agent/abilities/echo-js/0.0.1/service.js +41 -0
- package/examples/example-agent/abilities/hash-go/0.0.1/agent.json +53 -0
- package/examples/example-agent/abilities/hash-go/0.0.1/bin/hash_ability +0 -0
- package/examples/example-agent/abilities/hash-go/0.0.1/cmd/hash_ability/main.go +340 -0
- package/examples/example-agent/abilities/hash-go/0.0.1/go.mod +3 -0
- package/examples/example-agent/agent.json +39 -0
- package/examples/example-agent/index.js +102 -0
- package/examples/example-agent/package-lock.json +93 -0
- package/examples/example-agent/package.json +17 -0
- package/package.json +4 -2
- package/src/KadiAbility.js +478 -0
- package/src/index.js +65 -0
- package/src/loadAbility.js +1086 -0
- package/src/servers/BaseRpcServer.js +404 -0
- package/src/servers/BrokerRpcServer.js +776 -0
- package/src/servers/StdioRpcServer.js +360 -0
- package/src/transport/BrokerMessageBuilder.js +377 -0
- package/src/transport/IpcMessageBuilder.js +1229 -0
- package/src/utils/agentUtils.js +137 -0
- package/src/utils/commandUtils.js +64 -0
- package/src/utils/configUtils.js +72 -0
- package/src/utils/logger.js +161 -0
- package/src/utils/pathUtils.js +86 -0
- package/broker.js +0 -214
- package/index.js +0 -382
- package/ipc.js +0 -220
- package/ipcInterfaces/pythonAbilityIPC.py +0 -177
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
// A minimal JSON-RPC 2.0 server over stdin/stdout for the "hash-go" ability.
|
|
2
|
+
// - Uses LSP-style framing: Kadi-Content-Length header + JSON body
|
|
3
|
+
// - Implements:
|
|
4
|
+
// __kadi_init : handshake/version negotiation
|
|
5
|
+
// __kadi_discover : returns functions/tools metadata
|
|
6
|
+
// digest : computes sha256/md5 hex digest of input text
|
|
7
|
+
//
|
|
8
|
+
// This follows the LSP-style protocol used by spawnJSONRPCProcess() in kadi-core.
|
|
9
|
+
|
|
10
|
+
package main
|
|
11
|
+
|
|
12
|
+
import (
|
|
13
|
+
"crypto/md5"
|
|
14
|
+
"crypto/sha256"
|
|
15
|
+
"encoding/hex"
|
|
16
|
+
"encoding/json"
|
|
17
|
+
"fmt"
|
|
18
|
+
"io"
|
|
19
|
+
"os"
|
|
20
|
+
"strconv"
|
|
21
|
+
"strings"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
// RPCRequest models a JSON-RPC request coming from the agent.
|
|
25
|
+
// ID is left as interface{} so we can echo back either number or string.
|
|
26
|
+
type RPCRequest struct {
|
|
27
|
+
JSONRPC string `json:"jsonrpc"`
|
|
28
|
+
ID interface{} `json:"id"`
|
|
29
|
+
Method string `json:"method"`
|
|
30
|
+
Params json.RawMessage `json:"params"`
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// RPCError is the error object defined by JSON-RPC 2.0.
|
|
34
|
+
type RPCError struct {
|
|
35
|
+
Code int `json:"code"`
|
|
36
|
+
Message string `json:"message"`
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// RPCResponse models a JSON-RPC response. Either Result or Error is present.
|
|
40
|
+
type RPCResponse struct {
|
|
41
|
+
JSONRPC string `json:"jsonrpc"`
|
|
42
|
+
ID interface{} `json:"id"`
|
|
43
|
+
Result interface{} `json:"result,omitempty"`
|
|
44
|
+
Error *RPCError `json:"error,omitempty"`
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// digestParams describes the input we expect for the "digest" method/tool.
|
|
48
|
+
type digestParams struct {
|
|
49
|
+
Text string `json:"text"`
|
|
50
|
+
Algo string `json:"algo"` // "sha256" (default) or "md5"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// toolSpec models an MCP-style tool descriptor.
|
|
54
|
+
type toolSpec struct {
|
|
55
|
+
Name string `json:"name"`
|
|
56
|
+
Title string `json:"title,omitempty"`
|
|
57
|
+
Description string `json:"description,omitempty"`
|
|
58
|
+
InputSchema map[string]interface{} `json:"inputSchema"`
|
|
59
|
+
OutputSchema map[string]interface{} `json:"outputSchema,omitempty"`
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
func main() {
|
|
63
|
+
// Loop forever: read LSP-style frames → handle → write response.
|
|
64
|
+
for {
|
|
65
|
+
// Read headers byte by byte until we find \r\n\r\n
|
|
66
|
+
headers := make(map[string]string)
|
|
67
|
+
headerData := make([]byte, 0)
|
|
68
|
+
|
|
69
|
+
// Read until we find the header delimiter \r\n\r\n
|
|
70
|
+
delimiter := []byte{'\r', '\n', '\r', '\n'}
|
|
71
|
+
for {
|
|
72
|
+
b := make([]byte, 1)
|
|
73
|
+
_, err := os.Stdin.Read(b)
|
|
74
|
+
if err != nil {
|
|
75
|
+
if err == io.EOF {
|
|
76
|
+
return // Clean exit
|
|
77
|
+
}
|
|
78
|
+
fmt.Fprintf(os.Stderr, "Error reading header byte: %v\n", err)
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
headerData = append(headerData, b[0])
|
|
82
|
+
|
|
83
|
+
// Check if we have the delimiter
|
|
84
|
+
if len(headerData) >= 4 {
|
|
85
|
+
if string(headerData[len(headerData)-4:]) == string(delimiter) {
|
|
86
|
+
break
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Parse headers (exclude the delimiter)
|
|
92
|
+
headerSection := string(headerData[:len(headerData)-4])
|
|
93
|
+
lines := strings.Split(headerSection, "\r\n")
|
|
94
|
+
|
|
95
|
+
for _, line := range lines {
|
|
96
|
+
if strings.Contains(line, ":") {
|
|
97
|
+
parts := strings.SplitN(line, ":", 2)
|
|
98
|
+
if len(parts) == 2 {
|
|
99
|
+
name := strings.TrimSpace(parts[0])
|
|
100
|
+
value := strings.TrimSpace(parts[1])
|
|
101
|
+
headers[name] = value
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Extract Content-Length
|
|
107
|
+
contentLengthStr, ok := headers["Kadi-Content-Length"]
|
|
108
|
+
if !ok {
|
|
109
|
+
fmt.Fprintf(os.Stderr, "Missing Content-Length header\n")
|
|
110
|
+
continue
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
contentLength, err := strconv.Atoi(contentLengthStr)
|
|
114
|
+
if err != nil {
|
|
115
|
+
fmt.Fprintf(os.Stderr, "Invalid Content-Length: %v\n", err)
|
|
116
|
+
continue
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Read the JSON body
|
|
120
|
+
body := make([]byte, contentLength)
|
|
121
|
+
_, err = io.ReadFull(os.Stdin, body)
|
|
122
|
+
if err != nil {
|
|
123
|
+
fmt.Fprintf(os.Stderr, "Error reading body: %v\n", err)
|
|
124
|
+
continue
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
var req RPCRequest
|
|
128
|
+
if err := json.Unmarshal(body, &req); err != nil {
|
|
129
|
+
// If the request can't be parsed, return a JSON-RPC parse error (-32700).
|
|
130
|
+
writeResponse(RPCResponse{
|
|
131
|
+
JSONRPC: "2.0",
|
|
132
|
+
ID: nil,
|
|
133
|
+
Error: &RPCError{Code: -32700, Message: "parse error: " + err.Error()},
|
|
134
|
+
})
|
|
135
|
+
continue
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Dispatch by method. Each handler returns (result, *RPCError).
|
|
139
|
+
var (
|
|
140
|
+
result interface{}
|
|
141
|
+
rerr *RPCError
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
switch req.Method {
|
|
145
|
+
case "__kadi_init":
|
|
146
|
+
// Handshake/version negotiation. You can return metadata here.
|
|
147
|
+
result, rerr = handleInit(req.Params)
|
|
148
|
+
|
|
149
|
+
case "__kadi_discover":
|
|
150
|
+
// Return functions map + optional tools array (mirrors MCP).
|
|
151
|
+
result, rerr = handleDiscover()
|
|
152
|
+
|
|
153
|
+
case "digest":
|
|
154
|
+
// Direct method call (what loadAbility().call("digest", ...) would use).
|
|
155
|
+
result, rerr = handleDigest(req.Params)
|
|
156
|
+
|
|
157
|
+
default:
|
|
158
|
+
// Method not found (-32601) per JSON-RPC.
|
|
159
|
+
rerr = &RPCError{Code: -32601, Message: "method not found: " + req.Method}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Send the response using LSP-style framing.
|
|
163
|
+
writeResponse(RPCResponse{
|
|
164
|
+
JSONRPC: "2.0",
|
|
165
|
+
ID: req.ID,
|
|
166
|
+
Result: result,
|
|
167
|
+
Error: rerr,
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// writeResponse serializes and prints a JSON-RPC response using LSP-style framing.
|
|
173
|
+
// Format: Content-Length header + JSON body
|
|
174
|
+
func writeResponse(resp RPCResponse) {
|
|
175
|
+
b, err := json.Marshal(resp)
|
|
176
|
+
if err != nil {
|
|
177
|
+
// As a last resort, emit a generic error with no ID.
|
|
178
|
+
fallback := RPCResponse{
|
|
179
|
+
JSONRPC: "2.0",
|
|
180
|
+
ID: nil,
|
|
181
|
+
Error: &RPCError{Code: -32603, Message: "internal error: " + err.Error()},
|
|
182
|
+
}
|
|
183
|
+
b, _ = json.Marshal(fallback)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Write LSP-style frame: headers + body
|
|
187
|
+
header := fmt.Sprintf("Kadi-Content-Length: %d\r\nContent-Type: application/kadi-jsonrpc; charset=utf-8\r\n\r\n", len(b))
|
|
188
|
+
fmt.Print(header)
|
|
189
|
+
fmt.Print(string(b))
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/* ----------------------------- Handlers ---------------------------------- */
|
|
193
|
+
|
|
194
|
+
// handleInit replies to __kadi_init. You can extend this with capabilities.
|
|
195
|
+
func handleInit(params json.RawMessage) (interface{}, *RPCError) {
|
|
196
|
+
// Optionally parse params to inspect the API version.
|
|
197
|
+
var payload map[string]interface{}
|
|
198
|
+
_ = json.Unmarshal(params, &payload)
|
|
199
|
+
|
|
200
|
+
// Return metadata; you could also include "functions" here to skip discover.
|
|
201
|
+
return map[string]interface{}{
|
|
202
|
+
"api": "1.0",
|
|
203
|
+
"ability": map[string]interface{}{
|
|
204
|
+
"name": "hash-go",
|
|
205
|
+
"version": "0.0.1",
|
|
206
|
+
},
|
|
207
|
+
}, nil
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// handleDiscover advertises callable functions (your loader can auto-stub from this).
|
|
211
|
+
// We also include an MCP-compatible "tools" array for symmetry.
|
|
212
|
+
func handleDiscover() (interface{}, *RPCError) {
|
|
213
|
+
input, output := digestSchemas()
|
|
214
|
+
|
|
215
|
+
return map[string]interface{}{
|
|
216
|
+
"functions": map[string]interface{}{
|
|
217
|
+
"digest": map[string]interface{}{
|
|
218
|
+
"inputSchema": input,
|
|
219
|
+
"outputSchema": output,
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
"tools": []toolSpec{
|
|
223
|
+
{
|
|
224
|
+
Name: "digest",
|
|
225
|
+
Title: "Compute Digest",
|
|
226
|
+
Description: "Return a hex digest (sha256 default) of the input text.",
|
|
227
|
+
InputSchema: input,
|
|
228
|
+
OutputSchema: map[string]interface{}{
|
|
229
|
+
"type": "object",
|
|
230
|
+
"properties": map[string]interface{}{
|
|
231
|
+
"algo": map[string]interface{}{"type": "string"},
|
|
232
|
+
"hex": map[string]interface{}{"type": "string"},
|
|
233
|
+
},
|
|
234
|
+
"required": []string{"algo", "hex"},
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
}, nil
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// handleToolsList matches MCP "tools/list": return the list of tools.
|
|
242
|
+
func handleToolsList() (interface{}, *RPCError) {
|
|
243
|
+
input, _ := digestSchemas()
|
|
244
|
+
tools := []toolSpec{
|
|
245
|
+
{
|
|
246
|
+
Name: "digest",
|
|
247
|
+
Title: "Compute Digest",
|
|
248
|
+
Description: "Return a hex digest (sha256 default) of the input text.",
|
|
249
|
+
InputSchema: input,
|
|
250
|
+
OutputSchema: map[string]interface{}{
|
|
251
|
+
"type": "object",
|
|
252
|
+
"properties": map[string]interface{}{
|
|
253
|
+
"algo": map[string]interface{}{"type": "string"},
|
|
254
|
+
"hex": map[string]interface{}{"type": "string"},
|
|
255
|
+
},
|
|
256
|
+
"required": []string{"algo", "hex"},
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
}
|
|
260
|
+
return tools, nil
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// handleToolsCall matches MCP "tools/call": expects {"name": "...", "arguments": {...}}
|
|
264
|
+
func handleToolsCall(params json.RawMessage) (interface{}, *RPCError) {
|
|
265
|
+
var p struct {
|
|
266
|
+
Name string `json:"name"`
|
|
267
|
+
Arguments json.RawMessage `json:"arguments"`
|
|
268
|
+
}
|
|
269
|
+
if err := json.Unmarshal(params, &p); err != nil {
|
|
270
|
+
return nil, &RPCError{Code: -32602, Message: "invalid params: " + err.Error()}
|
|
271
|
+
}
|
|
272
|
+
switch p.Name {
|
|
273
|
+
case "digest":
|
|
274
|
+
// Reuse our regular digest handler for the arguments payload.
|
|
275
|
+
return handleDigest(p.Arguments)
|
|
276
|
+
default:
|
|
277
|
+
return nil, &RPCError{Code: -32601, Message: "tool not found: " + p.Name}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// handleDigest is the actual business logic: compute a digest and return algo+hex.
|
|
282
|
+
func handleDigest(params json.RawMessage) (interface{}, *RPCError) {
|
|
283
|
+
var p digestParams
|
|
284
|
+
if err := json.Unmarshal(params, &p); err != nil {
|
|
285
|
+
return nil, &RPCError{Code: -32602, Message: "invalid params: " + err.Error()}
|
|
286
|
+
}
|
|
287
|
+
if p.Algo == "" {
|
|
288
|
+
p.Algo = "sha256"
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
textBytes := []byte(p.Text)
|
|
292
|
+
switch strings.ToLower(p.Algo) {
|
|
293
|
+
case "sha256":
|
|
294
|
+
sum := sha256.Sum256(textBytes)
|
|
295
|
+
return map[string]interface{}{
|
|
296
|
+
"algo": "sha256",
|
|
297
|
+
"hex": hex.EncodeToString(sum[:]),
|
|
298
|
+
}, nil
|
|
299
|
+
case "md5":
|
|
300
|
+
sum := md5.Sum(textBytes)
|
|
301
|
+
return map[string]interface{}{
|
|
302
|
+
"algo": "md5",
|
|
303
|
+
"hex": hex.EncodeToString(sum[:]),
|
|
304
|
+
}, nil
|
|
305
|
+
default:
|
|
306
|
+
return nil, &RPCError{Code: -32602, Message: "unsupported algo: " + p.Algo}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/* --------------------------- JSON Schemas -------------------------------- */
|
|
311
|
+
|
|
312
|
+
// digestSchemas returns the JSON Schemas for input/output (as plain Go maps).
|
|
313
|
+
func digestSchemas() (input map[string]interface{}, output map[string]interface{}) {
|
|
314
|
+
input = map[string]interface{}{
|
|
315
|
+
"type": "object",
|
|
316
|
+
"properties": map[string]interface{}{
|
|
317
|
+
"text": map[string]interface{}{
|
|
318
|
+
"type": "string",
|
|
319
|
+
"description": "Input text to hash.",
|
|
320
|
+
},
|
|
321
|
+
"algo": map[string]interface{}{
|
|
322
|
+
"type": "string",
|
|
323
|
+
"enum": []interface{}{"sha256", "md5"},
|
|
324
|
+
"default": "sha256",
|
|
325
|
+
"description": "Hash algorithm.",
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
"required": []string{"text"},
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
output = map[string]interface{}{
|
|
332
|
+
"type": "object",
|
|
333
|
+
"properties": map[string]interface{}{
|
|
334
|
+
"algo": map[string]interface{}{"type": "string"},
|
|
335
|
+
"hex": map[string]interface{}{"type": "string"},
|
|
336
|
+
},
|
|
337
|
+
"required": []string{"algo", "hex"},
|
|
338
|
+
}
|
|
339
|
+
return
|
|
340
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "example-agent",
|
|
3
|
+
"kind": "agent",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"description": "Example agent that calls echo-js ability written in Javascript and hash-go written Golang if you have it",
|
|
7
|
+
"repo": "",
|
|
8
|
+
"lib": "",
|
|
9
|
+
"brokers": {
|
|
10
|
+
"local": "ws://127.0.0.1:8080",
|
|
11
|
+
"remote": "ws://146.190.121.213:8080"
|
|
12
|
+
},
|
|
13
|
+
"abilities": {
|
|
14
|
+
"echo-js": "0.0.1",
|
|
15
|
+
"hash-go": "0.0.1",
|
|
16
|
+
"nlp-py": "0.0.1"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"preflight": "npm uninstall @kadi.build/core && npm cache clean --force && npm pack ../../ && npm install kadi.build-core-0.0.1-alpha.2.tgz && rm kadi.build-core-0.0.1-alpha.2.tgz",
|
|
20
|
+
"setup": "kadi install ../example-abilities/* --force && npm install",
|
|
21
|
+
"start": "node index.js",
|
|
22
|
+
"stop": "",
|
|
23
|
+
"clean": "rm -rf node_modules && rm -rf abilities"
|
|
24
|
+
},
|
|
25
|
+
"deploy": {
|
|
26
|
+
"services": {
|
|
27
|
+
"example-agent": {
|
|
28
|
+
"image": "example-agent:0.0.1",
|
|
29
|
+
"ports": ["8080:8080"],
|
|
30
|
+
"stdin_open": true,
|
|
31
|
+
"tty": true,
|
|
32
|
+
"networks": ["net"]
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"networks": {
|
|
36
|
+
"net": {}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// npm install ../../kadi.build-core-0.0.1-alpha.2.tgz
|
|
4
|
+
import { loadAbility } from '@kadi.build/core';
|
|
5
|
+
|
|
6
|
+
async function main() {
|
|
7
|
+
console.log('🎬 KADI LoadAbility Mechanism Demo');
|
|
8
|
+
console.log('====================================================');
|
|
9
|
+
|
|
10
|
+
// === WORKING ABILITIES ===
|
|
11
|
+
console.log('\n✅ === WORKING ABILITIES ===');
|
|
12
|
+
|
|
13
|
+
// try {
|
|
14
|
+
// console.log('\n🔧 Loading hash-go ability (Go)...');
|
|
15
|
+
// let goAbility = await loadAbility('hash-go');
|
|
16
|
+
// console.log('Available methods:', goAbility.__list());
|
|
17
|
+
// const hashGoResult = await goAbility.digest({
|
|
18
|
+
// text: 'I am calling hash-go digest method from Javascript',
|
|
19
|
+
// algo: 'sha256'
|
|
20
|
+
// });
|
|
21
|
+
// console.log('Go digest result:', hashGoResult);
|
|
22
|
+
|
|
23
|
+
// // This is done on purpose to test the error handling
|
|
24
|
+
// const someFunctionResult = await goAbility.someFunction({
|
|
25
|
+
// message: 'this function does not exist'
|
|
26
|
+
// });
|
|
27
|
+
|
|
28
|
+
// console.log('Go ability someFunction result:', someFunctionResult);
|
|
29
|
+
// } catch (err) {
|
|
30
|
+
// console.error('❌ hash-go failed:', err.message);
|
|
31
|
+
// }
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
console.log('\n🔧 Loading echo-js ability using native (Javascript)...');
|
|
35
|
+
let echoJsAbility = await loadAbility('echo-js');
|
|
36
|
+
|
|
37
|
+
// Subscribe first
|
|
38
|
+
echoJsAbility.events.on('echo:test-event', (data) => {
|
|
39
|
+
console.log(`[NATIVE] echo:test-event received:`, data);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
console.log('Available methods:', echoJsAbility.__list());
|
|
43
|
+
const echoJsResult = await echoJsAbility.echo({
|
|
44
|
+
message: 'I am calling echo-js echo method from Javascript'
|
|
45
|
+
});
|
|
46
|
+
console.log('Echo-js echo result:', echoJsResult);
|
|
47
|
+
} catch (err) {
|
|
48
|
+
console.error('❌ echo-js failed:', err.message);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
console.log('\n🔧 Loading echo-js ability using stdio (Javascript)...');
|
|
53
|
+
let echoJsAbility = await loadAbility('echo-js', 'stdio');
|
|
54
|
+
console.log('Available methods:', echoJsAbility.__list());
|
|
55
|
+
|
|
56
|
+
// Subscribe first
|
|
57
|
+
echoJsAbility.events.on('echo:test-event', (data) => {
|
|
58
|
+
console.log(`[STDIO] echo:test-event received:`, data);
|
|
59
|
+
});
|
|
60
|
+
// Now trigger the method that emits the event
|
|
61
|
+
const echoJsResult = await echoJsAbility.echo({
|
|
62
|
+
message: 'I am calling echo-js echo method from Javascript'
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
console.log('Echo-js echo result:', echoJsResult);
|
|
66
|
+
} catch (err) {
|
|
67
|
+
console.error('❌ echo-js failed:', err.message);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// try {
|
|
71
|
+
// console.log('\n🔧 Loading echo-js ability using broker (Javascript)...');
|
|
72
|
+
// let echoJsAbility = await loadAbility('echo-js', 'broker');
|
|
73
|
+
// console.log('Available methods:', echoJsAbility.__list());
|
|
74
|
+
// const echoJsResult = await echoJsAbility.echo({
|
|
75
|
+
// message:
|
|
76
|
+
// 'I am calling echo-js echo method from Javascript - ability speaking through Broker - open your browser to http://kadi.build/network.html to see the network'
|
|
77
|
+
// });
|
|
78
|
+
// console.log('Echo-js ability result:', echoJsResult);
|
|
79
|
+
|
|
80
|
+
// const sayMessageResult = await echoJsAbility.say_message({
|
|
81
|
+
// message: 'I am calling echo-js say_message method from Javascript'
|
|
82
|
+
// });
|
|
83
|
+
// console.log('say_message result:', sayMessageResult);
|
|
84
|
+
// } catch (err) {
|
|
85
|
+
// console.error('❌ echo-js failed:', err.message);
|
|
86
|
+
// }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Start the agent
|
|
90
|
+
main().catch((err) => {
|
|
91
|
+
// Display a concise, user-friendly message
|
|
92
|
+
console.error('❌ ' + (err?.message || err));
|
|
93
|
+
// Exit gracefully (0) so parent runner does not
|
|
94
|
+
// print an additional stack trace
|
|
95
|
+
process.exit(0);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Handle graceful shutdown
|
|
99
|
+
process.on('SIGINT', () => {
|
|
100
|
+
console.log('\nShutting down...');
|
|
101
|
+
process.exit(0);
|
|
102
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "example-agent",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"lockfileVersion": 3,
|
|
5
|
+
"requires": true,
|
|
6
|
+
"packages": {
|
|
7
|
+
"": {
|
|
8
|
+
"name": "example-agent",
|
|
9
|
+
"version": "0.0.1",
|
|
10
|
+
"license": "ISC",
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@kadi.build/core": "file:kadi.build-core-0.0.1-alpha.2.tgz"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"node_modules/@kadi.build/core": {
|
|
16
|
+
"version": "0.0.1-alpha.2",
|
|
17
|
+
"resolved": "file:kadi.build-core-0.0.1-alpha.2.tgz",
|
|
18
|
+
"integrity": "sha512-CLLvPCq6ZiUWb0pSIIUfBJdpbsB23J8Ie0lZ8OynTO9j98cOfUISMIBo4iL3vgMVA7E0UNf1hD+whVBWQSdqeA==",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"chalk": "^5.5.0",
|
|
22
|
+
"debug": "^4.4.1",
|
|
23
|
+
"events": "^3.3.0",
|
|
24
|
+
"ws": "^8.16.0"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"node_modules/chalk": {
|
|
28
|
+
"version": "5.6.0",
|
|
29
|
+
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz",
|
|
30
|
+
"integrity": "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": "^12.17.0 || ^14.13 || >=16.0.0"
|
|
34
|
+
},
|
|
35
|
+
"funding": {
|
|
36
|
+
"url": "https://github.com/chalk/chalk?sponsor=1"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"node_modules/debug": {
|
|
40
|
+
"version": "4.4.1",
|
|
41
|
+
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
|
|
42
|
+
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"ms": "^2.1.3"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=6.0"
|
|
49
|
+
},
|
|
50
|
+
"peerDependenciesMeta": {
|
|
51
|
+
"supports-color": {
|
|
52
|
+
"optional": true
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"node_modules/events": {
|
|
57
|
+
"version": "3.3.0",
|
|
58
|
+
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
|
59
|
+
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
|
|
60
|
+
"license": "MIT",
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=0.8.x"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"node_modules/ms": {
|
|
66
|
+
"version": "2.1.3",
|
|
67
|
+
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
|
68
|
+
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
|
69
|
+
"license": "MIT"
|
|
70
|
+
},
|
|
71
|
+
"node_modules/ws": {
|
|
72
|
+
"version": "8.18.3",
|
|
73
|
+
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
|
|
74
|
+
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
|
|
75
|
+
"license": "MIT",
|
|
76
|
+
"engines": {
|
|
77
|
+
"node": ">=10.0.0"
|
|
78
|
+
},
|
|
79
|
+
"peerDependencies": {
|
|
80
|
+
"bufferutil": "^4.0.1",
|
|
81
|
+
"utf-8-validate": ">=5.0.2"
|
|
82
|
+
},
|
|
83
|
+
"peerDependenciesMeta": {
|
|
84
|
+
"bufferutil": {
|
|
85
|
+
"optional": true
|
|
86
|
+
},
|
|
87
|
+
"utf-8-validate": {
|
|
88
|
+
"optional": true
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "example-agent",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node index.js",
|
|
8
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [],
|
|
11
|
+
"author": "",
|
|
12
|
+
"license": "ISC",
|
|
13
|
+
"description": "",
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@kadi.build/core": "file:kadi.build-core-0.0.1-alpha.2.tgz"
|
|
16
|
+
}
|
|
17
|
+
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kadi.build/core",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.3",
|
|
4
4
|
"description": "A module that is a comprehensive toolkit for developers integrating with the KADI infrastructure.",
|
|
5
|
-
"main": "index.js",
|
|
5
|
+
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"format": "prettier --write .",
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
],
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"dependencies": {
|
|
20
|
+
"chalk": "^5.5.0",
|
|
21
|
+
"debug": "^4.4.1",
|
|
20
22
|
"events": "^3.3.0",
|
|
21
23
|
"ws": "^8.16.0"
|
|
22
24
|
},
|