@happyvertical/smrt-chat 0.51.31 → 0.51.33

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.
@@ -0,0 +1,8 @@
1
+ import type { DatabaseInterface } from '@happyvertical/sql';
2
+ import '../index.js';
3
+ export declare function createChatTestDatabase(url: string): Promise<DatabaseInterface>;
4
+ export declare function seedChatRoom(db: DatabaseInterface, id?: string): Promise<void>;
5
+ export declare function seedChatMessage(db: DatabaseInterface, id?: string, roomId?: string): Promise<void>;
6
+ export declare function seedChatThread(db: DatabaseInterface, id: string, rootMessageId?: string): Promise<void>;
7
+ export declare function seedAgentSession(db: DatabaseInterface, id: string): Promise<void>;
8
+ //# sourceMappingURL=chat-test-db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-test-db.d.ts","sourceRoot":"","sources":["../../src/__tests__/chat-test-db.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,aAAa,CAAC;AAgBrB,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,iBAAiB,CAAC,CAE5B;AAED,wBAAsB,YAAY,CAChC,EAAE,EAAE,iBAAiB,EACrB,EAAE,SAAW,GACZ,OAAO,CAAC,IAAI,CAAC,CASf;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,iBAAiB,EACrB,EAAE,SAAU,EACZ,MAAM,SAAW,GAChB,OAAO,CAAC,IAAI,CAAC,CASf;AAED,wBAAsB,cAAc,CAClC,EAAE,EAAE,iBAAiB,EACrB,EAAE,EAAE,MAAM,EACV,aAAa,SAA2B,GACvC,OAAO,CAAC,IAAI,CAAC,CAQf;AAED,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,iBAAiB,EACrB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,IAAI,CAAC,CASf"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Test-only access to the raw chat collections (S5 #1392).
3
+ *
4
+ * The `ChatService` collections are `#private` and the package index no longer
5
+ * exports the collection classes, so production consumers can only mutate chat
6
+ * state through the authorized facade. Security regression tests, however, must
7
+ * sometimes forge a row that "slipped past" the facade or read a row directly to
8
+ * assert tenant binding. They obtain the collections from the `ObjectRegistry`
9
+ * — the same registry `ChatService.create()` registers into — rather than
10
+ * reaching into the service's private fields. This keeps the production surface
11
+ * closed while letting tests exercise the collection layer.
12
+ */
13
+ import { type SmrtObjectOptions } from '@happyvertical/smrt-core';
14
+ import type { AgentSessionCollection } from '../collections/AgentSessionCollection.js';
15
+ import type { ChatMessageCollection } from '../collections/ChatMessageCollection.js';
16
+ import type { ChatParticipantCollection } from '../collections/ChatParticipantCollection.js';
17
+ import type { ChatReactionCollection } from '../collections/ChatReactionCollection.js';
18
+ import type { ChatRoomCollection } from '../collections/ChatRoomCollection.js';
19
+ import type { ChatThreadCollection } from '../collections/ChatThreadCollection.js';
20
+ import type { VoiceSessionCollection } from '../collections/VoiceSessionCollection.js';
21
+ export interface RawChatCollections {
22
+ rooms: ChatRoomCollection;
23
+ messages: ChatMessageCollection;
24
+ participants: ChatParticipantCollection;
25
+ threads: ChatThreadCollection;
26
+ agentSessions: AgentSessionCollection;
27
+ reactions: ChatReactionCollection;
28
+ voiceSessions: VoiceSessionCollection;
29
+ }
30
+ /**
31
+ * Resolve the raw chat collections from the registry for the given DB options.
32
+ * Must be called after `ChatService.create(options)` has registered them.
33
+ */
34
+ export declare function getRawChatCollections(options: SmrtObjectOptions): Promise<RawChatCollections>;
35
+ //# sourceMappingURL=raw-collections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raw-collections.d.ts","sourceRoot":"","sources":["../../src/__tests__/raw-collections.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AACvF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AACrF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AAC7F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AACvF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AACnF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAEvF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,qBAAqB,CAAC;IAChC,YAAY,EAAE,yBAAyB,CAAC;IACxC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,aAAa,EAAE,sBAAsB,CAAC;IACtC,SAAS,EAAE,sBAAsB,CAAC;IAClC,aAAa,EAAE,sBAAsB,CAAC;CACvC;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,kBAAkB,CAAC,CAsC7B"}
@@ -1,5 +1,24 @@
1
- import { LearningMemoryRecord, LearningSemanticSearch, SmrtClassOptions } from '@happyvertical/smrt-core';
2
- import { Feedback, FeedbackSignalType } from '@happyvertical/smrt-personas';
1
+ /**
2
+ * Chat feedback capture — turn an in-conversation judgement into a first-class
3
+ * learning signal (L3 of the learning-agents epic, #1891).
4
+ *
5
+ * A tenant end-user accepting or rejecting an applied change, giving a
6
+ * thumbs-up/down, or typing an inline correction produces a {@link Feedback}
7
+ * row — carrying the conversation's **correlation-id** back to the turn it
8
+ * judges — and (by default) immediately reinforces the persona's learning
9
+ * memory. Because recall draws on that same memory next turn, captured feedback
10
+ * *influences subsequent behaviour*: a rejected strategy decays below the reuse
11
+ * floor and stops resurfacing; a correction supersedes it with the corrected
12
+ * value.
13
+ *
14
+ * This is the human-signal half of the loop the personas package already models
15
+ * ({@link reinforceFromFeedback}); the gated half — rewriting a persona's
16
+ * instructions — stays in the directive-proposal flow.
17
+ *
18
+ * @module
19
+ */
20
+ import type { LearningMemoryRecord, LearningSemanticSearch, SmrtClassOptions } from '@happyvertical/smrt-core';
21
+ import { type Feedback, type FeedbackSignalType } from '@happyvertical/smrt-personas';
3
22
  /** The minimal persona shape chat feedback needs to route the signal. */
4
23
  export interface ChatFeedbackPersona {
5
24
  /** Persona id — required (a signal always judges a specific persona). */
@@ -1,10 +1,38 @@
1
- import { AIInterface } from '@happyvertical/ai';
2
- import { PrincipalAuditSink, PrincipalTool } from '@happyvertical/smrt-agents';
3
- import { SmrtClassOptions } from '@happyvertical/smrt-core';
4
- import { AgentSession } from './models/AgentSession.js';
5
- import { ConversationPersona, PersonaRecallOptions } from './persona-conversation.js';
6
- import { ChatService } from './services/index.js';
7
- import { VoiceGatewayTurnMetadata } from './voice.js';
1
+ /**
2
+ * Token-streaming conversation endpoint (SSE) for embeddable chat clients
3
+ * (issue #1936).
4
+ *
5
+ * The seam that joins the conversational harness to an embeddable widget: a
6
+ * client (first consumer: the Happy chat widget, `happyvertical/animation#5`)
7
+ * POSTs the conversation so far and receives a `text/event-stream` of
8
+ * `data: <json>` frames — token deltas as the model generates them, then a
9
+ * final `done` frame carrying the persisted message. A floating character can
10
+ * stream the reply into a bubble and lip-sync each sentence as it completes,
11
+ * instead of waiting for the whole JSON reply the way `POST /api/dev-chat` does.
12
+ *
13
+ * Two modes, dispatched by the resolved {@link ChatStreamContext}:
14
+ * - **persona-bound** (`context.binding` present): runs the full
15
+ * {@link runPersonaConversationTurn} — persona principal, allow-listed tools,
16
+ * recalled memory — with a token sink wired through the tool loop, then
17
+ * persists via `ChatService` and emits the persisted message as `done`.
18
+ * - **plain / unbound** (`context.binding` absent): streams `ai.stream()`
19
+ * directly and emits a synthesized (unpersisted) `done` message.
20
+ *
21
+ * Security posture (mirrors the voice gateway, #1910): this module NEVER
22
+ * authorizes from the request's `session` metadata. `createChatStreamHandler`
23
+ * takes an injected `authorize(request, body)` that the app implements to
24
+ * validate the caller (bearer session id / cookie) and resolve an already-
25
+ * authorized `ChatStreamContext`. The streaming engine enforces whatever that
26
+ * returns; no authorizer ⇒ the handler cannot run. The persona path reuses the
27
+ * harness's own fail-closed principal + allow-list gates unchanged.
28
+ */
29
+ import type { AIInterface } from '@happyvertical/ai';
30
+ import type { PrincipalAuditSink, PrincipalTool } from '@happyvertical/smrt-agents';
31
+ import type { SmrtClassOptions } from '@happyvertical/smrt-core';
32
+ import type { AgentSession } from './models/AgentSession.js';
33
+ import { type ConversationPersona, type PersonaRecallOptions } from './persona-conversation.js';
34
+ import type { ChatService } from './services/index.js';
35
+ import type { VoiceGatewayTurnMetadata } from './voice.js';
8
36
  /** Max conversation messages accepted on one streaming request. */
9
37
  export declare const MAX_CHAT_STREAM_MESSAGES = 50;
10
38
  /** Max characters per message (matches the voice gateway text cap). */
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Compile-time contract locks between the browser client (`client.ts`) and
3
+ * the wire contract `chat-stream.ts` owns.
4
+ *
5
+ * This is deliberately a NON-TEST module: the typecheck tsconfig excludes
6
+ * `.test.ts` files and Vitest transpiles without typechecking, so locks inside
7
+ * a test file would enforce nothing (PR #2033 review). Here they sit in the
8
+ * `pnpm typecheck` program, so server-side drift in `ChatStreamEvent` /
9
+ * `ChatStreamSession` breaks the build instead of silently breaking clients.
10
+ *
11
+ * Nothing imports this module — it is type-only ballast and never reaches a
12
+ * runtime bundle (the vite entries don't reference it), keeping the `/client`
13
+ * subpath free of server imports.
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=client.contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.contract.d.ts","sourceRoot":"","sources":["../src/client.contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
@@ -1,6 +1,6 @@
1
1
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
2
  import { ChatMessage } from '../models/ChatMessage.js';
3
- import { ChatMessageSearchFilters } from '../types.js';
3
+ import type { ChatMessageSearchFilters } from '../types.js';
4
4
  export declare class ChatMessageCollection extends SmrtCollection<ChatMessage> {
5
5
  static readonly _itemClass: typeof ChatMessage;
6
6
  /**
@@ -1,7 +1,7 @@
1
1
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
- import { ChatParticipantCollection } from '../collections/ChatParticipantCollection.js';
2
+ import type { ChatParticipantCollection } from '../collections/ChatParticipantCollection.js';
3
3
  import { ChatRoom } from '../models/ChatRoom.js';
4
- import { ChatRoomType } from '../types.js';
4
+ import type { ChatRoomType } from '../types.js';
5
5
  /**
6
6
  * Deterministic, order-independent room id for a 1:1 DM between two profiles
7
7
  * within a tenant (S5 #1392, DM race hardening).
@@ -0,0 +1,9 @@
1
+ export { AgentSessionCollection } from './AgentSessionCollection.js';
2
+ export { ChatMessageCollection } from './ChatMessageCollection.js';
3
+ export { ChatParticipantCollection } from './ChatParticipantCollection.js';
4
+ export { ChatReactionCollection } from './ChatReactionCollection.js';
5
+ export { ChatRoomCollection } from './ChatRoomCollection.js';
6
+ export { ChatThreadCollection } from './ChatThreadCollection.js';
7
+ export { VoiceGatewayTurnCollection } from './VoiceGatewayTurnCollection.js';
8
+ export { VoiceSessionCollection } from './VoiceSessionCollection.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/collections/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,45 @@
1
+ /**
2
+ * @happyvertical/smrt-chat
3
+ *
4
+ * Chat rooms, DMs, threads, and agent conversations for the SMRT framework.
5
+ *
6
+ * Provides models and collections for real-time chat with support for:
7
+ * - Public/private rooms and channels
8
+ * - Direct messages between profiles
9
+ * - Threaded conversations (Slack-style)
10
+ * - Agent conversation sessions with tool access control
11
+ * - Message reactions and read receipts
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { ChatService } from '@happyvertical/smrt-chat';
16
+ *
17
+ * const chat = await ChatService.create({
18
+ * persistence: { type: 'sql', url: 'chat.db' }
19
+ * });
20
+ *
21
+ * // actorProfileId is the authenticated principal injected by the route; the
22
+ * // acting actor becomes the room owner.
23
+ * const room = await chat.createRoom({
24
+ * tenantId: 'tenant-1',
25
+ * name: 'General',
26
+ * roomType: 'public',
27
+ * actorProfileId: 'profile-1',
28
+ * });
29
+ *
30
+ * // actorProfileId is the authenticated principal injected by the route;
31
+ * // the message is always authored as that actor with role 'user'.
32
+ * await chat.sendMessage({
33
+ * tenantId: 'tenant-1',
34
+ * roomId: room.id,
35
+ * actorProfileId: 'profile-1',
36
+ * content: 'Hello, world!',
37
+ * });
38
+ * ```
39
+ *
40
+ * @packageDocumentation
41
+ */
42
+ import './__smrt-register__.js';
1
43
  export { acceptAppliedChange, type CaptureChatFeedbackOptions, type ChatFeedbackBase, type ChatFeedbackPersona, type ChatFeedbackResult, captureChatFeedback, correctResponse, rateResponse, rejectAppliedChange, thumbsDown, thumbsUp, } from './chat-feedback.js';
2
44
  export { ChatStreamBadRequestError, type ChatStreamContext, type ChatStreamControlCommand, ChatStreamError, type ChatStreamEvent, type ChatStreamHandlerOptions, type ChatStreamMessage, type ChatStreamPersonaBinding, type ChatStreamRequestBody, type ChatStreamRole, type ChatStreamSession, ChatStreamUnauthorizedError, createChatStreamHandler, DEFAULT_CHAT_STREAM_HEARTBEAT_MS, encodeChatStreamEvent, MAX_CHAT_STREAM_CONTENT_LENGTH, MAX_CHAT_STREAM_MESSAGES, type RunChatConversationStreamOptions, runChatConversationStream, } from './chat-stream.js';
3
45
  export { createDataSurfaceBridge, createDataSurfaceCommandBridge, createServerDataSurfaceBridge, DATA_SURFACE_BRIDGE_VERSION, type DataSurfaceBridgeConnectionState, type DataSurfaceBridgeEvent, type DataSurfaceBridgeFailureReason, type DataSurfaceBridgeMessage, type DataSurfaceBridgeTransport, type DataSurfaceCommandAck, type DataSurfaceCommandBridge, type DataSurfaceCommandBridgeOptions, type DataSurfaceCommandRequest, DEFAULT_DATA_SURFACE_BRIDGE_TTL_MS, } from './data-surface-bridge.js';