lemma-sdk 0.2.18 → 0.2.20
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 +82 -1
- package/dist/openapi_client/index.d.ts +1 -0
- package/dist/openapi_client/index.js +1 -0
- package/dist/openapi_client/models/BulkCreateRecordsRequest.d.ts +4 -0
- package/dist/openapi_client/models/CreateFunctionRequest.d.ts +2 -0
- package/dist/openapi_client/models/FunctionResponse.d.ts +2 -0
- package/dist/openapi_client/models/FunctionRunResponse.d.ts +2 -0
- package/dist/openapi_client/models/FunctionType.d.ts +7 -0
- package/dist/openapi_client/models/FunctionType.js +12 -0
- package/dist/openapi_client/models/UpdateFunctionRequest.d.ts +2 -0
- package/dist/react/components/AssistantChrome.js +13 -23
- package/dist/react/components/AssistantExperience.d.ts +12 -4
- package/dist/react/components/AssistantExperience.js +31 -39
- package/dist/react/components/assistant-types.d.ts +5 -0
- package/dist/react/index.d.ts +3 -3
- package/dist/react/index.js +1 -1
- package/dist/react/styles.css +1268 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -179,7 +179,32 @@ Import the bundled stylesheet once anywhere in your app:
|
|
|
179
179
|
import "lemma-sdk/react/styles.css";
|
|
180
180
|
```
|
|
181
181
|
|
|
182
|
-
The stylesheet includes the SDK theme tokens and semantic assistant
|
|
182
|
+
The stylesheet includes the SDK theme tokens and the complete semantic assistant UI. The assistant components do not depend on the host app's Tailwind version or Tailwind content scanning.
|
|
183
|
+
|
|
184
|
+
If you alias the package to local SDK source in Vite, make sure the alias points at the React source and stylesheet:
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
// vite.config.ts
|
|
188
|
+
import path from "node:path";
|
|
189
|
+
|
|
190
|
+
export default {
|
|
191
|
+
resolve: {
|
|
192
|
+
alias: {
|
|
193
|
+
"lemma-sdk/react/styles.css": path.resolve(__dirname, "../lemma-typescript/src/react/styles.css"),
|
|
194
|
+
"lemma-sdk/react": path.resolve(__dirname, "../lemma-typescript/src/react/index.ts"),
|
|
195
|
+
"lemma-sdk": path.resolve(__dirname, "../lemma-typescript/src/index.ts"),
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Quick checklist for developers:
|
|
202
|
+
|
|
203
|
+
- import `lemma-sdk/react/styles.css` once
|
|
204
|
+
- give the assistant container a real height
|
|
205
|
+
- if the assistant is inside flex/grid, add `min-height: 0` on the relevant parent
|
|
206
|
+
- if you use `AssistantEmbedded`, pass `theme` directly there
|
|
207
|
+
- if you use `AssistantExperienceView`, wrap it in `AssistantThemeScope`
|
|
183
208
|
|
|
184
209
|
The assistant UI renders markdown by default:
|
|
185
210
|
|
|
@@ -188,11 +213,22 @@ The assistant UI renders markdown by default:
|
|
|
188
213
|
- links open safely in a new tab by default
|
|
189
214
|
- lists, tables, blockquotes, inline code, and fenced code blocks are styled out of the box
|
|
190
215
|
|
|
216
|
+
#### Recommended path
|
|
217
|
+
|
|
218
|
+
For most apps, start with `AssistantEmbedded`.
|
|
219
|
+
|
|
220
|
+
- use `AssistantEmbedded` when you want the SDK to handle the controller lifecycle and render the ready-made assistant UI
|
|
221
|
+
- use `AssistantExperienceView` when you still want the SDK's default assistant UI, but you need to own the controller lifecycle yourself
|
|
222
|
+
- use `useAssistantController` plus primitives only when you are intentionally building a custom shell or custom layout
|
|
223
|
+
|
|
224
|
+
If you are unsure, use `AssistantEmbedded` first. It is the path we recommend and the one we expect most SDK consumers to ship.
|
|
225
|
+
|
|
191
226
|
#### Choose an integration level
|
|
192
227
|
|
|
193
228
|
##### 1. `AssistantEmbedded` for the fastest setup
|
|
194
229
|
|
|
195
230
|
Use `AssistantEmbedded` when you want a ready-made assistant surface with the SDK defaults.
|
|
231
|
+
This is the recommended integration for most users.
|
|
196
232
|
|
|
197
233
|
```tsx
|
|
198
234
|
import "lemma-sdk/react/styles.css";
|
|
@@ -208,7 +244,14 @@ function SupportAssistant() {
|
|
|
208
244
|
title="Support Assistant"
|
|
209
245
|
subtitle="Ask questions about this pod."
|
|
210
246
|
placeholder="Message Support Assistant"
|
|
247
|
+
emptyStateSuggestions={[
|
|
248
|
+
{ text: "Summarize this conversation", icon: "✦" },
|
|
249
|
+
{ text: "Help me draft a response", icon: "✎" },
|
|
250
|
+
{ text: "List the next steps", icon: "→" },
|
|
251
|
+
]}
|
|
211
252
|
showConversationList
|
|
253
|
+
showModelPicker={false}
|
|
254
|
+
radius="lg"
|
|
212
255
|
theme="auto"
|
|
213
256
|
/>
|
|
214
257
|
</div>
|
|
@@ -219,13 +262,18 @@ function SupportAssistant() {
|
|
|
219
262
|
Important notes:
|
|
220
263
|
|
|
221
264
|
- `theme` accepts `"auto" | "light" | "dark"`
|
|
265
|
+
- `radius` lets you pick the built-in rounding scale from `"none"` through `"xl"`
|
|
266
|
+
- `showModelPicker={false}` hides the built-in model chooser when you do not want model controls visible
|
|
222
267
|
- `theme="auto"` follows the host app when it uses common selectors like `.dark`, `[data-theme="dark"]`, `[data-mode="dark"]`, and also falls back to `prefers-color-scheme`
|
|
223
268
|
- the parent container must have a real height; if it lives inside flex/grid, `min-height: 0` is usually needed too
|
|
224
269
|
- attachments are queued into the composer and sent with the next message by default
|
|
270
|
+
- `emptyStateSuggestions` lets you replace the built-in prompt chips shown before the first message
|
|
271
|
+
- prefer this component unless you specifically need to own controller state or replace the built-in layout
|
|
225
272
|
|
|
226
273
|
##### 2. `AssistantExperienceView` for the default UI with your own controller
|
|
227
274
|
|
|
228
275
|
Use `AssistantExperienceView` when you want the built-in assistant layout, but you need to own the controller lifecycle yourself.
|
|
276
|
+
This is the second-best default when `AssistantEmbedded` is too opinionated for your integration.
|
|
229
277
|
|
|
230
278
|
```tsx
|
|
231
279
|
import "lemma-sdk/react/styles.css";
|
|
@@ -249,6 +297,11 @@ function ControlledAssistant() {
|
|
|
249
297
|
title="Support Assistant"
|
|
250
298
|
subtitle="Direct use of the default assistant experience."
|
|
251
299
|
placeholder="Message Support Assistant"
|
|
300
|
+
emptyStateSuggestions={[
|
|
301
|
+
{ text: "Summarize the current context" },
|
|
302
|
+
{ text: "Help me write a reply" },
|
|
303
|
+
{ text: "What should I do next?" },
|
|
304
|
+
]}
|
|
252
305
|
showConversationList
|
|
253
306
|
chromeStyle="subtle"
|
|
254
307
|
statusPlacement="inline"
|
|
@@ -263,13 +316,19 @@ Useful props on `AssistantExperienceView`:
|
|
|
263
316
|
- `showConversationList`: show the built-in conversation sidebar
|
|
264
317
|
- `chromeStyle`: `"elevated" | "subtle" | "flat"`
|
|
265
318
|
- `statusPlacement`: `"inline" | "composer" | "none"`
|
|
319
|
+
- `radius`: `"none" | "sm" | "md" | "lg" | "xl"`
|
|
320
|
+
- `showModelPicker`: show or hide the built-in model selector
|
|
321
|
+
- `showNewConversationButton`: show or hide the built-in reset/new-conversation button
|
|
322
|
+
- `emptyStateSuggestions`: replace the built-in generic prompt suggestions used by the default empty state
|
|
266
323
|
- `renderMessageContent`: override markdown rendering for custom message content
|
|
267
324
|
- `renderToolInvocation`: replace the default tool activity renderer
|
|
268
325
|
- `renderPresentedFile` and `renderPendingFile`: customize attachment rendering
|
|
326
|
+
- prefer this over building from primitives if you still want the SDK's default assistant experience
|
|
269
327
|
|
|
270
328
|
##### 3. `useAssistantController` + primitives for a custom shell
|
|
271
329
|
|
|
272
330
|
Use the primitives when you want full control over layout and app chrome.
|
|
331
|
+
This is the advanced path and should be the exception, not the starting point.
|
|
273
332
|
|
|
274
333
|
```tsx
|
|
275
334
|
import "lemma-sdk/react/styles.css";
|
|
@@ -279,6 +338,7 @@ import {
|
|
|
279
338
|
AssistantMessageViewport,
|
|
280
339
|
AssistantShellLayout,
|
|
281
340
|
AssistantThemeScope,
|
|
341
|
+
EmptyState,
|
|
282
342
|
MessageGroup,
|
|
283
343
|
PlanSummaryStrip,
|
|
284
344
|
ThinkingIndicator,
|
|
@@ -313,6 +373,19 @@ function CustomAssistantShell() {
|
|
|
313
373
|
{activeToolBanner ? <div>{activeToolBanner.summary}</div> : null}
|
|
314
374
|
|
|
315
375
|
<AssistantMessageViewport>
|
|
376
|
+
{assistant.messages.length === 0 ? (
|
|
377
|
+
<EmptyState
|
|
378
|
+
suggestions={[
|
|
379
|
+
{ text: "Summarize this for me" },
|
|
380
|
+
{ text: "Help me draft a reply" },
|
|
381
|
+
{ text: "Brainstorm next steps" },
|
|
382
|
+
]}
|
|
383
|
+
onSendMessage={(text) => {
|
|
384
|
+
void assistant.sendMessage(text);
|
|
385
|
+
}}
|
|
386
|
+
/>
|
|
387
|
+
) : null}
|
|
388
|
+
|
|
316
389
|
{rows.map((row, index) => (
|
|
317
390
|
<MessageGroup
|
|
318
391
|
key={row.id}
|
|
@@ -355,6 +428,14 @@ Useful primitives exported from `lemma-sdk/react`:
|
|
|
355
428
|
- `PlanSummaryStrip`
|
|
356
429
|
- `ThinkingIndicator`
|
|
357
430
|
|
|
431
|
+
Guidance:
|
|
432
|
+
|
|
433
|
+
- prefer `AssistantEmbedded` over this path when the SDK layout is acceptable
|
|
434
|
+
- prefer `AssistantExperienceView` over this path when you only need controller ownership, theming control, or a few render overrides
|
|
435
|
+
- reach for primitives only when you are replacing the layout itself or deeply integrating the assistant into app-specific chrome
|
|
436
|
+
|
|
437
|
+
Default empty-state suggestions are intentionally generic so they work across support, internal tools, content, and general assistant use cases. Override them with `emptyStateSuggestions` when you want task-specific prompts.
|
|
438
|
+
|
|
358
439
|
#### Theming
|
|
359
440
|
|
|
360
441
|
Use `AssistantThemeScope` around custom assistant layouts:
|
|
@@ -103,6 +103,7 @@ export type { FunctionRunListResponse } from './models/FunctionRunListResponse.j
|
|
|
103
103
|
export type { FunctionRunResponse } from './models/FunctionRunResponse.js';
|
|
104
104
|
export { FunctionRunStatus } from './models/FunctionRunStatus.js';
|
|
105
105
|
export { FunctionStatus } from './models/FunctionStatus.js';
|
|
106
|
+
export { FunctionType } from './models/FunctionType.js';
|
|
106
107
|
export type { HTTPValidationError } from './models/HTTPValidationError.js';
|
|
107
108
|
export type { IconUploadRequest } from './models/IconUploadRequest.js';
|
|
108
109
|
export type { IconUploadResponse } from './models/IconUploadResponse.js';
|
|
@@ -18,6 +18,7 @@ export { FlowRunStatus } from './models/FlowRunStatus.js';
|
|
|
18
18
|
export { FlowStartType } from './models/FlowStartType.js';
|
|
19
19
|
export { FunctionRunStatus } from './models/FunctionRunStatus.js';
|
|
20
20
|
export { FunctionStatus } from './models/FunctionStatus.js';
|
|
21
|
+
export { FunctionType } from './models/FunctionType.js';
|
|
21
22
|
export { OrganizationInvitationStatus } from './models/OrganizationInvitationStatus.js';
|
|
22
23
|
export { OrganizationRole } from './models/OrganizationRole.js';
|
|
23
24
|
export { PodAppMode } from './models/PodAppMode.js';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ApplicationAccessConfig } from './ApplicationAccessConfig.js';
|
|
2
|
+
import type { FunctionType } from './FunctionType.js';
|
|
2
3
|
import type { TableAccessEntry } from './TableAccessEntry.js';
|
|
3
4
|
/**
|
|
4
5
|
* Request to create a function.
|
|
@@ -15,4 +16,5 @@ export type CreateFunctionRequest = {
|
|
|
15
16
|
input_schema?: Record<string, any>;
|
|
16
17
|
name: string;
|
|
17
18
|
output_schema?: Record<string, any>;
|
|
19
|
+
type?: FunctionType;
|
|
18
20
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ApplicationAccessConfig } from './ApplicationAccessConfig.js';
|
|
2
2
|
import type { FunctionStatus } from './FunctionStatus.js';
|
|
3
|
+
import type { FunctionType } from './FunctionType.js';
|
|
3
4
|
import type { TableAccessEntry } from './TableAccessEntry.js';
|
|
4
5
|
/**
|
|
5
6
|
* Function response.
|
|
@@ -21,6 +22,7 @@ export type FunctionResponse = {
|
|
|
21
22
|
output_schema: Record<string, any>;
|
|
22
23
|
pod_id: string;
|
|
23
24
|
status: FunctionStatus;
|
|
25
|
+
type: FunctionType;
|
|
24
26
|
updated_at: any;
|
|
25
27
|
user_id: string;
|
|
26
28
|
};
|
|
@@ -9,9 +9,11 @@ export type FunctionRunResponse = {
|
|
|
9
9
|
function_id: string;
|
|
10
10
|
id: string;
|
|
11
11
|
input_data?: (Record<string, any> | null);
|
|
12
|
+
job_id?: (string | null);
|
|
12
13
|
logs?: (string | null);
|
|
13
14
|
output_data?: (Record<string, any> | null);
|
|
14
15
|
started_at: any;
|
|
15
16
|
status: FunctionRunStatus;
|
|
17
|
+
user_email?: (string | null);
|
|
16
18
|
user_id: string;
|
|
17
19
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/* generated using openapi-typescript-codegen -- do not edit */
|
|
2
|
+
/* istanbul ignore file */
|
|
3
|
+
/* tslint:disable */
|
|
4
|
+
/* eslint-disable */
|
|
5
|
+
/**
|
|
6
|
+
* Execution mode for a function.
|
|
7
|
+
*/
|
|
8
|
+
export var FunctionType;
|
|
9
|
+
(function (FunctionType) {
|
|
10
|
+
FunctionType["API"] = "API";
|
|
11
|
+
FunctionType["JOB"] = "JOB";
|
|
12
|
+
})(FunctionType || (FunctionType = {}));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ApplicationAccessConfig } from './ApplicationAccessConfig.js';
|
|
2
|
+
import type { FunctionType } from './FunctionType.js';
|
|
2
3
|
import type { TableAccessEntry } from './TableAccessEntry.js';
|
|
3
4
|
/**
|
|
4
5
|
* Request to update a function.
|
|
@@ -11,4 +12,5 @@ export type UpdateFunctionRequest = {
|
|
|
11
12
|
config?: (Record<string, any> | null);
|
|
12
13
|
description?: (string | null);
|
|
13
14
|
icon_url?: (string | null);
|
|
15
|
+
type?: (FunctionType | null);
|
|
14
16
|
};
|
|
@@ -7,52 +7,42 @@ export function AssistantThemeScope({ className, children, theme = "auto", ...pr
|
|
|
7
7
|
return (_jsx("div", { "data-lemma-theme": theme, className: cx("lemma-assistant-theme", className), ...props, children: children }));
|
|
8
8
|
}
|
|
9
9
|
export const AssistantMessageViewport = forwardRef(function AssistantMessageViewport({ className, innerClassName, children, ...props }, ref) {
|
|
10
|
-
return (_jsx("div", { ref: ref, className: cx("lemma-assistant-viewport",
|
|
10
|
+
return (_jsx("div", { ref: ref, className: cx("lemma-assistant-viewport", className), ...props, children: _jsx("div", { className: cx("lemma-assistant-viewport-inner", innerClassName), children: children }) }));
|
|
11
11
|
});
|
|
12
12
|
export function AssistantShellLayout({ sidebar, sidebarVisible = false, main, className, }) {
|
|
13
13
|
const hasSidebar = !!sidebar;
|
|
14
|
-
return (_jsxs("div", { className: cx("lemma-assistant-shell", hasSidebar && "lemma-assistant-shell--with-sidebar", hasSidebar && sidebarVisible && "lemma-assistant-shell--sidebar-visible",
|
|
14
|
+
return (_jsxs("div", { className: cx("lemma-assistant-shell", hasSidebar && "lemma-assistant-shell--with-sidebar", hasSidebar && sidebarVisible && "lemma-assistant-shell--sidebar-visible", className), children: [sidebar && sidebarVisible ? (_jsx("div", { className: "lemma-assistant-shell-sidebar", children: sidebar })) : null, main] }));
|
|
15
15
|
}
|
|
16
16
|
export function AssistantHeader({ title, subtitle, badge, controls, tone = "subtle", className, }) {
|
|
17
|
-
return (_jsxs("div", { "data-tone": tone, className: cx("lemma-assistant-header",
|
|
17
|
+
return (_jsxs("div", { "data-tone": tone, className: cx("lemma-assistant-header", className), children: [_jsxs("div", { className: "lemma-assistant-header-copy", children: [badge ? (_jsx("div", { className: "lemma-assistant-header-badge", children: badge })) : null, _jsxs("div", { className: "lemma-assistant-header-titles", children: [_jsx("h3", { className: "lemma-assistant-header-title", children: title }), subtitle ? (_jsx("p", { className: "lemma-assistant-header-subtitle", children: subtitle })) : null] })] }), controls ? (_jsx("div", { className: "lemma-assistant-header-controls", children: controls })) : null] }));
|
|
18
18
|
}
|
|
19
19
|
export function AssistantConversationList({ conversations, activeConversationId, onSelectConversation, onNewConversation, renderConversationLabel, title = "Conversations", newLabel = "New", className, }) {
|
|
20
|
-
return (_jsxs("aside", { className: cx("lemma-assistant-conversation-list",
|
|
20
|
+
return (_jsxs("aside", { className: cx("lemma-assistant-conversation-list", className), children: [_jsx("div", { className: "lemma-assistant-conversation-list-header", children: _jsxs("div", { className: "lemma-assistant-conversation-list-header-row", children: [_jsxs("div", { className: "lemma-assistant-conversation-list-copy", children: [_jsx("div", { className: "lemma-assistant-conversation-list-title", children: title }), _jsxs("div", { className: "lemma-assistant-conversation-list-meta", children: [conversations.length, " total"] })] }), onNewConversation ? (_jsx("button", { type: "button", onClick: onNewConversation, className: "lemma-assistant-conversation-list-new", children: newLabel })) : null] }) }), _jsx("div", { className: "lemma-assistant-conversation-list-items", children: conversations.map((conversation) => {
|
|
21
21
|
const isActive = conversation.id === activeConversationId;
|
|
22
|
-
return (_jsxs("button", { type: "button", onClick: () => onSelectConversation(conversation.id), className: cx("lemma-assistant-conversation-list-item", "
|
|
23
|
-
? "lemma-assistant-conversation-list-item-active border-[color:color-mix(in_srgb,_var(--brand-primary)_44%,_var(--border-default))] bg-[color:color-mix(in_srgb,_var(--brand-glow)_42%,_var(--bg-surface))]"
|
|
24
|
-
: "border-[var(--border-default)] bg-[var(--bg-surface)] hover:bg-[var(--bg-subtle)]"), children: [_jsx("div", { className: "lemma-assistant-conversation-list-item-title truncate text-[12px] font-medium text-[var(--text-primary)]", children: renderConversationLabel
|
|
22
|
+
return (_jsxs("button", { type: "button", onClick: () => onSelectConversation(conversation.id), className: cx("lemma-assistant-conversation-list-item", isActive && "lemma-assistant-conversation-list-item-active"), children: [_jsx("div", { className: "lemma-assistant-conversation-list-item-title", children: renderConversationLabel
|
|
25
23
|
? renderConversationLabel({ conversation, isActive })
|
|
26
|
-
: (conversation.title || "Untitled conversation") }), _jsx("div", { className: "lemma-assistant-conversation-list-item-status
|
|
24
|
+
: (conversation.title || "Untitled conversation") }), _jsx("div", { className: "lemma-assistant-conversation-list-item-status", children: (conversation.status || "waiting").toLowerCase() })] }, conversation.id));
|
|
27
25
|
}) })] }));
|
|
28
26
|
}
|
|
29
27
|
export function AssistantModelPicker({ value, options, disabled, autoLabel = "Auto", getOptionLabel, onChange, className, }) {
|
|
30
28
|
const autoValue = "__AUTO__";
|
|
31
|
-
return (_jsxs("select", { value: value ?? autoValue, onChange: (event) => onChange(event.target.value === autoValue ? null : event.target.value), disabled: disabled, className: cx("lemma-assistant-model-picker",
|
|
29
|
+
return (_jsxs("select", { value: value ?? autoValue, onChange: (event) => onChange(event.target.value === autoValue ? null : event.target.value), disabled: disabled, className: cx("lemma-assistant-model-picker", className), "aria-label": "Conversation model", title: "Conversation model", children: [_jsx("option", { value: autoValue, children: autoLabel }), options.map((option) => (_jsx("option", { value: option, children: getOptionLabel ? getOptionLabel(option) : option }, option)))] }));
|
|
32
30
|
}
|
|
33
31
|
export function AssistantAskOverlay({ questionNumber, totalQuestions, question, options, selectedOptions, canContinue, continueLabel, onSelectOption, onContinue, onSkip, mode = "single_select", }) {
|
|
34
|
-
return (_jsxs("div", { className: "lemma-assistant-ask-overlay
|
|
32
|
+
return (_jsxs("div", { className: "lemma-assistant-ask-overlay", children: [_jsxs("div", { className: "lemma-assistant-ask-overlay-header", children: [_jsxs("div", { className: "lemma-assistant-ask-overlay-copy", children: [_jsxs("div", { className: "lemma-assistant-ask-overlay-kicker", children: ["Question ", questionNumber, " of ", totalQuestions] }), _jsx("p", { className: "lemma-assistant-ask-overlay-question", children: question })] }), onSkip ? (_jsx("button", { type: "button", onClick: onSkip, className: "lemma-assistant-ask-overlay-skip", children: "Skip" })) : null] }), _jsx("div", { className: "lemma-assistant-ask-overlay-options", children: options.map((option, optionIndex) => {
|
|
35
33
|
const isSelected = selectedOptions.includes(option);
|
|
36
34
|
const rankLabel = mode === "rank_priorities" && isSelected
|
|
37
35
|
? selectedOptions.indexOf(option) + 1
|
|
38
36
|
: null;
|
|
39
|
-
return (_jsx("button", { type: "button", onClick: () => onSelectOption(option), className: cx("lemma-assistant-ask-overlay-option", "
|
|
40
|
-
|
|
41
|
-
: "border-[var(--border-default)] bg-[var(--bg-canvas)] text-[var(--text-secondary)] hover:bg-[var(--bg-subtle)] hover:text-[var(--text-primary)]"), children: _jsxs("span", { className: "lemma-assistant-ask-overlay-option-label inline-flex items-center gap-2", children: [rankLabel ? (_jsx("span", { className: "inline-flex h-4 min-w-4 items-center justify-center rounded-full bg-[var(--brand-primary)] px-1 text-[10px] font-semibold text-[var(--text-on-brand)]", children: rankLabel })) : (_jsx("span", { className: cx("inline-block h-2.5 w-2.5 rounded-full border", isSelected
|
|
42
|
-
? "border-[var(--brand-primary)] bg-[var(--brand-primary)]"
|
|
43
|
-
: "border-[var(--border-default)] bg-transparent") })), option] }) }, `${option}-${optionIndex}`));
|
|
44
|
-
}) }), onContinue ? (_jsx("div", { className: "lemma-assistant-ask-overlay-actions flex justify-end", children: _jsx("button", { type: "button", onClick: onContinue, disabled: !canContinue, className: cx("lemma-assistant-ask-overlay-continue", "rounded-md px-2.5 py-1.5 text-[12px] font-medium transition-colors", canContinue
|
|
45
|
-
? "bg-[var(--brand-primary)] text-[var(--text-on-brand)] hover:bg-[color:color-mix(in_srgb,_var(--brand-primary)_88%,_var(--text-primary))]"
|
|
46
|
-
: "bg-[var(--bg-subtle)] text-[var(--text-tertiary)]"), children: continueLabel }) })) : null] }));
|
|
37
|
+
return (_jsx("button", { type: "button", onClick: () => onSelectOption(option), className: cx("lemma-assistant-ask-overlay-option", isSelected && "lemma-assistant-ask-overlay-option-selected"), children: _jsxs("span", { className: "lemma-assistant-ask-overlay-option-label", children: [rankLabel ? (_jsx("span", { className: "lemma-assistant-ask-overlay-option-rank", children: rankLabel })) : (_jsx("span", { className: cx("lemma-assistant-ask-overlay-option-indicator", isSelected && "lemma-assistant-ask-overlay-option-indicator-selected") })), option] }) }, `${option}-${optionIndex}`));
|
|
38
|
+
}) }), onContinue ? (_jsx("div", { className: "lemma-assistant-ask-overlay-actions", children: _jsx("button", { type: "button", onClick: onContinue, disabled: !canContinue, className: cx("lemma-assistant-ask-overlay-continue", canContinue && "lemma-assistant-ask-overlay-continue-enabled"), children: continueLabel }) })) : null] }));
|
|
47
39
|
}
|
|
48
40
|
export function AssistantComposer({ floating, status, pendingFiles, children, tone = "default", className, }) {
|
|
49
|
-
return (_jsxs("div", { "data-tone": tone, "data-has-status": status ? "true" : "false", "data-has-pending-files": pendingFiles ? "true" : "false", "data-has-floating": floating ? "true" : "false", className: cx("lemma-assistant-composer",
|
|
41
|
+
return (_jsxs("div", { "data-tone": tone, "data-has-status": status ? "true" : "false", "data-has-pending-files": pendingFiles ? "true" : "false", "data-has-floating": floating ? "true" : "false", className: cx("lemma-assistant-composer", className), children: [floating ? (_jsx("div", { className: "lemma-assistant-composer-floating", children: floating })) : null, status ? (_jsx("div", { className: "lemma-assistant-composer-status-rail", children: _jsx("div", { className: "lemma-assistant-composer-status", children: status }) })) : null, pendingFiles ? (_jsx("div", { className: "lemma-assistant-composer-pending", children: pendingFiles })) : null, _jsx("div", { className: "lemma-assistant-composer-body", children: children })] }));
|
|
50
42
|
}
|
|
51
43
|
export function AssistantPendingFileChip({ label, onRemove, className, }) {
|
|
52
|
-
return (_jsxs("span", { className: cx("lemma-assistant-pending-file-chip",
|
|
44
|
+
return (_jsxs("span", { className: cx("lemma-assistant-pending-file-chip", className), children: [_jsx("span", { className: "lemma-assistant-pending-file-chip-label", children: label }), onRemove ? (_jsx("button", { type: "button", onClick: onRemove, className: "lemma-assistant-pending-file-chip-remove", title: "Remove file", children: "\u00D7" })) : null] }));
|
|
53
45
|
}
|
|
54
46
|
export function AssistantStatusPill({ label, subtle = false, className, }) {
|
|
55
|
-
return (_jsxs("div", { className: cx("lemma-assistant-status-pill", "
|
|
56
|
-
? "lemma-assistant-status-pill-subtle border border-[color:color-mix(in_srgb,_var(--border-default)_72%,_transparent)] bg-[color:color-mix(in_srgb,_var(--bg-surface)_90%,_transparent)] text-[var(--text-tertiary)]"
|
|
57
|
-
: "border border-[color:color-mix(in_srgb,_var(--brand-primary)_24%,_var(--border-default))] bg-[color:color-mix(in_srgb,_var(--brand-glow)_28%,_var(--bg-surface))] text-[var(--text-secondary)]", className), children: [_jsxs("span", { className: "lemma-assistant-status-pill-dot relative inline-flex h-2.5 w-2.5 shrink-0", children: [_jsx("span", { className: "lemma-assistant-status-pill-dot-ping absolute inline-flex h-full w-full animate-ping rounded-full bg-[var(--brand-primary)]/45" }), _jsx("span", { className: "lemma-assistant-status-pill-dot-core relative inline-flex h-2.5 w-2.5 rounded-full bg-[var(--brand-primary)]" })] }), _jsx("span", { className: "lemma-assistant-status-pill-label truncate", children: label })] }));
|
|
47
|
+
return (_jsxs("div", { className: cx("lemma-assistant-status-pill", subtle && "lemma-assistant-status-pill-subtle", className), children: [_jsxs("span", { className: "lemma-assistant-status-pill-dot", children: [_jsx("span", { className: "lemma-assistant-status-pill-dot-ping" }), _jsx("span", { className: "lemma-assistant-status-pill-dot-core" })] }), _jsx("span", { className: "lemma-assistant-status-pill-label", children: label })] }));
|
|
58
48
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import type { AssistantRenderableMessage, AssistantToolInvocation } from "../useAssistantController.js";
|
|
3
|
-
import type { AssistantControllerView, AssistantConversationRenderArgs, AssistantMessageRenderArgs, AssistantPendingFileRenderArgs, AssistantPresentedFileRenderArgs, AssistantToolRenderArgs } from "./assistant-types.js";
|
|
3
|
+
import type { AssistantControllerView, AssistantConversationRenderArgs, AssistantMessageRenderArgs, AssistantPendingFileRenderArgs, AssistantPresentedFileRenderArgs, AssistantToolRenderArgs, EmptyStateSuggestion } from "./assistant-types.js";
|
|
4
4
|
type PlanStatus = "pending" | "in_progress" | "completed";
|
|
5
5
|
export interface PlanStepState {
|
|
6
6
|
step: string;
|
|
@@ -35,17 +35,22 @@ export interface ActiveToolBanner {
|
|
|
35
35
|
}
|
|
36
36
|
export type AssistantChromeStyle = "elevated" | "subtle" | "flat";
|
|
37
37
|
export type AssistantStatusPlacement = "inline" | "composer" | "none";
|
|
38
|
+
export type AssistantRadiusScale = "none" | "sm" | "md" | "lg" | "xl";
|
|
38
39
|
export interface AssistantExperienceViewProps {
|
|
39
40
|
controller: AssistantControllerView;
|
|
40
41
|
title?: ReactNode;
|
|
41
42
|
subtitle?: ReactNode;
|
|
42
43
|
placeholder?: string;
|
|
43
44
|
emptyState?: ReactNode;
|
|
45
|
+
emptyStateSuggestions?: EmptyStateSuggestion[];
|
|
44
46
|
draft?: string;
|
|
45
47
|
onDraftChange?: (value: string) => void;
|
|
46
48
|
showConversationList?: boolean;
|
|
47
49
|
chromeStyle?: AssistantChromeStyle;
|
|
48
50
|
statusPlacement?: AssistantStatusPlacement;
|
|
51
|
+
radius?: AssistantRadiusScale;
|
|
52
|
+
showModelPicker?: boolean;
|
|
53
|
+
showNewConversationButton?: boolean;
|
|
49
54
|
onNavigateResource?: (resourceType: string, resourceId: string, meta?: Record<string, unknown>) => void;
|
|
50
55
|
renderConversationLabel?: (args: AssistantConversationRenderArgs) => ReactNode;
|
|
51
56
|
renderMessageContent?: (args: AssistantMessageRenderArgs) => ReactNode;
|
|
@@ -65,9 +70,12 @@ export declare function PlanSummaryStrip({ plan, onHide }: {
|
|
|
65
70
|
onHide: () => void;
|
|
66
71
|
}): import("react/jsx-runtime").JSX.Element;
|
|
67
72
|
export declare function ThinkingIndicator(): import("react/jsx-runtime").JSX.Element | null;
|
|
68
|
-
export
|
|
73
|
+
export interface EmptyStateProps {
|
|
69
74
|
onSendMessage: (msg: string) => void;
|
|
70
|
-
|
|
75
|
+
suggestions?: EmptyStateSuggestion[];
|
|
76
|
+
}
|
|
77
|
+
export declare const DEFAULT_EMPTY_STATE_SUGGESTIONS: EmptyStateSuggestion[];
|
|
78
|
+
export declare function EmptyState({ onSendMessage, suggestions, }: EmptyStateProps): import("react/jsx-runtime").JSX.Element;
|
|
71
79
|
export declare function MessageGroup({ message, conversationId, onNavigateResource, onWidgetSendPrompt, isStreaming, showAssistantHeader, renderMessageContent, renderPresentedFile, renderToolInvocation, }: {
|
|
72
80
|
message: AssistantRenderableMessage;
|
|
73
81
|
conversationId?: string | null;
|
|
@@ -79,5 +87,5 @@ export declare function MessageGroup({ message, conversationId, onNavigateResour
|
|
|
79
87
|
renderPresentedFile?: (args: AssistantPresentedFileRenderArgs) => ReactNode;
|
|
80
88
|
renderToolInvocation?: (args: AssistantToolRenderArgs) => ReactNode;
|
|
81
89
|
}): import("react/jsx-runtime").JSX.Element;
|
|
82
|
-
export declare function AssistantExperienceView({ controller, title, subtitle, placeholder, emptyState, draft: controlledDraft, onDraftChange, showConversationList, chromeStyle, statusPlacement, onNavigateResource, renderConversationLabel, renderMessageContent, renderPresentedFile, renderPendingFile, renderToolInvocation, }: AssistantExperienceViewProps): import("react/jsx-runtime").JSX.Element;
|
|
90
|
+
export declare function AssistantExperienceView({ controller, title, subtitle, placeholder, emptyState, emptyStateSuggestions, draft: controlledDraft, onDraftChange, showConversationList, chromeStyle, statusPlacement, radius, showModelPicker, showNewConversationButton, onNavigateResource, renderConversationLabel, renderMessageContent, renderPresentedFile, renderPendingFile, renderToolInvocation, }: AssistantExperienceViewProps): import("react/jsx-runtime").JSX.Element;
|
|
83
91
|
export {};
|