@lobu/gateway 3.0.8 → 3.0.9
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/dist/api/platform.d.ts.map +1 -1
- package/dist/api/platform.js +1 -0
- package/dist/api/platform.js.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/connections/interaction-bridge.d.ts.map +1 -1
- package/dist/connections/interaction-bridge.js +57 -15
- package/dist/connections/interaction-bridge.js.map +1 -1
- package/dist/connections/message-handler-bridge.d.ts.map +1 -1
- package/dist/connections/message-handler-bridge.js +44 -26
- package/dist/connections/message-handler-bridge.js.map +1 -1
- package/dist/orchestration/base-deployment-manager.js +7 -7
- package/dist/orchestration/base-deployment-manager.js.map +1 -1
- package/dist/platform/unified-thread-consumer.d.ts.map +1 -1
- package/dist/platform/unified-thread-consumer.js +38 -34
- package/dist/platform/unified-thread-consumer.js.map +1 -1
- package/package.json +10 -10
- package/src/cli/index.ts +2 -2
- package/src/connections/message-handler-bridge.ts +76 -51
- package/src/orchestration/base-deployment-manager.ts +7 -7
- package/src/platform/unified-thread-consumer.ts +49 -42
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -49,53 +49,57 @@ class UnifiedThreadResponseConsumer {
|
|
|
49
49
|
* Handle a thread response job by routing to the appropriate platform renderer.
|
|
50
50
|
*/
|
|
51
51
|
async handleThreadResponse(job) {
|
|
52
|
-
var _a, _b;
|
|
52
|
+
var _a, _b, _c;
|
|
53
53
|
const data = job.data;
|
|
54
54
|
if (!data || !data.messageId) {
|
|
55
55
|
logger.error(`Invalid thread response data: ${JSON.stringify(data)}`);
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
// Create child span for response processing (linked to original trace)
|
|
59
|
+
const traceparent = (_a = data.platformMetadata) === null || _a === void 0 ? void 0 : _a.traceparent;
|
|
60
|
+
const span = (0, core_1.createChildSpan)("response_delivery", traceparent, {
|
|
61
|
+
"lobu.message_id": data.messageId,
|
|
62
|
+
"lobu.user_id": data.userId,
|
|
63
|
+
"lobu.platform": data.platform || data.teamId || "unknown",
|
|
64
|
+
});
|
|
65
|
+
try {
|
|
66
|
+
// Check if this response belongs to a Chat SDK connection — handle before legacy routing
|
|
67
|
+
if ((_b = this.chatResponseBridge) === null || _b === void 0 ? void 0 : _b.canHandle(data)) {
|
|
68
|
+
const sessionKey = `${data.userId}:${data.originalMessageId || data.messageId}`;
|
|
62
69
|
await this.routeToRenderer(this.chatResponseBridge, data, sessionKey);
|
|
70
|
+
return;
|
|
63
71
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
72
|
+
// Use platform field, fall back to teamId
|
|
73
|
+
const platformName = data.platform || data.teamId;
|
|
74
|
+
if (!platformName) {
|
|
75
|
+
logger.warn(`Missing platform in thread response for message ${data.messageId}, skipping`);
|
|
76
|
+
return;
|
|
67
77
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const renderer = (_b = platform.getResponseRenderer) === null || _b === void 0 ? void 0 : _b.call(platform);
|
|
84
|
-
if (!renderer) {
|
|
85
|
-
logger.warn(`Platform ${platformName} does not provide a response renderer, skipping message ${data.messageId}`);
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
// Create session key for tracking
|
|
89
|
-
const sessionKey = `${data.userId}:${data.originalMessageId || data.messageId}`;
|
|
90
|
-
logger.info(`Processing thread response for platform=${platformName}, message=${data.messageId}, session=${sessionKey}`);
|
|
91
|
-
try {
|
|
78
|
+
// Get platform adapter from registry
|
|
79
|
+
const platform = this.platformRegistry.get(platformName);
|
|
80
|
+
if (!platform) {
|
|
81
|
+
logger.warn(`No platform adapter registered for: ${platformName}, skipping message ${data.messageId}`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// Get renderer from platform
|
|
85
|
+
const renderer = (_c = platform.getResponseRenderer) === null || _c === void 0 ? void 0 : _c.call(platform);
|
|
86
|
+
if (!renderer) {
|
|
87
|
+
logger.warn(`Platform ${platformName} does not provide a response renderer, skipping message ${data.messageId}`);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
// Create session key for tracking
|
|
91
|
+
const sessionKey = `${data.userId}:${data.originalMessageId || data.messageId}`;
|
|
92
|
+
logger.info(`Processing thread response for platform=${platformName}, message=${data.messageId}, session=${sessionKey}`);
|
|
92
93
|
await this.routeToRenderer(renderer, data, sessionKey);
|
|
93
94
|
}
|
|
94
95
|
catch (error) {
|
|
95
|
-
logger.error(`Error processing thread response for ${
|
|
96
|
-
// Let queue handle retry logic
|
|
96
|
+
logger.error(`Error processing thread response for message ${data.messageId}:`, error);
|
|
97
97
|
throw error;
|
|
98
98
|
}
|
|
99
|
+
finally {
|
|
100
|
+
span === null || span === void 0 ? void 0 : span.end();
|
|
101
|
+
void (0, core_1.flushTracing)();
|
|
102
|
+
}
|
|
99
103
|
}
|
|
100
104
|
/**
|
|
101
105
|
* Route the payload to the appropriate renderer method.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unified-thread-consumer.js","sourceRoot":"","sources":["../../src/platform/unified-thread-consumer.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,
|
|
1
|
+
{"version":3,"file":"unified-thread-consumer.js","sourceRoot":"","sources":["../../src/platform/unified-thread-consumer.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobu/gateway",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.9",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Lobu SDK — embed AI agents with platform adapters, worker orchestration, and MCP proxy",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -22,13 +22,6 @@
|
|
|
22
22
|
"require": "./dist/api/index.js"
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
|
-
"scripts": {
|
|
26
|
-
"build": "tsc",
|
|
27
|
-
"dev": "DEPLOYMENT_MODE=docker bun --watch src/index.ts -- --env ../../.env",
|
|
28
|
-
"start": "cd ../core && bun run build && cd ../gateway && bun src/index.ts",
|
|
29
|
-
"test": "bun test",
|
|
30
|
-
"typecheck": "tsc --noEmit"
|
|
31
|
-
},
|
|
32
25
|
"dependencies": {
|
|
33
26
|
"@aws-sdk/client-bedrock": "^3.1028.0",
|
|
34
27
|
"@chat-adapter/discord": "^4",
|
|
@@ -41,7 +34,7 @@
|
|
|
41
34
|
"@hono/node-server": "^1.19.9",
|
|
42
35
|
"@hono/zod-openapi": "^1.2.1",
|
|
43
36
|
"@kubernetes/client-node": "0.21.0",
|
|
44
|
-
"@lobu/core": "
|
|
37
|
+
"@lobu/core": "^3.0.5",
|
|
45
38
|
"@mariozechner/pi-ai": "^0.51.6",
|
|
46
39
|
"@scalar/hono-api-reference": "^0.9.39",
|
|
47
40
|
"@sentry/node": "^10.19.0",
|
|
@@ -61,5 +54,12 @@
|
|
|
61
54
|
"@types/dockerode": "^3.3.29",
|
|
62
55
|
"@types/node": "^20.0.0",
|
|
63
56
|
"typescript": "^5.8.3"
|
|
57
|
+
},
|
|
58
|
+
"scripts": {
|
|
59
|
+
"build": "tsc",
|
|
60
|
+
"dev": "DEPLOYMENT_MODE=docker bun --watch src/index.ts -- --env ../../.env",
|
|
61
|
+
"start": "cd ../core && bun run build && cd ../gateway && bun src/index.ts",
|
|
62
|
+
"test": "bun test",
|
|
63
|
+
"typecheck": "tsc --noEmit"
|
|
64
64
|
}
|
|
65
|
-
}
|
|
65
|
+
}
|
package/src/cli/index.ts
CHANGED
|
@@ -34,8 +34,8 @@ async function main() {
|
|
|
34
34
|
initTracing({
|
|
35
35
|
serviceName: "lobu-gateway",
|
|
36
36
|
serviceVersion: process.env.npm_package_version || "2.0.0",
|
|
37
|
-
|
|
38
|
-
enabled: !!process.env.
|
|
37
|
+
otlpEndpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
|
|
38
|
+
enabled: !!process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
const config = buildGatewayConfig();
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
* settings links, allowlist, audio transcription, etc.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
createLogger,
|
|
9
|
+
createRootSpan,
|
|
10
|
+
flushTracing,
|
|
11
|
+
generateTraceId,
|
|
12
|
+
} from "@lobu/core";
|
|
8
13
|
import type Redis from "ioredis";
|
|
9
14
|
import type { CommandDispatcher } from "../commands/command-dispatcher";
|
|
10
15
|
import { createChatReply } from "../commands/command-reply-adapters";
|
|
@@ -290,62 +295,82 @@ class MessageHandlerBridge {
|
|
|
290
295
|
const traceId = generateTraceId(messageId);
|
|
291
296
|
const agentSettingsStore = this.services.getAgentSettingsStore();
|
|
292
297
|
|
|
293
|
-
//
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
}
|
|
298
|
+
// Create root span for distributed tracing
|
|
299
|
+
const { span: rootSpan, traceparent } = createRootSpan("message_received", {
|
|
300
|
+
"lobu.agent_id": agentId,
|
|
301
|
+
"lobu.message_id": messageId,
|
|
302
|
+
"lobu.platform": platform,
|
|
303
|
+
"lobu.connection_id": this.connection.id,
|
|
304
|
+
});
|
|
300
305
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
{
|
|
304
|
-
|
|
305
|
-
|
|
306
|
+
try {
|
|
307
|
+
// Check if agent has any provider credentials before enqueuing
|
|
308
|
+
if (!(await hasConfiguredProvider(agentId, agentSettingsStore))) {
|
|
309
|
+
await thread.post(
|
|
310
|
+
"No AI provider is configured yet. Provider setup is not available in the end-user chat flow yet. Ask an admin to connect a provider for the base agent."
|
|
311
|
+
);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
306
314
|
|
|
307
|
-
|
|
308
|
-
platform,
|
|
309
|
-
userId,
|
|
310
|
-
botId: platform,
|
|
311
|
-
conversationId: isGroup ? messageId : channelId,
|
|
312
|
-
teamId: isGroup ? channelId : platform,
|
|
313
|
-
agentId,
|
|
314
|
-
messageId,
|
|
315
|
-
messageText,
|
|
316
|
-
channelId,
|
|
317
|
-
platformMetadata: {
|
|
318
|
-
traceId,
|
|
315
|
+
const agentOptions = await resolveAgentOptions(
|
|
319
316
|
agentId,
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
senderDisplayName: message.author?.fullName,
|
|
324
|
-
isGroup,
|
|
325
|
-
connectionId: this.connection.id,
|
|
326
|
-
responseChannel: channelId,
|
|
327
|
-
responseId: messageId,
|
|
328
|
-
responseThreadId: thread.id,
|
|
329
|
-
conversationHistory:
|
|
330
|
-
conversationHistory.length > 0 ? conversationHistory : undefined,
|
|
331
|
-
...(sessionReset && { sessionReset: true }),
|
|
332
|
-
},
|
|
333
|
-
agentOptions,
|
|
334
|
-
});
|
|
317
|
+
{},
|
|
318
|
+
agentSettingsStore
|
|
319
|
+
);
|
|
335
320
|
|
|
336
|
-
|
|
337
|
-
|
|
321
|
+
const payload = buildMessagePayload({
|
|
322
|
+
platform,
|
|
323
|
+
userId,
|
|
324
|
+
botId: platform,
|
|
325
|
+
conversationId: isGroup ? messageId : channelId,
|
|
326
|
+
teamId: isGroup ? channelId : platform,
|
|
327
|
+
agentId,
|
|
328
|
+
messageId,
|
|
329
|
+
messageText,
|
|
330
|
+
channelId,
|
|
331
|
+
platformMetadata: {
|
|
332
|
+
traceId,
|
|
333
|
+
traceparent: traceparent || undefined,
|
|
334
|
+
agentId,
|
|
335
|
+
chatId: channelId,
|
|
336
|
+
senderId: userId,
|
|
337
|
+
senderUsername: message.author?.userName,
|
|
338
|
+
senderDisplayName: message.author?.fullName,
|
|
339
|
+
isGroup,
|
|
340
|
+
connectionId: this.connection.id,
|
|
341
|
+
responseChannel: channelId,
|
|
342
|
+
responseId: messageId,
|
|
343
|
+
responseThreadId: thread.id,
|
|
344
|
+
conversationHistory:
|
|
345
|
+
conversationHistory.length > 0 ? conversationHistory : undefined,
|
|
346
|
+
...(sessionReset && { sessionReset: true }),
|
|
347
|
+
},
|
|
348
|
+
agentOptions,
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
const queueProducer = this.services.getQueueProducer();
|
|
352
|
+
await queueProducer.enqueueMessage(payload);
|
|
338
353
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
354
|
+
logger.info(
|
|
355
|
+
{
|
|
356
|
+
traceId,
|
|
357
|
+
traceparent,
|
|
358
|
+
messageId,
|
|
359
|
+
agentId,
|
|
360
|
+
connectionId: this.connection.id,
|
|
361
|
+
},
|
|
362
|
+
"Message enqueued via Chat SDK bridge"
|
|
363
|
+
);
|
|
343
364
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
365
|
+
// Show typing indicator
|
|
366
|
+
try {
|
|
367
|
+
await thread.startTyping?.("Processing...");
|
|
368
|
+
} catch {
|
|
369
|
+
// best effort
|
|
370
|
+
}
|
|
371
|
+
} finally {
|
|
372
|
+
rootSpan?.end();
|
|
373
|
+
void flushTracing();
|
|
349
374
|
}
|
|
350
375
|
}
|
|
351
376
|
|
|
@@ -480,15 +480,15 @@ export abstract class BaseDeploymentManager {
|
|
|
480
480
|
envVars.TRACE_ID = traceId;
|
|
481
481
|
}
|
|
482
482
|
|
|
483
|
-
// Add
|
|
484
|
-
const
|
|
485
|
-
if (
|
|
486
|
-
envVars.
|
|
483
|
+
// Add OTLP endpoint for distributed tracing
|
|
484
|
+
const otlpEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
485
|
+
if (otlpEndpoint) {
|
|
486
|
+
envVars.OTEL_EXPORTER_OTLP_ENDPOINT = otlpEndpoint;
|
|
487
487
|
try {
|
|
488
|
-
const
|
|
489
|
-
envVars.NO_PROXY = `${envVars.NO_PROXY},${
|
|
488
|
+
const otlpUrl = new URL(otlpEndpoint);
|
|
489
|
+
envVars.NO_PROXY = `${envVars.NO_PROXY},${otlpUrl.hostname}`;
|
|
490
490
|
} catch {
|
|
491
|
-
envVars.NO_PROXY = `${envVars.NO_PROXY},
|
|
491
|
+
envVars.NO_PROXY = `${envVars.NO_PROXY},tempo`;
|
|
492
492
|
}
|
|
493
493
|
}
|
|
494
494
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* via the PlatformRegistry, eliminating duplicate queue filtering logic.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { createLogger } from "@lobu/core";
|
|
7
|
+
import { createChildSpan, createLogger, flushTracing } from "@lobu/core";
|
|
8
8
|
import type { ChatResponseBridge } from "../connections/chat-response-bridge";
|
|
9
9
|
import type {
|
|
10
10
|
IMessageQueue,
|
|
@@ -77,61 +77,68 @@ export class UnifiedThreadResponseConsumer {
|
|
|
77
77
|
return;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
// Create child span for response processing (linked to original trace)
|
|
81
|
+
const traceparent = data.platformMetadata?.traceparent as
|
|
82
|
+
| string
|
|
83
|
+
| undefined;
|
|
84
|
+
const span = createChildSpan("response_delivery", traceparent, {
|
|
85
|
+
"lobu.message_id": data.messageId,
|
|
86
|
+
"lobu.user_id": data.userId,
|
|
87
|
+
"lobu.platform": data.platform || data.teamId || "unknown",
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
// Check if this response belongs to a Chat SDK connection — handle before legacy routing
|
|
92
|
+
if (this.chatResponseBridge?.canHandle(data)) {
|
|
93
|
+
const sessionKey = `${data.userId}:${data.originalMessageId || data.messageId}`;
|
|
84
94
|
await this.routeToRenderer(this.chatResponseBridge, data, sessionKey);
|
|
85
|
-
|
|
86
|
-
logger.error("Error processing Chat SDK response:", error);
|
|
87
|
-
throw error;
|
|
95
|
+
return;
|
|
88
96
|
}
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
97
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
// Use platform field, fall back to teamId
|
|
99
|
+
const platformName = data.platform || data.teamId;
|
|
100
|
+
if (!platformName) {
|
|
101
|
+
logger.warn(
|
|
102
|
+
`Missing platform in thread response for message ${data.messageId}, skipping`
|
|
103
|
+
);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
100
106
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
// Get platform adapter from registry
|
|
108
|
+
const platform = this.platformRegistry.get(platformName);
|
|
109
|
+
if (!platform) {
|
|
110
|
+
logger.warn(
|
|
111
|
+
`No platform adapter registered for: ${platformName}, skipping message ${data.messageId}`
|
|
112
|
+
);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
109
115
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
// Get renderer from platform
|
|
117
|
+
const renderer = platform.getResponseRenderer?.();
|
|
118
|
+
if (!renderer) {
|
|
119
|
+
logger.warn(
|
|
120
|
+
`Platform ${platformName} does not provide a response renderer, skipping message ${data.messageId}`
|
|
121
|
+
);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
118
124
|
|
|
119
|
-
|
|
120
|
-
|
|
125
|
+
// Create session key for tracking
|
|
126
|
+
const sessionKey = `${data.userId}:${data.originalMessageId || data.messageId}`;
|
|
121
127
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
128
|
+
logger.info(
|
|
129
|
+
`Processing thread response for platform=${platformName}, message=${data.messageId}, session=${sessionKey}`
|
|
130
|
+
);
|
|
125
131
|
|
|
126
|
-
try {
|
|
127
132
|
await this.routeToRenderer(renderer, data, sessionKey);
|
|
128
133
|
} catch (error) {
|
|
129
134
|
logger.error(
|
|
130
|
-
`Error processing thread response for ${
|
|
135
|
+
`Error processing thread response for message ${data.messageId}:`,
|
|
131
136
|
error
|
|
132
137
|
);
|
|
133
|
-
// Let queue handle retry logic
|
|
134
138
|
throw error;
|
|
139
|
+
} finally {
|
|
140
|
+
span?.end();
|
|
141
|
+
void flushTracing();
|
|
135
142
|
}
|
|
136
143
|
}
|
|
137
144
|
|