openbot 0.4.6 → 0.5.4

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 (132) hide show
  1. package/.claude/agents/runtime-security-reviewer.md +32 -0
  2. package/.claude/hooks/format.sh +18 -0
  3. package/.claude/hooks/protect-secrets.sh +23 -0
  4. package/.claude/settings.json +26 -0
  5. package/.claude/skills/deploy/SKILL.md +26 -0
  6. package/.claude/skills/new-plugin/SKILL.md +46 -0
  7. package/.dockerignore +9 -0
  8. package/.mcp.json +8 -0
  9. package/AGENTS.md +2 -2
  10. package/CLAUDE.md +50 -0
  11. package/Dockerfile +41 -0
  12. package/deploy/README.md +61 -0
  13. package/deploy/entrypoint.sh +6 -0
  14. package/deploy/fly.toml +36 -0
  15. package/dist/app/bootstrap.js +29 -0
  16. package/dist/app/cli.js +3 -1
  17. package/dist/app/cloud-mode.js +26 -0
  18. package/dist/app/config.js +61 -16
  19. package/dist/app/responding-agent.js +32 -0
  20. package/dist/app/server.js +47 -9
  21. package/dist/plugins/approval/index.js +1 -1
  22. package/dist/plugins/bash/index.js +386 -164
  23. package/dist/plugins/memory/service.js +2 -5
  24. package/dist/plugins/openbot/context.js +17 -1
  25. package/dist/plugins/openbot/index.js +25 -9
  26. package/dist/plugins/openbot/model.js +59 -0
  27. package/dist/plugins/openbot/runtime.js +39 -56
  28. package/dist/plugins/openbot/system-prompt.js +44 -9
  29. package/dist/plugins/preview/index.js +267 -0
  30. package/dist/plugins/storage/index.js +3 -3
  31. package/dist/plugins/storage/service.js +58 -12
  32. package/dist/plugins/todo/index.js +131 -38
  33. package/dist/plugins/todo/service.js +93 -0
  34. package/dist/plugins/ui/index.js +8 -1
  35. package/dist/services/plugins/model-registry.js +101 -0
  36. package/dist/services/plugins/registry.js +6 -4
  37. package/dist/services/plugins/service.js +2 -6
  38. package/docs/agents.md +20 -2
  39. package/docs/architecture.md +1 -1
  40. package/docs/plugins.md +13 -3
  41. package/docs/templates/AGENT.example.md +1 -1
  42. package/package.json +5 -2
  43. package/pnpm-workspace.yaml +2 -0
  44. package/src/app/bootstrap.ts +43 -0
  45. package/src/app/cli.ts +3 -1
  46. package/src/app/cloud-mode.ts +41 -0
  47. package/src/app/config.ts +71 -19
  48. package/src/app/responding-agent.ts +46 -0
  49. package/src/app/server.ts +55 -9
  50. package/src/app/types.ts +167 -31
  51. package/src/plugins/approval/index.ts +1 -1
  52. package/src/plugins/bash/index.ts +498 -185
  53. package/src/plugins/memory/service.ts +2 -5
  54. package/src/plugins/openbot/context.ts +17 -1
  55. package/src/plugins/openbot/index.ts +27 -11
  56. package/src/plugins/openbot/model.ts +76 -0
  57. package/src/plugins/openbot/runtime.ts +47 -69
  58. package/src/plugins/openbot/system-prompt.ts +44 -9
  59. package/src/plugins/preview/index.ts +323 -0
  60. package/src/plugins/storage/index.ts +5 -8
  61. package/src/plugins/storage/service.ts +79 -15
  62. package/src/plugins/todo/index.ts +166 -0
  63. package/src/plugins/todo/service.ts +123 -0
  64. package/src/plugins/ui/index.ts +8 -1
  65. package/src/services/plugins/domain.ts +2 -0
  66. package/src/services/plugins/model-registry.ts +146 -0
  67. package/src/services/plugins/registry.ts +6 -4
  68. package/src/services/plugins/service.ts +2 -6
  69. package/dist/agents/openbot/index.js +0 -76
  70. package/dist/agents/openbot/middleware/approval.js +0 -132
  71. package/dist/agents/openbot/runtime.js +0 -289
  72. package/dist/agents/openbot/system-prompt.js +0 -32
  73. package/dist/agents/openbot/tools/delegation.js +0 -78
  74. package/dist/agents/openbot/tools/mcp.js +0 -99
  75. package/dist/agents/openbot/tools/shell.js +0 -91
  76. package/dist/agents/openbot/tools/storage.js +0 -75
  77. package/dist/agents/openbot/tools/ui.js +0 -176
  78. package/dist/agents/system.js +0 -33
  79. package/dist/bus/agent-package.js +0 -1
  80. package/dist/bus/plugin.js +0 -1
  81. package/dist/bus/services.js +0 -754
  82. package/dist/bus/types.js +0 -1
  83. package/dist/harness/agent-harness.js +0 -45
  84. package/dist/harness/agent-invoke-run.js +0 -44
  85. package/dist/harness/agent-turn.js +0 -99
  86. package/dist/harness/channel-participants.js +0 -40
  87. package/dist/harness/constants.js +0 -2
  88. package/dist/harness/context-meter.js +0 -97
  89. package/dist/harness/context.js +0 -363
  90. package/dist/harness/dispatch.js +0 -144
  91. package/dist/harness/dispatcher.js +0 -156
  92. package/dist/harness/event-normalizer.js +0 -59
  93. package/dist/harness/history.js +0 -177
  94. package/dist/harness/mcp.js +0 -61
  95. package/dist/harness/orchestration.js +0 -88
  96. package/dist/harness/orchestrator.js +0 -149
  97. package/dist/harness/participants.js +0 -22
  98. package/dist/harness/process.js +0 -29
  99. package/dist/harness/queue-processor.js +0 -187
  100. package/dist/harness/run-harness.js +0 -154
  101. package/dist/harness/run.js +0 -98
  102. package/dist/harness/runtime-factory.js +0 -73
  103. package/dist/harness/runtime.js +0 -57
  104. package/dist/harness/todo-advance.js +0 -93
  105. package/dist/harness/todo-dispatch.js +0 -51
  106. package/dist/harness/todos.js +0 -5
  107. package/dist/harness/turn.js +0 -79
  108. package/dist/harness/types.js +0 -1
  109. package/dist/plugins/ai-sdk/index.js +0 -34
  110. package/dist/plugins/ai-sdk/runtime.js +0 -395
  111. package/dist/plugins/ai-sdk/system-prompt.js +0 -18
  112. package/dist/plugins/ai-sdk.js +0 -331
  113. package/dist/plugins/approval.js +0 -163
  114. package/dist/plugins/delegation.js +0 -108
  115. package/dist/plugins/mcp/index.js +0 -108
  116. package/dist/plugins/mcp.js +0 -140
  117. package/dist/plugins/shell/index.js +0 -100
  118. package/dist/plugins/shell.js +0 -123
  119. package/dist/plugins/storage-tools/index.js +0 -76
  120. package/dist/plugins/storage.js +0 -737
  121. package/dist/plugins/thread-namer/index.js +0 -72
  122. package/dist/plugins/threads/index.js +0 -114
  123. package/dist/plugins/ui.js +0 -211
  124. package/dist/plugins/workflow/index.js +0 -65
  125. package/dist/registry/agents.js +0 -138
  126. package/dist/registry/plugins.js +0 -110
  127. package/dist/services/agent-packages.js +0 -103
  128. package/dist/services/memory.js +0 -152
  129. package/dist/services/plugins.js +0 -98
  130. package/dist/services/storage.js +0 -1028
  131. package/dist/workflow/service.js +0 -106
  132. package/dist/workflow/types.js +0 -3
@@ -8,7 +8,8 @@ import { createRequire } from 'module';
8
8
  const require = createRequire(import.meta.url);
9
9
  const pkg = require('../../package.json');
10
10
  import { generateId } from 'melony';
11
- import { DEFAULT_BASE_DIR, loadConfig, resolvePath } from '../app/config.js';
11
+ import { getBaseDir, loadConfig } from '../app/config.js';
12
+ import { isCloudMode, getCloudIntegrationsConfig } from './cloud-mode.js';
12
13
  import { processService } from '../services/process.js';
13
14
  import { runAgent, STATE_AGENT_ID, ORCHESTRATOR_AGENT_ID } from '../harness/index.js';
14
15
  import { initPlugins } from '../services/plugins/registry.js';
@@ -16,7 +17,7 @@ import { storageService } from '../plugins/storage/service.js';
16
17
  import { buildWorkspaceFileUrl, getPublicBaseUrl, openChannelFileStream, } from '../plugins/storage/files.js';
17
18
  import { ensureEventId, openBotEventFromQuery } from './utils.js';
18
19
  import { abortRegistry, abortKey } from '../services/abort.js';
19
- import { resolveRespondingAgentId } from './responding-agent.js';
20
+ import { resolvePublishTargetAgentId, resolveRespondingAgentId } from './responding-agent.js';
20
21
  import { DEFAULT_UNCATEGORIZED_SPEC, UNCATEGORIZED_CHANNEL_ID, } from './channel-ids.js';
21
22
  export async function startServer(options = {}) {
22
23
  const publishEventSchema = z
@@ -29,8 +30,11 @@ export async function startServer(options = {}) {
29
30
  .passthrough();
30
31
  const config = loadConfig();
31
32
  processService.syncWorkspaceVariablesToProcessEnv();
32
- const baseDir = config.baseDir || DEFAULT_BASE_DIR;
33
- const openBotDir = resolvePath(baseDir);
33
+ if (isCloudMode()) {
34
+ const integrations = getCloudIntegrationsConfig();
35
+ console.log(`[server] Cloud mode enabled${integrations ? '' : ' (integrations proxy env not set)'}`);
36
+ }
37
+ const openBotDir = getBaseDir();
34
38
  const PORT = Number(options.port ?? config.port ?? process.env.PORT ?? 4132);
35
39
  const app = express();
36
40
  const clients = new Map();
@@ -194,6 +198,21 @@ export async function startServer(options = {}) {
194
198
  next();
195
199
  });
196
200
  app.use(cors());
201
+ const gatewayToken = process.env.OPENBOT_GATEWAY_TOKEN?.trim();
202
+ if (gatewayToken) {
203
+ app.use((req, res, next) => {
204
+ if (req.path === '/api/health' || req.method === 'OPTIONS') {
205
+ next();
206
+ return;
207
+ }
208
+ const got = req.get('x-openbot-gateway-token');
209
+ if (got !== gatewayToken) {
210
+ res.status(401).json({ error: 'unauthorized' });
211
+ return;
212
+ }
213
+ next();
214
+ });
215
+ }
197
216
  const resolvePublicBaseUrl = () => getPublicBaseUrl(PORT, config.publicUrl);
198
217
  app.use((req, res, next) => {
199
218
  const isWorkspaceUpload = req.method === 'POST' &&
@@ -206,7 +225,7 @@ export async function startServer(options = {}) {
206
225
  express.json({ limit: '20mb' })(req, res, next);
207
226
  });
208
227
  app.get('/api/health', (req, res) => {
209
- res.json({ status: 'ok', version: pkg.version });
228
+ res.json({ status: 'ok', version: pkg.version, apiVersion: 1 });
210
229
  });
211
230
  app.get('/api/events', (req, res) => {
212
231
  const { channelId, threadId } = getContext(req);
@@ -457,15 +476,21 @@ export async function startServer(options = {}) {
457
476
  });
458
477
  }
459
478
  const bindIfUnbound = event.type === 'agent:invoke';
460
- const resolved = await resolveRespondingAgentId({
479
+ const target = await resolvePublishTargetAgentId({
480
+ eventType: event.type,
461
481
  channelId,
462
482
  threadId,
463
483
  requestedAgentId: agentId,
484
+ eventMeta: event.meta,
464
485
  bindIfUnbound,
465
486
  });
487
+ if ('error' in target) {
488
+ res.status(400).json({ error: 'agentId is required for widget response' });
489
+ return;
490
+ }
466
491
  await runAgent({
467
492
  runId,
468
- agentId: resolved.agentId,
493
+ agentId: target.agentId,
469
494
  event,
470
495
  channelId,
471
496
  threadId,
@@ -561,8 +586,21 @@ export async function startServer(options = {}) {
561
586
  res.status(500).json({ error: 'Failed to process state request' });
562
587
  }
563
588
  });
564
- app.listen(PORT, () => {
565
- console.log(`\x1b[32mOpenBot server listening at http://localhost:${PORT}\x1b[0m`);
589
+ const HOST = process.env.HOST || '0.0.0.0';
590
+ const server = app.listen(PORT, HOST, () => {
591
+ console.log(`\x1b[32mOpenBot server listening at http://${HOST}:${PORT}\x1b[0m`);
566
592
  console.log(`🌐 Visit \x1b[96m\x1b[1mhttps://openbot.one\x1b[0m to connect to this runtime and manage everything from there. ✨`);
567
593
  });
594
+ const shutdown = (signal) => {
595
+ console.log(`\n[server] Received ${signal}, shutting down...`);
596
+ server.close(() => {
597
+ process.exit(0);
598
+ });
599
+ setTimeout(() => {
600
+ console.error('[server] Forced shutdown after timeout');
601
+ process.exit(1);
602
+ }, 10000).unref();
603
+ };
604
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
605
+ process.on('SIGINT', () => shutdown('SIGINT'));
568
606
  }
@@ -14,7 +14,7 @@ export const approvalPlugin = {
14
14
  description: 'Gate protected tool calls behind a UI confirmation widget.',
15
15
  factory: ({ config, storage }) => (builder) => {
16
16
  // Actions that require approval. Defaults to bash.
17
- const actionsToApprove = config.actions || ['action:bash'];
17
+ const actionsToApprove = config.actions || ['action:shell_exec'];
18
18
  for (const action of actionsToApprove) {
19
19
  builder.intercept(action, (event, context) => {
20
20
  // If already approved in this flow, let it pass to the actual handler