@automagik/omni 2.260923.1 → 2.260923.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.
|
@@ -22,6 +22,12 @@
|
|
|
22
22
|
* omni instances syncs cancel <id> <job-id>
|
|
23
23
|
*/
|
|
24
24
|
import { Command } from 'commander';
|
|
25
|
+
/**
|
|
26
|
+
* --clear-reply-filter on an instance that keeps its agent must not store null
|
|
27
|
+
* (reply-to-everything, #1248): swap in the documented default instead.
|
|
28
|
+
* Returns true when it did, so the caller can say so.
|
|
29
|
+
*/
|
|
30
|
+
export declare function defaultClearedReplyFilter(body: Record<string, unknown>, currentAgentId: () => Promise<string | null | undefined>): Promise<boolean>;
|
|
25
31
|
/** Mask a secret for display, matching the API's `get` shape (`xoxp-****9bdc`) */
|
|
26
32
|
declare function maskSecret(secret: string): string;
|
|
27
33
|
/** Copy of a request/response body safe to print: secret strings masked, `null` clears kept */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instances.d.ts","sourceRoot":"","sources":["../../src/commands/instances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"instances.d.ts","sourceRoot":"","sources":["../../src/commands/instances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AA2E5C;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GACvD,OAAO,CAAC,OAAO,CAAC,CAKlB;AAoHD,kFAAkF;AAClF,iBAAS,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAG1C;AAED,+FAA+F;AAC/F,iBAAS,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOhF;AAcD;;;;GAIG;AACH,iBAAe,qBAAqB,CAClC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,GAAE,MAAM,OAAO,CAAC,MAAM,CAAiB,GAC/C,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAsB7B;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYxF;AA8BD,wBAAgB,sBAAsB,IAAI,OAAO,CA+6ChD;AAED,eAAO,MAAM,WAAW;;;;CAA0D,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -137460,7 +137460,7 @@ import { fileURLToPath } from "url";
|
|
|
137460
137460
|
// package.json
|
|
137461
137461
|
var package_default = {
|
|
137462
137462
|
name: "@automagik/omni",
|
|
137463
|
-
version: "2.260923.
|
|
137463
|
+
version: "2.260923.2",
|
|
137464
137464
|
repository: {
|
|
137465
137465
|
type: "git",
|
|
137466
137466
|
url: "git+https://github.com/automagik-dev/omni.git",
|
|
@@ -146028,7 +146028,7 @@ function setBool(body, key, val) {
|
|
|
146028
146028
|
body[key] = false;
|
|
146029
146029
|
}
|
|
146030
146030
|
function applyAgentFields(body, opts) {
|
|
146031
|
-
setVal(body, "agentId", opts.agentFkId);
|
|
146031
|
+
setVal(body, "agentId", opts.agentFkId ?? opts.agent);
|
|
146032
146032
|
if (opts.agentTimeout !== undefined)
|
|
146033
146033
|
body.agentTimeout = opts.agentTimeout;
|
|
146034
146034
|
if (Array.isArray(opts.agentErrorMessage)) {
|
|
@@ -146062,6 +146062,15 @@ function applyReplyFilter(body, opts) {
|
|
|
146062
146062
|
}
|
|
146063
146063
|
body.agentReplyFilter = { mode: opts.replyFilterMode, conditions: cond };
|
|
146064
146064
|
}
|
|
146065
|
+
var DEFAULT_AGENT_REPLY_FILTER = { mode: "all", conditions: { onDm: true } };
|
|
146066
|
+
async function defaultClearedReplyFilter(body, currentAgentId) {
|
|
146067
|
+
if (body.agentReplyFilter !== null || body.agentId === null)
|
|
146068
|
+
return false;
|
|
146069
|
+
if (!(body.agentId ?? await currentAgentId()))
|
|
146070
|
+
return false;
|
|
146071
|
+
body.agentReplyFilter = DEFAULT_AGENT_REPLY_FILTER;
|
|
146072
|
+
return true;
|
|
146073
|
+
}
|
|
146065
146074
|
function applyFormatFields(body, opts) {
|
|
146066
146075
|
setBool(body, "enableAutoSplit", opts.enableAutoSplit);
|
|
146067
146076
|
setVal(body, "messageFormatMode", opts.messageFormatMode);
|
|
@@ -146651,7 +146660,7 @@ function createInstancesCommand() {
|
|
|
146651
146660
|
throw new Error(err2?.error?.message ?? `HTTP ${response.status}`);
|
|
146652
146661
|
}
|
|
146653
146662
|
}
|
|
146654
|
-
instances.command("update <id>").description("Update an instance (supports all API fields)").option("--name <name>", "Instance name").option("--is-default", "Set as default instance for channel").option("--no-is-default", "Unset as default instance for channel").option("--agent-fk-id <uuid>", 'Agent FK UUID (references agents table, use "null" to clear). When assigning an agent on an instance with no reply filter, the filter defaults to {mode:"all", onDm:true} so messages are dispatched instead of silently dropped (omni#443).').option("--agent-provider <id>", "Removed: set the provider on the agent (omni agents update <agentId> --agent-provider)").option("--agent <id>", 'Agent ID (use "null" to clear)').option("--agent-type <type>", "Agent type: agent, team, or workflow").option("--agent-timeout <seconds>", "Agent timeout in seconds", (v4) => Number.parseInt(v4, 10)).option("--agent-error-message <text>", 'Customer-facing reply when agent dispatch fails; repeat the flag for multiple variants (one is picked at random per failure). Use "null" to clear; falls back to OMNI_AGENT_DISPATCH_ERROR_MESSAGE env, then built-in default', (value, previous = []) => [...previous, value]).option("--agent-stream-mode", "Enable streaming responses").option("--no-agent-stream-mode", "Disable streaming responses").option("--agent-session-strategy <strategy>", "Session strategy: per_user, per_chat, per_user_per_chat").option("--agent-prefix-sender-name", "Prefix messages with sender name").option("--no-agent-prefix-sender-name", "Disable sender name prefix").option("--agent-wait-for-media", "Wait for media processing before dispatch").option("--no-agent-wait-for-media", "Dispatch immediately without waiting for media").option("--agent-send-media-path", "Include file path in formatted media text").option("--no-agent-send-media-path", "Exclude file path from formatted media text").option("--agent-send-media-path-types <types>", "Content types that receive file path (comma-separated: image,video,document)").option("--reply-filter-mode <mode>", "Reply filter: all or filtered").option("--reply-on-dm", "Reply to DMs (requires --reply-filter-mode filtered)").option("--no-reply-on-dm", "Ignore DMs").option("--reply-on-mention", "Reply when @mentioned").option("--no-reply-on-mention", "Ignore @mentions").option("--reply-on-reply", "Reply when message is reply to bot").option("--no-reply-on-reply", "Ignore replies").option("--reply-on-name", "Reply when bot name appears in text").option("--no-reply-on-name", "Ignore name matches").option("--reply-name-patterns <patterns>", "Custom name patterns (comma-separated)").option("--clear-reply-filter",
|
|
146663
|
+
instances.command("update <id>").description("Update an instance (supports all API fields)").option("--name <name>", "Instance name").option("--is-default", "Set as default instance for channel").option("--no-is-default", "Unset as default instance for channel").option("--agent-fk-id <uuid>", 'Agent FK UUID (references agents table, use "null" to clear). When assigning an agent on an instance with no reply filter, the filter defaults to {mode:"all", onDm:true} so messages are dispatched instead of silently dropped (omni#443).').option("--agent-provider <id>", "Removed: set the provider on the agent (omni agents update <agentId> --agent-provider)").option("--agent <id>", 'Agent ID (use "null" to clear)').option("--agent-type <type>", "Agent type: agent, team, or workflow").option("--agent-timeout <seconds>", "Agent timeout in seconds", (v4) => Number.parseInt(v4, 10)).option("--agent-error-message <text>", 'Customer-facing reply when agent dispatch fails; repeat the flag for multiple variants (one is picked at random per failure). Use "null" to clear; falls back to OMNI_AGENT_DISPATCH_ERROR_MESSAGE env, then built-in default', (value, previous = []) => [...previous, value]).option("--agent-stream-mode", "Enable streaming responses").option("--no-agent-stream-mode", "Disable streaming responses").option("--agent-session-strategy <strategy>", "Session strategy: per_user, per_chat, per_user_per_chat").option("--agent-prefix-sender-name", "Prefix messages with sender name").option("--no-agent-prefix-sender-name", "Disable sender name prefix").option("--agent-wait-for-media", "Wait for media processing before dispatch").option("--no-agent-wait-for-media", "Dispatch immediately without waiting for media").option("--agent-send-media-path", "Include file path in formatted media text").option("--no-agent-send-media-path", "Exclude file path from formatted media text").option("--agent-send-media-path-types <types>", "Content types that receive file path (comma-separated: image,video,document)").option("--reply-filter-mode <mode>", "Reply filter: all or filtered").option("--reply-on-dm", "Reply to DMs (requires --reply-filter-mode filtered)").option("--no-reply-on-dm", "Ignore DMs").option("--reply-on-mention", "Reply when @mentioned").option("--no-reply-on-mention", "Ignore @mentions").option("--reply-on-reply", "Reply when message is reply to bot").option("--no-reply-on-reply", "Ignore replies").option("--reply-on-name", "Reply when bot name appears in text").option("--no-reply-on-name", "Ignore name matches").option("--reply-name-patterns <patterns>", "Custom name patterns (comma-separated)").option("--clear-reply-filter", 'Remove reply filter (set to null). On an instance that keeps its agent, resets to the default {mode:"all", onDm:true} instead').option("--enable-auto-split", "Split responses on double newlines").option("--no-enable-auto-split", "Disable auto-split").option("--message-format-mode <mode>", "Format mode: convert or passthrough").option("--debounce-mode <mode>", "Debounce mode: disabled, fixed, randomized, or presence").option("--debounce-min <ms>", "Minimum debounce delay in ms", (v4) => Number.parseInt(v4, 10)).option("--debounce-max <ms>", "Maximum debounce delay in ms", (v4) => Number.parseInt(v4, 10)).option("--debounce-restart-on-typing", "Restart debounce timer on typing").option("--no-debounce-restart-on-typing", "Do not restart debounce on typing").option("--debounce-group <ms>", 'Group chat debounce in ms (use "null" to inherit)', (v4) => v4 === "null" ? null : Number.parseInt(v4, 10)).option("--debounce-max-wait <ms>", 'Presence-mode hard cap in ms (use "null" to inherit)', (v4) => v4 === "null" ? null : Number.parseInt(v4, 10)).option("--split-delay-mode <mode>", "Split delay mode: disabled, fixed, or randomized").option("--split-delay-fixed <ms>", "Fixed delay between split chunks in ms", (v4) => Number.parseInt(v4, 10)).option("--split-delay-min <ms>", "Minimum delay between split chunks in ms", (v4) => Number.parseInt(v4, 10)).option("--split-delay-max <ms>", "Maximum delay between split chunks in ms", (v4) => Number.parseInt(v4, 10)).option("--agent-gate", "Enable LLM response gate").option("--no-agent-gate", "Disable LLM response gate").option("--agent-gate-model <model>", 'Model for response gate (use "null" for default)').option("--agent-gate-prompt <prompt>", 'Custom gate prompt (use "null" for default)').option("--tts-voice <id>", 'ElevenLabs voice ID (use "null" to clear)').option("--tts-model <id>", 'ElevenLabs model ID (use "null" to clear)').option("--read-receipts <mode>", "Read receipts mode: on, off, or exclude-self").addOption(new Option("--history-identity <identity>", "WhatsApp pairing identity: desktop (macOS Desktop + group history, fuller sync) or web (Ubuntu/Chrome). Applies on next pairing (default: desktop)").choices(["desktop", "web"])).option("--sync-full-history", "WhatsApp: request full message history on connect (default: off)").option("--no-sync-full-history", "WhatsApp: do not request full message history on connect").option("--access-mode <mode>", "Access mode: disabled, blocklist, or allowlist").option("--reaction-ack <mode>", "Reaction ack mode (on|off)").option("--reaction-ack-emoji <json>", "Per-channel emoji map as JSON").option("--ack-timeout <ms>", "Ack timeout in milliseconds", (v4) => Number.parseInt(v4, 10)).option("--agent-stalled-timeout-ms <ms>", "Idle threshold in ms before the internal turn.stalled event fires (no channel message is ever sent)", (v4) => Number.parseInt(v4, 10)).option("--token <token>", "Generic bot token (auto-resolves to channel-specific field)").option("--telegram-token <token>", 'Telegram bot token (use "null" to clear)').option("--discord-token <token>", 'Discord bot token (use "null" to clear)').option("--slack-bot-token <token>", 'Slack bot token (use "null" to clear)').option("--slack-app-token <token>", 'Slack app token (use "null" to clear)').option("--slack-user-token <token>", 'Slack user token xoxp-... (use "null" to clear)').option("--slack-user-token-env <VAR>", "Read the Slack user token from environment variable VAR").option("--slack-user-token-stdin", "Read the Slack user token from stdin").option("--slack-auth-mode <mode>", 'Slack identity: bot or user (use "null" to clear)').option("--twilio-account-sid <sid>", 'Twilio Account SID (use "null" to clear)').option("--twilio-auth-token <token>", 'Twilio Auth Token (use "null" to clear)').option("--twilio-from <address>", 'Twilio WhatsApp sender address (use "null" to clear)').option("--twilio-messaging-service-sid <sid>", 'Twilio Messaging Service SID (use "null" to clear)').option("--twilio-status-callback-url <url>", 'Twilio outbound status callback URL (use "null" to clear)').option("--twilio-webhook-url <url>", 'Public Twilio webhook URL for signature validation (use "null" to clear)').option("--twilio-validate-signature", "Validate X-Twilio-Signature on webhooks").option("--no-twilio-validate-signature", "Disable X-Twilio-Signature validation").option("--gupshup-handoff-options <json>", 'Gupshup HANDOFF routing defaults and customerFields template (JSON object, use "null" to clear). The plugin reads it at connect: restart the instance for the change to take effect').option("--trigger-events <events>", 'Trigger events (comma-separated, use "null" to clear)').option("--profile-name <name>", "Update WhatsApp display name (push name)").option("--bridge-tmux-session <name>", 'Tmux session name the genie bridge spawns into for this instance (propagated as GENIE_TMUX_SESSION via NATS). Use "null" to clear.').option("--require-genie-signature", "Require a verified X-Genie-Signature on requests targeting this instance. Bearer-only requests will be rejected with 401.").option("--no-require-genie-signature", "Allow bearer-only requests targeting this instance (default).").option("--allow-first-party", "Process (do not drop) inbound messages whose sender matches another active instance owner. Lets this instance reply to messages from your own personal number.").option("--no-allow-first-party", "Drop inbound messages whose sender matches another active instance owner (default, loop-protection).").option("--force", "Proceed even if another active Slack instance uses the same app token").action(async (rawId, options) => {
|
|
146655
146664
|
const client = getClient();
|
|
146656
146665
|
if (options.agentProvider !== undefined) {
|
|
146657
146666
|
error("instances update no longer accepts --agent-provider: the provider belongs to the agent. Use `omni agents update <agentId> --agent-provider <providerId>`.");
|
|
@@ -146666,6 +146675,9 @@ function createInstancesCommand() {
|
|
|
146666
146675
|
setVal(body, "name", options.name);
|
|
146667
146676
|
setBool(body, "isDefault", options.isDefault);
|
|
146668
146677
|
setBool(body, "force", options.force);
|
|
146678
|
+
if (await defaultClearedReplyFilter(body, async () => (await client.instances.get(id)).agentId)) {
|
|
146679
|
+
warn('Instance has an agent: --clear-reply-filter stored the default reply filter {mode:"all", onDm:true}, which replies to every message. To stop replies use --agent null or --reply-filter-mode filtered.');
|
|
146680
|
+
}
|
|
146669
146681
|
if (Object.keys(body).length > 0) {
|
|
146670
146682
|
await client.instances.update(id, body);
|
|
146671
146683
|
success(`Instance updated: ${id}`, maskSecretFields(body));
|
package/dist/server/index.js
CHANGED
|
@@ -266442,7 +266442,7 @@ var init_sentry_scrub = __esm(() => {
|
|
|
266442
266442
|
var require_package7 = __commonJS((exports, module) => {
|
|
266443
266443
|
module.exports = {
|
|
266444
266444
|
name: "@omni/api",
|
|
266445
|
-
version: "2.260923.
|
|
266445
|
+
version: "2.260923.2",
|
|
266446
266446
|
private: true,
|
|
266447
266447
|
type: "module",
|
|
266448
266448
|
exports: {
|
|
@@ -544470,6 +544470,7 @@ class WhatsAppStreamSender {
|
|
|
544470
544470
|
lastRenderedText = "";
|
|
544471
544471
|
editFailed = false;
|
|
544472
544472
|
throttleMs;
|
|
544473
|
+
onSent;
|
|
544473
544474
|
constructor(getSock, jid, replyToMessageId, _chatType, options) {
|
|
544474
544475
|
this.getSock = getSock;
|
|
544475
544476
|
this.jid = jid;
|
|
@@ -544477,6 +544478,7 @@ class WhatsAppStreamSender {
|
|
|
544477
544478
|
this.formatMode = options?.formatMode ?? "convert";
|
|
544478
544479
|
this.editMode = options?.editMode ?? false;
|
|
544479
544480
|
this.throttleMs = options?.throttleMs ?? DEFAULT_THROTTLE_MS;
|
|
544481
|
+
this.onSent = options?.onSent;
|
|
544480
544482
|
}
|
|
544481
544483
|
async onThinkingDelta(_delta) {
|
|
544482
544484
|
if (this.phase === "done")
|
|
@@ -544598,7 +544600,9 @@ class WhatsAppStreamSender {
|
|
|
544598
544600
|
message: {}
|
|
544599
544601
|
}
|
|
544600
544602
|
} : undefined;
|
|
544601
|
-
await this.getSock().sendMessage(this.jid, { text }, quoted);
|
|
544603
|
+
const result = await this.getSock().sendMessage(this.jid, { text }, quoted);
|
|
544604
|
+
if (result?.key?.id)
|
|
544605
|
+
this.onSent?.(result.key.id);
|
|
544602
544606
|
this.firstMessageSent = true;
|
|
544603
544607
|
} catch (err2) {
|
|
544604
544608
|
log54.error("Failed to send message during stream", {
|
|
@@ -544641,6 +544645,8 @@ class WhatsAppStreamSender {
|
|
|
544641
544645
|
} : undefined;
|
|
544642
544646
|
const result = await this.getSock().sendMessage(this.jid, { text }, quoted);
|
|
544643
544647
|
this.messageId = result?.key?.id ?? null;
|
|
544648
|
+
if (this.messageId)
|
|
544649
|
+
this.onSent?.(this.messageId);
|
|
544644
544650
|
this.firstMessageSent = true;
|
|
544645
544651
|
} else {
|
|
544646
544652
|
const sock = this.getSock();
|
|
@@ -546062,7 +546068,8 @@ class WhatsAppPlugin extends BaseChannelPlugin {
|
|
|
546062
546068
|
return new WhatsAppStreamSender(() => this.getSocket(instanceId), jid, replyToMessageId, chatType, {
|
|
546063
546069
|
formatMode: options?.formatMode,
|
|
546064
546070
|
editMode: streamOpts.streamEditMode ?? false,
|
|
546065
|
-
throttleMs: streamOpts.streamThrottleMs ?? undefined
|
|
546071
|
+
throttleMs: streamOpts.streamThrottleMs ?? undefined,
|
|
546072
|
+
onSent: (messageId) => this.trackSentMessageId(instanceId, messageId)
|
|
546066
546073
|
});
|
|
546067
546074
|
}
|
|
546068
546075
|
async sendTyping(instanceId, chatId, duration) {
|