openbot 0.2.12 → 0.2.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/.prettierrc +8 -0
  2. package/AGENTS.md +68 -0
  3. package/CONTRIBUTING.md +74 -0
  4. package/LICENSE +21 -0
  5. package/README.md +117 -14
  6. package/dist/agents/system.js +106 -0
  7. package/dist/app/cli.js +27 -0
  8. package/dist/app/config.js +64 -0
  9. package/dist/app/server.js +237 -0
  10. package/dist/app/utils.js +35 -0
  11. package/dist/harness/agent-harness.js +45 -0
  12. package/dist/harness/mcp.js +61 -0
  13. package/dist/harness/orchestrator.js +273 -0
  14. package/dist/harness/process.js +7 -0
  15. package/dist/plugins/ai-sdk.js +141 -0
  16. package/dist/plugins/delegation.js +52 -0
  17. package/dist/plugins/mcp.js +140 -0
  18. package/dist/plugins/storage.js +502 -0
  19. package/dist/plugins/ui.js +47 -0
  20. package/dist/registry/plugins.js +73 -0
  21. package/dist/services/storage.js +724 -0
  22. package/docs/README.md +7 -0
  23. package/docs/agents.md +83 -0
  24. package/docs/architecture.md +34 -0
  25. package/docs/plugins.md +77 -0
  26. package/logo-black.png +0 -0
  27. package/{dist/assets/logo.js → logo-black.svg} +24 -24
  28. package/{dist/ui/sidebar.js → logo-white.svg} +23 -88
  29. package/package.json +6 -5
  30. package/src/agents/system.ts +112 -0
  31. package/src/app/cli.ts +38 -0
  32. package/src/app/config.ts +104 -0
  33. package/src/app/server.ts +284 -0
  34. package/src/app/types.ts +476 -0
  35. package/src/app/utils.ts +43 -0
  36. package/src/assets/icon.svg +1 -0
  37. package/src/harness/agent-harness.ts +58 -0
  38. package/src/harness/mcp.ts +78 -0
  39. package/src/harness/orchestrator.ts +342 -0
  40. package/src/harness/process.ts +9 -0
  41. package/src/harness/types.ts +34 -0
  42. package/src/plugins/ai-sdk.ts +197 -0
  43. package/src/plugins/delegation.ts +60 -0
  44. package/src/plugins/mcp.ts +154 -0
  45. package/src/plugins/storage.ts +725 -0
  46. package/src/plugins/ui.ts +57 -0
  47. package/src/registry/plugins.ts +85 -0
  48. package/src/services/storage.ts +957 -0
  49. package/tsconfig.json +18 -0
  50. package/dist/agents/agent-creator.js +0 -74
  51. package/dist/agents/browser-agent.js +0 -31
  52. package/dist/agents/os-agent.js +0 -32
  53. package/dist/agents/planner-agent.js +0 -32
  54. package/dist/agents/topic-agent.js +0 -46
  55. package/dist/architecture/execution-engine.js +0 -151
  56. package/dist/architecture/intent-classifier.js +0 -26
  57. package/dist/architecture/planner.js +0 -106
  58. package/dist/automation-worker.js +0 -121
  59. package/dist/automations.js +0 -52
  60. package/dist/cli.js +0 -279
  61. package/dist/config.js +0 -53
  62. package/dist/core/agents.js +0 -41
  63. package/dist/core/delegation.js +0 -230
  64. package/dist/core/manager.js +0 -96
  65. package/dist/core/plugins.js +0 -74
  66. package/dist/core/router.js +0 -191
  67. package/dist/handlers/init.js +0 -29
  68. package/dist/handlers/session-change.js +0 -21
  69. package/dist/handlers/settings.js +0 -47
  70. package/dist/handlers/tab-change.js +0 -14
  71. package/dist/installers.js +0 -156
  72. package/dist/marketplace.js +0 -80
  73. package/dist/model-catalog.js +0 -132
  74. package/dist/model-defaults.js +0 -25
  75. package/dist/models.js +0 -47
  76. package/dist/open-bot.js +0 -51
  77. package/dist/orchestrator/direct-invocation.js +0 -13
  78. package/dist/orchestrator/events.js +0 -36
  79. package/dist/orchestrator/state.js +0 -54
  80. package/dist/orchestrator.js +0 -422
  81. package/dist/plugins/agent/index.js +0 -81
  82. package/dist/plugins/approval/index.js +0 -100
  83. package/dist/plugins/brain/identity.js +0 -77
  84. package/dist/plugins/brain/index.js +0 -204
  85. package/dist/plugins/brain/memory.js +0 -120
  86. package/dist/plugins/brain/prompt.js +0 -46
  87. package/dist/plugins/brain/types.js +0 -45
  88. package/dist/plugins/brain/ui.js +0 -7
  89. package/dist/plugins/browser/index.js +0 -629
  90. package/dist/plugins/browser/ui.js +0 -13
  91. package/dist/plugins/file-system/index.js +0 -171
  92. package/dist/plugins/file-system/ui.js +0 -6
  93. package/dist/plugins/llm/context-budget.js +0 -139
  94. package/dist/plugins/llm/context-shaping.js +0 -177
  95. package/dist/plugins/llm/index.js +0 -380
  96. package/dist/plugins/memory/index.js +0 -220
  97. package/dist/plugins/memory/memory.js +0 -122
  98. package/dist/plugins/memory/prompt.js +0 -55
  99. package/dist/plugins/memory/types.js +0 -45
  100. package/dist/plugins/meta-agent/index.js +0 -570
  101. package/dist/plugins/meta-agent/ui.js +0 -11
  102. package/dist/plugins/shell/index.js +0 -100
  103. package/dist/plugins/shell/ui.js +0 -6
  104. package/dist/plugins/skills/index.js +0 -286
  105. package/dist/plugins/skills/types.js +0 -50
  106. package/dist/plugins/skills/ui.js +0 -12
  107. package/dist/registry/agent-registry.js +0 -35
  108. package/dist/registry/index.js +0 -2
  109. package/dist/registry/plugin-loader.js +0 -499
  110. package/dist/registry/plugin-registry.js +0 -44
  111. package/dist/registry/ts-agent-loader.js +0 -82
  112. package/dist/registry/yaml-agent-loader.js +0 -246
  113. package/dist/runtime/execution-trace.js +0 -41
  114. package/dist/runtime/intent-routing.js +0 -26
  115. package/dist/runtime/openbot-runtime.js +0 -354
  116. package/dist/server.js +0 -890
  117. package/dist/session.js +0 -179
  118. package/dist/ui/block.js +0 -12
  119. package/dist/ui/header.js +0 -52
  120. package/dist/ui/layout.js +0 -26
  121. package/dist/ui/navigation.js +0 -15
  122. package/dist/ui/settings.js +0 -106
  123. package/dist/ui/skills.js +0 -7
  124. package/dist/ui/thread.js +0 -16
  125. package/dist/ui/widgets/action-list.js +0 -2
  126. package/dist/ui/widgets/approval-card.js +0 -9
  127. package/dist/ui/widgets/code-snippet.js +0 -2
  128. package/dist/ui/widgets/data-block.js +0 -2
  129. package/dist/ui/widgets/data-table.js +0 -2
  130. package/dist/ui/widgets/delegation.js +0 -29
  131. package/dist/ui/widgets/empty-state.js +0 -2
  132. package/dist/ui/widgets/index.js +0 -23
  133. package/dist/ui/widgets/inquiry.js +0 -7
  134. package/dist/ui/widgets/key-value.js +0 -2
  135. package/dist/ui/widgets/progress-step.js +0 -2
  136. package/dist/ui/widgets/resource-card.js +0 -2
  137. package/dist/ui/widgets/status.js +0 -2
  138. package/dist/ui/widgets/todo-list.js +0 -2
  139. package/dist/version.js +0 -62
  140. /package/dist/{types.js → app/types.js} +0 -0
  141. /package/dist/{architecture/contracts.js → harness/types.js} +0 -0
package/.prettierrc ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "semi": true,
3
+ "singleQuote": true,
4
+ "trailingComma": "all",
5
+ "printWidth": 100,
6
+ "tabWidth": 2,
7
+ "useTabs": false
8
+ }
package/AGENTS.md ADDED
@@ -0,0 +1,68 @@
1
+ # AGENTS.md
2
+
3
+ ## Purpose
4
+
5
+ This file gives coding agents persistent project context and working rules for OpenBot.
6
+ Use it as the default guidance for all tasks in this repository.
7
+
8
+ ## Main Goal
9
+
10
+ To solve agent fragmentation and communication problems.
11
+
12
+ ## Project Snapshot
13
+
14
+ OpenBot is a local-first platform for multi-agent orchestration and coordination.
15
+
16
+ - `src/`: event-driven orchestration engine built on Melony.
17
+ - Persistence is local-file based (no mandatory cloud datastore by default).
18
+ - API surface is intentionally minimal: only `GET /api/events`, `POST /api/publish`, and `GET /api/state`.
19
+
20
+ ## Product Mental Model
21
+
22
+ - **Orchestration**: The platform manages the lifecycle and communication of multiple specialized agents.
23
+ - **Agents**: Specialized participants (bots/personas) that users can delegate tasks to via command prefixes or direct interaction.
24
+ - **Channels**: Shared context spaces where multiple agents collaborate to solve complex problems.
25
+ - **Event-Driven**: The system is entirely event-stream oriented: the orchestrator and agents communicate via events, and the UI renders the evolving state.
26
+
27
+ ## Architecture Rules
28
+
29
+ 1. Favor event-based integration over tightly coupled imperative calls.
30
+ 2. Keep storage local-first unless a task explicitly requests remote persistence.
31
+ 3. Make incremental, composable changes rather than broad rewrites.
32
+
33
+ ## Server Guidance
34
+
35
+ - The server is event-first: treat HTTP routes as entry points into the event pipeline.
36
+ - Follow Melony's event flow: `Event -> Handler -> Events`.
37
+ - Keep the public API constrained to the three existing endpoints: `GET /api/events`, `POST /api/publish`, `GET /api/state`. Never introduce new endpoints; all functionality must be modeled through the event system.
38
+ - Plugin changes belong in `src/plugins/*`.
39
+ - Agent behavior and orchestration belong in agent/runtime layers, not UI code.
40
+ - For tool-calling flows, ensure completion/result events are emitted consistently.
41
+ - Avoid introducing hidden side effects in handlers; keep event output explicit.
42
+
43
+ ## Code Quality Expectations
44
+
45
+ - Make small, reviewable diffs with clear intent.
46
+ - Reuse existing utilities and conventions before adding new ones.
47
+ - Do not add dependencies unless necessary and justified by the task.
48
+ - Add/update tests when behavior changes in non-trivial ways.
49
+ - Run relevant checks for touched areas whenever possible.
50
+
51
+ ## Safe Change Policy
52
+
53
+ - Do not remove or rewrite unrelated user changes.
54
+ - Do not run destructive git operations unless explicitly requested.
55
+ - If encountering unexpected modified files, pause and confirm next step.
56
+
57
+ ## Useful Repo Context
58
+
59
+ - Detailed architecture: `docs/architecture.md`
60
+ - Plugin docs: `docs/plugins.md`
61
+ - Agent docs: `docs/agents.md`
62
+ - Cursor rules: `.cursor/rules/*.mdc`
63
+
64
+ ## Task Completion Checklist
65
+
66
+ - Changes align with local-first + event-driven design.
67
+ - Multi-agent/channel model is preserved.
68
+ - Any new behavior is documented where appropriate.
@@ -0,0 +1,74 @@
1
+ # Contributing to OpenBot 🤖
2
+
3
+ Thank you for your interest in contributing to OpenBot! We're building the future of local-first, multi-agent AI assistants, and we'd love for you to join us.
4
+
5
+ ---
6
+
7
+ ## 🗺️ Project Overview
8
+
9
+ OpenBot is a monorepo consisting of:
10
+ - **`server/`**: The core Node.js/TypeScript backend that orchestrates agents and handles the Melony event bus.
11
+ - **`web/`**: A React-based dashboard for interacting with your OpenBot instance.
12
+ - **`docs/`**: Detailed documentation on architecture, plugins, and agents.
13
+
14
+ ## 🚀 Getting Started
15
+
16
+ ### Prerequisites
17
+ - [Node.js](https://nodejs.org/) (v18 or higher)
18
+ - [npm](https://www.npmjs.com/)
19
+
20
+ ### Development Setup
21
+
22
+ 1. **Clone the repository**:
23
+ ```bash
24
+ git clone https://github.com/meetopenbot/openbot.git
25
+ cd openbot
26
+ ```
27
+
28
+ 2. **Install dependencies**:
29
+ We use a root-level script to install dependencies for both the server and the web dashboard:
30
+ ```bash
31
+ npm run install-all
32
+ ```
33
+
34
+ 3. **Run in development mode**:
35
+ To start both the server and the web dashboard concurrently:
36
+ ```bash
37
+ npm run dev
38
+ ```
39
+ The server typically runs on `http://localhost:4001` and the web dashboard on `http://localhost:5173`.
40
+
41
+ ## 🛠️ How to Contribute
42
+
43
+ ### Reporting Bugs or Requesting Features
44
+ - Check the [Issues](https://github.com/meetopenbot/openbot/issues) to see if it's already being discussed.
45
+ - If not, feel free to open a new issue with a clear description and steps to reproduce.
46
+
47
+ ### Submitting a Pull Request
48
+ 1. **Fork the repository** and create your branch from `main`.
49
+ 2. **Make your changes**. If you're adding a new feature, please include relevant documentation in the `docs/` folder or update the READMEs.
50
+ 3. **Ensure your code builds**:
51
+ ```bash
52
+ cd server && npm run build
53
+ ```
54
+ 4. **Create a Pull Request** with a clear title and description of your changes.
55
+
56
+ ## 🎨 Coding Standards
57
+
58
+ - **TypeScript**: We use TypeScript for both the server and the web dashboard. Please ensure your code is type-safe.
59
+ - **Linting**: Before submitting a PR, please run the linters:
60
+ ```bash
61
+ npm run lint --prefix web
62
+ ```
63
+ - **Functional & Event-Driven**: Since OpenBot is built on the [Melony](https://github.com/meetopenbot/melony) framework, try to stick to event-driven patterns when extending core functionality.
64
+
65
+ ## 🧩 Extending OpenBot
66
+
67
+ OpenBot is designed to be extensible. You can contribute in several ways:
68
+ - **New Plugins**: Add new capabilities (tools) to the `server/src/plugins/` directory.
69
+ - **Built-in Agents**: Define new specialized agents in `server/src/agents/`.
70
+ - **UI Enhancements**: Improve the React dashboard in the `web/` directory.
71
+
72
+ ---
73
+
74
+ We appreciate every contribution, big or small! If you have any questions, feel free to reach out via GitHub issues. Happy coding! 🚀
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 OpenBot Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,32 +1,135 @@
1
- # 👋 Meet OpenBot
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="logo-white.svg">
4
+ <img src="logo-black.svg" width="200" alt="OpenBot Logo" />
5
+ </picture>
6
+ </p>
2
7
 
3
- OpenBot is your personal AI assistant that's always ready to help! Built with **Melony**, it can chat, browse the web, and manage files—giving you a powerful, real-time sidekick right in your terminal.
8
+ <h1 align="center">OpenBot</h1>
4
9
 
5
- ## Get Started in Seconds
10
+ <p align="center">
11
+ <a href="https://www.npmjs.com/package/openbot"><img src="https://img.shields.io/npm/v/openbot" alt="npm version" /></a>
12
+ <a href="https://github.com/meetopenbot/openbot/blob/main/LICENSE"><img src="https://img.shields.io/github/license/meetopenbot/openbot" alt="license" /></a>
13
+ </p>
6
14
 
7
- Installing your new assistant is easy:
15
+ OpenBot is a local-first harness for running AI agents. It is built around a small event API, local file storage, and a Melony-powered runtime that routes events to agents and plugins.
16
+
17
+ ## What It Does
18
+
19
+ - Runs a local agent server.
20
+ - Stores channels, threads, agents, plugins, config, and variables under `~/.openbot`.
21
+ - Ships with a built-in `system` agent named Lolly.
22
+ - Loads custom agents from `~/.openbot/agents/<agent-id>/AGENT.md`.
23
+ - Loads shared plugins from `~/.openbot/plugins`.
24
+ - Streams events to clients with Server-Sent Events.
25
+
26
+ ## Quick Start
27
+
28
+ Requires Node.js `>=20.12.0`.
8
29
 
9
30
  ```bash
10
31
  npm i -g openbot
32
+ openbot start
33
+ ```
34
+
35
+ The server listens on `http://localhost:4132` by default. Set a different port with:
36
+
37
+ ```bash
38
+ openbot start --port 3000
11
39
  ```
12
40
 
13
- To start your assistant's server, just run:
41
+ For local development:
14
42
 
15
43
  ```bash
16
- openbot server
44
+ npm install
45
+ npm run dev
17
46
  ```
18
47
 
19
- OpenBot will start listening for you at `http://localhost:4001`.
48
+ ## API
20
49
 
21
- ## Say Hello
50
+ OpenBot intentionally keeps the public API small:
22
51
 
23
- You can talk to OpenBot using a simple POST request:
52
+ - `GET /api/events` opens an SSE stream for a channel or thread.
53
+ - `POST /api/publish` publishes an event into the harness.
54
+ - `GET /api/state` runs an event and returns the resulting events without opening a stream.
55
+
56
+ Example:
24
57
 
25
58
  ```bash
26
- curl -N \
27
- -H "Content-Type: application/json" \
28
- -d '{"event":{"type":"agent:input","data":{"content":"Hello!"}}}' \
29
- http://localhost:4001/api/chat
59
+ curl -X POST http://localhost:4132/api/publish \
60
+ -H "content-type: application/json" \
61
+ -d '{"type":"user:input","data":{"content":"hello"}}'
62
+ ```
63
+
64
+ Useful context can be passed as headers, query params, or body fields:
65
+
66
+ - `channelId`
67
+ - `threadId`
68
+ - `agentId`
69
+ - `runId`
70
+
71
+ ## Configuration
72
+
73
+ OpenBot reads config from `~/.openbot/config.json`.
74
+
75
+ ```json
76
+ {
77
+ "port": 4132,
78
+ "baseDir": "~/.openbot",
79
+ "model": "openai/gpt-4o-mini",
80
+ "mcpServers": []
81
+ }
30
82
  ```
31
83
 
32
- That's it! OpenBot will stream its response right back to you. 🚀
84
+ Variables are read from `~/.openbot/variables.json` and applied to the server process environment on startup.
85
+
86
+ ## Agents
87
+
88
+ The built-in `system` agent is always available. Add a custom agent by creating `~/.openbot/agents/<agent-id>/AGENT.md`:
89
+
90
+ ```markdown
91
+ ---
92
+ name: Researcher
93
+ description: Helps collect and summarize information.
94
+ runtime:
95
+ name: ai-sdk
96
+ config:
97
+ model: openai/gpt-4o-mini
98
+ plugins:
99
+ - name: storage
100
+ ---
101
+
102
+ You are a careful research assistant.
103
+ Summarize findings clearly and cite sources when available.
104
+ ```
105
+
106
+ Agents are discovered from disk when the server starts.
107
+
108
+ ## Plugins
109
+
110
+ Built-in plugins include:
111
+
112
+ - `storage`
113
+ - `delegation`
114
+ - `mcp`
115
+ - `ui`
116
+ - `ai-sdk`
117
+
118
+ Shared plugins can be placed in `~/.openbot/plugins` and referenced by agents.
119
+
120
+ ## Project Layout
121
+
122
+ - `src/app`: CLI, server, event types, and app config.
123
+ - `src/harness`: agent harness, orchestration, process, and MCP runtime helpers.
124
+ - `src/plugins`: built-in plugin implementations.
125
+ - `src/services`: local storage service.
126
+ - `src/registry`: plugin registry.
127
+ - `docs`: architecture, agents, and plugin notes.
128
+
129
+ ## Learn More
130
+
131
+ - [Architecture](./docs/architecture.md)
132
+ - [Agents](./docs/agents.md)
133
+ - [Plugins](./docs/plugins.md)
134
+
135
+ Need help or want to share feedback? Join the community on Discord: https://discord.gg/XYYXvN2ebB
@@ -0,0 +1,106 @@
1
+ import { delegationToolDefinitions } from '../plugins/delegation.js';
2
+ import { storageToolDefinitions } from '../plugins/storage.js';
3
+ import { mcpToolDefinitions } from '../plugins/mcp.js';
4
+ import { uiToolDefinitions } from '../plugins/ui.js';
5
+ import { storageService } from '../services/storage.js';
6
+ import { readFileSync } from 'node:fs';
7
+ const SYSTEM_ICON_DATA_URL = (() => {
8
+ try {
9
+ const svg = readFileSync(new URL('../assets/icon.svg', import.meta.url), 'utf-8').trim();
10
+ if (!svg.startsWith('<svg'))
11
+ return undefined;
12
+ return `data:image/svg+xml;base64,${Buffer.from(svg, 'utf-8').toString('base64')}`;
13
+ }
14
+ catch {
15
+ return undefined;
16
+ }
17
+ })();
18
+ export const getSystemAgentDetails = (overrides) => {
19
+ const defaults = {
20
+ id: 'system',
21
+ name: 'Lolly',
22
+ image: SYSTEM_ICON_DATA_URL,
23
+ instructions: 'You are OpenBot, the primary AI assistant and orchestrator of this workspace. Your goal is to help users onboard, answer questions about the system, and suggest specialized agents for specific tasks.\n\n' +
24
+ '### How to use OpenBot:\n' +
25
+ '1. **General Chat**: Just type your message here, and I will help you.\n' +
26
+ '2. **Specialized Agents**: You can delegate tasks to specialized agents for specific tasks. For example, use the `delegate` tool to invoke the `os` agent for terminal commands and file operations.\n' +
27
+ '3. **Channels**: Channels are shared spaces where multiple agents can participate. You can create new channels for different topics.\n' +
28
+ '4. **Local-First**: OpenBot runs entirely on your machine. Your data stays private and local.\n\n' +
29
+ '### Workflow Guidelines:\n' +
30
+ '- **Todo Schema**: Keep todo items simple. Each item should have a short `id`, a clear `task` description, and a `status` (e.g., "pending", "in_progress", "done").\n' +
31
+ '- **Interactive Widgets**: Use `render_ui_widget` to give the user a visual progress bar (`kind: "todo_list"`), request permissions (`kind: "approval"`), or gather structured data (`kind: "form"`).\n' +
32
+ '- **Delegation**: When delegating to another agent, reference the relevant Task ID from the thread state. Update the task status (e.g., using `patch_thread_details`) as progress is made.\n\n' +
33
+ 'If you need to know what agents or plugins are installed, I can help you find that information.',
34
+ runtime: {
35
+ name: 'ai-sdk',
36
+ config: {
37
+ model: 'openai/gpt-4o-mini',
38
+ toolDefinitions: {
39
+ ...delegationToolDefinitions,
40
+ ...storageToolDefinitions,
41
+ ...mcpToolDefinitions,
42
+ ...uiToolDefinitions,
43
+ },
44
+ },
45
+ },
46
+ plugins: [
47
+ { name: 'storage', config: { storage: storageService } },
48
+ { name: 'delegation', config: {} },
49
+ { name: 'mcp', config: {} },
50
+ { name: 'ui', config: {} },
51
+ ],
52
+ description: 'System coordinator agent',
53
+ createdAt: new Date(),
54
+ updatedAt: new Date(),
55
+ };
56
+ if (!overrides)
57
+ return defaults;
58
+ // Merge logic:
59
+ // - Simple fields: override if present
60
+ // - Runtime: merge config/model, but preserve toolDefinitions unless explicitly overridden
61
+ // - Plugins: merge by name (user plugins override defaults)
62
+ const mergedRuntime = {
63
+ ...(typeof defaults.runtime === 'object' ? defaults.runtime : {}),
64
+ ...(typeof overrides.runtime === 'object' ? overrides.runtime : {}),
65
+ name: (typeof overrides.runtime === 'object' ? overrides.runtime.name : overrides.runtime) ||
66
+ (typeof defaults.runtime === 'object' ? defaults.runtime.name : defaults.runtime) ||
67
+ 'ai-sdk',
68
+ config: {
69
+ ...(defaults.runtime && typeof defaults.runtime !== 'string' ? defaults.runtime.config : {}),
70
+ ...(overrides.runtime && typeof overrides.runtime !== 'string' ? overrides.runtime.config : {}),
71
+ toolDefinitions: {
72
+ ...(defaults.runtime && typeof defaults.runtime !== 'string'
73
+ ? defaults.runtime.config?.toolDefinitions
74
+ : {}),
75
+ ...(overrides.runtime && typeof overrides.runtime !== 'string'
76
+ ? overrides.runtime.config?.toolDefinitions
77
+ : {}),
78
+ },
79
+ },
80
+ };
81
+ const mergedPlugins = [...(defaults.plugins || [])];
82
+ if (overrides.plugins) {
83
+ for (const p of overrides.plugins) {
84
+ const name = typeof p === 'string' ? p : p.name;
85
+ const index = mergedPlugins.findIndex((existing) => {
86
+ const existingName = typeof existing === 'string' ? existing : existing.name;
87
+ return existingName === name;
88
+ });
89
+ if (index !== -1) {
90
+ mergedPlugins[index] = p;
91
+ }
92
+ else {
93
+ mergedPlugins.push(p);
94
+ }
95
+ }
96
+ }
97
+ return {
98
+ ...defaults,
99
+ ...overrides,
100
+ id: 'system', // Always enforce 'system' ID
101
+ image: overrides.image || defaults.image, // Ensure image is preserved if not explicitly overridden
102
+ runtime: mergedRuntime,
103
+ plugins: mergedPlugins,
104
+ updatedAt: new Date(),
105
+ };
106
+ };
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { startServer } from './server.js';
4
+ const program = new Command();
5
+ const REQUIRED_NODE_VERSION = '20.12.0';
6
+ function checkNodeVersion() {
7
+ const [major, minor, patch] = process.versions.node.split('.').map(Number);
8
+ const [reqMajor, reqMinor, reqPatch] = REQUIRED_NODE_VERSION.split('.').map(Number);
9
+ const isOld = major < reqMajor ||
10
+ (major === reqMajor && minor < reqMinor) ||
11
+ (major === reqMajor && minor === reqMinor && patch < reqPatch);
12
+ if (isOld) {
13
+ console.warn(`\n⚠️ WARNING: You are using Node.js ${process.version}.`);
14
+ console.warn(` OpenBot works best with Node.js >=${REQUIRED_NODE_VERSION}.`);
15
+ console.warn(` You may encounter "ERR_REQUIRE_ESM" or other compatibility issues on older versions.\n`);
16
+ }
17
+ }
18
+ checkNodeVersion();
19
+ program.name('openbot').description('OpenBot CLI').version('0.2.14');
20
+ program
21
+ .command('start')
22
+ .description('Start the OpenBot harness')
23
+ .option('-p, --port <number>', 'Port to listen on')
24
+ .action(async (options) => {
25
+ await startServer(options);
26
+ });
27
+ program.parse();
@@ -0,0 +1,64 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ export const DEFAULT_BASE_DIR = '~/.openbot';
5
+ export const DEFAULT_PLUGINS_DIR = 'plugins';
6
+ export const DEFAULT_AGENTS_DIR = 'agents';
7
+ export const DEFAULT_CHANNELS_DIR = 'channels';
8
+ export const CONFIG_FILE = 'config.json';
9
+ export const VARIABLES_FILE = 'variables.json';
10
+ export function resolvePath(p) {
11
+ return p.startsWith('~/') ? path.join(os.homedir(), p.slice(2)) : path.resolve(p);
12
+ }
13
+ export function loadConfig() {
14
+ const configPath = path.join(os.homedir(), '.openbot', CONFIG_FILE);
15
+ if (fs.existsSync(configPath)) {
16
+ try {
17
+ return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
18
+ }
19
+ catch (error) {
20
+ console.error(`Warning: Failed to parse config at ${configPath}`, error);
21
+ }
22
+ }
23
+ return {};
24
+ }
25
+ export function saveConfig(config) {
26
+ const configDir = resolvePath(DEFAULT_BASE_DIR);
27
+ const configPath = path.join(configDir, CONFIG_FILE);
28
+ if (!fs.existsSync(configDir)) {
29
+ fs.mkdirSync(configDir, { recursive: true, mode: 0o700 });
30
+ }
31
+ const currentConfig = loadConfig();
32
+ const newConfig = { ...currentConfig, ...config };
33
+ fs.writeFileSync(configPath, JSON.stringify(newConfig, null, 2), { mode: 0o600 });
34
+ }
35
+ export function isConfigured() {
36
+ const configPath = path.join(resolvePath(DEFAULT_BASE_DIR), CONFIG_FILE);
37
+ return fs.existsSync(configPath);
38
+ }
39
+ export function loadVariables() {
40
+ const variablesPath = path.join(resolvePath(DEFAULT_BASE_DIR), VARIABLES_FILE);
41
+ if (fs.existsSync(variablesPath)) {
42
+ return JSON.parse(fs.readFileSync(variablesPath, 'utf-8'));
43
+ }
44
+ return { version: 1, variables: [] };
45
+ }
46
+ export const DEFAULT_AGENT_MD = `---
47
+ description: A specialized AI agent
48
+ ---
49
+
50
+ # Agent Profile
51
+
52
+ You are a specialized AI agent within the OpenBot system.
53
+ Your role is defined by your configuration and the tools you have access to.
54
+
55
+ ## Persona
56
+ - Helpful and precise
57
+ - Focused on my specific domain
58
+ - Professional in all interactions
59
+ `;
60
+ export const DEFAULT_USER_MD = `# About Me
61
+
62
+ <!-- OpenBot reads this file to understand who you are and how you like to work. -->
63
+ <!-- Edit it here or just chat — agents can update it with the "remember" tool. -->
64
+ `;