@automagik/omni 2.260603.1 → 2.260603.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +5 -1
- package/dist/server/index.js +216 -19
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -36303,9 +36303,13 @@ class AgnoClient {
|
|
|
36303
36303
|
async deleteSession(sessionId) {
|
|
36304
36304
|
const url = `${this.baseUrl}/sessions/${encodeURIComponent(sessionId)}`;
|
|
36305
36305
|
const response = await this.fetchWithTimeout(url, { method: "DELETE", headers: this.getHeaders() }, this.defaultTimeoutMs);
|
|
36306
|
+
if (response.status === 404) {
|
|
36307
|
+
return { ok: true, status: response.status, sessionId, existed: false };
|
|
36308
|
+
}
|
|
36306
36309
|
if (!response.ok) {
|
|
36307
36310
|
this.handleErrorResponse(response, `deleting session ${sessionId}`);
|
|
36308
36311
|
}
|
|
36312
|
+
return { ok: true, status: response.status, sessionId, existed: true };
|
|
36309
36313
|
}
|
|
36310
36314
|
}
|
|
36311
36315
|
function createAgnoClient(config2) {
|
|
@@ -124967,7 +124971,7 @@ import { fileURLToPath } from "url";
|
|
|
124967
124971
|
// package.json
|
|
124968
124972
|
var package_default = {
|
|
124969
124973
|
name: "@automagik/omni",
|
|
124970
|
-
version: "2.260603.
|
|
124974
|
+
version: "2.260603.2",
|
|
124971
124975
|
description: "LLM-optimized CLI for Omni",
|
|
124972
124976
|
type: "module",
|
|
124973
124977
|
bin: {
|
package/dist/server/index.js
CHANGED
|
@@ -29981,9 +29981,13 @@ class AgnoClient {
|
|
|
29981
29981
|
async deleteSession(sessionId) {
|
|
29982
29982
|
const url = `${this.baseUrl}/sessions/${encodeURIComponent(sessionId)}`;
|
|
29983
29983
|
const response = await this.fetchWithTimeout(url, { method: "DELETE", headers: this.getHeaders() }, this.defaultTimeoutMs);
|
|
29984
|
+
if (response.status === 404) {
|
|
29985
|
+
return { ok: true, status: response.status, sessionId, existed: false };
|
|
29986
|
+
}
|
|
29984
29987
|
if (!response.ok) {
|
|
29985
29988
|
this.handleErrorResponse(response, `deleting session ${sessionId}`);
|
|
29986
29989
|
}
|
|
29990
|
+
return { ok: true, status: response.status, sessionId, existed: true };
|
|
29987
29991
|
}
|
|
29988
29992
|
}
|
|
29989
29993
|
function createAgnoClient(config2) {
|
|
@@ -225241,7 +225245,7 @@ var init_sentry_scrub = __esm(() => {
|
|
|
225241
225245
|
var require_package7 = __commonJS((exports, module) => {
|
|
225242
225246
|
module.exports = {
|
|
225243
225247
|
name: "@omni/api",
|
|
225244
|
-
version: "2.260603.
|
|
225248
|
+
version: "2.260603.2",
|
|
225245
225249
|
type: "module",
|
|
225246
225250
|
exports: {
|
|
225247
225251
|
".": {
|
|
@@ -336612,6 +336616,117 @@ var init_idempotency = __esm(() => {
|
|
|
336612
336616
|
log93 = createLogger("idempotency");
|
|
336613
336617
|
});
|
|
336614
336618
|
|
|
336619
|
+
// ../api/src/services/agent-session-identity.ts
|
|
336620
|
+
function computeLegacySessionId(strategy, userId, chatId, threadId2) {
|
|
336621
|
+
switch (strategy) {
|
|
336622
|
+
case "per_user":
|
|
336623
|
+
return userId;
|
|
336624
|
+
case "per_chat":
|
|
336625
|
+
return chatId;
|
|
336626
|
+
case "per_thread":
|
|
336627
|
+
return `thread:${chatId}:${threadId2 ?? chatId}`;
|
|
336628
|
+
default:
|
|
336629
|
+
return `${userId}:${chatId}`;
|
|
336630
|
+
}
|
|
336631
|
+
}
|
|
336632
|
+
function readHeader(headers, name) {
|
|
336633
|
+
if (!headers || typeof headers !== "object")
|
|
336634
|
+
return;
|
|
336635
|
+
const headerMap = headers;
|
|
336636
|
+
const lowerName = name.toLowerCase();
|
|
336637
|
+
for (const [key, value] of Object.entries(headerMap)) {
|
|
336638
|
+
if (key.toLowerCase() === lowerName && typeof value === "string" && value.trim())
|
|
336639
|
+
return value.trim();
|
|
336640
|
+
}
|
|
336641
|
+
return;
|
|
336642
|
+
}
|
|
336643
|
+
function readStringField(source, names) {
|
|
336644
|
+
if (!source)
|
|
336645
|
+
return;
|
|
336646
|
+
for (const name of names) {
|
|
336647
|
+
const value = source[name];
|
|
336648
|
+
if (typeof value === "string" && value.trim())
|
|
336649
|
+
return value.trim();
|
|
336650
|
+
}
|
|
336651
|
+
return;
|
|
336652
|
+
}
|
|
336653
|
+
function extractKhalSessionIdFromRawPayload(rawPayload) {
|
|
336654
|
+
const direct = readStringField(rawPayload, ["khalSessionId", "khal_session_id", "session_id"]);
|
|
336655
|
+
if (direct)
|
|
336656
|
+
return direct;
|
|
336657
|
+
return readHeader(rawPayload?.headers, "x-khal-session-id");
|
|
336658
|
+
}
|
|
336659
|
+
function resolveKhalEnvironment(rawPayload, explicitEnvironment) {
|
|
336660
|
+
const explicit = explicitEnvironment?.trim();
|
|
336661
|
+
if (explicit)
|
|
336662
|
+
return explicit;
|
|
336663
|
+
const fromPayload = readStringField(rawPayload, ["khalEnv", "khalEnvironment", "environment", "env"]);
|
|
336664
|
+
if (fromPayload)
|
|
336665
|
+
return fromPayload;
|
|
336666
|
+
return readHeader(rawPayload?.headers, "x-khal-env") ?? readHeader(rawPayload?.headers, "x-khal-environment") ?? process.env.KHAL_SESSION_ENV?.trim() ?? process.env.KHAL_ENV?.trim() ?? process.env.OMNI_ENV?.trim();
|
|
336667
|
+
}
|
|
336668
|
+
function channelToKhalSessionSegment(channel5) {
|
|
336669
|
+
if (!channel5)
|
|
336670
|
+
return;
|
|
336671
|
+
if (channel5 === "whatsapp-gupshup")
|
|
336672
|
+
return "gupshup";
|
|
336673
|
+
if (channel5 === "whatsapp-cloud")
|
|
336674
|
+
return "whatsapp";
|
|
336675
|
+
if (channel5 === "whatsapp-baileys")
|
|
336676
|
+
return "whatsapp";
|
|
336677
|
+
return String(channel5).replace(/^channel-/, "");
|
|
336678
|
+
}
|
|
336679
|
+
function buildCanonicalKhalSessionId(input) {
|
|
336680
|
+
return `khal:${input.environment}:omni:${input.instanceId}:${input.channelSegment}:${input.personId}`;
|
|
336681
|
+
}
|
|
336682
|
+
function resolveKhalSessionId(input) {
|
|
336683
|
+
const sessionStrategy = input.sessionStrategy ?? "per_chat";
|
|
336684
|
+
const legacySessionId = computeLegacySessionId(sessionStrategy, input.from, input.chatId, input.threadId);
|
|
336685
|
+
const explicitKhalSessionId = extractKhalSessionIdFromRawPayload(input.rawPayload);
|
|
336686
|
+
if (explicitKhalSessionId) {
|
|
336687
|
+
return {
|
|
336688
|
+
sessionId: explicitKhalSessionId,
|
|
336689
|
+
legacySessionId,
|
|
336690
|
+
sessionStrategy,
|
|
336691
|
+
canonicalSessionId: explicitKhalSessionId,
|
|
336692
|
+
personId: input.personId ?? undefined,
|
|
336693
|
+
environment: resolveKhalEnvironment(input.rawPayload, input.environment),
|
|
336694
|
+
channelSegment: channelToKhalSessionSegment(input.channel),
|
|
336695
|
+
source: "explicit-khal"
|
|
336696
|
+
};
|
|
336697
|
+
}
|
|
336698
|
+
const environment = resolveKhalEnvironment(input.rawPayload, input.environment);
|
|
336699
|
+
const channelSegment = channelToKhalSessionSegment(input.channel);
|
|
336700
|
+
const personId = input.personId?.trim();
|
|
336701
|
+
if (input.providerSchema === "agno" && environment && channelSegment && personId) {
|
|
336702
|
+
const canonicalSessionId = buildCanonicalKhalSessionId({
|
|
336703
|
+
environment,
|
|
336704
|
+
instanceId: input.instanceId,
|
|
336705
|
+
channelSegment,
|
|
336706
|
+
personId
|
|
336707
|
+
});
|
|
336708
|
+
return {
|
|
336709
|
+
sessionId: canonicalSessionId,
|
|
336710
|
+
legacySessionId,
|
|
336711
|
+
sessionStrategy,
|
|
336712
|
+
canonicalSessionId,
|
|
336713
|
+
personId,
|
|
336714
|
+
environment,
|
|
336715
|
+
channelSegment,
|
|
336716
|
+
source: "canonical-khal"
|
|
336717
|
+
};
|
|
336718
|
+
}
|
|
336719
|
+
return {
|
|
336720
|
+
sessionId: legacySessionId,
|
|
336721
|
+
legacySessionId,
|
|
336722
|
+
sessionStrategy,
|
|
336723
|
+
personId: personId ?? undefined,
|
|
336724
|
+
environment,
|
|
336725
|
+
channelSegment,
|
|
336726
|
+
source: "legacy"
|
|
336727
|
+
};
|
|
336728
|
+
}
|
|
336729
|
+
|
|
336615
336730
|
// ../api/src/services/message-context.ts
|
|
336616
336731
|
function extractPhoneFromJid(jid) {
|
|
336617
336732
|
return jid.replace(/:.*$/, "").replace(/@.*$/, "").replace(/^@/, "");
|
|
@@ -338794,9 +338909,20 @@ async function dispatchViaStreamingProvider(services, instance4, messages4, trig
|
|
|
338794
338909
|
if (!messageTexts.length && mediaFiles.length)
|
|
338795
338910
|
messageTexts.push("[Media message]");
|
|
338796
338911
|
const rawThreadId = extractThreadId(messages4);
|
|
338797
|
-
const explicitKhalSessionId = extractKhalSessionId(messages4);
|
|
338798
|
-
const sessionId = explicitKhalSessionId ?? computeSessionId(instance4.agentSessionStrategy ?? "per_chat", senderId, chatId, rawThreadId);
|
|
338799
338912
|
const rawPl = messages4[0]?.payload.rawPayload ?? {};
|
|
338913
|
+
const sessionIdentity = resolveKhalSessionId({
|
|
338914
|
+
providerSchema: resolved.provider.schema,
|
|
338915
|
+
sessionStrategy: instance4.agentSessionStrategy ?? "per_chat",
|
|
338916
|
+
from: senderId,
|
|
338917
|
+
chatId,
|
|
338918
|
+
channel: channel5,
|
|
338919
|
+
instanceId: instance4.id,
|
|
338920
|
+
personId,
|
|
338921
|
+
rawPayload: rawPl,
|
|
338922
|
+
threadId: rawThreadId
|
|
338923
|
+
});
|
|
338924
|
+
const sessionId = sessionIdentity.sessionId;
|
|
338925
|
+
const explicitKhalSessionId = sessionIdentity.canonicalSessionId;
|
|
338800
338926
|
const replyToId = messages4[0]?.payload.replyToId ?? messages4[0]?.payload.externalId;
|
|
338801
338927
|
const currentMessageIds = messages4.map((msg) => msg.payload.externalId).filter((id) => !!id);
|
|
338802
338928
|
const dbContextMessages = await buildContextMessages(services, instance4, chatId, currentMessageIds);
|
|
@@ -339030,8 +339156,20 @@ async function dispatchViaProvider(services, instance4, messages4, triggerType,
|
|
|
339030
339156
|
messageTexts.push("[Media message]");
|
|
339031
339157
|
}
|
|
339032
339158
|
const rawThreadId = extractThreadId(messages4);
|
|
339033
|
-
const
|
|
339034
|
-
const
|
|
339159
|
+
const rawPl = messages4[0]?.payload.rawPayload ?? {};
|
|
339160
|
+
const sessionIdentity = resolveKhalSessionId({
|
|
339161
|
+
providerSchema: provider.schema,
|
|
339162
|
+
sessionStrategy: instance4.agentSessionStrategy ?? "per_chat",
|
|
339163
|
+
from: senderId,
|
|
339164
|
+
chatId,
|
|
339165
|
+
channel: channel5,
|
|
339166
|
+
instanceId: instance4.id,
|
|
339167
|
+
personId,
|
|
339168
|
+
rawPayload: rawPl,
|
|
339169
|
+
threadId: rawThreadId
|
|
339170
|
+
});
|
|
339171
|
+
const sessionId = sessionIdentity.sessionId;
|
|
339172
|
+
const explicitKhalSessionId = sessionIdentity.canonicalSessionId;
|
|
339035
339173
|
const currentMessageIds = messages4.map((msg) => msg.payload.externalId).filter((id) => !!id);
|
|
339036
339174
|
const dbContextMessages = await buildContextMessages(services, instance4, chatId, currentMessageIds);
|
|
339037
339175
|
const allContextMessages = mergeContextMessages(extraContextMessages, dbContextMessages);
|
|
@@ -339970,7 +340108,16 @@ async function processReactionTrigger(services, baseInstance, payload, metadata,
|
|
|
339970
340108
|
if (provider) {
|
|
339971
340109
|
const effectivePersonId = reactionPersonId ?? metadata.personId;
|
|
339972
340110
|
const senderName2 = await services.agentRunner.getSenderName(effectivePersonId, undefined);
|
|
339973
|
-
const sessionId =
|
|
340111
|
+
const sessionId = resolveKhalSessionId({
|
|
340112
|
+
providerSchema: provider.schema,
|
|
340113
|
+
sessionStrategy: instance4.agentSessionStrategy ?? "per_chat",
|
|
340114
|
+
from: payload.from,
|
|
340115
|
+
chatId: externalChatId,
|
|
340116
|
+
channel: channel5,
|
|
340117
|
+
instanceId: instance4.id,
|
|
340118
|
+
personId: effectivePersonId,
|
|
340119
|
+
rawPayload: payload.rawPayload
|
|
340120
|
+
}).sessionId;
|
|
339974
340121
|
const customerContext = await resolveCustomerContext(services, effectivePersonId);
|
|
339975
340122
|
const trigger = {
|
|
339976
340123
|
traceId: metadata.traceId,
|
|
@@ -349830,7 +349977,16 @@ async function sendMessage(services, instanceId, chatId, text3) {
|
|
|
349830
349977
|
});
|
|
349831
349978
|
}
|
|
349832
349979
|
}
|
|
349833
|
-
async function
|
|
349980
|
+
async function resolveCleanupPersonId(services, db2, instanceId, chatId, from, metadataPersonId) {
|
|
349981
|
+
if (metadataPersonId?.trim())
|
|
349982
|
+
return metadataPersonId.trim();
|
|
349983
|
+
const dbChat = await services.chats.findByExternalIdSmart(instanceId, chatId);
|
|
349984
|
+
if (!dbChat?.id)
|
|
349985
|
+
return;
|
|
349986
|
+
const [participant] = await db2.select({ personId: chatParticipants.personId }).from(chatParticipants).where(and2(eq(chatParticipants.chatId, dbChat.id), eq(chatParticipants.platformUserId, from))).limit(1);
|
|
349987
|
+
return participant?.personId ?? undefined;
|
|
349988
|
+
}
|
|
349989
|
+
async function clearAgentSession(services, db2, instanceId, from, chatId, options = {}) {
|
|
349834
349990
|
const instance4 = await services.agentRunner.getInstanceWithProvider(instanceId);
|
|
349835
349991
|
if (!instance4?.agentId) {
|
|
349836
349992
|
throw new Error("No agent configured for instance");
|
|
@@ -349840,14 +349996,31 @@ async function clearAgentSession(services, db2, instanceId, from, chatId) {
|
|
|
349840
349996
|
throw new Error("Agent has no provider configured");
|
|
349841
349997
|
}
|
|
349842
349998
|
const providerRecord = await services.providers.getById(agentRow.agentProviderId);
|
|
349843
|
-
const
|
|
349844
|
-
const
|
|
349999
|
+
const personId = await resolveCleanupPersonId(services, db2, instanceId, chatId, from, options.personId);
|
|
350000
|
+
const identity = resolveKhalSessionId({
|
|
350001
|
+
providerSchema: providerRecord.schema,
|
|
350002
|
+
sessionStrategy: instance4.agentSessionStrategy ?? "per_chat",
|
|
350003
|
+
from,
|
|
350004
|
+
chatId,
|
|
350005
|
+
channel: instance4.channel,
|
|
350006
|
+
instanceId,
|
|
350007
|
+
personId,
|
|
350008
|
+
rawPayload: options.rawPayload
|
|
350009
|
+
});
|
|
350010
|
+
const { sessionId, legacySessionId } = identity;
|
|
350011
|
+
const hasKhalContext = !!identity.canonicalSessionId || !!identity.environment || !!options.rawPayload?.khalSessionId;
|
|
350012
|
+
if (providerRecord.schema === "agno" && hasKhalContext && identity.source === "legacy") {
|
|
350013
|
+
throw new Error("Canonical KHAL session resolution failed; refusing blind legacy Agno reset");
|
|
350014
|
+
}
|
|
349845
350015
|
const dispatchInstance = { ...instance4, agentProviderId: agentRow.agentProviderId };
|
|
349846
350016
|
await applyAgentFkOverrides(db2, instance4.agentId, dispatchInstance);
|
|
349847
350017
|
const agentProvider = resolveProvider(providerRecord, dispatchInstance, db2);
|
|
349848
350018
|
if (agentProvider?.resetSession) {
|
|
349849
350019
|
await agentProvider.resetSession(sessionId, chatId, instanceId);
|
|
349850
|
-
|
|
350020
|
+
if (legacySessionId !== sessionId) {
|
|
350021
|
+
await agentProvider.resetSession(legacySessionId, chatId, instanceId);
|
|
350022
|
+
}
|
|
350023
|
+
return identity;
|
|
349851
350024
|
}
|
|
349852
350025
|
if (providerRecord.schema !== "agno") {
|
|
349853
350026
|
throw new Error(`Session clearing not supported for ${providerRecord.schema} providers`);
|
|
@@ -349857,18 +350030,28 @@ async function clearAgentSession(services, db2, instanceId, from, chatId) {
|
|
|
349857
350030
|
apiKey: providerRecord.apiKey ?? "",
|
|
349858
350031
|
defaultTimeoutMs: (providerRecord.defaultTimeout ?? 60) * 1000
|
|
349859
350032
|
});
|
|
349860
|
-
await client.deleteSession?.(sessionId);
|
|
349861
|
-
|
|
350033
|
+
const primaryDelete = await client.deleteSession?.(sessionId);
|
|
350034
|
+
const legacyDelete = legacySessionId !== sessionId ? await client.deleteSession?.(legacySessionId) : undefined;
|
|
350035
|
+
log105.info("Agno session delete verified", {
|
|
350036
|
+
instanceId,
|
|
350037
|
+
sessionId,
|
|
350038
|
+
legacySessionId,
|
|
350039
|
+
primaryStatus: primaryDelete?.status,
|
|
350040
|
+
primaryExisted: primaryDelete?.existed,
|
|
350041
|
+
legacyStatus: legacyDelete?.status,
|
|
350042
|
+
legacyExisted: legacyDelete?.existed
|
|
350043
|
+
});
|
|
350044
|
+
return identity;
|
|
349862
350045
|
}
|
|
349863
350046
|
async function handleTrashEmojiMessage(services, db2, event) {
|
|
349864
|
-
const { content, chatId
|
|
350047
|
+
const { content, chatId } = event.payload;
|
|
349865
350048
|
const { instanceId } = event.metadata;
|
|
349866
350049
|
if (!instanceId || !content?.text)
|
|
349867
350050
|
return;
|
|
349868
350051
|
if (!isTrashEmojiOnly2(content.text))
|
|
349869
350052
|
return;
|
|
349870
350053
|
const result = await withIdempotency(db2, event.id, "session-cleaner", async () => {
|
|
349871
|
-
await runTrashEmojiCleanup(services, db2,
|
|
350054
|
+
await runTrashEmojiCleanup(services, db2, event);
|
|
349872
350055
|
});
|
|
349873
350056
|
if (!result.executed) {
|
|
349874
350057
|
log105.debug("Trash emoji event already processed (NATS redelivery skipped)", {
|
|
@@ -349878,11 +350061,26 @@ async function handleTrashEmojiMessage(services, db2, event) {
|
|
|
349878
350061
|
});
|
|
349879
350062
|
}
|
|
349880
350063
|
}
|
|
349881
|
-
async function runTrashEmojiCleanup(services, db2,
|
|
349882
|
-
|
|
350064
|
+
async function runTrashEmojiCleanup(services, db2, event) {
|
|
350065
|
+
const { chatId, from, rawPayload } = event.payload;
|
|
350066
|
+
const { instanceId, personId } = event.metadata;
|
|
350067
|
+
if (!instanceId)
|
|
350068
|
+
return;
|
|
350069
|
+
log105.info("Trash emoji detected, clearing session", { instanceId, chatId, from, personId });
|
|
349883
350070
|
try {
|
|
349884
|
-
const
|
|
349885
|
-
|
|
350071
|
+
const identity = await clearAgentSession(services, db2, instanceId, from, chatId, { personId, rawPayload });
|
|
350072
|
+
const { sessionId, legacySessionId, sessionStrategy, source, canonicalSessionId, environment, channelSegment } = identity;
|
|
350073
|
+
log105.info("Session cleared successfully", {
|
|
350074
|
+
instanceId,
|
|
350075
|
+
sessionId,
|
|
350076
|
+
legacySessionId,
|
|
350077
|
+
sessionStrategy,
|
|
350078
|
+
source,
|
|
350079
|
+
canonicalSessionId,
|
|
350080
|
+
personId: identity.personId,
|
|
350081
|
+
environment,
|
|
350082
|
+
channelSegment
|
|
350083
|
+
});
|
|
349886
350084
|
try {
|
|
349887
350085
|
const dbChat = await services.chats.findByExternalIdSmart(instanceId, chatId);
|
|
349888
350086
|
if (dbChat?.id) {
|
|
@@ -349954,7 +350152,6 @@ var init_session_cleaner = __esm(() => {
|
|
|
349954
350152
|
init_src5();
|
|
349955
350153
|
init_drizzle_orm();
|
|
349956
350154
|
init_idempotency();
|
|
349957
|
-
init_agent_runner();
|
|
349958
350155
|
init_agent_dispatcher();
|
|
349959
350156
|
init_loader2();
|
|
349960
350157
|
log105 = createLogger("session-cleaner");
|