@easynet-run/node 0.27.14

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 (61) hide show
  1. package/README.md +135 -0
  2. package/native/dendrite-bridge-manifest.json +38 -0
  3. package/native/dendrite-bridge.json +15 -0
  4. package/native/include/axon_dendrite_bridge.h +460 -0
  5. package/native/libaxon_dendrite_bridge.so +0 -0
  6. package/package.json +67 -0
  7. package/runtime/easynet-runtime-rs-0.27.14-x86_64-unknown-linux-gnu.tar.gz +0 -0
  8. package/runtime/runtime-bridge-manifest.json +20 -0
  9. package/runtime/runtime-bridge.json +9 -0
  10. package/src/ability_lifecycle.d.ts +140 -0
  11. package/src/ability_lifecycle.js +525 -0
  12. package/src/capability_request.d.ts +14 -0
  13. package/src/capability_request.js +247 -0
  14. package/src/dendrite_bridge/bridge.d.ts +98 -0
  15. package/src/dendrite_bridge/bridge.js +712 -0
  16. package/src/dendrite_bridge/ffi.d.ts +60 -0
  17. package/src/dendrite_bridge/ffi.js +139 -0
  18. package/src/dendrite_bridge/index.d.ts +3 -0
  19. package/src/dendrite_bridge/index.js +25 -0
  20. package/src/dendrite_bridge/types.d.ts +179 -0
  21. package/src/dendrite_bridge/types.js +23 -0
  22. package/src/dendrite_bridge.d.ts +1 -0
  23. package/src/dendrite_bridge.js +27 -0
  24. package/src/errors.d.ts +83 -0
  25. package/src/errors.js +146 -0
  26. package/src/index.d.ts +55 -0
  27. package/src/index.js +164 -0
  28. package/src/koffi.d.ts +34 -0
  29. package/src/mcp/server.d.ts +29 -0
  30. package/src/mcp/server.js +190 -0
  31. package/src/presets/ability_dispatch/args.d.ts +5 -0
  32. package/src/presets/ability_dispatch/args.js +36 -0
  33. package/src/presets/ability_dispatch/bundle.d.ts +7 -0
  34. package/src/presets/ability_dispatch/bundle.js +102 -0
  35. package/src/presets/ability_dispatch/media.d.ts +6 -0
  36. package/src/presets/ability_dispatch/media.js +48 -0
  37. package/src/presets/ability_dispatch/orchestrator.d.ts +21 -0
  38. package/src/presets/ability_dispatch/orchestrator.js +117 -0
  39. package/src/presets/ability_dispatch/workflow.d.ts +50 -0
  40. package/src/presets/ability_dispatch/workflow.js +333 -0
  41. package/src/presets/ability_dispatch.d.ts +1 -0
  42. package/src/presets/ability_dispatch.js +2 -0
  43. package/src/presets/remote_control/config.d.ts +16 -0
  44. package/src/presets/remote_control/config.js +63 -0
  45. package/src/presets/remote_control/descriptor.d.ts +34 -0
  46. package/src/presets/remote_control/descriptor.js +183 -0
  47. package/src/presets/remote_control/handlers.d.ts +12 -0
  48. package/src/presets/remote_control/handlers.js +279 -0
  49. package/src/presets/remote_control/kit.d.ts +22 -0
  50. package/src/presets/remote_control/kit.js +72 -0
  51. package/src/presets/remote_control/kit.test.js +87 -0
  52. package/src/presets/remote_control/orchestrator.d.ts +28 -0
  53. package/src/presets/remote_control/orchestrator.js +118 -0
  54. package/src/presets/remote_control/specs.d.ts +2 -0
  55. package/src/presets/remote_control/specs.js +152 -0
  56. package/src/presets/remote_control_case.d.ts +7 -0
  57. package/src/presets/remote_control_case.js +3 -0
  58. package/src/receipt.d.ts +46 -0
  59. package/src/receipt.js +98 -0
  60. package/src/tool_adapter.d.ts +90 -0
  61. package/src/tool_adapter.js +169 -0
package/README.md ADDED
@@ -0,0 +1,135 @@
1
+ <p align="center">
2
+ <a href="https://github.com/EasyRemote"><img src="https://avatars.githubusercontent.com/u/213722898?s=200&v=4" width="200" height="200" alt="EasyRemote"></a>
3
+ </p>
4
+
5
+ <h1 align="center">@easynet-run/node</h1>
6
+
7
+ <p align="center">
8
+ Node.js SDK for <strong>EasyNet Axon</strong> — the Capability Control Plane for agent-native distributed execution.
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href='https://github.com/EasyRemote/EasyNet-Axon'><img src='https://img.shields.io/badge/EasyNet-Axon-00d9ff?style=for-the-badge&labelColor=0f172a'></a>
13
+ <a href='https://github.com/EasyRemote/EasyNet-Axon/blob/main/LICENSE'><img src='https://img.shields.io/badge/License-Apache_2.0-f97316?style=for-the-badge&labelColor=0f172a'></a>
14
+ </p>
15
+ <p align="center">
16
+ <img src='https://img.shields.io/badge/Node.js-20+-339933?style=for-the-badge&logo=node.js&logoColor=white&labelColor=0f172a'>
17
+ <img src='https://img.shields.io/badge/Platform-macOS_|_Linux_|_Windows-22c55e?style=for-the-badge&labelColor=0f172a'>
18
+ </p>
19
+
20
+ ---
21
+
22
+ ## What is this?
23
+
24
+ This is the Node.js surface for **Axon**, a protocol-level control plane that treats agent capabilities as first-class network objects. Every ability you expose carries its own schema, trust posture, scheduling contract, and tenant isolation rules — enforced atomically at invocation time.
25
+
26
+ Axon collapses tenant isolation, rate limiting, policy evaluation, node selection, concurrency admission, and circuit breaking into a **single atomic decision** against the same state snapshot. No race window between policy check and routing.
27
+
28
+ The SDK ships a native Dendrite bridge binary (loaded via `koffi`) that provides protocol-complete Axon gRPC calls without gRPC codegen in JavaScript.
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ npm install @easynet-run/node
34
+ ```
35
+
36
+ ## Quick Start
37
+
38
+ ### Expose an ability
39
+
40
+ ```ts
41
+ import { ability, serve } from "@easynet-run/node";
42
+
43
+ ability("easynet:///r/org/reg/agent.quote-bot/abilities/order.quote@1?tenant_id=tenant-test")
44
+ .handle(async ({ sku, qty = 1 }) => ({ sku, price: 19.9 * qty }))
45
+ .expose();
46
+
47
+ await serve("agent.quote-bot");
48
+ ```
49
+
50
+ ### Invoke an ability
51
+
52
+ ```ts
53
+ import { client } from "@easynet-run/node";
54
+
55
+ const res = await client()
56
+ .tenant("tenant-test")
57
+ .ability("easynet:///r/org/reg/agent.quote-bot/abilities/order.quote@1?tenant_id=tenant-test")
58
+ .call({ sku: "A1", qty: 2 });
59
+ ```
60
+
61
+ `call()` returns business payload (`result_json`). Use `callAny()` or `callRaw()` for stream/media-oriented non-object payloads.
62
+
63
+ ### Bootstrap a local runtime behind NAT
64
+
65
+ ```ts
66
+ import { startServer } from "@easynet-run/node";
67
+
68
+ const srv = await startServer(undefined, {
69
+ hub: "axon://hub.easynet.run:50084",
70
+ hubTenant: "tenant-test",
71
+ hubLabel: "alice-macbook",
72
+ });
73
+ ```
74
+
75
+ No public IP required — the local runtime connects outbound to the Hub and receives federated invocations over that channel.
76
+
77
+ ## Sub-exports
78
+
79
+ | Path | Purpose |
80
+ |---|---|
81
+ | `@easynet-run/node/presets/remote-control` | Remote device orchestration presets |
82
+ | `@easynet-run/node/mcp` | MCP stdio server and tool provider |
83
+ | `@easynet-run/node/tool-adapter` | Ability → LLM tool schema conversion |
84
+
85
+ ## Capabilities
86
+
87
+ ### Core Protocol
88
+
89
+ - **Fluent builders** — `.tenant()` → `.principal()` → `.ability()` → `.call()` are immutable and chainable.
90
+ - **Native Dendrite bridge** — `DendriteBridge` loads the platform C ABI via koffi; all Axon gRPC shapes (unary, server-stream, client-stream, bidi-stream) available without gRPC codegen.
91
+ - **Subject binding** — `.principal(...)` scopes invocation to a subject identity with automatic URI visibility mapping.
92
+
93
+ ### Ability Lifecycle
94
+
95
+ Full lifecycle management — not just invocation:
96
+
97
+ - `createAbility()` / `exportAbility()` — define and register abilities with schemas
98
+ - `deployToNode()` — install + activate on target nodes
99
+ - `listAbilities()` / `invokeAbility()` / `uninstallAbility()`
100
+ - `discoverNodes()` / `executeCommand()` / `disconnectDevice()` / `drainDevice()`
101
+ - `buildDeployPackage()` / `deployPackage()` — packaging and deployment workflows
102
+
103
+ ### MCP & A2A Protocols
104
+
105
+ - **MCP server** — `StdioMcpServer` hosts JSON-RPC 2.0 tool endpoints over stdio.
106
+ - **MCP operations** — deploy, list, call, and update MCP tools on remote nodes.
107
+ - **A2A agent protocol** — inter-agent discovery and task dispatch.
108
+ - **Tool adapter** — `AbilityToolAdapter` converts abilities to OpenAI/Anthropic/generic tool definitions; supports local handler registration with zero network overhead.
109
+
110
+ ### Voice & Media Signaling
111
+
112
+ First-class voice call lifecycle and transport negotiation (19+ FFI bindings):
113
+
114
+ - Call management: create, join, leave, end, watch events, report metrics
115
+ - Transport sessions: create, set description, add ICE candidates, refresh lease
116
+ - Media path updates and codec negotiation
117
+
118
+ ### Federation
119
+
120
+ - `startServer()` spawns a local Axon runtime and joins the Hub — all traffic is outbound.
121
+ - Federated node discovery and cross-network invocation dispatch.
122
+
123
+ ### Remote Control & Orchestration
124
+
125
+ - Subprocess template building, descriptor parsing, orchestrator factory.
126
+ - Ability dispatch workflows with bundle reading and media persistence.
127
+ - Deploy trace lifecycle tracking (`Phase` → `PhaseReceipt`).
128
+
129
+ ## License
130
+
131
+ Apache-2.0 — see [LICENSE](https://github.com/EasyRemote/EasyNet-Axon/blob/main/LICENSE).
132
+
133
+ ## Author
134
+
135
+ [Silan Hu](https://github.com/Qingbolan) · [silan.hu@u.nus.edu](mailto:silan.hu@u.nus.edu)
@@ -0,0 +1,38 @@
1
+ {
2
+ "dendrite_bridge_version": "0.27.14",
3
+ "target": "x86_64-unknown-linux-gnu",
4
+ "os": "linux",
5
+ "arch": "x86_64",
6
+ "library": {
7
+ "path": "native/libaxon_dendrite_bridge.so",
8
+ "sha256": "48d24b376d4c233a4d836f01ad6ede4dd38677a63fd6b687eeabc6a387ee910b"
9
+ },
10
+ "header": {
11
+ "path": "native/include/axon_dendrite_bridge.h",
12
+ "sha256": "b54e9ce0898c95276e5a2f5752cf7c09255ab04d0ff6c50b1da86f194faf6b75"
13
+ },
14
+ "protocol_coverage": {
15
+ "rpc_shapes": ["unary", "server_stream", "client_stream", "bidi_stream"],
16
+ "path_contract": "caller provides canonical gRPC path, e.g. /axon.v1.Invocation/Invoke",
17
+ "request_encoding": "base64(protobuf-bytes)",
18
+ "response_encoding": "base64(protobuf-bytes)"
19
+ },
20
+ "ffi_exports": [
21
+ "axon_dendrite_client_open_json",
22
+ "axon_dendrite_client_close_json",
23
+ "axon_dendrite_unary_call_json",
24
+ "axon_dendrite_server_stream_call_json",
25
+ "axon_dendrite_client_stream_call_json",
26
+ "axon_dendrite_bidi_stream_call_json",
27
+ "axon_dendrite_invoke_ability_json",
28
+ "axon_dendrite_list_nodes_json",
29
+ "axon_dendrite_deploy_mcp_list_dir_json",
30
+ "axon_dendrite_list_mcp_tools_json",
31
+ "axon_dendrite_call_mcp_tool_json",
32
+ "axon_dendrite_uninstall_capability_json",
33
+ "axon_dendrite_update_mcp_list_dir_json",
34
+ "axon_dendrite_protocol_coverage_json",
35
+ "axon_dendrite_string_free"
36
+ ],
37
+ "generated_at_utc": "2026-03-19T17:45:33Z"
38
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "language": "node",
3
+ "dendrite_bridge_version": "0.27.14",
4
+ "target": "x86_64-unknown-linux-gnu",
5
+ "dendrite_manifest_path": "native/dendrite-bridge-manifest.json",
6
+ "dendrite_library_path": "native/libaxon_dendrite_bridge.so",
7
+ "dendrite_header_path": "native/include/axon_dendrite_bridge.h",
8
+ "call_contract": {
9
+ "unary": "axon_dendrite_unary_call_json",
10
+ "server_stream": "axon_dendrite_server_stream_call_json",
11
+ "client_stream": "axon_dendrite_client_stream_call_json",
12
+ "bidi_stream": "axon_dendrite_bidi_stream_call_json",
13
+ "ability_invoke": "axon_dendrite_invoke_ability_json"
14
+ }
15
+ }
@@ -0,0 +1,460 @@
1
+ // EasyNet Axon for AgentNet
2
+ // =========================
3
+ //
4
+ // File: core/runtime-rs/dendrite-bridge/include/axon_dendrite_bridge.h
5
+ // Description: C ABI header for Axon Dendrite bridge exported functions.
6
+ //
7
+ // Protocol Responsibility:
8
+ // - Declares stable FFI entrypoints for invoke/control operations exposed to non-Rust SDKs.
9
+ // - Defines ownership and transfer boundaries for bridge handles, buffers, and error payloads.
10
+ //
11
+ // Implementation Approach:
12
+ // - Uses C-compatible primitive and pointer types to preserve ABI portability.
13
+ // - Pairs allocation-returning calls with explicit free APIs to avoid cross-runtime leaks.
14
+ //
15
+ // Usage Contract:
16
+ // - Consumers must release bridge resources only through exported cleanup functions.
17
+ // - Header declarations must remain synchronized with src/ffi_exports.rs symbols.
18
+ //
19
+ // Architectural Position:
20
+ // - Lowest-level native boundary contract beneath language-specific SDK facades.
21
+ // - Protects protocol semantics from ABI drift across Go/Node/Python/Java integrations.
22
+ //
23
+ // Author: Silan.Hu
24
+ // Email: silan.hu@u.nus.edu
25
+ // Copyright (c) 2026-2027 easynet. All rights reserved.
26
+
27
+ #ifndef AXON_DENDRITE_BRIDGE_H
28
+ #define AXON_DENDRITE_BRIDGE_H
29
+
30
+ #include <stdint.h>
31
+
32
+ #ifdef __cplusplus
33
+ extern "C" {
34
+ #endif
35
+
36
+ // Creates a client handle.
37
+ // input JSON:
38
+ // {"endpoint":"http://127.0.0.1:50051","connect_timeout_ms":5000}
39
+ // output JSON:
40
+ // {"ok":true,"handle":1}
41
+ // {"ok":false,"error":"..."}
42
+ char *axon_dendrite_client_open_json(const char *config_json);
43
+
44
+ // Releases a client handle.
45
+ // output JSON: {"ok":true,"removed":true}
46
+ char *axon_dendrite_client_close_json(uint64_t handle);
47
+
48
+ // Calls any unary gRPC method.
49
+ // input JSON:
50
+ // {
51
+ // "path":"/axon.v1.Invocation/Invoke",
52
+ // "request_base64":"...",
53
+ // "metadata":{"x-foo":"bar"},
54
+ // "timeout_ms":10000
55
+ // }
56
+ // output JSON:
57
+ // {
58
+ // "ok":true,
59
+ // "path":"/axon.v1.Invocation/Invoke",
60
+ // "response_base64":"...",
61
+ // "response_bytes":123
62
+ // }
63
+ char *axon_dendrite_unary_call_json(uint64_t handle, const char *request_json);
64
+
65
+ // Calls any server-streaming gRPC method.
66
+ // input JSON fields are same as unary + optional "max_chunks".
67
+ // output JSON:
68
+ // {
69
+ // "ok":true,
70
+ // "path":"/axon.v1.Invocation/WatchInvocation",
71
+ // "chunk_count":3,
72
+ // "chunks_base64":["...","...","..."],
73
+ // "truncated":false
74
+ // }
75
+ char *axon_dendrite_server_stream_call_json(uint64_t handle,
76
+ const char *request_json);
77
+
78
+ // Calls any client-streaming gRPC method.
79
+ // input JSON:
80
+ // {
81
+ // "path":"/axon.v1.PayloadTransfer/UploadPayload",
82
+ // "request_chunks_base64":["...","..."],
83
+ // "metadata":{"x-foo":"bar"},
84
+ // "timeout_ms":10000,
85
+ // "max_request_chunks":4096
86
+ // }
87
+ // output JSON:
88
+ // {
89
+ // "ok":true,
90
+ // "path":"/axon.v1.PayloadTransfer/UploadPayload",
91
+ // "response_base64":"...",
92
+ // "response_bytes":123
93
+ // }
94
+ char *axon_dendrite_client_stream_call_json(uint64_t handle,
95
+ const char *request_json);
96
+
97
+ // Calls any bidi-stream gRPC method.
98
+ // input JSON:
99
+ // {
100
+ // "path":"/axon.v1.Stream/OpenStream",
101
+ // "request_chunks_base64":["...","..."],
102
+ // "metadata":{"x-foo":"bar"},
103
+ // "timeout_ms":10000,
104
+ // "max_request_chunks":4096,
105
+ // "max_response_chunks":4096
106
+ // }
107
+ // output JSON:
108
+ // {
109
+ // "ok":true,
110
+ // "path":"/axon.v1.Stream/OpenStream",
111
+ // "chunk_count":2,
112
+ // "chunks_base64":["...","..."],
113
+ // "truncated":false
114
+ // }
115
+ char *axon_dendrite_bidi_stream_call_json(uint64_t handle,
116
+ const char *request_json);
117
+
118
+ // Native helper for EasyNet ability call (Invocation/Invoke):
119
+ // input JSON:
120
+ // {
121
+ // "tenant_id":"tenant-test",
122
+ // "resource_uri":"easynet:///r/org/reg/agent.quote-bot/abilities/order.quote@1?tenant_id=tenant-test",
123
+ // "payload_json":{"sku":"A1","qty":2},
124
+ // "timeout_ms":30000
125
+ // }
126
+ // output JSON includes decoded invoke metadata and result payload fields:
127
+ // {
128
+ // "ok":true,
129
+ // "state":1,
130
+ // "result_content_type":"application/json",
131
+ // "result_base64":"...",
132
+ // "result_json":{"price":39.8}
133
+ // }
134
+ char *axon_dendrite_invoke_ability_json(uint64_t handle,
135
+ const char *request_json);
136
+
137
+ // Returns protocol catalog JSON generated from core/proto/axon/v1/*.proto.
138
+ // output JSON:
139
+ // {
140
+ // "ok":true,
141
+ // "count":123,
142
+ // "rpcs":[
143
+ // {"service":"ControlPlane","rpc":"Heartbeat","path":"/axon.v1.ControlPlane/Heartbeat","shape":"unary","proto":"control.proto"}
144
+ // ]
145
+ // }
146
+ char *axon_dendrite_protocol_catalog_json(void);
147
+
148
+ // Generic protocol helper: invoke any cataloged RPC by path or service/rpc.
149
+ // input JSON:
150
+ // {
151
+ // "service":"ControlPlane",
152
+ // "rpc":"Heartbeat",
153
+ // "path":"/axon.v1.ControlPlane/Heartbeat",
154
+ // "request_base64":"...",
155
+ // "request_chunks_base64":["..."],
156
+ // "metadata":{"x-foo":"bar"},
157
+ // "timeout_ms":1000,
158
+ // "max_chunks":64,
159
+ // "max_request_chunks":64,
160
+ // "max_response_chunks":64
161
+ // }
162
+ char *axon_dendrite_invoke_protocol_json(uint64_t handle,
163
+ const char *request_json);
164
+
165
+ // Control helper: list nodes for a tenant.
166
+ // input JSON:
167
+ // {"tenant_id":"tenant-test","owner_id":"user.alice"}
168
+ char *axon_dendrite_list_nodes_json(uint64_t handle, const char *request_json);
169
+
170
+ // Control helper: register a node in tenant scope.
171
+ // input JSON:
172
+ // {"tenant_id":"tenant-test","node_id":"node-a","display_name":"Node A"}
173
+ char *axon_dendrite_register_node_json(uint64_t handle,
174
+ const char *request_json);
175
+
176
+ // Control helper: send heartbeat for a node.
177
+ // input JSON:
178
+ // {"tenant_id":"tenant-test","node_id":"node-a"}
179
+ char *axon_dendrite_heartbeat_json(uint64_t handle, const char *request_json);
180
+
181
+ // Capability helper: publish package metadata into registry.
182
+ // input JSON:
183
+ // {
184
+ // "tenant_id":"tenant-test",
185
+ // "package_id":"pkg.desktop_camera",
186
+ // "capability_name":"desktop_camera",
187
+ // "version":"1.0.0",
188
+ // "digest":"sha256:desktop-camera",
189
+ // "signature_base64":"__AXON_EPHEMERAL_DO_NOT_USE_IN_PROD__",
190
+ // "metadata":{"a2a.skill_id":"take_photo"}
191
+ // }
192
+ char *axon_dendrite_publish_capability_json(uint64_t handle,
193
+ const char *request_json);
194
+
195
+ // Capability helper: install package on node.
196
+ // input JSON:
197
+ // {"tenant_id":"tenant-test","node_id":"node-a","package_id":"pkg.desktop_camera","version":"1.0.0","digest":"sha256:desktop-camera"}
198
+ char *axon_dendrite_install_capability_json(uint64_t handle,
199
+ const char *request_json);
200
+
201
+ // Capability helper: activate install on node.
202
+ // input JSON:
203
+ // {"tenant_id":"tenant-test","node_id":"node-a","install_id":"install-..."}
204
+ char *axon_dendrite_activate_capability_json(uint64_t handle,
205
+ const char *request_json);
206
+
207
+ // A2A helper: list agents.
208
+ // input JSON:
209
+ // {"tenant_id":"tenant-test","tags":["camera"],"owner_id":"","limit":100}
210
+ char *axon_dendrite_list_a2a_agents_json(uint64_t handle,
211
+ const char *request_json);
212
+
213
+ // A2A helper: get card for a node.
214
+ // input JSON:
215
+ // {"tenant_id":"tenant-test","node_id":"desktop-sandbox-01"}
216
+ char *axon_dendrite_get_a2a_agent_card_json(uint64_t handle,
217
+ const char *request_json);
218
+
219
+ // A2A helper: send task to target agent.
220
+ // input JSON:
221
+ // {
222
+ // "tenant_id":"tenant-test",
223
+ // "target_agent_id":"desktop-sandbox-01",
224
+ // "skill_id":"take_photo",
225
+ // "input_json":{"camera_id":"front"}
226
+ // }
227
+ char *axon_dendrite_send_a2a_task_json(uint64_t handle,
228
+ const char *request_json);
229
+
230
+ // Control helper: publish/install/activate and call a selected-node MCP
231
+ // list-dir tool. input JSON:
232
+ // {
233
+ // "tenant_id":"tenant-test",
234
+ // "node_id":"node-alice",
235
+ // "target_path":"/client",
236
+ // "command_template":"docker exec {node_id} /usr/local/bin/easynet-list-dir-json {path}",
237
+ // "signature_base64":"__AXON_EPHEMERAL_DO_NOT_USE_IN_PROD__"
238
+ // }
239
+ char *axon_dendrite_deploy_mcp_list_dir_json(uint64_t handle,
240
+ const char *request_json);
241
+
242
+ // Control helper: list MCP tools.
243
+ // input JSON:
244
+ // {"tenant_id":"tenant-test","name_pattern":"list_*","node_id":"node-alice","tags":["fs"]}
245
+ char *axon_dendrite_list_mcp_tools_json(uint64_t handle,
246
+ const char *request_json);
247
+
248
+ // Control helper: call MCP tool.
249
+ // input JSON:
250
+ // {"tenant_id":"tenant-test","tool_name":"list_current_dir_node-alice","target_node_id":"node-alice","arguments_json":{}}
251
+ char *axon_dendrite_call_mcp_tool_json(uint64_t handle,
252
+ const char *request_json);
253
+
254
+ // Control helper: deactivate (optional) and uninstall installed capability.
255
+ // input JSON:
256
+ // {
257
+ // "tenant_id":"tenant-test",
258
+ // "node_id":"node-alice",
259
+ // "install_id":"install-...",
260
+ // "deactivate_first":true,
261
+ // "deactivate_reason":"server-managed-uninstall",
262
+ // "force":false
263
+ // }
264
+ char *axon_dendrite_uninstall_capability_json(uint64_t handle,
265
+ const char *request_json);
266
+
267
+ // Control helper: optional old-install cleanup + deploy latest MCP list-dir
268
+ // package. input JSON:
269
+ // {
270
+ // "tenant_id":"tenant-test",
271
+ // "node_id":"node-alice",
272
+ // "existing_install_id":"install-...",
273
+ // "deactivate_old":true,
274
+ // "uninstall_old":true,
275
+ // "force_uninstall":false,
276
+ // "target_path":"/client",
277
+ // "command_template":"docker exec {node_id} /usr/local/bin/easynet-list-dir-json {path}",
278
+ // "version":"1.0.1"
279
+ // }
280
+ char *axon_dendrite_update_mcp_list_dir_json(uint64_t handle,
281
+ const char *request_json);
282
+
283
+ // Control helper: deregister (disconnect) a node.
284
+ // Request: {"tenant_id":"...", "node_id":"...", "reason":"..."}
285
+ char *axon_dendrite_deregister_node_json(uint64_t handle,
286
+ const char *request_json);
287
+
288
+ // Control helper: drain a node — stop accepting new invocations while
289
+ // finishing in-flight ones.
290
+ // Request: {"tenant_id":"...", "node_id":"...", "reason":"..."}
291
+ char *axon_dendrite_drain_node_json(uint64_t handle,
292
+ const char *request_json);
293
+
294
+ // Voice helper: create call.
295
+ // input JSON:
296
+ // {"tenant_id":"tenant-test","call_id":"call-1","display_name":"support","participant_limit":2}
297
+ char *axon_dendrite_voice_create_call_json(uint64_t handle,
298
+ const char *request_json);
299
+
300
+ // Voice helper: get call.
301
+ // input JSON:
302
+ // {"tenant_id":"tenant-test","call_id":"call-1"}
303
+ char *axon_dendrite_voice_get_call_json(uint64_t handle,
304
+ const char *request_json);
305
+
306
+ // Voice helper: join call.
307
+ // input JSON:
308
+ // {"tenant_id":"tenant-test","call_id":"call-1","participant_id":"agent-a","node_id":"node-a","transport":2}
309
+ char *axon_dendrite_voice_join_call_json(uint64_t handle,
310
+ const char *request_json);
311
+
312
+ // Voice helper: leave call.
313
+ // input JSON:
314
+ // {"tenant_id":"tenant-test","call_id":"call-1","participant_id":"agent-a","reason":"left"}
315
+ char *axon_dendrite_voice_leave_call_json(uint64_t handle,
316
+ const char *request_json);
317
+
318
+ // Voice helper: update media path.
319
+ // input JSON:
320
+ // {"tenant_id":"tenant-test","call_id":"call-1","participant_id":"agent-a","transport":2,"stream_session_id":"vts-1","muted":false}
321
+ char *axon_dendrite_voice_update_media_path_json(uint64_t handle,
322
+ const char *request_json);
323
+
324
+ // Voice helper: report metrics.
325
+ // input JSON:
326
+ // {"tenant_id":"tenant-test","call_id":"call-1","participant_id":"agent-a","metrics":{"rtt_ms":120.0,"jitter_ms":15.0,"packet_loss_ratio":0.01}}
327
+ char *axon_dendrite_voice_report_call_metrics_json(uint64_t handle,
328
+ const char *request_json);
329
+
330
+ // Voice helper: end call.
331
+ // input JSON:
332
+ // {"tenant_id":"tenant-test","call_id":"call-1","end_reason":1,"detail":"caller_end"}
333
+ char *axon_dendrite_voice_end_call_json(uint64_t handle,
334
+ const char *request_json);
335
+
336
+ // Voice helper: watch call events.
337
+ // input JSON:
338
+ // {"tenant_id":"tenant-test","call_id":"call-1","from_sequence":0,"max_events":128,"timeout_ms":1500}
339
+ char *axon_dendrite_voice_watch_call_events_json(uint64_t handle,
340
+ const char *request_json);
341
+
342
+ // Voice transport helper: create session.
343
+ // input JSON:
344
+ // {"tenant_id":"tenant-test","call_id":"call-1","participant_id":"agent-a","transport":2,"requested_ttl_seconds":60}
345
+ char *axon_dendrite_voice_create_transport_session_json(uint64_t handle,
346
+ const char *request_json);
347
+
348
+ // Voice transport helper: get session.
349
+ // input JSON:
350
+ // {"tenant_id":"tenant-test","call_id":"call-1","transport_session_id":"vts-1"}
351
+ char *axon_dendrite_voice_get_transport_session_json(uint64_t handle,
352
+ const char *request_json);
353
+
354
+ // Voice transport helper: set description.
355
+ // input JSON:
356
+ // {"tenant_id":"tenant-test","call_id":"call-1","transport_session_id":"vts-1","side":2,"description":{"sdp_type":3,"sdp":"v=0..."}}
357
+ char *axon_dendrite_voice_set_transport_description_json(uint64_t handle,
358
+ const char *request_json);
359
+
360
+ // Voice transport helper: add candidate.
361
+ // input JSON:
362
+ // {"tenant_id":"tenant-test","call_id":"call-1","transport_session_id":"vts-1","side":2,"candidate":{"candidate":"candidate:1 ..."}}
363
+ char *axon_dendrite_voice_add_transport_candidate_json(uint64_t handle,
364
+ const char *request_json);
365
+
366
+ // Voice transport helper: refresh lease.
367
+ // input JSON:
368
+ // {"tenant_id":"tenant-test","call_id":"call-1","transport_session_id":"vts-1","requested_ttl_seconds":120}
369
+ char *axon_dendrite_voice_refresh_transport_lease_json(uint64_t handle,
370
+ const char *request_json);
371
+
372
+ // Voice transport helper: end session.
373
+ // input JSON:
374
+ // {"tenant_id":"tenant-test","call_id":"call-1","transport_session_id":"vts-1","failed":false,"reason":"completed"}
375
+ char *axon_dendrite_voice_end_transport_session_json(uint64_t handle,
376
+ const char *request_json);
377
+
378
+ // Voice transport helper: watch events.
379
+ // input JSON:
380
+ // {"tenant_id":"tenant-test","call_id":"call-1","transport_session_id":"vts-1","from_sequence":0,"max_events":128,"timeout_ms":1500}
381
+ char *axon_dendrite_voice_watch_transport_events_json(uint64_t handle,
382
+ const char *request_json);
383
+
384
+ // ---------------------------------------------------------------------------
385
+ // Incremental streaming API (pull model)
386
+ // ---------------------------------------------------------------------------
387
+
388
+ // Opens a server-streaming gRPC call and returns a stream handle for
389
+ // incremental chunk retrieval via stream_next.
390
+ // input JSON:
391
+ // {
392
+ // "path":"/axon.v1.Invocation/WatchInvocation",
393
+ // "request_base64":"...",
394
+ // "metadata":{"x-foo":"bar"},
395
+ // "timeout_ms":10000,
396
+ // "chunk_timeout_ms":30000,
397
+ // "chunk_buffer_size":64
398
+ // }
399
+ // output JSON:
400
+ // {"ok":true,"stream_handle":1,"path":"/axon.v1.Invocation/WatchInvocation"}
401
+ char *axon_dendrite_server_stream_open_json(uint64_t handle,
402
+ const char *request_json);
403
+
404
+ // Pulls the next chunk from an open stream (server-stream or bidi-stream).
405
+ // input JSON (optional):
406
+ // {"timeout_ms":30000}
407
+ // output JSON (chunk available):
408
+ // {"ok":true,"done":false,"chunk_base64":"...","chunk_bytes":123}
409
+ // output JSON (stream completed):
410
+ // {"ok":true,"done":true}
411
+ // output JSON (timeout, stream still open):
412
+ // {"ok":true,"done":false,"timeout":true}
413
+ char *axon_dendrite_stream_next_json(uint64_t stream_handle,
414
+ const char *request_json);
415
+
416
+ // Closes an open stream handle, aborting the background task if still running.
417
+ // output JSON: {"ok":true,"removed":true}
418
+ char *axon_dendrite_stream_close_json(uint64_t stream_handle);
419
+
420
+ // Opens a bidi-streaming gRPC call. Returns a stream handle for both
421
+ // sending request chunks (via bidi_stream_send) and receiving response
422
+ // chunks (via stream_next).
423
+ // input JSON:
424
+ // {
425
+ // "path":"/axon.v1.Stream/OpenStream",
426
+ // "request_base64":"...",
427
+ // "request_chunks_base64":["..."],
428
+ // "metadata":{"x-foo":"bar"},
429
+ // "timeout_ms":10000,
430
+ // "chunk_timeout_ms":30000,
431
+ // "chunk_buffer_size":64,
432
+ // "request_buffer_size":64
433
+ // }
434
+ // output JSON:
435
+ // {"ok":true,"stream_handle":1,"path":"/axon.v1.Stream/OpenStream"}
436
+ char *axon_dendrite_bidi_stream_open_json(uint64_t handle,
437
+ const char *request_json);
438
+
439
+ // Sends a request chunk on an open bidi-stream.
440
+ // input JSON:
441
+ // {"chunk_base64":"..."}
442
+ // or to close the request side while continuing to receive:
443
+ // {"done":true}
444
+ // output JSON when sending a chunk: {"ok":true,"sent":true}
445
+ // output JSON when closing the request side:
446
+ // {"ok":true,"sent":false,"done":true,"request_stream_closed":true}
447
+ char *axon_dendrite_bidi_stream_send_json(uint64_t stream_handle,
448
+ const char *request_json);
449
+
450
+ // Returns protocol coverage descriptor JSON.
451
+ char *axon_dendrite_protocol_coverage_json(void);
452
+
453
+ // Frees memory returned by bridge APIs.
454
+ void axon_dendrite_string_free(char *s);
455
+
456
+ #ifdef __cplusplus
457
+ }
458
+ #endif
459
+
460
+ #endif // AXON_DENDRITE_BRIDGE_H