@agentorg/cli 0.0.4 → 0.0.6

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 (206) hide show
  1. package/README.md +18 -102
  2. package/dist/node_modules/@agentorg/hub/dist/src/hub-actor.d.ts +2 -7
  3. package/dist/node_modules/@agentorg/hub/dist/src/hub-actor.js +4 -111
  4. package/dist/node_modules/@agentorg/hub/dist/src/index.d.ts +1 -3
  5. package/dist/node_modules/@agentorg/hub/dist/src/index.js +1 -3
  6. package/dist/node_modules/@agentorg/hub/dist/src/router.d.ts +6 -57
  7. package/dist/node_modules/@agentorg/hub/dist/src/router.js +38 -413
  8. package/dist/node_modules/@agentorg/hub/dist/src/state.d.ts +20 -298
  9. package/dist/node_modules/@agentorg/hub/dist/src/state.js +73 -456
  10. package/dist/node_modules/@agentorg/hub/dist/src/validate.d.ts +1 -3
  11. package/dist/node_modules/@agentorg/hub/dist/src/validate.js +3 -15
  12. package/dist/node_modules/@agentorg/hub/package.json +0 -3
  13. package/dist/node_modules/@agentorg/interfaces/dist/src/agent-provider.d.ts +132 -0
  14. package/dist/node_modules/@agentorg/interfaces/dist/src/agent-provider.js +105 -0
  15. package/dist/node_modules/@agentorg/interfaces/dist/src/agent-settings.d.ts +42 -0
  16. package/dist/node_modules/@agentorg/interfaces/dist/src/agent-settings.js +53 -0
  17. package/dist/node_modules/@agentorg/interfaces/dist/src/chat.d.ts +15 -0
  18. package/dist/node_modules/@agentorg/interfaces/dist/src/chat.js +14 -0
  19. package/dist/node_modules/@agentorg/interfaces/dist/src/hub.d.ts +16 -267
  20. package/dist/node_modules/@agentorg/interfaces/dist/src/hub.js +17 -145
  21. package/dist/node_modules/@agentorg/interfaces/dist/src/index.d.ts +6 -8
  22. package/dist/node_modules/@agentorg/interfaces/dist/src/index.js +6 -8
  23. package/dist/node_modules/@agentorg/interfaces/dist/src/kv.d.ts +2 -2
  24. package/dist/node_modules/@agentorg/interfaces/dist/src/kv.js +2 -2
  25. package/dist/node_modules/@agentorg/interfaces/dist/src/manager.d.ts +272 -0
  26. package/dist/node_modules/@agentorg/interfaces/dist/src/manager.js +185 -0
  27. package/dist/node_modules/@agentorg/interfaces/dist/src/mcp-provider.d.ts +88 -0
  28. package/dist/node_modules/@agentorg/interfaces/dist/src/mcp-provider.js +78 -0
  29. package/dist/node_modules/@agentorg/interfaces/dist/src/tools.d.ts +39 -0
  30. package/dist/node_modules/@agentorg/interfaces/dist/src/tools.js +43 -0
  31. package/dist/node_modules/@agentorg/manager/dist/src/index.d.ts +1 -0
  32. package/dist/node_modules/@agentorg/manager/dist/src/index.js +1 -0
  33. package/dist/node_modules/@agentorg/manager/dist/src/manager.d.ts +21 -0
  34. package/dist/node_modules/@agentorg/manager/dist/src/manager.js +528 -0
  35. package/dist/node_modules/@agentorg/manager/dist/src/skills.d.ts +25 -0
  36. package/dist/node_modules/@agentorg/manager/dist/src/skills.js +145 -0
  37. package/dist/node_modules/@agentorg/manager/package.json +30 -0
  38. package/dist/node_modules/@agentorg/mcp/dist/src/connection.d.ts +33 -0
  39. package/dist/node_modules/@agentorg/mcp/dist/src/connection.js +290 -0
  40. package/dist/node_modules/@agentorg/mcp/dist/src/index.d.ts +1 -0
  41. package/dist/node_modules/@agentorg/mcp/dist/src/index.js +1 -0
  42. package/dist/node_modules/@agentorg/mcp/dist/src/kinds.d.ts +50 -0
  43. package/dist/node_modules/@agentorg/mcp/dist/src/kinds.js +69 -0
  44. package/dist/node_modules/@agentorg/mcp/dist/src/provider.d.ts +22 -0
  45. package/dist/node_modules/@agentorg/mcp/dist/src/provider.js +167 -0
  46. package/dist/node_modules/@agentorg/mcp/package.json +31 -0
  47. package/dist/node_modules/@agentorg/sdk/dist/src/cli.js +3 -23
  48. package/dist/node_modules/@agentorg/sdk/dist/src/client.d.ts +4 -25
  49. package/dist/node_modules/@agentorg/sdk/dist/src/client.js +5 -55
  50. package/dist/node_modules/@agentorg/sdk/dist/src/errors.d.ts +1 -1
  51. package/dist/node_modules/@agentorg/sdk/dist/src/errors.js +3 -3
  52. package/dist/node_modules/@agentorg/sdk/dist/src/index.d.ts +2 -2
  53. package/dist/node_modules/@agentorg/sdk/dist/src/index.js +1 -1
  54. package/dist/node_modules/@agentorg/sdk/dist/src/interface.d.ts +6 -34
  55. package/dist/node_modules/@agentorg/sdk/dist/src/interface.js +3 -24
  56. package/dist/node_modules/@agentorg/sdk/dist/src/module-host.d.ts +8 -17
  57. package/dist/node_modules/@agentorg/sdk/dist/src/module-host.js +15 -87
  58. package/dist/node_modules/@agentorg/sdk/dist/src/module.d.ts +10 -76
  59. package/dist/node_modules/@agentorg/sdk/dist/src/module.js +3 -23
  60. package/dist/node_modules/@agentorg/sdk/dist/src/person-commands.js +0 -5
  61. package/dist/node_modules/@agentorg/sdk/dist/src/runtime.d.ts +3 -27
  62. package/dist/node_modules/@agentorg/sdk/dist/src/runtime.js +5 -100
  63. package/dist/node_modules/@agentorg/sdk/dist/src/testing.d.ts +7 -8
  64. package/dist/node_modules/@agentorg/sdk/dist/src/testing.js +12 -24
  65. package/dist/node_modules/@agentorg/sdk/package.json +4 -37
  66. package/dist/node_modules/@agentorg/shell/dist/app.css +3435 -739
  67. package/dist/node_modules/@agentorg/shell/dist/app.js +204 -202
  68. package/dist/node_modules/@agentorg/shell/package.json +18 -10
  69. package/dist/node_modules/@agentorg/wire/dist/src/frames.d.ts +2 -3
  70. package/dist/node_modules/@agentorg/wire/dist/src/frames.js +2 -3
  71. package/dist/node_modules/@agentorg/wire/dist/src/ops.d.ts +5 -34
  72. package/dist/node_modules/@agentorg/wire/dist/src/ops.js +2 -17
  73. package/dist/node_modules/assistant/dist/src/agent.d.ts +62 -0
  74. package/dist/node_modules/assistant/dist/src/agent.js +226 -0
  75. package/dist/node_modules/assistant/dist/src/engine.d.ts +23 -0
  76. package/dist/node_modules/assistant/dist/src/engine.js +88 -0
  77. package/dist/node_modules/assistant/dist/src/history.d.ts +97 -0
  78. package/dist/node_modules/assistant/dist/src/history.js +235 -0
  79. package/dist/node_modules/assistant/dist/src/local-store.d.ts +3 -0
  80. package/dist/node_modules/assistant/dist/src/local-store.js +58 -0
  81. package/dist/node_modules/assistant/dist/src/provider.d.ts +21 -0
  82. package/dist/node_modules/assistant/dist/src/provider.js +231 -0
  83. package/dist/node_modules/assistant/dist/src/settings.d.ts +17 -0
  84. package/dist/node_modules/assistant/dist/src/settings.js +43 -0
  85. package/dist/node_modules/assistant/dist/src/tools.d.ts +74 -0
  86. package/dist/node_modules/assistant/dist/src/tools.js +123 -0
  87. package/dist/node_modules/assistant/package.json +29 -0
  88. package/dist/node_modules/chatgpt/dist/src/account.d.ts +52 -0
  89. package/dist/node_modules/chatgpt/dist/src/account.js +270 -0
  90. package/dist/node_modules/chatgpt/dist/src/encoding.d.ts +7 -0
  91. package/dist/node_modules/chatgpt/dist/src/encoding.js +20 -0
  92. package/dist/node_modules/chatgpt/dist/src/file-store.d.ts +9 -0
  93. package/dist/node_modules/chatgpt/dist/src/file-store.js +68 -0
  94. package/dist/node_modules/chatgpt/dist/src/index.d.ts +1 -0
  95. package/dist/node_modules/chatgpt/dist/src/index.js +1 -0
  96. package/dist/node_modules/chatgpt/dist/src/jwt.d.ts +15 -0
  97. package/dist/node_modules/chatgpt/dist/src/jwt.js +37 -0
  98. package/dist/node_modules/chatgpt/dist/src/oauth.d.ts +43 -0
  99. package/dist/node_modules/chatgpt/dist/src/oauth.js +104 -0
  100. package/dist/node_modules/chatgpt/dist/src/program.d.ts +23 -0
  101. package/dist/node_modules/chatgpt/dist/src/program.js +41 -0
  102. package/dist/node_modules/chatgpt/dist/src/responses.d.ts +54 -0
  103. package/dist/node_modules/chatgpt/dist/src/responses.js +300 -0
  104. package/dist/node_modules/chatgpt/dist/src/serve.d.ts +65 -0
  105. package/dist/node_modules/chatgpt/dist/src/serve.js +46 -0
  106. package/dist/node_modules/chatgpt/package.json +33 -0
  107. package/dist/src/api.d.ts +5 -34
  108. package/dist/src/api.js +6 -68
  109. package/dist/src/cli.js +3 -7
  110. package/dist/src/gateway.d.ts +6 -7
  111. package/dist/src/gateway.js +39 -285
  112. package/dist/src/index.d.ts +4 -5
  113. package/dist/src/index.js +3 -4
  114. package/dist/src/notes.d.ts +11 -0
  115. package/dist/src/notes.js +64 -0
  116. package/dist/src/oauth.d.ts +16 -0
  117. package/dist/src/oauth.js +46 -0
  118. package/dist/src/programs.d.ts +29 -0
  119. package/dist/src/programs.js +171 -0
  120. package/package.json +3 -11
  121. package/dist/bundled/index.json +0 -6
  122. package/dist/bundled/sha256-01d69bc3888c2a53963f4413d47de909d129ad27c78e9af6d830bb50c3478419.agentorg +0 -0
  123. package/dist/bundled/sha256-84165e3be5c904fc971d983dab31102e07cca725d8629a6fd7d118fa3a0a88b8.agentorg +0 -0
  124. package/dist/bundled/sha256-ade9132b3f34b4c39db92adeadc7e540dc745e4a81b5b54f5d45bf9ec92bca75.agentorg +0 -0
  125. package/dist/bundled/sha256-f4330f5987f37d8cf3aeb44d2f831b573641a87186daa2f811f0c35ba04804f0.agentorg +0 -0
  126. package/dist/node_modules/@agentorg/hub/dist/src/build.d.ts +0 -17
  127. package/dist/node_modules/@agentorg/hub/dist/src/build.js +0 -120
  128. package/dist/node_modules/@agentorg/hub/dist/src/logs.d.ts +0 -33
  129. package/dist/node_modules/@agentorg/hub/dist/src/logs.js +0 -162
  130. package/dist/node_modules/@agentorg/hub/dist/src/net.d.ts +0 -41
  131. package/dist/node_modules/@agentorg/hub/dist/src/net.js +0 -265
  132. package/dist/node_modules/@agentorg/hub/dist/src/processes.d.ts +0 -78
  133. package/dist/node_modules/@agentorg/hub/dist/src/processes.js +0 -485
  134. package/dist/node_modules/@agentorg/hub/dist/src/storage.d.ts +0 -38
  135. package/dist/node_modules/@agentorg/hub/dist/src/storage.js +0 -194
  136. package/dist/node_modules/@agentorg/interfaces/dist/src/http-egress.d.ts +0 -6
  137. package/dist/node_modules/@agentorg/interfaces/dist/src/http-egress.js +0 -7
  138. package/dist/node_modules/@agentorg/interfaces/dist/src/installer.d.ts +0 -191
  139. package/dist/node_modules/@agentorg/interfaces/dist/src/installer.js +0 -136
  140. package/dist/node_modules/@agentorg/interfaces/dist/src/layout.d.ts +0 -47
  141. package/dist/node_modules/@agentorg/interfaces/dist/src/layout.js +0 -52
  142. package/dist/node_modules/@agentorg/interfaces/dist/src/rules.d.ts +0 -35
  143. package/dist/node_modules/@agentorg/interfaces/dist/src/rules.js +0 -37
  144. package/dist/node_modules/@agentorg/interfaces/dist/src/storage-admin.d.ts +0 -23
  145. package/dist/node_modules/@agentorg/interfaces/dist/src/storage-admin.js +0 -31
  146. package/dist/node_modules/@agentorg/interfaces/dist/src/ui-shell.d.ts +0 -14
  147. package/dist/node_modules/@agentorg/interfaces/dist/src/ui-shell.js +0 -26
  148. package/dist/node_modules/@agentorg/interfaces/dist/src/ui-view.d.ts +0 -27
  149. package/dist/node_modules/@agentorg/interfaces/dist/src/ui-view.js +0 -26
  150. package/dist/node_modules/@agentorg/kit/dist/src/chat.d.ts +0 -37
  151. package/dist/node_modules/@agentorg/kit/dist/src/chat.js +0 -131
  152. package/dist/node_modules/@agentorg/kit/dist/src/components.d.ts +0 -94
  153. package/dist/node_modules/@agentorg/kit/dist/src/components.js +0 -66
  154. package/dist/node_modules/@agentorg/kit/dist/src/icons.d.ts +0 -17
  155. package/dist/node_modules/@agentorg/kit/dist/src/icons.js +0 -30
  156. package/dist/node_modules/@agentorg/kit/dist/src/index.d.ts +0 -6
  157. package/dist/node_modules/@agentorg/kit/dist/src/index.js +0 -10
  158. package/dist/node_modules/@agentorg/kit/dist/src/markdown.d.ts +0 -9
  159. package/dist/node_modules/@agentorg/kit/dist/src/markdown.js +0 -14
  160. package/dist/node_modules/@agentorg/kit/dist/src/resizable.d.ts +0 -5
  161. package/dist/node_modules/@agentorg/kit/dist/src/resizable.js +0 -8
  162. package/dist/node_modules/@agentorg/kit/dist/src/styles.d.ts +0 -11
  163. package/dist/node_modules/@agentorg/kit/dist/src/styles.js +0 -166
  164. package/dist/node_modules/@agentorg/kit/package.json +0 -44
  165. package/dist/node_modules/@agentorg/sdk/dist/frame/runtime.js +0 -753
  166. package/dist/node_modules/@agentorg/sdk/dist/host/runner.js +0 -21963
  167. package/dist/node_modules/@agentorg/sdk/dist/src/build.d.ts +0 -2
  168. package/dist/node_modules/@agentorg/sdk/dist/src/build.js +0 -2
  169. package/dist/node_modules/@agentorg/sdk/dist/src/client-http.d.ts +0 -24
  170. package/dist/node_modules/@agentorg/sdk/dist/src/client-http.js +0 -247
  171. package/dist/node_modules/@agentorg/sdk/dist/src/describe.d.ts +0 -13
  172. package/dist/node_modules/@agentorg/sdk/dist/src/describe.js +0 -16
  173. package/dist/node_modules/@agentorg/sdk/dist/src/frame-base.d.ts +0 -8
  174. package/dist/node_modules/@agentorg/sdk/dist/src/frame-base.js +0 -64
  175. package/dist/node_modules/@agentorg/sdk/dist/src/frame-entry.d.ts +0 -1
  176. package/dist/node_modules/@agentorg/sdk/dist/src/frame-entry.js +0 -35
  177. package/dist/node_modules/@agentorg/sdk/dist/src/frame-host.d.ts +0 -57
  178. package/dist/node_modules/@agentorg/sdk/dist/src/frame-host.js +0 -293
  179. package/dist/node_modules/@agentorg/sdk/dist/src/frame-protocol.d.ts +0 -124
  180. package/dist/node_modules/@agentorg/sdk/dist/src/frame-protocol.js +0 -16
  181. package/dist/node_modules/@agentorg/sdk/dist/src/frame.d.ts +0 -25
  182. package/dist/node_modules/@agentorg/sdk/dist/src/frame.js +0 -248
  183. package/dist/node_modules/@agentorg/sdk/dist/src/host-main.d.ts +0 -1
  184. package/dist/node_modules/@agentorg/sdk/dist/src/host-main.js +0 -60
  185. package/dist/node_modules/@agentorg/sdk/dist/src/host.d.ts +0 -25
  186. package/dist/node_modules/@agentorg/sdk/dist/src/host.js +0 -92
  187. package/dist/node_modules/@agentorg/sdk/dist/src/manifest-api.d.ts +0 -2
  188. package/dist/node_modules/@agentorg/sdk/dist/src/manifest-api.js +0 -2
  189. package/dist/node_modules/@agentorg/sdk/dist/src/manifest.d.ts +0 -56
  190. package/dist/node_modules/@agentorg/sdk/dist/src/manifest.js +0 -165
  191. package/dist/node_modules/@agentorg/sdk/dist/src/package.d.ts +0 -60
  192. package/dist/node_modules/@agentorg/sdk/dist/src/package.js +0 -538
  193. package/dist/node_modules/@agentorg/sdk/dist/src/tar.d.ts +0 -7
  194. package/dist/node_modules/@agentorg/sdk/dist/src/tar.js +0 -71
  195. package/dist/node_modules/@agentorg/shell/dist/agent-bindings.js +0 -59
  196. package/dist/node_modules/@agentorg/shell/src/agent-bindings.ts +0 -107
  197. package/dist/src/frames.d.ts +0 -23
  198. package/dist/src/frames.js +0 -78
  199. package/dist/src/layout.d.ts +0 -44
  200. package/dist/src/layout.js +0 -90
  201. package/dist/src/model.d.ts +0 -51
  202. package/dist/src/model.js +0 -230
  203. package/dist/src/rules.d.ts +0 -71
  204. package/dist/src/rules.js +0 -157
  205. package/dist/src/transfer.d.ts +0 -30
  206. package/dist/src/transfer.js +0 -110
@@ -0,0 +1,39 @@
1
+ import { z } from "zod";
2
+ /** One tool: `inputSchema` is the JSON Schema of its arguments, as its server states it. */
3
+ export declare const ToolEntry: z.ZodObject<{
4
+ name: z.ZodString;
5
+ description: z.ZodOptional<z.ZodString>;
6
+ inputSchema: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
7
+ }, z.core.$strip>;
8
+ /**
9
+ * `tools@1`: a set of tools whose names and arguments are known only at run time. It is one fixed
10
+ * contract however the tools change, so a binding to it holds while they do: the Hub checks a
11
+ * call's envelope, and whoever runs the tool checks its arguments.
12
+ *
13
+ * A call is refused `unknown` when no tool has that name and `not_connected` when what runs the
14
+ * tools can't be reached now. A tool that ran and failed isn't a refusal: it answers with
15
+ * `failed`, and its `output` says why, for the caller's model to read.
16
+ *
17
+ * A provider fits what it has to these limits: it leaves out a tool whose name is too long or that
18
+ * won't fit one frame, cuts a long description, and cuts an output, saying that it did.
19
+ */
20
+ export declare const tools: import("@agentorg/sdk").RpcInterface<"tools", {
21
+ list: import("@agentorg/sdk").MethodSpec<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
22
+ tools: z.ZodArray<z.ZodObject<{
23
+ name: z.ZodString;
24
+ description: z.ZodOptional<z.ZodString>;
25
+ inputSchema: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
26
+ }, z.core.$strip>>;
27
+ }, z.core.$strip>>;
28
+ /** Run one tool. `output` is its result as text. */
29
+ call: import("@agentorg/sdk").MethodSpec<z.ZodObject<{
30
+ name: z.ZodString;
31
+ arguments: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
32
+ }, z.core.$strip>, z.ZodObject<{
33
+ output: z.ZodString;
34
+ failed: z.ZodOptional<z.ZodLiteral<true>>;
35
+ }, z.core.$strip>>;
36
+ }, {
37
+ /** The tools changed: `list` again. */
38
+ changed: import("@agentorg/sdk").EventSpec<z.ZodObject<{}, z.core.$strip>>;
39
+ }, 1>;
@@ -0,0 +1,43 @@
1
+ import { defineInterface, event, method } from "@agentorg/sdk";
2
+ import { z } from "zod";
3
+ const ToolName = z.string().min(1).max(128);
4
+ /** The most a call's output carries: what a model's function output can take. */
5
+ const OUTPUT_MAX = 200_000;
6
+ /** One tool: `inputSchema` is the JSON Schema of its arguments, as its server states it. */
7
+ export const ToolEntry = z.object({
8
+ name: ToolName,
9
+ description: z.string().max(16_384).optional(),
10
+ inputSchema: z.record(z.string(), z.json()),
11
+ });
12
+ /**
13
+ * `tools@1`: a set of tools whose names and arguments are known only at run time. It is one fixed
14
+ * contract however the tools change, so a binding to it holds while they do: the Hub checks a
15
+ * call's envelope, and whoever runs the tool checks its arguments.
16
+ *
17
+ * A call is refused `unknown` when no tool has that name and `not_connected` when what runs the
18
+ * tools can't be reached now. A tool that ran and failed isn't a refusal: it answers with
19
+ * `failed`, and its `output` says why, for the caller's model to read.
20
+ *
21
+ * A provider fits what it has to these limits: it leaves out a tool whose name is too long or that
22
+ * won't fit one frame, cuts a long description, and cuts an output, saying that it did.
23
+ */
24
+ export const tools = defineInterface({
25
+ name: "tools",
26
+ major: 1,
27
+ kind: "rpc",
28
+ methods: {
29
+ list: method({ input: z.object({}), output: z.object({ tools: z.array(ToolEntry) }) }),
30
+ /** Run one tool. `output` is its result as text. */
31
+ call: method({
32
+ input: z.object({ name: ToolName, arguments: z.record(z.string(), z.json()) }),
33
+ output: z.object({
34
+ output: z.string().max(OUTPUT_MAX),
35
+ failed: z.literal(true).optional(),
36
+ }),
37
+ }),
38
+ },
39
+ events: {
40
+ /** The tools changed: `list` again. */
41
+ changed: event(z.object({})),
42
+ },
43
+ });
@@ -0,0 +1 @@
1
+ export { type Manager, type ManagerOptions, startManager } from "./manager.js";
@@ -0,0 +1 @@
1
+ export { startManager } from "./manager.js";
@@ -0,0 +1,21 @@
1
+ import { type Log } from "@agentorg/sdk";
2
+ export interface ManagerOptions {
3
+ hubUrl: string;
4
+ /** Its own Actor, bound to `hub.actors@1`, `hub.grants@1` and `hub.bindings@1`, which make it a manager. */
5
+ actorId: string;
6
+ credential: string;
7
+ /** A private folder of its own, which holds its records and the skills. */
8
+ dir: string;
9
+ log?: Log;
10
+ }
11
+ export interface Manager {
12
+ /** Leave the Hub. What it keeps stays. */
13
+ close(): Promise<void>;
14
+ }
15
+ /**
16
+ * Run management as an Actor exporting `agents@1`, `connections@1`, `skills@1` and, as `settings`,
17
+ * `agent.settings@1`. It keeps only what the Hub can't know. A provider is connected by exposing
18
+ * its export to this Actor: the Hub's slots are the list of them, and what is exposed to an agent
19
+ * is the Hub's bindings. No status is stored, and no secret reaches it to keep.
20
+ */
21
+ export declare function startManager(options: ManagerOptions): Promise<Manager>;
@@ -0,0 +1,528 @@
1
+ import { chmodSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { agentProvider, agentSettings, agents, ConnectionOrigin, connections, hubActors, hubBindings, hubGrants, mcpProvider, skills, } from "@agentorg/interfaces";
4
+ import { describeInterface, Refused } from "@agentorg/sdk";
5
+ import { connect } from "@agentorg/sdk/client";
6
+ import { z } from "zod";
7
+ import { createSkills, readSkillFolder } from "./skills.js";
8
+ /** What only management knows of an agent: where it came from, what it is told, and its skills. */
9
+ const AgentRecord = z.object({
10
+ provider: z.string(),
11
+ creatable: z.string(),
12
+ instructions: z.string(),
13
+ skills: z.array(z.string()),
14
+ });
15
+ const Records = z.object({
16
+ agents: z.record(z.string(), AgentRecord),
17
+ connections: z.record(z.string(), ConnectionOrigin),
18
+ });
19
+ const FILE = "manager.json";
20
+ const PERSON = "person";
21
+ const TOOLS = "tools@1";
22
+ const TOOLS_EXPORT = "tools";
23
+ const quiet = { info() { }, warn() { }, error() { } };
24
+ const messageOf = (error) => (error instanceof Error ? error.message : String(error));
25
+ const alreadyGone = (error) => error instanceof Refused && error.code === "unknown";
26
+ /**
27
+ * Run management as an Actor exporting `agents@1`, `connections@1`, `skills@1` and, as `settings`,
28
+ * `agent.settings@1`. It keeps only what the Hub can't know. A provider is connected by exposing
29
+ * its export to this Actor: the Hub's slots are the list of them, and what is exposed to an agent
30
+ * is the Hub's bindings. No status is stored, and no secret reaches it to keep.
31
+ */
32
+ export async function startManager(options) {
33
+ const log = options.log ?? quiet;
34
+ const { dir } = options;
35
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
36
+ chmodSync(dir, 0o700);
37
+ const path = join(dir, FILE);
38
+ const read = () => {
39
+ const empty = { agents: {}, connections: {} };
40
+ let raw;
41
+ try {
42
+ raw = readFileSync(path, "utf8");
43
+ }
44
+ catch (error) {
45
+ if (error.code === "ENOENT")
46
+ return empty;
47
+ throw error;
48
+ }
49
+ try {
50
+ return Records.parse(JSON.parse(raw));
51
+ }
52
+ catch {
53
+ renameSync(path, `${path}.unreadable-${Date.now()}`);
54
+ log.error("Management's records can't be read: they are set aside and start empty.");
55
+ return empty;
56
+ }
57
+ };
58
+ const records = read();
59
+ const save = () => {
60
+ writeFileSync(`${path}.tmp`, JSON.stringify(records), { mode: 0o600, flush: true });
61
+ renameSync(`${path}.tmp`, path);
62
+ };
63
+ const library = createSkills(join(dir, "skills"));
64
+ /** Agents being made: they can read their settings, and nothing else can see them yet. */
65
+ const creating = new Map();
66
+ const client = await connect({
67
+ hubUrl: options.hubUrl,
68
+ actorId: options.actorId,
69
+ credential: options.credential,
70
+ slots: { actors: hubActors, grants: hubGrants, bindings: hubBindings },
71
+ exports: { agents, connections, skills, settings: agentSettings },
72
+ log,
73
+ start(ctx) {
74
+ const hub = {
75
+ actors: ctx.slots.actors.call,
76
+ grants: ctx.slots.grants.call,
77
+ bindings: ctx.slots.bindings.call,
78
+ };
79
+ /** The providers of an interface exposed to this Actor now. */
80
+ const exposed = (iface) => {
81
+ const { id, hash } = describeInterface(iface);
82
+ return ctx
83
+ .exposed()
84
+ .filter(({ described }) => described.id === id && described.hash === hash)
85
+ .map(({ provider, call }) => ({ actor: provider.actor, call: call }));
86
+ };
87
+ const agentProviders = () => exposed(agentProvider);
88
+ const mcpProviders = () => exposed(mcpProvider);
89
+ const named = (list, actor, what) => {
90
+ const found = list.find((one) => one.actor === actor);
91
+ if (!found)
92
+ throw new Refused("unknown", `${actor} isn't a connected ${what}.`);
93
+ return found;
94
+ };
95
+ const open = async () => new Map((await hub.actors.list({})).actors
96
+ .filter((actor) => actor.state !== "closed")
97
+ .map((actor) => [actor.actorId, actor]));
98
+ const nameOf = async (actor) => (await hub.actors.get({ actorId: actor })).name;
99
+ const changed = (agent) => ctx.exports.settings.emit("changed", {}, { to: agent });
100
+ /** What every one of these answers; one that doesn't is logged and left out. */
101
+ const fromEach = async (list, read) => (await Promise.allSettled(list.map(read))).flatMap((result) => {
102
+ if (result.status === "fulfilled")
103
+ return [result.value];
104
+ log.warn(`A provider didn't answer: ${messageOf(result.reason)}`);
105
+ return [];
106
+ });
107
+ const recordOf = (agent) => {
108
+ const record = records.agents[agent];
109
+ if (!record)
110
+ throw new Refused("unknown", `Management has no agent ${agent}.`);
111
+ return record;
112
+ };
113
+ const settingsOf = (agent) => creating.get(agent) ?? recordOf(agent);
114
+ const originOf = (connection) => {
115
+ const origin = records.connections[connection];
116
+ if (!origin)
117
+ throw new Refused("unknown", `Management has no connection ${connection}.`);
118
+ return origin;
119
+ };
120
+ const agentStatus = async (agent, provider) => {
121
+ try {
122
+ return await named(agentProviders(), provider, "agent provider").call.status({ agent });
123
+ }
124
+ catch {
125
+ return { state: "down", detail: "Its provider can't be reached." };
126
+ }
127
+ };
128
+ const connectionStatus = async (connection) => {
129
+ const origin = records.connections[connection];
130
+ if (!origin) {
131
+ // Exposed by hand, so no provider is known: the Hub says whether it is there.
132
+ const { connected } = await hub.actors.get({ actorId: connection });
133
+ return { state: connected ? "connected" : "down", tools: [] };
134
+ }
135
+ try {
136
+ const mcp = named(mcpProviders(), origin.provider, "MCP provider");
137
+ return await mcp.call.status({ connection });
138
+ }
139
+ catch {
140
+ return { state: "down", detail: "Its provider can't be reached.", tools: [] };
141
+ }
142
+ };
143
+ const offering = async (kind) => {
144
+ const providers = mcpProviders();
145
+ const answers = await fromEach(providers, async ({ actor, call }) => ({
146
+ actor,
147
+ call,
148
+ kinds: (await call.kinds({})).kinds,
149
+ }));
150
+ const found = answers.find((one) => one.kinds.some((k) => k.kind === kind));
151
+ if (!found)
152
+ throw new Refused("unknown", `No connected MCP provider offers ${kind}.`);
153
+ return found;
154
+ };
155
+ const exposeConnection = async (agent, connection, as) => {
156
+ const { slot } = await hub.grants.expose({
157
+ provider: connection,
158
+ export: TOOLS_EXPORT,
159
+ to: agent,
160
+ ...(as ? { as } : {}),
161
+ });
162
+ return slot;
163
+ };
164
+ /** Remove a connection through its provider; one that has lost it leaves only the Actor. */
165
+ const removeConnection = async (connection, provider) => {
166
+ const mcp = mcpProviders().find((one) => one.actor === provider);
167
+ try {
168
+ if (mcp)
169
+ return void (await mcp.call.remove({ connection }));
170
+ }
171
+ catch (error) {
172
+ if (!alreadyGone(error))
173
+ throw error;
174
+ }
175
+ await hub.actors.close({ actorId: connection });
176
+ };
177
+ /** The same for an agent. */
178
+ const removeAgent = async (agent, provider) => {
179
+ const maker = agentProviders().find((one) => one.actor === provider);
180
+ try {
181
+ if (maker)
182
+ return void (await maker.call.remove({ agent }));
183
+ }
184
+ catch (error) {
185
+ if (!alreadyGone(error))
186
+ throw error;
187
+ }
188
+ await hub.actors.close({ actorId: agent });
189
+ };
190
+ /** For undoing: whatever the provider says, the thing goes. */
191
+ const closing = (what, remove) => remove().catch(async (error) => {
192
+ log.warn(`Removing ${what}: ${messageOf(error)}`);
193
+ await hub.actors.close({ actorId: what });
194
+ });
195
+ const dropSkill = (name) => {
196
+ library.remove(name);
197
+ for (const [agent, record] of Object.entries(records.agents))
198
+ if (record.skills.includes(name)) {
199
+ record.skills = record.skills.filter((skill) => skill !== name);
200
+ changed(agent);
201
+ }
202
+ };
203
+ ctx.exports.settings.implement({
204
+ get: (_, { caller }) => {
205
+ const { instructions, skills: names } = settingsOf(caller);
206
+ return {
207
+ instructions,
208
+ skills: names.flatMap((name) => library.entry(name) ?? []),
209
+ };
210
+ },
211
+ skill: ({ name, path: file }, { caller }) => {
212
+ const text = settingsOf(caller).skills.includes(name)
213
+ ? library.read(name, file)
214
+ : undefined;
215
+ if (text === undefined)
216
+ throw new Refused("unknown", `No skill ${name} with that file is exposed to you.`);
217
+ return { text };
218
+ },
219
+ });
220
+ ctx.exports.agents.implement({
221
+ creatable: async () => ({
222
+ creatables: (await fromEach(agentProviders(), async ({ actor, call }) => (await call.creatable({})).creatables.map((one) => ({ ...one, provider: actor })))).flat(),
223
+ }),
224
+ providers: async () => ({
225
+ providers: await Promise.all(agentProviders().map(async ({ actor }) => ({
226
+ provider: actor,
227
+ name: await nameOf(actor),
228
+ }))),
229
+ }),
230
+ async create(input, { caller }) {
231
+ const { creatable: id, name, answers, connections: picked = {} } = input;
232
+ const provider = named(agentProviders(), input.provider, "agent provider");
233
+ const creatable = (await provider.call.creatable({})).creatables.find((c) => c.id === id);
234
+ if (!creatable)
235
+ throw new Refused("unknown", `${input.provider} offers no ${id}.`);
236
+ for (const need of creatable.mcp)
237
+ if (need.how === "pick" && !picked[need.slot])
238
+ throw new Refused("invalid", `Pick a connection for ${need.slot}.`);
239
+ /** What this creation has made so far, undone last first if a step fails. */
240
+ const undo = [];
241
+ try {
242
+ const made = await provider.call.create({ creatable: id, name, answers });
243
+ const { agent } = made;
244
+ undo.push(() => closing(agent, () => removeAgent(agent, input.provider)));
245
+ const record = {
246
+ provider: input.provider,
247
+ creatable: id,
248
+ instructions: creatable.instructions,
249
+ skills: [],
250
+ };
251
+ creating.set(agent, record);
252
+ undo.push(() => creating.delete(agent));
253
+ const origins = {};
254
+ await hub.grants.bind({
255
+ consumer: agent,
256
+ slot: made.settings,
257
+ provider: options.actorId,
258
+ export: "settings",
259
+ });
260
+ for (const skill of creatable.skills) {
261
+ if (!library.has(skill.name)) {
262
+ const files = {};
263
+ for (const file of skill.files)
264
+ files[file] = (await provider.call.skill({ creatable: id, name: skill.name, path: file })).text;
265
+ library.add(files, skill.name);
266
+ // Another agent may have been given it meanwhile, and then it stays.
267
+ undo.push(() => {
268
+ if (!Object.values(records.agents).some((r) => r.skills.includes(skill.name)))
269
+ library.remove(skill.name);
270
+ });
271
+ }
272
+ record.skills.push(skill.name);
273
+ }
274
+ for (const need of creatable.mcp) {
275
+ let connection = picked[need.slot];
276
+ if (need.how === "create") {
277
+ const mcp = await offering(need.kind);
278
+ const params = { ...need.params };
279
+ for (const [param, ask] of Object.entries(need.fromAnswers ?? {}))
280
+ if (answers[ask] !== undefined)
281
+ params[param] = answers[ask];
282
+ const { connection: id2, target } = await mcp.call.create({
283
+ kind: need.kind,
284
+ params,
285
+ name: `${name}: ${need.title}`.slice(0, 128),
286
+ });
287
+ connection = id2;
288
+ undo.push(() => closing(id2, () => removeConnection(id2, mcp.actor)));
289
+ origins[id2] = {
290
+ provider: mcp.actor,
291
+ kind: need.kind,
292
+ target,
293
+ madeBy: caller,
294
+ madeFor: agent,
295
+ at: new Date().toISOString(),
296
+ };
297
+ }
298
+ await exposeConnection(agent, connection, need.slot);
299
+ }
300
+ await hub.grants.expose({
301
+ provider: agent,
302
+ export: made.chat,
303
+ to: PERSON,
304
+ });
305
+ records.agents[agent] = record;
306
+ Object.assign(records.connections, origins);
307
+ undo.push(() => {
308
+ delete records.agents[agent];
309
+ for (const connection of Object.keys(origins))
310
+ delete records.connections[connection];
311
+ });
312
+ save();
313
+ creating.delete(agent);
314
+ return { agent };
315
+ }
316
+ catch (error) {
317
+ for (const step of undo.reverse())
318
+ await Promise.resolve()
319
+ .then(step)
320
+ .catch((failed) => log.error(`Undoing a creation: ${messageOf(failed)}`));
321
+ throw error;
322
+ }
323
+ },
324
+ async list() {
325
+ const actors = await open();
326
+ return {
327
+ agents: await Promise.all(Object.entries(records.agents).flatMap(([agent, record]) => {
328
+ const actor = actors.get(agent);
329
+ return actor
330
+ ? [
331
+ agentStatus(agent, record.provider).then((status) => ({
332
+ agent,
333
+ name: actor.name,
334
+ status,
335
+ provider: record.provider,
336
+ creatable: record.creatable,
337
+ })),
338
+ ]
339
+ : [];
340
+ })),
341
+ };
342
+ },
343
+ async get({ agent }) {
344
+ const record = recordOf(agent);
345
+ const { bindings } = await hub.bindings.list({ actor: agent });
346
+ const [name, status, mcp] = await Promise.all([
347
+ nameOf(agent),
348
+ agentStatus(agent, record.provider),
349
+ Promise.all(bindings
350
+ .filter((b) => b.consumer === agent && b.interface === TOOLS)
351
+ .map(async (b) => ({
352
+ slot: b.slot,
353
+ connection: b.provider,
354
+ ...(records.connections[b.provider]
355
+ ? { origin: records.connections[b.provider] }
356
+ : {}),
357
+ status: await connectionStatus(b.provider),
358
+ }))),
359
+ ]);
360
+ return {
361
+ agent,
362
+ name,
363
+ status,
364
+ provider: record.provider,
365
+ creatable: record.creatable,
366
+ instructions: record.instructions,
367
+ skills: record.skills.flatMap((skill) => library.entry(skill) ?? []),
368
+ mcp,
369
+ };
370
+ },
371
+ async start({ agent }) {
372
+ const { provider } = recordOf(agent);
373
+ return named(agentProviders(), provider, "agent provider").call.start({ agent });
374
+ },
375
+ async stop({ agent }) {
376
+ const { provider } = recordOf(agent);
377
+ return named(agentProviders(), provider, "agent provider").call.stop({ agent });
378
+ },
379
+ async expose(input) {
380
+ const record = recordOf(input.agent);
381
+ if ("connection" in input)
382
+ return { slot: await exposeConnection(input.agent, input.connection, input.as) };
383
+ if (!library.has(input.skill))
384
+ throw new Refused("unknown", `Management has no skill ${input.skill}.`);
385
+ if (!record.skills.includes(input.skill)) {
386
+ record.skills.push(input.skill);
387
+ save();
388
+ changed(input.agent);
389
+ }
390
+ return {};
391
+ },
392
+ async unexpose(input) {
393
+ const record = recordOf(input.agent);
394
+ if ("slot" in input) {
395
+ await hub.grants.unexpose({ to: input.agent, slot: input.slot });
396
+ return {};
397
+ }
398
+ if (record.skills.includes(input.skill)) {
399
+ record.skills = record.skills.filter((skill) => skill !== input.skill);
400
+ save();
401
+ changed(input.agent);
402
+ }
403
+ return {};
404
+ },
405
+ /** The connections go first: if one can't, the agent is still here to be tried again. */
406
+ async remove({ agent }) {
407
+ const record = recordOf(agent);
408
+ for (const [connection, origin] of Object.entries(records.connections)) {
409
+ if (origin.madeFor !== agent)
410
+ continue;
411
+ await removeConnection(connection, origin.provider);
412
+ delete records.connections[connection];
413
+ save();
414
+ }
415
+ await removeAgent(agent, record.provider);
416
+ delete records.agents[agent];
417
+ save();
418
+ return {};
419
+ },
420
+ });
421
+ ctx.exports.connections.implement({
422
+ providers: async () => ({
423
+ providers: await fromEach(mcpProviders(), async ({ actor, call }) => ({
424
+ provider: actor,
425
+ name: await nameOf(actor),
426
+ kinds: (await call.kinds({})).kinds,
427
+ })),
428
+ }),
429
+ // `secrets` go straight to the provider: nothing here keeps or logs them.
430
+ async create({ provider, kind, params, secrets, name }, { caller }) {
431
+ const mcp = named(mcpProviders(), provider, "MCP provider");
432
+ const { connection, target } = await mcp.call.create({
433
+ kind,
434
+ params,
435
+ name,
436
+ ...(secrets ? { secrets } : {}),
437
+ });
438
+ try {
439
+ records.connections[connection] = {
440
+ provider,
441
+ kind,
442
+ target,
443
+ madeBy: caller,
444
+ at: new Date().toISOString(),
445
+ };
446
+ save();
447
+ }
448
+ catch (error) {
449
+ delete records.connections[connection];
450
+ await closing(connection, () => removeConnection(connection, provider));
451
+ throw error;
452
+ }
453
+ return { connection };
454
+ },
455
+ async list() {
456
+ const actors = await open();
457
+ return {
458
+ connections: await Promise.all(Object.entries(records.connections).flatMap(([connection, origin]) => {
459
+ const actor = actors.get(connection);
460
+ return actor
461
+ ? [
462
+ connectionStatus(connection).then(({ state }) => ({
463
+ connection,
464
+ name: actor.name,
465
+ state,
466
+ origin,
467
+ })),
468
+ ]
469
+ : [];
470
+ })),
471
+ };
472
+ },
473
+ async get({ connection }) {
474
+ const origin = originOf(connection);
475
+ return {
476
+ connection,
477
+ name: await nameOf(connection),
478
+ origin,
479
+ status: await connectionStatus(connection),
480
+ };
481
+ },
482
+ async remove({ connection }) {
483
+ const origin = originOf(connection);
484
+ await removeConnection(connection, origin.provider);
485
+ delete records.connections[connection];
486
+ save();
487
+ return {};
488
+ },
489
+ });
490
+ ctx.exports.skills.implement({
491
+ add: (input) => {
492
+ const added = library.add("path" in input ? readSkillFolder(input.path) : input.files);
493
+ for (const [agent, record] of Object.entries(records.agents))
494
+ if (record.skills.includes(added.name))
495
+ changed(agent);
496
+ return added;
497
+ },
498
+ list: () => ({ skills: library.list() }),
499
+ get: ({ name }) => {
500
+ const entry = library.entry(name);
501
+ if (!entry)
502
+ throw new Refused("unknown", `Management has no skill ${name}.`);
503
+ return {
504
+ ...entry,
505
+ text: library.read(name),
506
+ files: library.paths(name),
507
+ agents: Object.entries(records.agents)
508
+ .filter(([, record]) => record.skills.includes(name))
509
+ .map(([agent]) => agent),
510
+ };
511
+ },
512
+ remove: ({ name }) => {
513
+ if (!library.has(name))
514
+ throw new Refused("unknown", `Management has no skill ${name}.`);
515
+ dropSkill(name);
516
+ save();
517
+ return {};
518
+ },
519
+ });
520
+ },
521
+ });
522
+ return {
523
+ async close() {
524
+ client.close();
525
+ await client.closed;
526
+ },
527
+ };
528
+ }
@@ -0,0 +1,25 @@
1
+ import { SkillEntry } from "@agentorg/interfaces";
2
+ import type { z } from "zod";
3
+ type Entry = z.infer<typeof SkillEntry>;
4
+ export type SkillFiles = Record<string, string>;
5
+ /** A skill's folder on this machine, as files; each must be text within a skill's limits. */
6
+ export declare function readSkillFolder(folder: string): SkillFiles;
7
+ /** The skills, each a `SKILL.md` folder under `dir`. What each says of itself is read from it. */
8
+ export declare function createSkills(dir: string): {
9
+ has: (name: string) => boolean;
10
+ entry: (name: string) => Entry | undefined;
11
+ read: (name: string, path?: string) => string | undefined;
12
+ list(): {
13
+ name: string;
14
+ description: string;
15
+ }[];
16
+ paths(name: string): string[];
17
+ /**
18
+ * Add a skill, or replace the one of its name, whole: it is never seen half written. With
19
+ * `expected`, a skill that calls itself anything else is refused before anything is touched.
20
+ */
21
+ add(files: SkillFiles, expected?: string): Entry;
22
+ remove(name: string): void;
23
+ };
24
+ export type Skills = ReturnType<typeof createSkills>;
25
+ export {};