@moderta/mint-ai-assistant 0.1.4 → 0.1.6

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/README.md CHANGED
@@ -1,85 +1,100 @@
1
- # @moderta/mint-ai-assistant
2
-
3
- Embeddable **Mint AI** assistant — a floating chat widget shared across Moderta apps.
4
- React component, Tailwind-styled, distributed as an npm package.
5
-
6
- ## Why this exists
7
-
8
- The same architecture as the main `frontend` (RTK Query `api-details` → `base-slice`
9
- registry, scoped store), but packaged as a **library** you can drop into any React app
10
- without it touching the host's styles.
11
-
12
- - **Isolation:** Tailwind preflight is disabled and every utility is `mint-` prefixed, so
13
- embedding never resets or restyles the host app. The compiled CSS is auto-injected.
14
- - **Config via props**, not env vars (the package runs inside someone else's bundle).
15
- - **React + ReactDOM are peer dependencies** — the host provides them.
16
-
17
- ## Install
18
-
19
- ```bash
20
- npm install @moderta/mint-ai-assistant
21
- ```
22
-
23
- ## Usage
24
-
25
- ```tsx
26
- import { MintAIAssistant } from '@moderta/mint-ai-assistant';
27
-
28
- export function App() {
29
- return (
30
- <MintAIAssistant
31
- baseUrl="https://api.moderta.io/ai"
32
- getToken={() => localStorage.getItem('token') ?? undefined}
1
+ # @moderta/mint-ai-assistant
2
+
3
+ Embeddable **Mint AI** assistant — a floating chat widget shared across Moderta apps.
4
+ React component, Tailwind-styled, distributed as an npm package.
5
+
6
+ ## Why this exists
7
+
8
+ The same architecture as the main `frontend` (RTK Query `api-details` → `base-slice`
9
+ registry, scoped store), but packaged as a **library** you can drop into any React app
10
+ without it touching the host's styles.
11
+
12
+ - **Isolation:** Tailwind preflight is disabled and every utility is `mint-` prefixed, so
13
+ embedding never resets or restyles the host app. The compiled CSS is auto-injected.
14
+ - **Config via props**, not env vars (the package runs inside someone else's bundle).
15
+ - **React + ReactDOM are peer dependencies** — the host provides them.
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ npm install @moderta/mint-ai-assistant
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ```tsx
26
+ import { MintAIAssistant } from '@moderta/mint-ai-assistant';
27
+
28
+ export function App() {
29
+ return (
30
+ <MintAIAssistant
31
+ baseUrl="https://context-engine.moderta.io"
32
+ getToken={() => sessionStorage.getItem('jwt_access_token') ?? undefined}
33
+ tenantId={user.companyId}
33
34
  title="Mint AI"
34
35
  placement="bottom-right"
35
36
  enableExpandMode={false}
36
- context={{ orgId: 'org_123' }}
37
- />
38
- );
39
- }
40
- ```
41
-
42
- ### Props (`MintAIConfig`)
43
-
44
- | Prop | Type | Default | Notes |
45
- | ---------------- | ----------------------------- | ---------------- | --------------------------------------- |
46
- | `baseUrl` | `string` | — | Required. Base URL of the assistant API |
47
- | `getToken` | `() => string \| Promise<…>` | — | Bearer token for requests |
48
- | `placement` | `bottom-right \| …` | `bottom-right` | Launcher corner |
49
- | `title` | `string` | `Mint AI` | Panel header title |
50
- | `welcomeMessage` | `string` | greeting | Shown when there's no history |
51
- | `defaultOpen` | `boolean` | `false` | Open the panel on mount |
52
- | `context` | `Record<string, unknown>` | — | Forwarded with every chat request |
53
-
54
- ## API contract
55
-
56
- The widget talks to a small API (`src/api/api-details`):
57
-
58
- - `POST {baseUrl}/chat/messages` → `{ conversationId, reply }`
59
- - `GET {baseUrl}/chat/conversations/:id` → `{ conversationId, messages }`
60
- - `POST {baseUrl}/chat/feedback` → `{ success }`
61
-
62
- ## Develop
63
-
64
- ```bash
65
- npm install
66
- npm run dev # playground host app at / (see dev/main.tsx)
67
- npm run build # emits dist/ (ESM + CJS + types)
68
- ```
69
-
70
- ## Project structure
71
-
72
- ```
73
- src/
74
- index.ts public API
75
- mint-ai-assistant.tsx root component (provider + widget)
76
- config/ props-based config (replaces global-config)
77
- providers/ scoped provider stack
78
- store/ widget-scoped Redux + chat UI slice
79
- api/ RTK Query: api-details registry → base-slice
80
- sections/assistant/ the chat UI (launcher, panel, list, composer)
81
- components/iconify/ shared UI primitives
82
- hooks/ useChat
83
- types/ shared types
84
- utils/ cn(), uid()
85
- ```
37
+ />
38
+ );
39
+ }
40
+ ```
41
+
42
+ ### Props (`MintAIConfig`)
43
+
44
+ | Prop | Type | Default | Notes |
45
+ | ---------------- | ----------------------------- | ---------------- | --------------------------------------- |
46
+ | `baseUrl` | `string` | — | Required. Base URL of the assistant API |
47
+ | `getToken` | `() => string \| Promise<…>` | — | Supabase bearer token for requests |
48
+ | `tenantId` | `string` | — | Sent as `tenant_id`; the caller's company id |
49
+ | `user` | `{ name?: string; email?: string }` | — | Signed-in identity shown in the expanded-mode sidebar |
50
+ | `placement` | `bottom-right \| …` | `bottom-right` | Launcher corner |
51
+ | `title` | `string` | `Mint AI` | Panel header title |
52
+ | `welcomeMessage` | `string` | greeting | Shown when there's no history |
53
+ | `defaultOpen` | `boolean` | `false` | Open the panel on mount |
54
+
55
+ ## API contract
56
+
57
+ The widget talks to the Mint AI Context Engine (`src/api/api-details`):
58
+
59
+ - `POST {baseUrl}/query` — body `{ tenant_id, question }`, header
60
+ `Authorization: Bearer <token>` → `{ answer, sources: [{ chunk_id, text }], source_type }`
61
+
62
+ There is no conversation-history or feedback endpoint; conversation
63
+ continuity is client-side only.
64
+
65
+ ## Develop
66
+
67
+ ```bash
68
+ npm install
69
+ npm run dev # playground host app at / (see dev/main.tsx)
70
+ npm run build # emits dist/ (ESM + CJS + types)
71
+ ```
72
+
73
+ ## Project structure
74
+
75
+ ```
76
+ src/
77
+ index.ts public API
78
+ mint-ai-assistant.tsx root component (provider + widget)
79
+ config/ props-based config (replaces global-config)
80
+ providers/ scoped provider stack
81
+ store/ widget-scoped Redux + chat UI slice
82
+ api/ RTK Query: api-details registry → base-slice
83
+ sections/assistant/ the chat UI (launcher, panel, list, composer)
84
+ components/iconify/ shared UI primitives
85
+ hooks/ useChat
86
+ types/ shared types
87
+ utils/ cn(), uid()
88
+ ```
89
+
90
+ ## AI-assisted development
91
+
92
+ Repository-specific AI guidance lives in [AGENTS.md](AGENTS.md). Detailed architecture, security, testing, database, specifications, prompts and project knowledge are under [`.ai/`](.ai/); reusable Claude skills and permissions are under [`.claude/`](.claude/). Treat executable code and tests as authoritative when documentation becomes stale.
93
+
94
+ ## Current architecture snapshot
95
+
96
+ Embeddable `@moderta/mint-ai-assistant` React widget/library. `src/index.ts` defines the package public API. `MintAIAssistant` wraps the UI in `AssistantProvider`; `dev/main.tsx` is a local integration harness, not a production entry point.
97
+
98
+ A host passes API base URL, optional token getter/context/placement. The provider creates configuration and Redux context; `useChat` adds an optimistic user message, calls the chat endpoint, stores the returned conversation/assistant message, and emits a system error on failure.
99
+
100
+ For implementation rules and the complete source-derived map, read [AGENTS.md](AGENTS.md) and [the architecture instructions](.ai/instructions/architecture.md).
package/dist/index.d.ts CHANGED
@@ -1,12 +1,21 @@
1
- import { ChatMessage } from '@moderta/api-contracts';
2
- import { ChatMessageStatus } from '@moderta/api-contracts';
3
- import { ChatRole } from '@moderta/api-contracts';
1
+ import { BaseQueryApi } from '@reduxjs/toolkit/query';
2
+ import { ChatMessage } from '@moderta/api-contracts/chat';
3
+ import { ChatMessageStatus } from '@moderta/api-contracts/chat';
4
+ import { ChatRole } from '@moderta/api-contracts/chat';
5
+ import { FetchArgs } from '@reduxjs/toolkit/query';
6
+ import { FetchBaseQueryError } from '@reduxjs/toolkit/query';
7
+ import { FetchBaseQueryMeta } from '@reduxjs/toolkit/query';
8
+ import { InfiniteQueryActionCreatorResult } from '@reduxjs/toolkit/query';
9
+ import { InfiniteQueryDefinition } from '@reduxjs/toolkit/query';
4
10
  import { JSX as JSX_2 } from 'react';
11
+ import { QueryReturnValue } from '@reduxjs/toolkit/query';
5
12
  import { ReactNode } from 'react';
13
+ import { SessionSummary } from '@moderta/api-contracts/chat';
14
+ import { SubscriptionOptions } from '@reduxjs/toolkit/query';
6
15
 
7
16
  export declare type AssistantFormRenderer = () => ReactNode;
8
17
 
9
- export declare type AssistantPlacement = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
18
+ export declare type AssistantPlacement = "bottom-right" | "bottom-left" | "top-right" | "top-left";
10
19
 
11
20
  export { ChatMessage }
12
21
 
@@ -24,8 +33,21 @@ export declare interface MintAIAssistantProps extends MintAIConfig {
24
33
  export declare interface MintAIConfig {
25
34
  /** Base URL of the assistant API, e.g. `https://api.moderta.io`. */
26
35
  baseUrl: string;
36
+ /** Optional stable user identifier forwarded to the chat backend. */
37
+ userId?: string;
27
38
  /** Returns the bearer token for the current user (sync or async). */
28
39
  getToken?: TokenGetter;
40
+ /**
41
+ * Tenant identifier sent as `tenant_id` with every `/query` request.
42
+ * In ESM this is the caller's company id. The Context Engine still
43
+ * re-derives it from the bearer token and rejects a mismatch.
44
+ */
45
+ tenantId?: string;
46
+ /** Signed-in user's display identity, shown in the assistant UI. */
47
+ user?: {
48
+ name?: string;
49
+ email?: string;
50
+ };
29
51
  /** Where the floating launcher sits. Default: `bottom-right`. */
30
52
  placement?: AssistantPlacement;
31
53
  /** Greeting shown when the chat opens with no history. */
@@ -46,34 +68,68 @@ export declare interface MintAIConfig {
46
68
 
47
69
  declare type ResolvedConfig = MintAIConfig & Required<Pick<MintAIConfig, 'placement' | 'title' | 'welcomeMessage' | 'defaultOpen' | 'enableExpandMode'>>;
48
70
 
49
- export declare function SampleConversationPanel({ onClose }: {
50
- onClose?: () => void;
51
- }): JSX_2.Element;
52
-
53
- export declare function SampleEmptyPanel({ onClose }: {
54
- onClose?: () => void;
55
- }): JSX_2.Element;
56
-
57
- export declare function SampleExpandedMode({ onCollapse, onClose, }: Readonly<{
58
- onCollapse?: () => void;
59
- onClose?: () => void;
60
- }>): JSX_2.Element;
61
-
62
- export declare function SampleShowcase({ initial }: {
63
- initial?: Screen_2;
64
- }): JSX_2.Element;
65
-
66
- declare type Screen_2 = 'empty' | 'conversation' | 'expanded';
71
+ export { SessionSummary }
67
72
 
68
73
  export declare type TokenGetter = () => string | undefined | Promise<string | undefined>;
69
74
 
70
75
  export declare function useChat(): {
71
76
  messages: ChatMessage[];
72
- draft: string;
73
- isLoading: any;
77
+ notice: string | null;
78
+ isLoading: boolean;
74
79
  send: (raw?: string) => Promise<void>;
80
+ loadOlder: () => void;
81
+ hasOlder: boolean;
82
+ isLoadingOlder: boolean;
75
83
  };
76
84
 
77
85
  export declare function useConfig(): ResolvedConfig;
78
86
 
87
+ /**
88
+ * The Past Chats list for the expanded sidebar. Backed by the getSessions
89
+ * infinite query — one flat list, keyset-paginated, filtered by `search`
90
+ * (debounced). Re-sorts when sendMessage invalidates SessionList.
91
+ */
92
+ export declare function useSessions(search: string): {
93
+ sessions: {
94
+ sessionId: string;
95
+ title: string | null;
96
+ status: "active" | "expired";
97
+ createdAt: string;
98
+ lastActivityAt: string;
99
+ expiresAt: string;
100
+ }[];
101
+ activeSessionId: string | null;
102
+ isLoading: boolean;
103
+ /** A fetch is in flight that isn't "load next page" — initial load or a new search. */
104
+ isReloading: boolean;
105
+ isError: boolean;
106
+ hasNextPage: boolean;
107
+ isFetchingNextPage: boolean;
108
+ loadMore: () => void;
109
+ openSession: (sessionId: string) => {
110
+ payload: string | null;
111
+ type: "chatUi/setActiveSessionId";
112
+ };
113
+ newChat: () => {
114
+ payload: undefined;
115
+ type: "chatUi/startNewChat";
116
+ };
117
+ refetch: (options?: Pick<SubscriptionOptions & {
118
+ skip?: boolean;
119
+ refetchOnMountOrArgChange?: boolean | number;
120
+ initialPageParam?: string | undefined;
121
+ refetchCachedPages?: boolean;
122
+ }, "refetchCachedPages"> | undefined) => InfiniteQueryActionCreatorResult<InfiniteQueryDefinition<string, string | undefined, (args: string | FetchArgs, api: BaseQueryApi, extraOptions: {}) => Promise<QueryReturnValue<unknown, FetchBaseQueryError, FetchBaseQueryMeta>>, "SessionList", {
123
+ items: {
124
+ sessionId: string;
125
+ title: string | null;
126
+ status: "active" | "expired";
127
+ createdAt: string;
128
+ lastActivityAt: string;
129
+ expiresAt: string;
130
+ }[];
131
+ nextCursor: string | null;
132
+ }, "chatApi", unknown>>;
133
+ };
134
+
79
135
  export { }