@ai-matrx/messaging 0.10.0 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -291,6 +291,8 @@ interface ActorPresentation {
291
291
  /** The audit principal. Always the row's `sender_id`. Never rewritten. */
292
292
  readonly principalUserId: Message["senderId"];
293
293
  }
294
+ /** Stable presentation identity for grouping adjacent messages in the UI. */
295
+ declare function effectiveActorKey(message: Message): string;
294
296
  declare function resolveActor(message: Message, sender: UserSummary | null): ActorPresentation;
295
297
 
296
298
  /**
@@ -355,7 +357,13 @@ interface MessagingAiOptions {
355
357
  transport: MatrxTransport;
356
358
  organizationId: string;
357
359
  agents: MessagingAgents;
358
- /** Stable source slugs so server-side analytics can see where a run came from. */
360
+ /**
361
+ * The producer slugs stamped on every run. 🚨 The AI Matrx server keeps a
362
+ * REGISTER of legal producers and refuses an unregistered one with a 422, so
363
+ * the defaults below are placeholders that will NOT survive a real server —
364
+ * only the host knows its registered slugs. Not analytics garnish: an
365
+ * unstamped or unregistered run is a refused run.
366
+ */
359
367
  sourceApp?: string | undefined;
360
368
  sourceFeature?: string | undefined;
361
369
  /** Cap on how much transcript is sent. Default 200 messages. */
@@ -1024,6 +1032,8 @@ declare function groupMessages(messages: readonly Message[], args?: {
1024
1032
  now?: number;
1025
1033
  windowMs?: number;
1026
1034
  locale?: string;
1035
+ /** Split audit-principal rows by their effective actor presentation. */
1036
+ actorKey?: (message: Message) => string;
1027
1037
  }): readonly MessageGroup[];
1028
1038
  /** "Ana is typing…" / "Ana and Bo are typing…" / "3 people are typing…" */
1029
1039
  declare function formatTypists(names: readonly string[]): string | null;
@@ -1109,4 +1119,4 @@ declare function summarizeText(content: string, maxLength?: number): string;
1109
1119
  /** Serialize picked references into a fence the platform's other readers accept. */
1110
1120
  declare function composeFence(references: readonly MatrxReference[]): string;
1111
1121
 
1112
- export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, type AiCallArgs, type AiCapability, type AiResult, type Attachment, type ClientMessageId, type Conversation, type ConversationCursor, type ConversationId, type ConversationSummary, type ConversationThread, type ConversationType, type DeliveryState, type DraftMessage, type EngineDiagnostic, type JsonObject, type JsonValue, MESSAGING_EVENTS, MESSAGING_RPC_SCHEMA, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessagingAgentIdentity, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingIdentity, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type MessagingSupabaseClient, type MessagingSupabaseInternal, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, type Participant, type ParticipantRole, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, type RepositoryOptions, type SchemaLike, type SessionResolver, type SupabaseLike, TABLES, type TextSegment, type UserId, type UserSummary, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, composeFence, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createWebOutboxStorage, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, unreadCutoff };
1122
+ export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, type AiCallArgs, type AiCapability, type AiResult, type Attachment, type ClientMessageId, type Conversation, type ConversationCursor, type ConversationId, type ConversationSummary, type ConversationThread, type ConversationType, type DeliveryState, type DraftMessage, type EngineDiagnostic, type JsonObject, type JsonValue, MESSAGING_EVENTS, MESSAGING_RPC_SCHEMA, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessagingAgentIdentity, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingIdentity, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type MessagingSupabaseClient, type MessagingSupabaseInternal, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, type Participant, type ParticipantRole, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, type RepositoryOptions, type SchemaLike, type SessionResolver, type SupabaseLike, TABLES, type TextSegment, type UserId, type UserSummary, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, composeFence, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createWebOutboxStorage, effectiveActorKey, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, unreadCutoff };
package/dist/index.d.ts CHANGED
@@ -291,6 +291,8 @@ interface ActorPresentation {
291
291
  /** The audit principal. Always the row's `sender_id`. Never rewritten. */
292
292
  readonly principalUserId: Message["senderId"];
293
293
  }
294
+ /** Stable presentation identity for grouping adjacent messages in the UI. */
295
+ declare function effectiveActorKey(message: Message): string;
294
296
  declare function resolveActor(message: Message, sender: UserSummary | null): ActorPresentation;
295
297
 
296
298
  /**
@@ -355,7 +357,13 @@ interface MessagingAiOptions {
355
357
  transport: MatrxTransport;
356
358
  organizationId: string;
357
359
  agents: MessagingAgents;
358
- /** Stable source slugs so server-side analytics can see where a run came from. */
360
+ /**
361
+ * The producer slugs stamped on every run. 🚨 The AI Matrx server keeps a
362
+ * REGISTER of legal producers and refuses an unregistered one with a 422, so
363
+ * the defaults below are placeholders that will NOT survive a real server —
364
+ * only the host knows its registered slugs. Not analytics garnish: an
365
+ * unstamped or unregistered run is a refused run.
366
+ */
359
367
  sourceApp?: string | undefined;
360
368
  sourceFeature?: string | undefined;
361
369
  /** Cap on how much transcript is sent. Default 200 messages. */
@@ -1024,6 +1032,8 @@ declare function groupMessages(messages: readonly Message[], args?: {
1024
1032
  now?: number;
1025
1033
  windowMs?: number;
1026
1034
  locale?: string;
1035
+ /** Split audit-principal rows by their effective actor presentation. */
1036
+ actorKey?: (message: Message) => string;
1027
1037
  }): readonly MessageGroup[];
1028
1038
  /** "Ana is typing…" / "Ana and Bo are typing…" / "3 people are typing…" */
1029
1039
  declare function formatTypists(names: readonly string[]): string | null;
@@ -1109,4 +1119,4 @@ declare function summarizeText(content: string, maxLength?: number): string;
1109
1119
  /** Serialize picked references into a fence the platform's other readers accept. */
1110
1120
  declare function composeFence(references: readonly MatrxReference[]): string;
1111
1121
 
1112
- export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, type AiCallArgs, type AiCapability, type AiResult, type Attachment, type ClientMessageId, type Conversation, type ConversationCursor, type ConversationId, type ConversationSummary, type ConversationThread, type ConversationType, type DeliveryState, type DraftMessage, type EngineDiagnostic, type JsonObject, type JsonValue, MESSAGING_EVENTS, MESSAGING_RPC_SCHEMA, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessagingAgentIdentity, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingIdentity, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type MessagingSupabaseClient, type MessagingSupabaseInternal, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, type Participant, type ParticipantRole, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, type RepositoryOptions, type SchemaLike, type SessionResolver, type SupabaseLike, TABLES, type TextSegment, type UserId, type UserSummary, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, composeFence, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createWebOutboxStorage, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, unreadCutoff };
1122
+ export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, type AiCallArgs, type AiCapability, type AiResult, type Attachment, type ClientMessageId, type Conversation, type ConversationCursor, type ConversationId, type ConversationSummary, type ConversationThread, type ConversationType, type DeliveryState, type DraftMessage, type EngineDiagnostic, type JsonObject, type JsonValue, MESSAGING_EVENTS, MESSAGING_RPC_SCHEMA, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessagingAgentIdentity, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingIdentity, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type MessagingSupabaseClient, type MessagingSupabaseInternal, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, type Participant, type ParticipantRole, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, type RepositoryOptions, type SchemaLike, type SessionResolver, type SupabaseLike, TABLES, type TextSegment, type UserId, type UserSummary, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, composeFence, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createWebOutboxStorage, effectiveActorKey, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, unreadCutoff };
package/dist/index.js CHANGED
@@ -71,19 +71,36 @@ function createActionRegistry() {
71
71
 
72
72
  // src/core/actor.ts
73
73
  function readActorHint(metadata) {
74
- const raw = metadata["actor"];
75
- if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return null;
76
- const record = raw;
77
- const agentId = record["agentId"] ?? record["agent_id"];
78
- if (typeof agentId !== "string" || agentId.length === 0) return null;
79
- const name = record["agentName"] ?? record["agent_name"];
80
- const avatar = record["agentAvatarUrl"] ?? record["agent_avatar_url"];
74
+ const envelope = metadata;
75
+ const raw = envelope["actor"];
76
+ if (typeof raw === "object" && raw !== null && !Array.isArray(raw)) {
77
+ const record = raw;
78
+ const agentId = record["agentId"] ?? record["agent_id"];
79
+ if (typeof agentId !== "string" || agentId.length === 0) return null;
80
+ const name2 = record["agentName"] ?? record["agent_name"];
81
+ const avatar2 = record["agentAvatarUrl"] ?? record["agent_avatar_url"];
82
+ return {
83
+ agentId,
84
+ ...typeof name2 === "string" && name2.length > 0 ? { agentName: name2 } : {},
85
+ ...typeof avatar2 === "string" && avatar2.length > 0 ? { agentAvatarUrl: avatar2 } : {}
86
+ };
87
+ }
88
+ const actorKind = envelope["actor_kind"] ?? envelope["actorKind"];
89
+ if (actorKind !== "agent") return null;
90
+ const id = envelope["actor_id"] ?? envelope["actorId"];
91
+ const name = envelope["actor_label"] ?? envelope["actorLabel"];
92
+ const avatar = envelope["actor_avatar_url"] ?? envelope["actorAvatarUrl"];
81
93
  return {
82
- agentId,
94
+ ...typeof id === "string" && id.length > 0 ? { agentId: id } : {},
83
95
  ...typeof name === "string" && name.length > 0 ? { agentName: name } : {},
84
96
  ...typeof avatar === "string" && avatar.length > 0 ? { agentAvatarUrl: avatar } : {}
85
97
  };
86
98
  }
99
+ function effectiveActorKey(message) {
100
+ const hint = readActorHint(message.metadata);
101
+ if (hint === null) return `principal:${message.senderId}`;
102
+ return `agent:${hint.agentId ?? hint.agentName ?? "anonymous"}`;
103
+ }
87
104
  function resolveActor(message, sender) {
88
105
  const hint = readActorHint(message.metadata);
89
106
  const humanName = sender?.displayName ?? message.senderId;
@@ -1452,18 +1469,20 @@ function groupMessages(messages, args = {}) {
1452
1469
  let current = null;
1453
1470
  let previousDay = null;
1454
1471
  for (const message of messages) {
1472
+ const actorKey = args.actorKey?.(message) ?? `principal:${message.senderId}`;
1455
1473
  const day = message.createdAt.slice(0, 10);
1456
1474
  const startsNewDay = day !== previousDay;
1457
1475
  previousDay = day;
1458
1476
  const last = current?.messages.at(-1);
1459
1477
  const withinWindow = last !== void 0 && Math.abs(Date.parse(message.createdAt) - Date.parse(last.createdAt)) <= windowMs;
1460
- if (current !== null && current.senderId === message.senderId && withinWindow && !startsNewDay) {
1478
+ if (current !== null && current.senderId === message.senderId && current.actorKey === actorKey && withinWindow && !startsNewDay) {
1461
1479
  current.messages.push(message);
1462
1480
  continue;
1463
1481
  }
1464
1482
  if (current !== null) groups.push(current);
1465
1483
  current = {
1466
1484
  senderId: message.senderId,
1485
+ actorKey,
1467
1486
  messages: [message],
1468
1487
  dateSeparator: startsNewDay ? formatDateSeparator(message.createdAt, now, args.locale) : null
1469
1488
  };
@@ -1862,6 +1881,7 @@ export {
1862
1881
  createOutbox,
1863
1882
  createReadCache,
1864
1883
  createWebOutboxStorage,
1884
+ effectiveActorKey,
1865
1885
  extractReferences,
1866
1886
  formatConversationTime,
1867
1887
  formatDateSeparator,