lemma-sdk 0.2.17 → 0.2.19
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 +213 -76
- package/dist/openapi_client/models/AssistantResponse.d.ts +2 -0
- package/dist/openapi_client/models/CreateAssistantRequest.d.ts +2 -0
- package/dist/openapi_client/models/DeskResponse.d.ts +1 -0
- package/dist/openapi_client/models/UpdateAssistantRequest.d.ts +2 -0
- package/dist/openapi_client/services/ConversationsService.d.ts +1 -2
- package/dist/openapi_client/services/ConversationsService.js +1 -3
- package/dist/react/components/AssistantChrome.d.ts +8 -3
- package/dist/react/components/AssistantChrome.js +6 -6
- package/dist/react/components/AssistantEmbedded.d.ts +3 -1
- package/dist/react/components/AssistantEmbedded.js +2 -2
- package/dist/react/components/AssistantExperience.d.ts +5 -1
- package/dist/react/components/AssistantExperience.js +56 -25
- package/dist/react/index.d.ts +2 -2
- package/dist/react/styles.css +361 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -169,85 +169,86 @@ Notes:
|
|
|
169
169
|
|
|
170
170
|
## Assistants + Agent Runs
|
|
171
171
|
|
|
172
|
-
### React assistant
|
|
172
|
+
### React assistant UI
|
|
173
173
|
|
|
174
|
-
`lemma-sdk/react`
|
|
174
|
+
`lemma-sdk/react` ships the assistant controller, the default assistant experience, and the lower-level UI primitives used to build custom shells.
|
|
175
175
|
|
|
176
|
-
|
|
176
|
+
Import the bundled stylesheet once anywhere in your app:
|
|
177
177
|
|
|
178
178
|
```tsx
|
|
179
179
|
import "lemma-sdk/react/styles.css";
|
|
180
180
|
```
|
|
181
181
|
|
|
182
|
-
The stylesheet
|
|
183
|
-
The SDK UI now ships its own semantic assistant classes and default styling, so consumers should not need the Lemma app's internal theme setup or Tailwind config just to render the assistant correctly.
|
|
182
|
+
The stylesheet includes the SDK theme tokens and semantic assistant classes. You do not need the Lemma app's internal Tailwind setup just to render the assistant correctly.
|
|
184
183
|
|
|
185
|
-
|
|
186
|
-
import {
|
|
187
|
-
MessageGroup,
|
|
188
|
-
PlanSummaryStrip,
|
|
189
|
-
ThinkingIndicator,
|
|
190
|
-
buildDisplayMessageRows,
|
|
191
|
-
getActiveToolBanner,
|
|
192
|
-
latestPlanSummary,
|
|
193
|
-
useAssistantController,
|
|
194
|
-
} from "lemma-sdk/react";
|
|
184
|
+
#### Important for Tailwind apps
|
|
195
185
|
|
|
196
|
-
|
|
197
|
-
const assistant = useAssistantController({
|
|
198
|
-
client,
|
|
199
|
-
assistantId: "uuid",
|
|
200
|
-
podId: "pod_123",
|
|
201
|
-
});
|
|
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.
|
|
202
187
|
|
|
203
|
-
|
|
204
|
-
const plan = latestPlanSummary(assistant.messages);
|
|
205
|
-
const activeToolBanner = getActiveToolBanner(assistant.messages);
|
|
188
|
+
For Tailwind v3, add the SDK package to `content`:
|
|
206
189
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
message={row.message}
|
|
216
|
-
conversationId={assistant.activeConversationId}
|
|
217
|
-
onWidgetSendPrompt={(text) => assistant.sendMessage(text)}
|
|
218
|
-
isStreaming={assistant.isActiveConversationRunning && row.sourceIndexes.includes(assistant.messages.length - 1)}
|
|
219
|
-
showAssistantHeader={index === 0 || rows[index - 1]?.message.role !== "assistant"}
|
|
220
|
-
renderMessageContent={({ message }) => <div>{message.content}</div>}
|
|
221
|
-
/>
|
|
222
|
-
))}
|
|
223
|
-
|
|
224
|
-
{assistant.isActiveConversationRunning ? <ThinkingIndicator /> : null}
|
|
225
|
-
</div>
|
|
226
|
-
);
|
|
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
|
+
],
|
|
227
198
|
}
|
|
228
199
|
```
|
|
229
200
|
|
|
230
|
-
|
|
201
|
+
If you are developing against a local checkout of the SDK source instead of the published npm package, scan the source files too:
|
|
231
202
|
|
|
232
|
-
|
|
233
|
-
|
|
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
|
+
```
|
|
234
213
|
|
|
235
|
-
|
|
214
|
+
If you alias the package to local SDK source in Vite, make sure the alias points at the React source and stylesheet:
|
|
236
215
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
-
|
|
245
|
-
-
|
|
246
|
-
-
|
|
247
|
-
|
|
248
|
-
|
|
216
|
+
```ts
|
|
217
|
+
// vite.config.ts
|
|
218
|
+
import path from "node:path";
|
|
219
|
+
|
|
220
|
+
export default {
|
|
221
|
+
resolve: {
|
|
222
|
+
alias: {
|
|
223
|
+
"lemma-sdk/react/styles.css": path.resolve(__dirname, "../lemma-typescript/src/react/styles.css"),
|
|
224
|
+
"lemma-sdk/react": path.resolve(__dirname, "../lemma-typescript/src/react/index.ts"),
|
|
225
|
+
"lemma-sdk": path.resolve(__dirname, "../lemma-typescript/src/index.ts"),
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Quick checklist for developers:
|
|
232
|
+
|
|
233
|
+
- import `lemma-sdk/react/styles.css` once
|
|
234
|
+
- give the assistant container a real height
|
|
235
|
+
- 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
|
+
- if you use `AssistantEmbedded`, pass `theme` directly there
|
|
238
|
+
- if you use `AssistantExperienceView`, wrap it in `AssistantThemeScope`
|
|
239
|
+
|
|
240
|
+
The assistant UI renders markdown by default:
|
|
241
|
+
|
|
242
|
+
- GitHub-flavored markdown is enabled for assistant and user messages
|
|
243
|
+
- raw HTML is not rendered
|
|
244
|
+
- links open safely in a new tab by default
|
|
245
|
+
- lists, tables, blockquotes, inline code, and fenced code blocks are styled out of the box
|
|
249
246
|
|
|
250
|
-
|
|
247
|
+
#### Choose an integration level
|
|
248
|
+
|
|
249
|
+
##### 1. `AssistantEmbedded` for the fastest setup
|
|
250
|
+
|
|
251
|
+
Use `AssistantEmbedded` when you want a ready-made assistant surface with the SDK defaults.
|
|
251
252
|
|
|
252
253
|
```tsx
|
|
253
254
|
import "lemma-sdk/react/styles.css";
|
|
@@ -255,20 +256,76 @@ import { AssistantEmbedded } from "lemma-sdk/react";
|
|
|
255
256
|
|
|
256
257
|
function SupportAssistant() {
|
|
257
258
|
return (
|
|
258
|
-
<
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
259
|
+
<div style={{ height: 720, minHeight: 0 }}>
|
|
260
|
+
<AssistantEmbedded
|
|
261
|
+
client={client}
|
|
262
|
+
podId="pod_123"
|
|
263
|
+
assistantId="uuid"
|
|
264
|
+
title="Support Assistant"
|
|
265
|
+
subtitle="Ask questions about this pod."
|
|
266
|
+
placeholder="Message Support Assistant"
|
|
267
|
+
showConversationList
|
|
268
|
+
theme="auto"
|
|
269
|
+
/>
|
|
270
|
+
</div>
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Important notes:
|
|
276
|
+
|
|
277
|
+
- `theme` accepts `"auto" | "light" | "dark"`
|
|
278
|
+
- `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
|
+
- the parent container must have a real height; if it lives inside flex/grid, `min-height: 0` is usually needed too
|
|
280
|
+
- attachments are queued into the composer and sent with the next message by default
|
|
281
|
+
|
|
282
|
+
##### 2. `AssistantExperienceView` for the default UI with your own controller
|
|
283
|
+
|
|
284
|
+
Use `AssistantExperienceView` when you want the built-in assistant layout, but you need to own the controller lifecycle yourself.
|
|
285
|
+
|
|
286
|
+
```tsx
|
|
287
|
+
import "lemma-sdk/react/styles.css";
|
|
288
|
+
import {
|
|
289
|
+
AssistantExperienceView,
|
|
290
|
+
AssistantThemeScope,
|
|
291
|
+
useAssistantController,
|
|
292
|
+
} from "lemma-sdk/react";
|
|
293
|
+
|
|
294
|
+
function ControlledAssistant() {
|
|
295
|
+
const assistant = useAssistantController({
|
|
296
|
+
client,
|
|
297
|
+
podId: "pod_123",
|
|
298
|
+
assistantId: "uuid",
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
return (
|
|
302
|
+
<AssistantThemeScope theme="dark" style={{ height: 720 }}>
|
|
303
|
+
<AssistantExperienceView
|
|
304
|
+
controller={assistant}
|
|
305
|
+
title="Support Assistant"
|
|
306
|
+
subtitle="Direct use of the default assistant experience."
|
|
307
|
+
placeholder="Message Support Assistant"
|
|
308
|
+
showConversationList
|
|
309
|
+
chromeStyle="subtle"
|
|
310
|
+
statusPlacement="inline"
|
|
311
|
+
/>
|
|
312
|
+
</AssistantThemeScope>
|
|
267
313
|
);
|
|
268
314
|
}
|
|
269
315
|
```
|
|
270
316
|
|
|
271
|
-
|
|
317
|
+
Useful props on `AssistantExperienceView`:
|
|
318
|
+
|
|
319
|
+
- `showConversationList`: show the built-in conversation sidebar
|
|
320
|
+
- `chromeStyle`: `"elevated" | "subtle" | "flat"`
|
|
321
|
+
- `statusPlacement`: `"inline" | "composer" | "none"`
|
|
322
|
+
- `renderMessageContent`: override markdown rendering for custom message content
|
|
323
|
+
- `renderToolInvocation`: replace the default tool activity renderer
|
|
324
|
+
- `renderPresentedFile` and `renderPendingFile`: customize attachment rendering
|
|
325
|
+
|
|
326
|
+
##### 3. `useAssistantController` + primitives for a custom shell
|
|
327
|
+
|
|
328
|
+
Use the primitives when you want full control over layout and app chrome.
|
|
272
329
|
|
|
273
330
|
```tsx
|
|
274
331
|
import "lemma-sdk/react/styles.css";
|
|
@@ -278,29 +335,109 @@ import {
|
|
|
278
335
|
AssistantMessageViewport,
|
|
279
336
|
AssistantShellLayout,
|
|
280
337
|
AssistantThemeScope,
|
|
338
|
+
MessageGroup,
|
|
339
|
+
PlanSummaryStrip,
|
|
340
|
+
ThinkingIndicator,
|
|
341
|
+
buildDisplayMessageRows,
|
|
342
|
+
getActiveToolBanner,
|
|
343
|
+
latestPlanSummary,
|
|
344
|
+
useAssistantController,
|
|
281
345
|
} from "lemma-sdk/react";
|
|
282
346
|
|
|
283
347
|
function CustomAssistantShell() {
|
|
348
|
+
const assistant = useAssistantController({
|
|
349
|
+
client,
|
|
350
|
+
podId: "pod_123",
|
|
351
|
+
assistantId: "uuid",
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
const rows = buildDisplayMessageRows(assistant.messages);
|
|
355
|
+
const plan = latestPlanSummary(assistant.messages);
|
|
356
|
+
const activeToolBanner = getActiveToolBanner(assistant.messages);
|
|
357
|
+
|
|
284
358
|
return (
|
|
285
|
-
<AssistantThemeScope>
|
|
359
|
+
<AssistantThemeScope theme="auto" style={{ height: 720 }}>
|
|
286
360
|
<AssistantShellLayout
|
|
287
|
-
main={
|
|
361
|
+
main={(
|
|
288
362
|
<div className="flex min-h-0 flex-1 flex-col gap-3">
|
|
289
|
-
<AssistantHeader
|
|
363
|
+
<AssistantHeader
|
|
364
|
+
title="Lemma Assistant"
|
|
365
|
+
subtitle="Ask anything"
|
|
366
|
+
/>
|
|
367
|
+
|
|
368
|
+
{plan ? <PlanSummaryStrip plan={plan} onHide={() => {}} /> : null}
|
|
369
|
+
{activeToolBanner ? <div>{activeToolBanner.summary}</div> : null}
|
|
370
|
+
|
|
290
371
|
<AssistantMessageViewport>
|
|
291
|
-
|
|
372
|
+
{rows.map((row, index) => (
|
|
373
|
+
<MessageGroup
|
|
374
|
+
key={row.id}
|
|
375
|
+
message={row.message}
|
|
376
|
+
conversationId={assistant.activeConversationId}
|
|
377
|
+
onWidgetSendPrompt={(text) => assistant.sendMessage(text)}
|
|
378
|
+
isStreaming={assistant.isActiveConversationRunning && row.sourceIndexes.includes(assistant.messages.length - 1)}
|
|
379
|
+
showAssistantHeader={index === 0 || rows[index - 1]?.message.role !== "assistant"}
|
|
380
|
+
renderMessageContent={({ message }) => <div>{message.content}</div>}
|
|
381
|
+
/>
|
|
382
|
+
))}
|
|
383
|
+
|
|
384
|
+
{assistant.isActiveConversationRunning ? <ThinkingIndicator /> : null}
|
|
292
385
|
</AssistantMessageViewport>
|
|
386
|
+
|
|
293
387
|
<AssistantComposer>
|
|
294
388
|
<textarea placeholder="Message Lemma Assistant" />
|
|
295
389
|
</AssistantComposer>
|
|
296
390
|
</div>
|
|
297
|
-
}
|
|
391
|
+
)}
|
|
298
392
|
/>
|
|
299
393
|
</AssistantThemeScope>
|
|
300
394
|
);
|
|
301
395
|
}
|
|
302
396
|
```
|
|
303
397
|
|
|
398
|
+
Useful primitives exported from `lemma-sdk/react`:
|
|
399
|
+
|
|
400
|
+
- `AssistantThemeScope`
|
|
401
|
+
- `AssistantHeader`
|
|
402
|
+
- `AssistantConversationList`
|
|
403
|
+
- `AssistantModelPicker`
|
|
404
|
+
- `AssistantShellLayout`
|
|
405
|
+
- `AssistantComposer`
|
|
406
|
+
- `AssistantMessageViewport`
|
|
407
|
+
- `AssistantAskOverlay`
|
|
408
|
+
- `AssistantPendingFileChip`
|
|
409
|
+
- `AssistantStatusPill`
|
|
410
|
+
- `MessageGroup`
|
|
411
|
+
- `PlanSummaryStrip`
|
|
412
|
+
- `ThinkingIndicator`
|
|
413
|
+
|
|
414
|
+
#### Theming
|
|
415
|
+
|
|
416
|
+
Use `AssistantThemeScope` around custom assistant layouts:
|
|
417
|
+
|
|
418
|
+
```tsx
|
|
419
|
+
import { AssistantThemeScope } from "lemma-sdk/react";
|
|
420
|
+
|
|
421
|
+
<AssistantThemeScope theme="light">
|
|
422
|
+
<YourAssistant />
|
|
423
|
+
</AssistantThemeScope>
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
Theme behavior:
|
|
427
|
+
|
|
428
|
+
- `theme="auto"`: follows host dark-mode selectors and system color scheme
|
|
429
|
+
- `theme="light"`: forces the light SDK palette
|
|
430
|
+
- `theme="dark"`: forces the dark SDK palette
|
|
431
|
+
|
|
432
|
+
If you use `AssistantEmbedded`, pass `theme` directly on that component instead of wrapping it again.
|
|
433
|
+
|
|
434
|
+
#### What belongs in the SDK vs your app
|
|
435
|
+
|
|
436
|
+
The intended split is:
|
|
437
|
+
|
|
438
|
+
- SDK: `useAssistantController`, message/tool normalization, markdown rendering, plan parsing, tool rollups, and reusable assistant UI primitives
|
|
439
|
+
- App: modal shell, fullscreen/window controls, route navigation, workspace/file viewers, and product-specific renderers
|
|
440
|
+
|
|
304
441
|
### Assistant names (resource key)
|
|
305
442
|
|
|
306
443
|
Assistant CRUD is name-based:
|
|
@@ -8,8 +8,10 @@ export type AssistantResponse = {
|
|
|
8
8
|
accessible_applications: Array<ApplicationAccessConfig>;
|
|
9
9
|
accessible_folders: Array<string>;
|
|
10
10
|
accessible_tables: Array<TableAccessEntry>;
|
|
11
|
+
agent_names: Array<string>;
|
|
11
12
|
created_at: any;
|
|
12
13
|
description: (string | null);
|
|
14
|
+
function_names: Array<string>;
|
|
13
15
|
icon_url: (string | null);
|
|
14
16
|
id: string;
|
|
15
17
|
instruction: string;
|
|
@@ -8,7 +8,9 @@ export type CreateAssistantRequest = {
|
|
|
8
8
|
accessible_applications?: Array<ApplicationAccessConfig>;
|
|
9
9
|
accessible_folders?: Array<string>;
|
|
10
10
|
accessible_tables?: Array<TableAccessEntry>;
|
|
11
|
+
agent_names?: Array<string>;
|
|
11
12
|
description?: (string | null);
|
|
13
|
+
function_names?: Array<string>;
|
|
12
14
|
icon_url?: (string | null);
|
|
13
15
|
instruction: string;
|
|
14
16
|
name: string;
|
|
@@ -8,7 +8,9 @@ export type UpdateAssistantRequest = {
|
|
|
8
8
|
accessible_applications?: (Array<ApplicationAccessConfig> | null);
|
|
9
9
|
accessible_folders?: (Array<string> | null);
|
|
10
10
|
accessible_tables?: (Array<TableAccessEntry> | null);
|
|
11
|
+
agent_names?: (Array<string> | null);
|
|
11
12
|
description?: (string | null);
|
|
13
|
+
function_names?: (Array<string> | null);
|
|
12
14
|
icon_url?: (string | null);
|
|
13
15
|
instruction?: (string | null);
|
|
14
16
|
tool_sets?: (Array<ToolSet> | null);
|
|
@@ -45,13 +45,12 @@ export declare class ConversationsService {
|
|
|
45
45
|
* List Messages
|
|
46
46
|
* List messages in a conversation with token pagination. Use `page_token` to fetch older messages.
|
|
47
47
|
* @param conversationId
|
|
48
|
-
* @param podId
|
|
49
48
|
* @param pageToken
|
|
50
49
|
* @param limit
|
|
51
50
|
* @returns ConversationMessageListResponse Successful Response
|
|
52
51
|
* @throws ApiError
|
|
53
52
|
*/
|
|
54
|
-
static conversationMessageList(conversationId: string,
|
|
53
|
+
static conversationMessageList(conversationId: string, pageToken?: (string | null), limit?: number): CancelablePromise<ConversationMessageListResponse>;
|
|
55
54
|
/**
|
|
56
55
|
* Send Message (Stream)
|
|
57
56
|
* @param conversationId
|
|
@@ -95,13 +95,12 @@ export class ConversationsService {
|
|
|
95
95
|
* List Messages
|
|
96
96
|
* List messages in a conversation with token pagination. Use `page_token` to fetch older messages.
|
|
97
97
|
* @param conversationId
|
|
98
|
-
* @param podId
|
|
99
98
|
* @param pageToken
|
|
100
99
|
* @param limit
|
|
101
100
|
* @returns ConversationMessageListResponse Successful Response
|
|
102
101
|
* @throws ApiError
|
|
103
102
|
*/
|
|
104
|
-
static conversationMessageList(conversationId,
|
|
103
|
+
static conversationMessageList(conversationId, pageToken, limit = 20) {
|
|
105
104
|
return __request(OpenAPI, {
|
|
106
105
|
method: 'GET',
|
|
107
106
|
url: '/conversations/{conversation_id}/messages',
|
|
@@ -109,7 +108,6 @@ export class ConversationsService {
|
|
|
109
108
|
'conversation_id': conversationId,
|
|
110
109
|
},
|
|
111
110
|
query: {
|
|
112
|
-
'pod_id': podId,
|
|
113
111
|
'page_token': pageToken,
|
|
114
112
|
'limit': limit,
|
|
115
113
|
},
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { type ComponentPropsWithoutRef, type ReactNode } from "react";
|
|
2
2
|
import type { AssistantConversationListItem, AssistantConversationRenderArgs } from "./assistant-types.js";
|
|
3
|
+
export type AssistantSurfaceTone = "default" | "subtle" | "flat";
|
|
4
|
+
export type AssistantThemeMode = "auto" | "light" | "dark";
|
|
3
5
|
export interface AssistantThemeScopeProps extends ComponentPropsWithoutRef<"div"> {
|
|
4
6
|
children: ReactNode;
|
|
7
|
+
theme?: AssistantThemeMode;
|
|
5
8
|
}
|
|
6
|
-
export declare function AssistantThemeScope({ className, children, ...props }: AssistantThemeScopeProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export declare function AssistantThemeScope({ className, children, theme, ...props }: AssistantThemeScopeProps): import("react/jsx-runtime").JSX.Element;
|
|
7
10
|
export interface AssistantHeaderProps {
|
|
8
11
|
title: ReactNode;
|
|
9
12
|
subtitle?: ReactNode;
|
|
10
13
|
badge?: ReactNode;
|
|
11
14
|
controls?: ReactNode;
|
|
15
|
+
tone?: AssistantSurfaceTone;
|
|
12
16
|
className?: string;
|
|
13
17
|
}
|
|
14
18
|
export interface AssistantMessageViewportProps extends ComponentPropsWithoutRef<"div"> {
|
|
@@ -23,7 +27,7 @@ export interface AssistantShellLayoutProps {
|
|
|
23
27
|
className?: string;
|
|
24
28
|
}
|
|
25
29
|
export declare function AssistantShellLayout({ sidebar, sidebarVisible, main, className, }: AssistantShellLayoutProps): import("react/jsx-runtime").JSX.Element;
|
|
26
|
-
export declare function AssistantHeader({ title, subtitle, badge, controls, className, }: AssistantHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
export declare function AssistantHeader({ title, subtitle, badge, controls, tone, className, }: AssistantHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
27
31
|
export interface AssistantConversationListProps {
|
|
28
32
|
conversations: AssistantConversationListItem[];
|
|
29
33
|
activeConversationId: string | null;
|
|
@@ -69,9 +73,10 @@ export interface AssistantComposerProps {
|
|
|
69
73
|
status?: ReactNode;
|
|
70
74
|
pendingFiles?: ReactNode;
|
|
71
75
|
children: ReactNode;
|
|
76
|
+
tone?: AssistantSurfaceTone;
|
|
72
77
|
className?: string;
|
|
73
78
|
}
|
|
74
|
-
export declare function AssistantComposer({ floating, status, pendingFiles, children, className, }: AssistantComposerProps): import("react/jsx-runtime").JSX.Element;
|
|
79
|
+
export declare function AssistantComposer({ floating, status, pendingFiles, children, tone, className, }: AssistantComposerProps): import("react/jsx-runtime").JSX.Element;
|
|
75
80
|
export declare function AssistantPendingFileChip({ label, onRemove, className, }: AssistantPendingFileChipProps): import("react/jsx-runtime").JSX.Element;
|
|
76
81
|
export interface AssistantStatusPillProps {
|
|
77
82
|
label: ReactNode;
|
|
@@ -3,8 +3,8 @@ import { forwardRef } from "react";
|
|
|
3
3
|
function cx(...values) {
|
|
4
4
|
return values.filter(Boolean).join(" ");
|
|
5
5
|
}
|
|
6
|
-
export function AssistantThemeScope({ className, children, ...props }) {
|
|
7
|
-
return (_jsx("div", { className: cx("lemma-assistant-theme", className), ...props, children: children }));
|
|
6
|
+
export function AssistantThemeScope({ className, children, theme = "auto", ...props }) {
|
|
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
10
|
return (_jsx("div", { ref: ref, className: cx("lemma-assistant-viewport", "min-h-0 flex-1 overflow-y-auto bg-[var(--bg-surface)] px-4 py-4", className), ...props, children: _jsx("div", { className: cx("lemma-assistant-viewport-inner", "mx-auto flex w-full max-w-5xl flex-col gap-3", innerClassName), children: children }) }));
|
|
@@ -13,8 +13,8 @@ export function AssistantShellLayout({ sidebar, sidebarVisible = false, main, cl
|
|
|
13
13
|
const hasSidebar = !!sidebar;
|
|
14
14
|
return (_jsxs("div", { className: cx("lemma-assistant-shell", hasSidebar && "lemma-assistant-shell--with-sidebar", hasSidebar && sidebarVisible && "lemma-assistant-shell--sidebar-visible", "mx-auto h-full w-full min-h-0 font-sans antialiased", className), children: [sidebar && sidebarVisible ? (_jsx("div", { className: "lemma-assistant-shell-sidebar", children: sidebar })) : null, main] }));
|
|
15
15
|
}
|
|
16
|
-
export function AssistantHeader({ title, subtitle, badge, controls, className, }) {
|
|
17
|
-
return (_jsxs("div", { className: cx("lemma-assistant-header", "flex items-center justify-between border-b border-[color:color-mix(in_srgb,_var(--border-default)_80%,_transparent)] px-4 py-3", className), children: [_jsxs("div", { className: "lemma-assistant-header-copy flex items-center gap-2.5", children: [badge ? (_jsx("div", { className: "lemma-assistant-header-badge flex h-7 w-7 items-center justify-center rounded-full bg-[linear-gradient(135deg,var(--brand-primary),var(--brand-secondary))] shadow-[var(--shadow-xs)]", children: badge })) : null, _jsxs("div", { className: "lemma-assistant-header-titles", children: [_jsx("h3", { className: "lemma-assistant-header-title text-[13px] font-semibold leading-tight text-[var(--text-primary)]", children: title }), subtitle ? (_jsx("p", { className: "lemma-assistant-header-subtitle text-[11px] text-[var(--text-tertiary)]", children: subtitle })) : null] })] }), controls ? (_jsx("div", { className: "lemma-assistant-header-controls flex items-center gap-1", children: controls })) : null] }));
|
|
16
|
+
export function AssistantHeader({ title, subtitle, badge, controls, tone = "subtle", className, }) {
|
|
17
|
+
return (_jsxs("div", { "data-tone": tone, className: cx("lemma-assistant-header", "flex items-center justify-between border-b border-[color:color-mix(in_srgb,_var(--border-default)_80%,_transparent)] px-4 py-3", className), children: [_jsxs("div", { className: "lemma-assistant-header-copy flex items-center gap-2.5", children: [badge ? (_jsx("div", { className: "lemma-assistant-header-badge flex h-7 w-7 items-center justify-center rounded-full bg-[linear-gradient(135deg,var(--brand-primary),var(--brand-secondary))] shadow-[var(--shadow-xs)]", children: badge })) : null, _jsxs("div", { className: "lemma-assistant-header-titles", children: [_jsx("h3", { className: "lemma-assistant-header-title text-[13px] font-semibold leading-tight text-[var(--text-primary)]", children: title }), subtitle ? (_jsx("p", { className: "lemma-assistant-header-subtitle text-[11px] text-[var(--text-tertiary)]", children: subtitle })) : null] })] }), controls ? (_jsx("div", { className: "lemma-assistant-header-controls flex items-center gap-1", children: controls })) : null] }));
|
|
18
18
|
}
|
|
19
19
|
export function AssistantConversationList({ conversations, activeConversationId, onSelectConversation, onNewConversation, renderConversationLabel, title = "Conversations", newLabel = "New", className, }) {
|
|
20
20
|
return (_jsxs("aside", { className: cx("lemma-assistant-conversation-list", "flex h-full min-h-0 flex-col overflow-hidden rounded-2xl border border-[color:color-mix(in_srgb,_var(--border-default)_80%,_transparent)] bg-[var(--bg-surface)] shadow-[var(--shadow-lg)]", className), children: [_jsx("div", { className: "lemma-assistant-conversation-list-header border-b border-[color:color-mix(in_srgb,_var(--border-default)_80%,_transparent)] px-4 py-3", children: _jsxs("div", { className: "lemma-assistant-conversation-list-header-row flex items-center justify-between gap-3", children: [_jsxs("div", { className: "lemma-assistant-conversation-list-copy", children: [_jsx("div", { className: "lemma-assistant-conversation-list-title text-[13px] font-semibold text-[var(--text-primary)]", children: title }), _jsxs("div", { className: "lemma-assistant-conversation-list-meta mt-1 text-[11px] text-[var(--text-tertiary)]", children: [conversations.length, " total"] })] }), onNewConversation ? (_jsx("button", { type: "button", onClick: onNewConversation, className: "lemma-assistant-conversation-list-new rounded-full border border-[var(--border-default)] bg-[var(--bg-surface)] px-3 py-1.5 text-[11px] font-medium text-[var(--text-secondary)] hover:text-[var(--text-primary)]", children: newLabel })) : null] }) }), _jsx("div", { className: "lemma-assistant-conversation-list-items min-h-0 flex-1 overflow-y-auto p-3 space-y-2", children: conversations.map((conversation) => {
|
|
@@ -45,8 +45,8 @@ export function AssistantAskOverlay({ questionNumber, totalQuestions, question,
|
|
|
45
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
46
|
: "bg-[var(--bg-subtle)] text-[var(--text-tertiary)]"), children: continueLabel }) })) : null] }));
|
|
47
47
|
}
|
|
48
|
-
export function AssistantComposer({ floating, status, pendingFiles, children, className, }) {
|
|
49
|
-
return (_jsxs("div", { className: cx("lemma-assistant-composer", "relative rounded-2xl border border-[color:color-mix(in_srgb,_var(--border-default)_80%,_transparent)] bg-[var(--bg-surface)] p-2 shadow-[var(--shadow-md)]", className), children: [floating ? (_jsx("div", { className: "lemma-assistant-composer-floating absolute bottom-[calc(100%+8px)] left-0 right-0 z-20", children: floating })) : null, _jsx("div", { className: "lemma-assistant-composer-status-rail min-h-[34px] px-2 pb-1", children: _jsx("div", { className: "lemma-assistant-composer-status flex min-h-[26px] items-center transition-opacity duration-200", children: status
|
|
48
|
+
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", "relative rounded-2xl border border-[color:color-mix(in_srgb,_var(--border-default)_80%,_transparent)] bg-[var(--bg-surface)] p-2 shadow-[var(--shadow-md)]", className), children: [floating ? (_jsx("div", { className: "lemma-assistant-composer-floating absolute bottom-[calc(100%+8px)] left-0 right-0 z-20", children: floating })) : null, status ? (_jsx("div", { className: "lemma-assistant-composer-status-rail min-h-[34px] px-2 pb-1", children: _jsx("div", { className: "lemma-assistant-composer-status flex min-h-[26px] items-center transition-opacity duration-200", children: status }) })) : null, pendingFiles ? (_jsx("div", { className: "lemma-assistant-composer-pending flex flex-wrap items-center gap-1.5 px-1 pb-1.5", children: pendingFiles })) : null, _jsx("div", { className: "lemma-assistant-composer-body", children: children })] }));
|
|
50
50
|
}
|
|
51
51
|
export function AssistantPendingFileChip({ label, onRemove, className, }) {
|
|
52
52
|
return (_jsxs("span", { className: cx("lemma-assistant-pending-file-chip", "inline-flex max-w-full items-center gap-1.5 rounded-full bg-[var(--bg-subtle)] px-2 py-1 text-[11px] text-[var(--text-secondary)]", className), children: [_jsx("span", { className: "lemma-assistant-pending-file-chip-label truncate max-w-[180px]", children: label }), onRemove ? (_jsx("button", { type: "button", onClick: onRemove, className: "lemma-assistant-pending-file-chip-remove inline-flex h-4 w-4 items-center justify-center rounded-full hover:bg-[var(--bg-canvas)]", title: "Remove file", children: "\u00D7" })) : null] }));
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { LemmaClient } from "../../client.js";
|
|
2
2
|
import { type AssistantConversationScope } from "../useAssistantController.js";
|
|
3
|
+
import { type AssistantThemeMode } from "./AssistantChrome.js";
|
|
3
4
|
import { type AssistantExperienceViewProps } from "./AssistantExperience.js";
|
|
4
5
|
export interface AssistantEmbeddedProps extends Omit<AssistantExperienceViewProps, "controller">, AssistantConversationScope {
|
|
5
6
|
client: LemmaClient;
|
|
6
7
|
enabled?: boolean;
|
|
8
|
+
theme?: AssistantThemeMode;
|
|
7
9
|
}
|
|
8
|
-
export declare function AssistantEmbedded({ client, podId, assistantId, organizationId, enabled, ...props }: AssistantEmbeddedProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export declare function AssistantEmbedded({ client, podId, assistantId, organizationId, enabled, theme, ...props }: AssistantEmbeddedProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useAssistantController } from "../useAssistantController.js";
|
|
3
3
|
import { AssistantThemeScope } from "./AssistantChrome.js";
|
|
4
4
|
import { AssistantExperienceView } from "./AssistantExperience.js";
|
|
5
|
-
export function AssistantEmbedded({ client, podId, assistantId, organizationId, enabled = true, ...props }) {
|
|
5
|
+
export function AssistantEmbedded({ client, podId, assistantId, organizationId, enabled = true, theme = "auto", ...props }) {
|
|
6
6
|
const controller = useAssistantController({
|
|
7
7
|
client,
|
|
8
8
|
podId: podId ?? undefined,
|
|
@@ -10,5 +10,5 @@ export function AssistantEmbedded({ client, podId, assistantId, organizationId,
|
|
|
10
10
|
organizationId: organizationId ?? undefined,
|
|
11
11
|
enabled,
|
|
12
12
|
});
|
|
13
|
-
return (_jsx(AssistantThemeScope, { children: _jsx(AssistantExperienceView, { controller: controller, ...props }) }));
|
|
13
|
+
return (_jsx(AssistantThemeScope, { className: "lemma-assistant-embedded", theme: theme, children: _jsx(AssistantExperienceView, { controller: controller, ...props }) }));
|
|
14
14
|
}
|
|
@@ -33,6 +33,8 @@ export interface ActiveToolBanner {
|
|
|
33
33
|
summary: string;
|
|
34
34
|
activeCount: number;
|
|
35
35
|
}
|
|
36
|
+
export type AssistantChromeStyle = "elevated" | "subtle" | "flat";
|
|
37
|
+
export type AssistantStatusPlacement = "inline" | "composer" | "none";
|
|
36
38
|
export interface AssistantExperienceViewProps {
|
|
37
39
|
controller: AssistantControllerView;
|
|
38
40
|
title?: ReactNode;
|
|
@@ -42,6 +44,8 @@ export interface AssistantExperienceViewProps {
|
|
|
42
44
|
draft?: string;
|
|
43
45
|
onDraftChange?: (value: string) => void;
|
|
44
46
|
showConversationList?: boolean;
|
|
47
|
+
chromeStyle?: AssistantChromeStyle;
|
|
48
|
+
statusPlacement?: AssistantStatusPlacement;
|
|
45
49
|
onNavigateResource?: (resourceType: string, resourceId: string, meta?: Record<string, unknown>) => void;
|
|
46
50
|
renderConversationLabel?: (args: AssistantConversationRenderArgs) => ReactNode;
|
|
47
51
|
renderMessageContent?: (args: AssistantMessageRenderArgs) => ReactNode;
|
|
@@ -75,5 +79,5 @@ export declare function MessageGroup({ message, conversationId, onNavigateResour
|
|
|
75
79
|
renderPresentedFile?: (args: AssistantPresentedFileRenderArgs) => ReactNode;
|
|
76
80
|
renderToolInvocation?: (args: AssistantToolRenderArgs) => ReactNode;
|
|
77
81
|
}): import("react/jsx-runtime").JSX.Element;
|
|
78
|
-
export declare function AssistantExperienceView({ controller, title, subtitle, placeholder, emptyState, draft: controlledDraft, onDraftChange, showConversationList, onNavigateResource, renderConversationLabel, renderMessageContent, renderPresentedFile, renderPendingFile, renderToolInvocation, }: AssistantExperienceViewProps): 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;
|
|
79
83
|
export {};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
|
|
3
|
+
import ReactMarkdown from "react-markdown";
|
|
4
|
+
import remarkGfm from "remark-gfm";
|
|
3
5
|
import { AvailableModels } from "../../types.js";
|
|
4
|
-
import { AssistantAskOverlay, AssistantMessageViewport, } from "./AssistantChrome.js";
|
|
6
|
+
import { AssistantAskOverlay, AssistantComposer, AssistantHeader, AssistantMessageViewport, AssistantModelPicker, AssistantStatusPill, } from "./AssistantChrome.js";
|
|
5
7
|
function cx(...values) {
|
|
6
8
|
return values.filter(Boolean).join(" ");
|
|
7
9
|
}
|
|
@@ -500,8 +502,11 @@ function useControllableDraft(controlledValue, onChange) {
|
|
|
500
502
|
function defaultConversationLabel({ conversation }) {
|
|
501
503
|
return conversation.title || "Untitled conversation";
|
|
502
504
|
}
|
|
505
|
+
const markdownComponents = {
|
|
506
|
+
a: ({ node: _node, ...props }) => (_jsx("a", { ...props, target: props.target || "_blank", rel: props.rel || "noreferrer noopener" })),
|
|
507
|
+
};
|
|
503
508
|
function defaultMessageContent({ message }) {
|
|
504
|
-
return _jsx("div", { className: "
|
|
509
|
+
return (_jsx("div", { className: "lemma-assistant-markdown", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], skipHtml: true, components: markdownComponents, children: message.content }) }));
|
|
505
510
|
}
|
|
506
511
|
function defaultPresentedFile({ filepath }) {
|
|
507
512
|
return (_jsxs("div", { className: "rounded-2xl border border-[color:color-mix(in_srgb,_var(--border-default)_78%,_transparent)] bg-[linear-gradient(180deg,color-mix(in_srgb,var(--bg-surface)_96%,transparent),color-mix(in_srgb,var(--bg-canvas)_76%,transparent))] px-3 py-2.5", children: [_jsx("div", { className: "text-[14px] font-medium text-[var(--text-primary)]", children: fileNameFromPath(filepath) }), _jsx("div", { className: "mt-1 text-[12px] text-[var(--text-tertiary)]", children: filepath })] }));
|
|
@@ -513,7 +518,7 @@ export function PlanSummaryStrip({ plan, onHide }) {
|
|
|
513
518
|
const [showAll, setShowAll] = useState(false);
|
|
514
519
|
const visibleSteps = showAll ? plan.steps : plan.steps.slice(0, 5);
|
|
515
520
|
const hiddenCount = Math.max(0, plan.steps.length - visibleSteps.length);
|
|
516
|
-
return (_jsxs("div", { className: "lemma-assistant-plan-strip rounded-xl border border-[color:color-mix(in_srgb,_var(--
|
|
521
|
+
return (_jsxs("div", { className: "lemma-assistant-plan-strip rounded-xl border border-[color:color-mix(in_srgb,_var(--border-default)_88%,_transparent)] bg-[var(--bg-surface)] px-3 py-2.5 shadow-[var(--shadow-sm)]", children: [_jsxs("div", { className: "lemma-assistant-plan-strip-header flex items-center justify-between gap-2", children: [_jsxs("div", { className: "lemma-assistant-plan-strip-summary inline-flex items-center gap-2", children: [_jsx("span", { className: "lemma-assistant-plan-strip-title text-[12px] font-semibold text-[var(--text-primary)]", children: "Task plan" }), _jsxs("span", { className: "lemma-assistant-plan-strip-count text-[11px] text-[var(--text-tertiary)]", children: [plan.completedCount, "/", plan.steps.length, " complete"] }), plan.inProgressCount > 0 ? (_jsxs("span", { className: "lemma-assistant-plan-strip-active rounded-full bg-[color:color-mix(in_srgb,_var(--brand-primary)_16%,_transparent)] px-1.5 py-0.5 text-[10px] font-medium text-[var(--brand-primary)]", children: [plan.inProgressCount, " active"] })) : null] }), _jsx("button", { type: "button", onClick: onHide, className: "text-[11px] font-medium text-[var(--text-tertiary)] hover:text-[var(--text-primary)] transition-colors", children: "Hide" })] }), plan.activeStep ? (_jsxs("div", { className: "mt-1.5 truncate text-[11px] text-[var(--text-secondary)]", title: plan.activeStep, children: [plan.running ? "Running:" : "Current:", " ", plan.activeStep] })) : null, _jsxs("div", { className: "lemma-assistant-plan-strip-steps mt-2 space-y-1", children: [visibleSteps.map((step, index) => (_jsxs("div", { className: "lemma-assistant-plan-strip-step flex items-start gap-2 text-[11px]", children: [_jsx("span", { className: cx("mt-1 inline-block h-2 w-2 shrink-0 rounded-full", step.status === "completed" && "bg-[var(--state-success)]", step.status === "in_progress" && "bg-[var(--brand-primary)]", step.status === "pending" && "bg-[var(--border-default)]") }), _jsx("span", { className: cx("leading-5", step.status === "completed" && "text-[var(--text-tertiary)] line-through", step.status === "in_progress" && "text-[var(--brand-primary)] font-medium", step.status === "pending" && "text-[var(--text-secondary)]"), children: step.step })] }, `${step.step}-${index}`))), plan.steps.length > 5 ? (_jsxs("div", { className: "flex items-center gap-2 pt-0.5", children: [_jsx("button", { type: "button", onClick: () => setShowAll((prev) => !prev), className: "text-[10px] font-medium text-[var(--brand-primary)] hover:text-[var(--text-primary)] transition-colors", children: showAll ? "Show less" : `See all ${plan.steps.length} steps` }), !showAll && hiddenCount > 0 ? (_jsxs("span", { className: "text-[10px] text-[var(--text-tertiary)]", children: ["+", hiddenCount, " more"] })) : null] })) : null] })] }));
|
|
517
522
|
}
|
|
518
523
|
export function ThinkingIndicator() {
|
|
519
524
|
const [show, setShow] = useState(false);
|
|
@@ -575,7 +580,7 @@ function ToolDetailsPanel({ toolName, args, state, result, onNavigateResource, r
|
|
|
575
580
|
activeConversationId,
|
|
576
581
|
}) }));
|
|
577
582
|
}
|
|
578
|
-
return (_jsxs("div", { className: "pl-4 border-l border-[var(--border-default)] space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("div", { className: "text-[
|
|
583
|
+
return (_jsxs("div", { className: "pl-4 border-l border-[var(--border-default)] space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("div", { className: "text-[10px] font-medium uppercase tracking-[0.04em] text-[var(--text-tertiary)]", children: formatToolDisplayName(toolName) }), canNavigate && onNavigateResource ? (_jsx("button", { type: "button", onClick: () => onNavigateResource(resultData.resourceType, resultData.resourceId, resultData), className: "inline-flex items-center gap-1 text-[10px] font-medium text-[var(--state-success)] hover:text-[var(--state-success)] transition-colors", children: "Open \u203A" })) : null] }), _jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-2", children: [_jsxs("div", { children: [_jsx("div", { className: "text-[10px] font-medium uppercase tracking-[0.1em] text-[var(--text-tertiary)] mb-1", children: "Input" }), _jsx("div", { className: "p-2 rounded bg-[color:color-mix(in_srgb,_var(--bg-canvas)_70%,_transparent)] font-mono text-[11px] max-h-24 overflow-auto", children: _jsx("pre", { className: "text-[var(--text-secondary)] whitespace-pre-wrap", children: JSON.stringify(args, null, 2) }) })] }), _jsxs("div", { children: [_jsx("div", { className: "text-[10px] font-medium uppercase tracking-[0.1em] text-[var(--text-tertiary)] mb-1", children: "Output" }), _jsx("div", { className: "p-2 rounded bg-[color:color-mix(in_srgb,_var(--bg-canvas)_70%,_transparent)] font-mono text-[11px] max-h-24 overflow-auto", children: _jsx("pre", { className: "text-[var(--text-secondary)] whitespace-pre-wrap", children: Object.keys(resultData).length > 0 ? JSON.stringify(resultData, null, 2) : "No output yet" }) })] })] })] }));
|
|
579
584
|
}
|
|
580
585
|
function InlineToolCall({ invocation, isSelected, onClick, }) {
|
|
581
586
|
const resultData = (invocation.result || {});
|
|
@@ -587,7 +592,7 @@ function InlineToolCall({ invocation, isSelected, onClick, }) {
|
|
|
587
592
|
: isFailed
|
|
588
593
|
? (typeof resultData.error === "string" ? resultData.error : "Tool failed")
|
|
589
594
|
: (formatToolResultSummary(invocation.toolName, invocation.args, resultData) || "Completed");
|
|
590
|
-
return (_jsxs("button", { type: "button", onClick: onClick, className: cx("w-full text-left inline-flex items-center gap-1.5 text-[
|
|
595
|
+
return (_jsxs("button", { type: "button", onClick: onClick, className: cx("w-full text-left inline-flex items-center gap-1.5 text-[11px] leading-5 transition-colors hover:text-[var(--text-primary)]", isExecuting && "text-[var(--state-info)]", isComplete && "text-[var(--state-success)]", isFailed && "text-[var(--state-error)]", !isExecuting && !isComplete && !isFailed && "text-[var(--text-secondary)]"), children: [_jsx("span", { className: "font-medium whitespace-nowrap", children: formatToolDisplayName(invocation.toolName) }), _jsx("span", { className: "text-current/80 truncate", children: summary }), _jsx("span", { className: "ml-auto transition-transform", children: isSelected ? "⌄" : "›" })] }));
|
|
591
596
|
}
|
|
592
597
|
function ToolActivityRollup({ detailParts, onNavigateResource, renderToolInvocation, message, activeConversationId, }) {
|
|
593
598
|
const [activeToolCallId, setActiveToolCallId] = useState(null);
|
|
@@ -603,7 +608,7 @@ function ToolActivityRollup({ detailParts, onNavigateResource, renderToolInvocat
|
|
|
603
608
|
const summary = activeInvocation
|
|
604
609
|
? formatActiveToolSummary(activeInvocation.toolName, activeInvocation.args)
|
|
605
610
|
: `Worked across ${toolParts.length} tool${toolParts.length === 1 ? "" : "s"}${failedCount > 0 ? ` · ${failedCount} failed` : ""}`;
|
|
606
|
-
return (_jsxs("div", { className: "lemma-assistant-tool-rollup space-y-1", children: [_jsxs("button", { type: "button", onClick: () => setIsExpanded((prev) => !prev), className: "lemma-assistant-tool-rollup-toggle inline-flex items-center gap-1.5 text-[
|
|
611
|
+
return (_jsxs("div", { className: "lemma-assistant-tool-rollup space-y-1", children: [_jsxs("button", { type: "button", onClick: () => setIsExpanded((prev) => !prev), className: "lemma-assistant-tool-rollup-toggle inline-flex items-center gap-1.5 text-[11px] leading-5 text-[var(--text-tertiary)] hover:text-[var(--text-secondary)] transition-colors", children: [_jsx("span", { className: cx("transition-transform", isExpanded && "rotate-90"), children: "\u203A" }), isWorking ? _jsx("span", { className: "inline-flex h-2 w-2 rounded-full bg-[var(--brand-accent)]" }) : null, _jsx("span", { className: cx("text-[var(--text-secondary)]", isWorking && "font-medium"), children: summary })] }), isExpanded ? (_jsx("div", { className: "lemma-assistant-tool-rollup-details pl-4 border-l border-[var(--border-default)] space-y-1.5", children: detailParts.map((part) => {
|
|
607
612
|
if (part.type === "reasoning") {
|
|
608
613
|
return (_jsxs("div", { className: "lemma-assistant-tool-rollup-thinking rounded-md bg-[var(--bg-canvas)] px-2.5 py-2", children: [_jsx("div", { className: "mb-1 text-[10px] font-medium uppercase tracking-[0.1em] text-[var(--text-tertiary)]", children: part.state === "streaming" ? "Thinking" : "Thought" }), _jsx("pre", { className: "text-[11px] leading-5 text-[var(--text-secondary)] whitespace-pre-wrap font-mono max-h-40 overflow-auto", children: part.text })] }, `thinking-${part.id}`));
|
|
609
614
|
}
|
|
@@ -755,7 +760,7 @@ export function MessageGroup({ message, conversationId, onNavigateResource, onWi
|
|
|
755
760
|
return null;
|
|
756
761
|
}), presentableFilepaths.length > 0 ? (_jsx(PresentFilesCard, { filepaths: presentableFilepaths, conversationId: conversationId, renderPresentedFile: renderPresentedFile })) : null] })] }));
|
|
757
762
|
}
|
|
758
|
-
export function AssistantExperienceView({ controller, title = "Lemma Assistant", subtitle = "Ask across your workspace and organization.", placeholder = "Message Lemma Assistant", emptyState, draft: controlledDraft, onDraftChange, showConversationList = false, onNavigateResource, renderConversationLabel = defaultConversationLabel, renderMessageContent = defaultMessageContent, renderPresentedFile, renderPendingFile = defaultPendingFile, renderToolInvocation, }) {
|
|
763
|
+
export function AssistantExperienceView({ controller, title = "Lemma Assistant", subtitle = "Ask across your workspace and organization.", placeholder = "Message Lemma Assistant", emptyState, draft: controlledDraft, onDraftChange, showConversationList = false, chromeStyle = "subtle", statusPlacement = "inline", onNavigateResource, renderConversationLabel = defaultConversationLabel, renderMessageContent = defaultMessageContent, renderPresentedFile, renderPendingFile = defaultPendingFile, renderToolInvocation, }) {
|
|
759
764
|
const [draft, setDraft] = useControllableDraft(controlledDraft, onDraftChange);
|
|
760
765
|
const [isPlanHidden, setIsPlanHidden] = useState(false);
|
|
761
766
|
const [dismissedAskToolCallIds, setDismissedAskToolCallIds] = useState([]);
|
|
@@ -764,6 +769,7 @@ export function AssistantExperienceView({ controller, title = "Lemma Assistant",
|
|
|
764
769
|
const messagesContainerRef = useRef(null);
|
|
765
770
|
const inputRef = useRef(null);
|
|
766
771
|
const fileInputRef = useRef(null);
|
|
772
|
+
const bottomAnchorRef = useRef(null);
|
|
767
773
|
const isPinnedToBottomRef = useRef(true);
|
|
768
774
|
const loadingOlderFromScrollRef = useRef(false);
|
|
769
775
|
const isConversationBusy = controller.isLoading || controller.isActiveConversationRunning;
|
|
@@ -780,6 +786,15 @@ export function AssistantExperienceView({ controller, title = "Lemma Assistant",
|
|
|
780
786
|
textarea.style.overflowY = textarea.scrollHeight > maxHeight ? "auto" : "hidden";
|
|
781
787
|
}, []);
|
|
782
788
|
const scrollToLatest = useCallback((behavior = "auto") => {
|
|
789
|
+
const anchor = bottomAnchorRef.current;
|
|
790
|
+
if (anchor) {
|
|
791
|
+
anchor.scrollIntoView({
|
|
792
|
+
block: "end",
|
|
793
|
+
behavior,
|
|
794
|
+
});
|
|
795
|
+
isPinnedToBottomRef.current = true;
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
783
798
|
const el = messagesContainerRef.current;
|
|
784
799
|
if (!el)
|
|
785
800
|
return;
|
|
@@ -825,10 +840,18 @@ export function AssistantExperienceView({ controller, title = "Lemma Assistant",
|
|
|
825
840
|
return;
|
|
826
841
|
if (isPinnedToBottomRef.current) {
|
|
827
842
|
requestAnimationFrame(() => {
|
|
828
|
-
|
|
843
|
+
requestAnimationFrame(() => {
|
|
844
|
+
scrollToLatest(isConversationBusy ? "auto" : "smooth");
|
|
845
|
+
});
|
|
829
846
|
});
|
|
830
847
|
}
|
|
831
848
|
}, [controller.messages, isConversationBusy, scrollToLatest]);
|
|
849
|
+
useEffect(() => {
|
|
850
|
+
isPinnedToBottomRef.current = true;
|
|
851
|
+
requestAnimationFrame(() => {
|
|
852
|
+
scrollToLatest("auto");
|
|
853
|
+
});
|
|
854
|
+
}, [controller.activeConversationId, scrollToLatest]);
|
|
832
855
|
useEffect(() => {
|
|
833
856
|
resizeComposer();
|
|
834
857
|
}, [draft, resizeComposer]);
|
|
@@ -959,7 +982,10 @@ export function AssistantExperienceView({ controller, title = "Lemma Assistant",
|
|
|
959
982
|
if (selectedFiles.length === 0)
|
|
960
983
|
return;
|
|
961
984
|
try {
|
|
962
|
-
await controller.uploadFiles(selectedFiles);
|
|
985
|
+
await controller.uploadFiles(selectedFiles, { deferUntilSend: true });
|
|
986
|
+
requestAnimationFrame(() => {
|
|
987
|
+
inputRef.current?.focus();
|
|
988
|
+
});
|
|
963
989
|
}
|
|
964
990
|
finally {
|
|
965
991
|
if (fileInputRef.current) {
|
|
@@ -993,29 +1019,34 @@ export function AssistantExperienceView({ controller, title = "Lemma Assistant",
|
|
|
993
1019
|
? effectiveAskOverlayState.answers[effectiveAskOverlayState.currentQuestionIndex] || []
|
|
994
1020
|
: [];
|
|
995
1021
|
const canContinueAsk = activeAskAnswers.length > 0;
|
|
996
|
-
|
|
1022
|
+
const liveStatusLabel = activeToolBanner?.summary || "Thinking through this...";
|
|
1023
|
+
const headerTone = chromeStyle === "elevated" ? "default" : chromeStyle === "flat" ? "flat" : "subtle";
|
|
1024
|
+
const composerTone = chromeStyle === "flat" ? "flat" : chromeStyle === "subtle" ? "subtle" : "default";
|
|
1025
|
+
const showInlineStatus = statusPlacement === "inline" && isConversationBusy;
|
|
1026
|
+
const showComposerStatus = statusPlacement === "composer" && isConversationBusy;
|
|
1027
|
+
return (_jsxs("div", { className: cx("lemma-assistant-experience", "flex h-full min-h-0 flex-col gap-3 font-sans antialiased", showConversationList && "lg:grid lg:grid-cols-[280px_minmax(0,1fr)] lg:gap-3"), "data-chrome-style": chromeStyle, "data-status-placement": statusPlacement, "data-busy": isConversationBusy ? "true" : "false", "data-has-plan": planSummary ? "true" : "false", "data-has-pending-files": controller.pendingFiles.length > 0 ? "true" : "false", "data-show-conversation-list": showConversationList ? "true" : "false", children: [showConversationList ? (_jsxs("aside", { className: "lemma-assistant-experience-sidebar hidden min-h-0 overflow-hidden rounded-2xl border border-[color:color-mix(in_srgb,_var(--border-default)_80%,_transparent)] bg-[var(--bg-surface)] shadow-[var(--shadow-lg)] lg:flex lg:flex-col", children: [_jsx("div", { className: "lemma-assistant-experience-sidebar-header border-b border-[color:color-mix(in_srgb,_var(--border-default)_80%,_transparent)] px-4 py-3", children: _jsxs("div", { className: "lemma-assistant-experience-sidebar-header-row flex items-center justify-between gap-3", children: [_jsxs("div", { className: "lemma-assistant-experience-sidebar-copy", children: [_jsx("div", { className: "lemma-assistant-experience-sidebar-title text-[13px] font-semibold text-[var(--text-primary)]", children: "Conversations" }), _jsxs("div", { className: "lemma-assistant-experience-sidebar-meta mt-1 text-[11px] text-[var(--text-tertiary)]", children: [controller.conversations.length, " total"] })] }), _jsx("button", { type: "button", onClick: controller.clearMessages, className: "lemma-assistant-experience-sidebar-new rounded-full border border-[var(--border-default)] bg-[var(--bg-surface)] px-3 py-1.5 text-[11px] font-medium text-[var(--text-secondary)] hover:text-[var(--text-primary)]", children: "New" })] }) }), _jsx("div", { className: "lemma-assistant-experience-sidebar-items min-h-0 flex-1 overflow-y-auto p-3 space-y-2", children: controller.conversations.map((conversation) => {
|
|
997
1028
|
const isActive = conversation.id === controller.activeConversationId;
|
|
998
1029
|
return (_jsxs("button", { type: "button", onClick: () => controller.selectConversation(conversation.id), className: cx("lemma-assistant-experience-sidebar-item", "w-full rounded-xl border px-3 py-2.5 text-left transition-colors", isActive
|
|
999
1030
|
? "lemma-assistant-experience-sidebar-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))]"
|
|
1000
1031
|
: "border-[var(--border-default)] bg-[var(--bg-surface)] hover:bg-[var(--bg-subtle)]"), children: [_jsx("div", { className: "lemma-assistant-experience-sidebar-item-title text-[12px] font-medium text-[var(--text-primary)]", children: renderConversationLabel({ conversation, isActive }) }), _jsx("div", { className: "lemma-assistant-experience-sidebar-item-status mt-1 text-[10px] uppercase tracking-[0.08em] text-[var(--text-tertiary)]", children: (conversation.status || "waiting").toLowerCase() })] }, conversation.id));
|
|
1001
|
-
}) })] })) : null, _jsxs("div", { className: "lemma-assistant-experience-main flex h-full min-h-0 flex-col gap-3", children: [_jsxs("div", { className: "lemma-assistant-experience-card flex min-h-0 flex-1 flex-col overflow-hidden rounded-2xl border border-[color:color-mix(in_srgb,_var(--border-default)_80%,_transparent)] bg-[var(--bg-surface)] shadow-[var(--shadow-lg)]", children: [
|
|
1032
|
+
}) })] })) : null, _jsxs("div", { className: "lemma-assistant-experience-main flex h-full min-h-0 flex-col gap-3", children: [_jsxs("div", { className: "lemma-assistant-experience-card flex min-h-0 flex-1 flex-col overflow-hidden rounded-2xl border border-[color:color-mix(in_srgb,_var(--border-default)_80%,_transparent)] bg-[var(--bg-surface)] shadow-[var(--shadow-lg)]", children: [_jsx(AssistantHeader, { className: "lemma-assistant-experience-header", tone: headerTone, title: title, subtitle: subtitle, badge: _jsx("span", { className: "text-[var(--text-on-brand)] text-xs", children: "\u2728" }), controls: (_jsxs(_Fragment, { children: [_jsx(AssistantModelPicker, { value: controller.conversationModel, options: availableModels, onChange: (nextModel) => { void handleModelChange(nextModel); }, disabled: isConversationBusy || isUpdatingModel, autoLabel: "Auto", className: "lemma-assistant-experience-model-picker" }), _jsx("button", { type: "button", onClick: controller.clearMessages, title: "New conversation", className: "lemma-assistant-experience-new inline-flex h-8 w-8 items-center justify-center rounded-full text-[var(--text-tertiary)] hover:bg-[var(--bg-subtle)] hover:text-[var(--text-secondary)]", children: "\u21BA" })] })) }), _jsxs(AssistantMessageViewport, { className: "lemma-assistant-experience-viewport min-h-[180px]", ref: messagesContainerRef, onScroll: updatePinnedState, children: [controller.messages.length === 0 && !isConversationBusy ? (emptyState || _jsx(EmptyState, { onSendMessage: (message) => { void controller.sendMessage(message); } })) : null, (controller.isLoadingMessages && controller.messages.length === 0) ? (_jsx("div", { className: "lemma-assistant-experience-loading flex justify-center py-6", children: _jsx("span", { className: "lemma-assistant-experience-loading-text text-[var(--text-tertiary)] text-sm", children: "Loading\u2026" }) })) : null, (controller.isLoadingOlderMessages && controller.messages.length > 0) ? (_jsx("div", { className: "lemma-assistant-experience-loading-older flex justify-center py-1", children: _jsx("span", { className: "lemma-assistant-experience-loading-older-text text-[var(--text-tertiary)] text-xs", children: "Loading older\u2026" }) })) : null, displayMessageRows.map((row, index) => {
|
|
1002
1033
|
const previousRow = index > 0 ? displayMessageRows[index - 1] : null;
|
|
1003
1034
|
const showAssistantHeader = row.message.role !== "assistant"
|
|
1004
1035
|
? false
|
|
1005
1036
|
: previousRow?.message.role !== "assistant";
|
|
1006
1037
|
const includesLastRawMessage = row.sourceIndexes.includes(controller.messages.length - 1);
|
|
1007
1038
|
return (_jsx(MessageGroup, { message: row.message, onNavigateResource: onNavigateResource, onWidgetSendPrompt: handleWidgetSendPrompt, conversationId: controller.activeConversationId, isStreaming: isConversationBusy && includesLastRawMessage && row.message.role === "assistant", showAssistantHeader: showAssistantHeader, renderMessageContent: renderMessageContent, renderPresentedFile: renderPresentedFile, renderToolInvocation: renderToolInvocation }, row.id || index));
|
|
1008
|
-
}), controller.error ? (_jsx("div", { className: "lemma-assistant-experience-error bg-[color:color-mix(in_srgb,_var(--state-error)_12%,_transparent)] border border-[color:color-mix(in_srgb,_var(--state-error)_48%,_var(--border-subtle))] rounded-lg p-3 text-xs text-[var(--state-error)] flex items-start gap-2.5", children: _jsxs("div", { children: [_jsx("p", { className: "font-medium", children: "Something went wrong" }), _jsx("p", { className: "text-[var(--state-error)] mt-1", children: controller.error })] }) })) : null, (controller.messages.length > 0 || isConversationBusy || !!controller.error) ? (_jsx("div", { "aria-hidden": "true", className: "h-14 shrink-0" })) : null
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1039
|
+
}), showInlineStatus ? (_jsx("div", { className: "lemma-assistant-experience-inline-status flex min-h-[38px] items-center px-1", children: _jsx("div", { className: cx("transition-all duration-200", lastMessageHasContent ? "opacity-80" : "opacity-100"), children: _jsx(AssistantStatusPill, { label: liveStatusLabel, subtle: lastMessageHasContent }) }) })) : null, controller.error ? (_jsx("div", { className: "lemma-assistant-experience-error bg-[color:color-mix(in_srgb,_var(--state-error)_12%,_transparent)] border border-[color:color-mix(in_srgb,_var(--state-error)_48%,_var(--border-subtle))] rounded-lg p-3 text-xs text-[var(--state-error)] flex items-start gap-2.5", children: _jsxs("div", { children: [_jsx("p", { className: "font-medium", children: "Something went wrong" }), _jsx("p", { className: "text-[var(--state-error)] mt-1", children: controller.error })] }) })) : null, (controller.messages.length > 0 || isConversationBusy || !!controller.error) ? (_jsx("div", { "aria-hidden": "true", className: "h-14 shrink-0" })) : null, _jsx("div", { ref: bottomAnchorRef, "aria-hidden": "true", className: "lemma-assistant-experience-bottom-anchor h-px" })] })] }), _jsx(AssistantComposer, { className: "lemma-assistant-experience-composer", tone: composerTone, floating: planSummary ? (isPlanHidden ? (_jsxs("button", { type: "button", onClick: () => setIsPlanHidden(false), className: "inline-flex items-center gap-2 rounded-full border border-[color:color-mix(in_srgb,_var(--border-default)_88%,_transparent)] bg-[var(--bg-surface)] px-3 py-1.5 text-[11px] font-medium text-[var(--text-secondary)] shadow-[var(--shadow-xs)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-subtle)] transition-colors", children: ["Show plan (", planSummary.completedCount, "/", planSummary.steps.length, ")"] })) : (_jsx(PlanSummaryStrip, { plan: planSummary, onHide: () => setIsPlanHidden(true) }))) : undefined, status: showComposerStatus ? (_jsx(AssistantStatusPill, { label: liveStatusLabel, subtle: true })) : undefined, pendingFiles: controller.pendingFiles.length > 0 ? (_jsx(_Fragment, { children: controller.pendingFiles.map((file) => {
|
|
1040
|
+
const fileKey = `${file.name}:${file.size}:${file.lastModified}`;
|
|
1041
|
+
return (_jsx("div", { children: renderPendingFile({
|
|
1042
|
+
file,
|
|
1043
|
+
remove: () => controller.removePendingFile(fileKey),
|
|
1044
|
+
}) }, fileKey));
|
|
1045
|
+
}) })) : undefined, children: activeAskQuestion && effectiveAskOverlayState && pendingAskUserInput ? (_jsx(AssistantAskOverlay, { questionNumber: effectiveAskOverlayState.currentQuestionIndex + 1, totalQuestions: pendingAskUserInput.questions.length, question: activeAskQuestion.question, options: activeAskQuestion.options, selectedOptions: activeAskAnswers, canContinue: canContinueAsk, continueLabel: effectiveAskOverlayState.currentQuestionIndex >= pendingAskUserInput.questions.length - 1 ? "Use answers" : "Continue", onSelectOption: updateAskAnswer, onContinue: activeAskQuestion.type !== "single_select" || pendingAskUserInput.questions.length > 1 ? continueAskQuestions : undefined, onSkip: () => dismissAskOverlay(effectiveAskOverlayState.toolCallId), mode: activeAskQuestion.type })) : (_jsx("div", { className: "lemma-assistant-experience-composer-body space-y-1.5", children: _jsxs("div", { className: "lemma-assistant-experience-input-row relative flex items-end gap-2", children: [_jsx("input", { ref: fileInputRef, type: "file", multiple: true, className: "lemma-assistant-experience-file-input hidden", onChange: (event) => { void handleUploadSelection(event.target.files); } }), _jsx("button", { type: "button", onClick: () => fileInputRef.current?.click(), disabled: isConversationBusy || controller.isUploadingFiles, className: cx("lemma-assistant-experience-upload", "mb-1.5 ml-1 h-9 w-9 rounded-full flex items-center justify-center transition-colors", isConversationBusy || controller.isUploadingFiles
|
|
1046
|
+
? "bg-[var(--bg-subtle)] text-[var(--text-tertiary)]"
|
|
1047
|
+
: "bg-[var(--bg-subtle)] text-[var(--text-secondary)] hover:bg-[var(--bg-canvas)] hover:text-[var(--text-primary)]"), title: "Upload files", children: controller.isUploadingFiles ? "…" : "+" }), _jsx("textarea", { ref: inputRef, value: draft, onChange: (event) => setDraft(event.target.value), onKeyDown: handleKeyDown, placeholder: placeholder, className: "lemma-assistant-experience-textarea flex-1 resize-none border-0 bg-transparent px-3 py-2.5 text-[14px] text-[var(--text-primary)] leading-6 focus:ring-0 focus:outline-none placeholder:text-[var(--text-tertiary)] min-h-[48px] max-h-[220px]", rows: 1, disabled: isConversationBusy }), _jsx("div", { className: "lemma-assistant-experience-send-wrap pb-1.5 pr-1.5", children: _jsx("button", { onClick: isConversationBusy ? controller.stop : () => { void handleSubmit(); }, disabled: !isConversationBusy && !draft.trim(), className: cx("lemma-assistant-experience-send", "h-9 w-9 rounded-full flex items-center justify-center transition-all duration-200", isConversationBusy
|
|
1048
|
+
? "bg-[var(--text-primary)] text-[var(--text-inverse)] hover:bg-[color:color-mix(in_srgb,_var(--text-primary)_80%,_transparent)] hover:scale-105"
|
|
1049
|
+
: draft.trim()
|
|
1050
|
+
? "bg-[var(--brand-primary)] text-[var(--text-on-brand)] shadow-[var(--shadow-xs)] hover:bg-[color:color-mix(in_srgb,_var(--brand-primary)_88%,_var(--text-primary))]"
|
|
1051
|
+
: "bg-[var(--bg-subtle)] text-[var(--text-tertiary)]"), title: isConversationBusy ? "Stop generating" : "Send message", children: isConversationBusy ? "■" : "→" }) })] }) })) })] })] }));
|
|
1021
1052
|
}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -14,9 +14,9 @@ export { useAssistantController } from "./useAssistantController.js";
|
|
|
14
14
|
export type { AssistantAction, AssistantConversationScope, AssistantMessagePart, AssistantRenderableMessage, AssistantToolInvocation, UseAssistantControllerOptions, UseAssistantControllerResult, } from "./useAssistantController.js";
|
|
15
15
|
export type { AssistantConversationRenderArgs, AssistantControllerView, AssistantExperienceCustomizationProps, AssistantMessageRenderArgs, AssistantPendingFileRenderArgs, AssistantPresentedFileRenderArgs, AssistantToolRenderArgs, } from "./components/assistant-types.js";
|
|
16
16
|
export { AssistantAskOverlay, AssistantComposer, AssistantConversationList, AssistantHeader, AssistantMessageViewport, AssistantModelPicker, AssistantPendingFileChip, AssistantShellLayout, AssistantStatusPill, AssistantThemeScope, } from "./components/AssistantChrome.js";
|
|
17
|
-
export type { AssistantAskOverlayProps, AssistantComposerProps, AssistantConversationListProps, AssistantHeaderProps, AssistantMessageViewportProps, AssistantModelPickerProps, AssistantPendingFileChipProps, AssistantShellLayoutProps, AssistantStatusPillProps, AssistantThemeScopeProps, } from "./components/AssistantChrome.js";
|
|
17
|
+
export type { AssistantAskOverlayProps, AssistantComposerProps, AssistantConversationListProps, AssistantHeaderProps, AssistantMessageViewportProps, AssistantModelPickerProps, AssistantPendingFileChipProps, AssistantShellLayoutProps, AssistantStatusPillProps, AssistantSurfaceTone, AssistantThemeMode, AssistantThemeScopeProps, } from "./components/AssistantChrome.js";
|
|
18
18
|
export { AssistantExperienceView } from "./components/AssistantExperience.js";
|
|
19
|
-
export type { ActiveToolBanner, AskUserInputQuestion, AssistantExperienceViewProps, DisplayMessageRow, PendingAskUserInput, PlanStepState, PlanSummaryState, } from "./components/AssistantExperience.js";
|
|
19
|
+
export type { ActiveToolBanner, AskUserInputQuestion, AssistantChromeStyle, AssistantExperienceViewProps, AssistantStatusPlacement, DisplayMessageRow, PendingAskUserInput, PlanStepState, PlanSummaryState, } from "./components/AssistantExperience.js";
|
|
20
20
|
export { AssistantEmbedded } from "./components/AssistantEmbedded.js";
|
|
21
21
|
export type { AssistantEmbeddedProps } from "./components/AssistantEmbedded.js";
|
|
22
22
|
export { buildDisplayMessageRows, dedupToolInvocations, EmptyState, findPendingAskUserInput, formatAskUserInputAnswers, getActiveToolBanner, extractPresentFilePathsFromInvocation, latestPlanSummary, MessageGroup, PlanSummaryStrip, ThinkingIndicator, } from "./components/AssistantExperience.js";
|
package/dist/react/styles.css
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
.lemma-assistant-theme {
|
|
2
|
+
color-scheme: light;
|
|
2
3
|
--bg-canvas: #f6f2ea;
|
|
3
4
|
--bg-surface: #fffdf9;
|
|
4
5
|
--bg-subtle: #f1ebde;
|
|
@@ -53,6 +54,294 @@
|
|
|
53
54
|
color: var(--text-tertiary);
|
|
54
55
|
}
|
|
55
56
|
|
|
57
|
+
@media (prefers-color-scheme: dark) {
|
|
58
|
+
.lemma-assistant-theme:not([data-lemma-theme="light"]):not([data-lemma-theme="dark"]),
|
|
59
|
+
.lemma-assistant-theme[data-lemma-theme="auto"] {
|
|
60
|
+
color-scheme: dark;
|
|
61
|
+
--bg-canvas: #12100d;
|
|
62
|
+
--bg-surface: #1b1814;
|
|
63
|
+
--bg-subtle: #272118;
|
|
64
|
+
--border-default: #3d3428;
|
|
65
|
+
--border-subtle: #2d261d;
|
|
66
|
+
--text-primary: #f5ede0;
|
|
67
|
+
--text-secondary: #d0c3b1;
|
|
68
|
+
--text-tertiary: #988d7d;
|
|
69
|
+
--text-inverse: #15120f;
|
|
70
|
+
--text-on-brand: #15120f;
|
|
71
|
+
--brand-primary: #ead9b3;
|
|
72
|
+
--brand-secondary: #8daa73;
|
|
73
|
+
--brand-accent: #d9a44b;
|
|
74
|
+
--brand-glow: #2d2418;
|
|
75
|
+
--state-success: #7cbc72;
|
|
76
|
+
--state-error: #ec8d74;
|
|
77
|
+
--state-info: #7eb8f5;
|
|
78
|
+
--state-warning: #e0b45d;
|
|
79
|
+
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.32);
|
|
80
|
+
--shadow-sm: 0 10px 26px rgba(0, 0, 0, 0.32);
|
|
81
|
+
--shadow-md: 0 20px 40px rgba(0, 0, 0, 0.4);
|
|
82
|
+
--shadow-lg: 0 28px 56px rgba(0, 0, 0, 0.5);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
:where(.light, [data-theme="light"], [data-color-scheme="light"], [data-mode="light"]) .lemma-assistant-theme:not([data-lemma-theme="dark"]),
|
|
87
|
+
.lemma-assistant-theme[data-lemma-theme="light"] {
|
|
88
|
+
color-scheme: light;
|
|
89
|
+
--bg-canvas: #f6f2ea;
|
|
90
|
+
--bg-surface: #fffdf9;
|
|
91
|
+
--bg-subtle: #f1ebde;
|
|
92
|
+
--border-default: #ddd2bb;
|
|
93
|
+
--border-subtle: #ebe2d0;
|
|
94
|
+
--text-primary: #241f16;
|
|
95
|
+
--text-secondary: #5c5344;
|
|
96
|
+
--text-tertiary: #8a7f6f;
|
|
97
|
+
--text-inverse: #fffdf9;
|
|
98
|
+
--text-on-brand: #fffdf9;
|
|
99
|
+
--brand-primary: #202418;
|
|
100
|
+
--brand-secondary: #6e8c56;
|
|
101
|
+
--brand-accent: #c78a2c;
|
|
102
|
+
--brand-glow: #efe3c7;
|
|
103
|
+
--state-success: #3e7a3c;
|
|
104
|
+
--state-error: #b44d36;
|
|
105
|
+
--state-info: #2f6fb2;
|
|
106
|
+
--state-warning: #c78a2c;
|
|
107
|
+
--shadow-xs: 0 1px 2px rgba(36, 31, 22, 0.08);
|
|
108
|
+
--shadow-sm: 0 8px 24px rgba(36, 31, 22, 0.08);
|
|
109
|
+
--shadow-md: 0 18px 36px rgba(36, 31, 22, 0.1);
|
|
110
|
+
--shadow-lg: 0 24px 48px rgba(36, 31, 22, 0.14);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
:where(.dark, [data-theme="dark"], [data-color-scheme="dark"], [data-mode="dark"]) .lemma-assistant-theme:not([data-lemma-theme="light"]),
|
|
114
|
+
.lemma-assistant-theme[data-lemma-theme="dark"] {
|
|
115
|
+
color-scheme: dark;
|
|
116
|
+
--bg-canvas: #12100d;
|
|
117
|
+
--bg-surface: #1b1814;
|
|
118
|
+
--bg-subtle: #272118;
|
|
119
|
+
--border-default: #3d3428;
|
|
120
|
+
--border-subtle: #2d261d;
|
|
121
|
+
--text-primary: #f5ede0;
|
|
122
|
+
--text-secondary: #d0c3b1;
|
|
123
|
+
--text-tertiary: #988d7d;
|
|
124
|
+
--text-inverse: #15120f;
|
|
125
|
+
--text-on-brand: #15120f;
|
|
126
|
+
--brand-primary: #ead9b3;
|
|
127
|
+
--brand-secondary: #8daa73;
|
|
128
|
+
--brand-accent: #d9a44b;
|
|
129
|
+
--brand-glow: #2d2418;
|
|
130
|
+
--state-success: #7cbc72;
|
|
131
|
+
--state-error: #ec8d74;
|
|
132
|
+
--state-info: #7eb8f5;
|
|
133
|
+
--state-warning: #e0b45d;
|
|
134
|
+
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.32);
|
|
135
|
+
--shadow-sm: 0 10px 26px rgba(0, 0, 0, 0.32);
|
|
136
|
+
--shadow-md: 0 20px 40px rgba(0, 0, 0, 0.4);
|
|
137
|
+
--shadow-lg: 0 28px 56px rgba(0, 0, 0, 0.5);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.lemma-assistant-embedded {
|
|
141
|
+
display: flex;
|
|
142
|
+
flex-direction: column;
|
|
143
|
+
min-height: 0;
|
|
144
|
+
height: 100%;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.lemma-assistant-markdown {
|
|
148
|
+
color: inherit;
|
|
149
|
+
line-height: 1.7;
|
|
150
|
+
word-break: break-word;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.lemma-assistant-markdown > :first-child {
|
|
154
|
+
margin-top: 0;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.lemma-assistant-markdown > :last-child {
|
|
158
|
+
margin-bottom: 0;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.lemma-assistant-markdown p,
|
|
162
|
+
.lemma-assistant-markdown ul,
|
|
163
|
+
.lemma-assistant-markdown ol,
|
|
164
|
+
.lemma-assistant-markdown pre,
|
|
165
|
+
.lemma-assistant-markdown blockquote,
|
|
166
|
+
.lemma-assistant-markdown table,
|
|
167
|
+
.lemma-assistant-markdown hr {
|
|
168
|
+
margin: 0 0 0.95em;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.lemma-assistant-markdown h1,
|
|
172
|
+
.lemma-assistant-markdown h2,
|
|
173
|
+
.lemma-assistant-markdown h3,
|
|
174
|
+
.lemma-assistant-markdown h4 {
|
|
175
|
+
margin: 1.15em 0 0.55em;
|
|
176
|
+
line-height: 1.25;
|
|
177
|
+
color: var(--text-primary);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.lemma-assistant-markdown h1 {
|
|
181
|
+
font-size: 1.4rem;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.lemma-assistant-markdown h2 {
|
|
185
|
+
font-size: 1.2rem;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.lemma-assistant-markdown h3 {
|
|
189
|
+
font-size: 1.05rem;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.lemma-assistant-markdown h4 {
|
|
193
|
+
font-size: 0.95rem;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.lemma-assistant-markdown ul,
|
|
197
|
+
.lemma-assistant-markdown ol {
|
|
198
|
+
padding-left: 1.35rem;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.lemma-assistant-markdown ul {
|
|
202
|
+
list-style: disc;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.lemma-assistant-markdown ol {
|
|
206
|
+
list-style: decimal;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.lemma-assistant-markdown li + li {
|
|
210
|
+
margin-top: 0.3rem;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.lemma-assistant-markdown li > ul,
|
|
214
|
+
.lemma-assistant-markdown li > ol {
|
|
215
|
+
margin-top: 0.35rem;
|
|
216
|
+
margin-bottom: 0;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.lemma-assistant-markdown a {
|
|
220
|
+
color: var(--state-info);
|
|
221
|
+
text-decoration: underline;
|
|
222
|
+
text-decoration-color: color-mix(in srgb, var(--state-info) 56%, transparent);
|
|
223
|
+
text-underline-offset: 0.16em;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.lemma-assistant-markdown a:hover {
|
|
227
|
+
color: color-mix(in srgb, var(--state-info) 82%, var(--text-primary));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.lemma-assistant-markdown strong {
|
|
231
|
+
color: var(--text-primary);
|
|
232
|
+
font-weight: 650;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.lemma-assistant-markdown em {
|
|
236
|
+
color: var(--text-secondary);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.lemma-assistant-markdown hr {
|
|
240
|
+
border: 0;
|
|
241
|
+
border-top: 1px solid color-mix(in srgb, var(--border-default) 88%, transparent);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.lemma-assistant-markdown blockquote {
|
|
245
|
+
padding: 0.15rem 0 0.15rem 0.9rem;
|
|
246
|
+
border-left: 3px solid color-mix(in srgb, var(--brand-accent) 60%, var(--border-default));
|
|
247
|
+
color: var(--text-secondary);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.lemma-assistant-markdown :not(pre) > code {
|
|
251
|
+
display: inline-block;
|
|
252
|
+
margin: 0 0.08rem;
|
|
253
|
+
padding: 0.1rem 0.42rem;
|
|
254
|
+
border: 1px solid color-mix(in srgb, var(--border-default) 82%, transparent);
|
|
255
|
+
border-radius: 999px;
|
|
256
|
+
background: color-mix(in srgb, var(--bg-subtle) 88%, transparent);
|
|
257
|
+
color: var(--text-primary);
|
|
258
|
+
font-size: 0.92em;
|
|
259
|
+
line-height: 1.45;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.lemma-assistant-markdown pre {
|
|
263
|
+
overflow-x: auto;
|
|
264
|
+
padding: 0.9rem 1rem;
|
|
265
|
+
border: 1px solid color-mix(in srgb, var(--border-default) 82%, transparent);
|
|
266
|
+
border-radius: 16px;
|
|
267
|
+
background: color-mix(in srgb, var(--bg-canvas) 74%, var(--bg-surface));
|
|
268
|
+
box-shadow: inset 0 1px 0 color-mix(in srgb, var(--bg-surface) 60%, transparent);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.lemma-assistant-markdown pre code {
|
|
272
|
+
padding: 0;
|
|
273
|
+
border: 0;
|
|
274
|
+
background: transparent;
|
|
275
|
+
color: inherit;
|
|
276
|
+
font-size: 0.92em;
|
|
277
|
+
line-height: 1.65;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.lemma-assistant-markdown table {
|
|
281
|
+
display: block;
|
|
282
|
+
width: 100%;
|
|
283
|
+
overflow-x: auto;
|
|
284
|
+
border-collapse: separate;
|
|
285
|
+
border-spacing: 0;
|
|
286
|
+
border: 1px solid color-mix(in srgb, var(--border-default) 82%, transparent);
|
|
287
|
+
border-radius: 16px;
|
|
288
|
+
background: color-mix(in srgb, var(--bg-surface) 96%, transparent);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.lemma-assistant-markdown thead {
|
|
292
|
+
background: color-mix(in srgb, var(--bg-subtle) 76%, transparent);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.lemma-assistant-markdown th,
|
|
296
|
+
.lemma-assistant-markdown td {
|
|
297
|
+
padding: 0.7rem 0.85rem;
|
|
298
|
+
border-bottom: 1px solid color-mix(in srgb, var(--border-default) 72%, transparent);
|
|
299
|
+
text-align: left;
|
|
300
|
+
vertical-align: top;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.lemma-assistant-markdown tr:last-child td {
|
|
304
|
+
border-bottom: 0;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.lemma-assistant-markdown img {
|
|
308
|
+
max-width: 100%;
|
|
309
|
+
border-radius: 14px;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.lemma-assistant-message-user-bubble .lemma-assistant-markdown,
|
|
313
|
+
.lemma-assistant-message-user-bubble .lemma-assistant-markdown h1,
|
|
314
|
+
.lemma-assistant-message-user-bubble .lemma-assistant-markdown h2,
|
|
315
|
+
.lemma-assistant-message-user-bubble .lemma-assistant-markdown h3,
|
|
316
|
+
.lemma-assistant-message-user-bubble .lemma-assistant-markdown h4,
|
|
317
|
+
.lemma-assistant-message-user-bubble .lemma-assistant-markdown strong,
|
|
318
|
+
.lemma-assistant-message-user-bubble .lemma-assistant-markdown em,
|
|
319
|
+
.lemma-assistant-message-user-bubble .lemma-assistant-markdown a,
|
|
320
|
+
.lemma-assistant-message-user-bubble .lemma-assistant-markdown code,
|
|
321
|
+
.lemma-assistant-message-user-bubble .lemma-assistant-markdown pre code {
|
|
322
|
+
color: inherit;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.lemma-assistant-message-user-bubble .lemma-assistant-markdown a {
|
|
326
|
+
text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.lemma-assistant-message-user-bubble .lemma-assistant-markdown blockquote {
|
|
330
|
+
border-left-color: color-mix(in srgb, currentColor 34%, transparent);
|
|
331
|
+
color: inherit;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.lemma-assistant-message-user-bubble .lemma-assistant-markdown :not(pre) > code {
|
|
335
|
+
border-color: color-mix(in srgb, currentColor 18%, transparent);
|
|
336
|
+
background: color-mix(in srgb, currentColor 10%, transparent);
|
|
337
|
+
color: inherit;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.lemma-assistant-message-user-bubble .lemma-assistant-markdown pre {
|
|
341
|
+
border-color: color-mix(in srgb, currentColor 18%, transparent);
|
|
342
|
+
background: color-mix(in srgb, currentColor 8%, transparent);
|
|
343
|
+
}
|
|
344
|
+
|
|
56
345
|
.lemma-assistant-shell,
|
|
57
346
|
.lemma-assistant-experience,
|
|
58
347
|
.lemma-assistant-shell-sidebar,
|
|
@@ -95,6 +384,24 @@
|
|
|
95
384
|
align-items: center;
|
|
96
385
|
justify-content: space-between;
|
|
97
386
|
gap: 12px;
|
|
387
|
+
background: transparent;
|
|
388
|
+
border-bottom: 0;
|
|
389
|
+
box-shadow: none;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
.lemma-assistant-header[data-tone="default"],
|
|
394
|
+
.lemma-assistant-experience-header[data-tone="default"] {
|
|
395
|
+
background: var(--bg-surface);
|
|
396
|
+
border-bottom: 1px solid var(--border-default);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
.lemma-assistant-header[data-tone="flat"],
|
|
400
|
+
.lemma-assistant-experience-header[data-tone="flat"] {
|
|
401
|
+
background: transparent;
|
|
402
|
+
border-bottom: 0;
|
|
403
|
+
box-shadow: none;
|
|
404
|
+
padding-bottom: 0;
|
|
98
405
|
}
|
|
99
406
|
|
|
100
407
|
.lemma-assistant-header-copy,
|
|
@@ -177,6 +484,8 @@
|
|
|
177
484
|
.lemma-assistant-experience-model-picker {
|
|
178
485
|
appearance: none;
|
|
179
486
|
min-width: 132px;
|
|
487
|
+
border-color: transparent;
|
|
488
|
+
background: color-mix(in srgb, var(--bg-surface) 88%, transparent);
|
|
180
489
|
}
|
|
181
490
|
|
|
182
491
|
.lemma-assistant-viewport,
|
|
@@ -198,6 +507,22 @@
|
|
|
198
507
|
box-shadow: var(--shadow-md);
|
|
199
508
|
}
|
|
200
509
|
|
|
510
|
+
|
|
511
|
+
.lemma-assistant-composer[data-tone="subtle"],
|
|
512
|
+
.lemma-assistant-experience-composer[data-tone="subtle"] {
|
|
513
|
+
background: color-mix(in srgb, var(--bg-surface) 96%, transparent);
|
|
514
|
+
border-color: color-mix(in srgb, var(--border-default) 88%, transparent);
|
|
515
|
+
box-shadow: var(--shadow-sm);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
.lemma-assistant-composer[data-tone="flat"],
|
|
519
|
+
.lemma-assistant-experience-composer[data-tone="flat"] {
|
|
520
|
+
background: transparent;
|
|
521
|
+
border-color: transparent;
|
|
522
|
+
box-shadow: none;
|
|
523
|
+
padding: 0;
|
|
524
|
+
}
|
|
525
|
+
|
|
201
526
|
.lemma-assistant-composer-floating,
|
|
202
527
|
.lemma-assistant-experience-plan {
|
|
203
528
|
position: absolute;
|
|
@@ -205,6 +530,7 @@
|
|
|
205
530
|
right: 0;
|
|
206
531
|
bottom: calc(100% + 8px);
|
|
207
532
|
z-index: 20;
|
|
533
|
+
pointer-events: auto;
|
|
208
534
|
}
|
|
209
535
|
|
|
210
536
|
.lemma-assistant-composer-status-rail {
|
|
@@ -223,6 +549,41 @@
|
|
|
223
549
|
gap: 6px;
|
|
224
550
|
}
|
|
225
551
|
|
|
552
|
+
.lemma-assistant-conversation-list-new,
|
|
553
|
+
.lemma-assistant-experience-sidebar-new {
|
|
554
|
+
border-color: color-mix(in srgb, var(--border-default) 88%, transparent);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
.lemma-assistant-experience-new,
|
|
559
|
+
.lemma-assistant-conversation-list-new,
|
|
560
|
+
.lemma-assistant-experience-sidebar-new {
|
|
561
|
+
background: color-mix(in srgb, var(--bg-surface) 90%, transparent);
|
|
562
|
+
backdrop-filter: blur(12px);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
.lemma-assistant-experience-new {
|
|
566
|
+
border: 0;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
.lemma-assistant-experience[data-chrome-style="subtle"] .lemma-assistant-experience-card,
|
|
570
|
+
.lemma-assistant-experience[data-chrome-style="subtle"] .lemma-assistant-experience-sidebar {
|
|
571
|
+
box-shadow: var(--shadow-md);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
.lemma-assistant-experience[data-chrome-style="flat"] .lemma-assistant-experience-card,
|
|
575
|
+
.lemma-assistant-experience[data-chrome-style="flat"] .lemma-assistant-experience-sidebar {
|
|
576
|
+
background: transparent;
|
|
577
|
+
border-color: transparent;
|
|
578
|
+
box-shadow: none;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
.lemma-assistant-plan-strip {
|
|
582
|
+
background: var(--bg-surface);
|
|
583
|
+
border-color: color-mix(in srgb, var(--border-default) 88%, transparent);
|
|
584
|
+
box-shadow: var(--shadow-sm);
|
|
585
|
+
}
|
|
586
|
+
|
|
226
587
|
.lemma-assistant-pending-file-chip {
|
|
227
588
|
display: inline-flex;
|
|
228
589
|
align-items: center;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lemma-sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.19",
|
|
4
4
|
"description": "Official TypeScript SDK for Lemma pod-scoped APIs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -53,6 +53,8 @@
|
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
+
"react-markdown": "^10.1.0",
|
|
57
|
+
"remark-gfm": "^4.0.1",
|
|
56
58
|
"supertokens-web-js": "^0.16.0"
|
|
57
59
|
},
|
|
58
60
|
"devDependencies": {
|