@ai-matrx/messaging 0.14.0 → 0.15.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.
package/dist/index.d.cts CHANGED
@@ -412,11 +412,34 @@ interface AiResult {
412
412
  readonly text: string;
413
413
  readonly conversationId: string | null;
414
414
  }
415
+ /**
416
+ * Facts about the open conversation the caller already holds (the inbox row
417
+ * and the signed-in reader). Each is sent by its offered name
418
+ * (`messaging.conversation`, mapped-only) beside the transcript; an absent
419
+ * one is omitted, never sent empty. Nothing here changes the transcript.
420
+ */
421
+ interface ConversationAiContext {
422
+ conversationType?: ConversationType | undefined;
423
+ /** The name the reader sees: the group name, or the other person's name. */
424
+ conversationName?: string | undefined;
425
+ conversationCreatedAt?: string | undefined;
426
+ unreadCount?: number | undefined;
427
+ isMuted?: boolean | undefined;
428
+ readerUserId?: string | undefined;
429
+ }
430
+ /**
431
+ * The offered values of `ConversationAiContext`, by name. Pure, so a host that
432
+ * builds its own call can reuse it. `total_loaded_message_count` is the
433
+ * messages the caller loaded BEFORE windowing.
434
+ */
435
+ declare function conversationContextVariables(context: ConversationAiContext | undefined, loadedMessageCount: number): MatrxJsonObject;
415
436
  /** What every capability takes: the conversation, and how to watch the run. */
416
437
  interface AiCallArgs {
417
438
  conversationId: ConversationId;
418
439
  messages: readonly Message[];
419
440
  participants: readonly UserSummary[];
441
+ /** Conversation facts sent by name beside the transcript (optional). */
442
+ context?: ConversationAiContext | undefined;
420
443
  signal?: AbortSignal | undefined;
421
444
  /** The accumulated answer so far, after every streamed chunk. */
422
445
  onText?: ((fullText: string) => void) | undefined;
@@ -1122,11 +1145,18 @@ interface MessagingSnapshot {
1122
1145
  } | null;
1123
1146
  /** Conversations whose last open failed, keyed by id. Cleared on the next open. */
1124
1147
  readonly conversationReadFailures: ReadonlyMap<ConversationId, ConversationReadFailure>;
1148
+ /**
1149
+ * The inbox read FAILED (and no later read succeeded). Without it a failed
1150
+ * first read left `hasLoadedConversations` false forever — a skeleton that
1151
+ * never resolves is a screen telling a lie (RC-B12 round 11).
1152
+ */
1153
+ readonly conversationsLoadError: string | null;
1125
1154
  }
1126
1155
  interface MessagingStore {
1127
1156
  snapshot(): MessagingSnapshot;
1128
1157
  subscribe(listener: (snapshot: MessagingSnapshot) => void): () => void;
1129
1158
  setConversations(items: readonly ConversationSummary[], hasMore: boolean): void;
1159
+ setConversationsLoadError(message: string | null): void;
1130
1160
  /**
1131
1161
  * Switch the archive axis. Clears the list and marks it UNLOADED: the rows
1132
1162
  * on screen belong to the old filter, and leaving them there while the new
@@ -1236,6 +1266,8 @@ interface MessagingEngine {
1236
1266
  * refreshes the archived count the reveal label prints.
1237
1267
  */
1238
1268
  setArchiveFilter(next: MessagingArchiveFilter): Promise<void>;
1269
+ /** Read the inbox again (the failed-read view's Try again). Never throws; a failure lands in the snapshot. */
1270
+ refreshInbox(): Promise<void>;
1239
1271
  /** Re-read how many archived conversations exist, for the reveal's label. */
1240
1272
  refreshArchivedCount(): Promise<void>;
1241
1273
  /** Open a conversation: load its thread and subscribe to its channel. */
@@ -1390,4 +1422,4 @@ declare function summarizeText(content: string, maxLength?: number): string;
1390
1422
  /** Serialize picked references into a fence the platform's other readers accept. */
1391
1423
  declare function composeFence(references: readonly MatrxReference[]): string;
1392
1424
 
1393
- 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 ConversationReadFailure, type ConversationSummary, type ConversationThread, type ConversationType, DEFAULT_MESSAGING_ARCHIVE_FILTER, 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 MessagingArchiveFilter, 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, SERVER_SESSION_IDENTITY, type SchemaLike, type SessionIdentity, type SessionIdentitySnapshot, 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, createSessionIdentity, createWebOutboxStorage, effectiveActorKey, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, toMessagingArchiveFilter, unreadCutoff };
1425
+ 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 ConversationAiContext, type ConversationCursor, type ConversationId, type ConversationReadFailure, type ConversationSummary, type ConversationThread, type ConversationType, DEFAULT_MESSAGING_ARCHIVE_FILTER, 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 MessagingArchiveFilter, 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, SERVER_SESSION_IDENTITY, type SchemaLike, type SessionIdentity, type SessionIdentitySnapshot, type SessionResolver, type SupabaseLike, TABLES, type TextSegment, type UserId, type UserSummary, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, composeFence, conversationContextVariables, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createSessionIdentity, createWebOutboxStorage, effectiveActorKey, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, toMessagingArchiveFilter, unreadCutoff };
package/dist/index.d.ts CHANGED
@@ -412,11 +412,34 @@ interface AiResult {
412
412
  readonly text: string;
413
413
  readonly conversationId: string | null;
414
414
  }
415
+ /**
416
+ * Facts about the open conversation the caller already holds (the inbox row
417
+ * and the signed-in reader). Each is sent by its offered name
418
+ * (`messaging.conversation`, mapped-only) beside the transcript; an absent
419
+ * one is omitted, never sent empty. Nothing here changes the transcript.
420
+ */
421
+ interface ConversationAiContext {
422
+ conversationType?: ConversationType | undefined;
423
+ /** The name the reader sees: the group name, or the other person's name. */
424
+ conversationName?: string | undefined;
425
+ conversationCreatedAt?: string | undefined;
426
+ unreadCount?: number | undefined;
427
+ isMuted?: boolean | undefined;
428
+ readerUserId?: string | undefined;
429
+ }
430
+ /**
431
+ * The offered values of `ConversationAiContext`, by name. Pure, so a host that
432
+ * builds its own call can reuse it. `total_loaded_message_count` is the
433
+ * messages the caller loaded BEFORE windowing.
434
+ */
435
+ declare function conversationContextVariables(context: ConversationAiContext | undefined, loadedMessageCount: number): MatrxJsonObject;
415
436
  /** What every capability takes: the conversation, and how to watch the run. */
416
437
  interface AiCallArgs {
417
438
  conversationId: ConversationId;
418
439
  messages: readonly Message[];
419
440
  participants: readonly UserSummary[];
441
+ /** Conversation facts sent by name beside the transcript (optional). */
442
+ context?: ConversationAiContext | undefined;
420
443
  signal?: AbortSignal | undefined;
421
444
  /** The accumulated answer so far, after every streamed chunk. */
422
445
  onText?: ((fullText: string) => void) | undefined;
@@ -1122,11 +1145,18 @@ interface MessagingSnapshot {
1122
1145
  } | null;
1123
1146
  /** Conversations whose last open failed, keyed by id. Cleared on the next open. */
1124
1147
  readonly conversationReadFailures: ReadonlyMap<ConversationId, ConversationReadFailure>;
1148
+ /**
1149
+ * The inbox read FAILED (and no later read succeeded). Without it a failed
1150
+ * first read left `hasLoadedConversations` false forever — a skeleton that
1151
+ * never resolves is a screen telling a lie (RC-B12 round 11).
1152
+ */
1153
+ readonly conversationsLoadError: string | null;
1125
1154
  }
1126
1155
  interface MessagingStore {
1127
1156
  snapshot(): MessagingSnapshot;
1128
1157
  subscribe(listener: (snapshot: MessagingSnapshot) => void): () => void;
1129
1158
  setConversations(items: readonly ConversationSummary[], hasMore: boolean): void;
1159
+ setConversationsLoadError(message: string | null): void;
1130
1160
  /**
1131
1161
  * Switch the archive axis. Clears the list and marks it UNLOADED: the rows
1132
1162
  * on screen belong to the old filter, and leaving them there while the new
@@ -1236,6 +1266,8 @@ interface MessagingEngine {
1236
1266
  * refreshes the archived count the reveal label prints.
1237
1267
  */
1238
1268
  setArchiveFilter(next: MessagingArchiveFilter): Promise<void>;
1269
+ /** Read the inbox again (the failed-read view's Try again). Never throws; a failure lands in the snapshot. */
1270
+ refreshInbox(): Promise<void>;
1239
1271
  /** Re-read how many archived conversations exist, for the reveal's label. */
1240
1272
  refreshArchivedCount(): Promise<void>;
1241
1273
  /** Open a conversation: load its thread and subscribe to its channel. */
@@ -1390,4 +1422,4 @@ declare function summarizeText(content: string, maxLength?: number): string;
1390
1422
  /** Serialize picked references into a fence the platform's other readers accept. */
1391
1423
  declare function composeFence(references: readonly MatrxReference[]): string;
1392
1424
 
1393
- 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 ConversationReadFailure, type ConversationSummary, type ConversationThread, type ConversationType, DEFAULT_MESSAGING_ARCHIVE_FILTER, 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 MessagingArchiveFilter, 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, SERVER_SESSION_IDENTITY, type SchemaLike, type SessionIdentity, type SessionIdentitySnapshot, 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, createSessionIdentity, createWebOutboxStorage, effectiveActorKey, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, toMessagingArchiveFilter, unreadCutoff };
1425
+ 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 ConversationAiContext, type ConversationCursor, type ConversationId, type ConversationReadFailure, type ConversationSummary, type ConversationThread, type ConversationType, DEFAULT_MESSAGING_ARCHIVE_FILTER, 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 MessagingArchiveFilter, 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, SERVER_SESSION_IDENTITY, type SchemaLike, type SessionIdentity, type SessionIdentitySnapshot, type SessionResolver, type SupabaseLike, TABLES, type TextSegment, type UserId, type UserSummary, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, composeFence, conversationContextVariables, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createSessionIdentity, createWebOutboxStorage, effectiveActorKey, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, toMessagingArchiveFilter, unreadCutoff };
package/dist/index.js CHANGED
@@ -323,6 +323,20 @@ ${JSON.stringify(references, null, 2)}
323
323
  }
324
324
 
325
325
  // src/core/ai.ts
326
+ function conversationContextVariables(context, loadedMessageCount) {
327
+ const values = {
328
+ total_loaded_message_count: loadedMessageCount
329
+ };
330
+ if (context === void 0) return values;
331
+ if (context.conversationType) values.conversation_type = context.conversationType;
332
+ if (context.conversationName) values.conversation_name = context.conversationName;
333
+ if (context.conversationCreatedAt)
334
+ values.conversation_created_at = context.conversationCreatedAt;
335
+ if (typeof context.unreadCount === "number") values.unread_count = context.unreadCount;
336
+ if (typeof context.isMuted === "boolean") values.is_muted = context.isMuted;
337
+ if (context.readerUserId) values.reader_user_id = context.readerUserId;
338
+ return values;
339
+ }
326
340
  function unreadCutoff(messages, unreadCount) {
327
341
  if (unreadCount <= 0) return null;
328
342
  const index = messages.length - unreadCount - 1;
@@ -412,7 +426,8 @@ function createMessagingAi(options) {
412
426
  transcript_message_count: transcript.length,
413
427
  // Honest about the cut, so an agent can say "showing the last 200".
414
428
  transcript_truncated: args.messages.length > transcript.length,
415
- ...args.since != null ? { unread_since: args.since } : {}
429
+ ...args.since != null ? { unread_since: args.since } : {},
430
+ ...conversationContextVariables(args.context, args.messages.length)
416
431
  };
417
432
  }
418
433
  function configured(capability) {
@@ -975,6 +990,7 @@ function createMessagingStore() {
975
990
  let threads = /* @__PURE__ */ new Map();
976
991
  let activeConversationId = null;
977
992
  let conversationReadFailures = /* @__PURE__ */ new Map();
993
+ let conversationsLoadError = null;
978
994
  const listeners = /* @__PURE__ */ new Set();
979
995
  let cached = null;
980
996
  function snapshot() {
@@ -988,7 +1004,8 @@ function createMessagingStore() {
988
1004
  totalUnreadConversations: conversations.filter((item) => item.unreadCount > 0).length,
989
1005
  archiveFilter,
990
1006
  archivedCount,
991
- conversationReadFailures
1007
+ conversationReadFailures,
1008
+ conversationsLoadError
992
1009
  };
993
1010
  return cached;
994
1011
  }
@@ -1033,6 +1050,12 @@ function createMessagingStore() {
1033
1050
  conversations = normalizeConversations(items);
1034
1051
  hasMoreConversations = hasMore;
1035
1052
  hasLoadedConversations = true;
1053
+ conversationsLoadError = null;
1054
+ emit();
1055
+ },
1056
+ setConversationsLoadError(message) {
1057
+ if (message === conversationsLoadError) return;
1058
+ conversationsLoadError = message;
1036
1059
  emit();
1037
1060
  },
1038
1061
  setArchiveFilter(next) {
@@ -1265,10 +1288,20 @@ function createMessagingEngine(options) {
1265
1288
  }
1266
1289
  async function reloadInbox() {
1267
1290
  if (disposed) return;
1268
- const page = await repository.listConversations({
1269
- limit: conversationPageSize,
1270
- archived: store.snapshot().archiveFilter
1271
- });
1291
+ let page;
1292
+ try {
1293
+ page = await repository.listConversations({
1294
+ limit: conversationPageSize,
1295
+ archived: store.snapshot().archiveFilter
1296
+ });
1297
+ } catch (error) {
1298
+ if (!disposed) {
1299
+ store.setConversationsLoadError(
1300
+ error instanceof Error ? error.message : typeof error === "string" ? error : "The conversation list could not be read."
1301
+ );
1302
+ }
1303
+ throw error;
1304
+ }
1272
1305
  if (disposed) return;
1273
1306
  conversationCursor = page.nextCursor;
1274
1307
  store.setConversations(page.items, page.hasMore);
@@ -1353,6 +1386,13 @@ function createMessagingEngine(options) {
1353
1386
  }
1354
1387
  });
1355
1388
  },
1389
+ async refreshInbox() {
1390
+ try {
1391
+ await reloadInbox();
1392
+ } catch (error) {
1393
+ reportError(error, "inboxRefresh");
1394
+ }
1395
+ },
1356
1396
  async setArchiveFilter(next) {
1357
1397
  if (next === store.snapshot().archiveFilter) return;
1358
1398
  store.setArchiveFilter(next);
@@ -2201,6 +2241,7 @@ export {
2201
2241
  asOrganizationId,
2202
2242
  asUserId,
2203
2243
  composeFence,
2244
+ conversationContextVariables,
2204
2245
  conversationTopic,
2205
2246
  createActionRegistry,
2206
2247
  createMemoryOutboxStorage,