@automagik/omni 2.260906.2 → 2.260906.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.
- package/db/drizzle/0057_connector_lifecycle_contract.sql +40 -0
- package/db/drizzle/0058_omni_events_causation_id.sql +24 -0
- package/db/drizzle/meta/_journal.json +14 -0
- package/dist/commands/events.d.ts +14 -0
- package/dist/commands/events.d.ts.map +1 -1
- package/dist/commands/webhooks.d.ts.map +1 -1
- package/dist/index.js +410 -65
- package/dist/sdk/client.d.ts +21 -0
- package/dist/sdk/client.d.ts.map +1 -1
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +7 -0
- package/dist/sdk/types.generated.d.ts +376 -10
- package/dist/sdk/types.generated.d.ts.map +1 -1
- package/dist/server/index.js +760 -223
- package/package.json +1 -1
package/dist/server/index.js
CHANGED
|
@@ -207,6 +207,19 @@ var init_types2 = __esm(() => {
|
|
|
207
207
|
"flow.data_exchange"
|
|
208
208
|
];
|
|
209
209
|
});
|
|
210
|
+
// ../core/src/events/causality.ts
|
|
211
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
212
|
+
function runWithEventCausality(context2, fn) {
|
|
213
|
+
return storage.run(context2, fn);
|
|
214
|
+
}
|
|
215
|
+
function currentEventCausality() {
|
|
216
|
+
return storage.getStore();
|
|
217
|
+
}
|
|
218
|
+
var storage;
|
|
219
|
+
var init_causality = __esm(() => {
|
|
220
|
+
storage = new AsyncLocalStorage;
|
|
221
|
+
});
|
|
222
|
+
|
|
210
223
|
// ../core/src/events/envelope.ts
|
|
211
224
|
function classifyEnvelope(metadata) {
|
|
212
225
|
if (metadata === null || metadata === undefined)
|
|
@@ -18232,6 +18245,38 @@ var init_logger = __esm(() => {
|
|
|
18232
18245
|
rootLogger = createLogger("system");
|
|
18233
18246
|
});
|
|
18234
18247
|
|
|
18248
|
+
// ../core/src/events/factory.ts
|
|
18249
|
+
function createOmniEvent(type, payload, metadata, serviceName) {
|
|
18250
|
+
const eventId = crypto.randomUUID();
|
|
18251
|
+
const timestamp = Date.now();
|
|
18252
|
+
const tenantId = resolvePublishTenantId(metadata?.tenantId, metadata?.instanceId);
|
|
18253
|
+
const ambient = currentEventCausality();
|
|
18254
|
+
const causationId = metadata?.causationId ?? ambient?.causationId;
|
|
18255
|
+
return {
|
|
18256
|
+
id: eventId,
|
|
18257
|
+
type,
|
|
18258
|
+
payload,
|
|
18259
|
+
timestamp,
|
|
18260
|
+
metadata: {
|
|
18261
|
+
correlationId: metadata?.correlationId ?? ambient?.correlationId ?? eventId,
|
|
18262
|
+
...causationId ? { causationId } : {},
|
|
18263
|
+
instanceId: metadata?.instanceId,
|
|
18264
|
+
channelType: metadata?.channelType,
|
|
18265
|
+
personId: metadata?.personId,
|
|
18266
|
+
platformIdentityId: metadata?.platformIdentityId,
|
|
18267
|
+
traceId: metadata?.traceId ?? eventId,
|
|
18268
|
+
source: metadata?.source ?? serviceName,
|
|
18269
|
+
ingestMode: metadata?.ingestMode,
|
|
18270
|
+
timings: metadata?.timings,
|
|
18271
|
+
...tenantId ? { envelopeVersion: CURRENT_ENVELOPE_VERSION, tenantId } : {}
|
|
18272
|
+
}
|
|
18273
|
+
};
|
|
18274
|
+
}
|
|
18275
|
+
var init_factory = __esm(() => {
|
|
18276
|
+
init_causality();
|
|
18277
|
+
init_envelope();
|
|
18278
|
+
});
|
|
18279
|
+
|
|
18235
18280
|
// ../core/src/events/nats/streams.ts
|
|
18236
18281
|
function getStreamForEventType(eventType) {
|
|
18237
18282
|
const prefix = eventType.split(".")[0] ?? "";
|
|
@@ -22567,7 +22612,24 @@ var init_registry = __esm(() => {
|
|
|
22567
22612
|
component: exports_external.string(),
|
|
22568
22613
|
reason: exports_external.string(),
|
|
22569
22614
|
severity: exports_external.enum(["warning", "critical"])
|
|
22570
|
-
}), { description: "System health degradation detected" })
|
|
22615
|
+
}), { description: "System health degradation detected" }),
|
|
22616
|
+
connectorStalled: createEventSchema("system.connector.stalled", exports_external.object({
|
|
22617
|
+
sourceId: exports_external.string(),
|
|
22618
|
+
sourceName: exports_external.string(),
|
|
22619
|
+
expectedIntervalSeconds: exports_external.number(),
|
|
22620
|
+
lastReceivedAt: exports_external.number().nullable(),
|
|
22621
|
+
lastHeartbeatAt: exports_external.number().nullable(),
|
|
22622
|
+
silentForSeconds: exports_external.number(),
|
|
22623
|
+
stalledAt: exports_external.number()
|
|
22624
|
+
}), { description: "A supervised connector went silent beyond its declared cadence" }),
|
|
22625
|
+
connectorRecovered: createEventSchema("system.connector.recovered", exports_external.object({
|
|
22626
|
+
sourceId: exports_external.string(),
|
|
22627
|
+
sourceName: exports_external.string(),
|
|
22628
|
+
expectedIntervalSeconds: exports_external.number(),
|
|
22629
|
+
stalledForSeconds: exports_external.number(),
|
|
22630
|
+
recoveredBy: exports_external.enum(["event", "heartbeat", "rearmed"]),
|
|
22631
|
+
recoveredAt: exports_external.number()
|
|
22632
|
+
}), { description: "A stalled connector signalled again (event, heartbeat, or re-declared cadence)" })
|
|
22571
22633
|
};
|
|
22572
22634
|
CustomEventSchemas = {
|
|
22573
22635
|
chatUnreadUpdated: createEventSchema("custom.chat.unread-updated", exports_external.object({
|
|
@@ -22987,27 +23049,8 @@ class NatsEventBus {
|
|
|
22987
23049
|
}
|
|
22988
23050
|
async publishInternal(type, payload, metadata) {
|
|
22989
23051
|
await this.ensureConnected();
|
|
22990
|
-
const
|
|
22991
|
-
const
|
|
22992
|
-
const tenantId = resolvePublishTenantId(metadata?.tenantId, metadata?.instanceId);
|
|
22993
|
-
const event = {
|
|
22994
|
-
id: eventId,
|
|
22995
|
-
type,
|
|
22996
|
-
payload,
|
|
22997
|
-
timestamp,
|
|
22998
|
-
metadata: {
|
|
22999
|
-
correlationId: metadata?.correlationId ?? eventId,
|
|
23000
|
-
instanceId: metadata?.instanceId,
|
|
23001
|
-
channelType: metadata?.channelType,
|
|
23002
|
-
personId: metadata?.personId,
|
|
23003
|
-
platformIdentityId: metadata?.platformIdentityId,
|
|
23004
|
-
traceId: metadata?.traceId ?? eventId,
|
|
23005
|
-
source: metadata?.source ?? this.config.serviceName,
|
|
23006
|
-
ingestMode: metadata?.ingestMode,
|
|
23007
|
-
timings: metadata?.timings,
|
|
23008
|
-
...tenantId ? { envelopeVersion: CURRENT_ENVELOPE_VERSION, tenantId } : {}
|
|
23009
|
-
}
|
|
23010
|
-
};
|
|
23052
|
+
const event = createOmniEvent(type, payload, metadata, this.config.serviceName);
|
|
23053
|
+
const eventId = event.id;
|
|
23011
23054
|
let subject;
|
|
23012
23055
|
if (metadata?.channelType && metadata?.instanceId) {
|
|
23013
23056
|
subject = buildSubject(type, metadata.channelType, metadata.instanceId);
|
|
@@ -23283,7 +23326,7 @@ async function connectEventBus(config2) {
|
|
|
23283
23326
|
var import_api2, import_nats, log4, DEFAULTS, ENSURE_CONNECTED_WAIT_MS = 5000;
|
|
23284
23327
|
var init_client = __esm(() => {
|
|
23285
23328
|
init_logger();
|
|
23286
|
-
|
|
23329
|
+
init_factory();
|
|
23287
23330
|
init_consumer();
|
|
23288
23331
|
init_registry();
|
|
23289
23332
|
init_streams();
|
|
@@ -31276,6 +31319,7 @@ function estimateCompletion(progress) {
|
|
|
31276
31319
|
// ../core/src/events/index.ts
|
|
31277
31320
|
var init_events = __esm(() => {
|
|
31278
31321
|
init_types2();
|
|
31322
|
+
init_causality();
|
|
31279
31323
|
init_envelope();
|
|
31280
31324
|
init_nats();
|
|
31281
31325
|
init_dead_letter();
|
|
@@ -36955,13 +36999,7 @@ function resolveFollowUpValue(trimmed, followUp) {
|
|
|
36955
36999
|
return;
|
|
36956
37000
|
}
|
|
36957
37001
|
}
|
|
36958
|
-
function
|
|
36959
|
-
const trimmed = path.trim();
|
|
36960
|
-
if (!trimmed)
|
|
36961
|
-
return;
|
|
36962
|
-
const parts = trimmed.split(".");
|
|
36963
|
-
const root = parts[0] ?? "";
|
|
36964
|
-
const rest = parts.slice(1).join(".");
|
|
37002
|
+
function resolveSpecialValue(trimmed, root, rest, context2) {
|
|
36965
37003
|
if (context2.debounce) {
|
|
36966
37004
|
const debounceValue = resolveDebounceValue(trimmed, rest, context2.debounce);
|
|
36967
37005
|
if (debounceValue !== undefined)
|
|
@@ -36972,6 +37010,21 @@ function resolveTemplatePath(path, context2) {
|
|
|
36972
37010
|
if (followUpValue !== undefined)
|
|
36973
37011
|
return followUpValue;
|
|
36974
37012
|
}
|
|
37013
|
+
if (root === "event" && context2.event) {
|
|
37014
|
+
return rest ? getNestedValue(context2.event, rest) : context2.event;
|
|
37015
|
+
}
|
|
37016
|
+
return;
|
|
37017
|
+
}
|
|
37018
|
+
function resolveTemplatePath(path, context2) {
|
|
37019
|
+
const trimmed = path.trim();
|
|
37020
|
+
if (!trimmed)
|
|
37021
|
+
return;
|
|
37022
|
+
const parts = trimmed.split(".");
|
|
37023
|
+
const root = parts[0] ?? "";
|
|
37024
|
+
const rest = parts.slice(1).join(".");
|
|
37025
|
+
const specialValue = resolveSpecialValue(trimmed, root, rest, context2);
|
|
37026
|
+
if (specialValue !== undefined)
|
|
37027
|
+
return specialValue;
|
|
36975
37028
|
if (root === "payload")
|
|
36976
37029
|
return rest ? getNestedValue(context2.payload, rest) : context2.payload;
|
|
36977
37030
|
if (root === "env")
|
|
@@ -37053,7 +37106,9 @@ function createTemplateContext(payload, options = {}) {
|
|
|
37053
37106
|
variables: options.variables ?? {},
|
|
37054
37107
|
env: process.env,
|
|
37055
37108
|
debounce: options.debounce,
|
|
37056
|
-
followUp
|
|
37109
|
+
followUp,
|
|
37110
|
+
event: options.event,
|
|
37111
|
+
automation: options.automation
|
|
37057
37112
|
};
|
|
37058
37113
|
}
|
|
37059
37114
|
var TEMPLATE_REGEX;
|
|
@@ -37625,8 +37680,12 @@ var init_egress = __esm(() => {
|
|
|
37625
37680
|
});
|
|
37626
37681
|
|
|
37627
37682
|
// ../core/src/automations/actions.ts
|
|
37628
|
-
function buildWebhookHeaders(config2, context2) {
|
|
37683
|
+
function buildWebhookHeaders(config2, context2, actionIndex) {
|
|
37629
37684
|
const headers = { "Content-Type": "application/json" };
|
|
37685
|
+
if (context2.event) {
|
|
37686
|
+
headers["X-Omni-Event-Id"] = context2.event.id;
|
|
37687
|
+
headers["X-Omni-Delivery-Id"] = `${context2.event.id}:${context2.automation?.id ?? "manual"}:${actionIndex}`;
|
|
37688
|
+
}
|
|
37630
37689
|
if (config2.headers) {
|
|
37631
37690
|
for (const [key, value] of Object.entries(config2.headers)) {
|
|
37632
37691
|
headers[key] = substituteTemplate(value, context2);
|
|
@@ -37634,16 +37693,28 @@ function buildWebhookHeaders(config2, context2) {
|
|
|
37634
37693
|
}
|
|
37635
37694
|
return headers;
|
|
37636
37695
|
}
|
|
37696
|
+
function buildDefaultWebhookBody(config2, context2) {
|
|
37697
|
+
if (context2.event && config2.includeEnvelope !== false) {
|
|
37698
|
+
return JSON.stringify({
|
|
37699
|
+
id: context2.event.id,
|
|
37700
|
+
type: context2.event.type,
|
|
37701
|
+
payload: context2.payload,
|
|
37702
|
+
metadata: context2.event.metadata,
|
|
37703
|
+
timestamp: context2.event.timestamp
|
|
37704
|
+
});
|
|
37705
|
+
}
|
|
37706
|
+
return JSON.stringify(context2.payload);
|
|
37707
|
+
}
|
|
37637
37708
|
async function parseWebhookResponse(response) {
|
|
37638
37709
|
const contentType = response.headers.get("content-type") ?? "";
|
|
37639
37710
|
return contentType.includes("application/json") ? response.json() : response.text();
|
|
37640
37711
|
}
|
|
37641
|
-
async function executeWebhookAction(config2, context2, _deps, trustedTenantId) {
|
|
37712
|
+
async function executeWebhookAction(config2, context2, _deps, trustedTenantId, actionIndex = 0) {
|
|
37642
37713
|
try {
|
|
37643
37714
|
const url = substituteTemplate(config2.url, context2);
|
|
37644
37715
|
const method = config2.method ?? "POST";
|
|
37645
|
-
const headers = buildWebhookHeaders(config2, context2);
|
|
37646
|
-
const body = config2.bodyTemplate ? substituteTemplate(config2.bodyTemplate, context2) :
|
|
37716
|
+
const headers = buildWebhookHeaders(config2, context2, actionIndex);
|
|
37717
|
+
const body = config2.bodyTemplate ? substituteTemplate(config2.bodyTemplate, context2) : buildDefaultWebhookBody(config2, context2);
|
|
37647
37718
|
logger2.debug(`Webhook ${method} ${url}`, { method, url, waitForResponse: config2.waitForResponse });
|
|
37648
37719
|
const response = await brokeredFetch(url, {
|
|
37649
37720
|
method,
|
|
@@ -37733,8 +37804,10 @@ async function executeEmitEventAction(config2, context2, deps, trustedTenantId)
|
|
|
37733
37804
|
}
|
|
37734
37805
|
}
|
|
37735
37806
|
logger2.debug("Emitting event", { eventType });
|
|
37807
|
+
const correlationId = context2.event?.metadata.correlationId ?? context2.payload.correlationId ?? undefined;
|
|
37736
37808
|
const result = await deps.eventBus.publishGeneric(eventType, payload, {
|
|
37737
|
-
correlationId
|
|
37809
|
+
correlationId,
|
|
37810
|
+
causationId: context2.event?.id,
|
|
37738
37811
|
source: "automation",
|
|
37739
37812
|
...trustedTenantId ? { tenantId: trustedTenantId } : {}
|
|
37740
37813
|
});
|
|
@@ -37827,7 +37900,12 @@ function extractAgentCallContext(config2, context2) {
|
|
|
37827
37900
|
threadId,
|
|
37828
37901
|
senderId,
|
|
37829
37902
|
senderName,
|
|
37830
|
-
messages: messagesResult
|
|
37903
|
+
messages: messagesResult,
|
|
37904
|
+
event: context2.event ? {
|
|
37905
|
+
id: context2.event.id,
|
|
37906
|
+
type: context2.event.type,
|
|
37907
|
+
correlationId: context2.event.metadata.correlationId
|
|
37908
|
+
} : undefined
|
|
37831
37909
|
}
|
|
37832
37910
|
};
|
|
37833
37911
|
}
|
|
@@ -37868,12 +37946,12 @@ async function executeCallAgentAction(config2, context2, deps, trustedTenantId)
|
|
|
37868
37946
|
return { success: false, error: errorMessage };
|
|
37869
37947
|
}
|
|
37870
37948
|
}
|
|
37871
|
-
async function executeAction(action, context2, deps, trustedTenantId) {
|
|
37949
|
+
async function executeAction(action, context2, deps, trustedTenantId, actionIndex = 0) {
|
|
37872
37950
|
const start = Date.now();
|
|
37873
37951
|
let result;
|
|
37874
37952
|
switch (action.type) {
|
|
37875
37953
|
case "webhook":
|
|
37876
|
-
result = await executeWebhookAction(action.config, context2, deps, trustedTenantId);
|
|
37954
|
+
result = await executeWebhookAction(action.config, context2, deps, trustedTenantId, actionIndex);
|
|
37877
37955
|
break;
|
|
37878
37956
|
case "send_message":
|
|
37879
37957
|
result = await executeSendMessageAction(action.config, context2, deps, trustedTenantId);
|
|
@@ -37902,12 +37980,12 @@ async function executeAction(action, context2, deps, trustedTenantId) {
|
|
|
37902
37980
|
async function executeActions(actions, context2, deps, trustedTenantId) {
|
|
37903
37981
|
const results = [];
|
|
37904
37982
|
const variables = { ...context2.variables };
|
|
37905
|
-
for (const action of actions) {
|
|
37983
|
+
for (const [actionIndex, action] of actions.entries()) {
|
|
37906
37984
|
const actionContext = {
|
|
37907
37985
|
...context2,
|
|
37908
37986
|
variables
|
|
37909
37987
|
};
|
|
37910
|
-
const result = await executeAction(action, actionContext, deps, trustedTenantId);
|
|
37988
|
+
const result = await executeAction(action, actionContext, deps, trustedTenantId, actionIndex);
|
|
37911
37989
|
results.push(result);
|
|
37912
37990
|
if (action.type === "webhook" && action.config.responseAs && result.status === "success" && result.result) {
|
|
37913
37991
|
variables[action.config.responseAs] = result.result;
|
|
@@ -38337,13 +38415,18 @@ class AutomationEngine {
|
|
|
38337
38415
|
type: content?.type ?? "unknown",
|
|
38338
38416
|
text: content?.text,
|
|
38339
38417
|
timestamp: event.timestamp,
|
|
38340
|
-
payload
|
|
38418
|
+
payload,
|
|
38419
|
+
eventId: event.id,
|
|
38420
|
+
correlationId: event.metadata.correlationId
|
|
38341
38421
|
};
|
|
38342
38422
|
manager.addMessage(key, message2, from, instanceId, stamp);
|
|
38343
38423
|
}
|
|
38344
38424
|
async handleImmediate(automation, event) {
|
|
38345
38425
|
const instanceId = event.metadata.instanceId ?? "global";
|
|
38346
|
-
const context2 = createTemplateContext(event.payload
|
|
38426
|
+
const context2 = createTemplateContext(event.payload, {
|
|
38427
|
+
event: { id: event.id, type: event.type, timestamp: event.timestamp, metadata: event.metadata },
|
|
38428
|
+
automation: { id: automation.id }
|
|
38429
|
+
});
|
|
38347
38430
|
await this.queueExecution(automation, event, context2, instanceId);
|
|
38348
38431
|
}
|
|
38349
38432
|
setupDebounceManager(automation) {
|
|
@@ -38353,28 +38436,35 @@ class AutomationEngine {
|
|
|
38353
38436
|
logger4.warn("Debounce callback fired with empty messages array", { key });
|
|
38354
38437
|
return;
|
|
38355
38438
|
}
|
|
38356
|
-
const context2 = createTemplateContext(lastMessage.payload, {
|
|
38357
|
-
debounce: {
|
|
38358
|
-
messages: messages.map((m2) => ({
|
|
38359
|
-
type: m2.type,
|
|
38360
|
-
text: m2.text,
|
|
38361
|
-
timestamp: m2.timestamp
|
|
38362
|
-
})),
|
|
38363
|
-
from,
|
|
38364
|
-
instanceId
|
|
38365
|
-
}
|
|
38366
|
-
});
|
|
38367
38439
|
const syntheticEvent = {
|
|
38368
38440
|
id: generateId(),
|
|
38369
38441
|
type: automation.triggerEventType,
|
|
38370
38442
|
payload: lastMessage.payload,
|
|
38371
38443
|
metadata: {
|
|
38372
|
-
correlationId: generateId(),
|
|
38444
|
+
correlationId: lastMessage.correlationId ?? generateId(),
|
|
38373
38445
|
instanceId,
|
|
38374
38446
|
...stamp ? { envelopeVersion: stamp.envelopeVersion, tenantId: stamp.tenantId } : {}
|
|
38375
38447
|
},
|
|
38376
38448
|
timestamp: Date.now()
|
|
38377
38449
|
};
|
|
38450
|
+
const context2 = createTemplateContext(lastMessage.payload, {
|
|
38451
|
+
debounce: {
|
|
38452
|
+
messages: messages.map((m2) => ({
|
|
38453
|
+
type: m2.type,
|
|
38454
|
+
text: m2.text,
|
|
38455
|
+
timestamp: m2.timestamp
|
|
38456
|
+
})),
|
|
38457
|
+
from,
|
|
38458
|
+
instanceId
|
|
38459
|
+
},
|
|
38460
|
+
event: {
|
|
38461
|
+
id: lastMessage.eventId ?? syntheticEvent.id,
|
|
38462
|
+
type: syntheticEvent.type,
|
|
38463
|
+
timestamp: syntheticEvent.timestamp,
|
|
38464
|
+
metadata: syntheticEvent.metadata
|
|
38465
|
+
},
|
|
38466
|
+
automation: { id: automation.id }
|
|
38467
|
+
});
|
|
38378
38468
|
await this.queueExecution(automation, syntheticEvent, context2, instanceId);
|
|
38379
38469
|
};
|
|
38380
38470
|
const manager = new DebounceManager(automation.debounce, callback);
|
|
@@ -38462,7 +38552,10 @@ class AutomationEngine {
|
|
|
38462
38552
|
await this.logExecution(result2, trustedTenantId);
|
|
38463
38553
|
return result2;
|
|
38464
38554
|
}
|
|
38465
|
-
const actionsExecuted = await
|
|
38555
|
+
const actionsExecuted = await runWithEventCausality({
|
|
38556
|
+
correlationId: context2.event?.metadata.correlationId ?? event.metadata.correlationId,
|
|
38557
|
+
causationId: context2.event?.id ?? event.id
|
|
38558
|
+
}, () => executeActions(automation.actions, context2, this.deps, trustedTenantId));
|
|
38466
38559
|
const allSucceeded = actionsExecuted.every((a) => a.status === "success");
|
|
38467
38560
|
const status = allSucceeded ? "success" : "failed";
|
|
38468
38561
|
const result = {
|
|
@@ -38558,6 +38651,7 @@ function createAutomationEngine(config2) {
|
|
|
38558
38651
|
}
|
|
38559
38652
|
var logger4, QueueFullError;
|
|
38560
38653
|
var init_engine = __esm(() => {
|
|
38654
|
+
init_causality();
|
|
38561
38655
|
init_envelope();
|
|
38562
38656
|
init_ids();
|
|
38563
38657
|
init_logger();
|
|
@@ -38946,6 +39040,113 @@ var init_automations = __esm(() => {
|
|
|
38946
39040
|
init_sweeper();
|
|
38947
39041
|
});
|
|
38948
39042
|
|
|
39043
|
+
// ../core/src/connectors/liveness.ts
|
|
39044
|
+
function latestConnectorSignal(row) {
|
|
39045
|
+
let best = { at: row.createdAt, kind: "rearmed" };
|
|
39046
|
+
const candidates = [
|
|
39047
|
+
{ at: row.livenessArmedAt, kind: "rearmed" },
|
|
39048
|
+
{ at: row.lastReceivedAt, kind: "event" },
|
|
39049
|
+
{ at: row.lastHeartbeatAt, kind: "heartbeat" }
|
|
39050
|
+
];
|
|
39051
|
+
for (const candidate of candidates) {
|
|
39052
|
+
if (candidate.at && candidate.at.getTime() >= best.at.getTime()) {
|
|
39053
|
+
best = { at: candidate.at, kind: candidate.kind };
|
|
39054
|
+
}
|
|
39055
|
+
}
|
|
39056
|
+
return best;
|
|
39057
|
+
}
|
|
39058
|
+
async function sweepConnectorLiveness(deps) {
|
|
39059
|
+
const clock = deps.now ?? (() => new Date);
|
|
39060
|
+
const now = clock();
|
|
39061
|
+
const rows = await deps.repo.findSupervised();
|
|
39062
|
+
const stats = { scanned: rows.length, stalled: 0, recovered: 0, errors: 0 };
|
|
39063
|
+
for (const row of rows) {
|
|
39064
|
+
try {
|
|
39065
|
+
await processRow2(row, now, deps, stats);
|
|
39066
|
+
} catch (err2) {
|
|
39067
|
+
stats.errors += 1;
|
|
39068
|
+
deps.logger.error("connector liveness: failed to process source", {
|
|
39069
|
+
sourceId: row.id,
|
|
39070
|
+
sourceName: row.name,
|
|
39071
|
+
error: err2 instanceof Error ? err2.message : String(err2)
|
|
39072
|
+
});
|
|
39073
|
+
}
|
|
39074
|
+
}
|
|
39075
|
+
if (stats.stalled > 0 || stats.recovered > 0) {
|
|
39076
|
+
deps.logger.info("connector liveness sweep tick", { ...stats });
|
|
39077
|
+
}
|
|
39078
|
+
return stats;
|
|
39079
|
+
}
|
|
39080
|
+
async function processRow2(row, now, deps, stats) {
|
|
39081
|
+
const signal = latestConnectorSignal(row);
|
|
39082
|
+
const silentMs = Math.max(0, now.getTime() - signal.at.getTime());
|
|
39083
|
+
const overdue = silentMs > row.expectedIntervalSeconds * 1000;
|
|
39084
|
+
const silentForSeconds = Math.round(silentMs / 1000);
|
|
39085
|
+
if (overdue) {
|
|
39086
|
+
if (row.livenessStatus === "stalled")
|
|
39087
|
+
return;
|
|
39088
|
+
if (!await deps.repo.markStalled(row.id, now))
|
|
39089
|
+
return;
|
|
39090
|
+
const payload = {
|
|
39091
|
+
sourceId: row.id,
|
|
39092
|
+
sourceName: row.name,
|
|
39093
|
+
expectedIntervalSeconds: row.expectedIntervalSeconds,
|
|
39094
|
+
lastReceivedAt: row.lastReceivedAt?.getTime() ?? null,
|
|
39095
|
+
lastHeartbeatAt: row.lastHeartbeatAt?.getTime() ?? null,
|
|
39096
|
+
silentForSeconds,
|
|
39097
|
+
stalledAt: now.getTime()
|
|
39098
|
+
};
|
|
39099
|
+
const eventId = await publishTransition(deps, "system.connector.stalled", { ...payload }, row);
|
|
39100
|
+
stats.stalled += 1;
|
|
39101
|
+
await runHook(deps.logger, "onStalled", row, () => deps.onStalled?.(row, payload, eventId));
|
|
39102
|
+
return;
|
|
39103
|
+
}
|
|
39104
|
+
if (row.livenessStatus === "stalled") {
|
|
39105
|
+
if (!await deps.repo.markRecovered(row.id, now))
|
|
39106
|
+
return;
|
|
39107
|
+
const stalledSince = row.stalledAt ?? signal.at;
|
|
39108
|
+
const payload = {
|
|
39109
|
+
sourceId: row.id,
|
|
39110
|
+
sourceName: row.name,
|
|
39111
|
+
expectedIntervalSeconds: row.expectedIntervalSeconds,
|
|
39112
|
+
stalledForSeconds: Math.max(0, Math.round((now.getTime() - stalledSince.getTime()) / 1000)),
|
|
39113
|
+
recoveredBy: signal.kind,
|
|
39114
|
+
recoveredAt: now.getTime()
|
|
39115
|
+
};
|
|
39116
|
+
await publishTransition(deps, "system.connector.recovered", { ...payload }, row);
|
|
39117
|
+
stats.recovered += 1;
|
|
39118
|
+
await runHook(deps.logger, "onRecovered", row, () => deps.onRecovered?.(row, payload));
|
|
39119
|
+
}
|
|
39120
|
+
}
|
|
39121
|
+
async function publishTransition(deps, type, payload, row) {
|
|
39122
|
+
if (!deps.eventBus) {
|
|
39123
|
+
deps.logger.warn("connector liveness: no event bus, transition persisted without event", {
|
|
39124
|
+
type,
|
|
39125
|
+
sourceName: row.name
|
|
39126
|
+
});
|
|
39127
|
+
return null;
|
|
39128
|
+
}
|
|
39129
|
+
const result = await deps.eventBus.publishGeneric(type, payload, {
|
|
39130
|
+
source: "connector-liveness",
|
|
39131
|
+
...row.tenantId ? { tenantId: row.tenantId } : {}
|
|
39132
|
+
});
|
|
39133
|
+
return result.id;
|
|
39134
|
+
}
|
|
39135
|
+
async function runHook(logger5, name, row, hook) {
|
|
39136
|
+
try {
|
|
39137
|
+
await hook();
|
|
39138
|
+
} catch (err2) {
|
|
39139
|
+
logger5.error(`connector liveness: ${name} hook failed`, {
|
|
39140
|
+
sourceId: row.id,
|
|
39141
|
+
sourceName: row.name,
|
|
39142
|
+
error: err2 instanceof Error ? err2.message : String(err2)
|
|
39143
|
+
});
|
|
39144
|
+
}
|
|
39145
|
+
}
|
|
39146
|
+
|
|
39147
|
+
// ../core/src/connectors/index.ts
|
|
39148
|
+
var init_connectors = () => {};
|
|
39149
|
+
|
|
38949
39150
|
// ../core/src/sessions/reset.ts
|
|
38950
39151
|
class InMemorySessionActivityStore {
|
|
38951
39152
|
activities = new Map;
|
|
@@ -42989,7 +43190,7 @@ function isProviderSchemaSupported(schema) {
|
|
|
42989
43190
|
function getSupportedProviderSchemas() {
|
|
42990
43191
|
return ["agno", "webhook", "openclaw", "claude-code", "ag-ui", "a2a", "nats-genie"];
|
|
42991
43192
|
}
|
|
42992
|
-
var
|
|
43193
|
+
var init_factory2 = __esm(() => {
|
|
42993
43194
|
init_a2a_client();
|
|
42994
43195
|
init_ag_ui_client();
|
|
42995
43196
|
init_agno_client();
|
|
@@ -43009,7 +43210,7 @@ var init_providers = __esm(() => {
|
|
|
43009
43210
|
init_ag_ui_provider();
|
|
43010
43211
|
init_a2a_provider();
|
|
43011
43212
|
init_nats_genie_provider();
|
|
43012
|
-
|
|
43213
|
+
init_factory2();
|
|
43013
43214
|
});
|
|
43014
43215
|
|
|
43015
43216
|
// ../core/src/cache/types.ts
|
|
@@ -43678,6 +43879,7 @@ __export(exports_src, {
|
|
|
43678
43879
|
tenantLabelBucketCount: () => tenantLabelBucketCount,
|
|
43679
43880
|
tenantEventsProcessed: () => tenantEventsProcessed,
|
|
43680
43881
|
sweepFollowUps: () => sweepFollowUps,
|
|
43882
|
+
sweepConnectorLiveness: () => sweepConnectorLiveness,
|
|
43681
43883
|
substituteTemplateObject: () => substituteTemplateObject,
|
|
43682
43884
|
substituteTemplate: () => substituteTemplate,
|
|
43683
43885
|
stampsEqual: () => stampsEqual,
|
|
@@ -43692,6 +43894,7 @@ __export(exports_src, {
|
|
|
43692
43894
|
scheduledJobRuns: () => scheduledJobRuns,
|
|
43693
43895
|
scheduledJobNextRun: () => scheduledJobNextRun,
|
|
43694
43896
|
scheduledJobDuration: () => scheduledJobDuration,
|
|
43897
|
+
runWithEventCausality: () => runWithEventCausality,
|
|
43695
43898
|
rootLogger: () => rootLogger,
|
|
43696
43899
|
resolveResetConfig: () => resolveResetConfig,
|
|
43697
43900
|
resolvePublishTenantId: () => resolvePublishTenantId,
|
|
@@ -43740,6 +43943,7 @@ __export(exports_src, {
|
|
|
43740
43943
|
natsConnectionStatus: () => natsConnectionStatus,
|
|
43741
43944
|
matchesPattern: () => matchesPattern,
|
|
43742
43945
|
markdownToWhatsApp: () => markdownToWhatsApp,
|
|
43946
|
+
latestConnectorSignal: () => latestConnectorSignal,
|
|
43743
43947
|
jsonEquals: () => jsonEquals,
|
|
43744
43948
|
isValidUuid: () => isValidUuid,
|
|
43745
43949
|
isValidJsonSchema: () => isValidJsonSchema,
|
|
@@ -43803,6 +44007,7 @@ __export(exports_src, {
|
|
|
43803
44007
|
dbQueries: () => dbQueries,
|
|
43804
44008
|
dbPoolSize: () => dbPoolSize,
|
|
43805
44009
|
dbErrors: () => dbErrors,
|
|
44010
|
+
currentEventCausality: () => currentEventCausality,
|
|
43806
44011
|
createValidatedSubscription: () => createValidatedSubscription,
|
|
43807
44012
|
createTemplateContext: () => createTemplateContext,
|
|
43808
44013
|
createSubscription: () => createSubscription,
|
|
@@ -44065,6 +44270,7 @@ var init_src = __esm(() => {
|
|
|
44065
44270
|
init_observability();
|
|
44066
44271
|
init_secrets();
|
|
44067
44272
|
init_automations();
|
|
44273
|
+
init_connectors();
|
|
44068
44274
|
init_reset();
|
|
44069
44275
|
init_providers();
|
|
44070
44276
|
init_cache();
|
|
@@ -138899,9 +139105,9 @@ var require_session = __commonJS((exports) => {
|
|
|
138899
139105
|
return options.type === "multi" ? strictMultiSession(options) : strictSingleSession(options);
|
|
138900
139106
|
}
|
|
138901
139107
|
function strictSingleSession(options) {
|
|
138902
|
-
const { initial, storage, getSessionKey, custom: custom2 } = fillDefaults(options);
|
|
139108
|
+
const { initial, storage: storage2, getSessionKey, custom: custom2 } = fillDefaults(options);
|
|
138903
139109
|
return async (ctx, next) => {
|
|
138904
|
-
const propSession = new PropertySession(
|
|
139110
|
+
const propSession = new PropertySession(storage2, ctx, "session", initial);
|
|
138905
139111
|
const key = await getSessionKey(ctx);
|
|
138906
139112
|
await propSession.init(key, { custom: custom2, lazy: false });
|
|
138907
139113
|
await next();
|
|
@@ -138914,8 +139120,8 @@ var require_session = __commonJS((exports) => {
|
|
|
138914
139120
|
return async (ctx, next) => {
|
|
138915
139121
|
ctx.session = {};
|
|
138916
139122
|
const propSessions = await Promise.all(props.map(async (prop) => {
|
|
138917
|
-
const { initial, storage, getSessionKey, custom: custom2 } = defaults[prop];
|
|
138918
|
-
const s = new PropertySession(
|
|
139123
|
+
const { initial, storage: storage2, getSessionKey, custom: custom2 } = defaults[prop];
|
|
139124
|
+
const s = new PropertySession(storage2, ctx.session, prop, initial);
|
|
138919
139125
|
const key = await getSessionKey(ctx);
|
|
138920
139126
|
await s.init(key, { custom: custom2, lazy: false });
|
|
138921
139127
|
return s;
|
|
@@ -138930,9 +139136,9 @@ var require_session = __commonJS((exports) => {
|
|
|
138930
139136
|
if (options.type !== undefined && options.type !== "single") {
|
|
138931
139137
|
throw new Error("Cannot use lazy multi sessions!");
|
|
138932
139138
|
}
|
|
138933
|
-
const { initial, storage, getSessionKey, custom: custom2 } = fillDefaults(options);
|
|
139139
|
+
const { initial, storage: storage2, getSessionKey, custom: custom2 } = fillDefaults(options);
|
|
138934
139140
|
return async (ctx, next) => {
|
|
138935
|
-
const propSession = new PropertySession(
|
|
139141
|
+
const propSession = new PropertySession(storage2, ctx, "session", initial);
|
|
138936
139142
|
const key = await getSessionKey(ctx);
|
|
138937
139143
|
await propSession.init(key, { custom: custom2, lazy: true });
|
|
138938
139144
|
await next();
|
|
@@ -138941,8 +139147,8 @@ var require_session = __commonJS((exports) => {
|
|
|
138941
139147
|
}
|
|
138942
139148
|
|
|
138943
139149
|
class PropertySession {
|
|
138944
|
-
constructor(
|
|
138945
|
-
this.storage =
|
|
139150
|
+
constructor(storage2, obj, prop, initial) {
|
|
139151
|
+
this.storage = storage2;
|
|
138946
139152
|
this.obj = obj;
|
|
138947
139153
|
this.prop = prop;
|
|
138948
139154
|
this.initial = initial;
|
|
@@ -139025,15 +139231,15 @@ var require_session = __commonJS((exports) => {
|
|
|
139025
139231
|
}
|
|
139026
139232
|
}
|
|
139027
139233
|
function fillDefaults(opts = {}) {
|
|
139028
|
-
let { prefix = "", getSessionKey = defaultGetSessionKey, initial, storage } = opts;
|
|
139029
|
-
if (
|
|
139234
|
+
let { prefix = "", getSessionKey = defaultGetSessionKey, initial, storage: storage2 } = opts;
|
|
139235
|
+
if (storage2 == null) {
|
|
139030
139236
|
debug2("Storing session data in memory, all data will be lost when the bot restarts.");
|
|
139031
|
-
|
|
139237
|
+
storage2 = new MemorySessionStorage;
|
|
139032
139238
|
}
|
|
139033
139239
|
const custom2 = getSessionKey !== defaultGetSessionKey;
|
|
139034
139240
|
return {
|
|
139035
139241
|
initial,
|
|
139036
|
-
storage,
|
|
139242
|
+
storage: storage2,
|
|
139037
139243
|
getSessionKey: async (ctx) => {
|
|
139038
139244
|
const key = await getSessionKey(ctx);
|
|
139039
139245
|
return key === undefined ? undefined : prefix + key;
|
|
@@ -139054,30 +139260,30 @@ var require_session = __commonJS((exports) => {
|
|
|
139054
139260
|
return value === undefined || typeof value === "object" && value !== null && "__d" in value;
|
|
139055
139261
|
}
|
|
139056
139262
|
function enhanceStorage(options) {
|
|
139057
|
-
let { storage, millisecondsToLive, migrations } = options;
|
|
139058
|
-
|
|
139263
|
+
let { storage: storage2, millisecondsToLive, migrations } = options;
|
|
139264
|
+
storage2 = compatStorage(storage2);
|
|
139059
139265
|
if (millisecondsToLive !== undefined) {
|
|
139060
|
-
|
|
139266
|
+
storage2 = timeoutStorage(storage2, millisecondsToLive);
|
|
139061
139267
|
}
|
|
139062
139268
|
if (migrations !== undefined) {
|
|
139063
|
-
|
|
139269
|
+
storage2 = migrationStorage(storage2, migrations);
|
|
139064
139270
|
}
|
|
139065
|
-
return wrapStorage(
|
|
139271
|
+
return wrapStorage(storage2);
|
|
139066
139272
|
}
|
|
139067
|
-
function compatStorage(
|
|
139273
|
+
function compatStorage(storage2) {
|
|
139068
139274
|
return {
|
|
139069
139275
|
read: async (k2) => {
|
|
139070
|
-
const v2 = await
|
|
139276
|
+
const v2 = await storage2.read(k2);
|
|
139071
139277
|
return isEnhance(v2) ? v2 : { __d: v2 };
|
|
139072
139278
|
},
|
|
139073
|
-
write: (k2, v2) =>
|
|
139074
|
-
delete: (k2) =>
|
|
139279
|
+
write: (k2, v2) => storage2.write(k2, v2),
|
|
139280
|
+
delete: (k2) => storage2.delete(k2)
|
|
139075
139281
|
};
|
|
139076
139282
|
}
|
|
139077
|
-
function timeoutStorage(
|
|
139283
|
+
function timeoutStorage(storage2, millisecondsToLive) {
|
|
139078
139284
|
const ttlStorage = {
|
|
139079
139285
|
read: async (k2) => {
|
|
139080
|
-
const value = await
|
|
139286
|
+
const value = await storage2.read(k2);
|
|
139081
139287
|
if (value === undefined)
|
|
139082
139288
|
return;
|
|
139083
139289
|
if (value.e === undefined) {
|
|
@@ -139092,13 +139298,13 @@ var require_session = __commonJS((exports) => {
|
|
|
139092
139298
|
},
|
|
139093
139299
|
write: async (k2, v2) => {
|
|
139094
139300
|
v2.e = addExpiryDate(v2, millisecondsToLive).expires;
|
|
139095
|
-
await
|
|
139301
|
+
await storage2.write(k2, v2);
|
|
139096
139302
|
},
|
|
139097
|
-
delete: (k2) =>
|
|
139303
|
+
delete: (k2) => storage2.delete(k2)
|
|
139098
139304
|
};
|
|
139099
139305
|
return ttlStorage;
|
|
139100
139306
|
}
|
|
139101
|
-
function migrationStorage(
|
|
139307
|
+
function migrationStorage(storage2, migrations) {
|
|
139102
139308
|
const versions = Object.keys(migrations).map((v2) => parseInt(v2)).sort((a, b2) => a - b2);
|
|
139103
139309
|
const count = versions.length;
|
|
139104
139310
|
if (count === 0)
|
|
@@ -139117,7 +139323,7 @@ var require_session = __commonJS((exports) => {
|
|
|
139117
139323
|
return {
|
|
139118
139324
|
read: async (k2) => {
|
|
139119
139325
|
var _a;
|
|
139120
|
-
const val = await
|
|
139326
|
+
const val = await storage2.read(k2);
|
|
139121
139327
|
if (val === undefined)
|
|
139122
139328
|
return val;
|
|
139123
139329
|
let { __d: value, v: current = earliest - 1 } = val;
|
|
@@ -139126,15 +139332,15 @@ var require_session = __commonJS((exports) => {
|
|
|
139126
139332
|
value = migrations[versions[i]](value);
|
|
139127
139333
|
return { ...val, v: latest, __d: value };
|
|
139128
139334
|
},
|
|
139129
|
-
write: (k2, v2) =>
|
|
139130
|
-
delete: (k2) =>
|
|
139335
|
+
write: (k2, v2) => storage2.write(k2, { v: latest, ...v2 }),
|
|
139336
|
+
delete: (k2) => storage2.delete(k2)
|
|
139131
139337
|
};
|
|
139132
139338
|
}
|
|
139133
|
-
function wrapStorage(
|
|
139339
|
+
function wrapStorage(storage2) {
|
|
139134
139340
|
return {
|
|
139135
|
-
read: (k2) => Promise.resolve(
|
|
139136
|
-
write: (k2, v2) =>
|
|
139137
|
-
delete: (k2) =>
|
|
139341
|
+
read: (k2) => Promise.resolve(storage2.read(k2)).then((v2) => v2 === null || v2 === undefined ? undefined : v2.__d),
|
|
139342
|
+
write: (k2, v2) => storage2.write(k2, { __d: v2 }),
|
|
139343
|
+
delete: (k2) => storage2.delete(k2)
|
|
139138
139344
|
};
|
|
139139
139345
|
}
|
|
139140
139346
|
|
|
@@ -143264,9 +143470,9 @@ var require_session_builder = __commonJS((exports, module) => {
|
|
|
143264
143470
|
var queueJob = require_queue_job();
|
|
143265
143471
|
|
|
143266
143472
|
class SessionBuilder {
|
|
143267
|
-
constructor(
|
|
143473
|
+
constructor(storage2, protocolAddress) {
|
|
143268
143474
|
this.addr = protocolAddress;
|
|
143269
|
-
this.storage =
|
|
143475
|
+
this.storage = storage2;
|
|
143270
143476
|
}
|
|
143271
143477
|
async initOutgoing(device) {
|
|
143272
143478
|
const fqAddr = this.addr.toString();
|
|
@@ -144712,12 +144918,12 @@ var require_session_cipher = __commonJS((exports, module) => {
|
|
|
144712
144918
|
}
|
|
144713
144919
|
|
|
144714
144920
|
class SessionCipher {
|
|
144715
|
-
constructor(
|
|
144921
|
+
constructor(storage2, protocolAddress) {
|
|
144716
144922
|
if (!(protocolAddress instanceof ProtocolAddress)) {
|
|
144717
144923
|
throw new TypeError("protocolAddress must be a ProtocolAddress");
|
|
144718
144924
|
}
|
|
144719
144925
|
this.addr = protocolAddress;
|
|
144720
|
-
this.storage =
|
|
144926
|
+
this.storage = storage2;
|
|
144721
144927
|
}
|
|
144722
144928
|
_encodeTupleByte(number1, number2) {
|
|
144723
144929
|
if (number1 > 15 || number2 > 15) {
|
|
@@ -172164,6 +172370,9 @@ __export(exports_schema, {
|
|
|
172164
172370
|
conversations: () => conversations,
|
|
172165
172371
|
contentTypes: () => contentTypes,
|
|
172166
172372
|
consumerOffsets: () => consumerOffsets,
|
|
172373
|
+
connectorWindowSemanticsValues: () => connectorWindowSemanticsValues,
|
|
172374
|
+
connectorMutationPolicies: () => connectorMutationPolicies,
|
|
172375
|
+
connectorLivenessStatuses: () => connectorLivenessStatuses,
|
|
172167
172376
|
conditionOperators: () => conditionOperators,
|
|
172168
172377
|
closeContactOutcomes: () => closeContactOutcomes,
|
|
172169
172378
|
closeContactLogs: () => closeContactLogs,
|
|
@@ -172212,7 +172421,7 @@ __export(exports_schema, {
|
|
|
172212
172421
|
accessRules: () => accessRules,
|
|
172213
172422
|
accessModes: () => accessModes
|
|
172214
172423
|
});
|
|
172215
|
-
var channelTypes, agentTypes, agentSystems, agentEntityTypes, debounceMode, splitDelayMode, supersedeMode, replyFilterMode, agentSessionStrategies, ruleTypes, accessModes, settingValueTypes, apiKeyStatuses, apiKeyProfiles, eventTypes, contentTypes, chatTypes, messageSources, messageTypes, messageStatuses, deliveryStatuses, scheduledMessageDeliveryModes, scheduledMessageStatuses, jobStatuses, providerSchemas, agentProviders, agents, agentRoutes, agentSessions, apiKeys, apiKeyAuditLogs, apiKeysRelations, apiKeyAuditLogsRelations, instances, whatsappTemplates, whatsappFlowKeys, scheduledMessages, persons, platformIdentities, conversations, chats, chatParticipants, omniGroups, messages2, omniEvents, handoffLogs, closeContactOutcomes, closeContactLogs, accessRules, globalSettings, settingChangeHistory, batchJobs, syncJobTypes, syncJobs, mediaContent, chatIdMappings, pluginStorage, agentProvidersRelations, agentsRelations, instancesRelations, syncJobsRelations, personsRelations, platformIdentitiesRelations, conversationsRelations, chatsRelations, chatParticipantsRelations, messagesRelations, omniEventsRelations, accessRulesRelations, globalSettingsRelations, settingChangeHistoryRelations, batchJobsRelations, mediaContentRelations, chatIdMappingsRelations, deadLetterStatuses, deadLetterEvents, payloadStorageConfig, payloadStages, eventPayloads, webhookSignatureAlgorithms, webhookSources, eventSchemas, conditionOperators, actionTypes, automationDebounceModes, automations2, automationLogStatuses, automationLogs, consumerOffsets, automationsRelations, automationLogsRelations, triggerLogs, triggerLogsRelations, agentRoutesRelations, agentTaskStatuses, agentTasks, agentTasksRelations, turnStatuses, turnActions, turns, turnsRelations, followUpDisarmReasons, chatFollowUpState, chatFollowUpStateRelations, processedEvents, genieHosts, tenantStatuses, principalTypes, principalStatuses, tenantRoles, membershipStatuses, credentialClasses, authCredentialStatuses, platformApiKeyStatuses, tenants, principals, tenantMemberships, tenantRolePolicies, platformApiKeys, tenantKeyLineage, authCredentials, tenantAuditLogs, platformAuditLogs, platformProviderCatalog, tenantProviderConfig, platformSettings, tenantSettings, platformSettingChangeHistory, tenantSettingChangeHistory, platformPluginStorage, tenantPluginStorage, platformPayloadStorageConfig, tenantPayloadStorageOverrides, tenantMigrationLedger, tenantMigrationLedgerHistory;
|
|
172424
|
+
var channelTypes, agentTypes, agentSystems, agentEntityTypes, debounceMode, splitDelayMode, supersedeMode, replyFilterMode, agentSessionStrategies, ruleTypes, accessModes, settingValueTypes, apiKeyStatuses, apiKeyProfiles, eventTypes, contentTypes, chatTypes, messageSources, messageTypes, messageStatuses, deliveryStatuses, scheduledMessageDeliveryModes, scheduledMessageStatuses, jobStatuses, providerSchemas, agentProviders, agents, agentRoutes, agentSessions, apiKeys, apiKeyAuditLogs, apiKeysRelations, apiKeyAuditLogsRelations, instances, whatsappTemplates, whatsappFlowKeys, scheduledMessages, persons, platformIdentities, conversations, chats, chatParticipants, omniGroups, messages2, omniEvents, handoffLogs, closeContactOutcomes, closeContactLogs, accessRules, globalSettings, settingChangeHistory, batchJobs, syncJobTypes, syncJobs, mediaContent, chatIdMappings, pluginStorage, agentProvidersRelations, agentsRelations, instancesRelations, syncJobsRelations, personsRelations, platformIdentitiesRelations, conversationsRelations, chatsRelations, chatParticipantsRelations, messagesRelations, omniEventsRelations, accessRulesRelations, globalSettingsRelations, settingChangeHistoryRelations, batchJobsRelations, mediaContentRelations, chatIdMappingsRelations, deadLetterStatuses, deadLetterEvents, payloadStorageConfig, payloadStages, eventPayloads, webhookSignatureAlgorithms, connectorLivenessStatuses, connectorWindowSemanticsValues, connectorMutationPolicies, webhookSources, eventSchemas, conditionOperators, actionTypes, automationDebounceModes, automations2, automationLogStatuses, automationLogs, consumerOffsets, automationsRelations, automationLogsRelations, triggerLogs, triggerLogsRelations, agentRoutesRelations, agentTaskStatuses, agentTasks, agentTasksRelations, turnStatuses, turnActions, turns, turnsRelations, followUpDisarmReasons, chatFollowUpState, chatFollowUpStateRelations, processedEvents, genieHosts, tenantStatuses, principalTypes, principalStatuses, tenantRoles, membershipStatuses, credentialClasses, authCredentialStatuses, platformApiKeyStatuses, tenants, principals, tenantMemberships, tenantRolePolicies, platformApiKeys, tenantKeyLineage, authCredentials, tenantAuditLogs, platformAuditLogs, platformProviderCatalog, tenantProviderConfig, platformSettings, tenantSettings, platformSettingChangeHistory, tenantSettingChangeHistory, platformPluginStorage, tenantPluginStorage, platformPayloadStorageConfig, tenantPayloadStorageOverrides, tenantMigrationLedger, tenantMigrationLedgerHistory;
|
|
172216
172425
|
var init_schema2 = __esm(() => {
|
|
172217
172426
|
init_events();
|
|
172218
172427
|
init_types5();
|
|
@@ -172944,9 +173153,11 @@ var init_schema2 = __esm(() => {
|
|
|
172944
173153
|
agentRequest: jsonb("agent_request").$type(),
|
|
172945
173154
|
agentResponse: jsonb("agent_response").$type(),
|
|
172946
173155
|
metadata: jsonb("metadata").$type(),
|
|
173156
|
+
causationId: uuid("causation_id"),
|
|
172947
173157
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
172948
173158
|
tenantId: uuid("tenant_id").references(() => tenants.id, { onDelete: "restrict" })
|
|
172949
173159
|
}, (table3) => ({
|
|
173160
|
+
causationIdx: index("omni_events_causation_idx").on(table3.causationId),
|
|
172950
173161
|
tenantIdx: index("omni_events_tenant_idx").on(table3.tenantId),
|
|
172951
173162
|
tenantIdUq: uniqueIndex("omni_events_tenant_id_uq").on(table3.tenantId, table3.id),
|
|
172952
173163
|
externalIdIdx: index("omni_events_external_id_idx").on(table3.externalId),
|
|
@@ -173425,6 +173636,9 @@ var init_schema2 = __esm(() => {
|
|
|
173425
173636
|
eventStageIdx: index("event_payloads_event_stage_idx").on(table3.eventId, table3.stage)
|
|
173426
173637
|
}));
|
|
173427
173638
|
webhookSignatureAlgorithms = ["hmac-sha256", "hmac-sha1", "token-match"];
|
|
173639
|
+
connectorLivenessStatuses = ["healthy", "stalled"];
|
|
173640
|
+
connectorWindowSemanticsValues = ["future_only", "includes_in_progress"];
|
|
173641
|
+
connectorMutationPolicies = ["same_id", "new_id"];
|
|
173428
173642
|
webhookSources = pgTable("webhook_sources", {
|
|
173429
173643
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
173430
173644
|
name: varchar("name", { length: 100 }).notNull().unique(),
|
|
@@ -173436,6 +173650,14 @@ var init_schema2 = __esm(() => {
|
|
|
173436
173650
|
enabled: boolean2("enabled").notNull().default(true),
|
|
173437
173651
|
lastReceivedAt: timestamp("last_received_at", { withTimezone: true }),
|
|
173438
173652
|
totalReceived: integer("total_received").notNull().default(0),
|
|
173653
|
+
expectedIntervalSeconds: integer("expected_interval_seconds"),
|
|
173654
|
+
lastHeartbeatAt: timestamp("last_heartbeat_at", { withTimezone: true }),
|
|
173655
|
+
heartbeatCount: integer("heartbeat_count").notNull().default(0),
|
|
173656
|
+
livenessStatus: varchar("liveness_status", { length: 20 }).$type(),
|
|
173657
|
+
livenessArmedAt: timestamp("liveness_armed_at", { withTimezone: true }),
|
|
173658
|
+
stalledAt: timestamp("stalled_at", { withTimezone: true }),
|
|
173659
|
+
windowSemantics: varchar("window_semantics", { length: 40 }).$type(),
|
|
173660
|
+
mutationPolicy: varchar("mutation_policy", { length: 20 }).$type(),
|
|
173439
173661
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
173440
173662
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
|
173441
173663
|
tenantId: uuid("tenant_id").references(() => tenants.id, { onDelete: "restrict" })
|
|
@@ -173443,7 +173665,8 @@ var init_schema2 = __esm(() => {
|
|
|
173443
173665
|
tenantIdx: index("webhook_sources_tenant_idx").on(table3.tenantId),
|
|
173444
173666
|
tenantNameUq: uniqueIndex("webhook_sources_tenant_name_uq").on(table3.tenantId, table3.name).where(sql`${table3.tenantId} IS NOT NULL`),
|
|
173445
173667
|
nameIdx: uniqueIndex("webhook_sources_name_idx").on(table3.name),
|
|
173446
|
-
enabledIdx: index("webhook_sources_enabled_idx").on(table3.enabled)
|
|
173668
|
+
enabledIdx: index("webhook_sources_enabled_idx").on(table3.enabled),
|
|
173669
|
+
supervisedIdx: index("webhook_sources_supervised_idx").on(table3.enabled).where(sql`${table3.expectedIntervalSeconds} IS NOT NULL`)
|
|
173447
173670
|
}));
|
|
173448
173671
|
eventSchemas = pgTable("event_schemas", {
|
|
173449
173672
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
@@ -177895,6 +178118,9 @@ __export(exports_src3, {
|
|
|
177895
178118
|
conversations: () => conversations,
|
|
177896
178119
|
contentTypes: () => contentTypes,
|
|
177897
178120
|
consumerOffsets: () => consumerOffsets,
|
|
178121
|
+
connectorWindowSemanticsValues: () => connectorWindowSemanticsValues,
|
|
178122
|
+
connectorMutationPolicies: () => connectorMutationPolicies,
|
|
178123
|
+
connectorLivenessStatuses: () => connectorLivenessStatuses,
|
|
177898
178124
|
conditionOperators: () => conditionOperators,
|
|
177899
178125
|
closeDb: () => closeDb,
|
|
177900
178126
|
closeContactOutcomes: () => closeContactOutcomes,
|
|
@@ -179690,11 +179916,11 @@ function isTerminal(state) {
|
|
|
179690
179916
|
class A2ATaskStore {
|
|
179691
179917
|
memory = new Map;
|
|
179692
179918
|
storage;
|
|
179693
|
-
constructor(
|
|
179694
|
-
this.storage =
|
|
179919
|
+
constructor(storage2) {
|
|
179920
|
+
this.storage = storage2;
|
|
179695
179921
|
}
|
|
179696
|
-
setStorage(
|
|
179697
|
-
this.storage =
|
|
179922
|
+
setStorage(storage2) {
|
|
179923
|
+
this.storage = storage2;
|
|
179698
179924
|
}
|
|
179699
179925
|
async createTask(params) {
|
|
179700
179926
|
const now = new Date().toISOString();
|
|
@@ -201742,12 +201968,12 @@ var init_resource_Bhpm2sLf = __esm(() => {
|
|
|
201742
201968
|
});
|
|
201743
201969
|
|
|
201744
201970
|
// ../../node_modules/.bun/@sentry+opentelemetry@10.52.0+54dbe0b6443040f8/node_modules/@sentry/opentelemetry/build/esm/index.js
|
|
201745
|
-
import { AsyncLocalStorage as
|
|
201971
|
+
import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
|
|
201746
201972
|
import { EventEmitter as EventEmitter4 } from "events";
|
|
201747
201973
|
|
|
201748
201974
|
class SentryAsyncLocalStorageContextManager {
|
|
201749
201975
|
__init() {
|
|
201750
|
-
this._asyncLocalStorage = new
|
|
201976
|
+
this._asyncLocalStorage = new AsyncLocalStorage3;
|
|
201751
201977
|
}
|
|
201752
201978
|
__init2() {
|
|
201753
201979
|
this._kOtListeners = Symbol("OtListeners");
|
|
@@ -250680,7 +250906,7 @@ var init_sentry_scrub = __esm(() => {
|
|
|
250680
250906
|
var require_package7 = __commonJS((exports, module) => {
|
|
250681
250907
|
module.exports = {
|
|
250682
250908
|
name: "@omni/api",
|
|
250683
|
-
version: "2.260906.
|
|
250909
|
+
version: "2.260906.4",
|
|
250684
250910
|
private: true,
|
|
250685
250911
|
type: "module",
|
|
250686
250912
|
exports: {
|
|
@@ -257665,23 +257891,23 @@ var require_Meter = __commonJS((exports) => {
|
|
|
257665
257891
|
}
|
|
257666
257892
|
createGauge(name, options) {
|
|
257667
257893
|
const descriptor = (0, InstrumentDescriptor_1.createInstrumentDescriptor)(name, InstrumentDescriptor_1.InstrumentType.GAUGE, options);
|
|
257668
|
-
const
|
|
257669
|
-
return new Instruments_1.GaugeInstrument(
|
|
257894
|
+
const storage2 = this._meterSharedState.registerMetricStorage(descriptor);
|
|
257895
|
+
return new Instruments_1.GaugeInstrument(storage2, descriptor);
|
|
257670
257896
|
}
|
|
257671
257897
|
createHistogram(name, options) {
|
|
257672
257898
|
const descriptor = (0, InstrumentDescriptor_1.createInstrumentDescriptor)(name, InstrumentDescriptor_1.InstrumentType.HISTOGRAM, options);
|
|
257673
|
-
const
|
|
257674
|
-
return new Instruments_1.HistogramInstrument(
|
|
257899
|
+
const storage2 = this._meterSharedState.registerMetricStorage(descriptor);
|
|
257900
|
+
return new Instruments_1.HistogramInstrument(storage2, descriptor);
|
|
257675
257901
|
}
|
|
257676
257902
|
createCounter(name, options) {
|
|
257677
257903
|
const descriptor = (0, InstrumentDescriptor_1.createInstrumentDescriptor)(name, InstrumentDescriptor_1.InstrumentType.COUNTER, options);
|
|
257678
|
-
const
|
|
257679
|
-
return new Instruments_1.CounterInstrument(
|
|
257904
|
+
const storage2 = this._meterSharedState.registerMetricStorage(descriptor);
|
|
257905
|
+
return new Instruments_1.CounterInstrument(storage2, descriptor);
|
|
257680
257906
|
}
|
|
257681
257907
|
createUpDownCounter(name, options) {
|
|
257682
257908
|
const descriptor = (0, InstrumentDescriptor_1.createInstrumentDescriptor)(name, InstrumentDescriptor_1.InstrumentType.UP_DOWN_COUNTER, options);
|
|
257683
|
-
const
|
|
257684
|
-
return new Instruments_1.UpDownCounterInstrument(
|
|
257909
|
+
const storage2 = this._meterSharedState.registerMetricStorage(descriptor);
|
|
257910
|
+
return new Instruments_1.UpDownCounterInstrument(storage2, descriptor);
|
|
257685
257911
|
}
|
|
257686
257912
|
createObservableGauge(name, options) {
|
|
257687
257913
|
const descriptor = (0, InstrumentDescriptor_1.createInstrumentDescriptor)(name, InstrumentDescriptor_1.InstrumentType.OBSERVABLE_GAUGE, options);
|
|
@@ -258075,16 +258301,16 @@ var require_MetricStorageRegistry = __commonJS((exports) => {
|
|
|
258075
258301
|
}
|
|
258076
258302
|
return storages;
|
|
258077
258303
|
}
|
|
258078
|
-
register(
|
|
258079
|
-
this._registerStorage(
|
|
258304
|
+
register(storage2) {
|
|
258305
|
+
this._registerStorage(storage2, this._sharedRegistry);
|
|
258080
258306
|
}
|
|
258081
|
-
registerForCollector(collector,
|
|
258307
|
+
registerForCollector(collector, storage2) {
|
|
258082
258308
|
let storageMap = this._perCollectorRegistry.get(collector);
|
|
258083
258309
|
if (storageMap == null) {
|
|
258084
258310
|
storageMap = new Map;
|
|
258085
258311
|
this._perCollectorRegistry.set(collector, storageMap);
|
|
258086
258312
|
}
|
|
258087
|
-
this._registerStorage(
|
|
258313
|
+
this._registerStorage(storage2, storageMap);
|
|
258088
258314
|
}
|
|
258089
258315
|
findOrUpdateCompatibleStorage(expectedDescriptor) {
|
|
258090
258316
|
const storages = this._sharedRegistry.get(expectedDescriptor.name);
|
|
@@ -258104,14 +258330,14 @@ var require_MetricStorageRegistry = __commonJS((exports) => {
|
|
|
258104
258330
|
}
|
|
258105
258331
|
return this._findOrUpdateCompatibleStorage(expectedDescriptor, storages);
|
|
258106
258332
|
}
|
|
258107
|
-
_registerStorage(
|
|
258108
|
-
const descriptor =
|
|
258333
|
+
_registerStorage(storage2, storageMap) {
|
|
258334
|
+
const descriptor = storage2.getInstrumentDescriptor();
|
|
258109
258335
|
const storages = storageMap.get(descriptor.name);
|
|
258110
258336
|
if (storages === undefined) {
|
|
258111
|
-
storageMap.set(descriptor.name, [
|
|
258337
|
+
storageMap.set(descriptor.name, [storage2]);
|
|
258112
258338
|
return;
|
|
258113
258339
|
}
|
|
258114
|
-
storages.push(
|
|
258340
|
+
storages.push(storage2);
|
|
258115
258341
|
}
|
|
258116
258342
|
_findOrUpdateCompatibleStorage(expectedDescriptor, existingStorages) {
|
|
258117
258343
|
let compatibleStorage = null;
|
|
@@ -258459,9 +258685,9 @@ var require_MeterSharedState = __commonJS((exports) => {
|
|
|
258459
258685
|
return compatibleStorage;
|
|
258460
258686
|
}
|
|
258461
258687
|
const aggregator = aggregation.createAggregator(descriptor);
|
|
258462
|
-
const
|
|
258463
|
-
this.metricStorageRegistry.registerForCollector(collector,
|
|
258464
|
-
return
|
|
258688
|
+
const storage2 = new MetricStorageType(descriptor, aggregator, AttributesProcessor_1.AttributesProcessor.Noop(), [collector]);
|
|
258689
|
+
this.metricStorageRegistry.registerForCollector(collector, storage2);
|
|
258690
|
+
return storage2;
|
|
258465
258691
|
});
|
|
258466
258692
|
storages = storages.concat(collectorStorages);
|
|
258467
258693
|
}
|
|
@@ -300023,7 +300249,7 @@ var Factory = class {
|
|
|
300023
300249
|
return handlers2.filter((handler) => handler !== undefined);
|
|
300024
300250
|
};
|
|
300025
300251
|
}, createMiddleware = (middleware) => middleware;
|
|
300026
|
-
var
|
|
300252
|
+
var init_factory3 = __esm(() => {
|
|
300027
300253
|
init_hono2();
|
|
300028
300254
|
});
|
|
300029
300255
|
|
|
@@ -300552,20 +300778,20 @@ var init_tenant_transaction = __esm(() => {
|
|
|
300552
300778
|
});
|
|
300553
300779
|
|
|
300554
300780
|
// ../api/src/tenancy/tenant-scope.ts
|
|
300555
|
-
import { AsyncLocalStorage as
|
|
300781
|
+
import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
|
|
300556
300782
|
function currentTenantScope() {
|
|
300557
|
-
return
|
|
300783
|
+
return storage2.getStore() ?? null;
|
|
300558
300784
|
}
|
|
300559
300785
|
function scopedHandle(db2) {
|
|
300560
|
-
const scope =
|
|
300786
|
+
const scope = storage2.getStore();
|
|
300561
300787
|
return scope ? scope.tx : db2;
|
|
300562
300788
|
}
|
|
300563
300789
|
async function runInTenantScope(db2, context20, fn) {
|
|
300564
|
-
if (
|
|
300790
|
+
if (storage2.getStore()) {
|
|
300565
300791
|
throw new Error("tenant-scope: a tenant scope is already active for this request");
|
|
300566
300792
|
}
|
|
300567
300793
|
const postCommit = [];
|
|
300568
|
-
const result = await withTenantTransaction(db2, context20, async (tx, tenantId) =>
|
|
300794
|
+
const result = await withTenantTransaction(db2, context20, async (tx, tenantId) => storage2.run({ tx, tenantId, postCommit }, fn));
|
|
300569
300795
|
for (const cb of postCommit) {
|
|
300570
300796
|
try {
|
|
300571
300797
|
cb();
|
|
@@ -300574,7 +300800,7 @@ async function runInTenantScope(db2, context20, fn) {
|
|
|
300574
300800
|
return result;
|
|
300575
300801
|
}
|
|
300576
300802
|
function runAfterTenantCommit(fn) {
|
|
300577
|
-
const scope =
|
|
300803
|
+
const scope = storage2.getStore();
|
|
300578
300804
|
if (scope) {
|
|
300579
300805
|
scope.postCommit.push(fn);
|
|
300580
300806
|
} else {
|
|
@@ -300582,12 +300808,12 @@ function runAfterTenantCommit(fn) {
|
|
|
300582
300808
|
}
|
|
300583
300809
|
}
|
|
300584
300810
|
function runDetachedFromTenantScope(fn) {
|
|
300585
|
-
return
|
|
300811
|
+
return storage2.exit(fn);
|
|
300586
300812
|
}
|
|
300587
|
-
var
|
|
300813
|
+
var storage2;
|
|
300588
300814
|
var init_tenant_scope = __esm(() => {
|
|
300589
300815
|
init_tenant_transaction();
|
|
300590
|
-
|
|
300816
|
+
storage2 = new AsyncLocalStorage4;
|
|
300591
300817
|
});
|
|
300592
300818
|
|
|
300593
300819
|
// ../api/src/tenancy/auth-context.ts
|
|
@@ -300720,7 +300946,7 @@ function filterByInstanceAccess(items, getInstanceId, apiKey) {
|
|
|
300720
300946
|
}
|
|
300721
300947
|
var authMiddleware;
|
|
300722
300948
|
var init_auth = __esm(() => {
|
|
300723
|
-
|
|
300949
|
+
init_factory3();
|
|
300724
300950
|
init_api_keys();
|
|
300725
300951
|
init_tenant_scope();
|
|
300726
300952
|
init_worker_tenant_context();
|
|
@@ -300943,7 +301169,7 @@ function pathFromRequest(url) {
|
|
|
300943
301169
|
var log59, REPLAY_WINDOW_MS = 60000, ED25519_SPKI_PREFIX, HEADER_HOST_ID = "x-genie-host-id", HEADER_TIMESTAMP = "x-genie-timestamp", HEADER_SIGNATURE = "x-genie-signature", genieSignatureMiddleware;
|
|
300944
301170
|
var init_genie_signature = __esm(() => {
|
|
300945
301171
|
init_src();
|
|
300946
|
-
|
|
301172
|
+
init_factory3();
|
|
300947
301173
|
log59 = createLogger("api:genie-signature");
|
|
300948
301174
|
ED25519_SPKI_PREFIX = Buffer.from("302a300506032b6570032100", "hex");
|
|
300949
301175
|
genieSignatureMiddleware = createMiddleware(async (c, next) => {
|
|
@@ -301335,7 +301561,7 @@ async function emitRedactionEvents(c, apiKey, presetKey, hits) {
|
|
|
301335
301561
|
var log60, SEND_ROUTE_PREFIXES, REDACTION_MARKER = "[redacted]", SECRET_REDACTED_EVENT = "secret.redacted", MAX_REDACT_BYTES, presetRegistry = null, outputRedactorMiddleware;
|
|
301336
301562
|
var init_output_redactor = __esm(() => {
|
|
301337
301563
|
init_src();
|
|
301338
|
-
|
|
301564
|
+
init_factory3();
|
|
301339
301565
|
init_profiles();
|
|
301340
301566
|
log60 = createLogger("api:output-redactor");
|
|
301341
301567
|
SEND_ROUTE_PREFIXES = ["/messages/send"];
|
|
@@ -301499,6 +301725,7 @@ var init_scopes = __esm(() => {
|
|
|
301499
301725
|
"GET /events/timeline/:personId": "events:read",
|
|
301500
301726
|
"POST /events/search": "events:read",
|
|
301501
301727
|
"GET /events/:id": "events:read",
|
|
301728
|
+
"GET /events/:id/trace": "events:read",
|
|
301502
301729
|
"GET /events/by-sender/:senderId": "events:read",
|
|
301503
301730
|
"GET /follow-up/agents/:id": "follow-up:read",
|
|
301504
301731
|
"PUT /follow-up/agents/:id": "follow-up:write",
|
|
@@ -301898,7 +302125,7 @@ function invalidSignedHostScopeContextResponse(c, hostId) {
|
|
|
301898
302125
|
var log61, OUTBOUND_SEND_PREFIXES, PATH_INSTANCE_PREFIXES, PATH_CHAT_PREFIXES, PATH_MEDIA_INSTANCE_PREFIX = "/media/", scopeEnforcerMiddleware;
|
|
301899
302126
|
var init_scope_enforcer = __esm(() => {
|
|
301900
302127
|
init_src();
|
|
301901
|
-
|
|
302128
|
+
init_factory3();
|
|
301902
302129
|
init_profiles();
|
|
301903
302130
|
init_scopes();
|
|
301904
302131
|
init_signed_host_scope_context();
|
|
@@ -302020,7 +302247,7 @@ async function safeReadJsonBody2(c) {
|
|
|
302020
302247
|
var log62, requireSignedInstanceMiddleware;
|
|
302021
302248
|
var init_require_signed_instance = __esm(() => {
|
|
302022
302249
|
init_src();
|
|
302023
|
-
|
|
302250
|
+
init_factory3();
|
|
302024
302251
|
init_scope_enforcer();
|
|
302025
302252
|
log62 = createLogger("api:require-signed-instance");
|
|
302026
302253
|
requireSignedInstanceMiddleware = createMiddleware(async (c, next) => {
|
|
@@ -302317,6 +302544,7 @@ var init_route_ownership = __esm(() => {
|
|
|
302317
302544
|
"GET /api/v2/events/:eventId/payloads",
|
|
302318
302545
|
"GET /api/v2/events/:eventId/payloads/:stage",
|
|
302319
302546
|
"GET /api/v2/events/:id",
|
|
302547
|
+
"GET /api/v2/events/:id/trace",
|
|
302320
302548
|
"GET /api/v2/events/analytics",
|
|
302321
302549
|
"GET /api/v2/events/by-sender/:senderId",
|
|
302322
302550
|
"GET /api/v2/events/schemas",
|
|
@@ -302543,6 +302771,7 @@ var init_route_ownership = __esm(() => {
|
|
|
302543
302771
|
"POST /api/v2/voice/leave",
|
|
302544
302772
|
"POST /api/v2/webhook-sources",
|
|
302545
302773
|
"POST /api/v2/webhooks/:source",
|
|
302774
|
+
"POST /api/v2/webhooks/:source/heartbeat",
|
|
302546
302775
|
"PUT /api/v2/agent-state/:agentId/:chatId",
|
|
302547
302776
|
"PUT /api/v2/follow-up/agents/:id",
|
|
302548
302777
|
"PUT /api/v2/follow-up/chats/:id",
|
|
@@ -302727,7 +302956,7 @@ function refuseUnaddressableRoute(c) {
|
|
|
302727
302956
|
}
|
|
302728
302957
|
var TENANT_HINT_HEADER = "x-omni-tenant-id", tenancyMiddleware;
|
|
302729
302958
|
var init_tenancy = __esm(() => {
|
|
302730
|
-
|
|
302959
|
+
init_factory3();
|
|
302731
302960
|
init_route();
|
|
302732
302961
|
init_route_ownership();
|
|
302733
302962
|
init_scope_projection();
|
|
@@ -351163,24 +351392,24 @@ class InMemoryPluginStorage {
|
|
|
351163
351392
|
}
|
|
351164
351393
|
function setStorageDatabase(db2) {
|
|
351165
351394
|
globalDb = db2;
|
|
351166
|
-
for (const [pluginId,
|
|
351167
|
-
if (
|
|
351395
|
+
for (const [pluginId, storage3] of storageInstances.entries()) {
|
|
351396
|
+
if (storage3 instanceof InMemoryPluginStorage) {
|
|
351168
351397
|
storageInstances.set(pluginId, new DatabasePluginStorage(db2, pluginId));
|
|
351169
351398
|
}
|
|
351170
351399
|
}
|
|
351171
351400
|
}
|
|
351172
351401
|
function getPluginStorage(pluginId) {
|
|
351173
|
-
let
|
|
351174
|
-
if (!
|
|
351402
|
+
let storage3 = storageInstances.get(pluginId);
|
|
351403
|
+
if (!storage3) {
|
|
351175
351404
|
if (globalDb) {
|
|
351176
|
-
|
|
351405
|
+
storage3 = new DatabasePluginStorage(globalDb, pluginId);
|
|
351177
351406
|
} else {
|
|
351178
351407
|
log87.warn("Database not available, using in-memory storage", { pluginId });
|
|
351179
|
-
|
|
351408
|
+
storage3 = new InMemoryPluginStorage(pluginId);
|
|
351180
351409
|
}
|
|
351181
|
-
storageInstances.set(pluginId,
|
|
351410
|
+
storageInstances.set(pluginId, storage3);
|
|
351182
351411
|
}
|
|
351183
|
-
return
|
|
351412
|
+
return storage3;
|
|
351184
351413
|
}
|
|
351185
351414
|
var log87, INSTANCE_ID_IN_KEY, globalDb = null, storageInstances;
|
|
351186
351415
|
var init_storage = __esm(() => {
|
|
@@ -355451,7 +355680,8 @@ async function setupAgentDispatcher(eventBus, services, db2) {
|
|
|
355451
355680
|
tracker.recordCheckpoint(firstMsg.metadata.correlationId, "T5", JOURNEY_STAGES.T5);
|
|
355452
355681
|
}
|
|
355453
355682
|
queuedAck?.release();
|
|
355454
|
-
|
|
355683
|
+
const lastMsg = messages4[messages4.length - 1] ?? firstMsg;
|
|
355684
|
+
await runWithEventCausality({ correlationId: lastMsg.metadata.correlationId, causationId: lastMsg.metadata.eventId }, () => processAgentResponse(services, instance4, messages4, triggerType, db2, eventBus));
|
|
355455
355685
|
};
|
|
355456
355686
|
const debouncer = new MessageDebouncer(onDebouncedFlush, Date.now, {
|
|
355457
355687
|
onQueuedBehindActiveRun: (info2) => void ackQueuedMessage(info2)
|
|
@@ -355488,6 +355718,7 @@ async function setupAgentDispatcher(eventBus, services, db2) {
|
|
|
355488
355718
|
platformIdentityId: metadata.platformIdentityId,
|
|
355489
355719
|
traceId,
|
|
355490
355720
|
correlationId: metadata.correlationId,
|
|
355721
|
+
eventId: event.id,
|
|
355491
355722
|
journeyTracked: metadata.timings != null,
|
|
355492
355723
|
resolvedInstance: resolved,
|
|
355493
355724
|
routeId,
|
|
@@ -355519,14 +355750,14 @@ async function setupAgentDispatcher(eventBus, services, db2) {
|
|
|
355519
355750
|
if (!instance4)
|
|
355520
355751
|
return;
|
|
355521
355752
|
const traceId = metadata.traceId ?? generateCorrelationId("trc");
|
|
355522
|
-
await processReactionTrigger(services, instance4, payload, {
|
|
355753
|
+
await runWithEventCausality({ correlationId: metadata.correlationId, causationId: event.id }, () => processReactionTrigger(services, instance4, payload, {
|
|
355523
355754
|
instanceId: instance4.id,
|
|
355524
355755
|
channelType: metadata.channelType,
|
|
355525
355756
|
personId: metadata.personId,
|
|
355526
355757
|
platformIdentityId: metadata.platformIdentityId,
|
|
355527
355758
|
traceId,
|
|
355528
355759
|
trustedTenantId: trustedDispatchTenant(metadata)
|
|
355529
|
-
}, event, db2);
|
|
355760
|
+
}, event, db2));
|
|
355530
355761
|
} catch (error3) {
|
|
355531
355762
|
log91.error("Error processing reaction for dispatch", {
|
|
355532
355763
|
instanceId: metadata.instanceId,
|
|
@@ -355551,14 +355782,14 @@ async function setupAgentDispatcher(eventBus, services, db2) {
|
|
|
355551
355782
|
if (!instance4)
|
|
355552
355783
|
return;
|
|
355553
355784
|
const traceId = metadata.traceId ?? generateCorrelationId("trc");
|
|
355554
|
-
await processReactionTrigger(services, instance4, payload, {
|
|
355785
|
+
await runWithEventCausality({ correlationId: metadata.correlationId, causationId: event.id }, () => processReactionTrigger(services, instance4, payload, {
|
|
355555
355786
|
instanceId: instance4.id,
|
|
355556
355787
|
channelType: metadata.channelType,
|
|
355557
355788
|
personId: metadata.personId,
|
|
355558
355789
|
platformIdentityId: metadata.platformIdentityId,
|
|
355559
355790
|
traceId,
|
|
355560
355791
|
trustedTenantId: trustedDispatchTenant(metadata)
|
|
355561
|
-
}, event, db2);
|
|
355792
|
+
}, event, db2));
|
|
355562
355793
|
} catch (error3) {
|
|
355563
355794
|
log91.error("Error processing reaction removal for dispatch", {
|
|
355564
355795
|
instanceId: metadata.instanceId,
|
|
@@ -358067,6 +358298,9 @@ class DeadLetterService {
|
|
|
358067
358298
|
}
|
|
358068
358299
|
async create(options) {
|
|
358069
358300
|
const insertData = prepareDeadLetterInsert(options);
|
|
358301
|
+
if (options.autoRetry === false) {
|
|
358302
|
+
insertData.nextAutoRetryAt = null;
|
|
358303
|
+
}
|
|
358070
358304
|
const [result] = await this.db.insert(deadLetterEvents).values(insertData).returning();
|
|
358071
358305
|
if (!result) {
|
|
358072
358306
|
throw new Error("Failed to create dead letter entry");
|
|
@@ -358741,6 +358975,46 @@ class EventService {
|
|
|
358741
358975
|
}
|
|
358742
358976
|
return result;
|
|
358743
358977
|
}
|
|
358978
|
+
async trace(id) {
|
|
358979
|
+
const focus = await this.getById(id);
|
|
358980
|
+
const seen = new Set([focus.id]);
|
|
358981
|
+
const ancestors = [];
|
|
358982
|
+
let current = focus;
|
|
358983
|
+
let truncated = false;
|
|
358984
|
+
while (current.causationId && ancestors.length < TRACE_MAX_ANCESTORS) {
|
|
358985
|
+
if (seen.has(current.causationId))
|
|
358986
|
+
break;
|
|
358987
|
+
const [parent] = await this.db.select().from(omniEvents).where(eq(omniEvents.id, current.causationId)).limit(1);
|
|
358988
|
+
if (!parent)
|
|
358989
|
+
break;
|
|
358990
|
+
seen.add(parent.id);
|
|
358991
|
+
ancestors.unshift(parent);
|
|
358992
|
+
current = parent;
|
|
358993
|
+
}
|
|
358994
|
+
if (current.causationId && ancestors.length >= TRACE_MAX_ANCESTORS)
|
|
358995
|
+
truncated = true;
|
|
358996
|
+
const descendants = [];
|
|
358997
|
+
let frontier = [focus.id];
|
|
358998
|
+
let depth = 0;
|
|
358999
|
+
while (frontier.length > 0 && depth < TRACE_MAX_DEPTH && descendants.length < TRACE_MAX_NODES) {
|
|
359000
|
+
depth++;
|
|
359001
|
+
const children = await this.db.select().from(omniEvents).where(inArray(omniEvents.causationId, frontier)).orderBy(omniEvents.receivedAt).limit(TRACE_MAX_NODES + 1);
|
|
359002
|
+
const fresh = children.filter((c) => !seen.has(c.id));
|
|
359003
|
+
for (const child of fresh)
|
|
359004
|
+
seen.add(child.id);
|
|
359005
|
+
for (const child of fresh)
|
|
359006
|
+
descendants.push({ event: child, depth });
|
|
359007
|
+
if (descendants.length > TRACE_MAX_NODES) {
|
|
359008
|
+
descendants.length = TRACE_MAX_NODES;
|
|
359009
|
+
truncated = true;
|
|
359010
|
+
break;
|
|
359011
|
+
}
|
|
359012
|
+
frontier = fresh.map((c) => c.id);
|
|
359013
|
+
}
|
|
359014
|
+
if (frontier.length > 0 && depth >= TRACE_MAX_DEPTH)
|
|
359015
|
+
truncated = true;
|
|
359016
|
+
return { event: focus, ancestors, descendants, truncated };
|
|
359017
|
+
}
|
|
358744
359018
|
async getTimeline(personId, options = {}) {
|
|
358745
359019
|
const { channels, since, until, limit: limit2 = 50, cursor } = options;
|
|
358746
359020
|
const conditions3 = [eq(omniEvents.personId, personId)];
|
|
@@ -358842,6 +359116,7 @@ class EventService {
|
|
|
358842
359116
|
};
|
|
358843
359117
|
}
|
|
358844
359118
|
}
|
|
359119
|
+
var TRACE_MAX_ANCESTORS = 50, TRACE_MAX_DEPTH = 10, TRACE_MAX_NODES = 200;
|
|
358845
359120
|
var init_events2 = __esm(() => {
|
|
358846
359121
|
init_src();
|
|
358847
359122
|
init_src5();
|
|
@@ -363201,7 +363476,10 @@ class WebhookService {
|
|
|
363201
363476
|
if (data.signatureSecret && !data.signatureConfig) {
|
|
363202
363477
|
throw new ValidationError2("signatureSecret cannot be set without a signatureConfig");
|
|
363203
363478
|
}
|
|
363204
|
-
|
|
363479
|
+
let values2 = data.signatureSecret ? { ...data, signatureSecret: sealCredentialField(this.tenantId, data.signatureSecret) } : data;
|
|
363480
|
+
if (values2.expectedIntervalSeconds != null) {
|
|
363481
|
+
values2 = { ...values2, livenessArmedAt: new Date, livenessStatus: "healthy" };
|
|
363482
|
+
}
|
|
363205
363483
|
const [created] = await this.db.insert(webhookSources).values(values2).returning();
|
|
363206
363484
|
if (!created) {
|
|
363207
363485
|
throw new Error("Failed to create webhook source");
|
|
@@ -363227,12 +363505,28 @@ class WebhookService {
|
|
|
363227
363505
|
patch.signatureSecret = null;
|
|
363228
363506
|
}
|
|
363229
363507
|
}
|
|
363508
|
+
await this.applyLivenessArming(id, data, patch);
|
|
363230
363509
|
const [updated] = await this.db.update(webhookSources).set({ ...patch, updatedAt: new Date }).where(eq(webhookSources.id, id)).returning();
|
|
363231
363510
|
if (!updated) {
|
|
363232
363511
|
throw new NotFoundError("WebhookSource", id);
|
|
363233
363512
|
}
|
|
363234
363513
|
return updated;
|
|
363235
363514
|
}
|
|
363515
|
+
async applyLivenessArming(id, data, patch) {
|
|
363516
|
+
if (data.expectedIntervalSeconds === undefined)
|
|
363517
|
+
return;
|
|
363518
|
+
if (data.expectedIntervalSeconds === null) {
|
|
363519
|
+
patch.livenessStatus = null;
|
|
363520
|
+
patch.livenessArmedAt = null;
|
|
363521
|
+
patch.stalledAt = null;
|
|
363522
|
+
return;
|
|
363523
|
+
}
|
|
363524
|
+
patch.livenessArmedAt = new Date;
|
|
363525
|
+
const existing = await this.getById(id);
|
|
363526
|
+
if (existing.livenessStatus === null) {
|
|
363527
|
+
patch.livenessStatus = "healthy";
|
|
363528
|
+
}
|
|
363529
|
+
}
|
|
363236
363530
|
async delete(id) {
|
|
363237
363531
|
const result = await this.db.delete(webhookSources).where(eq(webhookSources.id, id)).returning();
|
|
363238
363532
|
if (!result.length) {
|
|
@@ -363275,12 +363569,12 @@ class WebhookService {
|
|
|
363275
363569
|
}
|
|
363276
363570
|
}
|
|
363277
363571
|
}
|
|
363278
|
-
const eventId = generateId();
|
|
363279
363572
|
const eventType = resolveWebhookEventType(sourceName, source.eventTypeMapping, headers);
|
|
363280
363573
|
const eventPayload = {
|
|
363281
363574
|
source: sourceName,
|
|
363282
363575
|
...payload
|
|
363283
363576
|
};
|
|
363577
|
+
let eventId = generateId();
|
|
363284
363578
|
await this.enforceRegisteredSchema(eventType, eventPayload, eventId, `webhook '${sourceName}'`);
|
|
363285
363579
|
await this.db.update(webhookSources).set({
|
|
363286
363580
|
lastReceivedAt: new Date,
|
|
@@ -363288,10 +363582,10 @@ class WebhookService {
|
|
|
363288
363582
|
updatedAt: new Date
|
|
363289
363583
|
}).where(eq(webhookSources.id, source.id));
|
|
363290
363584
|
if (this.eventBus) {
|
|
363291
|
-
await this.eventBus.publishGeneric(eventType, eventPayload, {
|
|
363292
|
-
correlationId: eventId,
|
|
363585
|
+
const result = await this.eventBus.publishGeneric(eventType, eventPayload, {
|
|
363293
363586
|
source: "webhook"
|
|
363294
363587
|
});
|
|
363588
|
+
eventId = result.id;
|
|
363295
363589
|
}
|
|
363296
363590
|
return {
|
|
363297
363591
|
received: true,
|
|
@@ -363348,17 +363642,112 @@ class WebhookService {
|
|
|
363348
363642
|
throw new ValidationError2(`${SCHEMA_VALIDATION_FAILED}: payload for '${eventType}' violates its registered schema (${origin})`, undefined, { eventType, errors: verdict.errors });
|
|
363349
363643
|
}
|
|
363350
363644
|
async trigger(eventType, payload, metadata) {
|
|
363351
|
-
const
|
|
363352
|
-
await this.enforceRegisteredSchema(eventType, payload,
|
|
363645
|
+
const provisionalId = metadata?.correlationId ?? generateId();
|
|
363646
|
+
await this.enforceRegisteredSchema(eventType, payload, provisionalId, "manual trigger");
|
|
363353
363647
|
if (this.eventBus) {
|
|
363354
|
-
await this.eventBus.publishGeneric(eventType, payload, {
|
|
363355
|
-
correlationId:
|
|
363648
|
+
const result = await this.eventBus.publishGeneric(eventType, payload, {
|
|
363649
|
+
correlationId: metadata?.correlationId,
|
|
363356
363650
|
instanceId: metadata?.instanceId,
|
|
363357
363651
|
source: "manual-trigger"
|
|
363358
363652
|
});
|
|
363359
|
-
return { eventId, published: true };
|
|
363653
|
+
return { eventId: result.id, published: true };
|
|
363654
|
+
}
|
|
363655
|
+
return { eventId: provisionalId, published: false };
|
|
363656
|
+
}
|
|
363657
|
+
async heartbeat(sourceName) {
|
|
363658
|
+
const source = await this.getByName(sourceName);
|
|
363659
|
+
if (!source) {
|
|
363660
|
+
throw new NotFoundError("WebhookSource", sourceName);
|
|
363661
|
+
}
|
|
363662
|
+
if (!source.enabled) {
|
|
363663
|
+
throw new OmniError({
|
|
363664
|
+
code: ERROR_CODES.FORBIDDEN,
|
|
363665
|
+
message: `Webhook source '${sourceName}' is disabled`,
|
|
363666
|
+
context: { sourceName }
|
|
363667
|
+
});
|
|
363668
|
+
}
|
|
363669
|
+
const now = new Date;
|
|
363670
|
+
await this.db.update(webhookSources).set({
|
|
363671
|
+
lastHeartbeatAt: now,
|
|
363672
|
+
heartbeatCount: sql`${webhookSources.heartbeatCount} + 1`,
|
|
363673
|
+
updatedAt: now
|
|
363674
|
+
}).where(eq(webhookSources.id, source.id));
|
|
363675
|
+
return {
|
|
363676
|
+
ok: true,
|
|
363677
|
+
source: sourceName,
|
|
363678
|
+
heartbeatAt: now.toISOString(),
|
|
363679
|
+
livenessStatus: source.livenessStatus,
|
|
363680
|
+
expectedIntervalSeconds: source.expectedIntervalSeconds
|
|
363681
|
+
};
|
|
363682
|
+
}
|
|
363683
|
+
async sweepLiveness(options = {}) {
|
|
363684
|
+
const { deadLetters } = options;
|
|
363685
|
+
const hooks2 = deadLetters ? {
|
|
363686
|
+
onStalled: (row, payload, publishedEventId) => fileStallDeadLetter(deadLetters, row, payload, publishedEventId),
|
|
363687
|
+
onRecovered: (row) => resolveStallDeadLetters(deadLetters, row)
|
|
363688
|
+
} : {};
|
|
363689
|
+
return sweepConnectorLiveness({
|
|
363690
|
+
repo: this.livenessRepo(),
|
|
363691
|
+
eventBus: this.eventBus,
|
|
363692
|
+
logger: log111,
|
|
363693
|
+
...hooks2
|
|
363694
|
+
});
|
|
363695
|
+
}
|
|
363696
|
+
livenessRepo() {
|
|
363697
|
+
return {
|
|
363698
|
+
findSupervised: async () => {
|
|
363699
|
+
const rows = await this.db.select().from(webhookSources).where(and2(eq(webhookSources.enabled, true), isNotNull(webhookSources.expectedIntervalSeconds)));
|
|
363700
|
+
return rows.filter((row) => row.expectedIntervalSeconds !== null).map((row) => ({
|
|
363701
|
+
id: row.id,
|
|
363702
|
+
name: row.name,
|
|
363703
|
+
expectedIntervalSeconds: row.expectedIntervalSeconds,
|
|
363704
|
+
lastReceivedAt: row.lastReceivedAt,
|
|
363705
|
+
lastHeartbeatAt: row.lastHeartbeatAt,
|
|
363706
|
+
livenessArmedAt: row.livenessArmedAt,
|
|
363707
|
+
livenessStatus: row.livenessStatus,
|
|
363708
|
+
stalledAt: row.stalledAt,
|
|
363709
|
+
createdAt: row.createdAt,
|
|
363710
|
+
tenantId: row.tenantId
|
|
363711
|
+
}));
|
|
363712
|
+
},
|
|
363713
|
+
markStalled: async (id, at) => {
|
|
363714
|
+
const res = await this.db.update(webhookSources).set({ livenessStatus: "stalled", stalledAt: at, updatedAt: at }).where(and2(eq(webhookSources.id, id), sql`${webhookSources.livenessStatus} IS DISTINCT FROM 'stalled'`)).returning({ id: webhookSources.id });
|
|
363715
|
+
return res.length > 0;
|
|
363716
|
+
},
|
|
363717
|
+
markRecovered: async (id, at) => {
|
|
363718
|
+
const res = await this.db.update(webhookSources).set({ livenessStatus: "healthy", stalledAt: null, updatedAt: at }).where(and2(eq(webhookSources.id, id), eq(webhookSources.livenessStatus, "stalled"))).returning({ id: webhookSources.id });
|
|
363719
|
+
return res.length > 0;
|
|
363720
|
+
}
|
|
363721
|
+
};
|
|
363722
|
+
}
|
|
363723
|
+
}
|
|
363724
|
+
async function fileStallDeadLetter(deadLetters, row, payload, publishedEventId) {
|
|
363725
|
+
const event = {
|
|
363726
|
+
id: publishedEventId ?? generateId(),
|
|
363727
|
+
type: "system.connector.stalled",
|
|
363728
|
+
payload: { ...payload },
|
|
363729
|
+
metadata: {
|
|
363730
|
+
correlationId: generateId(),
|
|
363731
|
+
source: "connector-liveness",
|
|
363732
|
+
...row.tenantId ? { tenantId: row.tenantId } : {}
|
|
363733
|
+
},
|
|
363734
|
+
timestamp: payload.stalledAt
|
|
363735
|
+
};
|
|
363736
|
+
await deadLetters.create({
|
|
363737
|
+
event,
|
|
363738
|
+
subject: "system.connector.stalled.internal.global",
|
|
363739
|
+
error: new Error(`Connector '${row.name}' declared >=1 event or heartbeat per ${row.expectedIntervalSeconds}s ` + `but has been silent for ${payload.silentForSeconds}s`),
|
|
363740
|
+
retryCount: 0,
|
|
363741
|
+
autoRetry: false
|
|
363742
|
+
});
|
|
363743
|
+
}
|
|
363744
|
+
async function resolveStallDeadLetters(deadLetters, row) {
|
|
363745
|
+
const { items } = await deadLetters.list({ status: ["pending"], eventType: ["system.connector.stalled"] });
|
|
363746
|
+
for (const entry of items) {
|
|
363747
|
+
const stored = entry.payload;
|
|
363748
|
+
if (stored.payload?.sourceId === row.id) {
|
|
363749
|
+
await deadLetters.resolve(entry.id, "connector-liveness: recovered");
|
|
363360
363750
|
}
|
|
363361
|
-
return { eventId, published: false };
|
|
363362
363751
|
}
|
|
363363
363752
|
}
|
|
363364
363753
|
var log111;
|
|
@@ -363526,7 +363915,7 @@ function createContextMiddleware(db2, eventBus, channelRegistry2 = null) {
|
|
|
363526
363915
|
return { middleware, services };
|
|
363527
363916
|
}
|
|
363528
363917
|
var init_context4 = __esm(() => {
|
|
363529
|
-
|
|
363918
|
+
init_factory3();
|
|
363530
363919
|
init_services();
|
|
363531
363920
|
});
|
|
363532
363921
|
|
|
@@ -363901,7 +364290,7 @@ function createRateLimiter2(config4 = RATE_LIMITS.general, keyPrefix = "ratelimi
|
|
|
363901
364290
|
var log113, warnedUnparseableProxyHop = false, rateLimitStore, cleanupTimer, RATE_LIMITS, clientIpSchema, rateLimitMiddleware, webhookIngressRateLimitMiddleware;
|
|
363902
364291
|
var init_rate_limit = __esm(() => {
|
|
363903
364292
|
init_src();
|
|
363904
|
-
|
|
364293
|
+
init_factory3();
|
|
363905
364294
|
init_zod();
|
|
363906
364295
|
log113 = createLogger("api:rate-limit");
|
|
363907
364296
|
rateLimitStore = new Map;
|
|
@@ -363945,7 +364334,7 @@ function timeoutMiddleware(config4 = {}) {
|
|
|
363945
364334
|
}
|
|
363946
364335
|
var DEFAULT_TIMEOUT_MS8 = 30000, defaultTimeoutMiddleware;
|
|
363947
364336
|
var init_timeout = __esm(() => {
|
|
363948
|
-
|
|
364337
|
+
init_factory3();
|
|
363949
364338
|
init_http_exception();
|
|
363950
364339
|
defaultTimeoutMiddleware = timeoutMiddleware();
|
|
363951
364340
|
});
|
|
@@ -363999,7 +364388,7 @@ function loadServerVersionInfo() {
|
|
|
363999
364388
|
}
|
|
364000
364389
|
var import__package, EMBEDDED_VERSION, LAST_RESORT_VERSION = "2.0.0-dev.1", FALLBACK_COMMIT = "unknown", SERVER_VERSION_INFO, versionHeadersMiddleware;
|
|
364001
364390
|
var init_version_headers = __esm(() => {
|
|
364002
|
-
|
|
364391
|
+
init_factory3();
|
|
364003
364392
|
import__package = __toESM(require_package7(), 1);
|
|
364004
364393
|
EMBEDDED_VERSION = import__package.default?.version;
|
|
364005
364394
|
SERVER_VERSION_INFO = loadServerVersionInfo();
|
|
@@ -364038,7 +364427,7 @@ function createWebhookAuthMiddleware(config4) {
|
|
|
364038
364427
|
var log114;
|
|
364039
364428
|
var init_webhook_auth = __esm(() => {
|
|
364040
364429
|
init_src();
|
|
364041
|
-
|
|
364430
|
+
init_factory3();
|
|
364042
364431
|
log114 = createLogger("api:webhook-auth");
|
|
364043
364432
|
});
|
|
364044
364433
|
|
|
@@ -366358,7 +366747,8 @@ var init_automations3 = __esm(() => {
|
|
|
366358
366747
|
bodyTemplate: exports_external.string().optional(),
|
|
366359
366748
|
waitForResponse: exports_external.boolean().default(false),
|
|
366360
366749
|
timeoutMs: exports_external.number().int().default(30000),
|
|
366361
|
-
responseAs: exports_external.string().optional()
|
|
366750
|
+
responseAs: exports_external.string().optional(),
|
|
366751
|
+
includeEnvelope: exports_external.boolean().optional().openapi({ description: "Send the full OmniEvent envelope as the default body (default true)" })
|
|
366362
366752
|
})
|
|
366363
366753
|
});
|
|
366364
366754
|
SendMessageActionSchema = exports_external.object({
|
|
@@ -366994,6 +367384,7 @@ function registerEventSchemas(registry4) {
|
|
|
366994
367384
|
registry4.register("EventSummary", EventSummarySchema);
|
|
366995
367385
|
registry4.register("EventAnalytics", EventAnalyticsSchema);
|
|
366996
367386
|
registry4.register("EventSearch", EventSearchSchema);
|
|
367387
|
+
registry4.register("EventTrace", EventTraceSchema);
|
|
366997
367388
|
registry4.registerPath({
|
|
366998
367389
|
method: "get",
|
|
366999
367390
|
path: "/events",
|
|
@@ -367118,6 +367509,22 @@ function registerEventSchemas(registry4) {
|
|
|
367118
367509
|
404: { description: "Event not found", content: { "application/json": { schema: ErrorSchema } } }
|
|
367119
367510
|
}
|
|
367120
367511
|
});
|
|
367512
|
+
registry4.registerPath({
|
|
367513
|
+
method: "get",
|
|
367514
|
+
path: "/events/{id}/trace",
|
|
367515
|
+
operationId: "traceEvent",
|
|
367516
|
+
tags: ["Events"],
|
|
367517
|
+
summary: "Trace the causality chain around an event",
|
|
367518
|
+
description: "Walks UP via causationId to the root ingress event and DOWN breadth-first through fan-out (children are events whose causationId equals this id). correlationId groups the flow; causationId gives the tree.",
|
|
367519
|
+
request: { params: exports_external.object({ id: exports_external.string().uuid().openapi({ description: "Event UUID" }) }) },
|
|
367520
|
+
responses: {
|
|
367521
|
+
200: {
|
|
367522
|
+
description: "Causality trace",
|
|
367523
|
+
content: { "application/json": { schema: exports_external.object({ data: EventTraceSchema }) } }
|
|
367524
|
+
},
|
|
367525
|
+
404: { description: "Event not found", content: { "application/json": { schema: ErrorSchema } } }
|
|
367526
|
+
}
|
|
367527
|
+
});
|
|
367121
367528
|
registry4.registerPath({
|
|
367122
367529
|
method: "get",
|
|
367123
367530
|
path: "/events/by-sender/{senderId}",
|
|
@@ -367147,7 +367554,7 @@ function registerEventSchemas(registry4) {
|
|
|
367147
367554
|
}
|
|
367148
367555
|
});
|
|
367149
367556
|
}
|
|
367150
|
-
var EventSchema, EventSummarySchema, EventAnalyticsSchema, EventSearchSchema;
|
|
367557
|
+
var EventSchema, EventSummarySchema, EventAnalyticsSchema, EventTraceSchema, EventSearchSchema;
|
|
367151
367558
|
var init_events3 = __esm(() => {
|
|
367152
367559
|
init_zod_openapi();
|
|
367153
367560
|
init_common4();
|
|
@@ -367165,7 +367572,8 @@ var init_events3 = __esm(() => {
|
|
|
367165
367572
|
agentId: exports_external.string().uuid().nullable().openapi({ description: "Agent UUID (FK \u2192 agents.id)" }),
|
|
367166
367573
|
conversationId: exports_external.string().uuid().nullable().openapi({ description: "Conversation UUID (FK \u2192 conversations.id)" }),
|
|
367167
367574
|
receivedAt: exports_external.string().datetime().openapi({ description: "When event was received" }),
|
|
367168
|
-
processedAt: exports_external.string().datetime().nullable().openapi({ description: "When event was processed" })
|
|
367575
|
+
processedAt: exports_external.string().datetime().nullable().openapi({ description: "When event was processed" }),
|
|
367576
|
+
causationId: exports_external.string().uuid().nullable().openapi({ description: "Id of the immediate parent event (null for roots and pre-#957 rows)" })
|
|
367169
367577
|
});
|
|
367170
367578
|
EventSummarySchema = exports_external.object({
|
|
367171
367579
|
id: exports_external.string().uuid().openapi({ description: "Event UUID" }),
|
|
@@ -367194,6 +367602,15 @@ var init_events3 = __esm(() => {
|
|
|
367194
367602
|
count: exports_external.number().int().openapi({ description: "Event count in bucket" })
|
|
367195
367603
|
})).optional().openapi({ description: "Timeline data (hourly or daily buckets)" })
|
|
367196
367604
|
});
|
|
367605
|
+
EventTraceSchema = exports_external.object({
|
|
367606
|
+
event: EventSchema.openapi({ description: "The event the trace was requested for" }),
|
|
367607
|
+
ancestors: exports_external.array(EventSchema).openapi({ description: "Chain above the event via causationId, root first, ending at the immediate parent" }),
|
|
367608
|
+
descendants: exports_external.array(exports_external.object({
|
|
367609
|
+
event: EventSchema,
|
|
367610
|
+
depth: exports_external.number().int().openapi({ description: "Distance below the focus event (1 = direct child)" })
|
|
367611
|
+
})).openapi({ description: "Fan-out below the event, breadth-first" }),
|
|
367612
|
+
truncated: exports_external.boolean().openapi({ description: "True when a depth/node cap cut the walk short" })
|
|
367613
|
+
});
|
|
367197
367614
|
EventSearchSchema = exports_external.object({
|
|
367198
367615
|
query: exports_external.string().optional().openapi({ description: "Full-text search query" }),
|
|
367199
367616
|
filters: exports_external.object({
|
|
@@ -369789,6 +370206,7 @@ function registerWebhookSchemas(registry4) {
|
|
|
369789
370206
|
registry4.register("CreateWebhookSourceRequest", CreateWebhookSourceSchema);
|
|
369790
370207
|
registry4.register("TriggerEventRequest", TriggerEventSchema);
|
|
369791
370208
|
registry4.register("WebhookReceiveResponse", WebhookReceiveResponseSchema);
|
|
370209
|
+
registry4.register("WebhookHeartbeatResponse", WebhookHeartbeatResponseSchema);
|
|
369792
370210
|
registry4.registerPath({
|
|
369793
370211
|
method: "get",
|
|
369794
370212
|
path: "/webhook-sources",
|
|
@@ -369887,6 +370305,25 @@ function registerWebhookSchemas(registry4) {
|
|
|
369887
370305
|
400: { description: "Body is not a JSON object", content: { "application/json": { schema: ErrorSchema } } }
|
|
369888
370306
|
}
|
|
369889
370307
|
});
|
|
370308
|
+
registry4.registerPath({
|
|
370309
|
+
method: "post",
|
|
370310
|
+
path: "/webhooks/{source}/heartbeat",
|
|
370311
|
+
operationId: "heartbeatWebhookSource",
|
|
370312
|
+
tags: ["Webhooks"],
|
|
370313
|
+
summary: "Connector heartbeat",
|
|
370314
|
+
description: 'Record a connector heartbeat: "I ran, zero events found". Resets the liveness window of a supervised ' + "source (one declaring expectedIntervalSeconds) so silence-beyond-window detection can tell quiet from " + "dead. Creates NO journal event \u2014 only the stalled/recovered transitions are journaled. No request body.",
|
|
370315
|
+
request: {
|
|
370316
|
+
params: exports_external.object({ source: exports_external.string().openapi({ description: "Source name" }) })
|
|
370317
|
+
},
|
|
370318
|
+
responses: {
|
|
370319
|
+
200: {
|
|
370320
|
+
description: "Heartbeat recorded",
|
|
370321
|
+
content: { "application/json": { schema: WebhookHeartbeatResponseSchema } }
|
|
370322
|
+
},
|
|
370323
|
+
403: { description: "Source disabled", content: { "application/json": { schema: ErrorSchema } } },
|
|
370324
|
+
404: { description: "Source not found", content: { "application/json": { schema: ErrorSchema } } }
|
|
370325
|
+
}
|
|
370326
|
+
});
|
|
369890
370327
|
registry4.registerPath({
|
|
369891
370328
|
method: "post",
|
|
369892
370329
|
path: "/webhooks/ingress/{source}",
|
|
@@ -369925,7 +370362,7 @@ function registerWebhookSchemas(registry4) {
|
|
|
369925
370362
|
}
|
|
369926
370363
|
});
|
|
369927
370364
|
}
|
|
369928
|
-
var WebhookSignatureConfigSchema, WebhookEventTypeMappingSchema, WebhookSourceSchema, CreateWebhookSourceSchema, TriggerEventSchema, WebhookReceiveResponseSchema;
|
|
370365
|
+
var WebhookSignatureConfigSchema, WebhookEventTypeMappingSchema, WebhookSourceSchema, CreateWebhookSourceSchema, WebhookHeartbeatResponseSchema, TriggerEventSchema, WebhookReceiveResponseSchema;
|
|
369929
370366
|
var init_webhooks2 = __esm(() => {
|
|
369930
370367
|
init_src5();
|
|
369931
370368
|
init_zod_openapi();
|
|
@@ -369963,6 +370400,16 @@ var init_webhooks2 = __esm(() => {
|
|
|
369963
370400
|
}),
|
|
369964
370401
|
hasSignatureSecret: exports_external.boolean().openapi({ description: "Whether a signature secret is stored (secret is write-only)" }),
|
|
369965
370402
|
enabled: exports_external.boolean().openapi({ description: "Whether enabled" }),
|
|
370403
|
+
lastReceivedAt: exports_external.string().datetime().nullable().openapi({ description: "When the last webhook was received" }),
|
|
370404
|
+
totalReceived: exports_external.number().int().openapi({ description: "Total webhooks received" }),
|
|
370405
|
+
expectedIntervalSeconds: exports_external.number().int().nullable().openapi({ description: "Declared cadence: >=1 event or heartbeat per N seconds. Null = unsupervised" }),
|
|
370406
|
+
lastHeartbeatAt: exports_external.string().datetime().nullable().openapi({ description: 'Last heartbeat ("ran, zero events")' }),
|
|
370407
|
+
heartbeatCount: exports_external.number().int().openapi({ description: "Total heartbeats received" }),
|
|
370408
|
+
livenessStatus: exports_external.enum(connectorLivenessStatuses).nullable().openapi({ description: "Liveness state; null = unsupervised. Transitions emit system.connector.* events" }),
|
|
370409
|
+
livenessArmedAt: exports_external.string().datetime().nullable().openapi({ description: "When the cadence was (re)declared" }),
|
|
370410
|
+
stalledAt: exports_external.string().datetime().nullable().openapi({ description: "When the current stall began" }),
|
|
370411
|
+
windowSemantics: exports_external.enum(connectorWindowSemanticsValues).nullable().openapi({ description: "Declared window semantics; null = undeclared" }),
|
|
370412
|
+
mutationPolicy: exports_external.enum(connectorMutationPolicies).nullable().openapi({ description: "Declared upstream-mutation re-emit policy; null = undeclared" }),
|
|
369966
370413
|
createdAt: exports_external.string().datetime().openapi({ description: "Creation timestamp" }),
|
|
369967
370414
|
updatedAt: exports_external.string().datetime().openapi({ description: "Last update timestamp" })
|
|
369968
370415
|
});
|
|
@@ -369979,7 +370426,23 @@ var init_webhooks2 = __esm(() => {
|
|
|
369979
370426
|
eventTypeMapping: WebhookEventTypeMappingSchema.nullable().optional().openapi({
|
|
369980
370427
|
description: "Semantic event-type extraction (e.g. header X-GitHub-Event: push emits custom.{source}.push). " + "Null or absent keeps the legacy collapsed custom.webhook.{source} type for every delivery."
|
|
369981
370428
|
}),
|
|
369982
|
-
enabled: exports_external.boolean().default(true).openapi({ description: "Whether enabled" })
|
|
370429
|
+
enabled: exports_external.boolean().default(true).openapi({ description: "Whether enabled" }),
|
|
370430
|
+
expectedIntervalSeconds: exports_external.number().int().min(1).max(2592000).nullable().optional().openapi({
|
|
370431
|
+
description: "Declared cadence: the connector promises >=1 event or heartbeat per N seconds (1s-30d). Declaring it " + "arms liveness supervision (silence beyond the window emits system.connector.stalled and marks the " + "source unhealthy); null disarms it."
|
|
370432
|
+
}),
|
|
370433
|
+
windowSemantics: exports_external.enum(connectorWindowSemanticsValues).nullable().optional().openapi({
|
|
370434
|
+
description: "Declared time-window semantics: 'future_only' (only not-yet-started items) or 'includes_in_progress'. " + "Informational contract for consumers; null = undeclared."
|
|
370435
|
+
}),
|
|
370436
|
+
mutationPolicy: exports_external.enum(connectorMutationPolicies).nullable().optional().openapi({
|
|
370437
|
+
description: "How the source re-emits a changed upstream item: 'same_id' (reschedule case \u2014 consumers must key on " + "id+content) or 'new_id'. Feeds the idempotency key template choice; null = undeclared."
|
|
370438
|
+
})
|
|
370439
|
+
});
|
|
370440
|
+
WebhookHeartbeatResponseSchema = exports_external.object({
|
|
370441
|
+
ok: exports_external.literal(true).openapi({ description: "Heartbeat recorded" }),
|
|
370442
|
+
source: exports_external.string().openapi({ description: "Webhook source name" }),
|
|
370443
|
+
heartbeatAt: exports_external.string().datetime().openapi({ description: "When the heartbeat was recorded" }),
|
|
370444
|
+
livenessStatus: exports_external.enum(connectorLivenessStatuses).nullable().openapi({ description: "Status before this heartbeat (a stalled source recovers on the next sweep tick)" }),
|
|
370445
|
+
expectedIntervalSeconds: exports_external.number().int().nullable().openapi({ description: "Declared cadence, if any" })
|
|
369983
370446
|
});
|
|
369984
370447
|
TriggerEventSchema = exports_external.object({
|
|
369985
370448
|
eventType: exports_external.string().min(1).openapi({ description: "Event type (must start with custom.)" }),
|
|
@@ -371547,7 +372010,8 @@ var init_automations4 = __esm(() => {
|
|
|
371547
372010
|
bodyTemplate: exports_external.string().optional().describe("Request body template (JSON)"),
|
|
371548
372011
|
waitForResponse: exports_external.boolean().default(false).describe("Wait for response before continuing"),
|
|
371549
372012
|
timeoutMs: exports_external.number().int().min(1000).max(120000).default(30000).describe("Request timeout"),
|
|
371550
|
-
responseAs: exports_external.string().optional().describe("Store response as variable name")
|
|
372013
|
+
responseAs: exports_external.string().optional().describe("Store response as variable name"),
|
|
372014
|
+
includeEnvelope: exports_external.boolean().optional().describe("Send the full OmniEvent envelope as the default body when no bodyTemplate is set (default true)")
|
|
371551
372015
|
})
|
|
371552
372016
|
});
|
|
371553
372017
|
sendMessageActionSchema = exports_external.object({
|
|
@@ -373343,6 +373807,16 @@ var init_events4 = __esm(() => {
|
|
|
373343
373807
|
}
|
|
373344
373808
|
return c.json({ data: event });
|
|
373345
373809
|
});
|
|
373810
|
+
eventsRoutes.get("/:id/trace", async (c) => {
|
|
373811
|
+
const id = c.req.param("id");
|
|
373812
|
+
const services = c.get("services");
|
|
373813
|
+
const apiKey = c.get("apiKey");
|
|
373814
|
+
const trace24 = await services.events.trace(id);
|
|
373815
|
+
if (trace24.event.instanceId && apiKey && !ApiKeyService.instanceAllowed(apiKey.instanceIds, trace24.event.instanceId)) {
|
|
373816
|
+
return c.json({ error: { code: "FORBIDDEN", message: "API key does not have access to this instance" } }, 403);
|
|
373817
|
+
}
|
|
373818
|
+
return c.json({ data: trace24 });
|
|
373819
|
+
});
|
|
373346
373820
|
eventsRoutes.get("/by-sender/:senderId", async (c) => {
|
|
373347
373821
|
const senderId = c.req.param("senderId");
|
|
373348
373822
|
const instanceId = c.req.query("instanceId");
|
|
@@ -378596,14 +379070,14 @@ var init_media2 = __esm(() => {
|
|
|
378596
379070
|
}
|
|
378597
379071
|
const relativePath = `${instanceId}/${path3}`;
|
|
378598
379072
|
const db2 = c.get("services");
|
|
378599
|
-
const
|
|
379073
|
+
const storage3 = getMediaStorage(db2);
|
|
378600
379074
|
try {
|
|
378601
|
-
const stat5 = await
|
|
379075
|
+
const stat5 = await storage3.statMedia(relativePath);
|
|
378602
379076
|
if (!stat5) {
|
|
378603
379077
|
return c.json({ error: { code: "NOT_FOUND", message: "Media not found" } }, 404);
|
|
378604
379078
|
}
|
|
378605
379079
|
const fileSize = stat5.size;
|
|
378606
|
-
const mimeType =
|
|
379080
|
+
const mimeType = storage3.getMimeType(path3);
|
|
378607
379081
|
const rangeHeader = c.req.header("Range");
|
|
378608
379082
|
if (rangeHeader) {
|
|
378609
379083
|
const matches = rangeHeader.match(/bytes=(\d+)-(\d*)/);
|
|
@@ -378617,7 +379091,7 @@ var init_media2 = __esm(() => {
|
|
|
378617
379091
|
headers: { "Content-Range": `bytes */${fileSize}`, "Accept-Ranges": "bytes" }
|
|
378618
379092
|
});
|
|
378619
379093
|
}
|
|
378620
|
-
const chunk2 = await
|
|
379094
|
+
const chunk2 = await storage3.readMediaRange(relativePath, start, end);
|
|
378621
379095
|
return new Response(chunk2, {
|
|
378622
379096
|
status: 206,
|
|
378623
379097
|
headers: {
|
|
@@ -378629,7 +379103,7 @@ var init_media2 = __esm(() => {
|
|
|
378629
379103
|
});
|
|
378630
379104
|
}
|
|
378631
379105
|
}
|
|
378632
|
-
const stream2 = await
|
|
379106
|
+
const stream2 = await storage3.readMediaStream(relativePath);
|
|
378633
379107
|
return new Response(stream2, {
|
|
378634
379108
|
status: 200,
|
|
378635
379109
|
headers: {
|
|
@@ -382522,6 +382996,12 @@ var init_webhooks3 = __esm(() => {
|
|
|
382522
382996
|
});
|
|
382523
382997
|
return c.json(result);
|
|
382524
382998
|
});
|
|
382999
|
+
webhooksRoutes.post("/webhooks/:source/heartbeat", async (c) => {
|
|
383000
|
+
const sourceName = c.req.param("source");
|
|
383001
|
+
const services = c.get("services");
|
|
383002
|
+
const result = await services.webhooks.heartbeat(sourceName);
|
|
383003
|
+
return c.json(result);
|
|
383004
|
+
});
|
|
382525
383005
|
triggerEventSchema = exports_external.object({
|
|
382526
383006
|
eventType: exports_external.string().min(1).refine((t) => t.startsWith("custom."), { message: 'Event type must start with "custom."' }).describe("Event type (must be custom.*)"),
|
|
382527
383007
|
payload: exports_external.record(exports_external.string(), exports_external.unknown()).describe("Event payload"),
|
|
@@ -383421,7 +383901,7 @@ function platformAuthMiddleware(requiredScope, platformAction) {
|
|
|
383421
383901
|
}
|
|
383422
383902
|
var UNAUTHORIZED, FORBIDDEN;
|
|
383423
383903
|
var init_platform_auth = __esm(() => {
|
|
383424
|
-
|
|
383904
|
+
init_factory3();
|
|
383425
383905
|
init_api_keys();
|
|
383426
383906
|
UNAUTHORIZED = { error: { code: "UNAUTHORIZED", message: "Platform credential required" } };
|
|
383427
383907
|
FORBIDDEN = {
|
|
@@ -384213,6 +384693,7 @@ async function setupEventPersistence(eventBus, db2) {
|
|
|
384213
384693
|
from: payload.from
|
|
384214
384694
|
},
|
|
384215
384695
|
agentId: metadata.agentId ?? null,
|
|
384696
|
+
causationId: metadata.causationId ?? null,
|
|
384216
384697
|
conversationId: null,
|
|
384217
384698
|
chatUuid
|
|
384218
384699
|
};
|
|
@@ -384266,6 +384747,7 @@ async function setupEventPersistence(eventBus, db2) {
|
|
|
384266
384747
|
voiceNote: payload.content.isVoiceNote
|
|
384267
384748
|
},
|
|
384268
384749
|
agentId: metadata.agentId ?? null,
|
|
384750
|
+
causationId: metadata.causationId ?? null,
|
|
384269
384751
|
conversationId: null,
|
|
384270
384752
|
chatUuid
|
|
384271
384753
|
};
|
|
@@ -384306,6 +384788,7 @@ async function setupEventPersistence(eventBus, db2) {
|
|
|
384306
384788
|
receivedAt: new Date(event.timestamp),
|
|
384307
384789
|
deliveredAt: new Date(payload.deliveredAt),
|
|
384308
384790
|
agentId: metadata.agentId ?? null,
|
|
384791
|
+
causationId: metadata.causationId ?? null,
|
|
384309
384792
|
conversationId: null,
|
|
384310
384793
|
chatUuid
|
|
384311
384794
|
};
|
|
@@ -384345,6 +384828,7 @@ async function setupEventPersistence(eventBus, db2) {
|
|
|
384345
384828
|
receivedAt: new Date(event.timestamp),
|
|
384346
384829
|
readAt: new Date(payload.readAt),
|
|
384347
384830
|
agentId: metadata.agentId ?? null,
|
|
384831
|
+
causationId: metadata.causationId ?? null,
|
|
384348
384832
|
conversationId: null,
|
|
384349
384833
|
chatUuid
|
|
384350
384834
|
};
|
|
@@ -384399,6 +384883,7 @@ async function setupEventPersistence(eventBus, db2) {
|
|
|
384399
384883
|
retryable: payload.retryable
|
|
384400
384884
|
},
|
|
384401
384885
|
agentId: metadata.agentId ?? null,
|
|
384886
|
+
causationId: metadata.causationId ?? null,
|
|
384402
384887
|
conversationId: null,
|
|
384403
384888
|
chatUuid
|
|
384404
384889
|
};
|
|
@@ -384419,6 +384904,38 @@ async function setupEventPersistence(eventBus, db2) {
|
|
|
384419
384904
|
});
|
|
384420
384905
|
}
|
|
384421
384906
|
}, { ...CONSUMER_OPTIONS, durable: "event-persistence-failed" });
|
|
384907
|
+
await eventBus.subscribePattern("custom.>", async (event) => {
|
|
384908
|
+
const metadata = event.metadata;
|
|
384909
|
+
try {
|
|
384910
|
+
await runConsumerInTenantContext(db2, event, async () => {
|
|
384911
|
+
const sdb = scopedHandle(db2);
|
|
384912
|
+
const newEvent = {
|
|
384913
|
+
...eventIdInsert(event.id),
|
|
384914
|
+
channel: "internal",
|
|
384915
|
+
instanceId: metadata.instanceId && isValidUuid(metadata.instanceId) ? metadata.instanceId : null,
|
|
384916
|
+
eventType: event.type.slice(0, 50),
|
|
384917
|
+
direction: "internal",
|
|
384918
|
+
status: "completed",
|
|
384919
|
+
receivedAt: new Date(event.timestamp),
|
|
384920
|
+
rawPayload: deepSanitize(event.payload),
|
|
384921
|
+
metadata: {
|
|
384922
|
+
correlationId: metadata.correlationId,
|
|
384923
|
+
source: metadata.source,
|
|
384924
|
+
fullEventType: event.type
|
|
384925
|
+
},
|
|
384926
|
+
causationId: metadata.causationId ?? null,
|
|
384927
|
+
conversationId: null
|
|
384928
|
+
};
|
|
384929
|
+
await sdb.insert(omniEvents).values(newEvent).onConflictDoNothing({ target: omniEvents.id });
|
|
384930
|
+
});
|
|
384931
|
+
} catch (error3) {
|
|
384932
|
+
log124.error("Failed to persist custom event", {
|
|
384933
|
+
eventType: event.type,
|
|
384934
|
+
eventId: event.id,
|
|
384935
|
+
error: String(error3)
|
|
384936
|
+
});
|
|
384937
|
+
}
|
|
384938
|
+
}, { ...CONSUMER_OPTIONS, durable: "event-persistence-custom", startFrom: "new" });
|
|
384422
384939
|
log124.info("Event persistence initialized - listening for message events");
|
|
384423
384940
|
} catch (error3) {
|
|
384424
384941
|
log124.error("Failed to set up event persistence", { error: String(error3) });
|
|
@@ -386672,6 +387189,26 @@ function setupScheduler(services, channelRegistry2) {
|
|
|
386672
387189
|
});
|
|
386673
387190
|
}
|
|
386674
387191
|
});
|
|
387192
|
+
scheduler.register({
|
|
387193
|
+
name: "connector-liveness-sweeper",
|
|
387194
|
+
cron: "*/30 * * * * *",
|
|
387195
|
+
runOnStart: false,
|
|
387196
|
+
handler: async () => {
|
|
387197
|
+
await withCronMonitor("connector-liveness-sweeper", "*/30 * * * * *", 1, 1, async () => {
|
|
387198
|
+
const startTime3 = Date.now();
|
|
387199
|
+
try {
|
|
387200
|
+
const stats = await services.webhooks.sweepLiveness({ deadLetters: services.deadLetters });
|
|
387201
|
+
recordScheduledJob("connector-liveness-sweeper", "success", (Date.now() - startTime3) / 1000);
|
|
387202
|
+
if (stats.stalled > 0 || stats.recovered > 0) {
|
|
387203
|
+
log130.info("Connector liveness sweep tick", { ...stats });
|
|
387204
|
+
}
|
|
387205
|
+
} catch (err2) {
|
|
387206
|
+
recordScheduledJob("connector-liveness-sweeper", "failure", (Date.now() - startTime3) / 1000);
|
|
387207
|
+
throw err2;
|
|
387208
|
+
}
|
|
387209
|
+
});
|
|
387210
|
+
}
|
|
387211
|
+
});
|
|
386675
387212
|
if (channelRegistry2) {
|
|
386676
387213
|
const scheduledMessages2 = createScheduledMessageSweeper(services, channelRegistry2);
|
|
386677
387214
|
scheduler.register({
|
|
@@ -389364,27 +389901,27 @@ var import_discord5 = __toESM(require_src2(), 1);
|
|
|
389364
389901
|
// ../channel-discord/src/auth.ts
|
|
389365
389902
|
init_src();
|
|
389366
389903
|
var log21 = createLogger("discord:auth");
|
|
389367
|
-
async function loadToken(
|
|
389904
|
+
async function loadToken(storage2, instanceId) {
|
|
389368
389905
|
const key = `${instanceId}:token`;
|
|
389369
|
-
const data = await
|
|
389906
|
+
const data = await storage2.get(key);
|
|
389370
389907
|
if (data?.token) {
|
|
389371
389908
|
log21.debug("Loaded token from storage", { instanceId });
|
|
389372
389909
|
return data.token;
|
|
389373
389910
|
}
|
|
389374
389911
|
return null;
|
|
389375
389912
|
}
|
|
389376
|
-
async function saveToken(
|
|
389913
|
+
async function saveToken(storage2, instanceId, token) {
|
|
389377
389914
|
const key = `${instanceId}:token`;
|
|
389378
389915
|
const data = {
|
|
389379
389916
|
token,
|
|
389380
389917
|
storedAt: Date.now()
|
|
389381
389918
|
};
|
|
389382
|
-
await
|
|
389919
|
+
await storage2.set(key, data);
|
|
389383
389920
|
log21.debug("Saved token to storage", { instanceId });
|
|
389384
389921
|
}
|
|
389385
|
-
async function clearToken(
|
|
389922
|
+
async function clearToken(storage2, instanceId) {
|
|
389386
389923
|
const key = `${instanceId}:token`;
|
|
389387
|
-
await
|
|
389924
|
+
await storage2.delete(key);
|
|
389388
389925
|
log21.debug("Cleared token from storage", { instanceId });
|
|
389389
389926
|
}
|
|
389390
389927
|
|
|
@@ -489935,11 +490472,11 @@ class GroupCipher {
|
|
|
489935
490472
|
const ret2 = wasm.groupcipher_encrypt(this.__wbg_ptr, ptr0, len0);
|
|
489936
490473
|
return takeObject(ret2);
|
|
489937
490474
|
}
|
|
489938
|
-
constructor(
|
|
490475
|
+
constructor(storage2, group_id, sender) {
|
|
489939
490476
|
const ptr0 = passStringToWasm0(group_id, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
489940
490477
|
const len0 = WASM_VECTOR_LEN;
|
|
489941
490478
|
_assertClass(sender, ProtocolAddress);
|
|
489942
|
-
const ret2 = wasm.groupcipher_new(addHeapObject(
|
|
490479
|
+
const ret2 = wasm.groupcipher_new(addHeapObject(storage2), ptr0, len0, sender.__wbg_ptr);
|
|
489943
490480
|
this.__wbg_ptr = ret2 >>> 0;
|
|
489944
490481
|
GroupCipherFinalization.register(this, this.__wbg_ptr, this);
|
|
489945
490482
|
return this;
|
|
@@ -489964,8 +490501,8 @@ class GroupSessionBuilder {
|
|
|
489964
490501
|
const ret2 = wasm.groupsessionbuilder_create(this.__wbg_ptr, sender_key_name.__wbg_ptr);
|
|
489965
490502
|
return takeObject(ret2);
|
|
489966
490503
|
}
|
|
489967
|
-
constructor(
|
|
489968
|
-
const ret2 = wasm.groupsessionbuilder_new(addHeapObject(
|
|
490504
|
+
constructor(storage2) {
|
|
490505
|
+
const ret2 = wasm.groupsessionbuilder_new(addHeapObject(storage2));
|
|
489969
490506
|
this.__wbg_ptr = ret2 >>> 0;
|
|
489970
490507
|
GroupSessionBuilderFinalization.register(this, this.__wbg_ptr, this);
|
|
489971
490508
|
return this;
|
|
@@ -490621,9 +491158,9 @@ class SessionBuilder {
|
|
|
490621
491158
|
const ret2 = wasm.sessionbuilder_initOutgoing(this.__wbg_ptr, addHeapObject(bundle_input));
|
|
490622
491159
|
return takeObject(ret2);
|
|
490623
491160
|
}
|
|
490624
|
-
constructor(
|
|
491161
|
+
constructor(storage2, remote_address) {
|
|
490625
491162
|
_assertClass(remote_address, ProtocolAddress);
|
|
490626
|
-
const ret2 = wasm.sessionbuilder_new(addHeapObject(
|
|
491163
|
+
const ret2 = wasm.sessionbuilder_new(addHeapObject(storage2), remote_address.__wbg_ptr);
|
|
490627
491164
|
this.__wbg_ptr = ret2 >>> 0;
|
|
490628
491165
|
SessionBuilderFinalization.register(this, this.__wbg_ptr, this);
|
|
490629
491166
|
return this;
|
|
@@ -490669,9 +491206,9 @@ class SessionCipher {
|
|
|
490669
491206
|
const ret2 = wasm.sessioncipher_hasOpenSession(this.__wbg_ptr);
|
|
490670
491207
|
return takeObject(ret2);
|
|
490671
491208
|
}
|
|
490672
|
-
constructor(
|
|
491209
|
+
constructor(storage2, remote_address) {
|
|
490673
491210
|
_assertClass(remote_address, ProtocolAddress);
|
|
490674
|
-
const ret2 = wasm.sessionbuilder_new(addHeapObject(
|
|
491211
|
+
const ret2 = wasm.sessionbuilder_new(addHeapObject(storage2), remote_address.__wbg_ptr);
|
|
490675
491212
|
this.__wbg_ptr = ret2 >>> 0;
|
|
490676
491213
|
SessionCipherFinalization.register(this, this.__wbg_ptr, this);
|
|
490677
491214
|
return this;
|
|
@@ -498744,8 +499281,8 @@ var CacheableSync = class extends Hookified {
|
|
|
498744
499281
|
data
|
|
498745
499282
|
});
|
|
498746
499283
|
}
|
|
498747
|
-
subscribe(
|
|
498748
|
-
this._storage =
|
|
499284
|
+
subscribe(storage2, cacheId) {
|
|
499285
|
+
this._storage = storage2;
|
|
498749
499286
|
this._cacheId = cacheId;
|
|
498750
499287
|
const setEvent = this.getPrefixedEvent("cache:set");
|
|
498751
499288
|
const deleteEvent = this.getPrefixedEvent("cache:delete");
|
|
@@ -498753,7 +499290,7 @@ var CacheableSync = class extends Hookified {
|
|
|
498753
499290
|
handler: async (message2) => {
|
|
498754
499291
|
const data = message2.data;
|
|
498755
499292
|
if (data.cacheId !== cacheId) {
|
|
498756
|
-
await
|
|
499293
|
+
await storage2.set(data.key, data.value, data.ttl);
|
|
498757
499294
|
}
|
|
498758
499295
|
}
|
|
498759
499296
|
});
|
|
@@ -498761,7 +499298,7 @@ var CacheableSync = class extends Hookified {
|
|
|
498761
499298
|
handler: async (message2) => {
|
|
498762
499299
|
const data = message2.data;
|
|
498763
499300
|
if (data.cacheId !== cacheId) {
|
|
498764
|
-
await
|
|
499301
|
+
await storage2.delete(data.key);
|
|
498765
499302
|
}
|
|
498766
499303
|
}
|
|
498767
499304
|
});
|
|
@@ -499749,7 +500286,7 @@ var index_default = NodeCache;
|
|
|
499749
500286
|
|
|
499750
500287
|
// ../../node_modules/.bun/baileys@vendor+baileys-v7.0.0-rc10.tgz+89588f7e3fe8b2e6/node_modules/baileys/lib/Utils/auth-utils.js
|
|
499751
500288
|
var import_boom10 = __toESM(require_lib7(), 1);
|
|
499752
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
500289
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
499753
500290
|
|
|
499754
500291
|
// ../../node_modules/.bun/async-mutex@0.5.0/node_modules/async-mutex/index.mjs
|
|
499755
500292
|
var E_TIMEOUT = new Error("timeout while waiting for mutex to become available");
|
|
@@ -500725,7 +501262,7 @@ class PreKeyManager {
|
|
|
500725
501262
|
|
|
500726
501263
|
// ../../node_modules/.bun/baileys@vendor+baileys-v7.0.0-rc10.tgz+89588f7e3fe8b2e6/node_modules/baileys/lib/Utils/auth-utils.js
|
|
500727
501264
|
var addTransactionCapability = (state, logger5, { maxCommitRetries, delayBetweenTriesMs }) => {
|
|
500728
|
-
const txStorage = new
|
|
501265
|
+
const txStorage = new AsyncLocalStorage2;
|
|
500729
501266
|
const keyQueues = new Map;
|
|
500730
501267
|
const txMutexes = new Map;
|
|
500731
501268
|
const txMutexRefCounts = new Map;
|
|
@@ -503410,7 +503947,7 @@ function extractIdentityFromPkmsg(ciphertext) {
|
|
|
503410
503947
|
}
|
|
503411
503948
|
function makeLibSignalRepository(auth, logger5, pnToLIDFunc) {
|
|
503412
503949
|
const lidMapping = new LIDMappingStore(auth.keys, logger5, pnToLIDFunc);
|
|
503413
|
-
const
|
|
503950
|
+
const storage2 = signalStorage(auth, lidMapping);
|
|
503414
503951
|
const parsedKeys = auth.keys;
|
|
503415
503952
|
const migratedSessionCache = new M({
|
|
503416
503953
|
ttl: 3 * 24 * 60 * 60 * 1000,
|
|
@@ -503422,21 +503959,21 @@ function makeLibSignalRepository(auth, logger5, pnToLIDFunc) {
|
|
|
503422
503959
|
const senderNameStr = senderName.toString();
|
|
503423
503960
|
const { [senderNameStr]: senderKey } = await auth.keys.get("sender-key", [senderNameStr]);
|
|
503424
503961
|
if (!senderKey) {
|
|
503425
|
-
await
|
|
503962
|
+
await storage2.storeSenderKey(senderName, new SenderKeyRecord2);
|
|
503426
503963
|
}
|
|
503427
|
-
const skdm = await new GroupSessionBuilder2(
|
|
503964
|
+
const skdm = await new GroupSessionBuilder2(storage2).create(senderName);
|
|
503428
503965
|
return { senderName, skdm };
|
|
503429
503966
|
};
|
|
503430
503967
|
const repository = {
|
|
503431
503968
|
decryptGroupMessage({ group, authorJid, msg }) {
|
|
503432
503969
|
const senderName = jidToSignalSenderKeyName(group, authorJid);
|
|
503433
|
-
const cipher = new GroupCipher2(
|
|
503970
|
+
const cipher = new GroupCipher2(storage2, senderName);
|
|
503434
503971
|
return parsedKeys.transaction(async () => {
|
|
503435
503972
|
return cipher.decrypt(msg);
|
|
503436
503973
|
}, group);
|
|
503437
503974
|
},
|
|
503438
503975
|
async processSenderKeyDistributionMessage({ item, authorJid }) {
|
|
503439
|
-
const builder = new GroupSessionBuilder2(
|
|
503976
|
+
const builder = new GroupSessionBuilder2(storage2);
|
|
503440
503977
|
if (!item.groupId) {
|
|
503441
503978
|
throw new Error("Group ID is required for sender key distribution message");
|
|
503442
503979
|
}
|
|
@@ -503445,24 +503982,24 @@ function makeLibSignalRepository(auth, logger5, pnToLIDFunc) {
|
|
|
503445
503982
|
const senderNameStr = senderName.toString();
|
|
503446
503983
|
const { [senderNameStr]: senderKey } = await auth.keys.get("sender-key", [senderNameStr]);
|
|
503447
503984
|
if (!senderKey) {
|
|
503448
|
-
await
|
|
503985
|
+
await storage2.storeSenderKey(senderName, new SenderKeyRecord2);
|
|
503449
503986
|
}
|
|
503450
503987
|
return parsedKeys.transaction(async () => {
|
|
503451
503988
|
const { [senderNameStr]: senderKey2 } = await auth.keys.get("sender-key", [senderNameStr]);
|
|
503452
503989
|
if (!senderKey2) {
|
|
503453
|
-
await
|
|
503990
|
+
await storage2.storeSenderKey(senderName, new SenderKeyRecord2);
|
|
503454
503991
|
}
|
|
503455
503992
|
await builder.process(senderName, senderMsg);
|
|
503456
503993
|
}, item.groupId);
|
|
503457
503994
|
},
|
|
503458
503995
|
async decryptMessage({ jid, type, ciphertext }) {
|
|
503459
503996
|
const addr = jidToSignalProtocolAddress(jid);
|
|
503460
|
-
const session = new libsignal.SessionCipher(
|
|
503997
|
+
const session = new libsignal.SessionCipher(storage2, addr);
|
|
503461
503998
|
if (type === "pkmsg") {
|
|
503462
503999
|
const identityKey = extractIdentityFromPkmsg(ciphertext);
|
|
503463
504000
|
if (identityKey) {
|
|
503464
504001
|
const addrStr = addr.toString();
|
|
503465
|
-
const identityChanged = await
|
|
504002
|
+
const identityChanged = await storage2.saveIdentity(addrStr, identityKey);
|
|
503466
504003
|
if (identityChanged) {
|
|
503467
504004
|
logger5.info({ jid, addr: addrStr }, "identity key changed or new contact, session will be re-established");
|
|
503468
504005
|
}
|
|
@@ -503486,7 +504023,7 @@ function makeLibSignalRepository(auth, logger5, pnToLIDFunc) {
|
|
|
503486
504023
|
},
|
|
503487
504024
|
async encryptMessage({ jid, data }) {
|
|
503488
504025
|
const addr = jidToSignalProtocolAddress(jid);
|
|
503489
|
-
const cipher = new libsignal.SessionCipher(
|
|
504026
|
+
const cipher = new libsignal.SessionCipher(storage2, addr);
|
|
503490
504027
|
return parsedKeys.transaction(async () => {
|
|
503491
504028
|
const { type: sigType, body } = await cipher.encrypt(data);
|
|
503492
504029
|
const type = sigType === 3 ? "pkmsg" : "msg";
|
|
@@ -503496,7 +504033,7 @@ function makeLibSignalRepository(auth, logger5, pnToLIDFunc) {
|
|
|
503496
504033
|
async encryptGroupMessage({ group, meId, data }) {
|
|
503497
504034
|
return parsedKeys.transaction(async () => {
|
|
503498
504035
|
const { senderName, skdm } = await ensureSenderKeyAndCreateSkdm(group, meId);
|
|
503499
|
-
const ciphertext = await new GroupCipher2(
|
|
504036
|
+
const ciphertext = await new GroupCipher2(storage2, senderName).encrypt(data);
|
|
503500
504037
|
return { ciphertext, senderKeyDistributionMessage: skdm.serialize() };
|
|
503501
504038
|
}, group);
|
|
503502
504039
|
},
|
|
@@ -503513,7 +504050,7 @@ function makeLibSignalRepository(auth, logger5, pnToLIDFunc) {
|
|
|
503513
504050
|
},
|
|
503514
504051
|
async getSessionInfo(jid) {
|
|
503515
504052
|
const addr = jidToSignalProtocolAddress(jid).toString();
|
|
503516
|
-
const session = await
|
|
504053
|
+
const session = await storage2.loadSession(addr);
|
|
503517
504054
|
if (!session) {
|
|
503518
504055
|
return null;
|
|
503519
504056
|
}
|
|
@@ -503527,7 +504064,7 @@ function makeLibSignalRepository(auth, logger5, pnToLIDFunc) {
|
|
|
503527
504064
|
},
|
|
503528
504065
|
async injectE2ESession({ jid, session }) {
|
|
503529
504066
|
logger5.trace({ jid }, "injecting E2EE session");
|
|
503530
|
-
const cipher = new libsignal.SessionBuilder(
|
|
504067
|
+
const cipher = new libsignal.SessionBuilder(storage2, jidToSignalProtocolAddress(jid));
|
|
503531
504068
|
return parsedKeys.transaction(async () => {
|
|
503532
504069
|
await cipher.initOutgoing(session);
|
|
503533
504070
|
}, jid);
|
|
@@ -503539,7 +504076,7 @@ function makeLibSignalRepository(auth, logger5, pnToLIDFunc) {
|
|
|
503539
504076
|
async validateSession(jid) {
|
|
503540
504077
|
try {
|
|
503541
504078
|
const addr = jidToSignalProtocolAddress(jid);
|
|
503542
|
-
const session = await
|
|
504079
|
+
const session = await storage2.loadSession(addr.toString());
|
|
503543
504080
|
if (!session) {
|
|
503544
504081
|
return { exists: false, reason: "no session" };
|
|
503545
504082
|
}
|
|
@@ -511533,11 +512070,11 @@ function deserializeSignalData(type, data) {
|
|
|
511533
512070
|
}
|
|
511534
512071
|
return data;
|
|
511535
512072
|
}
|
|
511536
|
-
async function createStorageAuthState(
|
|
512073
|
+
async function createStorageAuthState(storage2, instanceId) {
|
|
511537
512074
|
const credsKey = `auth:${instanceId}:creds`;
|
|
511538
512075
|
const keyPrefix = `auth:${instanceId}:keys`;
|
|
511539
512076
|
let creds;
|
|
511540
|
-
const existingCreds = await
|
|
512077
|
+
const existingCreds = await storage2.get(credsKey);
|
|
511541
512078
|
if (existingCreds) {
|
|
511542
512079
|
if (typeof existingCreds === "string") {
|
|
511543
512080
|
creds = deserialize(existingCreds);
|
|
@@ -511607,10 +512144,10 @@ async function createStorageAuthState(storage, instanceId) {
|
|
|
511607
512144
|
const previousPersist = persistQueues.get(key) ?? Promise.resolve();
|
|
511608
512145
|
const nextPersist = previousPersist.catch(() => {}).then(async () => {
|
|
511609
512146
|
if (value !== null && value !== undefined) {
|
|
511610
|
-
await
|
|
512147
|
+
await storage2.set(key, serialize(value));
|
|
511611
512148
|
return;
|
|
511612
512149
|
}
|
|
511613
|
-
await
|
|
512150
|
+
await storage2.delete(key);
|
|
511614
512151
|
}).catch((err2) => {
|
|
511615
512152
|
if (value !== null && value !== undefined) {
|
|
511616
512153
|
log50.error("Background key persist failed", { type, id: id.slice(-40), instanceId, err: String(err2) });
|
|
@@ -511639,7 +512176,7 @@ async function createStorageAuthState(storage, instanceId) {
|
|
|
511639
512176
|
data[id] = deserializeSignalData(type, cached);
|
|
511640
512177
|
continue;
|
|
511641
512178
|
}
|
|
511642
|
-
const value = await
|
|
512179
|
+
const value = await storage2.get(key);
|
|
511643
512180
|
if (value !== null && value !== undefined) {
|
|
511644
512181
|
const parsed = parseStorageValue(value);
|
|
511645
512182
|
setCachedValue(key, parsed);
|
|
@@ -511661,19 +512198,19 @@ async function createStorageAuthState(storage, instanceId) {
|
|
|
511661
512198
|
}
|
|
511662
512199
|
},
|
|
511663
512200
|
saveCreds: async () => {
|
|
511664
|
-
await
|
|
512201
|
+
await storage2.set(credsKey, serialize(creds));
|
|
511665
512202
|
}
|
|
511666
512203
|
};
|
|
511667
512204
|
}
|
|
511668
|
-
async function clearAuthState(
|
|
512205
|
+
async function clearAuthState(storage2, instanceId) {
|
|
511669
512206
|
const credsKey = `auth:${instanceId}:creds`;
|
|
511670
512207
|
const keyPrefix = `auth:${instanceId}:keys`;
|
|
511671
|
-
await
|
|
511672
|
-
const keys = await
|
|
512208
|
+
await storage2.delete(credsKey);
|
|
512209
|
+
const keys = await storage2.keys(`${keyPrefix}:*`);
|
|
511673
512210
|
const batchSize = 50;
|
|
511674
512211
|
for (let i = 0;i < keys.length; i += batchSize) {
|
|
511675
512212
|
const batch = keys.slice(i, i + batchSize);
|
|
511676
|
-
await Promise.all(batch.map((key) =>
|
|
512213
|
+
await Promise.all(batch.map((key) => storage2.delete(key)));
|
|
511677
512214
|
}
|
|
511678
512215
|
}
|
|
511679
512216
|
|