@automagik/omni 2.260911.2 → 2.260911.3

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.
@@ -38426,7 +38426,7 @@ var init_debounce = __esm(() => {
38426
38426
  class AutomationEngine {
38427
38427
  config;
38428
38428
  subscriptions = new Map;
38429
- instanceQueues = new Map;
38429
+ queues = new Map;
38430
38430
  debounceManagers = new Map;
38431
38431
  automations = [];
38432
38432
  eventBus = null;
@@ -38751,29 +38751,38 @@ class AutomationEngine {
38751
38751
  const manager = new DebounceManager(automation.debounce, callback);
38752
38752
  this.debounceManagers.set(automation.id, manager);
38753
38753
  }
38754
+ resolveQueueKey(automation, context2, instanceId) {
38755
+ if (automation.maxConcurrency == null && automation.concurrencyKey == null)
38756
+ return instanceId;
38757
+ const base = `${instanceId}:${automation.id}`;
38758
+ if (!automation.concurrencyKey)
38759
+ return base;
38760
+ const partition = substituteTemplate(automation.concurrencyKey, context2).trim();
38761
+ return partition ? `${base}:${partition}` : base;
38762
+ }
38754
38763
  async queueExecution(automation, event, context2, instanceId) {
38755
- let queue = this.instanceQueues.get(instanceId);
38756
- if (!queue) {
38757
- const maxConcurrency = this.config.instanceConcurrencyOverrides?.[instanceId] ?? this.config.defaultConcurrency;
38758
- queue = {
38759
- instanceId,
38760
- activeCount: 0,
38761
- maxConcurrency,
38762
- pending: []
38763
- };
38764
- this.instanceQueues.set(instanceId, queue);
38765
- }
38764
+ const key = this.resolveQueueKey(automation, context2, instanceId);
38765
+ const maxConcurrency = automation.maxConcurrency ?? this.config.instanceConcurrencyOverrides?.[instanceId] ?? this.config.defaultConcurrency;
38766
+ const queue = this.queues.get(key) ?? {
38767
+ key,
38768
+ evictWhenIdle: key !== instanceId,
38769
+ activeCount: 0,
38770
+ maxConcurrency,
38771
+ pending: []
38772
+ };
38773
+ queue.maxConcurrency = maxConcurrency;
38774
+ this.queues.set(key, queue);
38766
38775
  if (queue.activeCount < queue.maxConcurrency) {
38767
38776
  return this.executeAutomation(automation, event, context2, queue);
38768
38777
  }
38769
38778
  const maxQueueDepth = this.config.maxQueueDepth ?? 100;
38770
38779
  if (queue.pending.length >= maxQueueDepth) {
38771
38780
  logger4.warn("Queue full, applying backpressure", {
38772
- instanceId,
38781
+ queueKey: key,
38773
38782
  queueDepth: queue.pending.length,
38774
38783
  maxDepth: maxQueueDepth
38775
38784
  });
38776
- throw new QueueFullError(instanceId, queue.pending.length, maxQueueDepth);
38785
+ throw new QueueFullError(key, queue.pending.length, maxQueueDepth);
38777
38786
  }
38778
38787
  const queueRef = queue;
38779
38788
  return new Promise((resolve) => {
@@ -38785,7 +38794,7 @@ class AutomationEngine {
38785
38794
  });
38786
38795
  logger4.debug("Execution queued", {
38787
38796
  automationId: automation.id,
38788
- instanceId,
38797
+ queueKey: key,
38789
38798
  queueLength: queueRef.pending.length
38790
38799
  });
38791
38800
  });
@@ -38892,6 +38901,10 @@ class AutomationEngine {
38892
38901
  next.resolve(result);
38893
38902
  }
38894
38903
  }
38904
+ if (queue.evictWhenIdle && queue.activeCount === 0 && queue.pending.length === 0) {
38905
+ if (this.queues.get(queue.key) === queue)
38906
+ this.queues.delete(queue.key);
38907
+ }
38895
38908
  }
38896
38909
  }
38897
38910
  async logExecution(result, trustedTenantId = null) {
@@ -38917,8 +38930,8 @@ class AutomationEngine {
38917
38930
  });
38918
38931
  }
38919
38932
  getMetrics() {
38920
- const instanceQueues = Array.from(this.instanceQueues.values()).map((q) => ({
38921
- instanceId: q.instanceId,
38933
+ const instanceQueues = Array.from(this.queues.values()).map((q) => ({
38934
+ instanceId: q.key,
38922
38935
  activeCount: q.activeCount,
38923
38936
  pendingCount: q.pending.length
38924
38937
  }));
@@ -38961,12 +38974,12 @@ var init_engine = __esm(() => {
38961
38974
  init_templates();
38962
38975
  logger4 = createLogger("automations:engine");
38963
38976
  QueueFullError = class QueueFullError extends Error {
38964
- instanceId;
38977
+ queueKey;
38965
38978
  queueDepth;
38966
38979
  maxDepth;
38967
- constructor(instanceId, queueDepth, maxDepth) {
38968
- super(`Queue full for instance ${instanceId}: ${queueDepth}/${maxDepth} pending`);
38969
- this.instanceId = instanceId;
38980
+ constructor(queueKey, queueDepth, maxDepth) {
38981
+ super(`Queue full for ${queueKey}: ${queueDepth}/${maxDepth} pending`);
38982
+ this.queueKey = queueKey;
38970
38983
  this.queueDepth = queueDepth;
38971
38984
  this.maxDepth = maxDepth;
38972
38985
  this.name = "QueueFullError";
@@ -76985,7 +76998,7 @@ var require_ClientVoiceManager = __commonJS((exports, module) => {
76985
76998
 
76986
76999
  // ../../node_modules/.bun/@discordjs+ws@1.2.3/node_modules/@discordjs/ws/dist/index.js
76987
77000
  var require_dist9 = __commonJS((exports, module) => {
76988
- var __dirname = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/@discordjs+ws@1.2.3/node_modules/@discordjs/ws/dist";
77001
+ var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/@discordjs+ws@1.2.3/node_modules/@discordjs/ws/dist";
76989
77002
  var __create2 = Object.create;
76990
77003
  var __defProp2 = Object.defineProperty;
76991
77004
  var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
@@ -162265,7 +162278,7 @@ var require_indexes = __commonJS((exports, module) => {
162265
162278
 
162266
162279
  // ../../node_modules/.bun/thread-stream@3.1.0/node_modules/thread-stream/index.js
162267
162280
  var require_thread_stream = __commonJS((exports, module) => {
162268
- var __dirname = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/thread-stream@3.1.0/node_modules/thread-stream";
162281
+ var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/thread-stream@3.1.0/node_modules/thread-stream";
162269
162282
  var { version } = require_package5();
162270
162283
  var { EventEmitter: EventEmitter3 } = __require("events");
162271
162284
  var { Worker } = __require("worker_threads");
@@ -162686,7 +162699,7 @@ var require_thread_stream = __commonJS((exports, module) => {
162686
162699
 
162687
162700
  // ../../node_modules/.bun/pino@9.14.0/node_modules/pino/lib/transport.js
162688
162701
  var require_transport2 = __commonJS((exports, module) => {
162689
- var __dirname = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/pino@9.14.0/node_modules/pino/lib";
162702
+ var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/pino@9.14.0/node_modules/pino/lib";
162690
162703
  var { createRequire: createRequire2 } = __require("module");
162691
162704
  var getCallers = require_caller();
162692
162705
  var { join: join8, isAbsolute, sep: sep2 } = __require("path");
@@ -174411,6 +174424,8 @@ var init_schema2 = __esm(() => {
174411
174424
  enabled: boolean2("enabled").notNull().default(true),
174412
174425
  priority: integer("priority").notNull().default(0),
174413
174426
  transactionalEmissions: boolean2("transactional_emissions").notNull().default(false),
174427
+ maxConcurrency: integer("max_concurrency"),
174428
+ concurrencyKey: text("concurrency_key"),
174414
174429
  managedByAgentId: uuid("managed_by_agent_id").references(() => agents.id, { onDelete: "cascade" }),
174415
174430
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
174416
174431
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
@@ -244431,7 +244446,7 @@ var require_client3 = __commonJS((exports) => {
244431
244446
 
244432
244447
  // ../../node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js
244433
244448
  var require_esmLoader = __commonJS((exports) => {
244434
- var __filename = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js";
244449
+ var __filename = "/home/runner/work/omni/omni/node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js";
244435
244450
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
244436
244451
  var core3 = require_cjs6();
244437
244452
  var importInTheMiddle = require_import_in_the_middle();
@@ -251657,7 +251672,7 @@ var init_sentry_scrub = __esm(() => {
251657
251672
  var require_package7 = __commonJS((exports, module) => {
251658
251673
  module.exports = {
251659
251674
  name: "@omni/api",
251660
- version: "2.260911.2",
251675
+ version: "2.260911.3",
251661
251676
  private: true,
251662
251677
  type: "module",
251663
251678
  exports: {
@@ -278759,7 +278774,7 @@ var require_src45 = __commonJS((exports) => {
278759
278774
 
278760
278775
  // ../../node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src/channelz.js
278761
278776
  var require_channelz = __commonJS((exports) => {
278762
- var __dirname = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src";
278777
+ var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src";
278763
278778
  Object.defineProperty(exports, "__esModule", { value: true });
278764
278779
  exports.registerChannelzSocket = exports.registerChannelzServer = exports.registerChannelzSubchannel = exports.registerChannelzChannel = exports.ChannelzCallTrackerStub = exports.ChannelzCallTracker = exports.ChannelzChildrenTrackerStub = exports.ChannelzChildrenTracker = exports.ChannelzTrace = exports.ChannelzTraceStub = undefined;
278765
278780
  exports.unregisterChannelzRef = unregisterChannelzRef;
@@ -284162,7 +284177,7 @@ var require_duration = __commonJS((exports) => {
284162
284177
 
284163
284178
  // ../../node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src/orca.js
284164
284179
  var require_orca = __commonJS((exports) => {
284165
- var __dirname = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src";
284180
+ var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src";
284166
284181
  Object.defineProperty(exports, "__esModule", { value: true });
284167
284182
  exports.OrcaOobMetricsSubchannelWrapper = exports.GRPC_METRICS_HEADER = exports.ServerMetricRecorder = exports.PerRequestMetricRecorder = undefined;
284168
284183
  exports.createOrcaClient = createOrcaClient;
@@ -379382,6 +379397,12 @@ var init_automations3 = __esm(() => {
379382
379397
  transactionalEmissions: exports_external.boolean().openapi({
379383
379398
  description: "Transactional publication (G5, #988): buffer the run's emit_event publishes and flush them in order " + "only when every action succeeded; a failed run publishes zero"
379384
379399
  }),
379400
+ maxConcurrency: exports_external.number().int().nullable().openapi({
379401
+ description: "Per-automation concurrency limit (#1108). null = queued per instance with the engine default; " + "set = a queue private to this automation, 1 being strict single-flight"
379402
+ }),
379403
+ concurrencyKey: exports_external.string().nullable().openapi({
379404
+ description: "Template over the event payload partitioning this automation\u2019s queue (#1108), e.g. " + '"{{payload.from.id}}" to serialize per chat; null = one queue for the whole automation'
379405
+ }),
379385
379406
  managedByAgentId: exports_external.string().uuid().nullable().openapi({
379386
379407
  description: "Set when this automation was compiled from an agent event manifest (RFC #925 G4b, #986); " + "null = hand-made. Managed automations reject manual mutation \u2014 edit the owning agent\u2019s manifest instead"
379387
379408
  }),
@@ -379400,6 +379421,12 @@ var init_automations3 = __esm(() => {
379400
379421
  priority: exports_external.number().int().default(0).openapi({ description: "Priority" }),
379401
379422
  transactionalEmissions: exports_external.boolean().default(false).openapi({
379402
379423
  description: "Transactional publication (G5, #988): buffer the run's emit_event publishes and flush them in order " + "only when every action succeeded; a failed run publishes zero. Default false = immediate publishing"
379424
+ }),
379425
+ maxConcurrency: exports_external.number().int().min(1).nullable().optional().openapi({
379426
+ description: "Per-automation concurrency limit (#1108). Omit/null = today\u2019s per-instance queueing with the engine " + "default; 1 = strict single-flight, which is what a read-before-write action needs"
379427
+ }),
379428
+ concurrencyKey: exports_external.string().min(1).nullable().optional().openapi({
379429
+ description: "Template over the event payload partitioning this automation\u2019s queue (#1108), e.g. " + '"{{payload.from.id}}" to serialize per chat; omit/null = one queue for the whole automation'
379403
379430
  })
379404
379431
  });
379405
379432
  AutomationLogSchema = exports_external.object({
@@ -379445,7 +379472,9 @@ var init_automations3 = __esm(() => {
379445
379472
  AutomationMetricsSchema = exports_external.object({
379446
379473
  running: exports_external.boolean().openapi({ description: "Engine running" }),
379447
379474
  instanceQueues: exports_external.array(exports_external.object({
379448
- instanceId: exports_external.string().openapi({ description: "Instance ID" }),
379475
+ instanceId: exports_external.string().openapi({
379476
+ description: 'Queue key: the instance ID, or "<instanceId>:<automationId>[:<partition>]" for an automation ' + "running on its own queue (#1108)"
379477
+ }),
379449
379478
  activeCount: exports_external.number().int().openapi({ description: "Active jobs" }),
379450
379479
  pendingCount: exports_external.number().int().openapi({ description: "Pending jobs" })
379451
379480
  })).optional().openapi({ description: "Instance queue stats" }),
@@ -385197,7 +385226,9 @@ var init_automations4 = __esm(() => {
385197
385226
  debounce: debounceSchema.optional().describe("Message debounce configuration"),
385198
385227
  enabled: exports_external.boolean().default(true).describe("Whether automation is enabled"),
385199
385228
  priority: exports_external.number().int().default(0).describe("Priority (higher runs first)"),
385200
- transactionalEmissions: exports_external.boolean().default(false).describe("Transactional publication (G5, #988): buffer the run's emit_event publishes and flush them in order " + "only when every action succeeded; a failed run publishes zero. Default false = immediate publishing")
385229
+ transactionalEmissions: exports_external.boolean().default(false).describe("Transactional publication (G5, #988): buffer the run's emit_event publishes and flush them in order " + "only when every action succeeded; a failed run publishes zero. Default false = immediate publishing"),
385230
+ maxConcurrency: exports_external.number().int().min(1).nullable().optional().describe("Per-automation concurrency limit (#1108). Omit/null = today\u2019s per-instance queueing with the engine " + "default; 1 = strict single-flight, which is what a read-before-write action needs"),
385231
+ concurrencyKey: exports_external.string().min(1).nullable().optional().describe("Template over the event payload partitioning this automation\u2019s queue (#1108), e.g. " + '"{{payload.from.id}}" to serialize per chat; omit/null = one queue for the whole automation')
385201
385232
  });
385202
385233
  updateAutomationSchema = createAutomationSchema.partial();
385203
385234
  listQuerySchema5 = exports_external.object({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/omni",
3
- "version": "2.260911.2",
3
+ "version": "2.260911.3",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/automagik-dev/omni.git",