@frankieai/react 0.1.0 → 0.1.4

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
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, CSSProperties, ButtonHTMLAttributes, HTMLAttributes, TextareaHTMLAttributes } from 'react';
3
- import { PublicWidgetConfig, CreateSessionResponse, FrankieServerEvent, WidgetTheme } from '@frankieai/core';
3
+ import { PublicWidgetConfig, CreateSessionResponse, ChatAttachment, FrankieServerEvent, WidgetTheme } from '@frankieai/core';
4
4
  export { FrankieServerEvent, PublicWidgetConfig, WidgetTheme } from '@frankieai/core';
5
5
  import * as class_variance_authority_types from 'class-variance-authority/types';
6
6
  import { VariantProps } from 'class-variance-authority';
@@ -30,6 +30,16 @@ interface FrankieClientOptions {
30
30
  * set false for an ephemeral chat that starts fresh every load.
31
31
  */
32
32
  persist?: boolean;
33
+ /** Override localStorage namespace for session and transcript. */
34
+ storageNamespace?: string;
35
+ /** Stable id for a server-backed conversation. */
36
+ conversationId?: string;
37
+ }
38
+ interface ChatConversation {
39
+ id: string;
40
+ title: string;
41
+ createdAt: number;
42
+ updatedAt: number;
33
43
  }
34
44
  declare class FrankieApiError extends Error {
35
45
  readonly status: number;
@@ -43,41 +53,39 @@ declare class FrankieClient {
43
53
  private session?;
44
54
  constructor(options: FrankieClientOptions);
45
55
  get sessionId(): string | undefined;
56
+ get conversationId(): string | undefined;
46
57
  /** Whether this client persists across reloads (browser only, opt-out via `persist:false`). */
47
58
  get persist(): boolean;
48
- /** localStorage namespace for this tenant, shared with the chat hook. */
59
+ /** localStorage namespace for this tenant/conversation, shared with the chat hook. */
49
60
  get namespace(): string;
50
61
  private readStored;
51
62
  private writeStored;
52
63
  getConfig(signal?: AbortSignal): Promise<PublicWidgetConfig>;
53
- /** Opens (or reuses) a chat session. */
54
64
  ensureSession(context?: PageContext): Promise<CreateSessionResponse>;
55
- /** Forget the current session so the next send starts a fresh conversation. */
65
+ listConversations(): Promise<ChatConversation[]>;
66
+ resumeConversation(id?: string | undefined): Promise<{
67
+ messages: unknown[];
68
+ title: string;
69
+ } | undefined>;
70
+ syncConversation(messages: unknown[], title?: string): Promise<void>;
71
+ deleteConversation(id: string): Promise<void>;
72
+ private requireUserToken;
56
73
  resetSession(): void;
57
- /**
58
- * Sends a message and invokes `onEvent` for each server event as it arrives.
59
- * Resolves when the turn ends.
60
- */
61
74
  send(input: {
62
75
  message: string;
63
76
  context?: PageContext;
77
+ model?: string;
78
+ attachments?: ChatAttachment[];
64
79
  signal?: AbortSignal;
65
80
  }, onEvent: (event: FrankieServerEvent) => void): Promise<void>;
66
81
  private unwrap;
67
82
  }
68
- /** Parse the server's `data:`-only SSE stream into typed events. */
69
83
  declare function readEventStream(body: ReadableStream<Uint8Array>): AsyncGenerator<FrankieServerEvent>;
70
84
 
71
85
  interface FrankieProviderProps extends FrankieClientOptions {
72
86
  children: ReactNode;
73
- /**
74
- * Page context sent with every turn — current route, plan tier, whatever the
75
- * agent should know. Treated as data by the server, never as instructions.
76
- */
77
87
  context?: PageContext;
78
- /** Overrides for the server-side theme, so a host can restyle without a redeploy. */
79
88
  theme?: WidgetTheme;
80
- /** Skip the `/v1/config` fetch by supplying the config yourself. */
81
89
  config?: PublicWidgetConfig;
82
90
  }
83
91
  interface FrankieContextValue {
@@ -90,7 +98,6 @@ interface FrankieContextValue {
90
98
  }
91
99
  declare function FrankieProvider({ children, context, theme, config: providedConfig, ...clientOptions }: FrankieProviderProps): react.JSX.Element;
92
100
  declare function useFrankie(): FrankieContextValue;
93
- /** The theme actually in effect: provider override wins over server config. */
94
101
  declare function useFrankieTheme(): WidgetTheme | undefined;
95
102
 
96
103
  interface ToolActivity {
@@ -100,10 +107,16 @@ interface ToolActivity {
100
107
  status: "running" | "done" | "failed" | "denied";
101
108
  detail?: string;
102
109
  }
110
+ /** A file shown on a user message (name/type only — the bytes aren't kept in the transcript). */
111
+ interface MessageAttachment {
112
+ name: string;
113
+ mimeType: string;
114
+ }
103
115
  interface UserChatMessage {
104
116
  id: string;
105
117
  role: "user";
106
118
  text: string;
119
+ attachments?: MessageAttachment[];
107
120
  createdAt: number;
108
121
  }
109
122
  interface AssistantChatMessage {
@@ -125,15 +138,20 @@ type ChatMessage = UserChatMessage | AssistantChatMessage;
125
138
  */
126
139
  declare function applyEvent(message: AssistantChatMessage, event: FrankieServerEvent): AssistantChatMessage;
127
140
  declare function newAssistantMessage(id: string): AssistantChatMessage;
128
- declare function newUserMessage(id: string, text: string): UserChatMessage;
141
+ declare function newUserMessage(id: string, text: string, attachments?: MessageAttachment[]): UserChatMessage;
129
142
 
143
+ /** Extra inputs a turn can carry: attached files and a chosen model. */
144
+ interface SendOptions {
145
+ attachments?: ChatAttachment[];
146
+ model?: string;
147
+ }
130
148
  interface UseFrankieChatResult {
131
149
  messages: ChatMessage[];
132
150
  /** True from the moment a message is sent until the turn ends. */
133
151
  busy: boolean;
134
152
  /** Set when the turn failed outright (network, auth, rate limit). */
135
153
  error?: string;
136
- send: (text: string) => Promise<void>;
154
+ send: (text: string, opts?: SendOptions) => Promise<void>;
137
155
  /** Abort the in-flight turn. The partial answer stays in the transcript. */
138
156
  stop: () => void;
139
157
  /** Clear the transcript and start a brand-new server session. */
@@ -200,15 +218,47 @@ interface FrankieInlineProps extends ChatPanelProps {
200
218
  */
201
219
  declare function FrankieInline({ className, style, ...panelProps }: FrankieInlineProps): react.JSX.Element;
202
220
 
221
+ /**
222
+ * A complete chat route in one component. This is the simplest way to add a
223
+ * dedicated /chat page to an app while keeping the existing floating widget.
224
+ */
225
+ interface FrankieChatPageProps extends Omit<FrankieProviderProps, "children">, Pick<ChatPanelProps, "header" | "footer" | "emptyState" | "renderMessage" | "renderTool" | "placeholder" | "autoFocus"> {
226
+ className?: string;
227
+ style?: CSSProperties;
228
+ }
229
+ declare function FrankieChatPage({ className, style, header, footer, emptyState, renderMessage, renderTool, placeholder, autoFocus, ...providerProps }: FrankieChatPageProps): react.JSX.Element;
230
+
231
+ interface ComposerAttachmentsConfig {
232
+ enabled: boolean;
233
+ /** Accepted MIME patterns, e.g. "image/*". */
234
+ accept: string[];
235
+ maxCount: number;
236
+ maxMb: number;
237
+ }
238
+ interface ComposerModelPicker {
239
+ models: {
240
+ id: string;
241
+ label: string;
242
+ }[];
243
+ value?: string;
244
+ onChange: (id: string) => void;
245
+ }
203
246
  interface ComposerProps {
204
- onSend: (text: string) => void;
247
+ onSend: (text: string, opts?: {
248
+ attachments?: ChatAttachment[];
249
+ model?: string;
250
+ }) => void;
205
251
  onStop: () => void;
206
252
  busy: boolean;
207
253
  placeholder?: string;
208
254
  disabled?: boolean;
209
255
  autoFocus?: boolean;
256
+ /** Enables the attach button when provided and `enabled`. */
257
+ attachments?: ComposerAttachmentsConfig;
258
+ /** Enables a model dropdown when provided with at least one model. */
259
+ modelPicker?: ComposerModelPicker;
210
260
  }
211
- declare function Composer({ onSend, onStop, busy, placeholder, disabled, autoFocus }: ComposerProps): react.JSX.Element;
261
+ declare function Composer({ onSend, onStop, busy, placeholder, disabled, autoFocus, attachments, modelPicker }: ComposerProps): react.JSX.Element;
212
262
 
213
263
  interface MessageBubbleProps {
214
264
  message: ChatMessage;
@@ -307,4 +357,4 @@ declare function resolveMode(mode: WidgetTheme["mode"]): "light" | "dark";
307
357
  /** shadcn/ui's class helper: conditional classes with Tailwind conflict resolution. */
308
358
  declare function cn(...inputs: ClassValue[]): string;
309
359
 
310
- export { type AssistantChatMessage, Avatar, Badge, Button, type ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type ChatMessage, ChatPanel, type ChatPanelProps, Composer, FRANKIE_CLOUD_URL, FrankieApiError, FrankieClient, type FrankieClientOptions, FrankieInline, type FrankieInlineProps, FrankieProvider, type FrankieProviderProps, FrankieWidget, type FrankieWidgetProps, Markdown, MessageBubble, type PageContext, ScrollArea, Separator, SuggestedPrompts, Textarea, type ToolActivity, ToolActivityList, ToolActivityRow, TypingDots, type UseFrankieChatResult, type UserChatMessage, applyEvent, buttonVariants, cn, newAssistantMessage, newUserMessage, readEventStream, resolveMode, themeToCssVars, useFrankie, useFrankieChat, useFrankieTheme };
360
+ export { type AssistantChatMessage, Avatar, Badge, Button, type ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type ChatMessage, ChatPanel, type ChatPanelProps, Composer, FRANKIE_CLOUD_URL, FrankieApiError, FrankieChatPage, type FrankieChatPageProps, FrankieClient, type FrankieClientOptions, FrankieInline, type FrankieInlineProps, FrankieProvider, type FrankieProviderProps, FrankieWidget, type FrankieWidgetProps, Markdown, type MessageAttachment, MessageBubble, type PageContext, ScrollArea, type SendOptions, Separator, SuggestedPrompts, Textarea, type ToolActivity, ToolActivityList, ToolActivityRow, TypingDots, type UseFrankieChatResult, type UserChatMessage, applyEvent, buttonVariants, cn, newAssistantMessage, newUserMessage, readEventStream, resolveMode, themeToCssVars, useFrankie, useFrankieChat, useFrankieTheme };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, CSSProperties, ButtonHTMLAttributes, HTMLAttributes, TextareaHTMLAttributes } from 'react';
3
- import { PublicWidgetConfig, CreateSessionResponse, FrankieServerEvent, WidgetTheme } from '@frankieai/core';
3
+ import { PublicWidgetConfig, CreateSessionResponse, ChatAttachment, FrankieServerEvent, WidgetTheme } from '@frankieai/core';
4
4
  export { FrankieServerEvent, PublicWidgetConfig, WidgetTheme } from '@frankieai/core';
5
5
  import * as class_variance_authority_types from 'class-variance-authority/types';
6
6
  import { VariantProps } from 'class-variance-authority';
@@ -30,6 +30,16 @@ interface FrankieClientOptions {
30
30
  * set false for an ephemeral chat that starts fresh every load.
31
31
  */
32
32
  persist?: boolean;
33
+ /** Override localStorage namespace for session and transcript. */
34
+ storageNamespace?: string;
35
+ /** Stable id for a server-backed conversation. */
36
+ conversationId?: string;
37
+ }
38
+ interface ChatConversation {
39
+ id: string;
40
+ title: string;
41
+ createdAt: number;
42
+ updatedAt: number;
33
43
  }
34
44
  declare class FrankieApiError extends Error {
35
45
  readonly status: number;
@@ -43,41 +53,39 @@ declare class FrankieClient {
43
53
  private session?;
44
54
  constructor(options: FrankieClientOptions);
45
55
  get sessionId(): string | undefined;
56
+ get conversationId(): string | undefined;
46
57
  /** Whether this client persists across reloads (browser only, opt-out via `persist:false`). */
47
58
  get persist(): boolean;
48
- /** localStorage namespace for this tenant, shared with the chat hook. */
59
+ /** localStorage namespace for this tenant/conversation, shared with the chat hook. */
49
60
  get namespace(): string;
50
61
  private readStored;
51
62
  private writeStored;
52
63
  getConfig(signal?: AbortSignal): Promise<PublicWidgetConfig>;
53
- /** Opens (or reuses) a chat session. */
54
64
  ensureSession(context?: PageContext): Promise<CreateSessionResponse>;
55
- /** Forget the current session so the next send starts a fresh conversation. */
65
+ listConversations(): Promise<ChatConversation[]>;
66
+ resumeConversation(id?: string | undefined): Promise<{
67
+ messages: unknown[];
68
+ title: string;
69
+ } | undefined>;
70
+ syncConversation(messages: unknown[], title?: string): Promise<void>;
71
+ deleteConversation(id: string): Promise<void>;
72
+ private requireUserToken;
56
73
  resetSession(): void;
57
- /**
58
- * Sends a message and invokes `onEvent` for each server event as it arrives.
59
- * Resolves when the turn ends.
60
- */
61
74
  send(input: {
62
75
  message: string;
63
76
  context?: PageContext;
77
+ model?: string;
78
+ attachments?: ChatAttachment[];
64
79
  signal?: AbortSignal;
65
80
  }, onEvent: (event: FrankieServerEvent) => void): Promise<void>;
66
81
  private unwrap;
67
82
  }
68
- /** Parse the server's `data:`-only SSE stream into typed events. */
69
83
  declare function readEventStream(body: ReadableStream<Uint8Array>): AsyncGenerator<FrankieServerEvent>;
70
84
 
71
85
  interface FrankieProviderProps extends FrankieClientOptions {
72
86
  children: ReactNode;
73
- /**
74
- * Page context sent with every turn — current route, plan tier, whatever the
75
- * agent should know. Treated as data by the server, never as instructions.
76
- */
77
87
  context?: PageContext;
78
- /** Overrides for the server-side theme, so a host can restyle without a redeploy. */
79
88
  theme?: WidgetTheme;
80
- /** Skip the `/v1/config` fetch by supplying the config yourself. */
81
89
  config?: PublicWidgetConfig;
82
90
  }
83
91
  interface FrankieContextValue {
@@ -90,7 +98,6 @@ interface FrankieContextValue {
90
98
  }
91
99
  declare function FrankieProvider({ children, context, theme, config: providedConfig, ...clientOptions }: FrankieProviderProps): react.JSX.Element;
92
100
  declare function useFrankie(): FrankieContextValue;
93
- /** The theme actually in effect: provider override wins over server config. */
94
101
  declare function useFrankieTheme(): WidgetTheme | undefined;
95
102
 
96
103
  interface ToolActivity {
@@ -100,10 +107,16 @@ interface ToolActivity {
100
107
  status: "running" | "done" | "failed" | "denied";
101
108
  detail?: string;
102
109
  }
110
+ /** A file shown on a user message (name/type only — the bytes aren't kept in the transcript). */
111
+ interface MessageAttachment {
112
+ name: string;
113
+ mimeType: string;
114
+ }
103
115
  interface UserChatMessage {
104
116
  id: string;
105
117
  role: "user";
106
118
  text: string;
119
+ attachments?: MessageAttachment[];
107
120
  createdAt: number;
108
121
  }
109
122
  interface AssistantChatMessage {
@@ -125,15 +138,20 @@ type ChatMessage = UserChatMessage | AssistantChatMessage;
125
138
  */
126
139
  declare function applyEvent(message: AssistantChatMessage, event: FrankieServerEvent): AssistantChatMessage;
127
140
  declare function newAssistantMessage(id: string): AssistantChatMessage;
128
- declare function newUserMessage(id: string, text: string): UserChatMessage;
141
+ declare function newUserMessage(id: string, text: string, attachments?: MessageAttachment[]): UserChatMessage;
129
142
 
143
+ /** Extra inputs a turn can carry: attached files and a chosen model. */
144
+ interface SendOptions {
145
+ attachments?: ChatAttachment[];
146
+ model?: string;
147
+ }
130
148
  interface UseFrankieChatResult {
131
149
  messages: ChatMessage[];
132
150
  /** True from the moment a message is sent until the turn ends. */
133
151
  busy: boolean;
134
152
  /** Set when the turn failed outright (network, auth, rate limit). */
135
153
  error?: string;
136
- send: (text: string) => Promise<void>;
154
+ send: (text: string, opts?: SendOptions) => Promise<void>;
137
155
  /** Abort the in-flight turn. The partial answer stays in the transcript. */
138
156
  stop: () => void;
139
157
  /** Clear the transcript and start a brand-new server session. */
@@ -200,15 +218,47 @@ interface FrankieInlineProps extends ChatPanelProps {
200
218
  */
201
219
  declare function FrankieInline({ className, style, ...panelProps }: FrankieInlineProps): react.JSX.Element;
202
220
 
221
+ /**
222
+ * A complete chat route in one component. This is the simplest way to add a
223
+ * dedicated /chat page to an app while keeping the existing floating widget.
224
+ */
225
+ interface FrankieChatPageProps extends Omit<FrankieProviderProps, "children">, Pick<ChatPanelProps, "header" | "footer" | "emptyState" | "renderMessage" | "renderTool" | "placeholder" | "autoFocus"> {
226
+ className?: string;
227
+ style?: CSSProperties;
228
+ }
229
+ declare function FrankieChatPage({ className, style, header, footer, emptyState, renderMessage, renderTool, placeholder, autoFocus, ...providerProps }: FrankieChatPageProps): react.JSX.Element;
230
+
231
+ interface ComposerAttachmentsConfig {
232
+ enabled: boolean;
233
+ /** Accepted MIME patterns, e.g. "image/*". */
234
+ accept: string[];
235
+ maxCount: number;
236
+ maxMb: number;
237
+ }
238
+ interface ComposerModelPicker {
239
+ models: {
240
+ id: string;
241
+ label: string;
242
+ }[];
243
+ value?: string;
244
+ onChange: (id: string) => void;
245
+ }
203
246
  interface ComposerProps {
204
- onSend: (text: string) => void;
247
+ onSend: (text: string, opts?: {
248
+ attachments?: ChatAttachment[];
249
+ model?: string;
250
+ }) => void;
205
251
  onStop: () => void;
206
252
  busy: boolean;
207
253
  placeholder?: string;
208
254
  disabled?: boolean;
209
255
  autoFocus?: boolean;
256
+ /** Enables the attach button when provided and `enabled`. */
257
+ attachments?: ComposerAttachmentsConfig;
258
+ /** Enables a model dropdown when provided with at least one model. */
259
+ modelPicker?: ComposerModelPicker;
210
260
  }
211
- declare function Composer({ onSend, onStop, busy, placeholder, disabled, autoFocus }: ComposerProps): react.JSX.Element;
261
+ declare function Composer({ onSend, onStop, busy, placeholder, disabled, autoFocus, attachments, modelPicker }: ComposerProps): react.JSX.Element;
212
262
 
213
263
  interface MessageBubbleProps {
214
264
  message: ChatMessage;
@@ -307,4 +357,4 @@ declare function resolveMode(mode: WidgetTheme["mode"]): "light" | "dark";
307
357
  /** shadcn/ui's class helper: conditional classes with Tailwind conflict resolution. */
308
358
  declare function cn(...inputs: ClassValue[]): string;
309
359
 
310
- export { type AssistantChatMessage, Avatar, Badge, Button, type ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type ChatMessage, ChatPanel, type ChatPanelProps, Composer, FRANKIE_CLOUD_URL, FrankieApiError, FrankieClient, type FrankieClientOptions, FrankieInline, type FrankieInlineProps, FrankieProvider, type FrankieProviderProps, FrankieWidget, type FrankieWidgetProps, Markdown, MessageBubble, type PageContext, ScrollArea, Separator, SuggestedPrompts, Textarea, type ToolActivity, ToolActivityList, ToolActivityRow, TypingDots, type UseFrankieChatResult, type UserChatMessage, applyEvent, buttonVariants, cn, newAssistantMessage, newUserMessage, readEventStream, resolveMode, themeToCssVars, useFrankie, useFrankieChat, useFrankieTheme };
360
+ export { type AssistantChatMessage, Avatar, Badge, Button, type ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type ChatMessage, ChatPanel, type ChatPanelProps, Composer, FRANKIE_CLOUD_URL, FrankieApiError, FrankieChatPage, type FrankieChatPageProps, FrankieClient, type FrankieClientOptions, FrankieInline, type FrankieInlineProps, FrankieProvider, type FrankieProviderProps, FrankieWidget, type FrankieWidgetProps, Markdown, type MessageAttachment, MessageBubble, type PageContext, ScrollArea, type SendOptions, Separator, SuggestedPrompts, Textarea, type ToolActivity, ToolActivityList, ToolActivityRow, TypingDots, type UseFrankieChatResult, type UserChatMessage, applyEvent, buttonVariants, cn, newAssistantMessage, newUserMessage, readEventStream, resolveMode, themeToCssVars, useFrankie, useFrankieChat, useFrankieTheme };