orbitx 0.2.9 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +478 -456
- package/dist/agents/backend.d.ts +4 -0
- package/dist/agents/backend.d.ts.map +1 -0
- package/dist/agents/backend.js +54 -0
- package/dist/agents/backend.js.map +1 -0
- package/dist/agents/frontend.d.ts +4 -0
- package/dist/agents/frontend.d.ts.map +1 -0
- package/dist/agents/frontend.js +50 -0
- package/dist/agents/frontend.js.map +1 -0
- package/dist/agents/index.d.ts +10 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +22 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/planner.d.ts +4 -0
- package/dist/agents/planner.d.ts.map +1 -0
- package/dist/agents/planner.js +86 -0
- package/dist/agents/planner.js.map +1 -0
- package/dist/agents/protocol.d.ts +5 -0
- package/dist/agents/protocol.d.ts.map +1 -0
- package/dist/agents/protocol.js +70 -0
- package/dist/agents/protocol.js.map +1 -0
- package/dist/agents/reasoner.d.ts +5 -0
- package/dist/agents/reasoner.d.ts.map +1 -0
- package/dist/agents/reasoner.js +96 -0
- package/dist/agents/reasoner.js.map +1 -0
- package/dist/agents/research.d.ts +4 -0
- package/dist/agents/research.d.ts.map +1 -0
- package/dist/agents/research.js +28 -0
- package/dist/agents/research.js.map +1 -0
- package/dist/agents/tester.d.ts +4 -0
- package/dist/agents/tester.d.ts.map +1 -0
- package/dist/agents/tester.js +70 -0
- package/dist/agents/tester.js.map +1 -0
- package/dist/core/agent-definition.d.ts +61 -0
- package/dist/core/agent-definition.d.ts.map +1 -0
- package/dist/core/agent-definition.js +82 -0
- package/dist/core/agent-definition.js.map +1 -0
- package/dist/core/ai-provider.d.ts +3 -0
- package/dist/core/ai-provider.d.ts.map +1 -1
- package/dist/core/ai-provider.js.map +1 -1
- package/dist/core/anthropic-provider.d.ts +1 -0
- package/dist/core/anthropic-provider.d.ts.map +1 -1
- package/dist/core/anthropic-provider.js +3 -0
- package/dist/core/anthropic-provider.js.map +1 -1
- package/dist/core/base-agent.d.ts +51 -28
- package/dist/core/base-agent.d.ts.map +1 -1
- package/dist/core/base-agent.js +118 -26
- package/dist/core/base-agent.js.map +1 -1
- package/dist/core/deepseek-provider.d.ts +1 -0
- package/dist/core/deepseek-provider.d.ts.map +1 -1
- package/dist/core/deepseek-provider.js +3 -0
- package/dist/core/deepseek-provider.js.map +1 -1
- package/dist/core/mcp-computer.d.ts +14 -1
- package/dist/core/mcp-computer.d.ts.map +1 -1
- package/dist/core/mcp-computer.js +352 -71
- package/dist/core/mcp-computer.js.map +1 -1
- package/dist/core/ollama-provider.d.ts +1 -0
- package/dist/core/ollama-provider.d.ts.map +1 -1
- package/dist/core/ollama-provider.js +3 -0
- package/dist/core/ollama-provider.js.map +1 -1
- package/dist/core/openai-provider.d.ts +1 -0
- package/dist/core/openai-provider.d.ts.map +1 -1
- package/dist/core/openai-provider.js +3 -0
- package/dist/core/openai-provider.js.map +1 -1
- package/dist/core/swarm-base.d.ts +88 -0
- package/dist/core/swarm-base.d.ts.map +1 -0
- package/dist/core/swarm-base.js +427 -0
- package/dist/core/swarm-base.js.map +1 -0
- package/dist/index.d.ts +7 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/tests/agents/default-agents.test.d.ts +2 -0
- package/dist/tests/agents/default-agents.test.d.ts.map +1 -0
- package/dist/tests/agents/default-agents.test.js +106 -0
- package/dist/tests/agents/default-agents.test.js.map +1 -0
- package/dist/tests/core/agent-definition.test.d.ts +2 -0
- package/dist/tests/core/agent-definition.test.d.ts.map +1 -0
- package/dist/tests/core/agent-definition.test.js +99 -0
- package/dist/tests/core/agent-definition.test.js.map +1 -0
- package/dist/tests/core/scripted-provider.d.ts +38 -0
- package/dist/tests/core/scripted-provider.d.ts.map +1 -0
- package/dist/tests/core/scripted-provider.js +85 -0
- package/dist/tests/core/scripted-provider.js.map +1 -0
- package/dist/tests/core/swarm-base.test.d.ts +2 -0
- package/dist/tests/core/swarm-base.test.d.ts.map +1 -0
- package/dist/tests/core/swarm-base.test.js +387 -0
- package/dist/tests/core/swarm-base.test.js.map +1 -0
- package/dist/tests/index.d.ts +3 -0
- package/dist/tests/index.d.ts.map +1 -1
- package/dist/tests/index.js +3 -0
- package/dist/tests/index.js.map +1 -1
- package/dist/tests/tools/agent/agent-tools.test.js +225 -153
- package/dist/tests/tools/agent/agent-tools.test.js.map +1 -1
- package/dist/tools/agent/active.d.ts +5 -0
- package/dist/tools/agent/active.d.ts.map +1 -0
- package/dist/tools/agent/active.js +40 -0
- package/dist/tools/agent/active.js.map +1 -0
- package/dist/tools/agent/fire.d.ts +5 -0
- package/dist/tools/agent/fire.d.ts.map +1 -0
- package/dist/tools/agent/fire.js +38 -0
- package/dist/tools/agent/fire.js.map +1 -0
- package/dist/tools/agent/hire.d.ts +2 -2
- package/dist/tools/agent/hire.d.ts.map +1 -1
- package/dist/tools/agent/hire.js +43 -10
- package/dist/tools/agent/hire.js.map +1 -1
- package/dist/tools/agent/index.d.ts +22 -19
- package/dist/tools/agent/index.d.ts.map +1 -1
- package/dist/tools/agent/index.js +29 -21
- package/dist/tools/agent/index.js.map +1 -1
- package/dist/tools/agent/prompt.d.ts +2 -2
- package/dist/tools/agent/prompt.d.ts.map +1 -1
- package/dist/tools/agent/prompt.js +19 -53
- package/dist/tools/agent/prompt.js.map +1 -1
- package/dist/tools/agent/registry.d.ts +74 -24
- package/dist/tools/agent/registry.d.ts.map +1 -1
- package/dist/tools/agent/registry.js +93 -48
- package/dist/tools/agent/registry.js.map +1 -1
- package/dist/tools/agent/report-group.d.ts +5 -0
- package/dist/tools/agent/report-group.d.ts.map +1 -0
- package/dist/tools/agent/report-group.js +50 -0
- package/dist/tools/agent/report-group.js.map +1 -0
- package/dist/tools/agent/report-parent.d.ts +5 -0
- package/dist/tools/agent/report-parent.d.ts.map +1 -0
- package/dist/tools/agent/report-parent.js +36 -0
- package/dist/tools/agent/report-parent.js.map +1 -0
- package/dist/tools/agent/types.d.ts +5 -0
- package/dist/tools/agent/types.d.ts.map +1 -0
- package/dist/tools/agent/types.js +17 -0
- package/dist/tools/agent/types.js.map +1 -0
- package/docs/agents.md +173 -228
- package/docs/api-reference.md +9 -4
- package/docs/getting-started.md +78 -78
- package/docs/index.md +24 -23
- package/docs/mcp-architecture.md +29 -6
- package/docs/providers.md +258 -254
- package/docs/skills.md +0 -1
- package/docs/streaming.md +133 -133
- package/docs/swarm.md +503 -0
- package/docs/tools.md +214 -212
- package/package.json +1 -1
package/Readme.md
CHANGED
|
@@ -1,457 +1,479 @@
|
|
|
1
|
-
[](#)
|
|
2
|
-
|
|
3
|
-
📖 **[Full documentation](./docs/index.md)** — a deeper, page-by-page guide (providers, agents, tools, skills, MCP transport, streaming, full API reference), written to be useful both to humans learning the library and to AI agents coding against it.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install orbitx
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Demo
|
|
12
|
-
|
|
13
|
-
<table>
|
|
14
|
-
<tr>
|
|
15
|
-
<td align="center">
|
|
16
|
-
<a href="https://www.youtube.com/watch?v=nuIhIBdBjTI">
|
|
17
|
-
<img src="https://img.youtube.com/vi/nuIhIBdBjTI/maxresdefault.jpg" width="400" alt="Demo 1">
|
|
18
|
-
</a>
|
|
19
|
-
<br>
|
|
20
|
-
<b>Demo 1</b>
|
|
21
|
-
</td>
|
|
22
|
-
<td align="center">
|
|
23
|
-
<a href="https://www.youtube.com/watch?v=Go1PIYo0sFw">
|
|
24
|
-
<img src="https://img.youtube.com/vi/Go1PIYo0sFw/maxresdefault.jpg" width="400" alt="Demo 2">
|
|
25
|
-
</a>
|
|
26
|
-
<br>
|
|
27
|
-
<b>Demo 2</b>
|
|
28
|
-
</td>
|
|
29
|
-
</tr>
|
|
30
|
-
</table>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
## Quick Start
|
|
34
|
-
|
|
35
|
-
The fastest way to get an agent running is `SimpleAgent` — give it a provider, an instruction, and a list of tools/skills.
|
|
36
|
-
|
|
37
|
-
```ts
|
|
38
|
-
import { OllamaProvider, SimpleAgent, GetCurrentTimeTool } from "orbitx";
|
|
39
|
-
|
|
40
|
-
const ollamaProvider = new OllamaProvider("gemma4:e4b");
|
|
41
|
-
|
|
42
|
-
const agent = new SimpleAgent({
|
|
43
|
-
aiProvider: ollamaProvider,
|
|
44
|
-
instruction: "You are a helpful assistant.",
|
|
45
|
-
tools: [GetCurrentTimeTool()],
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
let oldRole: "assistant" | "tool" | "user" | undefined;
|
|
49
|
-
|
|
50
|
-
agent.run("what is current time?", (chunk) => {
|
|
51
|
-
if (oldRole !== chunk.role) {
|
|
52
|
-
process.stdout.write(`\n${chunk.role}: `);
|
|
53
|
-
oldRole = chunk.role;
|
|
54
|
-
}
|
|
55
|
-
process.stdout.write(chunk.content);
|
|
56
|
-
|
|
57
|
-
if (chunk.done && chunk.role === "assistant" && chunk.toolCalls?.length) {
|
|
58
|
-
console.log(chunk.toolCalls);
|
|
59
|
-
}
|
|
60
|
-
if (chunk.role === "tool") {
|
|
61
|
-
console.log({ toolCallId: chunk.toolCallId, toolName: chunk.toolName });
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (chunk.done) {
|
|
65
|
-
process.stdout.write("\n\n");
|
|
66
|
-
oldRole = undefined;
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
All tools and skills passed in are baked into the system prompt once, up front — there's no separate routing/selection step deciding what the model can see turn to turn.
|
|
72
|
-
|
|
73
|
-
### Recovering an agent's state
|
|
74
|
-
|
|
75
|
-
`getCurrentAgentStates()` returns a plain JSON-serializable snapshot (messages, memory, token counters). Save it wherever you like, and pass it back in as `initData` to resume the exact same agent later — a process restart, a saved session, etc.
|
|
76
|
-
|
|
77
|
-
```ts
|
|
78
|
-
import { writeFileSync, existsSync, readFileSync } from "fs";
|
|
79
|
-
|
|
80
|
-
const initData = existsSync("./state.json")
|
|
81
|
-
? JSON.parse(readFileSync("./state.json", "utf-8"))
|
|
82
|
-
: undefined;
|
|
83
|
-
|
|
84
|
-
const agent = new SimpleAgent({
|
|
85
|
-
aiProvider: ollamaProvider,
|
|
86
|
-
instruction: "You are a helpful assistant.",
|
|
87
|
-
tools: [GetCurrentTimeTool()],
|
|
88
|
-
...(initData ? { initData } : {}),
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// after any run() call:
|
|
92
|
-
writeFileSync("./state.json", JSON.stringify(agent.getCurrentAgentStates()));
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
Old messages are never rewritten once written — the agent only ever appends. When the conversation grows past its memory limit, OrbitX keeps the full history intact on disk (`messagesFull`) and instead resets the model's working context window from a running summary of what it already did, so it can keep going indefinitely without losing the ability to act on what happened earlier.
|
|
96
|
-
|
|
97
|
-
## Providers
|
|
98
|
-
|
|
99
|
-
OrbitX ships with pluggable AI providers so you can swap models without changing your agent logic.
|
|
100
|
-
|
|
101
|
-
### Ollama
|
|
102
|
-
|
|
103
|
-
```ts
|
|
104
|
-
import { OllamaProvider } from "orbitx";
|
|
105
|
-
|
|
106
|
-
const ollamaProvider = new OllamaProvider("gemma4:e4b");
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### DeepSeek
|
|
110
|
-
|
|
111
|
-
```ts
|
|
112
|
-
import { DeepSeekProvider } from "orbitx";
|
|
113
|
-
|
|
114
|
-
const deepseekProvider = new DeepSeekProvider("api-key", "deepseek-v4-flash");
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### Anthropic
|
|
118
|
-
|
|
119
|
-
```ts
|
|
120
|
-
import { AnthropicProvider } from "orbitx";
|
|
121
|
-
|
|
122
|
-
const anthropicProvider = new AnthropicProvider("api-key", "claude-sonnet-5");
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### OpenAI
|
|
126
|
-
|
|
127
|
-
```ts
|
|
128
|
-
import { OpenAIProvider } from "orbitx";
|
|
129
|
-
|
|
130
|
-
const openaiProvider = new OpenAIProvider("api-key", "gpt-5");
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### Think effort
|
|
134
|
-
|
|
135
|
-
Every provider accepts a universal `thinkEffort` option (`0`-`1`, e.g. `0.5` or `0.8`) instead of a provider-specific string — each provider maps it onto whatever scale it actually accepts (DeepSeek's `none/low/high/max`, OpenAI/Ollama's `low/medium/high`, Anthropic's numeric thinking budget), and it's silently ignored by providers/models that don't support thinking at all:
|
|
136
|
-
|
|
137
|
-
```ts
|
|
138
|
-
import { AnthropicProvider } from "orbitx";
|
|
139
|
-
|
|
140
|
-
const anthropicProvider = new AnthropicProvider("api-key", "claude-sonnet-5", { thinkEffort: 0.7 });
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
See the [docs](./docs/providers.md#think-effort) for the per-provider mapping and how thinking text streams (where supported).
|
|
144
|
-
|
|
145
|
-
### Two providers: main + image
|
|
146
|
-
|
|
147
|
-
An agent uses exactly two provider roles — `main` (drives the agent loop itself) and `image` (describes image tool output, e.g. screenshots, so the main conversation doesn't have to carry raw image bytes). Pass a single provider to use it for both roles, or an array to split them:
|
|
148
|
-
|
|
149
|
-
```ts
|
|
150
|
-
import { BaseAgent, DeepSeekProvider, OllamaProvider } from "orbitx";
|
|
151
|
-
|
|
152
|
-
const agent = new BaseAgent({
|
|
153
|
-
aiProvider: [
|
|
154
|
-
{ type: "main", aiProvider: new DeepSeekProvider("api-key", "deepseek-v4-flash") },
|
|
155
|
-
{ type: "image", aiProvider: new OllamaProvider("llava:latest") },
|
|
156
|
-
],
|
|
157
|
-
instruction: "You are a helpful assistant.",
|
|
158
|
-
mcpClient,
|
|
159
|
-
allowedTools: [/* ... */],
|
|
160
|
-
});
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
## Available Tools
|
|
164
|
-
|
|
165
|
-
Tools are grouped by domain. Import each group's array (e.g. `FsTools()`) to get every tool in that group at once, or import individual tools by name.
|
|
166
|
-
|
|
167
|
-
### Filesystem (`FsTools`)
|
|
168
|
-
|
|
169
|
-
⚠️ EXTREMELY IMPORTANT WARNING ABOUT `FsWriteFileTool` / `FsDeleteTool` ⚠️
|
|
170
|
-
|
|
171
|
-
🔴 CRITICAL: FsWriteFileTool and FsDeleteTool can permanently overwrite, delete, or corrupt existing files – no undo available.
|
|
172
|
-
|
|
173
|
-
We strongly prefer running bash commands through MCPComputer, which provides a sandboxed, isolated environment – protecting your host system from accidental damage.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
| Tool | Purpose |
|
|
177
|
-
|---|---|
|
|
178
|
-
| `FsReadFileTool` | Read a text file, paging through large files by line. |
|
|
179
|
-
| `FsWriteFileTool` | Write/overwrite a file's full content (creates parent dirs as needed). ⚠️ No undo. |
|
|
180
|
-
| `FsEditFileTool` | Replace a specific line range in an existing file without rewriting the whole thing. |
|
|
181
|
-
| `FsListDirTool` | List a directory's entries, paged by index for large directories. |
|
|
182
|
-
| `FsCreateDirTool` | Create a directory, including missing parents. |
|
|
183
|
-
| `FsDeleteTool` | Permanently delete a file or directory (recursive optional). ⚠️ No undo. |
|
|
184
|
-
| `FsMoveTool` | Move or rename a file or directory. |
|
|
185
|
-
| `FsStatTool` | Check whether a path exists and get its metadata (type, size, modified time). |
|
|
186
|
-
|
|
187
|
-
### Bash / processes (`BashTools`)
|
|
188
|
-
|
|
189
|
-
⚠️ EXTREMELY IMPORTANT WARNING ABOUT `BashRunTool` ⚠️
|
|
190
|
-
|
|
191
|
-
🔴 CRITICAL: Shell commands can permanently delete files, corrupt data, modify system settings, or execute harmful operations – no undo available.
|
|
192
|
-
|
|
193
|
-
We strongly prefer running bash commands through MCPComputer, which provides a sandboxed, isolated environment – protecting your host system from accidental damage.
|
|
194
|
-
|
|
195
|
-
| Tool | Purpose |
|
|
196
|
-
|---|---|
|
|
197
|
-
| `BashRunTool` | Launch a shell command as a background process; returns immediately if it's still running after `waitMs` (e.g. a dev server). |
|
|
198
|
-
| `BashWaitTool` | Wait again on a previously started process and get its latest status/output. |
|
|
199
|
-
| `BashLogsTool` | Read a process's combined stdout/stderr, paged by line. |
|
|
200
|
-
| `BashListTool` | List every process launched so far with its status. |
|
|
201
|
-
| `BashWriteInputTool` | Send text to a running process's stdin (answer an interactive prompt like `(y/n)`). |
|
|
202
|
-
| `BashTerminateTool` | Terminate a running process. |
|
|
203
|
-
|
|
204
|
-
### Browser (`BrowserTools`)
|
|
205
|
-
|
|
206
|
-
Drives a real headless browser session.
|
|
207
|
-
|
|
208
|
-
| Tool | Purpose |
|
|
209
|
-
|---|---|
|
|
210
|
-
| `BrowserCreateSessionTool` | Open a new headless browser session at a URL, returns its `sessionId`. |
|
|
211
|
-
| `BrowserRemoveSessionTool` | Close and remove a browser session. |
|
|
212
|
-
| `BrowserGetSessionsTool` | List all currently open session ids. |
|
|
213
|
-
| `BrowserNavigateTool` | Navigate an existing session to a new URL. |
|
|
214
|
-
| `BrowserReadTool` | Read the page as a text outline (headings, tables, links, forms), assigning ref ids to clickable/fillable elements. |
|
|
215
|
-
| `BrowserClickTool` | Click a `[CLICKABLE]` element by ref id. |
|
|
216
|
-
| `BrowserFillTool` | Type into a `[FILLABLE]` element by ref id; can submit via Enter if the field's form has no visible submit button. |
|
|
217
|
-
| `BrowserSubmitFormTool` | Submit a `[FORM]` ref directly — for forms with no visible submit button. |
|
|
218
|
-
| `BrowserScrollInfoTool` | Get total scrollable length and current scroll position. |
|
|
219
|
-
| `BrowserScrollTool` | Scroll to a given vertical pixel position. |
|
|
220
|
-
| `BrowserConsoleTool` | Read captured browser console log messages. |
|
|
221
|
-
| `BrowserNetworkTool` | Read captured network request/response activity. |
|
|
222
|
-
| `BrowserNetworkStatusTool` | Check whether the page currently has in-flight network activity (use before assuming a "no response yet" state means something broke). |
|
|
223
|
-
| `BrowserInjectTool` | Evaluate arbitrary JS in the page and return the result. |
|
|
224
|
-
| `BrowserScreenshotTool` | Capture a screenshot; can be described by the `image` provider instead of passed raw to the main model. |
|
|
225
|
-
|
|
226
|
-
### Todo lists (`TodoTools`)
|
|
227
|
-
|
|
228
|
-
| Tool | Purpose |
|
|
229
|
-
|---|---|
|
|
230
|
-
| `TodoCreateListTool` | Create a new todo list, returns its `todoListId`. |
|
|
231
|
-
| `TodoRemoveListTool` | Remove one or more todo lists (and their tasks). |
|
|
232
|
-
| `TodoGetListsTool` | Get all existing todo list ids. |
|
|
233
|
-
| `TodoGetListTool` | Get all tasks belonging to a list. |
|
|
234
|
-
| `TodoCreateTaskTool` | Create one or more tasks inside a list. |
|
|
235
|
-
| `TodoRemoveTaskTool` | Remove one or more tasks by id. |
|
|
236
|
-
| `TodoCheckTaskTool` | Set the checked/unchecked state of one or more tasks. |
|
|
237
|
-
|
|
238
|
-
### Present / deliverables (`PresentTools`)
|
|
239
|
-
|
|
240
|
-
| Tool | Purpose |
|
|
241
|
-
|---|---|
|
|
242
|
-
| `PresentAddTool` | Present a file to the user by copying it into the present folder (zip folders first — this only accepts single files). |
|
|
243
|
-
| `PresentClearTool` | Clear out every file currently presented. |
|
|
244
|
-
| `PresentGetListTool` | Get the list of files currently presented. |
|
|
245
|
-
|
|
246
|
-
### Utility (`UtilTools`)
|
|
247
|
-
|
|
248
|
-
| Tool | Purpose |
|
|
249
|
-
|---|---|
|
|
250
|
-
| `GetCurrentTimeTool` | Get the current date/time (ISO string, unix timestamp, timezone). |
|
|
251
|
-
| `DelayTool` | Wait a given number of milliseconds (max 60000ms) before continuing. |
|
|
252
|
-
|
|
253
|
-
###
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
|
275
|
-
|
|
276
|
-
| `
|
|
277
|
-
| `
|
|
278
|
-
| `
|
|
279
|
-
| `
|
|
280
|
-
| `
|
|
281
|
-
| `
|
|
282
|
-
| `
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
tools: [
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
```ts
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
1
|
+
[](#)
|
|
2
|
+
|
|
3
|
+
📖 **[Full documentation](./docs/index.md)** — a deeper, page-by-page guide (providers, agents, swarms, tools, skills, MCP transport, streaming, full API reference), written to be useful both to humans learning the library and to AI agents coding against it.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install orbitx
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Demo
|
|
12
|
+
|
|
13
|
+
<table>
|
|
14
|
+
<tr>
|
|
15
|
+
<td align="center">
|
|
16
|
+
<a href="https://www.youtube.com/watch?v=nuIhIBdBjTI">
|
|
17
|
+
<img src="https://img.youtube.com/vi/nuIhIBdBjTI/maxresdefault.jpg" width="400" alt="Demo 1">
|
|
18
|
+
</a>
|
|
19
|
+
<br>
|
|
20
|
+
<b>Demo 1</b>
|
|
21
|
+
</td>
|
|
22
|
+
<td align="center">
|
|
23
|
+
<a href="https://www.youtube.com/watch?v=Go1PIYo0sFw">
|
|
24
|
+
<img src="https://img.youtube.com/vi/Go1PIYo0sFw/maxresdefault.jpg" width="400" alt="Demo 2">
|
|
25
|
+
</a>
|
|
26
|
+
<br>
|
|
27
|
+
<b>Demo 2</b>
|
|
28
|
+
</td>
|
|
29
|
+
</tr>
|
|
30
|
+
</table>
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
The fastest way to get an agent running is `SimpleAgent` — give it a provider, an instruction, and a list of tools/skills.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { OllamaProvider, SimpleAgent, GetCurrentTimeTool } from "orbitx";
|
|
39
|
+
|
|
40
|
+
const ollamaProvider = new OllamaProvider("gemma4:e4b");
|
|
41
|
+
|
|
42
|
+
const agent = new SimpleAgent({
|
|
43
|
+
aiProvider: ollamaProvider,
|
|
44
|
+
instruction: "You are a helpful assistant.",
|
|
45
|
+
tools: [GetCurrentTimeTool()],
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
let oldRole: "assistant" | "tool" | "user" | undefined;
|
|
49
|
+
|
|
50
|
+
agent.run("what is current time?", (chunk) => {
|
|
51
|
+
if (oldRole !== chunk.role) {
|
|
52
|
+
process.stdout.write(`\n${chunk.role}: `);
|
|
53
|
+
oldRole = chunk.role;
|
|
54
|
+
}
|
|
55
|
+
process.stdout.write(chunk.content);
|
|
56
|
+
|
|
57
|
+
if (chunk.done && chunk.role === "assistant" && chunk.toolCalls?.length) {
|
|
58
|
+
console.log(chunk.toolCalls);
|
|
59
|
+
}
|
|
60
|
+
if (chunk.role === "tool") {
|
|
61
|
+
console.log({ toolCallId: chunk.toolCallId, toolName: chunk.toolName });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (chunk.done) {
|
|
65
|
+
process.stdout.write("\n\n");
|
|
66
|
+
oldRole = undefined;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
All tools and skills passed in are baked into the system prompt once, up front — there's no separate routing/selection step deciding what the model can see turn to turn.
|
|
72
|
+
|
|
73
|
+
### Recovering an agent's state
|
|
74
|
+
|
|
75
|
+
`getCurrentAgentStates()` returns a plain JSON-serializable snapshot (messages, memory, token counters). Save it wherever you like, and pass it back in as `initData` to resume the exact same agent later — a process restart, a saved session, etc.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { writeFileSync, existsSync, readFileSync } from "fs";
|
|
79
|
+
|
|
80
|
+
const initData = existsSync("./state.json")
|
|
81
|
+
? JSON.parse(readFileSync("./state.json", "utf-8"))
|
|
82
|
+
: undefined;
|
|
83
|
+
|
|
84
|
+
const agent = new SimpleAgent({
|
|
85
|
+
aiProvider: ollamaProvider,
|
|
86
|
+
instruction: "You are a helpful assistant.",
|
|
87
|
+
tools: [GetCurrentTimeTool()],
|
|
88
|
+
...(initData ? { initData } : {}),
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// after any run() call:
|
|
92
|
+
writeFileSync("./state.json", JSON.stringify(agent.getCurrentAgentStates()));
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Old messages are never rewritten once written — the agent only ever appends. When the conversation grows past its memory limit, OrbitX keeps the full history intact on disk (`messagesFull`) and instead resets the model's working context window from a running summary of what it already did, so it can keep going indefinitely without losing the ability to act on what happened earlier.
|
|
96
|
+
|
|
97
|
+
## Providers
|
|
98
|
+
|
|
99
|
+
OrbitX ships with pluggable AI providers so you can swap models without changing your agent logic.
|
|
100
|
+
|
|
101
|
+
### Ollama
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
import { OllamaProvider } from "orbitx";
|
|
105
|
+
|
|
106
|
+
const ollamaProvider = new OllamaProvider("gemma4:e4b");
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### DeepSeek
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { DeepSeekProvider } from "orbitx";
|
|
113
|
+
|
|
114
|
+
const deepseekProvider = new DeepSeekProvider("api-key", "deepseek-v4-flash");
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Anthropic
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
import { AnthropicProvider } from "orbitx";
|
|
121
|
+
|
|
122
|
+
const anthropicProvider = new AnthropicProvider("api-key", "claude-sonnet-5");
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### OpenAI
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import { OpenAIProvider } from "orbitx";
|
|
129
|
+
|
|
130
|
+
const openaiProvider = new OpenAIProvider("api-key", "gpt-5");
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Think effort
|
|
134
|
+
|
|
135
|
+
Every provider accepts a universal `thinkEffort` option (`0`-`1`, e.g. `0.5` or `0.8`) instead of a provider-specific string — each provider maps it onto whatever scale it actually accepts (DeepSeek's `none/low/high/max`, OpenAI/Ollama's `low/medium/high`, Anthropic's numeric thinking budget), and it's silently ignored by providers/models that don't support thinking at all:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import { AnthropicProvider } from "orbitx";
|
|
139
|
+
|
|
140
|
+
const anthropicProvider = new AnthropicProvider("api-key", "claude-sonnet-5", { thinkEffort: 0.7 });
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
See the [docs](./docs/providers.md#think-effort) for the per-provider mapping and how thinking text streams (where supported).
|
|
144
|
+
|
|
145
|
+
### Two providers: main + image
|
|
146
|
+
|
|
147
|
+
An agent uses exactly two provider roles — `main` (drives the agent loop itself) and `image` (describes image tool output, e.g. screenshots, so the main conversation doesn't have to carry raw image bytes). Pass a single provider to use it for both roles, or an array to split them:
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
import { BaseAgent, DeepSeekProvider, OllamaProvider } from "orbitx";
|
|
151
|
+
|
|
152
|
+
const agent = new BaseAgent({
|
|
153
|
+
aiProvider: [
|
|
154
|
+
{ type: "main", aiProvider: new DeepSeekProvider("api-key", "deepseek-v4-flash") },
|
|
155
|
+
{ type: "image", aiProvider: new OllamaProvider("llava:latest") },
|
|
156
|
+
],
|
|
157
|
+
instruction: "You are a helpful assistant.",
|
|
158
|
+
mcpClient,
|
|
159
|
+
allowedTools: [/* ... */],
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Available Tools
|
|
164
|
+
|
|
165
|
+
Tools are grouped by domain. Import each group's array (e.g. `FsTools()`) to get every tool in that group at once, or import individual tools by name.
|
|
166
|
+
|
|
167
|
+
### Filesystem (`FsTools`)
|
|
168
|
+
|
|
169
|
+
⚠️ EXTREMELY IMPORTANT WARNING ABOUT `FsWriteFileTool` / `FsDeleteTool` ⚠️
|
|
170
|
+
|
|
171
|
+
🔴 CRITICAL: FsWriteFileTool and FsDeleteTool can permanently overwrite, delete, or corrupt existing files – no undo available.
|
|
172
|
+
|
|
173
|
+
We strongly prefer running bash commands through MCPComputer, which provides a sandboxed, isolated environment – protecting your host system from accidental damage.
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
| Tool | Purpose |
|
|
177
|
+
|---|---|
|
|
178
|
+
| `FsReadFileTool` | Read a text file, paging through large files by line. |
|
|
179
|
+
| `FsWriteFileTool` | Write/overwrite a file's full content (creates parent dirs as needed). ⚠️ No undo. |
|
|
180
|
+
| `FsEditFileTool` | Replace a specific line range in an existing file without rewriting the whole thing. |
|
|
181
|
+
| `FsListDirTool` | List a directory's entries, paged by index for large directories. |
|
|
182
|
+
| `FsCreateDirTool` | Create a directory, including missing parents. |
|
|
183
|
+
| `FsDeleteTool` | Permanently delete a file or directory (recursive optional). ⚠️ No undo. |
|
|
184
|
+
| `FsMoveTool` | Move or rename a file or directory. |
|
|
185
|
+
| `FsStatTool` | Check whether a path exists and get its metadata (type, size, modified time). |
|
|
186
|
+
|
|
187
|
+
### Bash / processes (`BashTools`)
|
|
188
|
+
|
|
189
|
+
⚠️ EXTREMELY IMPORTANT WARNING ABOUT `BashRunTool` ⚠️
|
|
190
|
+
|
|
191
|
+
🔴 CRITICAL: Shell commands can permanently delete files, corrupt data, modify system settings, or execute harmful operations – no undo available.
|
|
192
|
+
|
|
193
|
+
We strongly prefer running bash commands through MCPComputer, which provides a sandboxed, isolated environment – protecting your host system from accidental damage.
|
|
194
|
+
|
|
195
|
+
| Tool | Purpose |
|
|
196
|
+
|---|---|
|
|
197
|
+
| `BashRunTool` | Launch a shell command as a background process; returns immediately if it's still running after `waitMs` (e.g. a dev server). |
|
|
198
|
+
| `BashWaitTool` | Wait again on a previously started process and get its latest status/output. |
|
|
199
|
+
| `BashLogsTool` | Read a process's combined stdout/stderr, paged by line. |
|
|
200
|
+
| `BashListTool` | List every process launched so far with its status. |
|
|
201
|
+
| `BashWriteInputTool` | Send text to a running process's stdin (answer an interactive prompt like `(y/n)`). |
|
|
202
|
+
| `BashTerminateTool` | Terminate a running process. |
|
|
203
|
+
|
|
204
|
+
### Browser (`BrowserTools`)
|
|
205
|
+
|
|
206
|
+
Drives a real headless browser session.
|
|
207
|
+
|
|
208
|
+
| Tool | Purpose |
|
|
209
|
+
|---|---|
|
|
210
|
+
| `BrowserCreateSessionTool` | Open a new headless browser session at a URL, returns its `sessionId`. |
|
|
211
|
+
| `BrowserRemoveSessionTool` | Close and remove a browser session. |
|
|
212
|
+
| `BrowserGetSessionsTool` | List all currently open session ids. |
|
|
213
|
+
| `BrowserNavigateTool` | Navigate an existing session to a new URL. |
|
|
214
|
+
| `BrowserReadTool` | Read the page as a text outline (headings, tables, links, forms), assigning ref ids to clickable/fillable elements. |
|
|
215
|
+
| `BrowserClickTool` | Click a `[CLICKABLE]` element by ref id. |
|
|
216
|
+
| `BrowserFillTool` | Type into a `[FILLABLE]` element by ref id; can submit via Enter if the field's form has no visible submit button. |
|
|
217
|
+
| `BrowserSubmitFormTool` | Submit a `[FORM]` ref directly — for forms with no visible submit button. |
|
|
218
|
+
| `BrowserScrollInfoTool` | Get total scrollable length and current scroll position. |
|
|
219
|
+
| `BrowserScrollTool` | Scroll to a given vertical pixel position. |
|
|
220
|
+
| `BrowserConsoleTool` | Read captured browser console log messages. |
|
|
221
|
+
| `BrowserNetworkTool` | Read captured network request/response activity. |
|
|
222
|
+
| `BrowserNetworkStatusTool` | Check whether the page currently has in-flight network activity (use before assuming a "no response yet" state means something broke). |
|
|
223
|
+
| `BrowserInjectTool` | Evaluate arbitrary JS in the page and return the result. |
|
|
224
|
+
| `BrowserScreenshotTool` | Capture a screenshot; can be described by the `image` provider instead of passed raw to the main model. |
|
|
225
|
+
|
|
226
|
+
### Todo lists (`TodoTools`)
|
|
227
|
+
|
|
228
|
+
| Tool | Purpose |
|
|
229
|
+
|---|---|
|
|
230
|
+
| `TodoCreateListTool` | Create a new todo list, returns its `todoListId`. |
|
|
231
|
+
| `TodoRemoveListTool` | Remove one or more todo lists (and their tasks). |
|
|
232
|
+
| `TodoGetListsTool` | Get all existing todo list ids. |
|
|
233
|
+
| `TodoGetListTool` | Get all tasks belonging to a list. |
|
|
234
|
+
| `TodoCreateTaskTool` | Create one or more tasks inside a list. |
|
|
235
|
+
| `TodoRemoveTaskTool` | Remove one or more tasks by id. |
|
|
236
|
+
| `TodoCheckTaskTool` | Set the checked/unchecked state of one or more tasks. |
|
|
237
|
+
|
|
238
|
+
### Present / deliverables (`PresentTools`)
|
|
239
|
+
|
|
240
|
+
| Tool | Purpose |
|
|
241
|
+
|---|---|
|
|
242
|
+
| `PresentAddTool` | Present a file to the user by copying it into the present folder (zip folders first — this only accepts single files). |
|
|
243
|
+
| `PresentClearTool` | Clear out every file currently presented. |
|
|
244
|
+
| `PresentGetListTool` | Get the list of files currently presented. |
|
|
245
|
+
|
|
246
|
+
### Utility (`UtilTools`)
|
|
247
|
+
|
|
248
|
+
| Tool | Purpose |
|
|
249
|
+
|---|---|
|
|
250
|
+
| `GetCurrentTimeTool` | Get the current date/time (ISO string, unix timestamp, timezone). |
|
|
251
|
+
| `DelayTool` | Wait a given number of milliseconds (max 60000ms) before continuing. |
|
|
252
|
+
|
|
253
|
+
### Swarm (`getAgentTools`)
|
|
254
|
+
|
|
255
|
+
The tools a group of agents uses to hire, task, and report to each other. Unlike the other domains this one returns a **handle**, not an array — `handle.tools` goes into your tool pool, and the handle itself goes into `SwarmBase`, because both sides share the state built with it (the shared hire pool, and which swarm the tools drive).
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
const agentTools = getAgentTools({ maxHired: 5 });
|
|
259
|
+
|
|
260
|
+
const swarm = new SwarmBase({
|
|
261
|
+
tools: [...FsTools(), ...BashTools(), ...UtilTools(), ...agentTools.tools],
|
|
262
|
+
agents: DefaultAgents(), // planner, reasoner, backend, frontend, tester, research
|
|
263
|
+
default: "planner",
|
|
264
|
+
agentTools,
|
|
265
|
+
aiProvider,
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
const done = await swarm.run("Build the checkout flow", chunk => {
|
|
269
|
+
process.stdout.write(`[${chunk.agentId}] ${chunk.content}`);
|
|
270
|
+
});
|
|
271
|
+
// true only once the planner AND every agent it hired are idle
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
| Tool | Purpose |
|
|
275
|
+
|---|---|
|
|
276
|
+
| `agent-types` | List the kinds of agent this swarm can hire — description, ratings, how many are working, slots left. |
|
|
277
|
+
| `agent-hire` | Spawn an agent of a type, optionally into a group and with a standing briefing. |
|
|
278
|
+
| `agent-fire` | Release one of your own hires and free its slot. |
|
|
279
|
+
| `agent-active` | List every hired agent — id, type, groups, parent, busy. |
|
|
280
|
+
| `agent-prompt` | Hand a task to one of your hires; returns immediately, the answer arrives later as a report. |
|
|
281
|
+
| `agent-report-parent` | Send a result to the agent that hired you, ending your turn. |
|
|
282
|
+
| `agent-report-group` | Message your group's other members; your parent never sees it. |
|
|
283
|
+
|
|
284
|
+
Which agent can do what is decided by its `allowedTools` — hiring tools for a planner, reporting tools for a worker — and agents themselves are written as reusable `AgentDefinition`s (the `Skill` idea, applied to agents) that you import rather than assemble.
|
|
285
|
+
|
|
286
|
+
`DefaultAgents()` ships a pipeline, not just a list: the planner hires a **reasoner** (five personas arguing for a measured five minutes before answering), then a **backend** agent that must publish an API contract, then a **tester** that verifies that contract against the running server *before* it reaches anyone, then one to three **frontend** agents in a shared group who agree on the scaffold and claim files between themselves so they never overwrite each other, and finally a **tester** on the whole flow. Point the shared `MCPClient` at an [`MCPComputer`](./docs/mcp-architecture.md#mcpcomputer-sandboxed-execution) and all of that happens inside a container instead of on your machine. Full walkthrough in the [docs](./docs/swarm.md).
|
|
287
|
+
|
|
288
|
+
## Available Skills
|
|
289
|
+
|
|
290
|
+
A `Skill` bundles instructions with the tools that go with them. Passing a skill into an agent adds its tools automatically and folds its instructions into the system prompt.
|
|
291
|
+
|
|
292
|
+
| Skill | Purpose |
|
|
293
|
+
|---|---|
|
|
294
|
+
| `PlannerSkill` | Stands up a persistent, checkable todo list for any large/multi-step/vague job so progress survives long conversations and context resets. |
|
|
295
|
+
| `BigTaskSkill` | Keeps the agent from stopping short on large or ambitious jobs — no declaring victory on a partial slice, no handing a big job back half-finished. |
|
|
296
|
+
| `LongTaskEfficiencySkill` | Keeps a long job efficient — batching, avoiding redundant reads, checkpointing, not gold-plating — without giving up on getting through the full scope. |
|
|
297
|
+
| `NodeBackendSkill` | Building, running, and debugging Node.js backends: APIs, servers, CLIs, workers, schedulers, DB access layers — new or existing. |
|
|
298
|
+
| `ReactFrontendSkill` | Building, running, and debugging modern React (`.tsx`/`.jsx`) projects, typically Vite-scaffolded — new or existing. |
|
|
299
|
+
| `UiUxDesignSkill` | Visual and interaction design quality for any user-facing UI — layout, hierarchy, feedback states, accessibility, responsiveness. |
|
|
300
|
+
| `BackendSecuritySkill` | Hardening server-side code that touches auth, sessions, tokens, uploads, DB queries, payments, or any trust boundary. |
|
|
301
|
+
| `CodeVerificationSkill` | Running the right type checker/build/lint/test suite before handing code back, and telling real bugs apart from sandbox artifacts. |
|
|
302
|
+
| `WebEndToEndTestSkill` | Testing a live web app like a real user would (fill, click, navigate) and verifying via the rendered page, console, and network — not by reading source and assuming. |
|
|
303
|
+
| `ResearchSkill` | Answering questions that need real, current information from the live web — opens pages, cross-checks multiple sources, never trusts one page. |
|
|
304
|
+
| `PresentSkill` | Deciding how to hand back a job's output as files (individually or zipped) and cleaning build artifacts out first. |
|
|
305
|
+
|
|
306
|
+
## Building from the Base Agent
|
|
307
|
+
|
|
308
|
+
For full control over the MCP server, connection, and client, compose an agent from the base primitives:
|
|
309
|
+
|
|
310
|
+
```ts
|
|
311
|
+
import {
|
|
312
|
+
OllamaProvider,
|
|
313
|
+
MCPConnection,
|
|
314
|
+
MCPServer,
|
|
315
|
+
MCPClient,
|
|
316
|
+
BaseAgent,
|
|
317
|
+
GetCurrentTimeTool,
|
|
318
|
+
} from "orbitx";
|
|
319
|
+
|
|
320
|
+
const ollamaProvider = new OllamaProvider("gemma4:e4b");
|
|
321
|
+
|
|
322
|
+
const connection = new MCPConnection();
|
|
323
|
+
|
|
324
|
+
const mcpServer = new MCPServer(connection);
|
|
325
|
+
mcpServer.registerTool(GetCurrentTimeTool());
|
|
326
|
+
|
|
327
|
+
const mcpClient = new MCPClient("DEFAULT_ENV", connection);
|
|
328
|
+
|
|
329
|
+
const agent = new BaseAgent({
|
|
330
|
+
aiProvider: ollamaProvider,
|
|
331
|
+
instruction: "",
|
|
332
|
+
mcpClient,
|
|
333
|
+
allowedTools: [GetCurrentTimeTool()],
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
let oldRole: "assistant" | "tool" | "user" | undefined;
|
|
337
|
+
|
|
338
|
+
agent.run("what is current time?", (chunk) => {
|
|
339
|
+
if (oldRole !== chunk.role) {
|
|
340
|
+
process.stdout.write(`\n${chunk.role}: `);
|
|
341
|
+
oldRole = chunk.role;
|
|
342
|
+
}
|
|
343
|
+
process.stdout.write(chunk.content);
|
|
344
|
+
if (chunk.done) {
|
|
345
|
+
process.stdout.write("\n\n");
|
|
346
|
+
oldRole = undefined;
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### IPC Connections
|
|
352
|
+
|
|
353
|
+
Run your MCP server as a separate process and connect to it over an inter-process communication (IPC) channel:
|
|
354
|
+
|
|
355
|
+
```ts
|
|
356
|
+
import os from "os";
|
|
357
|
+
import { MCPIPCConnection } from "orbitx";
|
|
358
|
+
|
|
359
|
+
const path =
|
|
360
|
+
os.platform() === "win32" ? `\\\\.\\pipe\\mcp_test` : `/tmp/mcp_test.sock`;
|
|
361
|
+
|
|
362
|
+
const ipcConnection = new MCPIPCConnection({ mode: "server", socketPath: path });
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### WS Connections
|
|
366
|
+
|
|
367
|
+
Run your MCP server as a separate process and connect to it over an web-socket communication (WS) channel:
|
|
368
|
+
|
|
369
|
+
```ts
|
|
370
|
+
import os from "os";
|
|
371
|
+
import { MCPWSConnection } from "orbitx";
|
|
372
|
+
|
|
373
|
+
const wsConnection = new MCPWSConnection({ mode: "server", host: "0.0.0.0", port: 9257, token: "1234" });
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
## Creating a Custom Tool
|
|
378
|
+
|
|
379
|
+
Define your own tools with `MCPTool` to extend an agent's capabilities and integrate with your own ecosystem.
|
|
380
|
+
|
|
381
|
+
```ts
|
|
382
|
+
import { MCPTool } from "orbitx";
|
|
383
|
+
|
|
384
|
+
export const SumTool = () => new MCPTool({
|
|
385
|
+
name: "math-sum",
|
|
386
|
+
description: "get two numbers and sum them",
|
|
387
|
+
inputs: [
|
|
388
|
+
{
|
|
389
|
+
name: "first",
|
|
390
|
+
type: "number",
|
|
391
|
+
description: "first number",
|
|
392
|
+
required: true,
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
name: "second",
|
|
396
|
+
type: "number",
|
|
397
|
+
description: "second number",
|
|
398
|
+
required: true,
|
|
399
|
+
},
|
|
400
|
+
],
|
|
401
|
+
execute: async (_envID: string, inputs: Record<string, any>) => {
|
|
402
|
+
const { first, second } = inputs;
|
|
403
|
+
|
|
404
|
+
if (typeof first !== "number") {
|
|
405
|
+
throw new Error("first must be a number");
|
|
406
|
+
}
|
|
407
|
+
if (typeof second !== "number") {
|
|
408
|
+
throw new Error("second must be a number");
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return { output: first + second };
|
|
412
|
+
},
|
|
413
|
+
});
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
Use it like any built-in tool:
|
|
417
|
+
|
|
418
|
+
```ts
|
|
419
|
+
const agent = new SimpleAgent({
|
|
420
|
+
aiProvider: ollamaProvider,
|
|
421
|
+
instruction: "You are a helpful assistant.",
|
|
422
|
+
tools: [SumTool()],
|
|
423
|
+
});
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
## Creating a Custom Skill
|
|
427
|
+
|
|
428
|
+
A `Skill` bundles instructions with the tools it needs, so an agent that includes it automatically gets both.
|
|
429
|
+
|
|
430
|
+
```ts
|
|
431
|
+
import { Skill, FsReadFileTool, FsWriteFileTool } from "orbitx";
|
|
432
|
+
import { SumTool } from "./sum-tool.js";
|
|
433
|
+
|
|
434
|
+
export const MathHelperSkill = () => new Skill({
|
|
435
|
+
name: "math-helper",
|
|
436
|
+
description:
|
|
437
|
+
"Use this skill whenever the user asks for arithmetic that should be computed exactly " +
|
|
438
|
+
"rather than estimated from the model's own reasoning — sums, running totals, or " +
|
|
439
|
+
"anything written to a file afterward.",
|
|
440
|
+
instructions: `
|
|
441
|
+
- Always use the math-sum tool for addition instead of computing it yourself.
|
|
442
|
+
- If asked to save a result, write it to disk with fs-write-file and confirm the path back to the user.
|
|
443
|
+
`,
|
|
444
|
+
tools: [
|
|
445
|
+
SumTool(),
|
|
446
|
+
FsReadFileTool(),
|
|
447
|
+
FsWriteFileTool(),
|
|
448
|
+
],
|
|
449
|
+
});
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
```ts
|
|
453
|
+
const agent = new SimpleAgent({
|
|
454
|
+
aiProvider: ollamaProvider,
|
|
455
|
+
instruction: "You are a helpful assistant.",
|
|
456
|
+
skills: [MathHelperSkill()],
|
|
457
|
+
});
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
## MCPComputer (Experimental Feature)
|
|
461
|
+
|
|
462
|
+
Spins up a sandboxed Docker container running the MCP server and returns a ready-to-use client connection — no need to manage IPC sockets, ports, or tokens manually.
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
import { MCPComputer } from "orbitx";
|
|
466
|
+
|
|
467
|
+
const computer = new MCPComputer("/path/to/mount", [3000, 8080]);
|
|
468
|
+
await computer.start();
|
|
469
|
+
|
|
470
|
+
const connection = computer.getConnection();
|
|
471
|
+
await computer.stop();
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
- **`mountPath`**: host directory mounted into the container
|
|
475
|
+
- **`ports`**: ports to expose, or `"*"` for host network mode (Linux only, or Windows via WSL2)
|
|
476
|
+
- **`getConnection()`**: returns a ready `MCPConnection` (IPC on Linux/macOS, WebSocket on Windows)
|
|
477
|
+
- **`stop()`**: kills the container
|
|
478
|
+
|
|
457
479
|
Requires the `aliafsordeh/orbitx-sandbox:0.1` image (pull it, or build from the `Dockerfile.sandbox` reference on our GitHub page).
|