@lobu/gateway 3.0.8 → 3.0.12

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 (219) hide show
  1. package/dist/api/platform.d.ts.map +1 -1
  2. package/dist/api/platform.js +8 -26
  3. package/dist/api/platform.js.map +1 -1
  4. package/dist/auth/mcp/proxy.d.ts +14 -0
  5. package/dist/auth/mcp/proxy.d.ts.map +1 -1
  6. package/dist/auth/mcp/proxy.js +149 -13
  7. package/dist/auth/mcp/proxy.js.map +1 -1
  8. package/dist/cli/gateway.d.ts.map +1 -1
  9. package/dist/cli/gateway.js +29 -0
  10. package/dist/cli/gateway.js.map +1 -1
  11. package/dist/cli/index.js +2 -2
  12. package/dist/cli/index.js.map +1 -1
  13. package/dist/connections/chat-instance-manager.d.ts.map +1 -1
  14. package/dist/connections/chat-instance-manager.js +2 -1
  15. package/dist/connections/chat-instance-manager.js.map +1 -1
  16. package/dist/connections/interaction-bridge.d.ts +9 -2
  17. package/dist/connections/interaction-bridge.d.ts.map +1 -1
  18. package/dist/connections/interaction-bridge.js +132 -230
  19. package/dist/connections/interaction-bridge.js.map +1 -1
  20. package/dist/connections/message-handler-bridge.d.ts.map +1 -1
  21. package/dist/connections/message-handler-bridge.js +44 -26
  22. package/dist/connections/message-handler-bridge.js.map +1 -1
  23. package/dist/interactions.d.ts +9 -43
  24. package/dist/interactions.d.ts.map +1 -1
  25. package/dist/interactions.js +10 -52
  26. package/dist/interactions.js.map +1 -1
  27. package/dist/orchestration/base-deployment-manager.js +7 -7
  28. package/dist/orchestration/base-deployment-manager.js.map +1 -1
  29. package/dist/platform/unified-thread-consumer.d.ts.map +1 -1
  30. package/dist/platform/unified-thread-consumer.js +38 -34
  31. package/dist/platform/unified-thread-consumer.js.map +1 -1
  32. package/dist/routes/public/agent.d.ts +4 -0
  33. package/dist/routes/public/agent.d.ts.map +1 -1
  34. package/dist/routes/public/agent.js +21 -0
  35. package/dist/routes/public/agent.js.map +1 -1
  36. package/dist/services/core-services.d.ts.map +1 -1
  37. package/dist/services/core-services.js +4 -0
  38. package/dist/services/core-services.js.map +1 -1
  39. package/package.json +2 -2
  40. package/src/__tests__/agent-config-routes.test.ts +0 -254
  41. package/src/__tests__/agent-history-routes.test.ts +0 -72
  42. package/src/__tests__/agent-routes.test.ts +0 -68
  43. package/src/__tests__/agent-schedules-routes.test.ts +0 -59
  44. package/src/__tests__/agent-settings-store.test.ts +0 -323
  45. package/src/__tests__/bedrock-model-catalog.test.ts +0 -40
  46. package/src/__tests__/bedrock-openai-service.test.ts +0 -157
  47. package/src/__tests__/bedrock-provider-module.test.ts +0 -56
  48. package/src/__tests__/chat-instance-manager-slack.test.ts +0 -204
  49. package/src/__tests__/chat-response-bridge.test.ts +0 -131
  50. package/src/__tests__/config-memory-plugins.test.ts +0 -92
  51. package/src/__tests__/config-request-store.test.ts +0 -127
  52. package/src/__tests__/connection-routes.test.ts +0 -144
  53. package/src/__tests__/core-services-store-selection.test.ts +0 -92
  54. package/src/__tests__/docker-deployment.test.ts +0 -1211
  55. package/src/__tests__/embedded-deployment.test.ts +0 -342
  56. package/src/__tests__/grant-store.test.ts +0 -148
  57. package/src/__tests__/http-proxy.test.ts +0 -281
  58. package/src/__tests__/instruction-service.test.ts +0 -37
  59. package/src/__tests__/link-buttons.test.ts +0 -112
  60. package/src/__tests__/lobu.test.ts +0 -32
  61. package/src/__tests__/mcp-config-service.test.ts +0 -347
  62. package/src/__tests__/mcp-proxy.test.ts +0 -694
  63. package/src/__tests__/message-handler-bridge.test.ts +0 -17
  64. package/src/__tests__/model-selection.test.ts +0 -172
  65. package/src/__tests__/oauth-templates.test.ts +0 -39
  66. package/src/__tests__/platform-adapter-slack-send.test.ts +0 -114
  67. package/src/__tests__/platform-helpers-model-resolution.test.ts +0 -253
  68. package/src/__tests__/provider-inheritance.test.ts +0 -212
  69. package/src/__tests__/routes/cli-auth.test.ts +0 -337
  70. package/src/__tests__/routes/interactions.test.ts +0 -121
  71. package/src/__tests__/secret-proxy.test.ts +0 -85
  72. package/src/__tests__/session-manager.test.ts +0 -572
  73. package/src/__tests__/setup.ts +0 -133
  74. package/src/__tests__/skill-and-mcp-registry.test.ts +0 -203
  75. package/src/__tests__/slack-routes.test.ts +0 -161
  76. package/src/__tests__/system-config-resolver.test.ts +0 -75
  77. package/src/__tests__/system-message-limiter.test.ts +0 -89
  78. package/src/__tests__/system-skills-service.test.ts +0 -362
  79. package/src/__tests__/transcription-service.test.ts +0 -222
  80. package/src/__tests__/utils/rate-limiter.test.ts +0 -102
  81. package/src/__tests__/worker-connection-manager.test.ts +0 -497
  82. package/src/__tests__/worker-job-router.test.ts +0 -722
  83. package/src/api/index.ts +0 -1
  84. package/src/api/platform.ts +0 -292
  85. package/src/api/response-renderer.ts +0 -157
  86. package/src/auth/agent-metadata-store.ts +0 -168
  87. package/src/auth/api-auth-middleware.ts +0 -69
  88. package/src/auth/api-key-provider-module.ts +0 -213
  89. package/src/auth/base-provider-module.ts +0 -201
  90. package/src/auth/bedrock/provider-module.ts +0 -110
  91. package/src/auth/chatgpt/chatgpt-oauth-module.ts +0 -185
  92. package/src/auth/chatgpt/device-code-client.ts +0 -218
  93. package/src/auth/chatgpt/index.ts +0 -1
  94. package/src/auth/claude/oauth-module.ts +0 -280
  95. package/src/auth/cli/token-service.ts +0 -249
  96. package/src/auth/external/client.ts +0 -560
  97. package/src/auth/external/device-code-client.ts +0 -235
  98. package/src/auth/mcp/config-service.ts +0 -420
  99. package/src/auth/mcp/proxy.ts +0 -1086
  100. package/src/auth/mcp/string-substitution.ts +0 -17
  101. package/src/auth/mcp/tool-cache.ts +0 -90
  102. package/src/auth/oauth/base-client.ts +0 -267
  103. package/src/auth/oauth/client.ts +0 -153
  104. package/src/auth/oauth/credentials.ts +0 -7
  105. package/src/auth/oauth/providers.ts +0 -69
  106. package/src/auth/oauth/state-store.ts +0 -150
  107. package/src/auth/oauth-templates.ts +0 -179
  108. package/src/auth/provider-catalog.ts +0 -220
  109. package/src/auth/provider-model-options.ts +0 -41
  110. package/src/auth/settings/agent-settings-store.ts +0 -565
  111. package/src/auth/settings/auth-profiles-manager.ts +0 -216
  112. package/src/auth/settings/index.ts +0 -12
  113. package/src/auth/settings/model-preference-store.ts +0 -52
  114. package/src/auth/settings/model-selection.ts +0 -135
  115. package/src/auth/settings/resolved-settings-view.ts +0 -298
  116. package/src/auth/settings/template-utils.ts +0 -44
  117. package/src/auth/settings/token-service.ts +0 -88
  118. package/src/auth/system-env-store.ts +0 -98
  119. package/src/auth/user-agents-store.ts +0 -68
  120. package/src/channels/binding-service.ts +0 -214
  121. package/src/channels/index.ts +0 -4
  122. package/src/cli/gateway.ts +0 -1312
  123. package/src/cli/index.ts +0 -74
  124. package/src/commands/built-in-commands.ts +0 -80
  125. package/src/commands/command-dispatcher.ts +0 -94
  126. package/src/commands/command-reply-adapters.ts +0 -27
  127. package/src/config/file-loader.ts +0 -618
  128. package/src/config/index.ts +0 -588
  129. package/src/config/network-allowlist.ts +0 -71
  130. package/src/connections/chat-instance-manager.ts +0 -1284
  131. package/src/connections/chat-response-bridge.ts +0 -618
  132. package/src/connections/index.ts +0 -7
  133. package/src/connections/interaction-bridge.ts +0 -831
  134. package/src/connections/message-handler-bridge.ts +0 -415
  135. package/src/connections/platform-auth-methods.ts +0 -15
  136. package/src/connections/types.ts +0 -84
  137. package/src/gateway/connection-manager.ts +0 -291
  138. package/src/gateway/index.ts +0 -698
  139. package/src/gateway/job-router.ts +0 -201
  140. package/src/gateway-main.ts +0 -200
  141. package/src/index.ts +0 -41
  142. package/src/infrastructure/queue/index.ts +0 -12
  143. package/src/infrastructure/queue/queue-producer.ts +0 -148
  144. package/src/infrastructure/queue/redis-queue.ts +0 -361
  145. package/src/infrastructure/queue/types.ts +0 -133
  146. package/src/infrastructure/redis/system-message-limiter.ts +0 -94
  147. package/src/interactions/config-request-store.ts +0 -198
  148. package/src/interactions.ts +0 -363
  149. package/src/lobu.ts +0 -311
  150. package/src/metrics/prometheus.ts +0 -159
  151. package/src/modules/module-system.ts +0 -179
  152. package/src/orchestration/base-deployment-manager.ts +0 -900
  153. package/src/orchestration/deployment-utils.ts +0 -98
  154. package/src/orchestration/impl/docker-deployment.ts +0 -620
  155. package/src/orchestration/impl/embedded-deployment.ts +0 -268
  156. package/src/orchestration/impl/index.ts +0 -8
  157. package/src/orchestration/impl/k8s/deployment.ts +0 -1061
  158. package/src/orchestration/impl/k8s/helpers.ts +0 -610
  159. package/src/orchestration/impl/k8s/index.ts +0 -1
  160. package/src/orchestration/index.ts +0 -333
  161. package/src/orchestration/message-consumer.ts +0 -584
  162. package/src/orchestration/scheduled-wakeup.ts +0 -704
  163. package/src/permissions/approval-policy.ts +0 -36
  164. package/src/permissions/grant-store.ts +0 -219
  165. package/src/platform/file-handler.ts +0 -66
  166. package/src/platform/link-buttons.ts +0 -57
  167. package/src/platform/renderer-utils.ts +0 -44
  168. package/src/platform/response-renderer.ts +0 -84
  169. package/src/platform/unified-thread-consumer.ts +0 -187
  170. package/src/platform.ts +0 -318
  171. package/src/proxy/http-proxy.ts +0 -752
  172. package/src/proxy/proxy-manager.ts +0 -81
  173. package/src/proxy/secret-proxy.ts +0 -402
  174. package/src/proxy/token-refresh-job.ts +0 -143
  175. package/src/routes/internal/audio.ts +0 -141
  176. package/src/routes/internal/device-auth.ts +0 -652
  177. package/src/routes/internal/files.ts +0 -226
  178. package/src/routes/internal/history.ts +0 -69
  179. package/src/routes/internal/images.ts +0 -127
  180. package/src/routes/internal/interactions.ts +0 -84
  181. package/src/routes/internal/middleware.ts +0 -23
  182. package/src/routes/internal/schedule.ts +0 -226
  183. package/src/routes/internal/types.ts +0 -22
  184. package/src/routes/openapi-auto.ts +0 -239
  185. package/src/routes/public/agent-access.ts +0 -23
  186. package/src/routes/public/agent-config.ts +0 -675
  187. package/src/routes/public/agent-history.ts +0 -422
  188. package/src/routes/public/agent-schedules.ts +0 -296
  189. package/src/routes/public/agent.ts +0 -1086
  190. package/src/routes/public/agents.ts +0 -373
  191. package/src/routes/public/channels.ts +0 -191
  192. package/src/routes/public/cli-auth.ts +0 -896
  193. package/src/routes/public/connections.ts +0 -574
  194. package/src/routes/public/landing.ts +0 -16
  195. package/src/routes/public/oauth.ts +0 -147
  196. package/src/routes/public/settings-auth.ts +0 -104
  197. package/src/routes/public/slack.ts +0 -173
  198. package/src/routes/shared/agent-ownership.ts +0 -101
  199. package/src/routes/shared/token-verifier.ts +0 -34
  200. package/src/services/bedrock-model-catalog.ts +0 -217
  201. package/src/services/bedrock-openai-service.ts +0 -658
  202. package/src/services/core-services.ts +0 -1072
  203. package/src/services/image-generation-service.ts +0 -257
  204. package/src/services/instruction-service.ts +0 -318
  205. package/src/services/mcp-registry.ts +0 -94
  206. package/src/services/platform-helpers.ts +0 -287
  207. package/src/services/session-manager.ts +0 -262
  208. package/src/services/settings-resolver.ts +0 -74
  209. package/src/services/system-config-resolver.ts +0 -89
  210. package/src/services/system-skills-service.ts +0 -229
  211. package/src/services/transcription-service.ts +0 -684
  212. package/src/session.ts +0 -110
  213. package/src/spaces/index.ts +0 -1
  214. package/src/spaces/space-resolver.ts +0 -17
  215. package/src/stores/in-memory-agent-store.ts +0 -403
  216. package/src/stores/redis-agent-store.ts +0 -279
  217. package/src/utils/public-url.ts +0 -44
  218. package/src/utils/rate-limiter.ts +0 -94
  219. package/tsconfig.json +0 -33
@@ -1,201 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- import { createLogger } from "@lobu/core";
4
- import type { IMessageQueue } from "../infrastructure/queue";
5
- import type { ISessionManager } from "../session";
6
- import type { WorkerConnectionManager } from "./connection-manager";
7
-
8
- const logger = createLogger("worker-job-router");
9
-
10
- interface PendingJob {
11
- resolve: (value: unknown) => void;
12
- reject: (error: Error) => void;
13
- timeout: NodeJS.Timeout;
14
- jobId: string;
15
- }
16
-
17
- /**
18
- * Routes jobs from queues to workers via SSE connections
19
- * Manages job acknowledgments and timeouts
20
- */
21
- export class WorkerJobRouter {
22
- private pendingJobs: Map<string, PendingJob> = new Map(); // In-memory timeouts only
23
-
24
- constructor(
25
- private queue: IMessageQueue,
26
- private connectionManager: WorkerConnectionManager,
27
- _sessionManager: ISessionManager
28
- ) {}
29
-
30
- /**
31
- * Register a worker to receive jobs from its deployment queue
32
- * Each worker listens on its own queue: thread_message_{deploymentName}
33
- *
34
- * Note: This is idempotent - BullMQ's queue.work() handles duplicate registrations gracefully.
35
- * Safe to call multiple times (e.g., on worker reconnection or gateway restart).
36
- */
37
- async registerWorker(deploymentName: string): Promise<void> {
38
- const queueName = `thread_message_${deploymentName}`;
39
-
40
- // Create queue if it doesn't exist
41
- await this.queue.createQueue(queueName);
42
-
43
- // Register job handler (idempotent - BullMQ handles duplicates)
44
- // Start paused so jobs aren't consumed before the SSE connection is live.
45
- // The caller must call resumeWorker() after SSE connects.
46
- await this.queue.work(
47
- queueName,
48
- async (job: unknown) => {
49
- await this.handleJob(deploymentName, job);
50
- },
51
- { startPaused: true }
52
- );
53
-
54
- logger.info(`Registered worker for queue ${queueName}`);
55
- }
56
-
57
- /**
58
- * Pause the BullMQ worker when SSE connection is lost
59
- * This prevents jobs from being processed when worker can't receive them
60
- */
61
- async pauseWorker(deploymentName: string): Promise<void> {
62
- const queueName = `thread_message_${deploymentName}`;
63
- await this.queue.pauseWorker(queueName);
64
- logger.info(
65
- `Paused job processing for ${deploymentName} - worker disconnected`
66
- );
67
- }
68
-
69
- /**
70
- * Resume the BullMQ worker when SSE connection is established
71
- * Jobs will now be processed and sent to the worker
72
- */
73
- async resumeWorker(deploymentName: string): Promise<void> {
74
- const queueName = `thread_message_${deploymentName}`;
75
- await this.queue.resumeWorker(queueName);
76
- logger.info(
77
- `Resumed job processing for ${deploymentName} - worker connected`
78
- );
79
- }
80
-
81
- /**
82
- * Handle a job from the queue and route it to the worker.
83
- *
84
- * Sends the job via SSE and waits for a delivery receipt from the worker.
85
- * If the worker doesn't acknowledge within the timeout, the job is retried
86
- * by BullMQ. This prevents jobs from being silently lost when sent to a
87
- * stale SSE connection (e.g., after a container dies without cleanly closing TCP).
88
- */
89
- private async handleJob(deploymentName: string, job: unknown): Promise<void> {
90
- const connection = this.connectionManager.getConnection(deploymentName);
91
-
92
- if (!connection) {
93
- logger.warn(
94
- `No connection for deployment ${deploymentName}, job will be retried`
95
- );
96
- throw new Error("Worker not connected");
97
- }
98
-
99
- // Extract job data and ID
100
- const jobData = (job as { data?: unknown }).data;
101
- const jobId =
102
- (job as { id?: string }).id ||
103
- `job-${Date.now()}-${Math.random().toString(36).substring(7)}`;
104
-
105
- // Send job to worker via SSE with jobId wrapped in payload
106
- const jobPayload =
107
- typeof jobData === "object" && jobData !== null
108
- ? { payload: jobData, jobId: jobId }
109
- : { payload: { data: jobData }, jobId: jobId };
110
-
111
- const sent = this.connectionManager.sendSSE(
112
- connection.writer,
113
- "job",
114
- jobPayload
115
- );
116
- if (!sent) {
117
- logger.warn(
118
- `SSE write failed for job ${jobId} to ${deploymentName}, will retry`
119
- );
120
- throw new Error("SSE write failed - worker connection may be dead");
121
- }
122
- this.connectionManager.touchConnection(deploymentName);
123
-
124
- // Wait for delivery receipt from worker. If the SSE connection is stale
125
- // (container dead but TCP not yet closed), the worker will never ack and
126
- // BullMQ will retry the job after the timeout.
127
- await this.awaitDeliveryReceipt(jobId, deploymentName);
128
- }
129
-
130
- /**
131
- * Wait for the worker to acknowledge receipt of a job.
132
- * Rejects after timeout so BullMQ retries the job.
133
- */
134
- private awaitDeliveryReceipt(
135
- jobId: string,
136
- deploymentName: string
137
- ): Promise<void> {
138
- return new Promise<void>((resolve, reject) => {
139
- const timeout = setTimeout(() => {
140
- this.pendingJobs.delete(jobId);
141
- logger.warn(
142
- `Job ${jobId} delivery receipt timeout - worker ${deploymentName} may be dead`
143
- );
144
- reject(
145
- new Error(
146
- `Delivery receipt timeout for job ${jobId} - worker may be dead`
147
- )
148
- );
149
- }, 5000); // 5 second timeout for delivery receipt
150
-
151
- this.pendingJobs.set(jobId, {
152
- resolve: () => {
153
- clearTimeout(timeout);
154
- resolve();
155
- },
156
- reject: (err: Error) => {
157
- clearTimeout(timeout);
158
- reject(err);
159
- },
160
- timeout,
161
- jobId,
162
- });
163
- });
164
- }
165
-
166
- /**
167
- * Acknowledge job completion from worker
168
- * Called when worker sends HTTP response
169
- */
170
- acknowledgeJob(jobId: string): void {
171
- const pendingJob = this.pendingJobs.get(jobId);
172
- if (pendingJob) {
173
- clearTimeout(pendingJob.timeout);
174
- pendingJob.resolve(undefined);
175
- this.pendingJobs.delete(jobId);
176
- logger.debug(`Job ${jobId} acknowledged`);
177
- } else {
178
- logger.warn(`Received acknowledgment for unknown job ${jobId}`);
179
- }
180
- }
181
-
182
- /**
183
- * Get number of pending jobs
184
- */
185
- getPendingJobCount(): number {
186
- return this.pendingJobs.size;
187
- }
188
-
189
- /**
190
- * Shutdown job router
191
- */
192
- shutdown(): void {
193
- // Reject all pending jobs
194
- for (const [jobId, pendingJob] of this.pendingJobs.entries()) {
195
- clearTimeout(pendingJob.timeout);
196
- pendingJob.reject(new Error("Job router shutting down"));
197
- logger.debug(`Rejected pending job ${jobId} due to shutdown`);
198
- }
199
- this.pendingJobs.clear();
200
- }
201
- }
@@ -1,200 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- import {
4
- type AgentAccessStore,
5
- type AgentConfigStore,
6
- type AgentConnectionStore,
7
- createLogger,
8
- type SystemSkillEntry,
9
- } from "@lobu/core";
10
- import type { GatewayConfig } from "./config";
11
- import { type PlatformAdapter, platformRegistry } from "./platform";
12
- import { UnifiedThreadResponseConsumer } from "./platform/unified-thread-consumer";
13
- import { CoreServices } from "./services/core-services";
14
-
15
- const logger = createLogger("gateway");
16
-
17
- /**
18
- * Main Gateway class that orchestrates all platform adapters
19
- *
20
- * Architecture:
21
- * - CoreServices: Platform-agnostic services (Redis, MCP, Anthropic)
22
- * - PlatformAdapters: Platform-specific integrations (Slack, Discord, etc.)
23
- *
24
- * Lifecycle:
25
- * 1. Gateway initializes CoreServices
26
- * 2. Platforms register themselves via registerPlatform()
27
- * 3. Gateway calls initialize() on each platform with CoreServices
28
- * 4. Gateway calls start() on each platform
29
- */
30
- export interface GatewayOptions {
31
- /** Agent settings + metadata store. Defaults to InMemoryAgentStore. */
32
- configStore?: AgentConfigStore;
33
- /** Connections + channel bindings store. Defaults to InMemoryAgentStore. */
34
- connectionStore?: AgentConnectionStore;
35
- /** Grants + user-agent associations store. Defaults to InMemoryAgentStore. */
36
- accessStore?: AgentAccessStore;
37
- /** Provide system skills programmatically (skips file loading). */
38
- systemSkills?: SystemSkillEntry[];
39
- }
40
-
41
- export class Gateway {
42
- private coreServices: CoreServices;
43
- private platforms: Map<string, PlatformAdapter> = new Map();
44
- private unifiedConsumer?: UnifiedThreadResponseConsumer;
45
- private isRunning = false;
46
-
47
- constructor(
48
- private readonly config: GatewayConfig,
49
- options?: GatewayOptions
50
- ) {
51
- this.coreServices = new CoreServices(config, {
52
- configStore: options?.configStore,
53
- connectionStore: options?.connectionStore,
54
- accessStore: options?.accessStore,
55
- systemSkills: options?.systemSkills,
56
- });
57
- }
58
-
59
- /**
60
- * Register a platform adapter
61
- * Platforms register themselves via dependency injection
62
- *
63
- * @param platform - Platform adapter to register
64
- * @returns This gateway for chaining
65
- */
66
- registerPlatform(platform: PlatformAdapter): this {
67
- if (this.platforms.has(platform.name)) {
68
- throw new Error(`Platform ${platform.name} is already registered`);
69
- }
70
-
71
- this.platforms.set(platform.name, platform);
72
- // Also register in global platform registry for deployment managers
73
- platformRegistry.register(platform);
74
- logger.debug(`Platform registered: ${platform.name}`);
75
- return this;
76
- }
77
-
78
- /**
79
- * Start the gateway
80
- * 1. Initialize core services
81
- * 2. Initialize all platforms
82
- * 3. Register instruction providers from platforms
83
- * 4. Start all platforms
84
- */
85
- async start(): Promise<void> {
86
- logger.debug("Starting gateway...");
87
-
88
- // 1. Initialize core services (Redis, MCP, Anthropic, etc.)
89
- await this.coreServices.initialize();
90
-
91
- // 2. Initialize each platform with core services
92
- for (const [name, platform] of this.platforms) {
93
- logger.debug(`Initializing platform: ${name}`);
94
- await platform.initialize(this.coreServices);
95
- }
96
-
97
- // 3. Register instruction providers from platforms
98
- const instructionService = this.coreServices.getInstructionService();
99
- if (instructionService) {
100
- for (const [name, platform] of this.platforms) {
101
- if (platform.getInstructionProvider) {
102
- const provider = platform.getInstructionProvider();
103
- if (provider) {
104
- instructionService.registerPlatformProvider(name, provider);
105
- }
106
- }
107
- }
108
- }
109
-
110
- // 4. Start all platforms
111
- for (const [name, platform] of this.platforms) {
112
- logger.debug(`Starting platform: ${name}`);
113
- await platform.start();
114
- }
115
-
116
- // 5. Start unified thread response consumer
117
- // Single consumer routes responses to platforms via registry
118
- this.unifiedConsumer = new UnifiedThreadResponseConsumer(
119
- this.coreServices.getQueue(),
120
- platformRegistry
121
- );
122
- await this.unifiedConsumer.start();
123
-
124
- this.isRunning = true;
125
- }
126
-
127
- /**
128
- * Stop the gateway gracefully
129
- * 1. Stop unified consumer if running
130
- * 2. Stop all platforms
131
- * 3. Shutdown core services
132
- */
133
- async stop(): Promise<void> {
134
- logger.info("Stopping gateway...");
135
-
136
- // Stop unified consumer if running
137
- if (this.unifiedConsumer) {
138
- logger.info("Stopping unified thread response consumer");
139
- try {
140
- await this.unifiedConsumer.stop();
141
- } catch (error) {
142
- logger.error("Failed to stop unified consumer:", error);
143
- }
144
- }
145
-
146
- // Stop all platforms
147
- for (const [name, platform] of this.platforms) {
148
- logger.info(`Stopping platform: ${name}`);
149
- try {
150
- await platform.stop();
151
- } catch (error) {
152
- logger.error(`Failed to stop platform ${name}:`, error);
153
- }
154
- }
155
-
156
- // Shutdown core services
157
- await this.coreServices.shutdown();
158
-
159
- this.isRunning = false;
160
- logger.info("✅ Gateway stopped");
161
- }
162
-
163
- /**
164
- * Get gateway status
165
- */
166
- getStatus(): {
167
- isRunning: boolean;
168
- platforms: string[];
169
- config: Partial<GatewayConfig>;
170
- } {
171
- return {
172
- isRunning: this.isRunning,
173
- platforms: Array.from(this.platforms.keys()),
174
- config: {
175
- queues: this.config.queues,
176
- },
177
- };
178
- }
179
-
180
- /**
181
- * Get core services (for platform adapters during initialization)
182
- */
183
- getCoreServices(): CoreServices {
184
- return this.coreServices;
185
- }
186
-
187
- /**
188
- * Get platform registry (for routes that need to access platform adapters)
189
- */
190
- getPlatformRegistry() {
191
- return platformRegistry;
192
- }
193
-
194
- /**
195
- * Get unified thread response consumer (for wiring Chat SDK response bridge)
196
- */
197
- getUnifiedConsumer() {
198
- return this.unifiedConsumer;
199
- }
200
- }
package/src/index.ts DELETED
@@ -1,41 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- /**
4
- * Main entry point for Lobu Gateway
5
- *
6
- * When run directly (CLI mode): starts the gateway server.
7
- * When imported as a library (embedded mode): exports Gateway, config builders,
8
- * and the Hono app factory for mounting on a host server.
9
- */
10
-
11
- // ── Primary API ─────────────────────────────────────────────────────────────
12
-
13
- export { Lobu, type LobuAgentConfig, type LobuConfig } from "./lobu";
14
-
15
- // ── Advanced (for custom setups) ────────────────────────────────────────────
16
-
17
- export { createGatewayApp, startGatewayServer } from "./cli/gateway";
18
- export {
19
- type AgentConfig,
20
- buildGatewayConfig,
21
- type GatewayConfig,
22
- } from "./config";
23
- export { Gateway, type GatewayOptions } from "./gateway-main";
24
- export { CoreServices } from "./services/core-services";
25
- export { InMemoryAgentStore } from "./stores/in-memory-agent-store";
26
-
27
- // ── Types ───────────────────────────────────────────────────────────────────
28
-
29
- export type {
30
- AgentAccessStore,
31
- AgentConfigStore,
32
- AgentConnectionStore,
33
- AgentMetadata,
34
- AgentSettings,
35
- AgentStore,
36
- } from "@lobu/core";
37
-
38
- // ── CLI mode (run directly, not when imported as library) ───────────────────
39
- if (require.main === module) {
40
- import("./cli");
41
- }
@@ -1,12 +0,0 @@
1
- /**
2
- * Queue infrastructure
3
- * Redis-based message queue using BullMQ
4
- */
5
-
6
- export { QueueProducer } from "./queue-producer";
7
- export { RedisQueue, type RedisQueueConfig } from "./redis-queue";
8
- export type {
9
- IMessageQueue,
10
- QueueJob,
11
- ThreadResponsePayload,
12
- } from "./types";
@@ -1,148 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- import {
4
- type AgentMcpConfig,
5
- createLogger,
6
- type NetworkConfig,
7
- type NixConfig,
8
- } from "@lobu/core";
9
- import type { IMessageQueue } from "./types";
10
-
11
- const logger = createLogger("queue-producer");
12
-
13
- /**
14
- * Job type for queue messages
15
- * - message: Standard agent message execution
16
- * - exec: Direct command execution in sandbox
17
- */
18
- export type JobType = "message" | "exec";
19
-
20
- /**
21
- * Universal message payload for all queue stages
22
- * Used by: Slack events → Queue → Message Consumer → Job Router → Worker
23
- */
24
- export interface MessagePayload {
25
- // Core identifiers (used by gateway for routing)
26
- userId: string; // Platform user ID
27
- conversationId: string; // Conversation ID (must be root conversation ID)
28
- messageId: string; // Individual message ID
29
- channelId: string; // Platform channel ID
30
- teamId: string; // Team/workspace ID (required for all platforms)
31
- agentId: string; // Agent/session ID for isolation (universal identifier)
32
-
33
- // Bot & platform info (passed through to worker)
34
- botId: string; // Bot identifier
35
- platform: string; // Platform name
36
-
37
- // Message content (used by worker)
38
- messageText: string; // The actual message text
39
-
40
- // Platform-specific data (used by worker for context)
41
- platformMetadata: Record<string, any>;
42
-
43
- // Agent configuration (used by worker)
44
- agentOptions: Record<string, any>;
45
-
46
- // Per-agent network configuration for sandbox isolation
47
- networkConfig?: NetworkConfig;
48
-
49
- // Per-agent MCP configuration (additive to global MCPs)
50
- mcpConfig?: AgentMcpConfig;
51
-
52
- // Nix environment configuration for agent workspace
53
- nixConfig?: NixConfig;
54
-
55
- // Job type (default: "message")
56
- jobType?: JobType;
57
-
58
- // Exec-specific fields (only used when jobType === "exec")
59
- execId?: string; // Unique ID for exec job (for response routing)
60
- execCommand?: string; // Command to execute
61
- execCwd?: string; // Working directory for command
62
- execEnv?: Record<string, string>; // Additional environment variables
63
- execTimeout?: number; // Timeout in milliseconds
64
- }
65
-
66
- /**
67
- * Queue producer for dispatching messages to Redis queues
68
- * Handles both direct_message and thread_message queues with bot isolation
69
- */
70
- export class QueueProducer {
71
- private queue: IMessageQueue;
72
- private isInitialized = false;
73
-
74
- constructor(queue: IMessageQueue) {
75
- this.queue = queue;
76
- }
77
-
78
- /**
79
- * Initialize the queue producer
80
- * Creates required queues
81
- */
82
- async start(): Promise<void> {
83
- try {
84
- // Create the messages queue if it doesn't exist
85
- await this.queue.createQueue("messages");
86
- this.isInitialized = true;
87
- logger.debug("Queue producer initialized");
88
- } catch (error) {
89
- logger.error("Failed to initialize queue producer:", error);
90
- throw error;
91
- }
92
- }
93
-
94
- /**
95
- * Stop the queue producer (no-op since queue lifecycle is managed externally)
96
- */
97
- async stop(): Promise<void> {
98
- this.isInitialized = false;
99
- logger.debug("Queue producer stopped");
100
- }
101
-
102
- /**
103
- * Enqueue any message (direct or thread) to the single 'messages' queue
104
- * Orchestrator will determine if it needs to create a deployment or route to existing thread
105
- */
106
- async enqueueMessage(
107
- payload: MessagePayload,
108
- options?: {
109
- priority?: number;
110
- retryLimit?: number;
111
- retryDelay?: number;
112
- expireInSeconds?: number;
113
- }
114
- ): Promise<string> {
115
- if (!this.isInitialized) {
116
- throw new Error("Queue producer is not initialized");
117
- }
118
-
119
- try {
120
- // All messages go to the single 'messages' queue
121
- const jobId = await this.queue.send("messages", payload, {
122
- priority: options?.priority || 0,
123
- retryLimit: options?.retryLimit || 3,
124
- retryDelay: options?.retryDelay || 30,
125
- expireInSeconds: options?.expireInSeconds || 300, // 5 minutes = 300 seconds
126
- singletonKey: `message-${payload.platform}-${payload.channelId}-${payload.conversationId}-${String(payload.messageId || Date.now()).replace(/:/g, "-")}`, // Prevent duplicates within canonical conversation identity
127
- });
128
-
129
- logger.info(
130
- `Enqueued message job ${jobId} for user ${payload.userId}, conversation ${payload.conversationId}`
131
- );
132
- return jobId || "job-sent";
133
- } catch (error) {
134
- logger.error(
135
- `Failed to enqueue message for user ${payload.userId}:`,
136
- error
137
- );
138
- throw error;
139
- }
140
- }
141
-
142
- /**
143
- * Check if producer is initialized
144
- */
145
- isHealthy(): boolean {
146
- return this.isInitialized && this.queue.isHealthy();
147
- }
148
- }