@ai-matrx/messaging 0.10.1 → 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/CHANGELOG.md +24 -0
- package/dist/index.cjs +29 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +29 -9
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +65 -23
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +21 -2
- package/dist/react.d.ts +21 -2
- package/dist/react.js +71 -24
- package/dist/react.js.map +1 -1
- package/package.json +2 -2
package/dist/react.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReactNode, ComponentType, SVGProps } from 'react';
|
|
1
|
+
import { ReactNode, ComponentType, KeyboardEvent, SVGProps } from 'react';
|
|
2
2
|
import { MatrxJsonObject, MatrxTransport } from '@ai-matrx/agents/matrx';
|
|
3
3
|
import { RealtimeClientLike, RealtimeManager } from '@ai-matrx/realtime';
|
|
4
4
|
|
|
@@ -1157,6 +1157,21 @@ interface ConversationViewProps {
|
|
|
1157
1157
|
conversationId: ConversationId | null;
|
|
1158
1158
|
onBack?: () => void;
|
|
1159
1159
|
className?: string;
|
|
1160
|
+
/** Hide package chrome when a containing workspace already owns the title. */
|
|
1161
|
+
showHeader?: boolean;
|
|
1162
|
+
/** Hide conversation AI controls on a surface that deliberately does not offer them. */
|
|
1163
|
+
showAi?: boolean;
|
|
1164
|
+
/** Let a host inject its canonical textarea chrome without taking composer behavior. */
|
|
1165
|
+
renderComposerInput?: (props: ComposerInputRenderProps) => ReactNode;
|
|
1166
|
+
}
|
|
1167
|
+
interface ComposerInputRenderProps {
|
|
1168
|
+
readonly value: string;
|
|
1169
|
+
readonly disabled: boolean;
|
|
1170
|
+
readonly canSend: boolean;
|
|
1171
|
+
readonly placeholder: string;
|
|
1172
|
+
readonly onChange: (value: string) => void;
|
|
1173
|
+
readonly onKeyDown: (event: KeyboardEvent<HTMLTextAreaElement>) => void;
|
|
1174
|
+
readonly onSubmit: () => void;
|
|
1160
1175
|
}
|
|
1161
1176
|
declare function ConversationView(props: ConversationViewProps): ReactNode;
|
|
1162
1177
|
declare function MessageBubble(props: {
|
|
@@ -1285,6 +1300,8 @@ interface ActorPresentation {
|
|
|
1285
1300
|
/** The audit principal. Always the row's `sender_id`. Never rewritten. */
|
|
1286
1301
|
readonly principalUserId: Message["senderId"];
|
|
1287
1302
|
}
|
|
1303
|
+
/** Stable presentation identity for grouping adjacent messages in the UI. */
|
|
1304
|
+
declare function effectiveActorKey(message: Message): string;
|
|
1288
1305
|
declare function resolveActor(message: Message, sender: UserSummary | null): ActorPresentation;
|
|
1289
1306
|
|
|
1290
1307
|
/**
|
|
@@ -1434,6 +1451,8 @@ declare function groupMessages(messages: readonly Message[], args?: {
|
|
|
1434
1451
|
now?: number;
|
|
1435
1452
|
windowMs?: number;
|
|
1436
1453
|
locale?: string;
|
|
1454
|
+
/** Split audit-principal rows by their effective actor presentation. */
|
|
1455
|
+
actorKey?: (message: Message) => string;
|
|
1437
1456
|
}): readonly MessageGroup[];
|
|
1438
1457
|
/** "Ana is typing…" / "Ana and Bo are typing…" / "3 people are typing…" */
|
|
1439
1458
|
declare function formatTypists(names: readonly string[]): string | null;
|
|
@@ -1519,4 +1538,4 @@ declare function summarizeText(content: string, maxLength?: number): string;
|
|
|
1519
1538
|
/** Serialize picked references into a fence the platform's other readers accept. */
|
|
1520
1539
|
declare function composeFence(references: readonly MatrxReference[]): string;
|
|
1521
1540
|
|
|
1522
|
-
export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, AgentTag, type AiCallArgs, type AiCapability, type AiResult, AlertIcon, type Attachment, Avatar, BotIcon, CheckIcon, ChevronLeftIcon, type ClientMessageId, ClockIcon, CloseIcon, Composer, type Conversation, type ConversationCursor, type ConversationId, ConversationList, type ConversationListProps, type ConversationRowWrapperProps, ConversationSkeleton, type ConversationSummary, type ConversationThread, type ConversationType, ConversationView, type ConversationViewProps, type DeliveryState, DeliveryTick, DoubleCheckIcon, type DraftMessage, EmptyState, type EngineDiagnostic, type IncomingMessageContext, type JsonObject, type JsonValue, LinkIcon, MESSAGING_EVENTS, MESSAGING_RPC_SCHEMA, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, MessageActionChips, type MessageActionRenderProps, type MessageActionRenderer, MessageBubble, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessageWrapperProps, type MessagingAgentIdentity, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingHost, type MessagingIdentity, MessagingInbox, type MessagingInboxProps, MessagingProvider, type MessagingProviderProps, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type MessagingSupabaseClient, type MessagingSupabaseInternal, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, PaperclipIcon, type Participant, type ParticipantRole, PlusIcon, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, ReferenceCard, type ReferenceRenderer, ReplyIcon, type RepositoryOptions, type SchemaLike, SearchIcon, SendIcon, type SessionResolver, SparklesIcon, type SupabaseLike, TABLES, type TextSegment, TypingDots, type UseComposerResult, type UseConversationResult, type UseConversationsResult, type UseMessageActionResult, type UseMessagingAiResult, type UseTypistsResult, type UserId, type UserSummary, UsersIcon, 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, useComposer, useConversation, useConversations, useMessageAction, useMessagingAi, useMessagingHost, useMessagingSnapshot, useOnlineUserIds, useRequiredMessagingHost, useTypists };
|
|
1541
|
+
export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, AgentTag, type AiCallArgs, type AiCapability, type AiResult, AlertIcon, type Attachment, Avatar, BotIcon, CheckIcon, ChevronLeftIcon, type ClientMessageId, ClockIcon, CloseIcon, Composer, type ComposerInputRenderProps, type Conversation, type ConversationCursor, type ConversationId, ConversationList, type ConversationListProps, type ConversationRowWrapperProps, ConversationSkeleton, type ConversationSummary, type ConversationThread, type ConversationType, ConversationView, type ConversationViewProps, type DeliveryState, DeliveryTick, DoubleCheckIcon, type DraftMessage, EmptyState, type EngineDiagnostic, type IncomingMessageContext, type JsonObject, type JsonValue, LinkIcon, MESSAGING_EVENTS, MESSAGING_RPC_SCHEMA, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, MessageActionChips, type MessageActionRenderProps, type MessageActionRenderer, MessageBubble, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessageWrapperProps, type MessagingAgentIdentity, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingHost, type MessagingIdentity, MessagingInbox, type MessagingInboxProps, MessagingProvider, type MessagingProviderProps, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type MessagingSupabaseClient, type MessagingSupabaseInternal, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, PaperclipIcon, type Participant, type ParticipantRole, PlusIcon, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, ReferenceCard, type ReferenceRenderer, ReplyIcon, type RepositoryOptions, type SchemaLike, SearchIcon, SendIcon, type SessionResolver, SparklesIcon, type SupabaseLike, TABLES, type TextSegment, TypingDots, type UseComposerResult, type UseConversationResult, type UseConversationsResult, type UseMessageActionResult, type UseMessagingAiResult, type UseTypistsResult, type UserId, type UserSummary, UsersIcon, 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, useComposer, useConversation, useConversations, useMessageAction, useMessagingAi, useMessagingHost, useMessagingSnapshot, useOnlineUserIds, useRequiredMessagingHost, useTypists };
|
package/dist/react.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReactNode, ComponentType, SVGProps } from 'react';
|
|
1
|
+
import { ReactNode, ComponentType, KeyboardEvent, SVGProps } from 'react';
|
|
2
2
|
import { MatrxJsonObject, MatrxTransport } from '@ai-matrx/agents/matrx';
|
|
3
3
|
import { RealtimeClientLike, RealtimeManager } from '@ai-matrx/realtime';
|
|
4
4
|
|
|
@@ -1157,6 +1157,21 @@ interface ConversationViewProps {
|
|
|
1157
1157
|
conversationId: ConversationId | null;
|
|
1158
1158
|
onBack?: () => void;
|
|
1159
1159
|
className?: string;
|
|
1160
|
+
/** Hide package chrome when a containing workspace already owns the title. */
|
|
1161
|
+
showHeader?: boolean;
|
|
1162
|
+
/** Hide conversation AI controls on a surface that deliberately does not offer them. */
|
|
1163
|
+
showAi?: boolean;
|
|
1164
|
+
/** Let a host inject its canonical textarea chrome without taking composer behavior. */
|
|
1165
|
+
renderComposerInput?: (props: ComposerInputRenderProps) => ReactNode;
|
|
1166
|
+
}
|
|
1167
|
+
interface ComposerInputRenderProps {
|
|
1168
|
+
readonly value: string;
|
|
1169
|
+
readonly disabled: boolean;
|
|
1170
|
+
readonly canSend: boolean;
|
|
1171
|
+
readonly placeholder: string;
|
|
1172
|
+
readonly onChange: (value: string) => void;
|
|
1173
|
+
readonly onKeyDown: (event: KeyboardEvent<HTMLTextAreaElement>) => void;
|
|
1174
|
+
readonly onSubmit: () => void;
|
|
1160
1175
|
}
|
|
1161
1176
|
declare function ConversationView(props: ConversationViewProps): ReactNode;
|
|
1162
1177
|
declare function MessageBubble(props: {
|
|
@@ -1285,6 +1300,8 @@ interface ActorPresentation {
|
|
|
1285
1300
|
/** The audit principal. Always the row's `sender_id`. Never rewritten. */
|
|
1286
1301
|
readonly principalUserId: Message["senderId"];
|
|
1287
1302
|
}
|
|
1303
|
+
/** Stable presentation identity for grouping adjacent messages in the UI. */
|
|
1304
|
+
declare function effectiveActorKey(message: Message): string;
|
|
1288
1305
|
declare function resolveActor(message: Message, sender: UserSummary | null): ActorPresentation;
|
|
1289
1306
|
|
|
1290
1307
|
/**
|
|
@@ -1434,6 +1451,8 @@ declare function groupMessages(messages: readonly Message[], args?: {
|
|
|
1434
1451
|
now?: number;
|
|
1435
1452
|
windowMs?: number;
|
|
1436
1453
|
locale?: string;
|
|
1454
|
+
/** Split audit-principal rows by their effective actor presentation. */
|
|
1455
|
+
actorKey?: (message: Message) => string;
|
|
1437
1456
|
}): readonly MessageGroup[];
|
|
1438
1457
|
/** "Ana is typing…" / "Ana and Bo are typing…" / "3 people are typing…" */
|
|
1439
1458
|
declare function formatTypists(names: readonly string[]): string | null;
|
|
@@ -1519,4 +1538,4 @@ declare function summarizeText(content: string, maxLength?: number): string;
|
|
|
1519
1538
|
/** Serialize picked references into a fence the platform's other readers accept. */
|
|
1520
1539
|
declare function composeFence(references: readonly MatrxReference[]): string;
|
|
1521
1540
|
|
|
1522
|
-
export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, AgentTag, type AiCallArgs, type AiCapability, type AiResult, AlertIcon, type Attachment, Avatar, BotIcon, CheckIcon, ChevronLeftIcon, type ClientMessageId, ClockIcon, CloseIcon, Composer, type Conversation, type ConversationCursor, type ConversationId, ConversationList, type ConversationListProps, type ConversationRowWrapperProps, ConversationSkeleton, type ConversationSummary, type ConversationThread, type ConversationType, ConversationView, type ConversationViewProps, type DeliveryState, DeliveryTick, DoubleCheckIcon, type DraftMessage, EmptyState, type EngineDiagnostic, type IncomingMessageContext, type JsonObject, type JsonValue, LinkIcon, MESSAGING_EVENTS, MESSAGING_RPC_SCHEMA, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, MessageActionChips, type MessageActionRenderProps, type MessageActionRenderer, MessageBubble, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessageWrapperProps, type MessagingAgentIdentity, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingHost, type MessagingIdentity, MessagingInbox, type MessagingInboxProps, MessagingProvider, type MessagingProviderProps, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type MessagingSupabaseClient, type MessagingSupabaseInternal, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, PaperclipIcon, type Participant, type ParticipantRole, PlusIcon, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, ReferenceCard, type ReferenceRenderer, ReplyIcon, type RepositoryOptions, type SchemaLike, SearchIcon, SendIcon, type SessionResolver, SparklesIcon, type SupabaseLike, TABLES, type TextSegment, TypingDots, type UseComposerResult, type UseConversationResult, type UseConversationsResult, type UseMessageActionResult, type UseMessagingAiResult, type UseTypistsResult, type UserId, type UserSummary, UsersIcon, 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, useComposer, useConversation, useConversations, useMessageAction, useMessagingAi, useMessagingHost, useMessagingSnapshot, useOnlineUserIds, useRequiredMessagingHost, useTypists };
|
|
1541
|
+
export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, AgentTag, type AiCallArgs, type AiCapability, type AiResult, AlertIcon, type Attachment, Avatar, BotIcon, CheckIcon, ChevronLeftIcon, type ClientMessageId, ClockIcon, CloseIcon, Composer, type ComposerInputRenderProps, type Conversation, type ConversationCursor, type ConversationId, ConversationList, type ConversationListProps, type ConversationRowWrapperProps, ConversationSkeleton, type ConversationSummary, type ConversationThread, type ConversationType, ConversationView, type ConversationViewProps, type DeliveryState, DeliveryTick, DoubleCheckIcon, type DraftMessage, EmptyState, type EngineDiagnostic, type IncomingMessageContext, type JsonObject, type JsonValue, LinkIcon, MESSAGING_EVENTS, MESSAGING_RPC_SCHEMA, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, MessageActionChips, type MessageActionRenderProps, type MessageActionRenderer, MessageBubble, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessageWrapperProps, type MessagingAgentIdentity, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingHost, type MessagingIdentity, MessagingInbox, type MessagingInboxProps, MessagingProvider, type MessagingProviderProps, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type MessagingSupabaseClient, type MessagingSupabaseInternal, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, PaperclipIcon, type Participant, type ParticipantRole, PlusIcon, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, ReferenceCard, type ReferenceRenderer, ReplyIcon, type RepositoryOptions, type SchemaLike, SearchIcon, SendIcon, type SessionResolver, SparklesIcon, type SupabaseLike, TABLES, type TextSegment, TypingDots, type UseComposerResult, type UseConversationResult, type UseConversationsResult, type UseMessageActionResult, type UseMessagingAiResult, type UseTypistsResult, type UserId, type UserSummary, UsersIcon, 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, useComposer, useConversation, useConversations, useMessageAction, useMessagingAi, useMessagingHost, useMessagingSnapshot, useOnlineUserIds, useRequiredMessagingHost, useTypists };
|
package/dist/react.js
CHANGED
|
@@ -1956,18 +1956,20 @@ function groupMessages(messages, args = {}) {
|
|
|
1956
1956
|
let current = null;
|
|
1957
1957
|
let previousDay = null;
|
|
1958
1958
|
for (const message of messages) {
|
|
1959
|
+
const actorKey = args.actorKey?.(message) ?? `principal:${message.senderId}`;
|
|
1959
1960
|
const day = message.createdAt.slice(0, 10);
|
|
1960
1961
|
const startsNewDay = day !== previousDay;
|
|
1961
1962
|
previousDay = day;
|
|
1962
1963
|
const last = current?.messages.at(-1);
|
|
1963
1964
|
const withinWindow = last !== void 0 && Math.abs(Date.parse(message.createdAt) - Date.parse(last.createdAt)) <= windowMs;
|
|
1964
|
-
if (current !== null && current.senderId === message.senderId && withinWindow && !startsNewDay) {
|
|
1965
|
+
if (current !== null && current.senderId === message.senderId && current.actorKey === actorKey && withinWindow && !startsNewDay) {
|
|
1965
1966
|
current.messages.push(message);
|
|
1966
1967
|
continue;
|
|
1967
1968
|
}
|
|
1968
1969
|
if (current !== null) groups.push(current);
|
|
1969
1970
|
current = {
|
|
1970
1971
|
senderId: message.senderId,
|
|
1972
|
+
actorKey,
|
|
1971
1973
|
messages: [message],
|
|
1972
1974
|
dateSeparator: startsNewDay ? formatDateSeparator(message.createdAt, now, args.locale) : null
|
|
1973
1975
|
};
|
|
@@ -2285,23 +2287,45 @@ function useMessageAction(message) {
|
|
|
2285
2287
|
}
|
|
2286
2288
|
|
|
2287
2289
|
// src/react/components.tsx
|
|
2288
|
-
import {
|
|
2290
|
+
import {
|
|
2291
|
+
useEffect as useEffect3,
|
|
2292
|
+
useMemo as useMemo3,
|
|
2293
|
+
useRef as useRef3,
|
|
2294
|
+
useState as useState2
|
|
2295
|
+
} from "react";
|
|
2289
2296
|
|
|
2290
2297
|
// src/core/actor.ts
|
|
2291
2298
|
function readActorHint(metadata) {
|
|
2292
|
-
const
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
+
const envelope = metadata;
|
|
2300
|
+
const raw = envelope["actor"];
|
|
2301
|
+
if (typeof raw === "object" && raw !== null && !Array.isArray(raw)) {
|
|
2302
|
+
const record = raw;
|
|
2303
|
+
const agentId = record["agentId"] ?? record["agent_id"];
|
|
2304
|
+
if (typeof agentId !== "string" || agentId.length === 0) return null;
|
|
2305
|
+
const name2 = record["agentName"] ?? record["agent_name"];
|
|
2306
|
+
const avatar2 = record["agentAvatarUrl"] ?? record["agent_avatar_url"];
|
|
2307
|
+
return {
|
|
2308
|
+
agentId,
|
|
2309
|
+
...typeof name2 === "string" && name2.length > 0 ? { agentName: name2 } : {},
|
|
2310
|
+
...typeof avatar2 === "string" && avatar2.length > 0 ? { agentAvatarUrl: avatar2 } : {}
|
|
2311
|
+
};
|
|
2312
|
+
}
|
|
2313
|
+
const actorKind = envelope["actor_kind"] ?? envelope["actorKind"];
|
|
2314
|
+
if (actorKind !== "agent") return null;
|
|
2315
|
+
const id = envelope["actor_id"] ?? envelope["actorId"];
|
|
2316
|
+
const name = envelope["actor_label"] ?? envelope["actorLabel"];
|
|
2317
|
+
const avatar = envelope["actor_avatar_url"] ?? envelope["actorAvatarUrl"];
|
|
2299
2318
|
return {
|
|
2300
|
-
agentId,
|
|
2319
|
+
...typeof id === "string" && id.length > 0 ? { agentId: id } : {},
|
|
2301
2320
|
...typeof name === "string" && name.length > 0 ? { agentName: name } : {},
|
|
2302
2321
|
...typeof avatar === "string" && avatar.length > 0 ? { agentAvatarUrl: avatar } : {}
|
|
2303
2322
|
};
|
|
2304
2323
|
}
|
|
2324
|
+
function effectiveActorKey(message) {
|
|
2325
|
+
const hint = readActorHint(message.metadata);
|
|
2326
|
+
if (hint === null) return `principal:${message.senderId}`;
|
|
2327
|
+
return `agent:${hint.agentId ?? hint.agentName ?? "anonymous"}`;
|
|
2328
|
+
}
|
|
2305
2329
|
function resolveActor(message, sender) {
|
|
2306
2330
|
const hint = readActorHint(message.metadata);
|
|
2307
2331
|
const humanName = sender?.displayName ?? message.senderId;
|
|
@@ -2697,7 +2721,7 @@ function ConversationView(props) {
|
|
|
2697
2721
|
);
|
|
2698
2722
|
const anyOnline = others.some((participant) => online.has(participant.userId));
|
|
2699
2723
|
return /* @__PURE__ */ jsxs2("div", { className: `mx-msg__thread${props.className !== void 0 ? ` ${props.className}` : ""}`, children: [
|
|
2700
|
-
/* @__PURE__ */ jsxs2("header", { className: "mx-msg__header", children: [
|
|
2724
|
+
props.showHeader !== false ? /* @__PURE__ */ jsxs2("header", { className: "mx-msg__header", children: [
|
|
2701
2725
|
props.onBack !== void 0 ? /* @__PURE__ */ jsx4(
|
|
2702
2726
|
"button",
|
|
2703
2727
|
{
|
|
@@ -2732,8 +2756,8 @@ function ConversationView(props) {
|
|
|
2732
2756
|
children: /* @__PURE__ */ jsx4(UsersIcon, {})
|
|
2733
2757
|
}
|
|
2734
2758
|
) : null })
|
|
2735
|
-
] }),
|
|
2736
|
-
ai.available.length > 0 ? /* @__PURE__ */ jsx4("div", { className: "mx-msg__ai-bar", children: ai.available.map((capability) => /* @__PURE__ */ jsxs2(
|
|
2759
|
+
] }) : null,
|
|
2760
|
+
props.showAi !== false && ai.available.length > 0 ? /* @__PURE__ */ jsx4("div", { className: "mx-msg__ai-bar", children: ai.available.map((capability) => /* @__PURE__ */ jsxs2(
|
|
2737
2761
|
"button",
|
|
2738
2762
|
{
|
|
2739
2763
|
type: "button",
|
|
@@ -2747,7 +2771,7 @@ function ConversationView(props) {
|
|
|
2747
2771
|
},
|
|
2748
2772
|
capability
|
|
2749
2773
|
)) }) : null,
|
|
2750
|
-
ai.isRunning ? /* @__PURE__ */ jsx4("p", { className: "mx-msg__ai-output", "aria-busy": "true", "aria-live": "polite", children: ai.partialText.length > 0 ? ai.partialText : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
2774
|
+
props.showAi !== false && ai.isRunning ? /* @__PURE__ */ jsx4("p", { className: "mx-msg__ai-output", "aria-busy": "true", "aria-live": "polite", children: ai.partialText.length > 0 ? ai.partialText : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
2751
2775
|
/* @__PURE__ */ jsx4("span", { className: "mx-msg__ai-output-label", children: ai.activeCapability !== null ? `${AI_LABELS[ai.activeCapability]}\u2026` : "Working\u2026" }),
|
|
2752
2776
|
/* @__PURE__ */ jsx4(
|
|
2753
2777
|
"span",
|
|
@@ -2756,7 +2780,7 @@ function ConversationView(props) {
|
|
|
2756
2780
|
style: { display: "block", height: 11, width: "72%" }
|
|
2757
2781
|
}
|
|
2758
2782
|
)
|
|
2759
|
-
] }) }) : ai.error !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-msg__ai-output", style: { color: "var(--mx-msg-danger)" }, children: ai.error }) : ai.result !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-msg__ai-output", children: [
|
|
2783
|
+
] }) }) : props.showAi !== false && ai.error !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-msg__ai-output", style: { color: "var(--mx-msg-danger)" }, children: ai.error }) : props.showAi !== false && ai.result !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-msg__ai-output", children: [
|
|
2760
2784
|
ai.result.text,
|
|
2761
2785
|
/* @__PURE__ */ jsx4(
|
|
2762
2786
|
"button",
|
|
@@ -2781,26 +2805,24 @@ function ConversationView(props) {
|
|
|
2781
2805
|
children: "Load earlier messages"
|
|
2782
2806
|
}
|
|
2783
2807
|
) : null,
|
|
2784
|
-
groupMessages(messages).map((group) => {
|
|
2808
|
+
groupMessages(messages, { actorKey: effectiveActorKey }).map((group) => {
|
|
2785
2809
|
const first = group.messages[0];
|
|
2786
2810
|
if (first === void 0) return null;
|
|
2787
|
-
const isMine = group.senderId === selfId;
|
|
2788
2811
|
const sender = conversation.participants.find(
|
|
2789
2812
|
(participant) => participant.userId === group.senderId
|
|
2790
2813
|
) ?? null;
|
|
2814
|
+
const actor = resolveActor(first, sender);
|
|
2815
|
+
const isMine = group.senderId === selfId && !actor.isAgent;
|
|
2791
2816
|
return /* @__PURE__ */ jsxs2("div", { children: [
|
|
2792
2817
|
group.dateSeparator !== null ? /* @__PURE__ */ jsx4("div", { className: "mx-msg__day", children: group.dateSeparator }) : null,
|
|
2793
2818
|
/* @__PURE__ */ jsx4(
|
|
2794
2819
|
MessageGroupView,
|
|
2795
2820
|
{
|
|
2796
2821
|
messages: group.messages,
|
|
2797
|
-
|
|
2822
|
+
actor,
|
|
2798
2823
|
isMine,
|
|
2799
2824
|
onRetry: conversation.retry,
|
|
2800
2825
|
onReply: composer.setReplyTo,
|
|
2801
|
-
pendingIds: new Set(
|
|
2802
|
-
conversation.pending.filter((entry) => entry.state === "failed").map((entry) => entry.clientMessageId)
|
|
2803
|
-
),
|
|
2804
2826
|
failedEntryIdByClientId: new Map(
|
|
2805
2827
|
conversation.pending.map((entry) => [entry.clientMessageId, entry.id])
|
|
2806
2828
|
)
|
|
@@ -2813,13 +2835,20 @@ function ConversationView(props) {
|
|
|
2813
2835
|
/* @__PURE__ */ jsx4(TypingDots, {}),
|
|
2814
2836
|
typists.label
|
|
2815
2837
|
] }) : null }),
|
|
2816
|
-
/* @__PURE__ */ jsx4(
|
|
2838
|
+
/* @__PURE__ */ jsx4(
|
|
2839
|
+
ComposerView,
|
|
2840
|
+
{
|
|
2841
|
+
composer,
|
|
2842
|
+
disabled: false,
|
|
2843
|
+
...props.renderComposerInput !== void 0 ? { renderInput: props.renderComposerInput } : {}
|
|
2844
|
+
}
|
|
2845
|
+
)
|
|
2817
2846
|
] });
|
|
2818
2847
|
}
|
|
2819
2848
|
function MessageGroupView(props) {
|
|
2820
2849
|
const first = props.messages[0];
|
|
2821
2850
|
if (first === void 0) return null;
|
|
2822
|
-
const actor =
|
|
2851
|
+
const actor = props.actor;
|
|
2823
2852
|
return /* @__PURE__ */ jsxs2("div", { className: `mx-msg__group${props.isMine ? " mx-msg__group--mine" : ""}`, children: [
|
|
2824
2853
|
/* @__PURE__ */ jsx4(
|
|
2825
2854
|
Avatar,
|
|
@@ -3006,7 +3035,24 @@ function ComposerView(props) {
|
|
|
3006
3035
|
}
|
|
3007
3036
|
)
|
|
3008
3037
|
] }) : null,
|
|
3009
|
-
|
|
3038
|
+
props.renderInput !== void 0 ? props.renderInput({
|
|
3039
|
+
value: composer.value,
|
|
3040
|
+
disabled: props.disabled,
|
|
3041
|
+
canSend: composer.canSend,
|
|
3042
|
+
placeholder: "Write a reply\u2026",
|
|
3043
|
+
onChange: (value) => {
|
|
3044
|
+
composer.setValue(value);
|
|
3045
|
+
composer.onKeystroke();
|
|
3046
|
+
},
|
|
3047
|
+
onKeyDown: (event) => {
|
|
3048
|
+
if (event.key !== "Enter" || event.shiftKey) return;
|
|
3049
|
+
const isTouch = typeof globalThis.matchMedia === "function" && globalThis.matchMedia("(pointer: coarse)").matches;
|
|
3050
|
+
if (isTouch) return;
|
|
3051
|
+
event.preventDefault();
|
|
3052
|
+
composer.send();
|
|
3053
|
+
},
|
|
3054
|
+
onSubmit: composer.send
|
|
3055
|
+
}) : /* @__PURE__ */ jsxs2("div", { className: "mx-msg__composer-row", children: [
|
|
3010
3056
|
/* @__PURE__ */ jsx4(
|
|
3011
3057
|
"textarea",
|
|
3012
3058
|
{
|
|
@@ -3137,6 +3183,7 @@ export {
|
|
|
3137
3183
|
createOutbox,
|
|
3138
3184
|
createReadCache,
|
|
3139
3185
|
createWebOutboxStorage,
|
|
3186
|
+
effectiveActorKey,
|
|
3140
3187
|
extractReferences,
|
|
3141
3188
|
formatConversationTime,
|
|
3142
3189
|
formatDateSeparator,
|