orbitx 0.2.9 → 0.3.2

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 (213) hide show
  1. package/Readme.md +478 -456
  2. package/dist/agents/backend.d.ts +4 -0
  3. package/dist/agents/backend.d.ts.map +1 -0
  4. package/dist/agents/backend.js +54 -0
  5. package/dist/agents/backend.js.map +1 -0
  6. package/dist/agents/frontend.d.ts +4 -0
  7. package/dist/agents/frontend.d.ts.map +1 -0
  8. package/dist/agents/frontend.js +50 -0
  9. package/dist/agents/frontend.js.map +1 -0
  10. package/dist/agents/index.d.ts +10 -0
  11. package/dist/agents/index.d.ts.map +1 -0
  12. package/dist/agents/index.js +22 -0
  13. package/dist/agents/index.js.map +1 -0
  14. package/dist/agents/planner.d.ts +4 -0
  15. package/dist/agents/planner.d.ts.map +1 -0
  16. package/dist/agents/planner.js +86 -0
  17. package/dist/agents/planner.js.map +1 -0
  18. package/dist/agents/protocol.d.ts +5 -0
  19. package/dist/agents/protocol.d.ts.map +1 -0
  20. package/dist/agents/protocol.js +70 -0
  21. package/dist/agents/protocol.js.map +1 -0
  22. package/dist/agents/reasoner.d.ts +5 -0
  23. package/dist/agents/reasoner.d.ts.map +1 -0
  24. package/dist/agents/reasoner.js +96 -0
  25. package/dist/agents/reasoner.js.map +1 -0
  26. package/dist/agents/research.d.ts +4 -0
  27. package/dist/agents/research.d.ts.map +1 -0
  28. package/dist/agents/research.js +28 -0
  29. package/dist/agents/research.js.map +1 -0
  30. package/dist/agents/tester.d.ts +4 -0
  31. package/dist/agents/tester.d.ts.map +1 -0
  32. package/dist/agents/tester.js +70 -0
  33. package/dist/agents/tester.js.map +1 -0
  34. package/dist/core/agent-definition.d.ts +61 -0
  35. package/dist/core/agent-definition.d.ts.map +1 -0
  36. package/dist/core/agent-definition.js +82 -0
  37. package/dist/core/agent-definition.js.map +1 -0
  38. package/dist/core/ai-ask.d.ts +28 -0
  39. package/dist/core/ai-ask.d.ts.map +1 -0
  40. package/dist/core/ai-ask.js +80 -0
  41. package/dist/core/ai-ask.js.map +1 -0
  42. package/dist/core/ai-provider.d.ts +3 -0
  43. package/dist/core/ai-provider.d.ts.map +1 -1
  44. package/dist/core/ai-provider.js.map +1 -1
  45. package/dist/core/anthropic-provider.d.ts +1 -0
  46. package/dist/core/anthropic-provider.d.ts.map +1 -1
  47. package/dist/core/anthropic-provider.js +3 -0
  48. package/dist/core/anthropic-provider.js.map +1 -1
  49. package/dist/core/base-agent.d.ts +51 -28
  50. package/dist/core/base-agent.d.ts.map +1 -1
  51. package/dist/core/base-agent.js +118 -26
  52. package/dist/core/base-agent.js.map +1 -1
  53. package/dist/core/deepseek-provider.d.ts +1 -0
  54. package/dist/core/deepseek-provider.d.ts.map +1 -1
  55. package/dist/core/deepseek-provider.js +3 -0
  56. package/dist/core/deepseek-provider.js.map +1 -1
  57. package/dist/core/mcp-auto-execution-policy.d.ts +22 -0
  58. package/dist/core/mcp-auto-execution-policy.d.ts.map +1 -0
  59. package/dist/core/mcp-auto-execution-policy.js +85 -0
  60. package/dist/core/mcp-auto-execution-policy.js.map +1 -0
  61. package/dist/core/mcp-computer.d.ts +14 -1
  62. package/dist/core/mcp-computer.d.ts.map +1 -1
  63. package/dist/core/mcp-computer.js +352 -71
  64. package/dist/core/mcp-computer.js.map +1 -1
  65. package/dist/core/ollama-provider.d.ts +1 -0
  66. package/dist/core/ollama-provider.d.ts.map +1 -1
  67. package/dist/core/ollama-provider.js +3 -0
  68. package/dist/core/ollama-provider.js.map +1 -1
  69. package/dist/core/openai-provider.d.ts +1 -0
  70. package/dist/core/openai-provider.d.ts.map +1 -1
  71. package/dist/core/openai-provider.js +3 -0
  72. package/dist/core/openai-provider.js.map +1 -1
  73. package/dist/core/stateless-agent.d.ts +30 -0
  74. package/dist/core/stateless-agent.d.ts.map +1 -0
  75. package/dist/core/stateless-agent.js +79 -0
  76. package/dist/core/stateless-agent.js.map +1 -0
  77. package/dist/core/swarm-base.d.ts +88 -0
  78. package/dist/core/swarm-base.d.ts.map +1 -0
  79. package/dist/core/swarm-base.js +427 -0
  80. package/dist/core/swarm-base.js.map +1 -0
  81. package/dist/index.d.ts +13 -5
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +7 -3
  84. package/dist/index.js.map +1 -1
  85. package/dist/tests/agents/default-agents.test.d.ts +2 -0
  86. package/dist/tests/agents/default-agents.test.d.ts.map +1 -0
  87. package/dist/tests/agents/default-agents.test.js +106 -0
  88. package/dist/tests/agents/default-agents.test.js.map +1 -0
  89. package/dist/tests/core/agent-definition.test.d.ts +2 -0
  90. package/dist/tests/core/agent-definition.test.d.ts.map +1 -0
  91. package/dist/tests/core/agent-definition.test.js +99 -0
  92. package/dist/tests/core/agent-definition.test.js.map +1 -0
  93. package/dist/tests/core/ai-ask.test.d.ts +2 -0
  94. package/dist/tests/core/ai-ask.test.d.ts.map +1 -0
  95. package/dist/tests/core/ai-ask.test.js +101 -0
  96. package/dist/tests/core/ai-ask.test.js.map +1 -0
  97. package/dist/tests/core/mcp-auto-execution-policy.test.d.ts +2 -0
  98. package/dist/tests/core/mcp-auto-execution-policy.test.d.ts.map +1 -0
  99. package/dist/tests/core/mcp-auto-execution-policy.test.js +107 -0
  100. package/dist/tests/core/mcp-auto-execution-policy.test.js.map +1 -0
  101. package/dist/tests/core/scripted-provider.d.ts +38 -0
  102. package/dist/tests/core/scripted-provider.d.ts.map +1 -0
  103. package/dist/tests/core/scripted-provider.js +85 -0
  104. package/dist/tests/core/scripted-provider.js.map +1 -0
  105. package/dist/tests/core/stateless-agent.test.d.ts +2 -0
  106. package/dist/tests/core/stateless-agent.test.d.ts.map +1 -0
  107. package/dist/tests/core/stateless-agent.test.js +73 -0
  108. package/dist/tests/core/stateless-agent.test.js.map +1 -0
  109. package/dist/tests/core/swarm-base.test.d.ts +2 -0
  110. package/dist/tests/core/swarm-base.test.d.ts.map +1 -0
  111. package/dist/tests/core/swarm-base.test.js +387 -0
  112. package/dist/tests/core/swarm-base.test.js.map +1 -0
  113. package/dist/tests/index.d.ts +6 -0
  114. package/dist/tests/index.d.ts.map +1 -1
  115. package/dist/tests/index.js +6 -0
  116. package/dist/tests/index.js.map +1 -1
  117. package/dist/tests/tools/agent/agent-tools.test.js +225 -153
  118. package/dist/tests/tools/agent/agent-tools.test.js.map +1 -1
  119. package/dist/tools/agent/active.d.ts +5 -0
  120. package/dist/tools/agent/active.d.ts.map +1 -0
  121. package/dist/tools/agent/active.js +40 -0
  122. package/dist/tools/agent/active.js.map +1 -0
  123. package/dist/tools/agent/fire.d.ts +5 -0
  124. package/dist/tools/agent/fire.d.ts.map +1 -0
  125. package/dist/tools/agent/fire.js +38 -0
  126. package/dist/tools/agent/fire.js.map +1 -0
  127. package/dist/tools/agent/hire.d.ts +2 -2
  128. package/dist/tools/agent/hire.d.ts.map +1 -1
  129. package/dist/tools/agent/hire.js +43 -10
  130. package/dist/tools/agent/hire.js.map +1 -1
  131. package/dist/tools/agent/index.d.ts +22 -19
  132. package/dist/tools/agent/index.d.ts.map +1 -1
  133. package/dist/tools/agent/index.js +29 -21
  134. package/dist/tools/agent/index.js.map +1 -1
  135. package/dist/tools/agent/prompt.d.ts +2 -2
  136. package/dist/tools/agent/prompt.d.ts.map +1 -1
  137. package/dist/tools/agent/prompt.js +19 -53
  138. package/dist/tools/agent/prompt.js.map +1 -1
  139. package/dist/tools/agent/registry.d.ts +74 -24
  140. package/dist/tools/agent/registry.d.ts.map +1 -1
  141. package/dist/tools/agent/registry.js +93 -48
  142. package/dist/tools/agent/registry.js.map +1 -1
  143. package/dist/tools/agent/report-group.d.ts +5 -0
  144. package/dist/tools/agent/report-group.d.ts.map +1 -0
  145. package/dist/tools/agent/report-group.js +50 -0
  146. package/dist/tools/agent/report-group.js.map +1 -0
  147. package/dist/tools/agent/report-parent.d.ts +5 -0
  148. package/dist/tools/agent/report-parent.d.ts.map +1 -0
  149. package/dist/tools/agent/report-parent.js +36 -0
  150. package/dist/tools/agent/report-parent.js.map +1 -0
  151. package/dist/tools/agent/types.d.ts +5 -0
  152. package/dist/tools/agent/types.d.ts.map +1 -0
  153. package/dist/tools/agent/types.js +17 -0
  154. package/dist/tools/agent/types.js.map +1 -0
  155. package/docs/agents.md +249 -228
  156. package/docs/api-reference.md +9 -4
  157. package/docs/getting-started.md +78 -78
  158. package/docs/index.md +24 -23
  159. package/docs/mcp-architecture.md +71 -6
  160. package/docs/providers.md +258 -254
  161. package/docs/skills.md +0 -1
  162. package/docs/streaming.md +133 -133
  163. package/docs/swarm.md +503 -0
  164. package/docs/tools.md +214 -212
  165. package/package.json +1 -1
  166. package/dist/core/image-describer.d.ts +0 -19
  167. package/dist/core/image-describer.d.ts.map +0 -1
  168. package/dist/core/image-describer.js +0 -37
  169. package/dist/core/image-describer.js.map +0 -1
  170. package/dist/core/worker-agent.d.ts +0 -43
  171. package/dist/core/worker-agent.d.ts.map +0 -1
  172. package/dist/core/worker-agent.js +0 -40
  173. package/dist/core/worker-agent.js.map +0 -1
  174. package/dist/skills/shopping.d.ts +0 -4
  175. package/dist/skills/shopping.d.ts.map +0 -1
  176. package/dist/skills/shopping.js +0 -71
  177. package/dist/skills/shopping.js.map +0 -1
  178. package/dist/tools/agent/interaction.d.ts +0 -25
  179. package/dist/tools/agent/interaction.d.ts.map +0 -1
  180. package/dist/tools/agent/interaction.js +0 -14
  181. package/dist/tools/agent/interaction.js.map +0 -1
  182. package/dist/tools/agent/list.d.ts +0 -5
  183. package/dist/tools/agent/list.d.ts.map +0 -1
  184. package/dist/tools/agent/list.js +0 -16
  185. package/dist/tools/agent/list.js.map +0 -1
  186. package/dist/tools/agent/report.d.ts +0 -12
  187. package/dist/tools/agent/report.d.ts.map +0 -1
  188. package/dist/tools/agent/report.js +0 -31
  189. package/dist/tools/agent/report.js.map +0 -1
  190. package/dist/tools/bash/interaction.d.ts +0 -29
  191. package/dist/tools/bash/interaction.d.ts.map +0 -1
  192. package/dist/tools/bash/interaction.js +0 -13
  193. package/dist/tools/bash/interaction.js.map +0 -1
  194. package/dist/tools/browser/interaction.d.ts +0 -49
  195. package/dist/tools/browser/interaction.d.ts.map +0 -1
  196. package/dist/tools/browser/interaction.js +0 -14
  197. package/dist/tools/browser/interaction.js.map +0 -1
  198. package/dist/tools/fs/interaction.d.ts +0 -37
  199. package/dist/tools/fs/interaction.d.ts.map +0 -1
  200. package/dist/tools/fs/interaction.js +0 -13
  201. package/dist/tools/fs/interaction.js.map +0 -1
  202. package/dist/tools/present/interaction.d.ts +0 -17
  203. package/dist/tools/present/interaction.d.ts.map +0 -1
  204. package/dist/tools/present/interaction.js +0 -15
  205. package/dist/tools/present/interaction.js.map +0 -1
  206. package/dist/tools/question-answer/interaction.d.ts +0 -14
  207. package/dist/tools/question-answer/interaction.d.ts.map +0 -1
  208. package/dist/tools/question-answer/interaction.js +0 -13
  209. package/dist/tools/question-answer/interaction.js.map +0 -1
  210. package/dist/tools/todo/interaction.d.ts +0 -30
  211. package/dist/tools/todo/interaction.d.ts.map +0 -1
  212. package/dist/tools/todo/interaction.js +0 -13
  213. package/dist/tools/todo/interaction.js.map +0 -1
@@ -17,9 +17,14 @@ Flat index of every public export from `orbitx` (see `src/index.ts`), grouped by
17
17
 
18
18
  - `BaseAgent`
19
19
  - `SimpleAgent`
20
- - `WorkerAgent` *(experimental)*, type `WorkerAgentRating`
21
20
  - Types: `ExtractedSegment`, `ParsedToolCall`
22
21
 
22
+ ## Swarm — see [Swarm](./swarm.md)
23
+
24
+ - `SwarmBase` — types `SwarmBaseProps`, `SwarmRunOptions`, `SwarmState`, `SwarmAgentState`, `SwarmStreamChunk`, `SwarmStreamCallback`, `SwarmAgentFailure`
25
+ - `AgentDefinition`, `selectTools()`, `applyTextOverride()` — types `AgentDefinitionProps`, `AgentOverrides`, `AgentFactory`, `AgentFactoryOptions`, `TextOverride`
26
+ - Ready-made definitions: `PlannerAgent`, `ReasonerAgent` (+ `REASONER_PANEL_MS`), `BackendAgent`, `FrontendAgent`, `TestAgent`, `ResearchAgent`, `DefaultAgents()`, and the shared instruction fragments `PLANNER_PROTOCOL` / `WORKER_PROTOCOL` / `TEAM_PROTOCOL` / `PRODUCTION_BAR`
27
+
23
28
  ## Tools — see [Tools](./tools.md)
24
29
 
25
30
  - `MCPTool`, `generateRefId()`, `normalizeToolOutput()`
@@ -36,18 +41,18 @@ Built-in tool factories, grouped by domain (each domain also exports a `*Tools()
36
41
  | Present | `PresentAddTool`, `PresentClearTool`, `PresentGetListTool`, `PresentTools`, `getPresentFolder()` |
37
42
  | Question/Answer | `QuestionAnswerTool`, `QuestionAnswerTools` |
38
43
  | Utility | `GetCurrentTimeTool`, `DelayTool`, `ReadImageTool`, `UtilTools` |
39
- | Multi-agent *(experimental)* | `AgentTools(availableAgents, options?)`, `AgentListTool`, `AgentHireTool`, `AgentPromptTool`, `AgentReportTool`, `AgentRegistry`, type `AgentInfo`, type `AgentToolsOptions` — see [Agents](./agents.md#multi-agent-workeragent-experimental) |
44
+ | Swarm | `getAgentTools(options?)`, `AgentTypesTool`, `AgentHireTool`, `AgentFireTool`, `AgentActiveTool`, `AgentPromptTool`, `AgentReportParentTool`, `AgentReportGroupTool`, `AgentToolsRegistry`, types `AgentToolsOptions`, `AgentToolsHandle`, `SwarmController`, `SwarmAgentTypeInfo`, `SwarmAgentInfo`, `AgentToolsEvent`, `AgentToolsAck`, `AgentToolsListener` — see [Swarm](./swarm.md#getagenttoolsoptions) |
40
45
 
41
46
  ## Skills — see [Skills](./skills.md)
42
47
 
43
48
  - `Skill`
44
- - `BackendSecuritySkill`, `BigTaskSkill`, `CodeVerificationSkill`, `LongTaskEfficiencySkill`, `NodeBackendSkill`, `PlannerSkill`, `PresentSkill`, `QuestionAnswerSkill`, `ReactFrontendSkill`, `ResearchSkill`, `ShoppingSkill`, `UiUxDesignSkill`, `WebEndToEndTestSkill`
49
+ - `BackendSecuritySkill`, `BigTaskSkill`, `CodeVerificationSkill`, `LongTaskEfficiencySkill`, `NodeBackendSkill`, `PlannerSkill`, `PresentSkill`, `QuestionAnswerSkill`, `ReactFrontendSkill`, `ResearchSkill`, `UiUxDesignSkill`, `WebEndToEndTestSkill`
45
50
 
46
51
  ## MCP transport — see [MCP Architecture](./mcp-architecture.md)
47
52
 
48
53
  - `MCPServer`, `MCPClient`
49
54
  - `MCPConnection`, `MCPIPCConnection`, `MCPWSConnection`
50
- - `MCPComputer` *(experimental)*
55
+ - `MCPComputer`, type `MCPComputerOptions` *(experimental)*
51
56
  - `MCPStorage`, `MCPFSStorage`
52
57
  - `MCPRNG`
53
58
  - `MCPOutputFilter` (`MCPFilter` is a deprecated alias, removed in `1.0.0`)
@@ -1,78 +1,78 @@
1
- # Getting Started
2
-
3
- ## Install
4
-
5
- ```bash
6
- npm install orbitx
7
- ```
8
-
9
- ## Your first agent
10
-
11
- The fastest path is `SimpleAgent`: give it a provider, an instruction, and a list of tools/skills. It wires up an in-process MCP server/client for you automatically.
12
-
13
- ```ts
14
- import { OllamaProvider, SimpleAgent, GetCurrentTimeTool } from "orbitx";
15
-
16
- const provider = new OllamaProvider("gemma4:e4b");
17
-
18
- const agent = new SimpleAgent({
19
- aiProvider: provider,
20
- instruction: "You are a helpful assistant.",
21
- tools: [GetCurrentTimeTool()],
22
- });
23
-
24
- await agent.run("what is current time?", (chunk) => {
25
- process.stdout.write(chunk.content);
26
- });
27
- ```
28
-
29
- `agent.run(prompt, streamCallback)` resolves once the model has stopped calling tools and produced a final answer. The `streamCallback` is optional — omit it if you only care about the eventual message history via `getCurrentAgentStates()`.
30
-
31
- See [Streaming](./streaming.md) for the full chunk shape (roles, tool call/result chunks, `done` flag).
32
-
33
- ## Choosing a provider
34
-
35
- ```ts
36
- import { OllamaProvider, DeepSeekProvider, AnthropicProvider, OpenAIProvider } from "orbitx";
37
-
38
- new OllamaProvider("gemma4:e4b"); // local, via Ollama
39
- new DeepSeekProvider("api-key", "deepseek-v4-flash"); // hosted
40
- new AnthropicProvider("api-key", "claude-sonnet-5"); // hosted
41
- new OpenAIProvider("api-key", "gpt-5"); // hosted
42
- ```
43
-
44
- Every provider implements the same `AIProvider` interface, so switching models is a one-line change to your agent's `aiProvider`. Details, capability flags, and the main/image role split are in [Providers](./providers.md).
45
-
46
- ## Tools and skills up front
47
-
48
- `SimpleAgent`'s `tools` and `skills` lists are baked into the system prompt once, at construction time — there's no per-turn tool selection/routing step deciding what the model is allowed to see. If you want the model to be able to call something, put it in `tools` (or bundle it inside a `Skill`). See [Tools](./tools.md) and [Skills](./skills.md).
49
-
50
- ## Recovering an agent's state
51
-
52
- `getCurrentAgentStates()` returns a plain JSON-serializable snapshot: message history (each message carrying its own token usage) and running memory summary. Persist it anywhere; pass it back in as `initData` to resume the exact same agent later (after a process restart, in a new request handler, etc.):
53
-
54
- ```ts
55
- import { writeFileSync, existsSync, readFileSync } from "fs";
56
-
57
- const initData = existsSync("./state.json")
58
- ? JSON.parse(readFileSync("./state.json", "utf-8"))
59
- : undefined;
60
-
61
- const agent = new SimpleAgent({
62
- aiProvider: provider,
63
- instruction: "You are a helpful assistant.",
64
- tools: [GetCurrentTimeTool()],
65
- ...(initData ? { initData } : {}),
66
- });
67
-
68
- // after any run() call:
69
- writeFileSync("./state.json", JSON.stringify(agent.getCurrentAgentStates()));
70
- ```
71
-
72
- Messages are only ever appended, never rewritten. When the conversation grows past the memory threshold, OrbitX retires the working context into `retiredMessages` and resets the model's *active* context (`messagesCompact`) from a running summary (`compactMemory`), so an agent can keep going indefinitely without losing the ability to act on what happened earlier — nothing on disk is ever deleted, it just moves from one array to the other. Mechanics are covered in [Agents](./agents.md#memory-compaction).
73
-
74
- ## Next steps
75
-
76
- - Full control over the MCP transport (custom server/client, IPC, WebSocket, sandboxed Docker execution): [MCP Architecture](./mcp-architecture.md).
77
- - Writing your own tool or skill: [Tools](./tools.md#writing-a-custom-tool), [Skills](./skills.md#writing-a-custom-skill).
78
- - Every public export: [API Reference](./api-reference.md).
1
+ # Getting Started
2
+
3
+ ## Install
4
+
5
+ ```bash
6
+ npm install orbitx
7
+ ```
8
+
9
+ ## Your first agent
10
+
11
+ The fastest path is `SimpleAgent`: give it a provider, an instruction, and a list of tools/skills. It wires up an in-process MCP server/client for you automatically.
12
+
13
+ ```ts
14
+ import { OllamaProvider, SimpleAgent, GetCurrentTimeTool } from "orbitx";
15
+
16
+ const provider = new OllamaProvider("gemma4:e4b");
17
+
18
+ const agent = new SimpleAgent({
19
+ aiProvider: provider,
20
+ instruction: "You are a helpful assistant.",
21
+ tools: [GetCurrentTimeTool()],
22
+ });
23
+
24
+ await agent.run("what is current time?", (chunk) => {
25
+ process.stdout.write(chunk.content);
26
+ });
27
+ ```
28
+
29
+ `agent.run(prompt, streamCallback)` resolves once the model has stopped calling tools and produced a final answer. The `streamCallback` is optional — omit it if you only care about the eventual message history via `getCurrentAgentStates()`.
30
+
31
+ See [Streaming](./streaming.md) for the full chunk shape (roles, tool call/result chunks, `done` flag).
32
+
33
+ ## Choosing a provider
34
+
35
+ ```ts
36
+ import { OllamaProvider, DeepSeekProvider, AnthropicProvider, OpenAIProvider } from "orbitx";
37
+
38
+ new OllamaProvider("gemma4:e4b"); // local, via Ollama
39
+ new DeepSeekProvider("api-key", "deepseek-v4-flash"); // hosted
40
+ new AnthropicProvider("api-key", "claude-sonnet-5"); // hosted
41
+ new OpenAIProvider("api-key", "gpt-5"); // hosted
42
+ ```
43
+
44
+ Every provider implements the same `AIProvider` interface, so switching models is a one-line change to your agent's `aiProvider`. Details, capability flags, and the main/image role split are in [Providers](./providers.md).
45
+
46
+ ## Tools and skills up front
47
+
48
+ `SimpleAgent`'s `tools` and `skills` lists are baked into the system prompt once, at construction time — there's no per-turn tool selection/routing step deciding what the model is allowed to see. If you want the model to be able to call something, put it in `tools` (or bundle it inside a `Skill`). See [Tools](./tools.md) and [Skills](./skills.md).
49
+
50
+ ## Recovering an agent's state
51
+
52
+ `getCurrentAgentStates()` returns a plain JSON-serializable snapshot: message history (each message carrying its own token usage) and running memory summary. Persist it anywhere; pass it back in as `initData` to resume the exact same agent later (after a process restart, in a new request handler, etc.):
53
+
54
+ ```ts
55
+ import { writeFileSync, existsSync, readFileSync } from "fs";
56
+
57
+ const initData = existsSync("./state.json")
58
+ ? JSON.parse(readFileSync("./state.json", "utf-8"))
59
+ : undefined;
60
+
61
+ const agent = new SimpleAgent({
62
+ aiProvider: provider,
63
+ instruction: "You are a helpful assistant.",
64
+ tools: [GetCurrentTimeTool()],
65
+ ...(initData ? { initData } : {}),
66
+ });
67
+
68
+ // after any run() call:
69
+ writeFileSync("./state.json", JSON.stringify(agent.getCurrentAgentStates()));
70
+ ```
71
+
72
+ Messages are only ever appended, never rewritten. When the conversation grows past the memory threshold, OrbitX retires the working context into `retiredMessages` and resets the model's *active* context (`messagesCompact`) from a running summary (`compactMemory`), so an agent can keep going indefinitely without losing the ability to act on what happened earlier — nothing on disk is ever deleted, it just moves from one array to the other. Mechanics are covered in [Agents](./agents.md#memory-compaction).
73
+
74
+ ## Next steps
75
+
76
+ - Full control over the MCP transport (custom server/client, IPC, WebSocket, sandboxed Docker execution): [MCP Architecture](./mcp-architecture.md).
77
+ - Writing your own tool or skill: [Tools](./tools.md#writing-a-custom-tool), [Skills](./skills.md#writing-a-custom-skill).
78
+ - Every public export: [API Reference](./api-reference.md).
package/docs/index.md CHANGED
@@ -1,23 +1,24 @@
1
- # OrbitX Docs
2
-
3
- OrbitX is a TypeScript SDK for building AI agents: pluggable model providers, a tool/skill system, an MCP-based execution layer (in-process, IPC, or WebSocket), and a resumable agent loop with automatic memory compaction.
4
-
5
- This directory is written for two audiences at once:
6
-
7
- - **Humans** learning the library for the first time — read top to bottom.
8
- - **AI coding agents** working inside a project that depends on `orbitx` — each page is self-contained enough to be read on its own when you only need one topic (e.g. "how do I define a tool").
9
-
10
- ## Pages
11
-
12
- 1. [Getting Started](./getting-started.md) — install, first agent, streaming output, resuming state.
13
- 2. [Providers](./providers.md) — `AIProvider`, the four built-in providers, capabilities, main/image roles.
14
- 3. [Agents](./agents.md) — `BaseAgent` vs `SimpleAgent`, the run loop, memory compaction, tokens, and multi-agent (`WorkerAgent`/`AgentTools`).
15
- 4. [Tools](./tools.md) — the `MCPTool` shape, built-in tool catalog, writing your own tools.
16
- 5. [Skills](./skills.md) — bundling instructions + tools, built-in skill catalog, writing your own.
17
- 6. [MCP Architecture](./mcp-architecture.md) — `MCPServer`/`MCPClient`/connections, in-process vs IPC vs WS, `MCPComputer` sandbox.
18
- 7. [Streaming](./streaming.md) — the `StreamCallback` chunk shape and how to consume it.
19
- 8. [API Reference](./api-reference.md) — flat index of every public export from `orbitx`.
20
-
21
- ## The shape of the library, in one paragraph
22
-
23
- You construct one or more `AIProvider` instances (OpenAI, Anthropic, DeepSeek, or Ollama), a list of `MCPTool`s and/or `Skill`s (a skill is just instructions + tools bundled together), and hand them to `SimpleAgent` (or `BaseAgent` for full control over the underlying MCP transport). Calling `agent.run(prompt, streamCallback)` drives a loop: send the conversation + tool schemas to the provider, dispatch any tool calls the model requests, feed results back, repeat until the model stops calling tools. Everything the model can see (tools, skills, instructions) is decided once, up front — there's no dynamic tool routing/selection step. Long conversations are handled by summarizing into a running `memory` string instead of ever deleting messages; the full history is preserved in `getCurrentAgentStates()` for persistence/resume.
1
+ # OrbitX Docs
2
+
3
+ OrbitX is a TypeScript SDK for building AI agents: pluggable model providers, a tool/skill system, an MCP-based execution layer (in-process, IPC, or WebSocket), and a resumable agent loop with automatic memory compaction.
4
+
5
+ This directory is written for two audiences at once:
6
+
7
+ - **Humans** learning the library for the first time — read top to bottom.
8
+ - **AI coding agents** working inside a project that depends on `orbitx` — each page is self-contained enough to be read on its own when you only need one topic (e.g. "how do I define a tool").
9
+
10
+ ## Pages
11
+
12
+ 1. [Getting Started](./getting-started.md) — install, first agent, streaming output, resuming state.
13
+ 2. [Providers](./providers.md) — `AIProvider`, the four built-in providers, capabilities, main/image roles.
14
+ 3. [Agents](./agents.md) — `BaseAgent` vs `SimpleAgent`, the run loop, memory compaction, tokens.
15
+ 4. [Swarm](./swarm.md) — many agents that hire, task, and report to each other: `SwarmBase`, `AgentDefinition`, `getAgentTools()`.
16
+ 5. [Tools](./tools.md) — the `MCPTool` shape, built-in tool catalog, writing your own tools.
17
+ 6. [Skills](./skills.md) — bundling instructions + tools, built-in skill catalog, writing your own.
18
+ 7. [MCP Architecture](./mcp-architecture.md) — `MCPServer`/`MCPClient`/connections, in-process vs IPC vs WS, `MCPComputer` sandbox.
19
+ 8. [Streaming](./streaming.md) — the `StreamCallback` chunk shape and how to consume it.
20
+ 9. [API Reference](./api-reference.md) — flat index of every public export from `orbitx`.
21
+
22
+ ## The shape of the library, in one paragraph
23
+
24
+ You construct one or more `AIProvider` instances (OpenAI, Anthropic, DeepSeek, or Ollama), a list of `MCPTool`s and/or `Skill`s (a skill is just instructions + tools bundled together), and hand them to `SimpleAgent` (or `BaseAgent` for full control over the underlying MCP transport). Calling `agent.run(prompt, streamCallback)` drives a loop: send the conversation + tool schemas to the provider, dispatch any tool calls the model requests, feed results back, repeat until the model stops calling tools. Everything the model can see (tools, skills, instructions) is decided once, up front — there's no dynamic tool routing/selection step. Long conversations are handled by summarizing into a running `memory` string instead of ever deleting messages; the full history is preserved in `getCurrentAgentStates()` for persistence/resume.
@@ -30,7 +30,7 @@ mcpClient.callTool(name: string, inputs: Record<string, any>, toolCallId?: strin
30
30
  mcpClient.setExecuteProviderHandler(handler: (toolCallId: string, type: ProviderType, input: Record<string, any>) => Promise<{ output: Record<string, any> }>): void;
31
31
  ```
32
32
 
33
- `toolCallId` on `callTool()` and the handler installed via `setExecuteProviderHandler()` are what `BaseAgent` wires up automatically so `mcp.executeProvider(...)` works inside a tool's `execute()` — see [Custom `MCP` subclasses](#custom-mcp-subclasses) below. You don't need to call either yourself unless you're driving `MCPClient` outside of `BaseAgent`.
33
+ `toolCallId` on `callTool()` and the handler installed via `setExecuteProviderHandler()` are what `BaseAgent` wires up automatically so `mcp.executeProvider(...)` works inside a tool's `execute()` — see [Custom `MCP` subclasses](#custom-mcp-subclasses) below. You don't need to call either yourself unless you're driving `MCPClient` outside of `BaseAgent`. A `SwarmBase` takes that handler back after building each agent, so in a swarm the provider call is answered by the swarm — see [Swarm](./swarm.md#providers-a-tool-reaches-for).
34
34
 
35
35
  This is what you pass into `BaseAgent({ mcpClient, ... })`. `envID` scopes storage/RNG state per logical environment/session — pass a stable id (e.g. a user or conversation id) if you want isolated tool state per agent instance sharing a server. Accepting an array of connections lets one client fan out across multiple servers.
36
36
 
@@ -82,12 +82,35 @@ const connection = computer.getConnection();
82
82
  await computer.stop();
83
83
  ```
84
84
 
85
- - `mountPath` — host directory mounted into the container (this is what filesystem tools inside the sandbox actually touch).
86
- - `ports` — ports to expose from the container, or `"*"` for host network mode (Linux only, or Windows via WSL2).
87
- - `getConnection()` — returns a ready `MCPConnection`: IPC on Linux/macOS, WebSocket on Windows (auth token generated automatically).
88
- - `stop()` — kills the container.
85
+ ```ts
86
+ new MCPComputer(mountPath: string, ports: number[] | "*", image?: string, options?: MCPComputerOptions);
87
+ ```
88
+
89
+ - `mountPath` — host directory mounted into the container (this is what filesystem tools inside the sandbox actually touch). Four subdirectories are created under it and mounted: `workspace`, `mcp-server-storage`, `presents`, `user-inputs`.
90
+ - `ports` — ports to publish from the container, or `"*"` for host network mode. **`"*"` is Linux-only**: on Windows and macOS the container joins a VM's network namespace, so nothing it binds is reachable from your machine and published ports are ignored — the constructor throws rather than letting that surface later as a connection timeout.
91
+ - `image` — defaults to `aliafsordeh/orbitx-sandbox:0.2`.
92
+ - `start()` — verifies the Docker daemon is reachable, prepares the mount, launches the container, waits for its ready log, and then waits for the connection endpoint to actually accept traffic. It resolves only when the sandbox is genuinely reachable, and rejects with the container's own output when it is not.
93
+ - `getConnection(wsHost?)` — returns a ready `MCPConnection`, cached (repeated calls hand back the same object). In `"ws"` mode it must be called after `start()`, since the port is only chosen there.
94
+ - `waitUntilConnected(timeoutMs?)` — optional; resolves once the transport is carrying traffic, if you want the MCP handshake up before the first tool call.
95
+ - `getPresentsHostPath()`, `getConnectionPort()`, `getContainerName()`, `isRunning()` — host-side accessors.
96
+ - `stop()` — removes the container, closes the connection, and cleans up the socket directory. Idempotent.
97
+
98
+ `MCPComputerOptions`:
99
+
100
+ | Option | Default | Purpose |
101
+ | --- | --- | --- |
102
+ | `connectionMode` | `"ipc"` on Linux, `"ws"` elsewhere | Transport between your process and the sandbox. |
103
+ | `readyTimeoutMs` | `60_000` | Wait for the sandbox's ready log once the container is running. |
104
+ | `pullTimeoutMs` | `300_000` | Inactivity budget while docker pulls the image, so a first run isn't killed mid-download. |
105
+ | `handshakeTimeoutMs` | `20_000` | Wait for the endpoint to accept traffic after the ready log. |
106
+ | `onLog` | — | `(line, "stdout" \| "stderr") => void`; receives everything the container writes. |
107
+ | `dockerBin` | `"docker"` | Override the executable (e.g. `"podman"`, or an absolute path). |
108
+
109
+ The transport default is not a style choice: Docker Desktop on Windows and macOS runs the daemon inside a VM and shares the mount over a network filesystem, which cannot carry a unix-domain socket. IPC therefore only works when the daemon and your process share a kernel, and WebSocket (loopback-published, with an auto-generated auth token) is used everywhere else.
89
110
 
90
- Requires the `aliafsordeh/orbitx-sandbox:0.1` image (pull it, or build it yourself from the `Dockerfile.sandbox` at the repo root).
111
+ Requires the `aliafsordeh/orbitx-sandbox:0.2` image (pull it, or build it yourself from the `Dockerfile.sandbox` at the repo root). Note that the sandbox's own stdout/stderr are drained continuously for the life of the container — a piped-but-unread stream fills its OS buffer after ~64KB and blocks the sandbox process on its next write, which surfaces much later as tool calls that never return.
112
+
113
+ Servers started *inside* the sandbox must bind `0.0.0.0`, not `localhost`, to be reachable through a published port; `getInstructions()` tells agents this.
91
114
 
92
115
  ## Storage and RNG
93
116
 
@@ -135,6 +158,48 @@ class AllowlistPolicy extends MCPExecutionPolicy {
135
158
  const mcpClient = new MCPClient(envID, connection, storage, rng, undefined, new AllowlistPolicy(["get_current_time"]));
136
159
  ```
137
160
 
161
+ ### `MCPAutoExecutionPolicy` — an AI-judged policy
162
+
163
+ `MCPAutoExecutionPolicy` (`src/core/mcp-auto-execution-policy.ts`) is a built-in `MCPExecutionPolicy` that asks a model, via [`AIASK`](./agents.md#aiask), whether each call is safe — an alternative to a hand-written allowlist/denylist for cases where "safe" isn't a fixed rule. It's built to keep the expensive part (an actual model call) as rare as possible rather than reviewing every single tool call:
164
+
165
+ ```ts
166
+ new MCPAutoExecutionPolicy({
167
+ aiModel: AIProvider | AgentProviderEntry[];
168
+ instruction?: string; // extra context appended after the built-in default instruction — e.g. what the user actually asked the agent to do
169
+ onVerdict?: (request: MCPToolCallRequest, verdict: { harmful: boolean; reason: string }) => void;
170
+ watchedTools?: string[]; // default: ["bash-run", "fs-write-file", "fs-edit-file", "fs-delete", "fs-move"]
171
+ scopeDir?: string; // default: process.cwd() at construction time
172
+ });
173
+ ```
174
+
175
+ Three cost-cutting layers, checked in order inside `authorize(request)`:
176
+
177
+ 1. **Not in `watchedTools`?** Authorized immediately — no model call, no verdict recorded at all. Most tools (`get-current-time`, `todo-*`, `fs-read-file`, ...) have nothing dangerous to weigh, so the default watch list is only the destructive/execution tools: `bash-run` and the fs tools that write, edit, delete, or move something. Pass your own `watchedTools` to widen or narrow that set.
178
+ 2. **A watched *fs* call whose path(s) all resolve inside `scopeDir`?** Also authorized immediately, no model call — a write/edit/delete confined to the expected working directory doesn't need judgment. Paths are resolved the same way the fs tools themselves resolve them (relative to `process.cwd()`); `fs-move` needs *both* `from` and `to` inside scope to skip the model — one path escaping scope is enough to escalate. `bash-run` has no path field to check here, so it always falls through to the model.
179
+ 3. **Otherwise, ask the model** — via `AIASK`, on `{ toolName, inputs }`. `authorize()` denies whenever the verdict comes back `harmful: true`, or whenever `AIASK` itself couldn't reach a valid verdict after its own retries (fails closed, not open).
180
+
181
+ Whenever a call *does* reach the model, file content is stripped out first — `fs-write-file`/`fs-edit-file`'s `content` field is replaced with `<omitted, N bytes>` before it's ever sent, since the file's contents aren't relevant to judging whether the *call* is safe, and including it would make every write/edit review needlessly expensive. The model judges those calls by path and other inputs alone.
182
+
183
+ `authorize()`'s boolean return only tells `MCPClient` whether to proceed — it doesn't surface *why* a call was judged (or skipped as) harmful/safe, which callers usually want (to log it, or show the user what got blocked). Three ways to get that — all populated for both a model-reviewed call and one that was authorized locally via the path-scope check, but never for a call outside `watchedTools`, which is never reviewed at all:
184
+
185
+ - `policy.getVerdict(toolCallId)` — the verdict recorded for one specific call, if it carried a `toolCallId`.
186
+ - `policy.getLastVerdict()` — the most recent verdict of any reviewed call, useful when only one policy instance is ever in flight at a time.
187
+ - `onVerdict` — called synchronously right after every reviewed `authorize()` decision, with both the request and the verdict.
188
+
189
+ ```ts
190
+ const policy = new MCPAutoExecutionPolicy({
191
+ aiModel,
192
+ scopeDir: "/home/me/project", // writes/edits/deletes/moves confined here skip the model entirely
193
+ onVerdict: (request, verdict) => {
194
+ if (verdict.harmful) console.warn(`blocked ${request.toolName}: ${verdict.reason}`);
195
+ },
196
+ });
197
+
198
+ const mcpClient = new MCPClient(envID, connection, storage, rng, undefined, policy);
199
+ ```
200
+
201
+ Even with those shortcuts, a call that does reach the model costs at least one real call (more if `AIASK`'s own retry loop kicks in — see [`AIASK`](./agents.md#aiask)) — this still trades latency/cost for judgment a fixed rule can't express, just as rarely as the watch list and scope check allow. Reach for a plain `MCPExecutionPolicy` subclass first when a simple allowlist/denylist actually covers the case.
202
+
138
203
  ## Custom `MCP` subclasses
139
204
 
140
205
  Both `MCPServer` and `MCPClient` extend the abstract `MCP` class — `getStorage()`, `getRNG()`, and `executeProvider(toolCallId, type, input)`. Tool `execute` functions receive the calling `MCP` instance directly, as their 4th argument (after a `toolCallId` — see [Tools](./tools.md#the-mcptool-shape)), so a tool can reach storage/RNG scoped to whichever client dispatched the call.