@automagik/omni 2.260422.4 → 2.260422.6

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.
@@ -0,0 +1,15 @@
1
+ -- #384: Drop inbound rate limiter on the dispatcher.
2
+ --
3
+ -- The `trigger_rate_limit` column gated raw inbound `message.received` events
4
+ -- (default 5 msgs / 60s per user-channel-instance) before they reached the
5
+ -- `MessageDebouncer`. Fast-typed conversational bursts — natural on WhatsApp —
6
+ -- routinely exceeded the cap and the limiter silently dropped messages with no
7
+ -- feedback, retry, or DLQ, corrupting agent context downstream.
8
+ --
9
+ -- The debouncer already collapses bursts into a single dispatch (messageCount:N),
10
+ -- so this cap was both redundant and actively harmful. The `RateLimiter` class,
11
+ -- inbound+reaction rate gates, and `trigger_rate_limit` column are all removed.
12
+ -- If backend-protection caps are later needed, they must be dispatch-level
13
+ -- (counting completed agent runs), not message-level.
14
+
15
+ ALTER TABLE "instances" DROP COLUMN "trigger_rate_limit";
@@ -197,6 +197,13 @@
197
197
  "when": 1776766900000,
198
198
  "tag": "0027_bridge_tmux_session",
199
199
  "breakpoints": true
200
+ },
201
+ {
202
+ "idx": 28,
203
+ "version": "7",
204
+ "when": 1777000000000,
205
+ "tag": "0028_drop_trigger_rate_limit",
206
+ "breakpoints": true
200
207
  }
201
208
  ]
202
209
  }
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkJpC,wBAAgB,mBAAmB,IAAI,OAAO,CAwK7C"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmJpC,wBAAgB,mBAAmB,IAAI,OAAO,CA2K7C"}
@@ -1 +1 @@
1
- {"version":3,"file":"follow-up.d.ts","sourceRoot":"","sources":["../../src/commands/follow-up.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6BpC,wBAAgB,qBAAqB,IAAI,OAAO,CAgE/C"}
1
+ {"version":3,"file":"follow-up.d.ts","sourceRoot":"","sources":["../../src/commands/follow-up.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoCpC,wBAAgB,qBAAqB,IAAI,OAAO,CAmE/C"}
@@ -1 +1 @@
1
- {"version":3,"file":"instances.d.ts","sourceRoot":"","sources":["../../src/commands/instances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0KpC,wBAAgB,sBAAsB,IAAI,OAAO,CAopChD"}
1
+ {"version":3,"file":"instances.d.ts","sourceRoot":"","sources":["../../src/commands/instances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0KpC,wBAAgB,sBAAsB,IAAI,OAAO,CA0pChD"}
@@ -6,7 +6,7 @@
6
6
  * omni providers create --name <name> --schema <schema> --base-url <url> [--api-key <key>]
7
7
  * Claude Code: --project-path <path> [--max-turns <n>] [--permission-mode <mode>]
8
8
  * OpenClaw: --default-agent-id <id>
9
- * Genie: --agent-name <name> --target-agent <name> [--team-name <template>]
9
+ * nats-genie: --agent-name <name> --target-agent <name> [--team-name <template>]
10
10
  * omni providers update <id> [--name <name>] [--base-url <url>] [--api-key <key>] [--schema-config <json>]
11
11
  * omni providers setup openclaw --gateway-url <url> --gateway-token <token> --agent-id <id>
12
12
  * omni providers agents <id>
@@ -1 +1 @@
1
- {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/commands/providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4TpC,wBAAgB,sBAAsB,IAAI,OAAO,CA0JhD"}
1
+ {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/commands/providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiUpC,wBAAgB,sBAAsB,IAAI,OAAO,CA6JhD"}
@@ -1 +1 @@
1
- {"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/commands/webhooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,qBAAqB,IAAI,OAAO,CAgL/C"}
1
+ {"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/commands/webhooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,qBAAqB,IAAI,OAAO,CAmL/C"}
package/dist/index.js CHANGED
@@ -58796,7 +58796,6 @@ var init_schema2 = __esm(() => {
58796
58796
  triggerReactions: jsonb("trigger_reactions").$type(),
58797
58797
  triggerMentionPatterns: jsonb("trigger_mention_patterns").$type(),
58798
58798
  triggerMode: varchar("trigger_mode", { length: 20 }).notNull().default("round-trip"),
58799
- triggerRateLimit: integer("trigger_rate_limit").notNull().default(5),
58800
58799
  inboundMaxAgeMinutes: integer("inbound_max_age_minutes").notNull().default(10),
58801
58800
  profileName: varchar("profile_name", { length: 255 }),
58802
58801
  profilePicUrl: text("profile_pic_url"),
@@ -113804,7 +113803,7 @@ import { fileURLToPath } from "url";
113804
113803
  // package.json
113805
113804
  var package_default = {
113806
113805
  name: "@automagik/omni",
113807
- version: "2.260422.4",
113806
+ version: "2.260422.6",
113808
113807
  description: "LLM-optimized CLI for Omni",
113809
113808
  type: "module",
113810
113809
  bin: {
@@ -114343,6 +114342,99 @@ ${ids}`);
114343
114342
  }
114344
114343
  error(`No batch job found matching "${input}"`);
114345
114344
  }
114345
+ async function resolveProviderId(input) {
114346
+ if (UUID_RE.test(input))
114347
+ return input;
114348
+ const client = getClient();
114349
+ const providers = await client.providers.list({});
114350
+ if (/^[0-9a-f]{2,}$/i.test(input)) {
114351
+ const matches = providers.filter((p) => p.id.toLowerCase().startsWith(input.toLowerCase()));
114352
+ if (matches.length === 1)
114353
+ return matches[0].id;
114354
+ if (matches.length > 1) {
114355
+ const names = matches.map((p) => ` ${p.id.slice(0, 8)} ${p.name}`).join(`
114356
+ `);
114357
+ error(`Ambiguous ID prefix "${input}" matches ${matches.length} providers:
114358
+ ${names}`);
114359
+ }
114360
+ }
114361
+ const lower = input.toLowerCase();
114362
+ const exactName = providers.find((p) => p.name.toLowerCase() === lower);
114363
+ if (exactName)
114364
+ return exactName.id;
114365
+ const nameMatches = providers.filter((p) => p.name.toLowerCase().includes(lower));
114366
+ if (nameMatches.length === 1)
114367
+ return nameMatches[0].id;
114368
+ if (nameMatches.length > 1) {
114369
+ const names = nameMatches.map((p) => ` ${p.id.slice(0, 8)} ${p.name}`).join(`
114370
+ `);
114371
+ error(`Ambiguous name "${input}" matches ${nameMatches.length} providers:
114372
+ ${names}`);
114373
+ }
114374
+ error(`No provider found matching "${input}"`);
114375
+ }
114376
+ async function resolveAgentId(input) {
114377
+ if (UUID_RE.test(input))
114378
+ return input;
114379
+ const client = getClient();
114380
+ const { items: agents } = await client.agents.list({});
114381
+ if (/^[0-9a-f]{2,}$/i.test(input)) {
114382
+ const matches = agents.filter((a) => a.id.toLowerCase().startsWith(input.toLowerCase()));
114383
+ if (matches.length === 1)
114384
+ return matches[0].id;
114385
+ if (matches.length > 1) {
114386
+ const names = matches.map((a) => ` ${a.id.slice(0, 8)} ${a.name}`).join(`
114387
+ `);
114388
+ error(`Ambiguous ID prefix "${input}" matches ${matches.length} agents:
114389
+ ${names}`);
114390
+ }
114391
+ }
114392
+ const lower = input.toLowerCase();
114393
+ const exactName = agents.find((a) => a.name.toLowerCase() === lower);
114394
+ if (exactName)
114395
+ return exactName.id;
114396
+ const nameMatches = agents.filter((a) => a.name.toLowerCase().includes(lower));
114397
+ if (nameMatches.length === 1)
114398
+ return nameMatches[0].id;
114399
+ if (nameMatches.length > 1) {
114400
+ const names = nameMatches.map((a) => ` ${a.id.slice(0, 8)} ${a.name}`).join(`
114401
+ `);
114402
+ error(`Ambiguous name "${input}" matches ${nameMatches.length} agents:
114403
+ ${names}`);
114404
+ }
114405
+ error(`No agent found matching "${input}"`);
114406
+ }
114407
+ async function resolveWebhookId(input) {
114408
+ if (UUID_RE.test(input))
114409
+ return input;
114410
+ const client = getClient();
114411
+ const sources = await client.webhooks.listSources({});
114412
+ if (/^[0-9a-f]{2,}$/i.test(input)) {
114413
+ const matches = sources.filter((w) => w.id.toLowerCase().startsWith(input.toLowerCase()));
114414
+ if (matches.length === 1)
114415
+ return matches[0].id;
114416
+ if (matches.length > 1) {
114417
+ const names = matches.map((w) => ` ${w.id.slice(0, 8)} ${w.name}`).join(`
114418
+ `);
114419
+ error(`Ambiguous ID prefix "${input}" matches ${matches.length} webhook sources:
114420
+ ${names}`);
114421
+ }
114422
+ }
114423
+ const lower = input.toLowerCase();
114424
+ const exactName = sources.find((w) => w.name.toLowerCase() === lower);
114425
+ if (exactName)
114426
+ return exactName.id;
114427
+ const nameMatches = sources.filter((w) => w.name.toLowerCase().includes(lower));
114428
+ if (nameMatches.length === 1)
114429
+ return nameMatches[0].id;
114430
+ if (nameMatches.length > 1) {
114431
+ const names = nameMatches.map((w) => ` ${w.id.slice(0, 8)} ${w.name}`).join(`
114432
+ `);
114433
+ error(`Ambiguous name "${input}" matches ${nameMatches.length} webhook sources:
114434
+ ${names}`);
114435
+ }
114436
+ error(`No webhook source found matching "${input}"`);
114437
+ }
114346
114438
  async function resolveRouteId(instanceId, input) {
114347
114439
  if (UUID_RE.test(input))
114348
114440
  return input;
@@ -114678,9 +114770,10 @@ function createAgentsCommand() {
114678
114770
  }
114679
114771
  });
114680
114772
  agents.command("get <id>").description("Get agent details").action(async (id) => {
114773
+ const resolvedId = await resolveAgentId(id);
114681
114774
  const client = getClient();
114682
114775
  try {
114683
- const agent = await client.agents.get(id);
114776
+ const agent = await client.agents.get(resolvedId);
114684
114777
  data(agent);
114685
114778
  } catch (err) {
114686
114779
  const message = err instanceof Error ? err.message : "Unknown error";
@@ -114703,10 +114796,11 @@ function createAgentsCommand() {
114703
114796
  if (options.configPath !== undefined)
114704
114797
  body.configPath = options.configPath;
114705
114798
  const parsedMetadata = parseMetadataJson(options.metadata);
114799
+ const resolvedId = await resolveAgentId(id);
114706
114800
  const client = getClient();
114707
114801
  try {
114708
114802
  if (parsedMetadata !== undefined || options.providerAgentId !== undefined) {
114709
- const existing = await client.agents.get(id);
114803
+ const existing = await client.agents.get(resolvedId);
114710
114804
  const existingMetadata = existing.metadata ?? {};
114711
114805
  const merged = { ...existingMetadata, ...parsedMetadata ?? {} };
114712
114806
  if (options.providerAgentId !== undefined)
@@ -114716,7 +114810,7 @@ function createAgentsCommand() {
114716
114810
  if (Object.keys(body).length === 0) {
114717
114811
  error("No fields to update. Pass at least one of --name, --model, --provider, --agent-provider, --type, --active, --inactive, --config-path, --metadata, --provider-agent-id.");
114718
114812
  }
114719
- const agent = await client.agents.update(id, body);
114813
+ const agent = await client.agents.update(resolvedId, body);
114720
114814
  data(agent);
114721
114815
  } catch (err) {
114722
114816
  const message = err instanceof Error ? err.message : "Unknown error";
@@ -114724,10 +114818,11 @@ function createAgentsCommand() {
114724
114818
  }
114725
114819
  });
114726
114820
  agents.command("delete <id>").description("Delete an agent (soft-delete, sets inactive)").action(async (id) => {
114821
+ const resolvedId = await resolveAgentId(id);
114727
114822
  const client = getClient();
114728
114823
  try {
114729
- await client.agents.delete(id);
114730
- success(`Agent ${id} deleted.`);
114824
+ await client.agents.delete(resolvedId);
114825
+ success(`Agent ${resolvedId} deleted.`);
114731
114826
  } catch (err) {
114732
114827
  const message = err instanceof Error ? err.message : "Unknown error";
114733
114828
  error(`Failed to delete agent: ${message}`, undefined, 3);
@@ -119464,6 +119559,13 @@ function assertScope(scope) {
119464
119559
  error(`Invalid scope: ${scope}. Expected one of: ${VALID_SCOPES.join(", ")}`);
119465
119560
  }
119466
119561
  }
119562
+ async function resolveScopedId(scope, id) {
119563
+ if (scope === "agents")
119564
+ return resolveAgentId(id);
119565
+ if (scope === "instances")
119566
+ return resolveInstanceId(id);
119567
+ return resolveChatId(id);
119568
+ }
119467
119569
  function readJsonArg(raw2) {
119468
119570
  let body = raw2;
119469
119571
  if (body === "-") {
@@ -119482,9 +119584,10 @@ function createFollowUpCommand() {
119482
119584
  const cmd = new Command("follow-up").description("Idle-chat follow-up config (agents/instances/chats). Closest scope wins at runtime.");
119483
119585
  cmd.command("get <scope> <id>").description("Read follow-up config at a scope (agents|instances|chats).").action(async (scope, id) => {
119484
119586
  assertScope(scope);
119587
+ const resolvedId = await resolveScopedId(scope, id);
119485
119588
  const client = getClient();
119486
119589
  try {
119487
- const data2 = scope === "agents" ? await client.followUp.getAgent(id) : scope === "instances" ? await client.followUp.getInstance(id) : await client.followUp.getChat(id);
119590
+ const data2 = scope === "agents" ? await client.followUp.getAgent(resolvedId) : scope === "instances" ? await client.followUp.getInstance(resolvedId) : await client.followUp.getChat(resolvedId);
119488
119591
  data(data2);
119489
119592
  } catch (err) {
119490
119593
  const message = err instanceof Error ? err.message : "Unknown error";
@@ -119494,10 +119597,11 @@ function createFollowUpCommand() {
119494
119597
  cmd.command("set <scope> <id> <json>").description("Write follow-up config at a scope. <json> can be a literal, `@path`, or `-` for stdin.").action(async (scope, id, json) => {
119495
119598
  assertScope(scope);
119496
119599
  const config = readJsonArg(json);
119600
+ const resolvedId = await resolveScopedId(scope, id);
119497
119601
  const client = getClient();
119498
119602
  try {
119499
- const data2 = scope === "agents" ? await client.followUp.setAgent(id, config) : scope === "instances" ? await client.followUp.setInstance(id, config) : await client.followUp.setChat(id, config);
119500
- success(`Follow-up config set on ${scope.slice(0, -1)} ${id}.`, data2);
119603
+ const data2 = scope === "agents" ? await client.followUp.setAgent(resolvedId, config) : scope === "instances" ? await client.followUp.setInstance(resolvedId, config) : await client.followUp.setChat(resolvedId, config);
119604
+ success(`Follow-up config set on ${scope.slice(0, -1)} ${resolvedId}.`, data2);
119501
119605
  } catch (err) {
119502
119606
  const message = err instanceof Error ? err.message : "Unknown error";
119503
119607
  error(`Failed to set ${scope} follow-up: ${message}`, undefined, 3);
@@ -119505,15 +119609,16 @@ function createFollowUpCommand() {
119505
119609
  });
119506
119610
  cmd.command("unset <scope> <id>").description("Clear the override at a scope so broader scopes apply.").action(async (scope, id) => {
119507
119611
  assertScope(scope);
119612
+ const resolvedId = await resolveScopedId(scope, id);
119508
119613
  const client = getClient();
119509
119614
  try {
119510
119615
  if (scope === "agents")
119511
- await client.followUp.unsetAgent(id);
119616
+ await client.followUp.unsetAgent(resolvedId);
119512
119617
  else if (scope === "instances")
119513
- await client.followUp.unsetInstance(id);
119618
+ await client.followUp.unsetInstance(resolvedId);
119514
119619
  else
119515
- await client.followUp.unsetChat(id);
119516
- success(`Follow-up config cleared on ${scope.slice(0, -1)} ${id}.`);
119620
+ await client.followUp.unsetChat(resolvedId);
119621
+ success(`Follow-up config cleared on ${scope.slice(0, -1)} ${resolvedId}.`);
119517
119622
  } catch (err) {
119518
119623
  const message = err instanceof Error ? err.message : "Unknown error";
119519
119624
  error(`Failed to unset ${scope} follow-up: ${message}`, undefined, 3);
@@ -120207,7 +120312,7 @@ function createInstancesCommand() {
120207
120312
  error(`Failed to get instance: ${message}`, undefined, 3);
120208
120313
  }
120209
120314
  });
120210
- instances.command("create").description("Create a new instance (supports all API fields)").requiredOption("--name <name>", "Instance name").requiredOption("--channel <type>", `Channel type (${VALID_CHANNELS2.join(", ")})`).option("--agent-fk-id <uuid>", 'Agent FK UUID (references agents table, use "null" to clear)').option("--agent-provider <id>", "Agent provider ID").option("--agent <id>", "Agent ID").option("--agent-type <type>", "Agent type: agent, team, or workflow").option("--agent-timeout <seconds>", "Agent timeout in seconds", (v) => Number.parseInt(v, 10)).option("--agent-stream-mode", "Enable 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").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("--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, or randomized").option("--debounce-min <ms>", "Minimum debounce delay in ms", (v) => Number.parseInt(v, 10)).option("--debounce-max <ms>", "Maximum debounce delay in ms", (v) => Number.parseInt(v, 10)).option("--debounce-restart-on-typing", "Restart debounce timer on typing").option("--debounce-group <ms>", "Group chat debounce in ms", (v) => Number.parseInt(v, 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", (v) => Number.parseInt(v, 10)).option("--split-delay-min <ms>", "Minimum delay between split chunks in ms", (v) => Number.parseInt(v, 10)).option("--split-delay-max <ms>", "Maximum delay between split chunks in ms", (v) => Number.parseInt(v, 10)).option("--agent-gate", "Enable LLM response gate").option("--agent-gate-model <model>", "Model for response gate").option("--agent-gate-prompt <prompt>", "Custom gate prompt").option("--tts-voice <id>", "ElevenLabs voice ID").option("--tts-model <id>", "ElevenLabs model ID").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", (v) => Number.parseInt(v, 10)).option("--agent-stalled-timeout-ms <ms>", "Idle threshold in ms before the internal turn.stalled event fires (no channel message is ever sent)", (v) => Number.parseInt(v, 10)).option("--token <token>", "Generic bot token (auto-resolves to channel-specific field)").option("--telegram-token <token>", "Telegram bot token").option("--discord-token <token>", "Discord bot token").option("--slack-bot-token <token>", "Slack bot token").option("--slack-app-token <token>", "Slack app token").option("--gupshup-callback-url <url>", "Gupshup Custom Integration callback URL").option("--gupshup-auth-token <token>", "Gupshup Custom Integration auth token").option("--gupshup-event-id <id>", "Gupshup event ID (default: nx_omni_agent_reply)").option("--gupshup-webhook-verify-token <token>", "Gupshup webhook verify token").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("--is-default", "Set as default instance for channel").action(async (options) => {
120315
+ instances.command("create").description("Create a new instance (supports all API fields)").requiredOption("--name <name>", "Instance name").requiredOption("--channel <type>", `Channel type (${VALID_CHANNELS2.join(", ")})`).option("--agent-fk-id <uuid>", 'Agent FK UUID (references agents table, use "null" to clear). When set without --reply-filter-mode, reply filter defaults to {mode:"all", onDm:true} so messages are dispatched instead of silently dropped (omni#443).').option("--agent-provider <id>", "Agent provider ID").option("--agent <id>", "Agent ID").option("--agent-type <type>", "Agent type: agent, team, or workflow").option("--agent-timeout <seconds>", "Agent timeout in seconds", (v) => Number.parseInt(v, 10)).option("--agent-stream-mode", "Enable 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").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("--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, or randomized").option("--debounce-min <ms>", "Minimum debounce delay in ms", (v) => Number.parseInt(v, 10)).option("--debounce-max <ms>", "Maximum debounce delay in ms", (v) => Number.parseInt(v, 10)).option("--debounce-restart-on-typing", "Restart debounce timer on typing").option("--debounce-group <ms>", "Group chat debounce in ms", (v) => Number.parseInt(v, 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", (v) => Number.parseInt(v, 10)).option("--split-delay-min <ms>", "Minimum delay between split chunks in ms", (v) => Number.parseInt(v, 10)).option("--split-delay-max <ms>", "Maximum delay between split chunks in ms", (v) => Number.parseInt(v, 10)).option("--agent-gate", "Enable LLM response gate").option("--agent-gate-model <model>", "Model for response gate").option("--agent-gate-prompt <prompt>", "Custom gate prompt").option("--tts-voice <id>", "ElevenLabs voice ID").option("--tts-model <id>", "ElevenLabs model ID").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", (v) => Number.parseInt(v, 10)).option("--agent-stalled-timeout-ms <ms>", "Idle threshold in ms before the internal turn.stalled event fires (no channel message is ever sent)", (v) => Number.parseInt(v, 10)).option("--token <token>", "Generic bot token (auto-resolves to channel-specific field)").option("--telegram-token <token>", "Telegram bot token").option("--discord-token <token>", "Discord bot token").option("--slack-bot-token <token>", "Slack bot token").option("--slack-app-token <token>", "Slack app token").option("--gupshup-callback-url <url>", "Gupshup Custom Integration callback URL").option("--gupshup-auth-token <token>", "Gupshup Custom Integration auth token").option("--gupshup-event-id <id>", "Gupshup event ID (default: nx_omni_agent_reply)").option("--gupshup-webhook-verify-token <token>", "Gupshup webhook verify token").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("--is-default", "Set as default instance for channel").action(async (options) => {
120211
120316
  const channel = options.channel;
120212
120317
  if (!VALID_CHANNELS2.includes(channel)) {
120213
120318
  error(`Invalid channel: ${channel}`, { validChannels: VALID_CHANNELS2 });
@@ -120468,7 +120573,7 @@ function createInstancesCommand() {
120468
120573
  throw new Error(err?.error?.message ?? `HTTP ${response.status}`);
120469
120574
  }
120470
120575
  }
120471
- 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)').option("--agent-provider <id>", 'Agent provider ID (use "null" to clear)').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", (v) => Number.parseInt(v, 10)).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)").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, or randomized").option("--debounce-min <ms>", "Minimum debounce delay in ms", (v) => Number.parseInt(v, 10)).option("--debounce-max <ms>", "Maximum debounce delay in ms", (v) => Number.parseInt(v, 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)', (v) => v === "null" ? null : Number.parseInt(v, 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", (v) => Number.parseInt(v, 10)).option("--split-delay-min <ms>", "Minimum delay between split chunks in ms", (v) => Number.parseInt(v, 10)).option("--split-delay-max <ms>", "Maximum delay between split chunks in ms", (v) => Number.parseInt(v, 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("--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", (v) => Number.parseInt(v, 10)).option("--agent-stalled-timeout-ms <ms>", "Idle threshold in ms before the internal turn.stalled event fires (no channel message is ever sent)", (v) => Number.parseInt(v, 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("--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.').action(async (rawId, options) => {
120576
+ 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>", 'Agent provider ID (use "null" to clear)').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", (v) => Number.parseInt(v, 10)).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)").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, or randomized").option("--debounce-min <ms>", "Minimum debounce delay in ms", (v) => Number.parseInt(v, 10)).option("--debounce-max <ms>", "Maximum debounce delay in ms", (v) => Number.parseInt(v, 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)', (v) => v === "null" ? null : Number.parseInt(v, 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", (v) => Number.parseInt(v, 10)).option("--split-delay-min <ms>", "Minimum delay between split chunks in ms", (v) => Number.parseInt(v, 10)).option("--split-delay-max <ms>", "Maximum delay between split chunks in ms", (v) => Number.parseInt(v, 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("--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", (v) => Number.parseInt(v, 10)).option("--agent-stalled-timeout-ms <ms>", "Idle threshold in ms before the internal turn.stalled event fires (no channel message is ever sent)", (v) => Number.parseInt(v, 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("--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.').action(async (rawId, options) => {
120472
120577
  const client = getClient();
120473
120578
  try {
120474
120579
  const id = await resolveInstanceId(rawId);
@@ -122991,8 +123096,8 @@ Example: omni providers create --schema openclaw --default-agent-id sofia ...`;
122991
123096
  Example: omni providers create --name "My Project" --schema claude-code --base-url http://localhost:8882 --project-path /home/user/myproject`;
122992
123097
  }
122993
123098
  if (options.schema === "nats-genie" && (!options.agentName || !options.targetAgent)) {
122994
- return `Genie providers require --agent-name and --target-agent.
122995
- Example: omni providers create --name "My Genie" --schema nats-genie --base-url "file:///home/user/.claude/teams" --agent-name omni --target-agent team-lead --team-name "workspace-{chat_id}"`;
123099
+ return `nats-genie providers require --agent-name and --target-agent.
123100
+ Example: omni providers create --name "My Nats Genie" --schema nats-genie --base-url "file:///home/user/.claude/teams" --agent-name omni --target-agent team-lead --team-name "workspace-{chat_id}"`;
122996
123101
  }
122997
123102
  return null;
122998
123103
  }
@@ -123117,9 +123222,10 @@ async function handleList3(options) {
123117
123222
  }
123118
123223
  }
123119
123224
  async function handleGet2(id) {
123225
+ const resolvedId = await resolveProviderId(id);
123120
123226
  const client = getClient();
123121
123227
  try {
123122
- const provider = await client.providers.get(id);
123228
+ const provider = await client.providers.get(resolvedId);
123123
123229
  data(provider);
123124
123230
  } catch (err2) {
123125
123231
  const message2 = err2 instanceof Error ? err2.message : "Unknown error";
@@ -123156,9 +123262,10 @@ Next steps:`);
123156
123262
  }
123157
123263
  }
123158
123264
  async function handleTest(id) {
123265
+ const resolvedId = await resolveProviderId(id);
123159
123266
  const client = getClient();
123160
123267
  try {
123161
- const result = await client.providers.checkHealth(id);
123268
+ const result = await client.providers.checkHealth(resolvedId);
123162
123269
  if (result.healthy) {
123163
123270
  success(`Provider is healthy (latency: ${result.latency}ms)`);
123164
123271
  } else {
@@ -123181,14 +123288,15 @@ async function handleUpdate2(id, options) {
123181
123288
  error("No fields to update. Provide at least one option.");
123182
123289
  return;
123183
123290
  }
123291
+ const resolvedId = await resolveProviderId(id);
123184
123292
  const client = getClient();
123185
123293
  try {
123186
123294
  if (body.schemaConfig && !options.schemaConfig) {
123187
- const existing = await client.providers.get(id);
123295
+ const existing = await client.providers.get(resolvedId);
123188
123296
  const existingConfig = existing.schemaConfig ?? {};
123189
123297
  body.schemaConfig = { ...existingConfig, ...body.schemaConfig };
123190
123298
  }
123191
- const provider = await client.providers.update(id, body);
123299
+ const provider = await client.providers.update(resolvedId, body);
123192
123300
  success(`Updated provider: ${provider.id}`);
123193
123301
  data(provider);
123194
123302
  } catch (err2) {
@@ -123201,10 +123309,11 @@ async function handleDelete2(id, options) {
123201
123309
  warn(`This will delete provider ${id}. Use --force to confirm.`);
123202
123310
  return;
123203
123311
  }
123312
+ const resolvedId = await resolveProviderId(id);
123204
123313
  const client = getClient();
123205
123314
  try {
123206
- await client.providers.delete(id);
123207
- success(`Deleted provider: ${id}`);
123315
+ await client.providers.delete(resolvedId);
123316
+ success(`Deleted provider: ${resolvedId}`);
123208
123317
  } catch (err2) {
123209
123318
  const message2 = err2 instanceof Error ? err2.message : "Unknown error";
123210
123319
  error(`Failed to delete provider: ${message2}`);
@@ -123215,12 +123324,13 @@ function createProvidersCommand() {
123215
123324
  providers2.addCommand(createSetupCommand());
123216
123325
  providers2.command("list").description("List available providers").option("--active", "Show only active providers").action(handleList3);
123217
123326
  providers2.command("get <id>").description("Get provider details").action(handleGet2);
123218
- providers2.command("create").description("Create a new AI provider").requiredOption("--name <name>", "Provider name (unique)").requiredOption("--schema <schema>", `Provider schema (${VALID_SCHEMAS.join(", ")})`).requiredOption("--base-url <url>", "API base URL (ws:// or wss:// for openclaw)").option("--api-key <key>", "API key (optional for claude-code if using env ANTHROPIC_API_KEY)").option("--description <desc>", "Provider description").option("--timeout <seconds>", "Default timeout in seconds", Number.parseInt, 60).option("--stream", "Enable streaming by default").option("--default-agent-id <agentId>", "Default agent ID (required for openclaw)").option("--project-path <path>", "Project directory path (required for claude-code)").option("--max-turns <number>", "Max conversation turns (claude-code)", Number.parseInt).option("--permission-mode <mode>", "Permission mode: default, acceptEdits, bypassPermissions, plan (claude-code)").option("--model <model>", "Model override (claude-code)").option("--system-prompt <prompt>", "System prompt prepended to agent (claude-code)").option("--agent-name <name>", 'Agent identity / "from" field (required for genie)').option("--target-agent <name>", "Target agent inbox to deliver to (required for genie)").option("--team-name <template>", "Team name template, supports {chat_id}, {thread_id}, {sender_id} (genie, default: omni-{chat_id})").action(handleCreate3);
123327
+ providers2.command("create").description("Create a new AI provider").requiredOption("--name <name>", "Provider name (unique)").requiredOption("--schema <schema>", `Provider schema (${VALID_SCHEMAS.join(", ")})`).requiredOption("--base-url <url>", "API base URL (ws:// or wss:// for openclaw)").option("--api-key <key>", "API key (optional for claude-code if using env ANTHROPIC_API_KEY)").option("--description <desc>", "Provider description").option("--timeout <seconds>", "Default timeout in seconds", Number.parseInt, 60).option("--stream", "Enable streaming by default").option("--default-agent-id <agentId>", "Default agent ID (required for openclaw)").option("--project-path <path>", "Project directory path (required for claude-code)").option("--max-turns <number>", "Max conversation turns (claude-code)", Number.parseInt).option("--permission-mode <mode>", "Permission mode: default, acceptEdits, bypassPermissions, plan (claude-code)").option("--model <model>", "Model override (claude-code)").option("--system-prompt <prompt>", "System prompt prepended to agent (claude-code)").option("--agent-name <name>", 'Agent identity / "from" field (required for nats-genie)').option("--target-agent <name>", "Target agent inbox to deliver to (required for nats-genie)").option("--team-name <template>", "Team name template, supports {chat_id}, {thread_id}, {sender_id} (nats-genie, default: omni-{chat_id})").action(handleCreate3);
123219
123328
  providers2.command("test <id>").description("Test provider health").action(handleTest);
123220
123329
  providers2.command("agents <id>").description("List agents from provider (Agno)").action(async (id) => {
123330
+ const resolvedId = await resolveProviderId(id);
123221
123331
  const client = getClient();
123222
123332
  try {
123223
- const agents2 = await client.providers.listAgents(id);
123333
+ const agents2 = await client.providers.listAgents(resolvedId);
123224
123334
  const items = agents2.map((a2) => ({
123225
123335
  id: a2.agent_id,
123226
123336
  name: a2.name,
@@ -123234,9 +123344,10 @@ function createProvidersCommand() {
123234
123344
  }
123235
123345
  });
123236
123346
  providers2.command("teams <id>").description("List teams from provider (Agno)").action(async (id) => {
123347
+ const resolvedId = await resolveProviderId(id);
123237
123348
  const client = getClient();
123238
123349
  try {
123239
- const teams = await client.providers.listTeams(id);
123350
+ const teams = await client.providers.listTeams(resolvedId);
123240
123351
  const items = teams.map((t) => ({
123241
123352
  id: t.team_id,
123242
123353
  name: t.name,
@@ -123251,9 +123362,10 @@ function createProvidersCommand() {
123251
123362
  }
123252
123363
  });
123253
123364
  providers2.command("workflows <id>").description("List workflows from provider (Agno)").action(async (id) => {
123365
+ const resolvedId = await resolveProviderId(id);
123254
123366
  const client = getClient();
123255
123367
  try {
123256
- const workflows = await client.providers.listWorkflows(id);
123368
+ const workflows = await client.providers.listWorkflows(resolvedId);
123257
123369
  const items = workflows.map((w) => ({
123258
123370
  id: w.workflow_id,
123259
123371
  name: w.name,
@@ -123265,7 +123377,7 @@ function createProvidersCommand() {
123265
123377
  error(`Failed to list workflows: ${message2}`);
123266
123378
  }
123267
123379
  });
123268
- providers2.command("update <id>").description("Update a provider").option("--name <name>", "Provider name").option("--base-url <url>", "API base URL").option("--api-key <key>", "API key").option("--description <desc>", "Provider description").option("--timeout <seconds>", "Default timeout in seconds", Number.parseInt).option("--stream", "Enable streaming by default").option("--no-stream", "Disable streaming by default").option("--active", "Set provider active").option("--no-active", "Set provider inactive").option("--agent-name <name>", "Agent identity (genie)").option("--target-agent <name>", "Target agent inbox (genie)").option("--team-name <template>", "Team name template (genie)").option("--project-path <path>", "Project directory path (claude-code)").option("--max-turns <number>", "Max conversation turns (claude-code)", Number.parseInt).option("--permission-mode <mode>", "Permission mode (claude-code)").option("--model <model>", "Model override (claude-code)").option("--system-prompt <prompt>", "System prompt (claude-code)").option("--schema-config <json>", "Raw schemaConfig as JSON (overrides individual schema flags)").action(handleUpdate2);
123380
+ providers2.command("update <id>").description("Update a provider").option("--name <name>", "Provider name").option("--base-url <url>", "API base URL").option("--api-key <key>", "API key").option("--description <desc>", "Provider description").option("--timeout <seconds>", "Default timeout in seconds", Number.parseInt).option("--stream", "Enable streaming by default").option("--no-stream", "Disable streaming by default").option("--active", "Set provider active").option("--no-active", "Set provider inactive").option("--agent-name <name>", "Agent identity (nats-genie)").option("--target-agent <name>", "Target agent inbox (nats-genie)").option("--team-name <template>", "Team name template (nats-genie)").option("--project-path <path>", "Project directory path (claude-code)").option("--max-turns <number>", "Max conversation turns (claude-code)", Number.parseInt).option("--permission-mode <mode>", "Permission mode (claude-code)").option("--model <model>", "Model override (claude-code)").option("--system-prompt <prompt>", "System prompt (claude-code)").option("--schema-config <json>", "Raw schemaConfig as JSON (overrides individual schema flags)").action(handleUpdate2);
123269
123381
  providers2.command("delete <id>").description("Delete a provider").option("--force", "Skip confirmation").action(handleDelete2);
123270
123382
  return providers2;
123271
123383
  }
@@ -125308,9 +125420,10 @@ function createWebhooksCommand() {
125308
125420
  }
125309
125421
  });
125310
125422
  webhooks.command("get <id>").description("Get webhook source details").action(async (id) => {
125423
+ const resolvedId = await resolveWebhookId(id);
125311
125424
  const client = getClient();
125312
125425
  try {
125313
- const source = await client.webhooks.getSource(id);
125426
+ const source = await client.webhooks.getSource(resolvedId);
125314
125427
  data(source);
125315
125428
  } catch (err2) {
125316
125429
  const message2 = err2 instanceof Error ? err2.message : "Unknown error";
@@ -125345,6 +125458,7 @@ function createWebhooksCommand() {
125345
125458
  }
125346
125459
  });
125347
125460
  webhooks.command("update <id>").description("Update a webhook source").option("--name <name>", "New name").option("--description <desc>", "New description").option("--enable", "Enable the webhook").option("--disable", "Disable the webhook").action(async (id, options3) => {
125461
+ const resolvedId = await resolveWebhookId(id);
125348
125462
  const client = getClient();
125349
125463
  try {
125350
125464
  const updates = {};
@@ -125356,7 +125470,7 @@ function createWebhooksCommand() {
125356
125470
  updates.enabled = true;
125357
125471
  if (options3.disable)
125358
125472
  updates.enabled = false;
125359
- const source = await client.webhooks.updateSource(id, updates);
125473
+ const source = await client.webhooks.updateSource(resolvedId, updates);
125360
125474
  success(`Webhook source updated: ${source.id}`, {
125361
125475
  id: source.id,
125362
125476
  name: source.name,
@@ -125368,10 +125482,11 @@ function createWebhooksCommand() {
125368
125482
  }
125369
125483
  });
125370
125484
  webhooks.command("delete <id>").description("Delete a webhook source").action(async (id) => {
125485
+ const resolvedId = await resolveWebhookId(id);
125371
125486
  const client = getClient();
125372
125487
  try {
125373
- await client.webhooks.deleteSource(id);
125374
- success(`Webhook source deleted: ${id}`);
125488
+ await client.webhooks.deleteSource(resolvedId);
125489
+ success(`Webhook source deleted: ${resolvedId}`);
125375
125490
  } catch (err2) {
125376
125491
  const message2 = err2 instanceof Error ? err2.message : "Unknown error";
125377
125492
  error(`Failed to delete webhook source: ${message2}`);
package/dist/resolve.d.ts CHANGED
@@ -97,6 +97,42 @@ export declare function resolveAutomationId(input: string): Promise<string>;
97
97
  * Exits with error if no match or ambiguous.
98
98
  */
99
99
  export declare function resolveBatchJobId(input: string): Promise<string>;
100
+ /**
101
+ * Resolve a provider identifier to a UUID.
102
+ *
103
+ * Matches in order:
104
+ * 1. Exact UUID match (skip API call)
105
+ * 2. UUID prefix match (minimum 2 hex chars)
106
+ * 3. Exact name match (case-insensitive)
107
+ * 4. Name substring match (case-insensitive)
108
+ *
109
+ * Exits with error if no match or ambiguous.
110
+ */
111
+ export declare function resolveProviderId(input: string): Promise<string>;
112
+ /**
113
+ * Resolve an agent identifier to a UUID.
114
+ *
115
+ * Matches in order:
116
+ * 1. Exact UUID match (skip API call)
117
+ * 2. UUID prefix match (minimum 2 hex chars)
118
+ * 3. Exact name match (case-insensitive)
119
+ * 4. Name substring match (case-insensitive)
120
+ *
121
+ * Exits with error if no match or ambiguous.
122
+ */
123
+ export declare function resolveAgentId(input: string): Promise<string>;
124
+ /**
125
+ * Resolve a webhook source identifier to a UUID.
126
+ *
127
+ * Matches in order:
128
+ * 1. Exact UUID match (skip API call)
129
+ * 2. UUID prefix match (minimum 2 hex chars)
130
+ * 3. Exact name match (case-insensitive)
131
+ * 4. Name substring match (case-insensitive)
132
+ *
133
+ * Exits with error if no match or ambiguous.
134
+ */
135
+ export declare function resolveWebhookId(input: string): Promise<string>;
100
136
  /**
101
137
  * Resolve an agent route identifier to a UUID.
102
138
  *
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA+BtE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA+BlE;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAYrE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwCtF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBpE;AAED;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA+BjE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BxE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBtE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBvF"}
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA+BtE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA+BlE;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAYrE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwCtF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBpE;AAED;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA+BjE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BxE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBtE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BtE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BnE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BrE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBvF"}