@ai-matrx/messaging 0.12.4 → 0.13.0

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
@@ -1046,6 +1046,24 @@ declare function createMessagingRepository(options: RepositoryOptions): Messagin
1046
1046
  * place here.
1047
1047
  */
1048
1048
 
1049
+ /**
1050
+ * Why a conversation could not be read — held PER conversation so a screen can
1051
+ * tell "still loading" from "this will never load".
1052
+ *
1053
+ * Without it a refused read left the thread absent forever (an endless
1054
+ * spinner), and a zero-row read of a conversation the caller cannot see
1055
+ * rendered "No messages yet" — a confident lie about a conversation they may
1056
+ * not even be allowed to know exists.
1057
+ */
1058
+ interface ConversationReadFailure {
1059
+ readonly error: MessagingError;
1060
+ /**
1061
+ * True when the conversation does not exist or this user may not read it
1062
+ * (`not-found` / `forbidden`) — an ACCESS question the host answers with its
1063
+ * access surface, never a retryable fault.
1064
+ */
1065
+ readonly unavailable: boolean;
1066
+ }
1049
1067
  interface ConversationThread {
1050
1068
  readonly conversationId: ConversationId;
1051
1069
  readonly messages: readonly Message[];
@@ -1087,6 +1105,8 @@ interface MessagingSnapshot {
1087
1105
  readonly count: number;
1088
1106
  readonly exact: boolean;
1089
1107
  } | null;
1108
+ /** Conversations whose last open failed, keyed by id. Cleared on the next open. */
1109
+ readonly conversationReadFailures: ReadonlyMap<ConversationId, ConversationReadFailure>;
1090
1110
  }
1091
1111
  interface MessagingStore {
1092
1112
  snapshot(): MessagingSnapshot;
@@ -1106,6 +1126,8 @@ interface MessagingStore {
1106
1126
  upsertConversation(item: ConversationSummary): void;
1107
1127
  removeConversation(id: ConversationId): void;
1108
1128
  setActiveConversation(id: ConversationId | null): void;
1129
+ /** Record (or clear, with `null`) why a conversation could not be read. */
1130
+ setConversationReadFailure(id: ConversationId, failure: ConversationReadFailure | null): void;
1109
1131
  setThread(id: ConversationId, messages: readonly Message[], args?: {
1110
1132
  hasMoreOlder?: boolean;
1111
1133
  }): void;
@@ -1349,4 +1371,4 @@ declare function summarizeText(content: string, maxLength?: number): string;
1349
1371
  /** Serialize picked references into a fence the platform's other readers accept. */
1350
1372
  declare function composeFence(references: readonly MatrxReference[]): string;
1351
1373
 
1352
- 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, 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 };
1374
+ 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 };
package/dist/index.d.ts CHANGED
@@ -1046,6 +1046,24 @@ declare function createMessagingRepository(options: RepositoryOptions): Messagin
1046
1046
  * place here.
1047
1047
  */
1048
1048
 
1049
+ /**
1050
+ * Why a conversation could not be read — held PER conversation so a screen can
1051
+ * tell "still loading" from "this will never load".
1052
+ *
1053
+ * Without it a refused read left the thread absent forever (an endless
1054
+ * spinner), and a zero-row read of a conversation the caller cannot see
1055
+ * rendered "No messages yet" — a confident lie about a conversation they may
1056
+ * not even be allowed to know exists.
1057
+ */
1058
+ interface ConversationReadFailure {
1059
+ readonly error: MessagingError;
1060
+ /**
1061
+ * True when the conversation does not exist or this user may not read it
1062
+ * (`not-found` / `forbidden`) — an ACCESS question the host answers with its
1063
+ * access surface, never a retryable fault.
1064
+ */
1065
+ readonly unavailable: boolean;
1066
+ }
1049
1067
  interface ConversationThread {
1050
1068
  readonly conversationId: ConversationId;
1051
1069
  readonly messages: readonly Message[];
@@ -1087,6 +1105,8 @@ interface MessagingSnapshot {
1087
1105
  readonly count: number;
1088
1106
  readonly exact: boolean;
1089
1107
  } | null;
1108
+ /** Conversations whose last open failed, keyed by id. Cleared on the next open. */
1109
+ readonly conversationReadFailures: ReadonlyMap<ConversationId, ConversationReadFailure>;
1090
1110
  }
1091
1111
  interface MessagingStore {
1092
1112
  snapshot(): MessagingSnapshot;
@@ -1106,6 +1126,8 @@ interface MessagingStore {
1106
1126
  upsertConversation(item: ConversationSummary): void;
1107
1127
  removeConversation(id: ConversationId): void;
1108
1128
  setActiveConversation(id: ConversationId | null): void;
1129
+ /** Record (or clear, with `null`) why a conversation could not be read. */
1130
+ setConversationReadFailure(id: ConversationId, failure: ConversationReadFailure | null): void;
1109
1131
  setThread(id: ConversationId, messages: readonly Message[], args?: {
1110
1132
  hasMoreOlder?: boolean;
1111
1133
  }): void;
@@ -1349,4 +1371,4 @@ declare function summarizeText(content: string, maxLength?: number): string;
1349
1371
  /** Serialize picked references into a fence the platform's other readers accept. */
1350
1372
  declare function composeFence(references: readonly MatrxReference[]): string;
1351
1373
 
1352
- 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, 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 };
1374
+ 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 };
package/dist/index.js CHANGED
@@ -974,6 +974,7 @@ function createMessagingStore() {
974
974
  let archivedCount = null;
975
975
  let threads = /* @__PURE__ */ new Map();
976
976
  let activeConversationId = null;
977
+ let conversationReadFailures = /* @__PURE__ */ new Map();
977
978
  const listeners = /* @__PURE__ */ new Set();
978
979
  let cached = null;
979
980
  function snapshot() {
@@ -986,7 +987,8 @@ function createMessagingStore() {
986
987
  activeConversationId,
987
988
  totalUnreadConversations: conversations.filter((item) => item.unreadCount > 0).length,
988
989
  archiveFilter,
989
- archivedCount
990
+ archivedCount,
991
+ conversationReadFailures
990
992
  };
991
993
  return cached;
992
994
  }
@@ -1070,6 +1072,14 @@ function createMessagingStore() {
1070
1072
  conversations = normalizeConversations(conversations);
1071
1073
  emit();
1072
1074
  },
1075
+ setConversationReadFailure(id, failure) {
1076
+ if (failure === null && !conversationReadFailures.has(id)) return;
1077
+ const next = new Map(conversationReadFailures);
1078
+ if (failure === null) next.delete(id);
1079
+ else next.set(id, failure);
1080
+ conversationReadFailures = next;
1081
+ emit();
1082
+ },
1073
1083
  setThread(id, messages, args = {}) {
1074
1084
  writeThread({
1075
1085
  conversationId: id,
@@ -1375,11 +1385,26 @@ function createMessagingEngine(options) {
1375
1385
  },
1376
1386
  async openConversation(id) {
1377
1387
  store.setActiveConversation(id);
1388
+ store.setConversationReadFailure(id, null);
1378
1389
  try {
1379
1390
  const page = await repository.listMessages(id, { limit: messagePageSize });
1391
+ if (page.items.length === 0) {
1392
+ await repository.getConversation(id);
1393
+ }
1380
1394
  store.setThread(id, page.items, { hasMoreOlder: page.hasMore });
1381
1395
  } catch (error) {
1382
- reportError(error, "openConversation");
1396
+ const normalized = normalizeMessagingError(error, "openConversation");
1397
+ const unavailable = normalized.code === "not-found" || normalized.code === "forbidden";
1398
+ store.setConversationReadFailure(id, { error: normalized, unavailable });
1399
+ if (unavailable) {
1400
+ report({
1401
+ level: "warn",
1402
+ message: normalized.message,
1403
+ remedy: normalized.remedy
1404
+ });
1405
+ return;
1406
+ }
1407
+ reportError(normalized, "openConversation");
1383
1408
  }
1384
1409
  if (openChannels.has(id) || disposed) return;
1385
1410
  const handle = manager.open({