lemma-sdk 0.2.19 → 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 +57 -32
- 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 +1246 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -179,37 +179,7 @@ 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
|
|
183
|
-
|
|
184
|
-
#### Important for Tailwind apps
|
|
185
|
-
|
|
186
|
-
If your app uses Tailwind and installs `lemma-sdk` from npm, Tailwind must scan the SDK package too. Otherwise the assistant can look half-styled: native file inputs may appear, layouts can collapse, spacing disappears, and buttons/header chrome look wrong.
|
|
187
|
-
|
|
188
|
-
For Tailwind v3, add the SDK package to `content`:
|
|
189
|
-
|
|
190
|
-
```js
|
|
191
|
-
// tailwind.config.js
|
|
192
|
-
export default {
|
|
193
|
-
content: [
|
|
194
|
-
"./index.html",
|
|
195
|
-
"./src/**/*.{js,ts,jsx,tsx}",
|
|
196
|
-
"./node_modules/lemma-sdk/dist/react/**/*.{js,mjs}",
|
|
197
|
-
],
|
|
198
|
-
}
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
If you are developing against a local checkout of the SDK source instead of the published npm package, scan the source files too:
|
|
202
|
-
|
|
203
|
-
```js
|
|
204
|
-
// tailwind.config.js
|
|
205
|
-
export default {
|
|
206
|
-
content: [
|
|
207
|
-
"./index.html",
|
|
208
|
-
"./src/**/*.{js,ts,jsx,tsx}",
|
|
209
|
-
"../lemma-typescript/src/react/**/*.{ts,tsx}",
|
|
210
|
-
],
|
|
211
|
-
}
|
|
212
|
-
```
|
|
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.
|
|
213
183
|
|
|
214
184
|
If you alias the package to local SDK source in Vite, make sure the alias points at the React source and stylesheet:
|
|
215
185
|
|
|
@@ -233,7 +203,6 @@ Quick checklist for developers:
|
|
|
233
203
|
- import `lemma-sdk/react/styles.css` once
|
|
234
204
|
- give the assistant container a real height
|
|
235
205
|
- if the assistant is inside flex/grid, add `min-height: 0` on the relevant parent
|
|
236
|
-
- if you use Tailwind, scan the SDK package or SDK source
|
|
237
206
|
- if you use `AssistantEmbedded`, pass `theme` directly there
|
|
238
207
|
- if you use `AssistantExperienceView`, wrap it in `AssistantThemeScope`
|
|
239
208
|
|
|
@@ -244,11 +213,22 @@ The assistant UI renders markdown by default:
|
|
|
244
213
|
- links open safely in a new tab by default
|
|
245
214
|
- lists, tables, blockquotes, inline code, and fenced code blocks are styled out of the box
|
|
246
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
|
+
|
|
247
226
|
#### Choose an integration level
|
|
248
227
|
|
|
249
228
|
##### 1. `AssistantEmbedded` for the fastest setup
|
|
250
229
|
|
|
251
230
|
Use `AssistantEmbedded` when you want a ready-made assistant surface with the SDK defaults.
|
|
231
|
+
This is the recommended integration for most users.
|
|
252
232
|
|
|
253
233
|
```tsx
|
|
254
234
|
import "lemma-sdk/react/styles.css";
|
|
@@ -264,7 +244,14 @@ function SupportAssistant() {
|
|
|
264
244
|
title="Support Assistant"
|
|
265
245
|
subtitle="Ask questions about this pod."
|
|
266
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
|
+
]}
|
|
267
252
|
showConversationList
|
|
253
|
+
showModelPicker={false}
|
|
254
|
+
radius="lg"
|
|
268
255
|
theme="auto"
|
|
269
256
|
/>
|
|
270
257
|
</div>
|
|
@@ -275,13 +262,18 @@ function SupportAssistant() {
|
|
|
275
262
|
Important notes:
|
|
276
263
|
|
|
277
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
|
|
278
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`
|
|
279
268
|
- the parent container must have a real height; if it lives inside flex/grid, `min-height: 0` is usually needed too
|
|
280
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
|
|
281
272
|
|
|
282
273
|
##### 2. `AssistantExperienceView` for the default UI with your own controller
|
|
283
274
|
|
|
284
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.
|
|
285
277
|
|
|
286
278
|
```tsx
|
|
287
279
|
import "lemma-sdk/react/styles.css";
|
|
@@ -305,6 +297,11 @@ function ControlledAssistant() {
|
|
|
305
297
|
title="Support Assistant"
|
|
306
298
|
subtitle="Direct use of the default assistant experience."
|
|
307
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
|
+
]}
|
|
308
305
|
showConversationList
|
|
309
306
|
chromeStyle="subtle"
|
|
310
307
|
statusPlacement="inline"
|
|
@@ -319,13 +316,19 @@ Useful props on `AssistantExperienceView`:
|
|
|
319
316
|
- `showConversationList`: show the built-in conversation sidebar
|
|
320
317
|
- `chromeStyle`: `"elevated" | "subtle" | "flat"`
|
|
321
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
|
|
322
323
|
- `renderMessageContent`: override markdown rendering for custom message content
|
|
323
324
|
- `renderToolInvocation`: replace the default tool activity renderer
|
|
324
325
|
- `renderPresentedFile` and `renderPendingFile`: customize attachment rendering
|
|
326
|
+
- prefer this over building from primitives if you still want the SDK's default assistant experience
|
|
325
327
|
|
|
326
328
|
##### 3. `useAssistantController` + primitives for a custom shell
|
|
327
329
|
|
|
328
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.
|
|
329
332
|
|
|
330
333
|
```tsx
|
|
331
334
|
import "lemma-sdk/react/styles.css";
|
|
@@ -335,6 +338,7 @@ import {
|
|
|
335
338
|
AssistantMessageViewport,
|
|
336
339
|
AssistantShellLayout,
|
|
337
340
|
AssistantThemeScope,
|
|
341
|
+
EmptyState,
|
|
338
342
|
MessageGroup,
|
|
339
343
|
PlanSummaryStrip,
|
|
340
344
|
ThinkingIndicator,
|
|
@@ -369,6 +373,19 @@ function CustomAssistantShell() {
|
|
|
369
373
|
{activeToolBanner ? <div>{activeToolBanner.summary}</div> : null}
|
|
370
374
|
|
|
371
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
|
+
|
|
372
389
|
{rows.map((row, index) => (
|
|
373
390
|
<MessageGroup
|
|
374
391
|
key={row.id}
|
|
@@ -411,6 +428,14 @@ Useful primitives exported from `lemma-sdk/react`:
|
|
|
411
428
|
- `PlanSummaryStrip`
|
|
412
429
|
- `ThinkingIndicator`
|
|
413
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
|
+
|
|
414
439
|
#### Theming
|
|
415
440
|
|
|
416
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 {};
|