@automagik/omni 2.260915.14 → 2.260915.16

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,19 @@
1
+ -- Competing (shared) durable consumers (issue #1188).
2
+ --
3
+ -- Consumers fan out: each name owns a cursor, so N workers on N names each
4
+ -- see every event. A shared consumer lets N pullers on ONE name split the
5
+ -- stream: pull leases a page (claimed watermark + lease list), ack releases
6
+ -- the lease, and an expired lease is redelivered (at-least-once).
7
+ --
8
+ -- durable_consumers.shared default false (fan-out, unchanged)
9
+ -- durable_consumers.lease_state jsonb, null unless shared
10
+ --
11
+ -- Hand-written following the 0043/0044/0052 precedent (additive, idempotent).
12
+ -- No explicit BEGIN/COMMIT — the boot migrator executes this file on a pooled
13
+ -- postgres-js connection, which rejects raw transaction control.
14
+
15
+ ALTER TABLE "durable_consumers"
16
+ ADD COLUMN IF NOT EXISTS "shared" boolean NOT NULL DEFAULT false;
17
+ --> statement-breakpoint
18
+ ALTER TABLE "durable_consumers"
19
+ ADD COLUMN IF NOT EXISTS "lease_state" jsonb;
@@ -505,6 +505,13 @@
505
505
  "when": 1787100000000,
506
506
  "tag": "0071_webhook_idempotency_across_event_types",
507
507
  "breakpoints": true
508
+ },
509
+ {
510
+ "idx": 72,
511
+ "version": "7",
512
+ "when": 1787200000000,
513
+ "tag": "0072_shared_durable_consumers",
514
+ "breakpoints": true
508
515
  }
509
516
  ]
510
517
  }
@@ -6,7 +6,27 @@
6
6
  * omni channels list - Show available channel types + instance counts
7
7
  * omni channels add <type> [--token <token>] [--name <name>] - Add a new channel instance
8
8
  * omni channels status - Overview of all channels and connection states
9
+ * omni channels capabilities - Event vocabulary + guarantees per loaded channel
9
10
  */
10
11
  import { Command } from 'commander';
12
+ type CapabilityFlag = boolean | 'unknown';
13
+ interface ChannelCapabilityRow {
14
+ id: string;
15
+ emits: string[] | null;
16
+ edits: CapabilityFlag;
17
+ deletes: CapabilityFlag;
18
+ idempotency: CapabilityFlag;
19
+ }
20
+ /** One matrix row; `?` wherever the plugin declares nothing. */
21
+ export declare function capabilityRow(ch: ChannelCapabilityRow): {
22
+ channel: string;
23
+ 'message.received': string;
24
+ 'message.sent': string;
25
+ 'reaction.*': string;
26
+ edit: string;
27
+ delete: string;
28
+ idempotency: string;
29
+ };
11
30
  export declare function createChannelsCommand(): Command;
31
+ export {};
12
32
  //# sourceMappingURL=channels.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../../src/commands/channels.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkDpC,wBAAgB,qBAAqB,IAAI,OAAO,CAqH/C"}
1
+ {"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../../src/commands/channels.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkDpC,KAAK,cAAc,GAAG,OAAO,GAAG,SAAS,CAAC;AAC1C,UAAU,oBAAoB;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,cAAc,CAAC;IACtB,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,EAAE,cAAc,CAAC;CAC7B;AAID,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,EAAE,EAAE,oBAAoB;;;;;;;;EAYrD;AAED,wBAAgB,qBAAqB,IAAI,OAAO,CAqI/C"}
@@ -202,6 +202,8 @@ interface ConsumerData {
202
202
  excludeTypes?: string[] | null;
203
203
  filters: AutomationCondition[] | null;
204
204
  cursor: number;
205
+ /** Competing consumers (#1188). Absent on older servers. */
206
+ shared?: boolean;
205
207
  head: number;
206
208
  lag: number;
207
209
  /** No type-matching row past the cursor (#1128). Absent on older servers. */
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/commands/events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/commands/events.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -83361,6 +83361,8 @@ var init_schema2 = __esm(() => {
83361
83361
  excludeTypes: jsonb("exclude_types").$type(),
83362
83362
  filters: jsonb("filters").$type(),
83363
83363
  cursor: bigint2("cursor", { mode: "number" }).notNull().default(0),
83364
+ shared: boolean2("shared").notNull().default(false),
83365
+ leaseState: jsonb("lease_state").$type(),
83364
83366
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
83365
83367
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
83366
83368
  }, (table3) => ({
@@ -104664,9 +104666,9 @@ __export(exports_supports_color, {
104664
104666
  import process10 from "process";
104665
104667
  import os3 from "os";
104666
104668
  import tty2 from "tty";
104667
- function hasFlag2(flag, argv = globalThis.Deno ? globalThis.Deno.args : process10.argv) {
104668
- const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
104669
- const position = argv.indexOf(prefix + flag);
104669
+ function hasFlag2(flag2, argv = globalThis.Deno ? globalThis.Deno.args : process10.argv) {
104670
+ const prefix = flag2.startsWith("-") ? "" : flag2.length === 1 ? "-" : "--";
104671
+ const position = argv.indexOf(prefix + flag2);
104670
104672
  const terminatorPosition = argv.indexOf("--");
104671
104673
  return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
104672
104674
  }
@@ -137384,7 +137386,7 @@ import { fileURLToPath } from "url";
137384
137386
  // package.json
137385
137387
  var package_default = {
137386
137388
  name: "@automagik/omni",
137387
- version: "2.260915.14",
137389
+ version: "2.260915.16",
137388
137390
  repository: {
137389
137391
  type: "git",
137390
137392
  url: "git+https://github.com/automagik-dev/omni.git",
@@ -140262,6 +140264,19 @@ function buildStatusItems(instances) {
140262
140264
  profile: inst.profileName ?? "-"
140263
140265
  }));
140264
140266
  }
140267
+ var flag = (v4) => v4 === "unknown" ? "?" : v4 ? "yes" : "no";
140268
+ function capabilityRow(ch) {
140269
+ const emits = (prefix) => ch.emits === null ? "?" : ch.emits.some((t) => t.startsWith(prefix)) ? "yes" : "no";
140270
+ return {
140271
+ channel: ch.id,
140272
+ "message.received": emits("message.received"),
140273
+ "message.sent": emits("message.sent"),
140274
+ "reaction.*": emits("reaction."),
140275
+ edit: flag(ch.edits),
140276
+ delete: flag(ch.deletes),
140277
+ idempotency: flag(ch.idempotency)
140278
+ };
140279
+ }
140265
140280
  function createChannelsCommand() {
140266
140281
  const channels = new Command("channels").description("Channel management \u2014 list types, add instances, check status");
140267
140282
  channels.command("list").description("Show available channel types and instance counts").action(async () => {
@@ -140294,6 +140309,15 @@ function createChannelsCommand() {
140294
140309
  error(`Failed to list channels: ${message2}`);
140295
140310
  }
140296
140311
  });
140312
+ channels.command("capabilities").description("Event vocabulary and guarantees per loaded channel (declared by code, see #1187)").action(async () => {
140313
+ try {
140314
+ const { items } = await apiCall("channels/capabilities");
140315
+ list(items.map(capabilityRow), { emptyMessage: "No channels loaded.", rawData: items });
140316
+ } catch (err2) {
140317
+ const message2 = err2 instanceof Error ? err2.message : "Unknown error";
140318
+ error(`Failed to load channel capabilities: ${message2}`);
140319
+ }
140320
+ });
140297
140321
  channels.command("add <type>").description("Add a new channel instance (interactive setup)").option("--token <token>", "Bot token (for Telegram, Discord, Slack)").option("--name <name>", "Instance name (auto-generated if not provided)").action(async (type, options) => {
140298
140322
  const validTypes = ["telegram", "discord", "slack", "whatsapp-baileys", "whatsapp-business", "twilio-whatsapp"];
140299
140323
  if (!validTypes.includes(type)) {
@@ -144888,7 +144912,12 @@ async function followConsumer(params) {
144888
144912
  await flushStdout();
144889
144913
  return;
144890
144914
  }
144891
- if (page.cursor > acked) {
144915
+ if (page.leaseId) {
144916
+ await consumersApiRequest(`/${encodeURIComponent(params.consumer)}/ack`, {
144917
+ method: "POST",
144918
+ body: JSON.stringify({ leaseId: page.leaseId })
144919
+ });
144920
+ } else if (page.cursor > acked) {
144892
144921
  await consumersApiRequest(`/${encodeURIComponent(params.consumer)}/ack`, {
144893
144922
  method: "POST",
144894
144923
  body: JSON.stringify({ cursor: page.cursor })
@@ -144907,7 +144936,25 @@ async function followConsumer(params) {
144907
144936
  }
144908
144937
  function createConsumersCommand() {
144909
144938
  const consumers = new Command("consumers").description("Manage durable event consumers (named cursors over the event journal)");
144910
- consumers.command("create <name>").description("Register a durable consumer").requiredOption("--type <type>", "Event type filter (trailing * = prefix glob, e.g. custom.github.*)").option("--exclude <glob>", "Drop event types matching this glob, repeatable; wins over --type (e.g. --exclude custom.chat.*)", (value, previous) => [...previous, value], []).option("--filter <k=v>", "Payload condition, repeatable (dot paths + JSON values \u2014 same matcher as events wait)", (value, previous) => [...previous, value], []).option("--from-beginning", "Start the cursor at 0 (replay the full journal) instead of the current head").action(async (name, options) => {
144939
+ consumers.command("create <name>").description("Register a durable consumer").addHelpText("after", `
144940
+ Fan-out (default) vs shared (--shared):
144941
+ Each consumer NAME owns one cursor. Two names on the same type BOTH see
144942
+ every event \u2014 right for observers (monitor, archiver, metrics).
144943
+ By default, starting a second worker on the SAME name does not split the
144944
+ work: both pull the same pages, so events get handled twice. Don't scale
144945
+ workers that way.
144946
+
144947
+ To scale workers, pick one:
144948
+ --shared competing consumers: N processes following this one name
144949
+ split the stream. Each pull leases a page to one process;
144950
+ ack releases it; an unacked page is redelivered after the
144951
+ lease expires (at-least-once \u2014 make handlers idempotent on id).
144952
+ one consumer, parallelize inside your process: a single follower that
144953
+ fans each page out to a local worker pool, then acks.
144954
+
144955
+ Examples:
144956
+ omni events consumers create audit-log --type 'custom.*'
144957
+ omni events consumers create my-workers --type custom.x --shared`).requiredOption("--type <type>", "Event type filter (trailing * = prefix glob, e.g. custom.github.*)").option("--exclude <glob>", "Drop event types matching this glob, repeatable; wins over --type (e.g. --exclude custom.chat.*)", (value, previous) => [...previous, value], []).option("--filter <k=v>", "Payload condition, repeatable (dot paths + JSON values \u2014 same matcher as events wait)", (value, previous) => [...previous, value], []).option("--from-beginning", "Start the cursor at 0 (replay the full journal) instead of the current head").option("--shared", "Competing consumers: followers of this name split events instead of each seeing all").action(async (name, options) => {
144911
144958
  try {
144912
144959
  const filters = parseWaitFilters(WaitOptionsSchema.shape.filter.parse(options.filter));
144913
144960
  const result = await consumersApiRequest("", {
@@ -144917,13 +144964,15 @@ function createConsumersCommand() {
144917
144964
  eventType: options.type,
144918
144965
  excludeTypes: options.exclude.length ? options.exclude : undefined,
144919
144966
  filters: filters.length ? filters : undefined,
144920
- startFrom: options.fromBeginning ? "beginning" : undefined
144967
+ startFrom: options.fromBeginning ? "beginning" : undefined,
144968
+ shared: options.shared || undefined
144921
144969
  })
144922
144970
  });
144923
144971
  success(`Consumer registered: ${result.data.name} (cursor ${result.data.cursor})`, {
144924
144972
  name: result.data.name,
144925
144973
  eventType: result.data.eventType,
144926
144974
  cursor: result.data.cursor,
144975
+ shared: result.data.shared ?? false,
144927
144976
  lag: result.data.lag
144928
144977
  });
144929
144978
  } catch (err2) {
@@ -145618,9 +145667,9 @@ function computeDefaultDatabaseUrl() {
145618
145667
  return buildEmbeddedDatabaseUrl();
145619
145668
  }
145620
145669
  function resolveInstallDatabaseUrl(options) {
145621
- const flag = options.databaseUrlFlag?.trim();
145622
- if (flag && flag.length > 0)
145623
- return flag;
145670
+ const flag2 = options.databaseUrlFlag?.trim();
145671
+ if (flag2 && flag2.length > 0)
145672
+ return flag2;
145624
145673
  return computeDefaultDatabaseUrl();
145625
145674
  }
145626
145675
  async function isBunAvailable() {
@@ -148308,12 +148357,12 @@ function extensionForMime2(mimeType) {
148308
148357
  return ".flac";
148309
148358
  return ".mp3";
148310
148359
  }
148311
- function parsePositiveIntOption(value, flag) {
148360
+ function parsePositiveIntOption(value, flag2) {
148312
148361
  if (value === undefined)
148313
148362
  return;
148314
148363
  const parsed = Number.parseInt(value, 10);
148315
148364
  if (Number.isNaN(parsed))
148316
- throw new Error(`Invalid ${flag}: ${value}`);
148365
+ throw new Error(`Invalid ${flag2}: ${value}`);
148317
148366
  return parsed;
148318
148367
  }
148319
148368
  function assertMusicMode(mode) {
@@ -154007,8 +154056,8 @@ function sanitizeArgs(argv) {
154007
154056
  const arg = argv[i6];
154008
154057
  const eqIdx = arg.indexOf("=");
154009
154058
  if (eqIdx !== -1) {
154010
- const flag = arg.slice(0, eqIdx).toLowerCase();
154011
- if (SENSITIVE_FLAGS.has(flag)) {
154059
+ const flag2 = arg.slice(0, eqIdx).toLowerCase();
154060
+ if (SENSITIVE_FLAGS.has(flag2)) {
154012
154061
  result.push(`${arg.slice(0, eqIdx)}=[REDACTED]`);
154013
154062
  } else {
154014
154063
  result.push(arg);
@@ -166112,7 +166112,26 @@ var init_capabilities3 = __esm(() => {
166112
166112
  maxSize: 100 * 1024 * 1024
166113
166113
  },
166114
166114
  { mimeType: "text/plain", maxSize: 100 * 1024 * 1024 }
166115
- ]
166115
+ ],
166116
+ events: {
166117
+ emits: [
166118
+ "channel.alert",
166119
+ "flow.data_exchange",
166120
+ "instance.connected",
166121
+ "instance.disconnected",
166122
+ "message.delivered",
166123
+ "message.failed",
166124
+ "message.read",
166125
+ "message.received",
166126
+ "message.sent",
166127
+ "reaction.received",
166128
+ "reaction.removed",
166129
+ "template.status_changed"
166130
+ ],
166131
+ edits: false,
166132
+ deletes: false,
166133
+ idempotency: true
166134
+ }
166116
166135
  };
166117
166136
  });
166118
166137
 
@@ -173827,6 +173846,8 @@ var init_schema2 = __esm(() => {
173827
173846
  excludeTypes: jsonb("exclude_types").$type(),
173828
173847
  filters: jsonb("filters").$type(),
173829
173848
  cursor: bigint2("cursor", { mode: "number" }).notNull().default(0),
173849
+ shared: boolean2("shared").notNull().default(false),
173850
+ leaseState: jsonb("lease_state").$type(),
173830
173851
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
173831
173852
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
173832
173853
  }, (table3) => ({
@@ -181067,7 +181088,13 @@ var init_plugin2 = __esm(() => {
181067
181088
  init_stream_store();
181068
181089
  A2A_CAPABILITIES = {
181069
181090
  ...DEFAULT_CAPABILITIES,
181070
- canSendText: true
181091
+ canSendText: true,
181092
+ events: {
181093
+ emits: ["instance.connected", "instance.disconnected", "message.received"],
181094
+ edits: false,
181095
+ deletes: false,
181096
+ idempotency: false
181097
+ }
181071
181098
  };
181072
181099
  A2AChannelPlugin = class A2AChannelPlugin extends BaseChannelPlugin {
181073
181100
  id = "a2a";
@@ -251050,7 +251077,7 @@ var init_sentry_scrub = __esm(() => {
251050
251077
  var require_package7 = __commonJS((exports, module) => {
251051
251078
  module.exports = {
251052
251079
  name: "@omni/api",
251053
- version: "2.260915.14",
251080
+ version: "2.260915.16",
251054
251081
  private: true,
251055
251082
  type: "module",
251056
251083
  exports: {
@@ -312878,6 +312905,7 @@ var init_scopes = __esm(() => {
312878
312905
  "GET /handoffs/:id": "handoffs:read",
312879
312906
  "GET /instances": "instances:read",
312880
312907
  "GET /instances/supported-channels": "instances:read",
312908
+ "GET /channels/capabilities": "instances:read",
312881
312909
  "GET /instances/:id": "instances:read",
312882
312910
  "POST /instances": "instances:write",
312883
312911
  "PATCH /instances/:id": "instances:write",
@@ -313697,6 +313725,7 @@ var init_route_ownership = __esm(() => {
313697
313725
  "GET /api/v2/batch-jobs",
313698
313726
  "GET /api/v2/batch-jobs/:id",
313699
313727
  "GET /api/v2/batch-jobs/:id/status",
313728
+ "GET /api/v2/channels/capabilities",
313700
313729
  "GET /api/v2/channels/harness/:instanceId/transcript",
313701
313730
  "GET /api/v2/chats",
313702
313731
  "GET /api/v2/chats/:id",
@@ -370407,6 +370436,24 @@ var init_events2 = __esm(() => {
370407
370436
  });
370408
370437
 
370409
370438
  // ../api/src/services/event-consumers.ts
370439
+ import { randomUUID as randomUUID4 } from "crypto";
370440
+ function planSharedPull(state, now) {
370441
+ const expired = state.leases.find((lease) => lease.expiresAt <= now);
370442
+ return expired ? { reclaim: expired } : { after: state.claimed };
370443
+ }
370444
+ function claimLease(state, lease, replaces) {
370445
+ return {
370446
+ claimed: Math.max(state.claimed, lease.to),
370447
+ leases: [...state.leases.filter((l) => l.id !== replaces), lease]
370448
+ };
370449
+ }
370450
+ function releaseLease(state, leaseId) {
370451
+ if (!state.leases.some((l) => l.id === leaseId))
370452
+ return null;
370453
+ const leases = state.leases.filter((l) => l.id !== leaseId);
370454
+ const cursor = leases.length ? Math.min(...leases.map((l) => l.from)) : state.claimed;
370455
+ return { state: { claimed: state.claimed, leases }, cursor };
370456
+ }
370410
370457
  function matchesConsumerPayload(row, filters) {
370411
370458
  if (!filters || filters.length === 0)
370412
370459
  return true;
@@ -370462,7 +370509,9 @@ class EventConsumerService {
370462
370509
  eventType: input.eventType,
370463
370510
  excludeTypes: input.excludeTypes?.length ? input.excludeTypes : null,
370464
370511
  filters: input.filters ?? null,
370465
- cursor
370512
+ cursor,
370513
+ shared: input.shared ?? false,
370514
+ leaseState: input.shared ? { claimed: cursor, leases: [] } : null
370466
370515
  }).onConflictDoNothing({ target: durableConsumers.name }).returning();
370467
370516
  if (!created) {
370468
370517
  throw new ConflictError("DurableConsumer", `a consumer named '${input.name}' already exists`, {
@@ -370474,7 +370523,8 @@ class EventConsumerService {
370474
370523
  consumerId: created.id,
370475
370524
  name: created.name,
370476
370525
  eventType: created.eventType,
370477
- cursor: created.cursor
370526
+ cursor: created.cursor,
370527
+ shared: created.shared
370478
370528
  });
370479
370529
  }
370480
370530
  return this.withLag(created, head);
@@ -370496,6 +370546,8 @@ class EventConsumerService {
370496
370546
  const limit2 = Math.min(Math.max(options.limit ?? 100, 1), PULL_MAX_LIMIT);
370497
370547
  const waitMs = Math.min(Math.max(options.waitMs ?? 0, 0), PULL_MAX_WAIT_MS);
370498
370548
  const consumer = await this.getByName(name);
370549
+ if (consumer.shared)
370550
+ return this.pullShared(consumer, limit2, waitMs, options.leaseMs ?? DEFAULT_LEASE_MS);
370499
370551
  const deadline = Date.now() + waitMs;
370500
370552
  let scanned = await this.scanPage(consumer, limit2);
370501
370553
  while (scanned.length === 0 && Date.now() < deadline) {
@@ -370519,20 +370571,93 @@ class EventConsumerService {
370519
370571
  scanExhausted: hasMore && items.length === 0
370520
370572
  };
370521
370573
  }
370522
- async ack(name, cursor) {
370523
- const [updated] = await this.db.update(durableConsumers).set({ cursor, updatedAt: new Date }).where(and2(eq(durableConsumers.name, name), lte(durableConsumers.cursor, cursor))).returning();
370574
+ async ack(name, cursor, leaseId) {
370575
+ if (leaseId)
370576
+ return this.ackShared(name, leaseId);
370577
+ const [updated] = await this.db.update(durableConsumers).set({ cursor, updatedAt: new Date }).where(and2(eq(durableConsumers.name, name), eq(durableConsumers.shared, false), lte(durableConsumers.cursor, cursor))).returning();
370524
370578
  if (!updated) {
370525
370579
  const existing = await this.getByName(name);
370580
+ if (existing.shared) {
370581
+ throw new ValidationError(`consumer '${name}' is shared \u2014 ack with the pull result's leaseId`, undefined, {
370582
+ name
370583
+ });
370584
+ }
370526
370585
  throw new ValidationError(`ack cursor ${cursor} is behind the stored cursor ${existing.cursor} \u2014 acks are monotonic`, undefined, { name, cursor, storedCursor: existing.cursor });
370527
370586
  }
370528
370587
  return this.withLag(updated, await this.head());
370529
370588
  }
370530
- async scanPage(consumer, limit2) {
370589
+ async pullShared(initial, limit2, waitMs, leaseMs) {
370590
+ const deadline = Date.now() + waitMs;
370591
+ let claim = await this.claimShared(initial, limit2, leaseMs);
370592
+ while (!claim.lease && Date.now() < deadline) {
370593
+ await new Promise((resolve4) => setTimeout(resolve4, PULL_POLL_INTERVAL_MS));
370594
+ claim = await this.claimShared(await this.getByName(initial.name), limit2, leaseMs);
370595
+ }
370596
+ const { consumer, lease, scanned } = claim;
370597
+ const items = scanned.filter((row) => matchesConsumerPayload(row, consumer.filters));
370598
+ if (lease && items.length === 0) {
370599
+ await this.ackShared(consumer.name, lease.id).catch(() => {
370600
+ return;
370601
+ });
370602
+ }
370603
+ const hasMore = scanned.length === limit2;
370604
+ return {
370605
+ consumer: consumer.name,
370606
+ items,
370607
+ cursor: lease?.to ?? consumer.cursor,
370608
+ head: await this.head(),
370609
+ hasMore,
370610
+ scanExhausted: hasMore && items.length === 0,
370611
+ ...lease && items.length > 0 ? { leaseId: lease.id } : {}
370612
+ };
370613
+ }
370614
+ async claimShared(start, limit2, leaseMs) {
370615
+ let consumer = start;
370616
+ for (let attempt = 0;attempt < SHARED_CAS_ATTEMPTS; attempt++) {
370617
+ const state = consumer.leaseState ?? { claimed: consumer.cursor, leases: [] };
370618
+ const now = Date.now();
370619
+ const plan = planSharedPull(state, now);
370620
+ const scanned = plan.reclaim ? await this.scanPage(consumer, PULL_MAX_LIMIT, plan.reclaim.from, plan.reclaim.to) : await this.scanPage(consumer, limit2, plan.after);
370621
+ const last = scanned[scanned.length - 1];
370622
+ if (!plan.reclaim && !last)
370623
+ return { consumer, lease: null, scanned };
370624
+ const lease = plan.reclaim ? { ...plan.reclaim, id: randomUUID4(), expiresAt: now + leaseMs } : { id: randomUUID4(), from: plan.after, to: Number(last?.journalSeq), expiresAt: now + leaseMs };
370625
+ if (await this.casLeaseState(consumer, claimLease(state, lease, plan.reclaim?.id))) {
370626
+ return { consumer, lease, scanned };
370627
+ }
370628
+ consumer = await this.getByName(consumer.name);
370629
+ }
370630
+ throw new ConflictError("DurableConsumer", `too much contention leasing '${start.name}', retry`, {
370631
+ name: start.name
370632
+ });
370633
+ }
370634
+ async ackShared(name, leaseId) {
370635
+ for (let attempt = 0;attempt < SHARED_CAS_ATTEMPTS; attempt++) {
370636
+ const consumer = await this.getByName(name);
370637
+ if (!consumer.shared) {
370638
+ throw new ValidationError(`consumer '${name}' is not shared \u2014 ack with a cursor`, undefined, { name });
370639
+ }
370640
+ const released = releaseLease(consumer.leaseState ?? { claimed: consumer.cursor, leases: [] }, leaseId);
370641
+ if (!released) {
370642
+ throw new ValidationError(`lease ${leaseId} is unknown or expired \u2014 its page was (or will be) redelivered`, undefined, { name, leaseId });
370643
+ }
370644
+ const updated = await this.casLeaseState(consumer, released.state, Math.max(consumer.cursor, released.cursor));
370645
+ if (updated)
370646
+ return this.withLag(updated, await this.head());
370647
+ }
370648
+ throw new ConflictError("DurableConsumer", `too much contention acking '${name}', retry`, { name });
370649
+ }
370650
+ async casLeaseState(consumer, next, cursor) {
370651
+ const unchanged = consumer.leaseState ? sql`${durableConsumers.leaseState} = ${JSON.stringify(consumer.leaseState)}::jsonb` : isNull2(durableConsumers.leaseState);
370652
+ const [updated] = await this.db.update(durableConsumers).set({ leaseState: next, ...cursor === undefined ? {} : { cursor }, updatedAt: new Date }).where(and2(eq(durableConsumers.id, consumer.id), unchanged)).returning();
370653
+ return updated ?? null;
370654
+ }
370655
+ async scanPage(consumer, limit2, after = consumer.cursor, through) {
370531
370656
  const typeClause = eventTypeFilterClause([consumer.eventType], consumer.excludeTypes ?? undefined);
370532
- return this.db.select().from(omniEvents).where(and2(gt(omniEvents.journalSeq, consumer.cursor), typeClause)).orderBy(asc(omniEvents.journalSeq)).limit(limit2);
370657
+ return this.db.select().from(omniEvents).where(and2(gt(omniEvents.journalSeq, after), through === undefined ? undefined : lte(omniEvents.journalSeq, through), typeClause)).orderBy(asc(omniEvents.journalSeq)).limit(limit2);
370533
370658
  }
370534
370659
  }
370535
- var PULL_POLL_INTERVAL_MS = 500, PULL_MAX_LIMIT = 500, PULL_MAX_WAIT_MS = 30000;
370660
+ var PULL_POLL_INTERVAL_MS = 500, PULL_MAX_LIMIT = 500, PULL_MAX_WAIT_MS = 30000, DEFAULT_LEASE_MS = 60000, SHARED_CAS_ATTEMPTS = 20;
370536
370661
  var init_event_consumers = __esm(() => {
370537
370662
  init_src();
370538
370663
  init_src5();
@@ -379436,6 +379561,39 @@ var init_channel_harness = __esm(() => {
379436
379561
  });
379437
379562
  });
379438
379563
 
379564
+ // ../api/src/schemas/openapi/channels.ts
379565
+ function registerChannelSchemas(registry4) {
379566
+ registry4.register("ChannelCapabilities", ChannelCapabilitiesSchema);
379567
+ registry4.registerPath({
379568
+ method: "get",
379569
+ path: "/channels/capabilities",
379570
+ operationId: "listChannelCapabilities",
379571
+ tags: ["Instances"],
379572
+ summary: "Channel capability matrix",
379573
+ description: "Event types and guarantees (edits, deletes, idempotency) each loaded channel plugin declares. Declarations are verified against the channel code by a static test.",
379574
+ responses: {
379575
+ 200: {
379576
+ description: "Capability matrix",
379577
+ content: { "application/json": { schema: ChannelCapabilitiesMatrixSchema } }
379578
+ }
379579
+ }
379580
+ });
379581
+ }
379582
+ var CapabilityFlagSchema, ChannelCapabilitiesSchema, ChannelCapabilitiesMatrixSchema;
379583
+ var init_channels = __esm(() => {
379584
+ init_zod_openapi();
379585
+ CapabilityFlagSchema = exports_external.union([exports_external.boolean(), exports_external.literal("unknown")]).openapi({ description: "true/false as established from the channel's code; 'unknown' when undeclared" });
379586
+ ChannelCapabilitiesSchema = exports_external.object({
379587
+ id: exports_external.string().openapi({ description: "Channel type (e.g. whatsapp-baileys)" }),
379588
+ name: exports_external.string().openapi({ description: "Human-readable channel name" }),
379589
+ emits: exports_external.array(exports_external.string()).nullable().openapi({ description: "Core event types the channel publishes; null when the plugin declares none" }),
379590
+ edits: CapabilityFlagSchema,
379591
+ deletes: CapabilityFlagSchema,
379592
+ idempotency: CapabilityFlagSchema
379593
+ });
379594
+ ChannelCapabilitiesMatrixSchema = exports_external.object({ items: exports_external.array(ChannelCapabilitiesSchema) });
379595
+ });
379596
+
379439
379597
  // ../api/src/schemas/openapi/conversations.ts
379440
379598
  function registerConversationSchemas(registry4) {
379441
379599
  registry4.register("Conversation", ConversationSchema2);
@@ -379843,6 +380001,9 @@ var init_event_consumers2 = __esm(() => {
379843
380001
  excludeTypes: exports_external.array(exports_external.string()).nullable().openapi({ description: "Type globs dropped from the stream (exclusion wins over eventType), or null" }),
379844
380002
  filters: exports_external.array(ConsumerConditionSchema).nullable().openapi({ description: "Payload conditions (AND), or null" }),
379845
380003
  cursor: exports_external.number().int().openapi({ description: "Last acked journal_seq; delivery resumes strictly after it" }),
380004
+ shared: exports_external.boolean().openapi({
380005
+ description: "true = competing consumers (pullers on this name split the stream); false = own cursor (fan-out)"
380006
+ }),
379846
380007
  head: exports_external.number().int().openapi({ description: "Highest journal_seq currently in the journal" }),
379847
380008
  lag: exports_external.number().int().openapi({ description: "head - cursor (all journal rows past the cursor, not only matches)" }),
379848
380009
  caughtUp: exports_external.boolean().openapi({ description: "No type-matching journal row past the cursor (lag may still count other types)" }),
@@ -379854,16 +380015,25 @@ var init_event_consumers2 = __esm(() => {
379854
380015
  eventType: exports_external.string().min(1).max(255).openapi({ description: "Type filter: exact event type, or trailing-* prefix glob (e.g. custom.github.*)" }),
379855
380016
  excludeTypes: exports_external.array(exports_external.string().min(1).max(255)).max(20).optional().openapi({ description: "Type globs to drop (same syntax as eventType); exclusion wins over inclusion" }),
379856
380017
  filters: exports_external.array(ConsumerConditionSchema).max(20).optional().openapi({ description: "Payload conditions (AND) \u2014 same matcher as events wait --filter" }),
379857
- startFrom: exports_external.enum(["now", "beginning"]).optional().openapi({ description: "Initial cursor: 'now' = journal head (default), 'beginning' = full replay" })
380018
+ startFrom: exports_external.enum(["now", "beginning"]).optional().openapi({ description: "Initial cursor: 'now' = journal head (default), 'beginning' = full replay" }),
380019
+ shared: exports_external.boolean().optional().openapi({
380020
+ description: "Competing consumers (#1188). false (default) = fan-out: every consumer name has its own cursor and sees every " + "event. true = N pullers on THIS name split the stream: each pull leases a page to one puller, ack(leaseId) " + "releases it, an unacked lease is redelivered after leaseMs (at-least-once)."
380021
+ })
379858
380022
  });
379859
380023
  PullConsumerQuerySchema = exports_external.object({
379860
380024
  limit: exports_external.coerce.number().int().min(1).max(500).optional().openapi({ description: "Max journal rows to scan (default 100)" }),
379861
- waitMs: exports_external.coerce.number().int().min(0).max(30000).optional().openapi({ description: "Long-poll: wait up to this long when no rows are available (default 0)" })
380025
+ waitMs: exports_external.coerce.number().int().min(0).max(30000).optional().openapi({ description: "Long-poll: wait up to this long when no rows are available (default 0)" }),
380026
+ leaseMs: exports_external.coerce.number().int().min(1000).max(3600000).optional().openapi({ description: "Shared consumers: lease duration before the page is redelivered (default 60000)" })
379862
380027
  });
379863
380028
  AckConsumerSchema = exports_external.object({
379864
- cursor: exports_external.coerce.number().int().min(0).openapi({
380029
+ cursor: exports_external.coerce.number().int().min(0).optional().openapi({
379865
380030
  description: `The journal_seq to advance to (a pull result's "cursor"). Monotonic: equal = no-op, lower = 400`
380031
+ }),
380032
+ leaseId: exports_external.string().uuid().optional().openapi({
380033
+ description: "Shared consumers: the pull result's leaseId (required instead of cursor)"
379866
380034
  })
380035
+ }).refine((body) => body.cursor !== undefined || body.leaseId !== undefined, {
380036
+ message: "cursor or leaseId is required"
379867
380037
  });
379868
380038
  PullResultSchema = exports_external.object({
379869
380039
  consumer: exports_external.string().openapi({ description: "Consumer name" }),
@@ -379875,6 +380045,9 @@ var init_event_consumers2 = __esm(() => {
379875
380045
  hasMore: exports_external.boolean().openapi({ description: "True when the scan filled the page \u2014 more rows are already waiting" }),
379876
380046
  scanExhausted: exports_external.boolean().openapi({
379877
380047
  description: "A full scan window matched nothing; the stored cursor was advanced past it (#1128)"
380048
+ }),
380049
+ leaseId: exports_external.string().optional().openapi({
380050
+ description: "Shared consumers only: ack this lease once the items are handled (absent when nothing delivered)"
379878
380051
  })
379879
380052
  });
379880
380053
  });
@@ -383749,6 +383922,7 @@ var init_openapi2 = __esm(() => {
383749
383922
  init_auth2();
383750
383923
  init_automations3();
383751
383924
  init_channel_harness();
383925
+ init_channels();
383752
383926
  init_common4();
383753
383927
  init_conversations2();
383754
383928
  init_dead_letters2();
@@ -383790,6 +383964,7 @@ var init_openapi2 = __esm(() => {
383790
383964
  registerLogSchemas(registry4);
383791
383965
  registerDeadLetterSchemas(registry4);
383792
383966
  registerEventOpsSchemas(registry4);
383967
+ registerChannelSchemas(registry4);
383793
383968
  registerEventSchemaSchemas(registry4);
383794
383969
  registerEventConsumerSchemas(registry4);
383795
383970
  registerMetricsSchemas(registry4);
@@ -385493,6 +385668,25 @@ var init_channel_harness2 = __esm(() => {
385493
385668
  });
385494
385669
  });
385495
385670
 
385671
+ // ../api/src/routes/v2/channels.ts
385672
+ var channelsRoutes;
385673
+ var init_channels2 = __esm(() => {
385674
+ init_dist2();
385675
+ channelsRoutes = new Hono2;
385676
+ channelsRoutes.get("/capabilities", (c) => {
385677
+ const plugins = c.get("channelRegistry")?.getAll() ?? [];
385678
+ const items = plugins.map((plugin13) => ({
385679
+ id: plugin13.id,
385680
+ name: plugin13.name,
385681
+ emits: plugin13.capabilities.events ? [...plugin13.capabilities.events.emits] : null,
385682
+ edits: plugin13.capabilities.events?.edits ?? "unknown",
385683
+ deletes: plugin13.capabilities.events?.deletes ?? "unknown",
385684
+ idempotency: plugin13.capabilities.events?.idempotency ?? "unknown"
385685
+ }));
385686
+ return c.json({ items });
385687
+ });
385688
+ });
385689
+
385496
385690
  // ../api/src/plugins/session-cleaner.ts
385497
385691
  function trustedTenantOf(event) {
385498
385692
  const classification = classifyEnvelope(event.metadata);
@@ -386708,16 +386902,16 @@ var init_event_consumers3 = __esm(() => {
386708
386902
  });
386709
386903
  eventConsumersRoutes.post("/events/consumers/:name/pull", zValidator("query", PullConsumerQuerySchema), async (c) => {
386710
386904
  const name = c.req.param("name");
386711
- const { limit: limit2, waitMs } = c.req.valid("query");
386905
+ const { limit: limit2, waitMs, leaseMs } = c.req.valid("query");
386712
386906
  const services = c.get("services");
386713
- const result = await services.eventConsumers.pull(name, { limit: limit2, waitMs });
386907
+ const result = await services.eventConsumers.pull(name, { limit: limit2, waitMs, leaseMs });
386714
386908
  return c.json(result);
386715
386909
  });
386716
386910
  eventConsumersRoutes.post("/events/consumers/:name/ack", zValidator("json", AckConsumerSchema), async (c) => {
386717
386911
  const name = c.req.param("name");
386718
- const { cursor } = c.req.valid("json");
386912
+ const { cursor, leaseId } = c.req.valid("json");
386719
386913
  const services = c.get("services");
386720
- const data = await services.eventConsumers.ack(name, cursor);
386914
+ const data = await services.eventConsumers.ack(name, cursor ?? 0, leaseId);
386721
386915
  return c.json({ data });
386722
386916
  });
386723
386917
  });
@@ -396376,7 +396570,7 @@ var init_webhooks3 = __esm(() => {
396376
396570
  });
396377
396571
 
396378
396572
  // ../api/src/lib/oauth-token-cache.ts
396379
- import { randomUUID as randomUUID4 } from "crypto";
396573
+ import { randomUUID as randomUUID5 } from "crypto";
396380
396574
  function put(accessToken, ttlMs = DEFAULT_TTL_MS4) {
396381
396575
  if (!accessToken)
396382
396576
  throw new Error("oauth-token-cache: accessToken is required");
@@ -396385,7 +396579,7 @@ function put(accessToken, ttlMs = DEFAULT_TTL_MS4) {
396385
396579
  if (oldest)
396386
396580
  store.delete(oldest);
396387
396581
  }
396388
- const handle = `eshandle_${randomUUID4()}`;
396582
+ const handle = `eshandle_${randomUUID5()}`;
396389
396583
  store.set(handle, { accessToken, expiresAt: Date.now() + ttlMs });
396390
396584
  return handle;
396391
396585
  }
@@ -397154,6 +397348,7 @@ var init_v2 = __esm(() => {
397154
397348
  init_automations4();
397155
397349
  init_batch_jobs2();
397156
397350
  init_channel_harness2();
397351
+ init_channels2();
397157
397352
  init_chats2();
397158
397353
  init_context5();
397159
397354
  init_conversations3();
@@ -397211,6 +397406,7 @@ var init_v2 = __esm(() => {
397211
397406
  v2Routes.route("/metrics", metricsRoutes);
397212
397407
  v2Routes.route("/conversations", conversationsRoutes);
397213
397408
  v2Routes.route("/chats", chatsRoutes);
397409
+ v2Routes.route("/channels", channelsRoutes);
397214
397410
  v2Routes.route("/channels/harness", harnessRoutes);
397215
397411
  v2Routes.route("/media", mediaRoutes);
397216
397412
  v2Routes.route("/batch-jobs", batchJobsRoutes);
@@ -402313,7 +402509,23 @@ var ASC_CAPABILITIES = {
402313
402509
  maxSize: 100 * 1024 * 1024
402314
402510
  },
402315
402511
  { mimeType: "text/plain", maxSize: 100 * 1024 * 1024 }
402316
- ]
402512
+ ],
402513
+ events: {
402514
+ emits: [
402515
+ "instance.connected",
402516
+ "instance.disconnected",
402517
+ "message.delivered",
402518
+ "message.failed",
402519
+ "message.read",
402520
+ "message.received",
402521
+ "message.sent",
402522
+ "reaction.received",
402523
+ "reaction.removed"
402524
+ ],
402525
+ edits: false,
402526
+ deletes: false,
402527
+ idempotency: true
402528
+ }
402317
402529
  };
402318
402530
 
402319
402531
  // ../channel-asc/src/utils/errors.ts
@@ -403239,7 +403451,13 @@ var ASC_FLOW_CAPABILITIES = {
403239
403451
  { mimeType: "audio/*", maxSize: 16 * 1024 * 1024 },
403240
403452
  { mimeType: "video/*", maxSize: 16 * 1024 * 1024 },
403241
403453
  { mimeType: "application/*", maxSize: 16 * 1024 * 1024 }
403242
- ]
403454
+ ],
403455
+ events: {
403456
+ emits: ["instance.connected", "instance.disconnected", "message.failed", "message.received", "message.sent"],
403457
+ edits: false,
403458
+ deletes: false,
403459
+ idempotency: true
403460
+ }
403243
403461
  };
403244
403462
 
403245
403463
  // ../channel-asc-flow/src/utils/errors.ts
@@ -404745,7 +404963,23 @@ var DISCORD_CAPABILITIES = {
404745
404963
  maxEmbedFields: 25,
404746
404964
  maxButtonsPerRow: 5,
404747
404965
  maxRowsPerMessage: 5,
404748
- maxSelectOptions: 25
404966
+ maxSelectOptions: 25,
404967
+ events: {
404968
+ emits: [
404969
+ "instance.connected",
404970
+ "instance.disconnected",
404971
+ "message.failed",
404972
+ "message.received",
404973
+ "message.sent",
404974
+ "reaction.received",
404975
+ "reaction.removed",
404976
+ "voice.user_joined_channel",
404977
+ "voice.user_left_channel"
404978
+ ],
404979
+ edits: true,
404980
+ deletes: true,
404981
+ idempotency: true
404982
+ }
404749
404983
  };
404750
404984
 
404751
404985
  // ../channel-discord/src/client.ts
@@ -408150,7 +408384,21 @@ var GUPSHUP_CAPABILITIES = {
408150
408384
  { mimeType: "video/*", maxSize: 100 * 1024 * 1024 },
408151
408385
  { mimeType: "application/*", maxSize: 100 * 1024 * 1024 },
408152
408386
  { mimeType: "image/webp", maxSize: 100 * 1024 * 1024 }
408153
- ]
408387
+ ],
408388
+ events: {
408389
+ emits: [
408390
+ "instance.connected",
408391
+ "instance.disconnected",
408392
+ "message.delivered",
408393
+ "message.failed",
408394
+ "message.read",
408395
+ "message.received",
408396
+ "message.sent"
408397
+ ],
408398
+ edits: false,
408399
+ deletes: false,
408400
+ idempotency: true
408401
+ }
408154
408402
  };
408155
408403
 
408156
408404
  // ../channel-gupshup/src/utils/errors.ts
@@ -409239,7 +409487,13 @@ var HARNESS_CAPABILITIES = {
409239
409487
  canSendButtons: true,
409240
409488
  canSendSelectMenu: true,
409241
409489
  canReplyToMessage: true,
409242
- supportedMediaTypes: [{ mimeType: "*/*" }]
409490
+ supportedMediaTypes: [{ mimeType: "*/*" }],
409491
+ events: {
409492
+ emits: ["message.failed", "message.received", "message.sent"],
409493
+ edits: false,
409494
+ deletes: false,
409495
+ idempotency: true
409496
+ }
409243
409497
  };
409244
409498
  var MEDIA_CONTENT_TYPES = new Set(["image", "audio", "video", "document", "sticker"]);
409245
409499
 
@@ -409545,7 +409799,23 @@ var HERMES_CAPABILITIES = {
409545
409799
  maxSize: 100 * 1024 * 1024
409546
409800
  },
409547
409801
  { mimeType: "text/plain", maxSize: 100 * 1024 * 1024 }
409548
- ]
409802
+ ],
409803
+ events: {
409804
+ emits: [
409805
+ "instance.connected",
409806
+ "instance.disconnected",
409807
+ "message.delivered",
409808
+ "message.failed",
409809
+ "message.read",
409810
+ "message.received",
409811
+ "message.sent",
409812
+ "reaction.received",
409813
+ "reaction.removed"
409814
+ ],
409815
+ edits: false,
409816
+ deletes: false,
409817
+ idempotency: true
409818
+ }
409549
409819
  };
409550
409820
 
409551
409821
  // ../channel-hermes/src/utils/errors.ts
@@ -410556,7 +410826,24 @@ var SLACK_CAPABILITIES = {
410556
410826
  maxFileSize: 1024 * 1024 * 1024,
410557
410827
  maxButtonsPerRow: 5,
410558
410828
  maxRowsPerMessage: 50,
410559
- maxSelectOptions: 100
410829
+ maxSelectOptions: 100,
410830
+ events: {
410831
+ emits: [
410832
+ "agent.run.cancel_requested",
410833
+ "instance.connected",
410834
+ "instance.disconnected",
410835
+ "message.failed",
410836
+ "message.pinned",
410837
+ "message.received",
410838
+ "message.sent",
410839
+ "message.unpinned",
410840
+ "reaction.received",
410841
+ "reaction.removed"
410842
+ ],
410843
+ edits: false,
410844
+ deletes: false,
410845
+ idempotency: true
410846
+ }
410560
410847
  };
410561
410848
 
410562
410849
  // ../channel-slack/src/config/stream-mode.ts
@@ -413401,7 +413688,24 @@ var TELEGRAM_CAPABILITIES = {
413401
413688
  { mimeType: "video/*", maxSize: 50 * 1024 * 1024 },
413402
413689
  { mimeType: "application/*", maxSize: 50 * 1024 * 1024 }
413403
413690
  ],
413404
- maxFileSize: 50 * 1024 * 1024
413691
+ maxFileSize: 50 * 1024 * 1024,
413692
+ events: {
413693
+ emits: [
413694
+ "instance.connected",
413695
+ "instance.disconnected",
413696
+ "message.button_click",
413697
+ "message.failed",
413698
+ "message.poll",
413699
+ "message.poll_vote",
413700
+ "message.received",
413701
+ "message.sent",
413702
+ "reaction.received",
413703
+ "reaction.removed"
413704
+ ],
413705
+ edits: false,
413706
+ deletes: false,
413707
+ idempotency: true
413708
+ }
413405
413709
  };
413406
413710
 
413407
413711
  // ../channel-telegram/src/client.ts
@@ -527765,7 +528069,28 @@ var WHATSAPP_CAPABILITIES = {
527765
528069
  { mimeType: "video/*", maxSize: 64 * 1024 * 1024 },
527766
528070
  { mimeType: "application/*", maxSize: 100 * 1024 * 1024 }
527767
528071
  ],
527768
- maxFileSize: 100 * 1024 * 1024
528072
+ maxFileSize: 100 * 1024 * 1024,
528073
+ events: {
528074
+ emits: [
528075
+ "instance.connected",
528076
+ "instance.disconnected",
528077
+ "instance.qr_code",
528078
+ "media.received",
528079
+ "message.delivered",
528080
+ "message.failed",
528081
+ "message.read",
528082
+ "message.received",
528083
+ "message.sent",
528084
+ "presence.offline",
528085
+ "presence.online",
528086
+ "presence.typing",
528087
+ "reaction.received",
528088
+ "reaction.removed"
528089
+ ],
528090
+ edits: true,
528091
+ deletes: true,
528092
+ idempotency: true
528093
+ }
527769
528094
  };
527770
528095
 
527771
528096
  // ../channel-whatsapp/src/env.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/omni",
3
- "version": "2.260915.14",
3
+ "version": "2.260915.16",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/automagik-dev/omni.git",