@automagik/omni 2.260520.20 → 2.260524.1

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.
@@ -18204,11 +18204,13 @@ function isStreamNotFoundError(error) {
18204
18204
  }
18205
18205
  return false;
18206
18206
  }
18207
- var import_nats, log, STREAM_NAMES, daysToNs = (days) => days * 24 * 60 * 60 * 1e9, STREAM_CONFIGS;
18207
+ var nats, log, NATS_STORAGE_FILE, NATS_RETENTION_LIMITS, STREAM_NAMES, daysToNs = (days) => days * 24 * 60 * 60 * 1e9, STREAM_CONFIGS;
18208
18208
  var init_streams = __esm(() => {
18209
18209
  init_logger();
18210
- import_nats = __toESM(require_mod4(), 1);
18210
+ nats = __toESM(require_mod4(), 1);
18211
18211
  log = createLogger("nats:streams");
18212
+ NATS_STORAGE_FILE = nats.StorageType.File;
18213
+ NATS_RETENTION_LIMITS = nats.RetentionPolicy.Limits;
18212
18214
  STREAM_NAMES = {
18213
18215
  MESSAGE: "MESSAGE",
18214
18216
  REACTION: "REACTION",
@@ -18226,80 +18228,80 @@ var init_streams = __esm(() => {
18226
18228
  name: STREAM_NAMES.MESSAGE,
18227
18229
  subjects: ["message.>"],
18228
18230
  max_age: daysToNs(30),
18229
- storage: import_nats.StorageType.File,
18230
- retention: import_nats.RetentionPolicy.Limits,
18231
+ storage: NATS_STORAGE_FILE,
18232
+ retention: NATS_RETENTION_LIMITS,
18231
18233
  description: "All message lifecycle events (received, sent, delivered, read, failed)"
18232
18234
  },
18233
18235
  [STREAM_NAMES.REACTION]: {
18234
18236
  name: STREAM_NAMES.REACTION,
18235
18237
  subjects: ["reaction.>"],
18236
18238
  max_age: daysToNs(7),
18237
- storage: import_nats.StorageType.File,
18238
- retention: import_nats.RetentionPolicy.Limits,
18239
+ storage: NATS_STORAGE_FILE,
18240
+ retention: NATS_RETENTION_LIMITS,
18239
18241
  description: "Reaction events (received, removed)"
18240
18242
  },
18241
18243
  [STREAM_NAMES.INSTANCE]: {
18242
18244
  name: STREAM_NAMES.INSTANCE,
18243
18245
  subjects: ["instance.>"],
18244
18246
  max_age: daysToNs(7),
18245
- storage: import_nats.StorageType.File,
18246
- retention: import_nats.RetentionPolicy.Limits,
18247
+ storage: NATS_STORAGE_FILE,
18248
+ retention: NATS_RETENTION_LIMITS,
18247
18249
  description: "Instance lifecycle events (connected, disconnected, qr_code)"
18248
18250
  },
18249
18251
  [STREAM_NAMES.IDENTITY]: {
18250
18252
  name: STREAM_NAMES.IDENTITY,
18251
18253
  subjects: ["identity.>"],
18252
18254
  max_age: daysToNs(90),
18253
- storage: import_nats.StorageType.File,
18254
- retention: import_nats.RetentionPolicy.Limits,
18255
+ storage: NATS_STORAGE_FILE,
18256
+ retention: NATS_RETENTION_LIMITS,
18255
18257
  description: "Identity management events (created, linked, merged, unlinked)"
18256
18258
  },
18257
18259
  [STREAM_NAMES.MEDIA]: {
18258
18260
  name: STREAM_NAMES.MEDIA,
18259
18261
  subjects: ["media.>"],
18260
18262
  max_age: daysToNs(7),
18261
- storage: import_nats.StorageType.File,
18262
- retention: import_nats.RetentionPolicy.Limits,
18263
+ storage: NATS_STORAGE_FILE,
18264
+ retention: NATS_RETENTION_LIMITS,
18263
18265
  description: "Media processing events (received, processed)"
18264
18266
  },
18265
18267
  [STREAM_NAMES.ACCESS]: {
18266
18268
  name: STREAM_NAMES.ACCESS,
18267
18269
  subjects: ["access.>"],
18268
18270
  max_age: daysToNs(30),
18269
- storage: import_nats.StorageType.File,
18270
- retention: import_nats.RetentionPolicy.Limits,
18271
+ storage: NATS_STORAGE_FILE,
18272
+ retention: NATS_RETENTION_LIMITS,
18271
18273
  description: "Access control events (allowed, denied)"
18272
18274
  },
18273
18275
  [STREAM_NAMES.SESSION]: {
18274
18276
  name: STREAM_NAMES.SESSION,
18275
18277
  subjects: ["session.>"],
18276
18278
  max_age: daysToNs(7),
18277
- storage: import_nats.StorageType.File,
18278
- retention: import_nats.RetentionPolicy.Limits,
18279
+ storage: NATS_STORAGE_FILE,
18280
+ retention: NATS_RETENTION_LIMITS,
18279
18281
  description: "Session lifecycle events (reset)"
18280
18282
  },
18281
18283
  [STREAM_NAMES.CUSTOM]: {
18282
18284
  name: STREAM_NAMES.CUSTOM,
18283
18285
  subjects: ["custom.>"],
18284
18286
  max_age: daysToNs(7),
18285
- storage: import_nats.StorageType.File,
18286
- retention: import_nats.RetentionPolicy.Limits,
18287
+ storage: NATS_STORAGE_FILE,
18288
+ retention: NATS_RETENTION_LIMITS,
18287
18289
  description: "User-defined custom events (webhooks, triggers, etc.)"
18288
18290
  },
18289
18291
  [STREAM_NAMES.SYSTEM]: {
18290
18292
  name: STREAM_NAMES.SYSTEM,
18291
18293
  subjects: ["system.>", "sync.>", "batch-job.>", "presence.>", "chat.>", "follow_up.>"],
18292
18294
  max_age: daysToNs(7),
18293
- storage: import_nats.StorageType.File,
18294
- retention: import_nats.RetentionPolicy.Limits,
18295
+ storage: NATS_STORAGE_FILE,
18296
+ retention: NATS_RETENTION_LIMITS,
18295
18297
  description: "Internal system events (dead_letter, replay, health, sync, batch-job, presence, chat, follow_up)"
18296
18298
  },
18297
18299
  [STREAM_NAMES.AGENT]: {
18298
18300
  name: STREAM_NAMES.AGENT,
18299
18301
  subjects: ["agent.>"],
18300
18302
  max_age: daysToNs(30),
18301
- storage: import_nats.StorageType.File,
18302
- retention: import_nats.RetentionPolicy.Limits,
18303
+ storage: NATS_STORAGE_FILE,
18304
+ retention: NATS_RETENTION_LIMITS,
18303
18305
  description: "Agent lifecycle events (state, tasks, A2A, internal routing)"
18304
18306
  }
18305
18307
  };
@@ -18316,7 +18318,7 @@ function buildConsumerConfig(pattern, options = {}) {
18316
18318
  } = options;
18317
18319
  const config2 = {
18318
18320
  filter_subject: pattern,
18319
- ack_policy: import_nats2.AckPolicy.Explicit,
18321
+ ack_policy: nats2.AckPolicy.Explicit,
18320
18322
  ack_wait: ackWaitMs * 1e6,
18321
18323
  max_deliver: maxRetries + 1,
18322
18324
  max_ack_pending: DEFAULT_CONSUMER_CONFIG.maxAckPending,
@@ -18334,15 +18336,15 @@ function buildConsumerConfig(pattern, options = {}) {
18334
18336
  }
18335
18337
  function mapStartFrom(startFrom) {
18336
18338
  if (startFrom instanceof Date) {
18337
- return import_nats2.DeliverPolicy.StartTime;
18339
+ return nats2.DeliverPolicy.StartTime;
18338
18340
  }
18339
18341
  switch (startFrom) {
18340
18342
  case "first":
18341
- return import_nats2.DeliverPolicy.All;
18343
+ return nats2.DeliverPolicy.All;
18342
18344
  case "last":
18343
- return import_nats2.DeliverPolicy.Last;
18345
+ return nats2.DeliverPolicy.Last;
18344
18346
  default:
18345
- return import_nats2.DeliverPolicy.New;
18347
+ return nats2.DeliverPolicy.New;
18346
18348
  }
18347
18349
  }
18348
18350
  function generateConsumerName(pattern) {
@@ -18365,10 +18367,10 @@ function calculateBackoffDelay(retryCount, baseDelayMs = DEFAULT_CONSUMER_CONFIG
18365
18367
  const jitter = delay * 0.1 * (Math.random() * 2 - 1);
18366
18368
  return Math.floor(Math.min(delay + jitter, maxDelayMs));
18367
18369
  }
18368
- var import_nats2, DEFAULT_CONSUMER_CONFIG;
18370
+ var nats2, DEFAULT_CONSUMER_CONFIG;
18369
18371
  var init_consumer = __esm(() => {
18370
18372
  init_streams();
18371
- import_nats2 = __toESM(require_mod4(), 1);
18373
+ nats2 = __toESM(require_mod4(), 1);
18372
18374
  DEFAULT_CONSUMER_CONFIG = {
18373
18375
  maxRetries: 3,
18374
18376
  retryDelayMs: 1000,
@@ -22720,7 +22722,7 @@ function buildTraceHeaders() {
22720
22722
  return null;
22721
22723
  const flags = (ctx.traceFlags ?? 0).toString(16).padStart(2, "0");
22722
22724
  const traceparent = `00-${ctx.traceId}-${ctx.spanId}-${flags}`;
22723
- const h = import_nats3.headers();
22725
+ const h = import_nats.headers();
22724
22726
  h.set("traceparent", traceparent);
22725
22727
  h.set("x-trace-id", ctx.traceId);
22726
22728
  h.set("x-span-id", ctx.spanId);
@@ -22735,7 +22737,7 @@ class NatsEventBus {
22735
22737
  js = null;
22736
22738
  jsm = null;
22737
22739
  config;
22738
- sc = import_nats3.StringCodec();
22740
+ sc = import_nats.StringCodec();
22739
22741
  subscriptionManager = new SubscriptionManager;
22740
22742
  connectionAttempts = 0;
22741
22743
  isClosing = false;
@@ -22768,7 +22770,7 @@ class NatsEventBus {
22768
22770
  }
22769
22771
  try {
22770
22772
  this.connectionAttempts++;
22771
- this.nc = await import_nats3.connect(connectionOptions);
22773
+ this.nc = await import_nats.connect(connectionOptions);
22772
22774
  this.setupConnectionHandlers();
22773
22775
  this.js = this.nc.jetstream();
22774
22776
  this.jsm = await this.nc.jetstreamManager();
@@ -23040,7 +23042,7 @@ async function connectEventBus(config2) {
23040
23042
  await bus.connect();
23041
23043
  return bus;
23042
23044
  }
23043
- var import_api2, import_nats3, log4, DEFAULTS;
23045
+ var import_api2, import_nats, log4, DEFAULTS;
23044
23046
  var init_client = __esm(() => {
23045
23047
  init_logger();
23046
23048
  init_consumer();
@@ -23048,7 +23050,7 @@ var init_client = __esm(() => {
23048
23050
  init_streams();
23049
23051
  init_subscription();
23050
23052
  import_api2 = __toESM(require_src(), 1);
23051
- import_nats3 = __toESM(require_mod4(), 1);
23053
+ import_nats = __toESM(require_mod4(), 1);
23052
23054
  log4 = createLogger("nats");
23053
23055
  DEFAULTS = {
23054
23056
  url: "nats://localhost:4222",
@@ -23271,8 +23273,10 @@ var init_common = __esm(() => {
23271
23273
  "discord",
23272
23274
  "slack",
23273
23275
  "telegram",
23276
+ "a2a",
23274
23277
  "gupshup",
23275
- "twilio-whatsapp"
23278
+ "twilio-whatsapp",
23279
+ "internal"
23276
23280
  ]);
23277
23281
  ContentTypeSchema = exports_external.enum([
23278
23282
  "text",
@@ -23301,6 +23305,7 @@ var init_agent2 = __esm(() => {
23301
23305
  AgentCardSchema = exports_external.object({
23302
23306
  name: exports_external.string(),
23303
23307
  url: exports_external.string().optional(),
23308
+ supportedInterfaces: exports_external.array(exports_external.unknown()).optional(),
23304
23309
  version: exports_external.string().optional(),
23305
23310
  skills: exports_external.array(exports_external.unknown()).optional()
23306
23311
  }).passthrough();
@@ -23334,7 +23339,8 @@ var init_agent2 = __esm(() => {
23334
23339
  configPath: exports_external.string().optional(),
23335
23340
  isInternal: exports_external.boolean().default(false),
23336
23341
  isActive: exports_external.boolean().default(true),
23337
- metadata: MetadataSchema.optional()
23342
+ metadata: MetadataSchema.optional(),
23343
+ agentCard: AgentCardSchema.optional()
23338
23344
  });
23339
23345
  UpdateAgentSchema = CreateAgentSchema.partial();
23340
23346
  });
@@ -32277,7 +32283,7 @@ class A2AClient {
32277
32283
  }
32278
32284
  async run(request) {
32279
32285
  const startMs = Date.now();
32280
- const body = this.buildJsonRpcRequest("message/send", request);
32286
+ const body = this.buildJsonRpcRequest("SendMessage", request);
32281
32287
  const response = await this.post(body, request.timeoutMs ?? this.defaultTimeoutMs);
32282
32288
  if (!response.ok) {
32283
32289
  throw new ProviderError(`A2A request failed: ${response.status}`, "SERVER_ERROR", response.status);
@@ -32294,13 +32300,13 @@ class A2AClient {
32294
32300
  throw new ProviderError("A2A response missing task.id", "INVALID_RESPONSE");
32295
32301
  }
32296
32302
  const state = task?.status?.state;
32297
- if (state === "completed" || state === "failed") {
32303
+ if (isTerminalState(state)) {
32298
32304
  return this.taskToProviderResponse(task, taskId, startMs);
32299
32305
  }
32300
32306
  return this.pollUntilComplete(taskId, startMs, request.timeoutMs ?? this.defaultTimeoutMs);
32301
32307
  }
32302
32308
  async* stream(request) {
32303
- const body = this.buildJsonRpcRequest("message/stream", request);
32309
+ const body = this.buildJsonRpcRequest("SendStreamingMessage", request);
32304
32310
  const controller = new AbortController;
32305
32311
  const timeoutMs = request.timeoutMs ?? this.defaultTimeoutMs;
32306
32312
  const timer = setTimeout(() => controller.abort(), timeoutMs);
@@ -32337,16 +32343,18 @@ class A2AClient {
32337
32343
  const response = await fetch(this.baseUrl, {
32338
32344
  method: "POST",
32339
32345
  headers: this.headers({ "Content-Type": "application/json" }),
32340
- body: JSON.stringify({ jsonrpc: "2.0", id: "health", method: "tasks/get", params: { id: "ping" } }),
32346
+ body: JSON.stringify({ jsonrpc: "2.0", id: "health", method: "GetTask", params: { id: "ping" } }),
32341
32347
  signal: AbortSignal.timeout(5000)
32342
32348
  });
32343
- return { healthy: response.ok, latencyMs: Date.now() - start };
32349
+ const healthy = response.status < 500 && response.status !== 401 && response.status !== 403;
32350
+ return { healthy, latencyMs: Date.now() - start, error: healthy ? undefined : `HTTP ${response.status}` };
32344
32351
  } catch (error) {
32345
32352
  return { healthy: false, latencyMs: Date.now() - start, error: String(error) };
32346
32353
  }
32347
32354
  }
32348
32355
  headers(extra) {
32349
32356
  return {
32357
+ "A2A-Version": "1.0",
32350
32358
  ...this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {},
32351
32359
  ...extra
32352
32360
  };
@@ -32378,12 +32386,13 @@ class A2AClient {
32378
32386
  method,
32379
32387
  params: {
32380
32388
  message: {
32381
- role: "user",
32382
- parts: [{ type: "text", text: request.message }],
32389
+ role: "ROLE_USER",
32390
+ parts: [{ text: request.message, mediaType: "text/plain" }],
32383
32391
  messageId: `msg-${crypto.randomUUID()}`
32384
32392
  },
32385
32393
  configuration: {
32386
- acceptedOutputModes: ["text"]
32394
+ acceptedOutputModes: ["text/plain"],
32395
+ returnImmediately: true
32387
32396
  },
32388
32397
  contextId: request.sessionId
32389
32398
  }
@@ -32426,13 +32435,49 @@ class A2AClient {
32426
32435
  }
32427
32436
  }
32428
32437
  parseSSEEvent(event) {
32438
+ const result = event.result ?? event;
32439
+ return this.parseArtifactUpdate(result) ?? this.parseStatusUpdate(result) ?? this.parseLegacySSEEvent(event);
32440
+ }
32441
+ parseArtifactUpdate(result) {
32442
+ const artifactUpdate = result.taskArtifactUpdate ?? result.artifactUpdate ?? result.artifact_update;
32443
+ if (artifactUpdate) {
32444
+ const artifact = artifactUpdate.artifact;
32445
+ if (!artifact)
32446
+ return null;
32447
+ const text = extractTextFromParts(artifact.parts ?? []);
32448
+ if (!text)
32449
+ return null;
32450
+ return {
32451
+ event: "artifact",
32452
+ content: text,
32453
+ isComplete: false,
32454
+ runId: artifactUpdate.taskId
32455
+ };
32456
+ }
32457
+ return null;
32458
+ }
32459
+ parseStatusUpdate(result) {
32460
+ const statusUpdate = result.taskStatusUpdate ?? result.statusUpdate ?? result.status_update;
32461
+ if (statusUpdate) {
32462
+ const status = statusUpdate.status;
32463
+ const state = status?.state;
32464
+ if (isTerminalState(state)) {
32465
+ return {
32466
+ event: "final",
32467
+ isComplete: true,
32468
+ runId: statusUpdate.taskId
32469
+ };
32470
+ }
32471
+ }
32472
+ return null;
32473
+ }
32474
+ parseLegacySSEEvent(event) {
32429
32475
  const type = event.type;
32430
32476
  if (type === "taskArtifactUpdateEvent") {
32431
32477
  const artifact = event.artifact;
32432
32478
  if (!artifact)
32433
32479
  return null;
32434
- const parts = artifact.parts ?? [];
32435
- const textParts = parts.filter((p2) => p2.type === "text").map((p2) => p2.text).join("");
32480
+ const textParts = extractTextFromParts(artifact.parts ?? []);
32436
32481
  if (!textParts)
32437
32482
  return null;
32438
32483
  return {
@@ -32445,7 +32490,7 @@ class A2AClient {
32445
32490
  if (type === "taskStatusUpdateEvent") {
32446
32491
  const status = event.status;
32447
32492
  const state = status?.state;
32448
- const isFinal = event.final === true || state === "completed" || state === "failed";
32493
+ const isFinal = event.final === true || isTerminalState(state);
32449
32494
  if (isFinal) {
32450
32495
  return {
32451
32496
  event: "final",
@@ -32461,11 +32506,9 @@ class A2AClient {
32461
32506
  const textParts = [];
32462
32507
  for (const artifact of artifacts) {
32463
32508
  const parts = artifact.parts ?? [];
32464
- for (const part of parts) {
32465
- if (part.type === "text" && part.text) {
32466
- textParts.push(part.text);
32467
- }
32468
- }
32509
+ const text = extractTextFromParts(parts);
32510
+ if (text)
32511
+ textParts.push(text);
32469
32512
  }
32470
32513
  const status = task?.status;
32471
32514
  const state = status?.state;
@@ -32474,7 +32517,7 @@ class A2AClient {
32474
32517
  `),
32475
32518
  runId: taskId,
32476
32519
  sessionId: task?.contextId ?? taskId,
32477
- status: state === "failed" ? "failed" : "completed",
32520
+ status: state === "TASK_STATE_COMPLETED" || state === "completed" ? "completed" : "failed",
32478
32521
  metrics: {
32479
32522
  inputTokens: 0,
32480
32523
  outputTokens: 0,
@@ -32491,7 +32534,7 @@ class A2AClient {
32491
32534
  const body = {
32492
32535
  jsonrpc: "2.0",
32493
32536
  id: `poll-${attempt}`,
32494
- method: "tasks/get",
32537
+ method: "GetTask",
32495
32538
  params: { id: taskId }
32496
32539
  };
32497
32540
  const response = await this.post(body, Math.min(1e4, Math.max(0, deadline - Date.now())));
@@ -32510,7 +32553,7 @@ class A2AClient {
32510
32553
  const task = taskResult?.task;
32511
32554
  const status = task?.status;
32512
32555
  const state = status?.state;
32513
- if (state === "completed" || state === "failed") {
32556
+ if (isTerminalState(state)) {
32514
32557
  return this.taskToProviderResponse(task, taskId, startMs);
32515
32558
  }
32516
32559
  await sleep(POLL_INTERVAL_MS);
@@ -32521,6 +32564,12 @@ class A2AClient {
32521
32564
  function sleep(ms) {
32522
32565
  return new Promise((resolve) => setTimeout(resolve, ms));
32523
32566
  }
32567
+ function isTerminalState(state) {
32568
+ return state === "TASK_STATE_COMPLETED" || state === "TASK_STATE_FAILED" || state === "TASK_STATE_CANCELED" || state === "TASK_STATE_REJECTED" || state === "TASK_STATE_INPUT_REQUIRED" || state === "TASK_STATE_AUTH_REQUIRED" || state === "completed" || state === "failed" || state === "canceled";
32569
+ }
32570
+ function extractTextFromParts(parts) {
32571
+ return parts.filter((part) => typeof part.text === "string").map((part) => part.text).join("");
32572
+ }
32524
32573
  function createA2AClient(config2) {
32525
32574
  return new A2AClient(config2);
32526
32575
  }
@@ -32643,7 +32692,7 @@ class NatsGenieProvider {
32643
32692
  schema = "nats-genie";
32644
32693
  mode;
32645
32694
  nc = null;
32646
- sc = import_nats4.StringCodec();
32695
+ sc = import_nats2.StringCodec();
32647
32696
  replySubscription = null;
32648
32697
  constructor(id, name, config2) {
32649
32698
  this.id = id;
@@ -32801,7 +32850,7 @@ class NatsGenieProvider {
32801
32850
  async ensureConnected() {
32802
32851
  if (this.nc)
32803
32852
  return;
32804
- this.nc = await import_nats4.connect({
32853
+ this.nc = await import_nats2.connect({
32805
32854
  servers: this.config.natsUrl,
32806
32855
  name: `omni-nats-genie-${this.config.instanceId}`,
32807
32856
  reconnect: true,
@@ -32840,10 +32889,10 @@ class NatsGenieProvider {
32840
32889
  }
32841
32890
  }
32842
32891
  }
32843
- var import_nats4, log17;
32892
+ var import_nats2, log17;
32844
32893
  var init_nats_genie_provider = __esm(() => {
32845
32894
  init_logger();
32846
- import_nats4 = __toESM(require_mod4(), 1);
32895
+ import_nats2 = __toESM(require_mod4(), 1);
32847
32896
  log17 = createLogger("provider:nats-genie");
32848
32897
  });
32849
32898
 
@@ -230137,7 +230186,7 @@ var init_sentry_scrub = __esm(() => {
230137
230186
  var require_package8 = __commonJS((exports, module) => {
230138
230187
  module.exports = {
230139
230188
  name: "@omni/api",
230140
- version: "2.260520.20",
230189
+ version: "2.260524.1",
230141
230190
  type: "module",
230142
230191
  exports: {
230143
230192
  ".": {
@@ -288940,6 +288989,24 @@ var init_api_keys = __esm(() => {
288940
288989
  });
288941
288990
 
288942
288991
  // ../api/src/middleware/auth.ts
288992
+ function requireAnyScope(requiredScopes) {
288993
+ return createMiddleware(async (c, next) => {
288994
+ const apiKey = c.get("apiKey");
288995
+ if (!apiKey) {
288996
+ return c.json({ error: { code: "UNAUTHORIZED", message: "Authentication required" } }, 401);
288997
+ }
288998
+ const allowed = requiredScopes.some((scope) => ApiKeyService.scopeAllows(apiKey.scopes, scope));
288999
+ if (!allowed) {
289000
+ return c.json({
289001
+ error: {
289002
+ code: "FORBIDDEN",
289003
+ message: `Insufficient permissions. Required one of: ${requiredScopes.join(", ")}`
289004
+ }
289005
+ }, 403);
289006
+ }
289007
+ return next();
289008
+ });
289009
+ }
288943
289010
  function requireInstanceAccess(instanceIdGetter) {
288944
289011
  return createMiddleware(async (c, next) => {
288945
289012
  const apiKey = c.get("apiKey");
@@ -288973,8 +289040,7 @@ var init_auth = __esm(() => {
288973
289040
  init_factory2();
288974
289041
  init_api_keys();
288975
289042
  authMiddleware = createMiddleware(async (c, next) => {
288976
- const bearer = c.req.header("authorization")?.replace(/^Bearer\s+/i, "");
288977
- const apiKey = c.req.header("x-api-key") ?? c.req.query("api_key") ?? bearer;
289043
+ const apiKey = c.req.header("x-api-key") ?? c.req.query("api_key") ?? c.req.header("authorization")?.replace(/^Bearer\s+/i, "");
288978
289044
  if (!apiKey) {
288979
289045
  return c.json({
288980
289046
  error: {
@@ -289535,6 +289601,8 @@ var DEFAULT_TURN_SCOPES, SCOPE_MAP;
289535
289601
  var init_scopes = __esm(() => {
289536
289602
  DEFAULT_TURN_SCOPES = ["messages:send", "turns:close", "tts:synthesize", "context:read"];
289537
289603
  SCOPE_MAP = {
289604
+ "GET /a2a/agents": "agents:read",
289605
+ "GET /a2a/agents/:agentId/card": "agents:read",
289538
289606
  "GET /access/rules": "access:read",
289539
289607
  "GET /access/rules/:id": "access:read",
289540
289608
  "POST /access/rules": "access:write",
@@ -317223,12 +317291,12 @@ class AgentStateService {
317223
317291
  return parsed.success ? parsed.data : null;
317224
317292
  }
317225
317293
  }
317226
- var import_nats6, log70, sc, KV_TTL_MS;
317294
+ var import_nats4, log70, sc, KV_TTL_MS;
317227
317295
  var init_agent_state2 = __esm(() => {
317228
317296
  init_src();
317229
- import_nats6 = __toESM(require_mod4(), 1);
317297
+ import_nats4 = __toESM(require_mod4(), 1);
317230
317298
  log70 = createLogger("services:agent-state");
317231
- sc = import_nats6.StringCodec();
317299
+ sc = import_nats4.StringCodec();
317232
317300
  KV_TTL_MS = 24 * 60 * 60 * 1000;
317233
317301
  });
317234
317302
 
@@ -331212,7 +331280,7 @@ async function initTurnEvents(natsUrl) {
331212
331280
  if (nc && !nc.isClosed())
331213
331281
  return;
331214
331282
  try {
331215
- nc = await import_nats7.connect({
331283
+ nc = await import_nats5.connect({
331216
331284
  servers: natsUrl,
331217
331285
  name: "omni-turn-events",
331218
331286
  reconnect: true,
@@ -331262,12 +331330,12 @@ function publishTurnTimeout(instanceId, chatId, event) {
331262
331330
  publish(topic, event);
331263
331331
  log89.debug("Published turn.timeout", { turnId: event.turnId, instanceId });
331264
331332
  }
331265
- var import_nats7, log89, sc2, nc = null;
331333
+ var import_nats5, log89, sc2, nc = null;
331266
331334
  var init_turn_events = __esm(() => {
331267
331335
  init_src();
331268
- import_nats7 = __toESM(require_mod4(), 1);
331336
+ import_nats5 = __toESM(require_mod4(), 1);
331269
331337
  log89 = createLogger("turn-events");
331270
- sc2 = import_nats7.StringCodec();
331338
+ sc2 = import_nats5.StringCodec();
331271
331339
  });
331272
331340
 
331273
331341
  // ../api/src/plugins/logger.ts
@@ -331756,6 +331824,40 @@ function buildChatPreview(payload, rawPayload) {
331756
331824
  }
331757
331825
  return preview.substring(0, 500);
331758
331826
  }
331827
+ function compactRecord(record) {
331828
+ const compacted = Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));
331829
+ return Object.keys(compacted).length > 0 ? compacted : undefined;
331830
+ }
331831
+ function isSentMediaContent(content) {
331832
+ return OUTBOUND_MEDIA_TYPES.has(content.type) || !!content.mediaUrl || !!content.localPath || !!content.mimeType;
331833
+ }
331834
+ function buildSentMediaMetadata(content, rawPayload) {
331835
+ if (!isSentMediaContent(content))
331836
+ return;
331837
+ const rawSource = typeof rawPayload?.mediaSource === "string" ? rawPayload.mediaSource : undefined;
331838
+ return compactRecord({
331839
+ caption: content.caption,
331840
+ filename: content.filename,
331841
+ voiceNote: content.isVoiceNote === true ? true : undefined,
331842
+ source: rawSource ?? (content.mediaUrl ? "url" : content.localPath ? "localPath" : "inline")
331843
+ });
331844
+ }
331845
+ function buildSentMessageContentFields(payload) {
331846
+ return {
331847
+ textContent: sanitizeText(payload.content.text ?? payload.content.caption),
331848
+ hasMedia: isSentMediaContent(payload.content),
331849
+ mediaMimeType: truncate3(payload.content.mimeType, 100),
331850
+ mediaUrl: payload.content.mediaUrl,
331851
+ mediaLocalPath: payload.content.localPath,
331852
+ mediaMetadata: buildSentMediaMetadata(payload.content, payload.rawPayload),
331853
+ rawPayload: payload.rawPayload ? deepSanitize(payload.rawPayload) : undefined
331854
+ };
331855
+ }
331856
+ function buildSentChatPreview(payload) {
331857
+ const text3 = payload.content.text ?? payload.content.caption ?? "";
331858
+ const badge = payload.content.type !== "text" ? MEDIA_BADGES2[payload.content.type] ?? `[${payload.content.type}]` : "";
331859
+ return badge ? text3 ? `${badge} ${text3}` : badge : text3;
331860
+ }
331759
331861
  function extractPhoneFromSender(senderId, channel5) {
331760
331862
  if (!channel5.startsWith("whatsapp"))
331761
331863
  return;
@@ -332047,17 +332149,22 @@ async function setupMessagePersistence(eventBus, services) {
332047
332149
  chatType: inferChatType(payload.chatId),
332048
332150
  channel: metadata.channelType ?? "whatsapp"
332049
332151
  });
332152
+ const sentContent = buildSentMessageContentFields(payload);
332050
332153
  const { message: message2, created } = await services.messages.findOrCreate(chat2.id, messageExternalId, {
332051
332154
  source: "realtime",
332052
332155
  messageType: mapContentType(payload.content.type),
332053
- textContent: sanitizeText(payload.content.text),
332156
+ textContent: sentContent.textContent,
332054
332157
  platformTimestamp: new Date(event.timestamp),
332055
332158
  senderPersonId: metadata.personId,
332056
332159
  senderPlatformIdentityId: metadata.platformIdentityId,
332057
332160
  isFromMe: true,
332058
332161
  senderAgentId: payload.senderAgentId ?? null,
332059
- hasMedia: !!payload.content.mediaUrl,
332060
- mediaUrl: payload.content.mediaUrl,
332162
+ hasMedia: sentContent.hasMedia,
332163
+ mediaMimeType: sentContent.mediaMimeType,
332164
+ mediaUrl: sentContent.mediaUrl,
332165
+ mediaLocalPath: sentContent.mediaLocalPath,
332166
+ mediaMetadata: sentContent.mediaMetadata,
332167
+ rawPayload: sentContent.rawPayload,
332061
332168
  replyToExternalId: truncate3(payload.replyToId, 255)
332062
332169
  });
332063
332170
  if (created) {
@@ -332067,7 +332174,7 @@ async function setupMessagePersistence(eventBus, services) {
332067
332174
  chatId: chat2.id
332068
332175
  });
332069
332176
  }
332070
- services.chats.updateLastMessage(chat2.id, sanitizeText(payload.content.text ?? "") ?? "", new Date(event.timestamp), true).catch((err) => log93.debug("Failed to update chat recency (sent)", { error: String(err) }));
332177
+ services.chats.updateLastMessage(chat2.id, sanitizeText(buildSentChatPreview(payload)) ?? "", new Date(event.timestamp), true).catch((err) => log93.debug("Failed to update chat recency (sent)", { error: String(err) }));
332071
332178
  if (metadata.streamSequence) {
332072
332179
  await services.consumerOffsets.updateOffset("message-persistence-sent", "MESSAGE", metadata.streamSequence, event.id);
332073
332180
  }
@@ -332236,7 +332343,7 @@ async function detectStartupGaps(services) {
332236
332343
  }
332237
332344
  }
332238
332345
  }
332239
- var log93, CONTENT_TYPE_MAP, INTERNAL_JID_SUFFIXES, MEDIA_BADGES2;
332346
+ var log93, CONTENT_TYPE_MAP, INTERNAL_JID_SUFFIXES, MEDIA_BADGES2, OUTBOUND_MEDIA_TYPES;
332240
332347
  var init_message_persistence = __esm(() => {
332241
332348
  init_src();
332242
332349
  init_esm5();
@@ -332266,6 +332373,7 @@ var init_message_persistence = __esm(() => {
332266
332373
  location: "[Location]",
332267
332374
  poll: "[Poll]"
332268
332375
  };
332376
+ OUTBOUND_MEDIA_TYPES = new Set(["audio", "image", "video", "document", "sticker"]);
332269
332377
  });
332270
332378
 
332271
332379
  // ../api/src/plugins/session-storage.ts
@@ -333886,7 +333994,8 @@ function createClaudeCodeProviderInstance(provider, instance4, db2) {
333886
333994
  model: schemaConfig.model,
333887
333995
  systemPrompt: schemaConfig.systemPrompt,
333888
333996
  mcpServers: schemaConfig.mcpServers,
333889
- maxTurns: schemaConfig.maxTurns
333997
+ maxTurns: schemaConfig.maxTurns,
333998
+ pathToClaudeCodeExecutable: schemaConfig.pathToClaudeCodeExecutable
333890
333999
  }, createSessionStorage(db2, provider.id), {
333891
334000
  timeoutMs: (instance4.agentTimeout ?? provider.defaultTimeout ?? 120) * 1000,
333892
334001
  enableAutoSplit: instance4.enableAutoSplit ?? true,
@@ -338802,6 +338911,7 @@ var init_agents2 = __esm(() => {
338802
338911
  isInternal: exports_external.boolean().openapi({ description: "Whether this is an internal system agent" }),
338803
338912
  isActive: exports_external.boolean().openapi({ description: "Whether agent is active" }),
338804
338913
  metadata: exports_external.record(exports_external.string(), exports_external.unknown()).nullable().openapi({ description: "Arbitrary metadata" }),
338914
+ agentCard: exports_external.record(exports_external.string(), exports_external.unknown()).nullable().openapi({ description: "A2A Agent Card overrides" }),
338805
338915
  createdAt: exports_external.string().datetime().openapi({ description: "Creation timestamp" }),
338806
338916
  updatedAt: exports_external.string().datetime().openapi({ description: "Last update timestamp" })
338807
338917
  });
@@ -338816,7 +338926,8 @@ var init_agents2 = __esm(() => {
338816
338926
  configPath: exports_external.string().optional().openapi({ description: "Path to agent config file" }),
338817
338927
  isInternal: exports_external.boolean().default(false).openapi({ description: "Whether this is an internal system agent" }),
338818
338928
  isActive: exports_external.boolean().default(true).openapi({ description: "Whether agent is active" }),
338819
- metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional().openapi({ description: "Arbitrary metadata" })
338929
+ metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional().openapi({ description: "Arbitrary metadata" }),
338930
+ agentCard: exports_external.record(exports_external.string(), exports_external.unknown()).optional().openapi({ description: "A2A Agent Card overrides" })
338820
338931
  });
338821
338932
  });
338822
338933
 
@@ -342560,6 +342671,228 @@ var init_dist6 = __esm(() => {
342560
342671
  init_zod();
342561
342672
  });
342562
342673
 
342674
+ // ../api/src/services/a2a-discovery.ts
342675
+ function isRecord(value) {
342676
+ return value !== null && typeof value === "object" && !Array.isArray(value);
342677
+ }
342678
+ function stringOverride(value) {
342679
+ return typeof value === "string" ? value : undefined;
342680
+ }
342681
+ function stringArray(value) {
342682
+ return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : undefined;
342683
+ }
342684
+ function normalizeBaseUrl(baseUrl) {
342685
+ return baseUrl.replace(/\/+$/, "");
342686
+ }
342687
+ function buildDefaultSkills(capabilities3) {
342688
+ const skills = [
342689
+ {
342690
+ id: "messaging",
342691
+ name: "Messaging",
342692
+ description: "Process and respond to text messages",
342693
+ tags: ["messaging", "chat"],
342694
+ inputModes: ["text/plain"],
342695
+ outputModes: ["text/plain"]
342696
+ }
342697
+ ];
342698
+ if (capabilities3.includes("image") || capabilities3.includes("vision")) {
342699
+ skills.push({
342700
+ id: "vision",
342701
+ name: "Vision",
342702
+ description: "Process and describe images",
342703
+ tags: ["vision", "image"],
342704
+ inputModes: ["text/plain", "image/png", "image/jpeg", "image/webp"],
342705
+ outputModes: ["text/plain"]
342706
+ });
342707
+ }
342708
+ if (capabilities3.includes("audio") || capabilities3.includes("transcription")) {
342709
+ skills.push({
342710
+ id: "audio",
342711
+ name: "Audio",
342712
+ description: "Transcribe and process audio",
342713
+ tags: ["audio", "transcription"],
342714
+ inputModes: ["audio/mpeg", "audio/ogg", "audio/wav"],
342715
+ outputModes: ["text/plain"]
342716
+ });
342717
+ }
342718
+ return skills;
342719
+ }
342720
+ function buildA2AAgentCard(params) {
342721
+ const { baseUrl, agent: agent3, instance: instance4 } = params;
342722
+ const override = isRecord(agent3.agentCard) ? agent3.agentCard : {};
342723
+ const capabilities3 = agent3.capabilities ?? [];
342724
+ const endpointUrl = `${normalizeBaseUrl(baseUrl)}/a2a/${instance4.id}`;
342725
+ const card = {
342726
+ name: stringOverride(override.name) ?? agent3.name,
342727
+ description: stringOverride(override.description) ?? `Omni agent ${agent3.name}`,
342728
+ version: stringOverride(override.version) ?? "1.0.0",
342729
+ supportedInterfaces: Array.isArray(override.supportedInterfaces) ? override.supportedInterfaces : [
342730
+ {
342731
+ url: endpointUrl,
342732
+ protocolBinding: "JSONRPC",
342733
+ protocolVersion: "1.0"
342734
+ }
342735
+ ],
342736
+ capabilities: {
342737
+ streaming: true,
342738
+ pushNotifications: false,
342739
+ extendedAgentCard: false,
342740
+ ...isRecord(override.capabilities) ? override.capabilities : {}
342741
+ },
342742
+ defaultInputModes: stringArray(override.defaultInputModes) ?? ["text/plain"],
342743
+ defaultOutputModes: stringArray(override.defaultOutputModes) ?? ["text/plain"],
342744
+ skills: Array.isArray(override.skills) ? override.skills : buildDefaultSkills(capabilities3),
342745
+ securitySchemes: {
342746
+ bearerAuth: {
342747
+ httpAuthSecurityScheme: {
342748
+ scheme: "Bearer",
342749
+ bearerFormat: "Omni API key",
342750
+ description: "Use an Omni API key as a bearer token."
342751
+ }
342752
+ },
342753
+ apiKeyHeader: {
342754
+ apiKeySecurityScheme: {
342755
+ location: "header",
342756
+ name: "x-api-key",
342757
+ description: "Legacy Omni API key header."
342758
+ }
342759
+ },
342760
+ ...isRecord(override.securitySchemes) ? override.securitySchemes : {}
342761
+ },
342762
+ securityRequirements: [{ schemes: { bearerAuth: { list: [] } } }, { schemes: { apiKeyHeader: { list: [] } } }]
342763
+ };
342764
+ const providerOverride = isRecord(override.provider) ? override.provider : undefined;
342765
+ if (providerOverride)
342766
+ card.provider = providerOverride;
342767
+ const metadataOverride = isRecord(override.metadata) ? override.metadata : undefined;
342768
+ if (metadataOverride)
342769
+ card.metadata = metadataOverride;
342770
+ const iconUrl = stringOverride(override.iconUrl);
342771
+ if (iconUrl)
342772
+ card.iconUrl = iconUrl;
342773
+ const documentationUrl = stringOverride(override.documentationUrl);
342774
+ if (documentationUrl)
342775
+ card.documentationUrl = documentationUrl;
342776
+ return card;
342777
+ }
342778
+ async function listA2ADiscoverableAgents(params) {
342779
+ const { services, baseUrl, includeUnconfigured = false } = params;
342780
+ const [agents2, instances2, providers2] = await Promise.all([
342781
+ services.agents.list({ isActive: true, limit: 200 }),
342782
+ services.instances.list({ channel: ["a2a"], status: ["active"], limit: 200 }),
342783
+ services.providers.list({ active: true })
342784
+ ]);
342785
+ const instanceByAgent = new Map;
342786
+ for (const instance4 of instances2.items) {
342787
+ if (instance4.agentId && !instanceByAgent.has(instance4.agentId)) {
342788
+ instanceByAgent.set(instance4.agentId, instance4);
342789
+ }
342790
+ }
342791
+ const providerById = new Map(providers2.map((provider) => [provider.id, provider]));
342792
+ const result = [];
342793
+ for (const agent3 of agents2) {
342794
+ const instance4 = instanceByAgent.get(agent3.id) ?? null;
342795
+ const provider = agent3.agentProviderId ? providerById.get(agent3.agentProviderId) : null;
342796
+ if (!instance4 && !includeUnconfigured)
342797
+ continue;
342798
+ result.push({
342799
+ agentId: agent3.id,
342800
+ name: agent3.name,
342801
+ description: stringOverride(agent3.agentCard?.description) ?? null,
342802
+ provider: agent3.provider,
342803
+ providerSchema: provider?.schema ?? null,
342804
+ model: agent3.model,
342805
+ capabilities: agent3.capabilities,
342806
+ configured: Boolean(instance4),
342807
+ instanceId: instance4?.id ?? null,
342808
+ endpointUrl: instance4 ? `${normalizeBaseUrl(baseUrl)}/a2a/${instance4.id}` : null,
342809
+ parameters: {
342810
+ agentType: agent3.agentType,
342811
+ providerId: agent3.agentProviderId,
342812
+ metadata: agent3.metadata ?? {},
342813
+ agentCard: agent3.agentCard ?? {}
342814
+ },
342815
+ card: instance4 ? buildA2AAgentCard({ baseUrl, agent: agent3, instance: instance4 }) : null
342816
+ });
342817
+ }
342818
+ return result;
342819
+ }
342820
+ async function resolveA2AAgentCard(params) {
342821
+ const { services, baseUrl, agentId, instanceId } = params;
342822
+ let instance4 = null;
342823
+ let agent3 = null;
342824
+ if (instanceId) {
342825
+ instance4 = await services.instances.getById(instanceId);
342826
+ if (!instance4 || instance4.channel !== "a2a" || !instance4.agentId)
342827
+ return null;
342828
+ agent3 = await services.agents.getById(instance4.agentId);
342829
+ } else if (agentId) {
342830
+ agent3 = await services.agents.getById(agentId);
342831
+ const instances2 = await services.instances.list({ channel: ["a2a"], status: ["active"], limit: 200 });
342832
+ instance4 = instances2.items.find((item) => item.agentId === agentId) ?? null;
342833
+ if (!instance4)
342834
+ return null;
342835
+ } else {
342836
+ const instances2 = await services.instances.list({ channel: ["a2a"], status: ["active"], limit: 2 });
342837
+ if (instances2.items.length !== 1)
342838
+ return null;
342839
+ instance4 = instances2.items[0] ?? null;
342840
+ if (!instance4?.agentId)
342841
+ return null;
342842
+ agent3 = await services.agents.getById(instance4.agentId);
342843
+ }
342844
+ if (!agent3 || !instance4 || !agent3.isActive || !instance4.isActive)
342845
+ return null;
342846
+ const provider = agent3.agentProviderId ? await services.providers.getById(agent3.agentProviderId).catch(() => null) : null;
342847
+ return {
342848
+ card: buildA2AAgentCard({ baseUrl, agent: agent3, instance: instance4 }),
342849
+ agent: agent3,
342850
+ instance: instance4,
342851
+ provider
342852
+ };
342853
+ }
342854
+
342855
+ // ../api/src/routes/v2/a2a.ts
342856
+ function baseUrlFromRequest(url) {
342857
+ return `${url.protocol}//${url.host}`;
342858
+ }
342859
+ var a2aRoutes, listQuerySchema, agentParamSchema;
342860
+ var init_a2a = __esm(() => {
342861
+ init_dist6();
342862
+ init_dist2();
342863
+ init_zod();
342864
+ a2aRoutes = new Hono2;
342865
+ listQuerySchema = exports_external.object({
342866
+ includeUnconfigured: exports_external.coerce.boolean().optional().default(false)
342867
+ });
342868
+ agentParamSchema = exports_external.object({
342869
+ agentId: exports_external.string().uuid()
342870
+ });
342871
+ a2aRoutes.get("/agents", zValidator("query", listQuerySchema), async (c) => {
342872
+ const query = c.req.valid("query");
342873
+ const url = new URL(c.req.url);
342874
+ const items = await listA2ADiscoverableAgents({
342875
+ services: c.get("services"),
342876
+ baseUrl: baseUrlFromRequest(url),
342877
+ includeUnconfigured: query.includeUnconfigured
342878
+ });
342879
+ return c.json({ items });
342880
+ });
342881
+ a2aRoutes.get("/agents/:agentId/card", zValidator("param", agentParamSchema), async (c) => {
342882
+ const { agentId } = c.req.valid("param");
342883
+ const url = new URL(c.req.url);
342884
+ const resolved = await resolveA2AAgentCard({
342885
+ services: c.get("services"),
342886
+ baseUrl: baseUrlFromRequest(url),
342887
+ agentId
342888
+ });
342889
+ if (!resolved) {
342890
+ return c.json({ error: { code: "A2A_AGENT_NOT_CONFIGURED", message: "Agent has no active A2A instance" } }, 404);
342891
+ }
342892
+ return c.json({ data: resolved.card });
342893
+ });
342894
+ });
342895
+
342563
342896
  // ../api/src/schemas/date-query.ts
342564
342897
  function parseDateOrIssue(paramName, v2, ctx) {
342565
342898
  const parsed = new Date(v2);
@@ -342594,7 +342927,7 @@ var init_date_query = __esm(() => {
342594
342927
  });
342595
342928
 
342596
342929
  // ../api/src/routes/v2/access.ts
342597
- var accessRoutes, listQuerySchema, createRuleSchema, updateRuleSchema, checkAccessSchema;
342930
+ var accessRoutes, listQuerySchema2, createRuleSchema, updateRuleSchema, checkAccessSchema;
342598
342931
  var init_access3 = __esm(() => {
342599
342932
  init_dist6();
342600
342933
  init_src();
@@ -342602,7 +342935,7 @@ var init_access3 = __esm(() => {
342602
342935
  init_zod();
342603
342936
  init_date_query();
342604
342937
  accessRoutes = new Hono2;
342605
- listQuerySchema = exports_external.object({
342938
+ listQuerySchema2 = exports_external.object({
342606
342939
  instanceId: exports_external.string().uuid().optional(),
342607
342940
  type: RuleTypeSchema.optional()
342608
342941
  });
@@ -342625,13 +342958,13 @@ var init_access3 = __esm(() => {
342625
342958
  platformUserId: exports_external.string().describe("Platform user ID to check"),
342626
342959
  channel: exports_external.string().describe("Channel type")
342627
342960
  });
342628
- accessRoutes.get("/", zValidator("query", listQuerySchema), async (c) => {
342961
+ accessRoutes.get("/", zValidator("query", listQuerySchema2), async (c) => {
342629
342962
  const { instanceId, type } = c.req.valid("query");
342630
342963
  const services = c.get("services");
342631
342964
  const rules = await services.access.list({ instanceId, type });
342632
342965
  return c.json({ items: rules });
342633
342966
  });
342634
- accessRoutes.get("/rules", zValidator("query", listQuerySchema), async (c) => {
342967
+ accessRoutes.get("/rules", zValidator("query", listQuerySchema2), async (c) => {
342635
342968
  const { instanceId, type } = c.req.valid("query");
342636
342969
  const services = c.get("services");
342637
342970
  const rules = await services.access.list({ instanceId, type });
@@ -343019,7 +343352,7 @@ var init_agent_state3 = __esm(() => {
343019
343352
  });
343020
343353
 
343021
343354
  // ../api/src/routes/v2/agent-tasks.ts
343022
- var agentTasksRoutes, agentTaskStatusValues, idParamSchema, listQuerySchema2, createTaskSchema, updateTaskSchema;
343355
+ var agentTasksRoutes, agentTaskStatusValues, idParamSchema, listQuerySchema3, createTaskSchema, updateTaskSchema;
343023
343356
  var init_agent_tasks2 = __esm(() => {
343024
343357
  init_dist6();
343025
343358
  init_dist2();
@@ -343029,7 +343362,7 @@ var init_agent_tasks2 = __esm(() => {
343029
343362
  idParamSchema = exports_external.object({
343030
343363
  id: exports_external.string().uuid()
343031
343364
  });
343032
- listQuerySchema2 = exports_external.object({
343365
+ listQuerySchema3 = exports_external.object({
343033
343366
  agentId: exports_external.string().uuid().optional(),
343034
343367
  chatId: exports_external.string().uuid().optional(),
343035
343368
  conversationId: exports_external.string().uuid().optional(),
@@ -343062,7 +343395,7 @@ var init_agent_tasks2 = __esm(() => {
343062
343395
  result: exports_external.record(exports_external.string(), exports_external.unknown()).nullable().optional(),
343063
343396
  error: exports_external.string().nullable().optional()
343064
343397
  });
343065
- agentTasksRoutes.get("/", zValidator("query", listQuerySchema2), async (c) => {
343398
+ agentTasksRoutes.get("/", zValidator("query", listQuerySchema3), async (c) => {
343066
343399
  const query = c.req.valid("query");
343067
343400
  const services = c.get("services");
343068
343401
  const result = await services.agentTasks.list(query);
@@ -343112,7 +343445,7 @@ var init_agent_tasks2 = __esm(() => {
343112
343445
  });
343113
343446
 
343114
343447
  // ../api/src/routes/v2/agents.ts
343115
- var agentsRoutes, idParamSchema2, listQuerySchema3, createAgentSchema, updateAgentSchema;
343448
+ var agentsRoutes, idParamSchema2, listQuerySchema4, createAgentSchema, updateAgentSchema;
343116
343449
  var init_agents3 = __esm(() => {
343117
343450
  init_dist6();
343118
343451
  init_src();
@@ -343122,7 +343455,7 @@ var init_agents3 = __esm(() => {
343122
343455
  idParamSchema2 = exports_external.object({
343123
343456
  id: exports_external.string().uuid()
343124
343457
  });
343125
- listQuerySchema3 = exports_external.object({
343458
+ listQuerySchema4 = exports_external.object({
343126
343459
  ownerId: exports_external.string().uuid().optional(),
343127
343460
  provider: exports_external.string().optional(),
343128
343461
  isActive: exports_external.coerce.boolean().optional(),
@@ -343139,10 +343472,11 @@ var init_agents3 = __esm(() => {
343139
343472
  configPath: exports_external.string().optional(),
343140
343473
  isInternal: exports_external.boolean().default(false),
343141
343474
  isActive: exports_external.boolean().default(true),
343142
- metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
343475
+ metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
343476
+ agentCard: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
343143
343477
  });
343144
343478
  updateAgentSchema = createAgentSchema.partial();
343145
- agentsRoutes.get("/", zValidator("query", listQuerySchema3), async (c) => {
343479
+ agentsRoutes.get("/", zValidator("query", listQuerySchema4), async (c) => {
343146
343480
  const { ownerId, provider, isActive, limit: limit2 } = c.req.valid("query");
343147
343481
  const services = c.get("services");
343148
343482
  const items = await services.agents.list({ ownerId, provider, isActive, limit: limit2 });
@@ -343228,7 +343562,7 @@ var init_auth3 = __esm(() => {
343228
343562
  });
343229
343563
 
343230
343564
  // ../api/src/routes/v2/automations.ts
343231
- var automationsRoutes, conditionSchema, webhookActionSchema, sendMessageActionSchema, emitEventActionSchema, logActionSchema, callAgentActionSchema, actionSchema, debounceSchema, createAutomationSchema, updateAutomationSchema, listQuerySchema4, testAutomationSchema, logsQuerySchema;
343565
+ var automationsRoutes, conditionSchema, webhookActionSchema, sendMessageActionSchema, emitEventActionSchema, logActionSchema, callAgentActionSchema, actionSchema, debounceSchema, createAutomationSchema, updateAutomationSchema, listQuerySchema5, testAutomationSchema, logsQuerySchema;
343232
343566
  var init_automations4 = __esm(() => {
343233
343567
  init_dist6();
343234
343568
  init_dist2();
@@ -343323,7 +343657,7 @@ var init_automations4 = __esm(() => {
343323
343657
  priority: exports_external.number().int().default(0).describe("Priority (higher runs first)")
343324
343658
  });
343325
343659
  updateAutomationSchema = createAutomationSchema.partial();
343326
- listQuerySchema4 = exports_external.object({
343660
+ listQuerySchema5 = exports_external.object({
343327
343661
  enabled: exports_external.coerce.boolean().optional()
343328
343662
  });
343329
343663
  testAutomationSchema = exports_external.object({
@@ -343339,7 +343673,7 @@ var init_automations4 = __esm(() => {
343339
343673
  eventType: exports_external.string().optional(),
343340
343674
  automationId: exports_external.string().uuid().optional()
343341
343675
  });
343342
- automationsRoutes.get("/", zValidator("query", listQuerySchema4), async (c) => {
343676
+ automationsRoutes.get("/", zValidator("query", listQuerySchema5), async (c) => {
343343
343677
  const { enabled } = c.req.valid("query");
343344
343678
  const services = c.get("services");
343345
343679
  const items = await services.automations.list({ enabled });
@@ -343429,7 +343763,7 @@ var init_automations4 = __esm(() => {
343429
343763
  });
343430
343764
 
343431
343765
  // ../api/src/routes/v2/batch-jobs.ts
343432
- var batchJobsRoutes, jobTypeSchema, contentTypeSchema, createBatchJobSchema, estimateSchema, listQuerySchema5, idParamSchema3;
343766
+ var batchJobsRoutes, jobTypeSchema, contentTypeSchema, createBatchJobSchema, estimateSchema, listQuerySchema6, idParamSchema3;
343433
343767
  var init_batch_jobs2 = __esm(() => {
343434
343768
  init_dist6();
343435
343769
  init_dist2();
@@ -343456,7 +343790,7 @@ var init_batch_jobs2 = __esm(() => {
343456
343790
  limit: exports_external.number().int().positive().optional(),
343457
343791
  contentTypes: exports_external.array(contentTypeSchema).optional()
343458
343792
  });
343459
- listQuerySchema5 = exports_external.object({
343793
+ listQuerySchema6 = exports_external.object({
343460
343794
  instanceId: exports_external.string().uuid().optional(),
343461
343795
  status: exports_external.string().optional().transform((v2) => v2?.split(",")),
343462
343796
  jobType: exports_external.string().optional().transform((v2) => v2?.split(",")),
@@ -343488,7 +343822,7 @@ var init_batch_jobs2 = __esm(() => {
343488
343822
  });
343489
343823
  return c.json({ data: job }, 201);
343490
343824
  });
343491
- batchJobsRoutes.get("/", zValidator("query", listQuerySchema5), async (c) => {
343825
+ batchJobsRoutes.get("/", zValidator("query", listQuerySchema6), async (c) => {
343492
343826
  const { instanceId, status, jobType, limit: limit2, cursor } = c.req.valid("query");
343493
343827
  const services = c.get("services");
343494
343828
  const result = await services.batchJobs.list({
@@ -343826,7 +344160,7 @@ function resolveContactName2(chat2, contactNames) {
343826
344160
  }
343827
344161
  return;
343828
344162
  }
343829
- var chatsRoutes, UUID_REGEX, ChatTypeSchema, listQuerySchema6, createChatSchema, updateChatSchema, addParticipantSchema, updateParticipantRoleSchema, chatChannelActionSchema, muteActionSchema, labelBodySchema, listMessagesQuerySchema, markChatReadSchema, disappearingSchema, DISAPPEARING_DURATIONS, syncNamesSchema, clearSessionSchema;
344163
+ var chatsRoutes, UUID_REGEX, ChatTypeSchema, listQuerySchema7, createChatSchema, updateChatSchema, addParticipantSchema, updateParticipantRoleSchema, chatChannelActionSchema, muteActionSchema, labelBodySchema, listMessagesQuerySchema, markChatReadSchema, disappearingSchema, DISAPPEARING_DURATIONS, syncNamesSchema, clearSessionSchema;
343830
344164
  var init_chats2 = __esm(() => {
343831
344165
  init_dist6();
343832
344166
  init_src();
@@ -343851,7 +344185,7 @@ var init_chats2 = __esm(() => {
343851
344185
  "announcement",
343852
344186
  "stage"
343853
344187
  ]);
343854
- listQuerySchema6 = exports_external.object({
344188
+ listQuerySchema7 = exports_external.object({
343855
344189
  instanceId: exports_external.string().uuid().optional(),
343856
344190
  channel: exports_external.string().optional().transform((v2) => v2?.split(",")),
343857
344191
  chatType: exports_external.string().optional().transform((v2) => v2?.split(",")),
@@ -343900,7 +344234,7 @@ var init_chats2 = __esm(() => {
343900
344234
  updateParticipantRoleSchema = exports_external.object({
343901
344235
  role: exports_external.string().min(1)
343902
344236
  });
343903
- chatsRoutes.get("/", zValidator("query", listQuerySchema6), async (c) => {
344237
+ chatsRoutes.get("/", zValidator("query", listQuerySchema7), async (c) => {
343904
344238
  const query = c.req.valid("query");
343905
344239
  const services = c.get("services");
343906
344240
  const apiKey = c.get("apiKey");
@@ -344511,13 +344845,13 @@ var init_context5 = __esm(() => {
344511
344845
  });
344512
344846
 
344513
344847
  // ../api/src/routes/v2/conversations.ts
344514
- var conversationsRoutes, listQuerySchema7, idParamSchema4, createConversationSchema, updateConversationSchema;
344848
+ var conversationsRoutes, listQuerySchema8, idParamSchema4, createConversationSchema, updateConversationSchema;
344515
344849
  var init_conversations3 = __esm(() => {
344516
344850
  init_dist6();
344517
344851
  init_dist2();
344518
344852
  init_zod();
344519
344853
  conversationsRoutes = new Hono2;
344520
- listQuerySchema7 = exports_external.object({
344854
+ listQuerySchema8 = exports_external.object({
344521
344855
  limit: exports_external.coerce.number().int().positive().max(200).optional().default(50)
344522
344856
  });
344523
344857
  idParamSchema4 = exports_external.object({
@@ -344529,7 +344863,7 @@ var init_conversations3 = __esm(() => {
344529
344863
  state: exports_external.record(exports_external.string(), exports_external.unknown()).nullable().optional()
344530
344864
  });
344531
344865
  updateConversationSchema = createConversationSchema.partial();
344532
- conversationsRoutes.get("/", zValidator("query", listQuerySchema7), async (c) => {
344866
+ conversationsRoutes.get("/", zValidator("query", listQuerySchema8), async (c) => {
344533
344867
  const { limit: limit2 } = c.req.valid("query");
344534
344868
  const services = c.get("services");
344535
344869
  const items = await services.conversations.list({ limit: limit2 });
@@ -344570,14 +344904,14 @@ var init_conversations3 = __esm(() => {
344570
344904
  });
344571
344905
 
344572
344906
  // ../api/src/routes/v2/dead-letters.ts
344573
- var deadLettersRoutes, listQuerySchema8, resolveBodySchema;
344907
+ var deadLettersRoutes, listQuerySchema9, resolveBodySchema;
344574
344908
  var init_dead_letters3 = __esm(() => {
344575
344909
  init_dist6();
344576
344910
  init_dist2();
344577
344911
  init_zod();
344578
344912
  init_date_query();
344579
344913
  deadLettersRoutes = new Hono2;
344580
- listQuerySchema8 = exports_external.object({
344914
+ listQuerySchema9 = exports_external.object({
344581
344915
  status: exports_external.string().optional().transform((v2) => v2?.split(",")),
344582
344916
  eventType: exports_external.string().optional().transform((v2) => v2?.split(",") ?? undefined),
344583
344917
  since: optionalDateParam("since"),
@@ -344588,7 +344922,7 @@ var init_dead_letters3 = __esm(() => {
344588
344922
  resolveBodySchema = exports_external.object({
344589
344923
  note: exports_external.string().min(1).max(500)
344590
344924
  });
344591
- deadLettersRoutes.get("/", zValidator("query", listQuerySchema8), async (c) => {
344925
+ deadLettersRoutes.get("/", zValidator("query", listQuerySchema9), async (c) => {
344592
344926
  const query = c.req.valid("query");
344593
344927
  const services = c.get("services");
344594
344928
  const result = await services.deadLetters.list(query);
@@ -344731,7 +345065,7 @@ function applyInstanceAccess(query, apiKey) {
344731
345065
  }
344732
345066
  return { ...query, instanceIds: apiKey.instanceIds };
344733
345067
  }
344734
- var eventsRoutes, listQuerySchema9, searchBodySchema, analyticsQuerySchema, timelineQuerySchema;
345068
+ var eventsRoutes, listQuerySchema10, searchBodySchema, analyticsQuerySchema, timelineQuerySchema;
344735
345069
  var init_events4 = __esm(() => {
344736
345070
  init_dist6();
344737
345071
  init_src();
@@ -344740,7 +345074,7 @@ var init_events4 = __esm(() => {
344740
345074
  init_date_query();
344741
345075
  init_api_keys();
344742
345076
  eventsRoutes = new Hono2;
344743
- listQuerySchema9 = exports_external.object({
345077
+ listQuerySchema10 = exports_external.object({
344744
345078
  channel: exports_external.string().optional().transform((v2) => v2?.split(",")),
344745
345079
  instanceId: exports_external.string().uuid().optional(),
344746
345080
  personId: exports_external.string().uuid().optional(),
@@ -344782,7 +345116,7 @@ var init_events4 = __esm(() => {
344782
345116
  limit: exports_external.coerce.number().int().min(1).max(100).default(50),
344783
345117
  cursor: exports_external.string().optional()
344784
345118
  });
344785
- eventsRoutes.get("/", zValidator("query", listQuerySchema9), async (c) => {
345119
+ eventsRoutes.get("/", zValidator("query", listQuerySchema10), async (c) => {
344786
345120
  const query = c.req.valid("query");
344787
345121
  const services = c.get("services");
344788
345122
  const apiKey = c.get("apiKey");
@@ -344998,7 +345332,7 @@ var init_follow_up3 = __esm(() => {
344998
345332
  });
344999
345333
 
345000
345334
  // ../api/src/routes/v2/handoffs.ts
345001
- var handoffsRoutes, listQuerySchema10;
345335
+ var handoffsRoutes, listQuerySchema11;
345002
345336
  var init_handoffs = __esm(() => {
345003
345337
  init_dist6();
345004
345338
  init_src5();
@@ -345006,7 +345340,7 @@ var init_handoffs = __esm(() => {
345006
345340
  init_dist2();
345007
345341
  init_zod();
345008
345342
  handoffsRoutes = new Hono2;
345009
- listQuerySchema10 = exports_external.object({
345343
+ listQuerySchema11 = exports_external.object({
345010
345344
  instanceId: exports_external.string().uuid().optional(),
345011
345345
  chatId: exports_external.string().optional(),
345012
345346
  since: exports_external.string().datetime().optional(),
@@ -345014,7 +345348,7 @@ var init_handoffs = __esm(() => {
345014
345348
  limit: exports_external.coerce.number().int().min(1).max(200).default(50),
345015
345349
  offset: exports_external.coerce.number().int().min(0).default(0)
345016
345350
  });
345017
- handoffsRoutes.get("/", zValidator("query", listQuerySchema10), async (c) => {
345351
+ handoffsRoutes.get("/", zValidator("query", listQuerySchema11), async (c) => {
345018
345352
  const { instanceId, chatId, since, until, limit: limit2, offset } = c.req.valid("query");
345019
345353
  const db2 = c.get("db");
345020
345354
  const conditions3 = [];
@@ -346665,7 +346999,7 @@ function getCacheKey(instanceId, guildId) {
346665
346999
  function invalidateGuildCache(instanceId, guildId) {
346666
347000
  guildConfigCache.delete(getCacheKey(instanceId, guildId));
346667
347001
  }
346668
- var log103, instancesRoutes, instanceAccess2, listQuerySchema11, agentReplyFilterSchema, createInstanceSchema, updateInstanceSchema, DEFAULT_AGENT_REPLY_FILTER, SENSITIVE_INSTANCE_FIELDS, pairingCodeSchema, connectInstanceSchema, syncRequestSchema, listContactsQuerySchema, listGroupsQuerySchema, checkNumberSchema, updateBioSchema, blockContactSchema, resyncSchema, replaySchema, pairingActionSchema, guildConfigOverrideSchema, guildConfigCache, GUILD_CONFIG_TTL, presenceSchema;
347002
+ var log103, instancesRoutes, instanceAccess2, listQuerySchema12, agentReplyFilterSchema, createInstanceSchema, updateInstanceSchema, DEFAULT_AGENT_REPLY_FILTER, SENSITIVE_INSTANCE_FIELDS, pairingCodeSchema, connectInstanceSchema, syncRequestSchema, listContactsQuerySchema, listGroupsQuerySchema, checkNumberSchema, updateBioSchema, blockContactSchema, resyncSchema, replaySchema, pairingActionSchema, guildConfigOverrideSchema, guildConfigCache, GUILD_CONFIG_TTL, presenceSchema;
346669
347003
  var init_instances3 = __esm(() => {
346670
347004
  init_dist6();
346671
347005
  init_src();
@@ -346680,7 +347014,7 @@ var init_instances3 = __esm(() => {
346680
347014
  log103 = createLogger("api:instances");
346681
347015
  instancesRoutes = new Hono2;
346682
347016
  instanceAccess2 = requireInstanceAccess((c) => c.req.param("id") ?? "");
346683
- listQuerySchema11 = exports_external.object({
347017
+ listQuerySchema12 = exports_external.object({
346684
347018
  channel: exports_external.string().optional().transform((v2) => v2?.split(",")),
346685
347019
  status: exports_external.string().optional().transform((v2) => v2?.split(",")),
346686
347020
  limit: exports_external.coerce.number().int().min(1).max(100).default(50),
@@ -346799,7 +347133,7 @@ var init_instances3 = __esm(() => {
346799
347133
  "webhookVerifyToken",
346800
347134
  "twilioAuthToken"
346801
347135
  ];
346802
- instancesRoutes.get("/", zValidator("query", listQuerySchema11), async (c) => {
347136
+ instancesRoutes.get("/", zValidator("query", listQuerySchema12), async (c) => {
346803
347137
  const { channel: channel5, status, limit: limit2, cursor } = c.req.valid("query");
346804
347138
  const services = c.get("services");
346805
347139
  const apiKey = c.get("apiKey");
@@ -346840,7 +347174,13 @@ var init_instances3 = __esm(() => {
346840
347174
  },
346841
347175
  { id: "discord", name: "Discord", description: "Discord bot integration", loaded: false },
346842
347176
  { id: "slack", name: "Slack", description: "Slack bot integration", loaded: false },
346843
- { id: "telegram", name: "Telegram", description: "Telegram bot integration", loaded: false }
347177
+ { id: "telegram", name: "Telegram", description: "Telegram bot integration", loaded: false },
347178
+ {
347179
+ id: "a2a",
347180
+ name: "A2A Protocol Server",
347181
+ description: "Agent-to-Agent protocol endpoint",
347182
+ loaded: false
347183
+ }
346844
347184
  ];
346845
347185
  const unloadedChannels = staticChannels.filter((ch) => !loadedIds.has(ch.id));
346846
347186
  return c.json({
@@ -348579,7 +348919,7 @@ async function handleLegacyCreate(c, data, services) {
348579
348919
  });
348580
348920
  return c.json({ data: { ...result.key, plainTextKey: result.plainTextKey } }, 201);
348581
348921
  }
348582
- var keysRoutes, NON_ADMIN_PROFILES, profileOverridesSchema, createKeySchema, updateKeySchema, revokeKeySchema, listQuerySchema12, auditQuerySchema;
348922
+ var keysRoutes, NON_ADMIN_PROFILES, profileOverridesSchema, createKeySchema, updateKeySchema, revokeKeySchema, listQuerySchema13, auditQuerySchema;
348583
348923
  var init_keys = __esm(() => {
348584
348924
  init_dist6();
348585
348925
  init_dist2();
@@ -348621,7 +348961,7 @@ var init_keys = __esm(() => {
348621
348961
  reason: exports_external.string().optional().describe("Reason for revocation"),
348622
348962
  revokedBy: exports_external.string().optional().describe("Who revoked the key")
348623
348963
  });
348624
- listQuerySchema12 = exports_external.object({
348964
+ listQuerySchema13 = exports_external.object({
348625
348965
  status: exports_external.enum(["active", "revoked", "expired"]).optional().describe("Filter by status"),
348626
348966
  limit: exports_external.coerce.number().int().min(1).max(100).default(50).describe("Max results")
348627
348967
  });
@@ -348652,7 +348992,7 @@ var init_keys = __esm(() => {
348652
348992
  }
348653
348993
  return handleLegacyCreate(c, data, services);
348654
348994
  });
348655
- keysRoutes.get("/", zValidator("query", listQuerySchema12), async (c) => {
348995
+ keysRoutes.get("/", zValidator("query", listQuerySchema13), async (c) => {
348656
348996
  const { status, limit: limit2 } = c.req.valid("query");
348657
348997
  const services = c.get("services");
348658
348998
  let items = await services.apiKeys.list();
@@ -349294,7 +349634,15 @@ var init__close_contact_config = __esm(() => {
349294
349634
 
349295
349635
  // ../api/src/routes/v2/messages.ts
349296
349636
  import { existsSync as existsSync7 } from "fs";
349297
- import { join as join22 } from "path";
349637
+ import { extname as extname3, join as join22 } from "path";
349638
+ function inferMediaMimeType(type, filename) {
349639
+ if (filename) {
349640
+ const fromExtension = MIME_BY_EXTENSION[extname3(filename).toLowerCase()];
349641
+ if (fromExtension)
349642
+ return fromExtension;
349643
+ }
349644
+ return DEFAULT_MIME_BY_MEDIA_TYPE[type];
349645
+ }
349298
349646
  function isUUID(value) {
349299
349647
  return UUID_REGEX2.test(value);
349300
349648
  }
@@ -349452,7 +349800,7 @@ async function verifyMessageInstanceOwnership(services, message2, instanceId) {
349452
349800
  });
349453
349801
  }
349454
349802
  }
349455
- var log105, mediaDownloadLog, messagesRoutes, UUID_REGEX2, MessageSourceSchema, MessageTypeSchema, MessageStatusSchema, DeliveryStatusSchema, listQuerySchema13, createMessageSchema, updateMessageSchema, recordEditSchema, addReactionSchema, removeReactionSchema, updateDeliveryStatusSchema, MentionSchema, sendTextSchema, sendMediaSchema, sendReactionSchema, sendStickerSchema, sendContactSchema, sendLocationSchema, sendHandoffSchema, sendCloseContactSchema, messageRefSchema, _mediaStorageForDownload = null, sendTtsSchema, forwardMessageSchema, sendPresenceSchema, markMessageReadSchema, markBatchReadSchema, sendPollSchema, sendEmbedSchema, editMessageChannelSchema, deleteMessageChannelSchema, starMessageSchema;
349803
+ var log105, mediaDownloadLog, messagesRoutes, MIME_BY_EXTENSION, DEFAULT_MIME_BY_MEDIA_TYPE, UUID_REGEX2, MessageSourceSchema, MessageTypeSchema, MessageStatusSchema, DeliveryStatusSchema, listQuerySchema14, createMessageSchema, updateMessageSchema, recordEditSchema, addReactionSchema, removeReactionSchema, updateDeliveryStatusSchema, MentionSchema, sendTextSchema, sendMediaSchema, sendReactionSchema, sendStickerSchema, sendContactSchema, sendLocationSchema, sendHandoffSchema, sendCloseContactSchema, messageRefSchema, _mediaStorageForDownload = null, sendTtsSchema, forwardMessageSchema, sendPresenceSchema, markMessageReadSchema, markBatchReadSchema, sendPollSchema, sendEmbedSchema, editMessageChannelSchema, deleteMessageChannelSchema, starMessageSchema;
349456
349804
  var init_messages5 = __esm(() => {
349457
349805
  init_dist6();
349458
349806
  init_src2();
@@ -349470,6 +349818,29 @@ var init_messages5 = __esm(() => {
349470
349818
  log105 = createLogger("routes:messages");
349471
349819
  mediaDownloadLog = createLogger("routes:messages:media-download");
349472
349820
  messagesRoutes = new Hono2;
349821
+ MIME_BY_EXTENSION = {
349822
+ ".jpg": "image/jpeg",
349823
+ ".jpeg": "image/jpeg",
349824
+ ".png": "image/png",
349825
+ ".gif": "image/gif",
349826
+ ".webp": "image/webp",
349827
+ ".mp3": "audio/mpeg",
349828
+ ".ogg": "audio/ogg",
349829
+ ".opus": "audio/opus",
349830
+ ".wav": "audio/wav",
349831
+ ".m4a": "audio/mp4",
349832
+ ".mp4": "video/mp4",
349833
+ ".webm": "video/webm",
349834
+ ".mov": "video/quicktime",
349835
+ ".avi": "video/x-msvideo",
349836
+ ".pdf": "application/pdf"
349837
+ };
349838
+ DEFAULT_MIME_BY_MEDIA_TYPE = {
349839
+ image: "image/jpeg",
349840
+ audio: "audio/ogg",
349841
+ video: "video/mp4",
349842
+ document: "application/octet-stream"
349843
+ };
349473
349844
  UUID_REGEX2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
349474
349845
  MessageSourceSchema = exports_external.enum(["realtime", "sync", "api", "import"]);
349475
349846
  MessageTypeSchema = exports_external.enum([
@@ -349486,7 +349857,7 @@ var init_messages5 = __esm(() => {
349486
349857
  ]);
349487
349858
  MessageStatusSchema = exports_external.enum(["active", "edited", "deleted", "expired"]);
349488
349859
  DeliveryStatusSchema = exports_external.enum(["pending", "sent", "delivered", "read", "failed"]);
349489
- listQuerySchema13 = exports_external.object({
349860
+ listQuerySchema14 = exports_external.object({
349490
349861
  chatId: exports_external.string().uuid().optional(),
349491
349862
  source: exports_external.string().optional().transform((v2) => v2?.split(",")),
349492
349863
  messageType: exports_external.string().optional().transform((v2) => v2?.split(",")),
@@ -349637,7 +350008,7 @@ var init_messages5 = __esm(() => {
349637
350008
  reason: exports_external.string().optional().describe("Free-text rationale persisted in close_contact_logs"),
349638
350009
  closeFields: exports_external.record(exports_external.unknown()).optional().describe("Structured BI/CRM payload \u2014 forwarded to Gupshup native send when supported")
349639
350010
  });
349640
- messagesRoutes.get("/", zValidator("query", listQuerySchema13), async (c) => {
350011
+ messagesRoutes.get("/", zValidator("query", listQuerySchema14), async (c) => {
349641
350012
  const query = c.req.valid("query");
349642
350013
  const services = c.get("services");
349643
350014
  const apiKey = c.get("apiKey");
@@ -349944,6 +350315,7 @@ var init_messages5 = __esm(() => {
349944
350315
  });
349945
350316
  }
349946
350317
  const resolvedTo = await resolveRecipient(data.to, instance4.channel, services);
350318
+ const mediaMimeType = data.mimeType ?? inferMediaMimeType(data.type, data.filename);
349947
350319
  const outgoingMessage = {
349948
350320
  to: resolvedTo,
349949
350321
  threadId: data.threadId,
@@ -349952,7 +350324,7 @@ var init_messages5 = __esm(() => {
349952
350324
  mediaUrl: data.url,
349953
350325
  caption: data.caption,
349954
350326
  filename: data.filename,
349955
- mimeType: data.mimeType
350327
+ mimeType: mediaMimeType
349956
350328
  },
349957
350329
  metadata: {
349958
350330
  base64: data.base64,
@@ -351229,14 +351601,14 @@ var init_payloads2 = __esm(() => {
351229
351601
  });
351230
351602
 
351231
351603
  // ../api/src/routes/v2/persons.ts
351232
- var personsRoutes, listQuerySchema14, timelineQuerySchema2, updatePersonSchema, linkIdentitiesSchema, unlinkIdentitySchema, mergePersonsSchema;
351604
+ var personsRoutes, listQuerySchema15, timelineQuerySchema2, updatePersonSchema, linkIdentitiesSchema, unlinkIdentitySchema, mergePersonsSchema;
351233
351605
  var init_persons3 = __esm(() => {
351234
351606
  init_dist6();
351235
351607
  init_dist2();
351236
351608
  init_zod();
351237
351609
  init_date_query();
351238
351610
  personsRoutes = new Hono2;
351239
- listQuerySchema14 = exports_external.object({
351611
+ listQuerySchema15 = exports_external.object({
351240
351612
  search: exports_external.string().min(1).optional().describe("Search term (name, email, or phone)"),
351241
351613
  limit: exports_external.coerce.number().int().min(1).max(100).default(20),
351242
351614
  cursor: exports_external.string().optional().describe("Cursor for pagination")
@@ -351268,7 +351640,7 @@ var init_persons3 = __esm(() => {
351268
351640
  targetPersonId: exports_external.string().uuid().describe("Person to merge into (will be kept)"),
351269
351641
  reason: exports_external.string().optional().describe("Reason for merge")
351270
351642
  });
351271
- personsRoutes.get("/", zValidator("query", listQuerySchema14), async (c) => {
351643
+ personsRoutes.get("/", zValidator("query", listQuerySchema15), async (c) => {
351272
351644
  const { search, limit: limit2, cursor } = c.req.valid("query");
351273
351645
  const services = c.get("services");
351274
351646
  if (search) {
@@ -351410,7 +351782,7 @@ function applySchemaDefaults(data) {
351410
351782
  supportsImages: data.supportsImages ?? data.schema === "claude-code"
351411
351783
  };
351412
351784
  }
351413
- var providersRoutes, SENSITIVE_KEY_PATTERN, listQuerySchema15, providerBaseSchema, createProviderSchema, updateProviderSchema;
351785
+ var providersRoutes, SENSITIVE_KEY_PATTERN, listQuerySchema16, providerBaseSchema, createProviderSchema, updateProviderSchema;
351414
351786
  var init_providers4 = __esm(() => {
351415
351787
  init_dist6();
351416
351788
  init_src();
@@ -351419,7 +351791,7 @@ var init_providers4 = __esm(() => {
351419
351791
  init_agent_dispatcher();
351420
351792
  providersRoutes = new Hono2;
351421
351793
  SENSITIVE_KEY_PATTERN = /private|secret|password|token|apikey|api_key/i;
351422
- listQuerySchema15 = exports_external.object({
351794
+ listQuerySchema16 = exports_external.object({
351423
351795
  active: exports_external.coerce.boolean().optional()
351424
351796
  });
351425
351797
  providerBaseSchema = exports_external.object({
@@ -351439,7 +351811,7 @@ var init_providers4 = __esm(() => {
351439
351811
  });
351440
351812
  createProviderSchema = providerBaseSchema.transform(applySchemaDefaults);
351441
351813
  updateProviderSchema = providerBaseSchema.partial().transform(applySchemaDefaults);
351442
- providersRoutes.get("/", zValidator("query", listQuerySchema15), async (c) => {
351814
+ providersRoutes.get("/", zValidator("query", listQuerySchema16), async (c) => {
351443
351815
  const { active } = c.req.valid("query");
351444
351816
  const services = c.get("services");
351445
351817
  const providers2 = await services.providers.list({ active });
@@ -351569,14 +351941,14 @@ var init_providers4 = __esm(() => {
351569
351941
  });
351570
351942
 
351571
351943
  // ../api/src/routes/v2/settings.ts
351572
- var settingsRoutes, listQuerySchema16, setSettingSchema, bulkUpdateSchema, historyQuerySchema;
351944
+ var settingsRoutes, listQuerySchema17, setSettingSchema, bulkUpdateSchema, historyQuerySchema;
351573
351945
  var init_settings3 = __esm(() => {
351574
351946
  init_dist6();
351575
351947
  init_dist2();
351576
351948
  init_zod();
351577
351949
  init_date_query();
351578
351950
  settingsRoutes = new Hono2;
351579
- listQuerySchema16 = exports_external.object({
351951
+ listQuerySchema17 = exports_external.object({
351580
351952
  category: exports_external.string().optional()
351581
351953
  });
351582
351954
  setSettingSchema = exports_external.object({
@@ -351591,7 +351963,7 @@ var init_settings3 = __esm(() => {
351591
351963
  limit: exports_external.coerce.number().int().min(1).max(100).default(50),
351592
351964
  since: optionalDateParam("since")
351593
351965
  });
351594
- settingsRoutes.get("/", zValidator("query", listQuerySchema16), async (c) => {
351966
+ settingsRoutes.get("/", zValidator("query", listQuerySchema17), async (c) => {
351595
351967
  const { category } = c.req.valid("query");
351596
351968
  const services = c.get("services");
351597
351969
  const settings = await services.settings.list(category);
@@ -351762,7 +352134,7 @@ async function resolveOpenTurn(services, keyId, turnId, headerInstanceId, header
351762
352134
  }
351763
352135
  return null;
351764
352136
  }
351765
- var turnsRoutes, closeTurnSchema, listQuerySchema17, adminForceCloseSchema, bulkCloseSchema;
352137
+ var turnsRoutes, closeTurnSchema, listQuerySchema18, adminForceCloseSchema, bulkCloseSchema;
351766
352138
  var init_turns2 = __esm(() => {
351767
352139
  init_dist6();
351768
352140
  init_dist2();
@@ -351825,7 +352197,7 @@ var init_turns2 = __esm(() => {
351825
352197
  }
351826
352198
  });
351827
352199
  });
351828
- listQuerySchema17 = exports_external.object({
352200
+ listQuerySchema18 = exports_external.object({
351829
352201
  status: exports_external.enum(["open", "done", "timeout"]).optional(),
351830
352202
  instanceId: exports_external.string().uuid().optional(),
351831
352203
  chatId: exports_external.string().optional(),
@@ -351840,7 +352212,7 @@ var init_turns2 = __esm(() => {
351840
352212
  confirm: exports_external.boolean(),
351841
352213
  reason: exports_external.string().optional()
351842
352214
  });
351843
- turnsRoutes.get("/", zValidator("query", listQuerySchema17), async (c) => {
352215
+ turnsRoutes.get("/", zValidator("query", listQuerySchema18), async (c) => {
351844
352216
  const denied = requireAdmin(c);
351845
352217
  if (denied)
351846
352218
  return denied;
@@ -352071,7 +352443,7 @@ var init_voice2 = __esm(() => {
352071
352443
  });
352072
352444
 
352073
352445
  // ../api/src/routes/v2/webhooks.ts
352074
- var webhooksRoutes, createWebhookSourceSchema, updateWebhookSourceSchema, listQuerySchema18, triggerEventSchema;
352446
+ var webhooksRoutes, createWebhookSourceSchema, updateWebhookSourceSchema, listQuerySchema19, triggerEventSchema;
352075
352447
  var init_webhooks3 = __esm(() => {
352076
352448
  init_dist6();
352077
352449
  init_dist2();
@@ -352085,10 +352457,10 @@ var init_webhooks3 = __esm(() => {
352085
352457
  enabled: exports_external.boolean().default(true).describe("Whether source is enabled")
352086
352458
  });
352087
352459
  updateWebhookSourceSchema = createWebhookSourceSchema.partial();
352088
- listQuerySchema18 = exports_external.object({
352460
+ listQuerySchema19 = exports_external.object({
352089
352461
  enabled: exports_external.coerce.boolean().optional()
352090
352462
  });
352091
- webhooksRoutes.get("/webhook-sources", zValidator("query", listQuerySchema18), async (c) => {
352463
+ webhooksRoutes.get("/webhook-sources", zValidator("query", listQuerySchema19), async (c) => {
352092
352464
  const { enabled } = c.req.valid("query");
352093
352465
  const services = c.get("services");
352094
352466
  const sources = await services.webhooks.list({ enabled });
@@ -352162,6 +352534,7 @@ var init_webhooks3 = __esm(() => {
352162
352534
  var v2Routes;
352163
352535
  var init_v2 = __esm(() => {
352164
352536
  init_dist2();
352537
+ init_a2a();
352165
352538
  init_access3();
352166
352539
  init_agent_routes2();
352167
352540
  init_agent_state3();
@@ -352195,6 +352568,7 @@ var init_v2 = __esm(() => {
352195
352568
  init_voice2();
352196
352569
  init_webhooks3();
352197
352570
  v2Routes = new Hono2;
352571
+ v2Routes.route("/a2a", a2aRoutes);
352198
352572
  v2Routes.route("/agents", agentsRoutes);
352199
352573
  v2Routes.route("/agent-state", agentStateRoutes);
352200
352574
  v2Routes.route("/agent-tasks", agentTasksRoutes);
@@ -352247,6 +352621,21 @@ function getAllowedOrigins() {
352247
352621
  }
352248
352622
  return envOrigins.split(",").map((origin) => origin.trim());
352249
352623
  }
352624
+ function validateA2AInstance(instance4) {
352625
+ if (!instance4) {
352626
+ return { body: { error: "Instance not found" }, status: 404 };
352627
+ }
352628
+ if (instance4.channel !== "a2a") {
352629
+ return { body: { error: "Instance is not an A2A channel instance" }, status: 400 };
352630
+ }
352631
+ if (!instance4.isActive) {
352632
+ return { body: { error: "A2A instance is inactive" }, status: 403 };
352633
+ }
352634
+ if (!instance4.agentId) {
352635
+ return { body: { error: "A2A instance has no linked agent" }, status: 409 };
352636
+ }
352637
+ return null;
352638
+ }
352250
352639
  function createApp(db2, eventBus = null, channelRegistry2 = null) {
352251
352640
  const app = new Hono2;
352252
352641
  const { middleware: contextMiddleware, services } = createContextMiddleware(db2, eventBus, channelRegistry2);
@@ -352266,7 +352655,7 @@ function createApp(db2, eventBus = null, channelRegistry2 = null) {
352266
352655
  const allowedOrigins = getAllowedOrigins();
352267
352656
  app.use("*", cors({
352268
352657
  origin: allowedOrigins === "*" ? "*" : allowedOrigins,
352269
- allowHeaders: ["Content-Type", "x-api-key", "x-request-id"],
352658
+ allowHeaders: ["Authorization", "Content-Type", "x-api-key", "x-request-id", "A2A-Version", "A2A-Extensions"],
352270
352659
  allowMethods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
352271
352660
  exposeHeaders: ["x-request-id", "X-RateLimit-Limit", "X-RateLimit-Remaining", "X-RateLimit-Reset"],
352272
352661
  maxAge: 86400
@@ -352279,29 +352668,54 @@ function createApp(db2, eventBus = null, channelRegistry2 = null) {
352279
352668
  app.route("/api/v2", healthRoutes);
352280
352669
  app.route("/api/v2", openapiRoutes);
352281
352670
  if (process.env.A2A_ENABLED === "true") {
352282
- app.get("/.well-known/agent.json", async (c) => {
352283
- const channelRegistry3 = c.get("channelRegistry");
352284
- const plugin7 = channelRegistry3?.get("a2a");
352285
- if (!plugin7?.handleWebhook) {
352286
- return c.json({ error: "A2A channel not available" }, 503);
352671
+ const handleWellKnownAgentCard = async (c) => {
352672
+ const url = new URL(c.req.url);
352673
+ const baseUrl = `${url.protocol}//${url.host}`;
352674
+ const resolved = await resolveA2AAgentCard({
352675
+ services: c.get("services"),
352676
+ baseUrl,
352677
+ instanceId: url.searchParams.get("instanceId"),
352678
+ agentId: url.searchParams.get("agentId")
352679
+ });
352680
+ if (!resolved) {
352681
+ return c.json({
352682
+ error: {
352683
+ code: "A2A_AGENT_CARD_NOT_FOUND",
352684
+ message: "No active A2A agent card matched the request. Pass instanceId or agentId when multiple agents exist."
352685
+ }
352686
+ }, 404);
352287
352687
  }
352288
- return plugin7.handleWebhook(c.req.raw);
352289
- });
352688
+ return c.json(resolved.card);
352689
+ };
352690
+ app.get("/.well-known/agent-card.json", handleWellKnownAgentCard);
352691
+ app.get("/.well-known/agent.json", handleWellKnownAgentCard);
352290
352692
  const UUID_REGEX3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
352291
- app.post("/a2a/:instanceId", authMiddleware, requireInstanceAccess((c) => c.req.param("instanceId") ?? ""), rateLimitMiddleware, async (c) => {
352693
+ app.post("/a2a/:instanceId", authMiddleware, requireInstanceAccess((c) => c.req.param("instanceId") ?? ""), requireAnyScope(["a2a:invoke", "messages:send"]), rateLimitMiddleware, async (c) => {
352292
352694
  const instanceId = c.req.param("instanceId") ?? "";
352293
352695
  if (!UUID_REGEX3.test(instanceId)) {
352294
352696
  return c.json({ error: "Invalid instance ID format" }, 400);
352295
352697
  }
352698
+ const services2 = c.get("services");
352699
+ const instance4 = await services2.instances.getById(instanceId);
352700
+ const validationError = validateA2AInstance(instance4);
352701
+ if (validationError) {
352702
+ return c.json(validationError.body, validationError.status);
352703
+ }
352296
352704
  const channelRegistry3 = c.get("channelRegistry");
352297
352705
  const plugin7 = channelRegistry3?.get("a2a");
352298
352706
  if (!plugin7?.handleWebhook) {
352299
352707
  return c.json({ error: "A2A channel not available" }, 503);
352300
352708
  }
352301
- return plugin7.handleWebhook(c.req.raw);
352709
+ const headers = new Headers(c.req.raw.headers);
352710
+ const apiKey = c.get("apiKey");
352711
+ if (apiKey?.id) {
352712
+ headers.set("x-omni-api-key-id", apiKey.id);
352713
+ }
352714
+ return plugin7.handleWebhook(new Request(c.req.raw, { headers }));
352302
352715
  });
352303
352716
  } else {
352304
352717
  app.all("/a2a/*", (c) => c.json({ error: "A2A channel not enabled. Set A2A_ENABLED=true." }, 503));
352718
+ app.get("/.well-known/agent-card.json", (c) => c.json({ error: "A2A not enabled" }, 503));
352305
352719
  app.get("/.well-known/agent.json", (c) => c.json({ error: "A2A not enabled" }, 503));
352306
352720
  }
352307
352721
  app.post("/api/v2/instances/:id/telegram/webhook", async (c) => {
@@ -352721,16 +353135,20 @@ async function setupEventPersistence(eventBus, db2) {
352721
353135
  eventType: "message.sent",
352722
353136
  direction: "outbound",
352723
353137
  contentType: mapContentType2(payload.content.type),
352724
- textContent: sanitizeText(payload.content.text),
353138
+ textContent: sanitizeText(payload.content.text ?? payload.content.caption),
352725
353139
  mediaUrl: payload.content.mediaUrl,
353140
+ mediaMimeType: payload.content.mimeType,
352726
353141
  chatId: payload.chatId,
352727
353142
  replyToExternalId: payload.replyToId,
352728
353143
  status: "completed",
352729
353144
  receivedAt: new Date(event.timestamp),
352730
353145
  processedAt: new Date,
353146
+ rawPayload: payload.rawPayload ? deepSanitize(payload.rawPayload) : undefined,
352731
353147
  metadata: {
352732
353148
  correlationId: metadata.correlationId,
352733
- to: payload.to
353149
+ to: payload.to,
353150
+ filename: payload.content.filename,
353151
+ voiceNote: payload.content.isVoiceNote
352734
353152
  },
352735
353153
  agentId: metadata.agentId ?? null,
352736
353154
  conversationId: null,
@@ -354793,12 +355211,12 @@ async function closeAgentHeartbeat() {
354793
355211
  await consumer.stop();
354794
355212
  consumer = null;
354795
355213
  }
354796
- var import_nats8, log111, sc3, HEARTBEAT_SUBJECT = "omni.agent.heartbeat.>", consumer = null;
355214
+ var import_nats6, log111, sc3, HEARTBEAT_SUBJECT = "omni.agent.heartbeat.>", consumer = null;
354797
355215
  var init_agent_heartbeat = __esm(() => {
354798
355216
  init_src();
354799
- import_nats8 = __toESM(require_mod4(), 1);
355217
+ import_nats6 = __toESM(require_mod4(), 1);
354800
355218
  log111 = createLogger("agent-heartbeat");
354801
- sc3 = import_nats8.StringCodec();
355219
+ sc3 = import_nats6.StringCodec();
354802
355220
  });
354803
355221
 
354804
355222
  // ../api/src/services/turn-monitor.ts
@@ -478760,6 +479178,49 @@ class WhatsAppPlugin extends BaseChannelPlugin {
478760
479178
  }
478761
479179
  return phoneJid;
478762
479180
  }
479181
+ getSentMediaSource(message2) {
479182
+ if (message2.content.mediaUrl)
479183
+ return "url";
479184
+ if (message2.content.localPath)
479185
+ return "localPath";
479186
+ if (message2.metadata?.base64)
479187
+ return "base64";
479188
+ return;
479189
+ }
479190
+ buildSentRawPayload(externalId, originalMessage, processedMessage) {
479191
+ const mediaSource = this.getSentMediaSource(processedMessage);
479192
+ return {
479193
+ externalId,
479194
+ isFromMe: true,
479195
+ to: originalMessage.to,
479196
+ ...processedMessage.content.caption ? { caption: processedMessage.content.caption } : {},
479197
+ ...processedMessage.content.filename ? { filename: processedMessage.content.filename } : {},
479198
+ ...processedMessage.content.mimeType ? { mimeType: processedMessage.content.mimeType } : {},
479199
+ ...processedMessage.metadata?.ptt === true ? { voiceNote: true } : {},
479200
+ ...mediaSource ? { mediaSource } : {}
479201
+ };
479202
+ }
479203
+ buildSentEventPayload(instanceId, externalId, chatId, originalMessage, processedMessage) {
479204
+ return {
479205
+ instanceId,
479206
+ externalId,
479207
+ chatId,
479208
+ to: originalMessage.to,
479209
+ content: {
479210
+ type: processedMessage.content.type,
479211
+ text: processedMessage.content.text ?? processedMessage.content.caption,
479212
+ caption: processedMessage.content.caption,
479213
+ mediaUrl: processedMessage.content.mediaUrl,
479214
+ localPath: processedMessage.content.localPath,
479215
+ mimeType: processedMessage.content.mimeType,
479216
+ filename: processedMessage.content.filename,
479217
+ isVoiceNote: processedMessage.metadata?.ptt === true
479218
+ },
479219
+ replyToId: originalMessage.replyTo,
479220
+ rawPayload: this.buildSentRawPayload(externalId, originalMessage, processedMessage),
479221
+ senderAgentId: originalMessage.metadata?.senderAgentId
479222
+ };
479223
+ }
478763
479224
  async sendMessage(instanceId, message2) {
478764
479225
  const sock = this.getSocket(instanceId);
478765
479226
  const jid = await this.resolveSendTarget(sock, instanceId, message2.to);
@@ -478786,18 +479247,7 @@ class WhatsAppPlugin extends BaseChannelPlugin {
478786
479247
  this.trackRecentSentMessage(instanceId, externalId, result.message);
478787
479248
  }
478788
479249
  }
478789
- await this.emitMessageSent({
478790
- instanceId,
478791
- externalId,
478792
- chatId: jid,
478793
- to: message2.to,
478794
- content: {
478795
- type: message2.content.type,
478796
- text: message2.content.text
478797
- },
478798
- replyToId: message2.replyTo,
478799
- senderAgentId: message2.metadata?.senderAgentId
478800
- });
479250
+ await this.emitMessageSent(this.buildSentEventPayload(instanceId, externalId, jid, message2, processedMessage));
478801
479251
  rateLimiter.reset();
478802
479252
  return {
478803
479253
  success: true,