@happyvertical/smrt-chat 0.30.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.
Files changed (169) hide show
  1. package/AGENTS.md +35 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +7 -0
  4. package/README.md +163 -0
  5. package/dist/__smrt-register__.d.ts +2 -0
  6. package/dist/__smrt-register__.d.ts.map +1 -0
  7. package/dist/chunks/ChatService-Dpzc1Pa5.js +2044 -0
  8. package/dist/chunks/ChatService-Dpzc1Pa5.js.map +1 -0
  9. package/dist/collections/AgentSessionCollection.d.ts +57 -0
  10. package/dist/collections/AgentSessionCollection.d.ts.map +1 -0
  11. package/dist/collections/ChatMessageCollection.d.ts +79 -0
  12. package/dist/collections/ChatMessageCollection.d.ts.map +1 -0
  13. package/dist/collections/ChatParticipantCollection.d.ts +26 -0
  14. package/dist/collections/ChatParticipantCollection.d.ts.map +1 -0
  15. package/dist/collections/ChatReactionCollection.d.ts +23 -0
  16. package/dist/collections/ChatReactionCollection.d.ts.map +1 -0
  17. package/dist/collections/ChatRoomCollection.d.ts +43 -0
  18. package/dist/collections/ChatRoomCollection.d.ts.map +1 -0
  19. package/dist/collections/ChatThreadCollection.d.ts +9 -0
  20. package/dist/collections/ChatThreadCollection.d.ts.map +1 -0
  21. package/dist/index.d.ts +5 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +18 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/internal/agent-runtime.d.ts +16 -0
  26. package/dist/internal/agent-runtime.d.ts.map +1 -0
  27. package/dist/internal/agent-runtime.js +5 -0
  28. package/dist/internal/agent-runtime.js.map +1 -0
  29. package/dist/manifest.json +2811 -0
  30. package/dist/models/AgentSession.d.ts +70 -0
  31. package/dist/models/AgentSession.d.ts.map +1 -0
  32. package/dist/models/ChatMessage.d.ts +55 -0
  33. package/dist/models/ChatMessage.d.ts.map +1 -0
  34. package/dist/models/ChatParticipant.d.ts +32 -0
  35. package/dist/models/ChatParticipant.d.ts.map +1 -0
  36. package/dist/models/ChatReaction.d.ts +19 -0
  37. package/dist/models/ChatReaction.d.ts.map +1 -0
  38. package/dist/models/ChatRoom.d.ts +44 -0
  39. package/dist/models/ChatRoom.d.ts.map +1 -0
  40. package/dist/models/ChatThread.d.ts +24 -0
  41. package/dist/models/ChatThread.d.ts.map +1 -0
  42. package/dist/models/index.d.ts +7 -0
  43. package/dist/models/index.d.ts.map +1 -0
  44. package/dist/playground.d.ts +2 -0
  45. package/dist/playground.d.ts.map +1 -0
  46. package/dist/playground.js +166 -0
  47. package/dist/playground.js.map +1 -0
  48. package/dist/services/ChatService.d.ts +390 -0
  49. package/dist/services/ChatService.d.ts.map +1 -0
  50. package/dist/services/index.d.ts +2 -0
  51. package/dist/services/index.d.ts.map +1 -0
  52. package/dist/smrt-knowledge.json +1507 -0
  53. package/dist/svelte/components/agent/AgentChat.svelte +542 -0
  54. package/dist/svelte/components/agent/AgentChat.svelte.d.ts +21 -0
  55. package/dist/svelte/components/agent/AgentChat.svelte.d.ts.map +1 -0
  56. package/dist/svelte/components/agent/AgentSelector.svelte +175 -0
  57. package/dist/svelte/components/agent/AgentSelector.svelte.d.ts +11 -0
  58. package/dist/svelte/components/agent/AgentSelector.svelte.d.ts.map +1 -0
  59. package/dist/svelte/components/agent/AgentSessionPanel.svelte +322 -0
  60. package/dist/svelte/components/agent/AgentSessionPanel.svelte.d.ts +15 -0
  61. package/dist/svelte/components/agent/AgentSessionPanel.svelte.d.ts.map +1 -0
  62. package/dist/svelte/components/agent/ToolCallDisplay.svelte +335 -0
  63. package/dist/svelte/components/agent/ToolCallDisplay.svelte.d.ts +9 -0
  64. package/dist/svelte/components/agent/ToolCallDisplay.svelte.d.ts.map +1 -0
  65. package/dist/svelte/components/agent/message-blocks.d.ts +12 -0
  66. package/dist/svelte/components/agent/message-blocks.d.ts.map +1 -0
  67. package/dist/svelte/components/agent/message-blocks.js +41 -0
  68. package/dist/svelte/components/agent/message-blocks.test.js +31 -0
  69. package/dist/svelte/components/dialogs/RoomCreateDialog.svelte +403 -0
  70. package/dist/svelte/components/dialogs/RoomCreateDialog.svelte.d.ts +16 -0
  71. package/dist/svelte/components/dialogs/RoomCreateDialog.svelte.d.ts.map +1 -0
  72. package/dist/svelte/components/dialogs/SearchMessages.svelte +457 -0
  73. package/dist/svelte/components/dialogs/SearchMessages.svelte.d.ts +17 -0
  74. package/dist/svelte/components/dialogs/SearchMessages.svelte.d.ts.map +1 -0
  75. package/dist/svelte/components/layout/ChatLayout.svelte +150 -0
  76. package/dist/svelte/components/layout/ChatLayout.svelte.d.ts +18 -0
  77. package/dist/svelte/components/layout/ChatLayout.svelte.d.ts.map +1 -0
  78. package/dist/svelte/components/layout/MemberList.svelte +389 -0
  79. package/dist/svelte/components/layout/MemberList.svelte.d.ts +11 -0
  80. package/dist/svelte/components/layout/MemberList.svelte.d.ts.map +1 -0
  81. package/dist/svelte/components/layout/RoomHeader.svelte +241 -0
  82. package/dist/svelte/components/layout/RoomHeader.svelte.d.ts +15 -0
  83. package/dist/svelte/components/layout/RoomHeader.svelte.d.ts.map +1 -0
  84. package/dist/svelte/components/layout/RoomList.svelte +471 -0
  85. package/dist/svelte/components/layout/RoomList.svelte.d.ts +15 -0
  86. package/dist/svelte/components/layout/RoomList.svelte.d.ts.map +1 -0
  87. package/dist/svelte/components/messages/MessageInput.svelte +232 -0
  88. package/dist/svelte/components/messages/MessageInput.svelte.d.ts +20 -0
  89. package/dist/svelte/components/messages/MessageInput.svelte.d.ts.map +1 -0
  90. package/dist/svelte/components/messages/MessageItem.svelte +431 -0
  91. package/dist/svelte/components/messages/MessageItem.svelte.d.ts +19 -0
  92. package/dist/svelte/components/messages/MessageItem.svelte.d.ts.map +1 -0
  93. package/dist/svelte/components/messages/MessageList.svelte +129 -0
  94. package/dist/svelte/components/messages/MessageList.svelte.d.ts +17 -0
  95. package/dist/svelte/components/messages/MessageList.svelte.d.ts.map +1 -0
  96. package/dist/svelte/components/messages/ThreadPanel.svelte +156 -0
  97. package/dist/svelte/components/messages/ThreadPanel.svelte.d.ts +17 -0
  98. package/dist/svelte/components/messages/ThreadPanel.svelte.d.ts.map +1 -0
  99. package/dist/svelte/components/messages/__tests__/MessageInput.test.js +38 -0
  100. package/dist/svelte/components/shared/Avatar.svelte +30 -0
  101. package/dist/svelte/components/shared/Avatar.svelte.d.ts +14 -0
  102. package/dist/svelte/components/shared/Avatar.svelte.d.ts.map +1 -0
  103. package/dist/svelte/components/shared/FileUpload.svelte +382 -0
  104. package/dist/svelte/components/shared/FileUpload.svelte.d.ts +14 -0
  105. package/dist/svelte/components/shared/FileUpload.svelte.d.ts.map +1 -0
  106. package/dist/svelte/components/shared/LinkPreview.svelte +108 -0
  107. package/dist/svelte/components/shared/LinkPreview.svelte.d.ts +18 -0
  108. package/dist/svelte/components/shared/LinkPreview.svelte.d.ts.map +1 -0
  109. package/dist/svelte/components/shared/MentionAutocomplete.svelte +168 -0
  110. package/dist/svelte/components/shared/MentionAutocomplete.svelte.d.ts +18 -0
  111. package/dist/svelte/components/shared/MentionAutocomplete.svelte.d.ts.map +1 -0
  112. package/dist/svelte/components/shared/MessageBubble.svelte +81 -0
  113. package/dist/svelte/components/shared/MessageBubble.svelte.d.ts +16 -0
  114. package/dist/svelte/components/shared/MessageBubble.svelte.d.ts.map +1 -0
  115. package/dist/svelte/components/shared/ReactionPicker.svelte +103 -0
  116. package/dist/svelte/components/shared/ReactionPicker.svelte.d.ts +10 -0
  117. package/dist/svelte/components/shared/ReactionPicker.svelte.d.ts.map +1 -0
  118. package/dist/svelte/components/shared/ReadReceipts.svelte +127 -0
  119. package/dist/svelte/components/shared/ReadReceipts.svelte.d.ts +13 -0
  120. package/dist/svelte/components/shared/ReadReceipts.svelte.d.ts.map +1 -0
  121. package/dist/svelte/components/shared/TypingIndicator.svelte +90 -0
  122. package/dist/svelte/components/shared/TypingIndicator.svelte.d.ts +12 -0
  123. package/dist/svelte/components/shared/TypingIndicator.svelte.d.ts.map +1 -0
  124. package/dist/svelte/components/shared/UserPresence.svelte +65 -0
  125. package/dist/svelte/components/shared/UserPresence.svelte.d.ts +13 -0
  126. package/dist/svelte/components/shared/UserPresence.svelte.d.ts.map +1 -0
  127. package/dist/svelte/components/shared/__tests__/Avatar.test.js +20 -0
  128. package/dist/svelte/components/shared/__tests__/LinkPreview.test.js +29 -0
  129. package/dist/svelte/components/shared/__tests__/MessageBubble.test.js +21 -0
  130. package/dist/svelte/components/shared/__tests__/ReactionPicker.test.js +35 -0
  131. package/dist/svelte/components/shared/__tests__/ReadReceipts.test.js +28 -0
  132. package/dist/svelte/components/shared/__tests__/TypingIndicator.test.js +27 -0
  133. package/dist/svelte/components/shared/__tests__/UserPresence.test.js +23 -0
  134. package/dist/svelte/components/tabs/ChatTab.svelte +240 -0
  135. package/dist/svelte/components/tabs/ChatTab.svelte.d.ts +21 -0
  136. package/dist/svelte/components/tabs/ChatTab.svelte.d.ts.map +1 -0
  137. package/dist/svelte/components/tabs/ChatTabList.svelte +158 -0
  138. package/dist/svelte/components/tabs/ChatTabList.svelte.d.ts +13 -0
  139. package/dist/svelte/components/tabs/ChatTabList.svelte.d.ts.map +1 -0
  140. package/dist/svelte/components/tabs/ChatTabs.svelte +88 -0
  141. package/dist/svelte/components/tabs/ChatTabs.svelte.d.ts +21 -0
  142. package/dist/svelte/components/tabs/ChatTabs.svelte.d.ts.map +1 -0
  143. package/dist/svelte/components/tabs/MiniChat.svelte +253 -0
  144. package/dist/svelte/components/tabs/MiniChat.svelte.d.ts +15 -0
  145. package/dist/svelte/components/tabs/MiniChat.svelte.d.ts.map +1 -0
  146. package/dist/svelte/i18n.d.ts +51 -0
  147. package/dist/svelte/i18n.d.ts.map +1 -0
  148. package/dist/svelte/i18n.js +72 -0
  149. package/dist/svelte/i18n.messages.d.ts +50 -0
  150. package/dist/svelte/i18n.messages.d.ts.map +1 -0
  151. package/dist/svelte/i18n.messages.js +69 -0
  152. package/dist/svelte/index.d.ts +48 -0
  153. package/dist/svelte/index.d.ts.map +1 -0
  154. package/dist/svelte/index.js +117 -0
  155. package/dist/svelte/playground.d.ts +171 -0
  156. package/dist/svelte/playground.d.ts.map +1 -0
  157. package/dist/svelte/playground.js +161 -0
  158. package/dist/svelte/types.d.ts +116 -0
  159. package/dist/svelte/types.d.ts.map +1 -0
  160. package/dist/svelte/types.js +1 -0
  161. package/dist/types.d.ts +99 -0
  162. package/dist/types.d.ts.map +1 -0
  163. package/dist/types.js +2 -0
  164. package/dist/types.js.map +1 -0
  165. package/dist/ui.d.ts +4 -0
  166. package/dist/ui.d.ts.map +1 -0
  167. package/dist/ui.js +92 -0
  168. package/dist/ui.js.map +1 -0
  169. package/package.json +95 -0
package/AGENTS.md ADDED
@@ -0,0 +1,35 @@
1
+ # @happyvertical/smrt-chat
2
+
3
+ Chat rooms, threads, and agent sessions with app-controlled tool whitelisting.
4
+
5
+ ## Models
6
+
7
+ Internal models — all mutations go through the membership/owner-checked `ChatService` (S5 #1392). EVERY `@smrt()` model in this package (ChatRoom, ChatMessage, ChatParticipant, ChatThread, ChatReaction, AgentSession) has a READ-ONLY generated REST/MCP surface (`list`/`get` only); `create`/`update`/`delete` are intentionally NOT generated so the raw collection routes cannot skip the service-layer authorization. A structural regression test enumerates the registry to assert no chat model exposes a mutating op.
8
+
9
+ `ChatService` is a CLOSED FACADE (S5 #1392). The raw collections (`rooms`, `messages`, `participants`, `threads`, `agentSessions`, `reactions`) are ES `#private` fields — they are NOT on the public `ChatService` type and the package index does NOT export the collection classes, so a consumer cannot do `chat.messages.create({senderProfileId, role})` / `new ChatParticipantCollection(...)` to mutate around the authorization. The security-sensitive internals (`#writeMessage`, `#emitAgentReply`, `#enrollParticipant`, `#loadActiveSession`, `#requireActiveMembership`, `#requireRoomAdmin`, `#extractToolName`) are ES `#private` too, so they are unreachable at runtime — TypeScript `private` alone is erased and would leave them callable on the prototype. The agent-reply bridge is a `Symbol`-keyed static (not the old enumerable `_runAgentReply`), reachable only by the module-local `sendAgentReply` that holds the non-exported symbol.
10
+
11
+ - **ChatRoom**: `roomType` (public/private/dm/agent), `status`, `topic`, `maxParticipants`, `lastMessageAt`. Tenant-scoped (required).
12
+ - **ChatMessage**: shared by users + agents. `role` (user/assistant/system/tool), `messageType` (text/system/action/file/tool_call/tool_result), `toolCallData` JSON. Unified model — no separate agent message type. Tenant-scoped (required).
13
+ - **ChatParticipant**: `role` (owner/admin/member/viewer), `onlineStatus`, `lastReadMessageId`, `isMuted`. Tenant-scoped (required).
14
+ - **ChatThread**: `rootMessageId`, `isResolved`, `messageCount`. Created via `ChatService.startThread()` (member-checked). Tenant-scoped (required).
15
+ - **ChatReaction**: `messageId`, `profileId`, `emoji`. Added/removed via `ChatService.addReaction()`/`removeReaction()` (member-checked, self-keyed). Tenant-scoped (required).
16
+ - **AgentSession**: `agentId` (string ref, not FK), `allowedTools` (JSON string array), `sessionContext` (JSON), `systemPrompt`, limits (`maxTokens`/`maxMessages`/`expiresAt`). Optional tenancy.
17
+
18
+ ## ChatService
19
+
20
+ Every public write takes an explicit server-supplied `actorProfileId` (the authenticated principal the route injects) — never a caller-controlled `senderProfileId`/`role` (S5 #1392).
21
+
22
+ Facade: `sendMessage()` (authors as the actor with `role: 'user'`; room-membership-checked; no caller-supplied sender/role and no public membership-skip), `createRoom()` (acting actor becomes owner — no caller-supplied `createdByProfileId`), `startThread()` (member-checked; optional `rootMessageId` bound to the same room+tenant), `addParticipant()`/`removeParticipant()` (owner/admin-checked; self-leave allowed), `updateRoom()` (owner/admin-checked), `addReaction()`/`removeReaction()` (member-checked, self-keyed), `getOrCreateDM()` (actor must be a DM participant), `createAgentSession()` (acting actor becomes the session participant — no caller-supplied `participantProfileId`; the existing-session room lookup is tenant-bound; optional `sessionKey` scopes session identity to a conversation subject so distinct keys get distinct sessions/rooms and a session opened for one subject is never reused/rewritten for another). Tenant-bound read facade (replaces raw-collection reach-ins; consumers apply their own ownership/context checks on the returned rows): `getAgentSession({agentSessionId, tenantId})`, `findActiveAgentSessions({tenantId, agentId, participantProfileId})`, `getThread({threadId, tenantId})`, `listRoomThreads({roomId, actorProfileId, tenantId})` (membership-gated), `getThreadMessages({threadId, actorProfileId, tenantId, limit?})` (membership-gated, chronological), `getRoomMessages({roomId, actorProfileId, tenantId})`/`getRoomForMember(roomId, actorProfileId, tenantId)` (membership-checked reads gated on the server-supplied `actorProfileId`, never a caller-controlled subject id — confused-deputy avoidance; `tenantId` required), `updateAgentSessionConfig()` (owner-checked; `tenantId` mandatory and bound into the lookup). Agent session messaging is split by authority: `sendAgentUserMessage()` (caller `actorProfileId` must be the session participant; always authored as the participant). The agent-authored reply path `sendAgentReply(service, params)` is an exported **function — NOT a `ChatService` method and NOT on the package index**; it is reachable only via the dedicated `@happyvertical/smrt-chat/internal/agent-runtime` subpath (S5 #1392), so only trusted in-process agent-runtime code that explicitly opts into that subpath can author as the agent. It authors as `session.agentId`, accepts an optional same-room/tenant `threadId`, and gates tool calls fail-closed against `allowedTools`. The shared internal persistence path (`writeMessage`) is private — it alone may author an arbitrary profile/role or skip the membership check, and is unreachable from any route; it also validates every supplied `threadId`/`agentSessionId`/`replyToMessageId` belongs to the SAME room AND tenant (tenant/room-bound lookups) before use, rejecting cross-room/cross-tenant references. Auto-creates rooms/sessions/participants via an internal `enrollParticipant`.
23
+
24
+ ## Agent Tool Whitelisting
25
+
26
+ `allowedTools` is a JSON array controlled by the consuming app. Fail-closed: an empty/unparseable whitelist permits NO tools. The internal `sendAgentReply(service, params)` function enforces the whitelist before emitting any `tool`/`tool_call` message; a caller cannot supply a `senderProfileId`/`role` to post as the agent, and the function is not reachable from the package index.
27
+
28
+ ## Gotchas
29
+
30
+ - **sessionContext, not context**: `context` is reserved for slug scoping. Use `getSessionContext()`/`updateSessionContext()` for agent memory.
31
+ - **Agent rooms auto-created**: `roomType: 'agent'`, `maxParticipants` defaults to 2; the agent is enrolled as a member so its replies pass the membership check. `createAgentSession()` re-enrolls the participant AND the agent on the existing-session path, so legacy sessions created before the agent was enrolled self-heal.
32
+ - **Per-subject sessions need `sessionKey`**: `createAgentSession()` reuses ANY active session for the same `(agentId, participantProfileId, tenantId)`. Callers that open separate conversations per subject (e.g. one content-editor session per content id) MUST pass a stable `sessionKey` (stored in `sessionContext.__sessionKey`, read via `AgentSession.getSessionKey()`); otherwise a session opened for one subject is reused and its context overwritten for another, surfacing the wrong room/threads (S5 #1392). A keyed create never reuses a keyless/legacy session.
33
+ - **Session expiry**: check `isActive()` before allowing messages (expiresAt or limit-based)
34
+ - **DM identity**: derived from the deterministic per-tenant `canonicalDmRoomId()` and the authoritative `chat_participants` join, not client metadata; concurrent creates upsert onto one row.
35
+ - **Tenant-bound lookups**: membership/session/DM lookups REQUIRE `tenantId` and always bind it into the WHERE clause (`findActiveMembership`/`isActiveMember`/`findActiveSession` take a required `tenantId`; AgentSession's `null` tenant is an explicit bound scope, not "any tenant") so they can never resolve a row from another tenant.
package/CLAUDE.md ADDED
@@ -0,0 +1 @@
1
+ @AGENTS.md
package/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright <2025> <Happy Vertical Corporation>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,163 @@
1
+ # @happyvertical/smrt-chat
2
+
3
+ Chat rooms, DMs, threads, and agent conversations for the SMRT framework. Supports public, private, DM, and agent-type rooms with threaded messages, reactions, and agent sessions with tool whitelisting.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @happyvertical/smrt-chat
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Rooms and messages
14
+
15
+ ```typescript
16
+ import { ChatService } from '@happyvertical/smrt-chat';
17
+
18
+ const chat = await ChatService.create({
19
+ persistence: { type: 'sql', url: 'chat.db' },
20
+ });
21
+
22
+ // `actorProfileId` is the authenticated principal the route injects. Every
23
+ // write takes it explicitly; the caller never supplies a `senderProfileId`,
24
+ // `role`, or `createdByProfileId` (S5 #1392).
25
+
26
+ // Create a public room (the acting actor becomes the owner)
27
+ const room = await chat.createRoom({
28
+ tenantId: 'tenant-1',
29
+ name: 'General',
30
+ roomType: 'public',
31
+ actorProfileId: 'profile-1',
32
+ });
33
+
34
+ // Send a message (always authored as the actor with role 'user')
35
+ const message = await chat.sendMessage({
36
+ tenantId: 'tenant-1',
37
+ roomId: room.id,
38
+ actorProfileId: 'profile-1',
39
+ content: 'Hello, world!',
40
+ });
41
+
42
+ // Start a threaded conversation from a message (member-checked)
43
+ const thread = await chat.startThread({
44
+ tenantId: 'tenant-1',
45
+ roomId: room.id,
46
+ actorProfileId: 'profile-1',
47
+ rootMessageId: message.id,
48
+ title: 'Follow-up discussion',
49
+ });
50
+
51
+ // Reply within the thread. The thread (and any reply-to message) must belong
52
+ // to the same room and tenant, or the write is rejected.
53
+ await chat.sendMessage({
54
+ tenantId: 'tenant-1',
55
+ roomId: room.id,
56
+ actorProfileId: 'profile-2',
57
+ content: 'Great point!',
58
+ threadId: thread.id,
59
+ });
60
+ ```
61
+
62
+ ### Agent sessions with tool whitelisting
63
+
64
+ ```typescript
65
+ // Create an agent session (auto-creates an agent-type room). The acting actor
66
+ // becomes the owning participant; the caller cannot open a session for someone
67
+ // else by supplying a participant id.
68
+ const { session, room } = await chat.createAgentSession({
69
+ tenantId: 'tenant-1',
70
+ agentId: 'agent-summarizer',
71
+ actorProfileId: 'profile-1',
72
+ allowedTools: ['web-search', 'summarize'],
73
+ systemPrompt: 'You are a research assistant.',
74
+ maxMessages: 100,
75
+ });
76
+
77
+ // Send a USER message within the agent session. The caller must be the
78
+ // session participant; the message is always authored as that participant.
79
+ await chat.sendAgentUserMessage({
80
+ tenantId: 'tenant-1',
81
+ agentSessionId: session.id,
82
+ actorProfileId: 'profile-1',
83
+ content: 'Summarize the latest news',
84
+ });
85
+
86
+ // Emit the agent's reply. This is the INTERNAL trusted authority that authors
87
+ // a message AS the agent, so it is intentionally NOT a public ChatService
88
+ // method and NOT on the package index. It is reachable only via the dedicated
89
+ // `./internal/agent-runtime` subpath, which a normal route/consumer importing
90
+ // from '@happyvertical/smrt-chat' cannot reach. Opting into this subpath
91
+ // signals the importer IS the trusted in-process agent runtime. Tool calls are
92
+ // gated fail-closed against the session's allowedTools.
93
+ import { sendAgentReply } from '@happyvertical/smrt-chat/internal/agent-runtime';
94
+ await sendAgentReply(chat, {
95
+ tenantId: 'tenant-1',
96
+ agentSessionId: session.id,
97
+ content: 'Here is the summary...',
98
+ kind: 'assistant',
99
+ });
100
+
101
+ // Check session limits before allowing more messages
102
+ if (session.isActive()) {
103
+ // Session has not expired or hit token/message limits
104
+ }
105
+ ```
106
+
107
+ ### Direct messages
108
+
109
+ ```typescript
110
+ // Get or create a DM room between two profiles. The acting actor must be one
111
+ // of the two DM participants.
112
+ const dmRoom = await chat.getOrCreateDM({
113
+ tenantId: 'tenant-1',
114
+ actorProfileId: 'profile-1',
115
+ profileId1: 'profile-1',
116
+ profileId2: 'profile-2',
117
+ });
118
+ ```
119
+
120
+ ## API
121
+
122
+ ### Models
123
+
124
+ | Export | Description |
125
+ |--------|------------|
126
+ | `ChatRoom` | Room with type (`public`/`private`/`dm`/`agent`), status, topic, and metadata |
127
+ | `ChatMessage` | Message with `role` (user/assistant/system/tool), `messageType` (text/system/action/file/tool_call/tool_result), optional thread and reply references |
128
+ | `ChatParticipant` | Room member with `role` (owner/admin/member/viewer), online status, read tracking |
129
+ | `ChatThread` | Threaded conversation linked to a root message, with resolve/reopen lifecycle |
130
+ | `ChatReaction` | Emoji reaction on a message |
131
+ | `AgentSession` | AI agent session with `allowedTools` (JSON string array), `sessionContext` for multi-turn memory, `systemPrompt`, and usage limits (`maxTokens`/`maxMessages`/`expiresAt`) |
132
+
133
+ ### Collections
134
+
135
+ | Export | Description |
136
+ |--------|------------|
137
+ | `ChatRoomCollection` | Room queries, `findOrCreateDM()` |
138
+ | `ChatMessageCollection` | Message queries and search filters |
139
+ | `ChatParticipantCollection` | Participant queries, `findMembership()` |
140
+ | `ChatThreadCollection` | Thread queries |
141
+ | `ChatReactionCollection` | Reaction queries |
142
+ | `AgentSessionCollection` | Session queries, `findActiveSession()`, `findOrCreate()` |
143
+
144
+ ### Services
145
+
146
+ | Export | Description |
147
+ |--------|------------|
148
+ | `ChatService` | Facade: `createRoom()`, `sendMessage()`, `startThread()`, `addParticipant()`, `removeParticipant()`, `updateRoom()`, `addReaction()`, `removeReaction()`, `getOrCreateDM()`, `createAgentSession()`, `sendAgentUserMessage()`, `getRoomMessages()`, `getRoomForMember()`, `updateAgentSessionConfig()`. Every write takes a server-supplied `actorProfileId`. The agent-authored reply path (`sendAgentReply`) is intentionally NOT on this facade or the package index — it is an internal function in `services/ChatService.ts` for the trusted in-process agent runtime only (S5 #1392). |
149
+
150
+ ### Types
151
+
152
+ `ChatRoomType`, `ChatRoomStatus`, `ChatRoomOptions`, `ChatMessageType`, `ChatMessageRole`, `ChatMessageOptions`, `ChatMessageSearchFilters`, `ChatParticipantRole`, `ChatParticipantStatus`, `ChatParticipantOptions`, `OnlineStatus`, `ChatThreadOptions`, `ChatReactionOptions`, `AgentSessionStatus`, `AgentSessionOptions`
153
+
154
+ ### Constants
155
+
156
+ `CHAT_MODULE_META`, `CHAT_UI_SLOTS`
157
+
158
+ ## Dependencies
159
+
160
+ - `@happyvertical/smrt-core` -- ORM and code generation
161
+ - `@happyvertical/smrt-tenancy` -- multi-tenant scoping
162
+ - `@happyvertical/smrt-types` -- shared type definitions
163
+ - Peer (optional): `@happyvertical/smrt-agents`, `@happyvertical/smrt-profiles`, `@happyvertical/smrt-svelte`
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=__smrt-register__.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"__smrt-register__.d.ts","sourceRoot":"","sources":["../src/__smrt-register__.ts"],"names":[],"mappings":""}