@osdk/react-components 0.33.0 → 0.34.0-main-9c6b0e3ff8efd7e86c4f7bc0edc53f6e26513b25
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/AGENTS.md +3 -0
- package/CHANGELOG.md +19 -0
- package/README.md +14 -13
- package/build/browser/aip-agent-chat/AipAgentChat.js +113 -0
- package/build/browser/aip-agent-chat/AipAgentChat.js.map +1 -0
- package/build/browser/aip-agent-chat/AipAgentChat.module.css +231 -0
- package/build/browser/aip-agent-chat/AipAgentChat.module.css.js +29 -0
- package/build/browser/aip-agent-chat/AipAgentChatApi.js +2 -0
- package/build/browser/aip-agent-chat/AipAgentChatApi.js.map +1 -0
- package/build/browser/aip-agent-chat/BaseAipAgentChat.js +67 -0
- package/build/browser/aip-agent-chat/BaseAipAgentChat.js.map +1 -0
- package/build/browser/aip-agent-chat/components/AipAgentChatComposer.js +96 -0
- package/build/browser/aip-agent-chat/components/AipAgentChatComposer.js.map +1 -0
- package/build/browser/aip-agent-chat/components/AipAgentChatLoader.js +43 -0
- package/build/browser/aip-agent-chat/components/AipAgentChatLoader.js.map +1 -0
- package/build/browser/aip-agent-chat/components/AipAgentChatMessage.js +60 -0
- package/build/browser/aip-agent-chat/components/AipAgentChatMessage.js.map +1 -0
- package/build/browser/aip-agent-chat/components/AipAgentChatMessageList.js +60 -0
- package/build/browser/aip-agent-chat/components/AipAgentChatMessageList.js.map +1 -0
- package/build/browser/aip-agent-chat/components/AipAgentChatModelPicker.js +56 -0
- package/build/browser/aip-agent-chat/components/AipAgentChatModelPicker.js.map +1 -0
- package/build/browser/aip-agent-chat/hooks/useChatAutoScroll.js +61 -0
- package/build/browser/aip-agent-chat/hooks/useChatAutoScroll.js.map +1 -0
- package/build/browser/base-components/callout/Callout.js +65 -0
- package/build/browser/base-components/callout/Callout.js.map +1 -0
- package/build/browser/base-components/callout/Callout.module.css +59 -0
- package/build/browser/base-components/callout/Callout.module.css.js +15 -0
- package/build/browser/public/experimental/aip-agent-chat.js +22 -0
- package/build/browser/public/experimental/aip-agent-chat.js.map +1 -0
- package/build/browser/styles.css +402 -0
- package/build/browser/tokens/base-tokens/dark.css +10 -0
- package/build/browser/tokens/component-tokens/aip-agent-chat.css +56 -0
- package/build/browser/tokens/component-tokens/callout.css +40 -0
- package/build/browser/tokens.css +2 -0
- package/build/browser/util/UserAgent.js +1 -1
- package/build/browser/util/UserAgent.js.map +1 -1
- package/build/cjs/chunk-5NDWL2Z4.cjs +11 -0
- package/build/cjs/{chunk-D6RQIMMX.cjs.map → chunk-5NDWL2Z4.cjs.map} +1 -1
- package/build/cjs/{chunk-XCZD54BD.cjs → chunk-67U7G75G.cjs} +4 -4
- package/build/cjs/{chunk-XCZD54BD.cjs.map → chunk-67U7G75G.cjs.map} +1 -1
- package/build/cjs/{chunk-N5NOB4G4.cjs → chunk-6F4AZP7V.cjs} +4 -4
- package/build/cjs/{chunk-N5NOB4G4.cjs.map → chunk-6F4AZP7V.cjs.map} +1 -1
- package/build/cjs/{chunk-56CFJTXV.cjs → chunk-6QEH3O26.cjs} +6 -6
- package/build/cjs/{chunk-56CFJTXV.cjs.map → chunk-6QEH3O26.cjs.map} +1 -1
- package/build/cjs/{chunk-OTAWBR27.cjs → chunk-AFK4GBYE.cjs} +4 -4
- package/build/cjs/{chunk-OTAWBR27.cjs.map → chunk-AFK4GBYE.cjs.map} +1 -1
- package/build/cjs/{chunk-QWFT3G4W.cjs → chunk-FTW4JVD7.cjs} +4 -4
- package/build/cjs/{chunk-QWFT3G4W.cjs.map → chunk-FTW4JVD7.cjs.map} +1 -1
- package/build/cjs/chunk-HFLRL2TQ.cjs +11 -0
- package/build/cjs/{chunk-3MDT2TJK.cjs.map → chunk-HFLRL2TQ.cjs.map} +1 -1
- package/build/cjs/chunk-K5J4ISSR.cjs +11 -0
- package/build/cjs/{chunk-N7TOWLUY.cjs.map → chunk-K5J4ISSR.cjs.map} +1 -1
- package/build/cjs/{chunk-4AGEVOFW.cjs → chunk-NG2KBWBB.cjs} +4 -4
- package/build/cjs/{chunk-4AGEVOFW.cjs.map → chunk-NG2KBWBB.cjs.map} +1 -1
- package/build/cjs/chunk-PFPLIUW2.cjs +11 -0
- package/build/cjs/{chunk-SUEZQS7M.cjs.map → chunk-PFPLIUW2.cjs.map} +1 -1
- package/build/cjs/{chunk-LYAAHEAS.cjs → chunk-QZHGAZFV.cjs} +4 -4
- package/build/cjs/{chunk-LYAAHEAS.cjs.map → chunk-QZHGAZFV.cjs.map} +1 -1
- package/build/cjs/chunk-REAYT6E6.cjs +11 -0
- package/build/cjs/{chunk-AEFCONAY.cjs.map → chunk-REAYT6E6.cjs.map} +1 -1
- package/build/cjs/{chunk-PFGIO77A.cjs → chunk-TXPS5JVL.cjs} +4 -4
- package/build/cjs/{chunk-PFGIO77A.cjs.map → chunk-TXPS5JVL.cjs.map} +1 -1
- package/build/cjs/{chunk-364UCCB2.cjs → chunk-VTZQLADC.cjs} +3 -3
- package/build/cjs/chunk-VTZQLADC.cjs.map +1 -0
- package/build/cjs/public/experimental/action-form.cjs +4 -4
- package/build/cjs/public/experimental/aip-agent-chat.cjs +434 -0
- package/build/cjs/public/experimental/aip-agent-chat.cjs.map +1 -0
- package/build/cjs/public/experimental/aip-agent-chat.css +304 -0
- package/build/cjs/public/experimental/aip-agent-chat.css.map +1 -0
- package/build/cjs/public/experimental/aip-agent-chat.d.cts +202 -0
- package/build/cjs/public/experimental/cbac-picker.cjs +11 -11
- package/build/cjs/public/experimental/document-viewer.cjs +6 -6
- package/build/cjs/public/experimental/email-viewer.cjs +3 -3
- package/build/cjs/public/experimental/excel-viewer.cjs +3 -3
- package/build/cjs/public/experimental/filter-list.cjs +15 -15
- package/build/cjs/public/experimental/image-viewer.cjs +3 -3
- package/build/cjs/public/experimental/markdown-renderer.cjs +3 -3
- package/build/cjs/public/experimental/object-table.cjs +8 -8
- package/build/cjs/public/experimental/pdf-viewer.cjs +7 -7
- package/build/cjs/public/experimental/tiff-renderer.cjs +3 -3
- package/build/cjs/public/experimental/video-viewer.cjs +3 -3
- package/build/cjs/public/experimental/xml-viewer.cjs +3 -3
- package/build/cjs/public/experimental.cjs +74 -74
- package/build/esm/aip-agent-chat/AipAgentChat.js +113 -0
- package/build/esm/aip-agent-chat/AipAgentChat.js.map +1 -0
- package/build/esm/aip-agent-chat/AipAgentChat.module.css +231 -0
- package/build/esm/aip-agent-chat/AipAgentChatApi.js +2 -0
- package/build/esm/aip-agent-chat/AipAgentChatApi.js.map +1 -0
- package/build/esm/aip-agent-chat/BaseAipAgentChat.js +67 -0
- package/build/esm/aip-agent-chat/BaseAipAgentChat.js.map +1 -0
- package/build/esm/aip-agent-chat/components/AipAgentChatComposer.js +96 -0
- package/build/esm/aip-agent-chat/components/AipAgentChatComposer.js.map +1 -0
- package/build/esm/aip-agent-chat/components/AipAgentChatLoader.js +43 -0
- package/build/esm/aip-agent-chat/components/AipAgentChatLoader.js.map +1 -0
- package/build/esm/aip-agent-chat/components/AipAgentChatMessage.js +60 -0
- package/build/esm/aip-agent-chat/components/AipAgentChatMessage.js.map +1 -0
- package/build/esm/aip-agent-chat/components/AipAgentChatMessageList.js +60 -0
- package/build/esm/aip-agent-chat/components/AipAgentChatMessageList.js.map +1 -0
- package/build/esm/aip-agent-chat/components/AipAgentChatModelPicker.js +56 -0
- package/build/esm/aip-agent-chat/components/AipAgentChatModelPicker.js.map +1 -0
- package/build/esm/aip-agent-chat/hooks/useChatAutoScroll.js +61 -0
- package/build/esm/aip-agent-chat/hooks/useChatAutoScroll.js.map +1 -0
- package/build/esm/base-components/callout/Callout.js +65 -0
- package/build/esm/base-components/callout/Callout.js.map +1 -0
- package/build/esm/base-components/callout/Callout.module.css +59 -0
- package/build/esm/public/experimental/aip-agent-chat.js +22 -0
- package/build/esm/public/experimental/aip-agent-chat.js.map +1 -0
- package/build/esm/tokens/base-tokens/dark.css +10 -0
- package/build/esm/tokens/component-tokens/aip-agent-chat.css +56 -0
- package/build/esm/tokens/component-tokens/callout.css +40 -0
- package/build/esm/tokens.css +2 -0
- package/build/esm/util/UserAgent.js +1 -1
- package/build/esm/util/UserAgent.js.map +1 -1
- package/build/types/aip-agent-chat/AipAgentChat.d.ts +10 -0
- package/build/types/aip-agent-chat/AipAgentChat.d.ts.map +1 -0
- package/build/types/aip-agent-chat/AipAgentChatApi.d.ts +135 -0
- package/build/types/aip-agent-chat/AipAgentChatApi.d.ts.map +1 -0
- package/build/types/aip-agent-chat/BaseAipAgentChat.d.ts +55 -0
- package/build/types/aip-agent-chat/BaseAipAgentChat.d.ts.map +1 -0
- package/build/types/aip-agent-chat/components/AipAgentChatComposer.d.ts +19 -0
- package/build/types/aip-agent-chat/components/AipAgentChatComposer.d.ts.map +1 -0
- package/build/types/aip-agent-chat/components/AipAgentChatLoader.d.ts +9 -0
- package/build/types/aip-agent-chat/components/AipAgentChatLoader.d.ts.map +1 -0
- package/build/types/aip-agent-chat/components/AipAgentChatMessage.d.ts +12 -0
- package/build/types/aip-agent-chat/components/AipAgentChatMessage.d.ts.map +1 -0
- package/build/types/aip-agent-chat/components/AipAgentChatMessageList.d.ts +11 -0
- package/build/types/aip-agent-chat/components/AipAgentChatMessageList.d.ts.map +1 -0
- package/build/types/aip-agent-chat/components/AipAgentChatModelPicker.d.ts +16 -0
- package/build/types/aip-agent-chat/components/AipAgentChatModelPicker.d.ts.map +1 -0
- package/build/types/aip-agent-chat/hooks/useChatAutoScroll.d.ts +11 -0
- package/build/types/aip-agent-chat/hooks/useChatAutoScroll.d.ts.map +1 -0
- package/build/types/base-components/callout/Callout.d.ts +33 -0
- package/build/types/base-components/callout/Callout.d.ts.map +1 -0
- package/build/types/public/experimental/aip-agent-chat.d.ts +7 -0
- package/build/types/public/experimental/aip-agent-chat.d.ts.map +1 -0
- package/docs/AipAgentChat.md +207 -0
- package/docs/CSSVariables.md +52 -0
- package/docs/Welcome.md +1 -0
- package/package.json +25 -9
- package/build/cjs/chunk-364UCCB2.cjs.map +0 -1
- package/build/cjs/chunk-3MDT2TJK.cjs +0 -11
- package/build/cjs/chunk-AEFCONAY.cjs +0 -11
- package/build/cjs/chunk-D6RQIMMX.cjs +0 -11
- package/build/cjs/chunk-N7TOWLUY.cjs +0 -11
- package/build/cjs/chunk-SUEZQS7M.cjs +0 -11
package/AGENTS.md
CHANGED
|
@@ -44,6 +44,7 @@ Components are imported from their individual entry points under `@osdk/react-co
|
|
|
44
44
|
- `@osdk/react-components/experimental/pdf-viewer` — PdfViewer, BasePdfViewer, and building blocks/hooks
|
|
45
45
|
- `@osdk/react-components/experimental/tiff-renderer` — TiffRenderer
|
|
46
46
|
- `@osdk/react-components/experimental/markdown-renderer` — MarkdownRenderer
|
|
47
|
+
- `@osdk/react-components/experimental/aip-agent-chat` — AipAgentChat, BaseAipAgentChat
|
|
47
48
|
- `@osdk/react-components/experimental/document-viewer` — DocumentViewer
|
|
48
49
|
- `@osdk/react-components/experimental/email-viewer` — EmailViewer, BaseEmailViewer
|
|
49
50
|
- `@osdk/react-components/experimental/excel-viewer` — ExcelViewer, BaseExcelViewer
|
|
@@ -64,6 +65,8 @@ Components are imported from their individual entry points under `@osdk/react-co
|
|
|
64
65
|
| **BasePdfViewer** | OSDK-agnostic base PDF viewer — accepts a URL or ArrayBuffer directly. Use when building custom data fetching on top of the viewer UI. |
|
|
65
66
|
| **TiffRenderer** | TIFF image renderer — accepts a `Uint8Array` and renders onto a canvas with size validation and error handling. |
|
|
66
67
|
| **MarkdownRenderer** | Markdown renderer that accepts a markdown string and renders it with styled headings, code blocks, tables, and links. |
|
|
68
|
+
| **AipAgentChat** | Chat surface backed by Foundry LMS via `useChat`. Takes a `PlatformClient` + model API name and renders messages, composer, and streaming. |
|
|
69
|
+
| **BaseAipAgentChat** | OSDK-agnostic base chat — accepts `messages`/`status`/`onSendMessage` directly. Use for custom chat-state plumbing. |
|
|
67
70
|
| **DocumentViewer** | Unified media viewer that auto-detects file type (PDF, TIFF, image, video, Excel, email, markdown, XML) and renders the appropriate viewer. |
|
|
68
71
|
| **EmailViewer** | Email viewer — parses and renders `.eml` files with headers, HTML body (sandboxed iframe), and plain text fallback. |
|
|
69
72
|
| **ExcelViewer** | Excel viewer — parses and renders `.xlsx` spreadsheets with sheet tabs and column/row headers. |
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @osdk/react-components
|
|
2
2
|
|
|
3
|
+
## 0.34.0-main-9c6b0e3ff8efd7e86c4f7bc0edc53f6e26513b25
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- afc63a7: Restore the AIP chat entry points (`@osdk/react/experimental/aip` and `@osdk/react-components/experimental/aip-agent-chat`) and publish `@osdk/aip-core` so the optional peer dependency resolves from the registry.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 0ed0b5c: Restyle AipAgentChat to match Threads 2.0 design with light gray user bubbles, plain-text assistant messages, rounded inlined composer, centered max-width layout, and no composer divider. Add reusable Callout base component with intent-tinted backgrounds and dark mode support. Add AipAgentChat storybook stories.
|
|
12
|
+
- d24cc61: Pin the `@osdk/aip-core` peerDependency range to `>=0.5.0 <1.0.0` instead of `workspace:^` so a minor bump of `@osdk/aip-core` (e.g. 0.5.0 -> 0.6.0) no longer falls out of the caret range and triggers a major-bump cascade across the release plan.
|
|
13
|
+
- Updated dependencies [d24cc61]
|
|
14
|
+
- Updated dependencies [afc63a7]
|
|
15
|
+
- Updated dependencies [9b150d7]
|
|
16
|
+
- Updated dependencies [15a35f2]
|
|
17
|
+
- @osdk/react@2.41.0-main-9c6b0e3ff8efd7e86c4f7bc0edc53f6e26513b25
|
|
18
|
+
- @osdk/aip-core@0.6.0-main-9c6b0e3ff8efd7e86c4f7bc0edc53f6e26513b25
|
|
19
|
+
- @osdk/client@2.41.0-main-9c6b0e3ff8efd7e86c4f7bc0edc53f6e26513b25
|
|
20
|
+
- @osdk/api@2.41.0-main-9c6b0e3ff8efd7e86c4f7bc0edc53f6e26513b25
|
|
21
|
+
|
|
3
22
|
## 0.33.0
|
|
4
23
|
|
|
5
24
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -125,19 +125,20 @@ Add `isolation: isolate` to your app's root element. This is required for Base U
|
|
|
125
125
|
|
|
126
126
|
The components that this package will provide are:
|
|
127
127
|
|
|
128
|
-
| Component | Description
|
|
129
|
-
| ---------------- |
|
|
130
|
-
| `ObjectTable` | Displays an Object Set as a sortable, paginated table with inline editing support
|
|
131
|
-
| `PdfViewer` | Renders PDF documents with annotations, search, sidebar navigation, and zoom
|
|
132
|
-
| `FilterList` | Visualize a high-level summary of objects data to allow users to filter that data.
|
|
133
|
-
| `ActionForm` | Auto-generated form for executing Ontology Actions
|
|
134
|
-
| `
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
128
|
+
| Component | Description | Documentation |
|
|
129
|
+
| ---------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
|
|
130
|
+
| `ObjectTable` | Displays an Object Set as a sortable, paginated table with inline editing support | [Guide](https://github.com/palantir/osdk-ts/blob/main/packages/react-components/docs/ObjectTable.md) |
|
|
131
|
+
| `PdfViewer` | Renders PDF documents with annotations, search, sidebar navigation, and zoom | [Guide](https://github.com/palantir/osdk-ts/blob/main/packages/react-components/docs/PdfViewer.md) |
|
|
132
|
+
| `FilterList` | Visualize a high-level summary of objects data to allow users to filter that data. | [Guide](https://github.com/palantir/osdk-ts/blob/main/packages/react-components/docs/FilterList.md) |
|
|
133
|
+
| `ActionForm` | Auto-generated form for executing Ontology Actions | [Guide](https://github.com/palantir/osdk-ts/blob/main/packages/react-components/docs/ActionForm.md) |
|
|
134
|
+
| `AipAgentChat` | Chat surface backed by Foundry LMS via `useChat` — takes a `PlatformClient` and model API name. | [Guide](https://github.com/palantir/osdk-ts/blob/main/packages/react-components/docs/AipAgentChat.md) |
|
|
135
|
+
| `DocumentViewer` | Unified media viewer that auto-detects file type and renders the appropriate viewer | [Guide](https://github.com/palantir/osdk-ts/blob/main/packages/react-components/docs/DocumentViewer.md) |
|
|
136
|
+
| `EmailViewer` | Parses and renders EML files with headers and sandboxed HTML body | [Guide](https://github.com/palantir/osdk-ts/blob/main/packages/react-components/docs/EmailViewer.md) |
|
|
137
|
+
| `ExcelViewer` | Renders Excel spreadsheets with sheet tabs and column/row headers | [Guide](https://github.com/palantir/osdk-ts/blob/main/packages/react-components/docs/ExcelViewer.md) |
|
|
138
|
+
| `ImageViewer` | Renders images (PNG, JPEG, GIF, SVG, WebP, BMP) | [Guide](https://github.com/palantir/osdk-ts/blob/main/packages/react-components/docs/ImageViewer.md) |
|
|
139
|
+
| `VideoViewer` | Renders video with native browser controls | [Guide](https://github.com/palantir/osdk-ts/blob/main/packages/react-components/docs/VideoViewer.md) |
|
|
140
|
+
| `XmlViewer` | Renders XML content with syntax preservation | [Guide](https://github.com/palantir/osdk-ts/blob/main/packages/react-components/docs/XmlViewer.md) |
|
|
141
|
+
| `CbacPicker` | Picker for classification-based access control (CBAC) markings with banner display | [Guide](https://github.com/palantir/osdk-ts/blob/main/packages/react-components/docs/CbacPicker.md) |
|
|
141
142
|
|
|
142
143
|
## Component Architecture
|
|
143
144
|
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { foundryModel } from "@osdk/aip-core";
|
|
18
|
+
import { useChat } from "@osdk/react/experimental/aip";
|
|
19
|
+
import * as React from "react";
|
|
20
|
+
import { BaseAipAgentChat } from "./BaseAipAgentChat.js";
|
|
21
|
+
import { AipAgentChatModelPicker } from "./components/AipAgentChatModelPicker.js";
|
|
22
|
+
const FALLBACK_MODEL_API_NAME = "gpt-4o";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* OSDK-aware chat surface backed by Foundry's Language Model Service.
|
|
26
|
+
* Constructs the LMS-backed model internally and uses `useChat` to
|
|
27
|
+
* manage conversation state, so consumers never need to import `useChat`,
|
|
28
|
+
* `streamText`, or `foundryModel` themselves.
|
|
29
|
+
*/
|
|
30
|
+
export function AipAgentChat({
|
|
31
|
+
client,
|
|
32
|
+
model: controlledModel,
|
|
33
|
+
defaultModel,
|
|
34
|
+
availableModels,
|
|
35
|
+
onModelChange,
|
|
36
|
+
system,
|
|
37
|
+
initialMessages,
|
|
38
|
+
className,
|
|
39
|
+
placeholder,
|
|
40
|
+
enableAutoScroll,
|
|
41
|
+
onError,
|
|
42
|
+
onFinish,
|
|
43
|
+
renderEmptyState,
|
|
44
|
+
renderMessage
|
|
45
|
+
}) {
|
|
46
|
+
// Internal state used only in uncontrolled mode. Initialized once
|
|
47
|
+
// from the first available source: `controlledModel` → `defaultModel`
|
|
48
|
+
// → first entry of `availableModels` → `FALLBACK_MODEL_API_NAME`.
|
|
49
|
+
const [internalModel, setInternalModel] = React.useState(() => controlledModel ?? defaultModel ?? availableModels?.[0] ?? FALLBACK_MODEL_API_NAME);
|
|
50
|
+
const isControlled = controlledModel != null;
|
|
51
|
+
const activeModel = isControlled ? controlledModel : internalModel;
|
|
52
|
+
const handleModelChange = React.useCallback(next => {
|
|
53
|
+
if (!isControlled) {
|
|
54
|
+
setInternalModel(next);
|
|
55
|
+
}
|
|
56
|
+
onModelChange?.(next);
|
|
57
|
+
}, [isControlled, onModelChange]);
|
|
58
|
+
const model = React.useMemo(() => foundryModel({
|
|
59
|
+
client,
|
|
60
|
+
model: activeModel
|
|
61
|
+
}), [client, activeModel]);
|
|
62
|
+
const {
|
|
63
|
+
messages,
|
|
64
|
+
status,
|
|
65
|
+
error,
|
|
66
|
+
sendMessage,
|
|
67
|
+
stop,
|
|
68
|
+
clearError
|
|
69
|
+
} = useChat({
|
|
70
|
+
model,
|
|
71
|
+
system,
|
|
72
|
+
messages: initialMessages,
|
|
73
|
+
onError,
|
|
74
|
+
onFinish
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Snap the uncontrolled model to the first available option whenever the
|
|
78
|
+
// current selection isn't in `availableModels` (e.g. on first async resolve).
|
|
79
|
+
React.useEffect(() => {
|
|
80
|
+
if (isControlled || availableModels == null || availableModels.length === 0) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (!availableModels.includes(internalModel)) {
|
|
84
|
+
setInternalModel(availableModels[0]);
|
|
85
|
+
}
|
|
86
|
+
}, [isControlled, availableModels, internalModel]);
|
|
87
|
+
const handleSendMessage = React.useCallback(text => {
|
|
88
|
+
return sendMessage({
|
|
89
|
+
text
|
|
90
|
+
});
|
|
91
|
+
}, [sendMessage]);
|
|
92
|
+
const composerFooter = availableModels != null && availableModels.length > 0 ? /*#__PURE__*/React.createElement(AipAgentChatModelPicker, {
|
|
93
|
+
activeModel: activeModel,
|
|
94
|
+
models: availableModels,
|
|
95
|
+
onModelChange: handleModelChange,
|
|
96
|
+
disabled: status === "submitted" || status === "streaming"
|
|
97
|
+
}) : undefined;
|
|
98
|
+
return /*#__PURE__*/React.createElement(BaseAipAgentChat, {
|
|
99
|
+
className: className,
|
|
100
|
+
composerFooter: composerFooter,
|
|
101
|
+
enableAutoScroll: enableAutoScroll,
|
|
102
|
+
messages: messages,
|
|
103
|
+
status: status,
|
|
104
|
+
error: error,
|
|
105
|
+
onClearError: clearError,
|
|
106
|
+
onSendMessage: handleSendMessage,
|
|
107
|
+
onStop: stop,
|
|
108
|
+
placeholder: placeholder,
|
|
109
|
+
renderEmptyState: renderEmptyState,
|
|
110
|
+
renderMessage: renderMessage
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=AipAgentChat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AipAgentChat.js","names":["foundryModel","useChat","React","BaseAipAgentChat","AipAgentChatModelPicker","FALLBACK_MODEL_API_NAME","AipAgentChat","client","model","controlledModel","defaultModel","availableModels","onModelChange","system","initialMessages","className","placeholder","enableAutoScroll","onError","onFinish","renderEmptyState","renderMessage","internalModel","setInternalModel","useState","isControlled","activeModel","handleModelChange","useCallback","next","useMemo","messages","status","error","sendMessage","stop","clearError","useEffect","length","includes","handleSendMessage","text","composerFooter","createElement","models","disabled","undefined","onClearError","onSendMessage","onStop"],"sources":["AipAgentChat.tsx"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { foundryModel } from \"@osdk/aip-core\";\nimport { useChat } from \"@osdk/react/experimental/aip\";\nimport * as React from \"react\";\nimport type { AipAgentChatProps } from \"./AipAgentChatApi.js\";\nimport { BaseAipAgentChat } from \"./BaseAipAgentChat.js\";\nimport { AipAgentChatModelPicker } from \"./components/AipAgentChatModelPicker.js\";\n\nexport type { AipAgentChatProps } from \"./AipAgentChatApi.js\";\n\nconst FALLBACK_MODEL_API_NAME = \"gpt-4o\";\n\n/**\n * OSDK-aware chat surface backed by Foundry's Language Model Service.\n * Constructs the LMS-backed model internally and uses `useChat` to\n * manage conversation state, so consumers never need to import `useChat`,\n * `streamText`, or `foundryModel` themselves.\n */\nexport function AipAgentChat({\n client,\n model: controlledModel,\n defaultModel,\n availableModels,\n onModelChange,\n system,\n initialMessages,\n className,\n placeholder,\n enableAutoScroll,\n onError,\n onFinish,\n renderEmptyState,\n renderMessage,\n}: AipAgentChatProps): React.ReactElement {\n // Internal state used only in uncontrolled mode. Initialized once\n // from the first available source: `controlledModel` → `defaultModel`\n // → first entry of `availableModels` → `FALLBACK_MODEL_API_NAME`.\n const [internalModel, setInternalModel] = React.useState<string>(\n () =>\n controlledModel\n ?? defaultModel\n ?? availableModels?.[0]\n ?? FALLBACK_MODEL_API_NAME,\n );\n\n const isControlled = controlledModel != null;\n const activeModel = isControlled ? controlledModel : internalModel;\n\n const handleModelChange = React.useCallback(\n (next: string) => {\n if (!isControlled) {\n setInternalModel(next);\n }\n onModelChange?.(next);\n },\n [isControlled, onModelChange],\n );\n\n const model = React.useMemo(\n () => foundryModel({ client, model: activeModel }),\n [client, activeModel],\n );\n\n const {\n messages,\n status,\n error,\n sendMessage,\n stop,\n clearError,\n } = useChat({\n model,\n system,\n messages: initialMessages,\n onError,\n onFinish,\n });\n\n // Snap the uncontrolled model to the first available option whenever the\n // current selection isn't in `availableModels` (e.g. on first async resolve).\n React.useEffect(() => {\n if (\n isControlled || availableModels == null || availableModels.length === 0\n ) {\n return;\n }\n if (!availableModels.includes(internalModel)) {\n setInternalModel(availableModels[0]);\n }\n }, [isControlled, availableModels, internalModel]);\n\n const handleSendMessage = React.useCallback(\n (text: string) => {\n return sendMessage({ text });\n },\n [sendMessage],\n );\n\n const isInFlight = status === \"submitted\" || status === \"streaming\";\n\n const composerFooter = availableModels != null && availableModels.length > 0\n ? (\n <AipAgentChatModelPicker\n activeModel={activeModel}\n models={availableModels}\n onModelChange={handleModelChange}\n disabled={isInFlight}\n />\n )\n : undefined;\n\n return (\n <BaseAipAgentChat\n className={className}\n composerFooter={composerFooter}\n enableAutoScroll={enableAutoScroll}\n messages={messages}\n status={status}\n error={error}\n onClearError={clearError}\n onSendMessage={handleSendMessage}\n onStop={stop}\n placeholder={placeholder}\n renderEmptyState={renderEmptyState}\n renderMessage={renderMessage}\n />\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
.chat {
|
|
2
|
+
background: var(--osdk-aip-agent-chat-background);
|
|
3
|
+
border: 1px solid var(--osdk-aip-agent-chat-border-color);
|
|
4
|
+
border-radius: var(--osdk-aip-agent-chat-border-radius);
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
height: 100%;
|
|
8
|
+
min-height: 0;
|
|
9
|
+
overflow: hidden;
|
|
10
|
+
width: 100%;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.messageList {
|
|
14
|
+
align-items: center;
|
|
15
|
+
display: flex;
|
|
16
|
+
flex: 1 1 auto;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
gap: var(--osdk-aip-agent-chat-message-gap);
|
|
19
|
+
min-height: 0;
|
|
20
|
+
overflow-y: auto;
|
|
21
|
+
padding: var(--osdk-aip-agent-chat-padding);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.messageList:not(.empty) > * {
|
|
25
|
+
max-width: var(--osdk-aip-agent-chat-content-max-width);
|
|
26
|
+
width: 100%;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.empty {
|
|
30
|
+
align-items: center;
|
|
31
|
+
color: var(--osdk-aip-agent-chat-empty-color);
|
|
32
|
+
display: flex;
|
|
33
|
+
flex: 1 1 auto;
|
|
34
|
+
flex-direction: column;
|
|
35
|
+
gap: var(--osdk-aip-agent-chat-message-gap);
|
|
36
|
+
justify-content: center;
|
|
37
|
+
padding: var(--osdk-aip-agent-chat-padding);
|
|
38
|
+
text-align: center;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.emptyIcon {
|
|
42
|
+
color: var(--osdk-aip-agent-chat-empty-icon-color);
|
|
43
|
+
font-size: var(--osdk-aip-agent-chat-empty-icon-size);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.emptyTitle {
|
|
47
|
+
color: var(--osdk-typography-color-default-rest);
|
|
48
|
+
font-size: var(--osdk-typography-size-body-large);
|
|
49
|
+
font-weight: var(--osdk-typography-weight-bold);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.message {
|
|
53
|
+
display: flex;
|
|
54
|
+
flex-direction: column;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.userMessage {
|
|
58
|
+
align-items: flex-end;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.assistantMessage {
|
|
62
|
+
align-items: flex-start;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.systemMessage {
|
|
66
|
+
align-items: center;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.bubble {
|
|
70
|
+
border-radius: var(--osdk-aip-agent-chat-bubble-border-radius);
|
|
71
|
+
max-width: var(--osdk-aip-agent-chat-bubble-max-width);
|
|
72
|
+
overflow-wrap: break-word;
|
|
73
|
+
padding: var(--osdk-aip-agent-chat-bubble-padding);
|
|
74
|
+
text-align: left;
|
|
75
|
+
white-space: pre-wrap;
|
|
76
|
+
word-break: break-word;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.userBubble {
|
|
80
|
+
background: var(--osdk-aip-agent-chat-user-bubble-background);
|
|
81
|
+
border-radius: var(--osdk-aip-agent-chat-user-bubble-border-radius);
|
|
82
|
+
color: var(--osdk-aip-agent-chat-user-bubble-color);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.assistantBubble {
|
|
86
|
+
background: transparent;
|
|
87
|
+
color: var(--osdk-aip-agent-chat-assistant-bubble-color);
|
|
88
|
+
padding: 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.systemBubble {
|
|
92
|
+
background: var(--osdk-background-tertiary);
|
|
93
|
+
color: var(--osdk-typography-color-muted);
|
|
94
|
+
font-size: var(--osdk-typography-size-body-small);
|
|
95
|
+
font-style: italic;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.streamingPlaceholder {
|
|
99
|
+
color: var(--osdk-typography-color-muted);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.composer {
|
|
103
|
+
align-items: center;
|
|
104
|
+
background: var(--osdk-aip-agent-chat-composer-background);
|
|
105
|
+
|
|
106
|
+
display: flex;
|
|
107
|
+
flex: 0 0 auto;
|
|
108
|
+
flex-direction: column;
|
|
109
|
+
gap: var(--osdk-aip-agent-chat-section-gap);
|
|
110
|
+
padding: var(--osdk-aip-agent-chat-padding);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.composer > * {
|
|
114
|
+
max-width: var(--osdk-aip-agent-chat-content-max-width);
|
|
115
|
+
width: 100%;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.inputWrapper {
|
|
119
|
+
background: var(--osdk-background-primary);
|
|
120
|
+
border: 1px solid var(--osdk-surface-border-color-default);
|
|
121
|
+
border-radius: var(--osdk-aip-agent-chat-composer-border-radius);
|
|
122
|
+
display: flex;
|
|
123
|
+
flex-direction: column;
|
|
124
|
+
overflow: hidden;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.inputWrapper:focus-within {
|
|
128
|
+
border-color: var(--osdk-emphasis-focus-color);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.textarea {
|
|
132
|
+
background: transparent;
|
|
133
|
+
border: none;
|
|
134
|
+
color: var(--osdk-typography-color-default-rest);
|
|
135
|
+
font-family: inherit;
|
|
136
|
+
font-size: var(--osdk-typography-size-body-medium);
|
|
137
|
+
line-height: var(--osdk-typography-line-height-default);
|
|
138
|
+
max-height: var(--osdk-aip-agent-chat-composer-textarea-max-height);
|
|
139
|
+
min-height: var(--osdk-aip-agent-chat-composer-textarea-min-height);
|
|
140
|
+
outline: none;
|
|
141
|
+
padding: var(--osdk-aip-agent-chat-section-gap);
|
|
142
|
+
resize: none;
|
|
143
|
+
width: 100%;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.inputActions {
|
|
147
|
+
align-items: center;
|
|
148
|
+
display: flex;
|
|
149
|
+
justify-content: flex-end;
|
|
150
|
+
padding: 0 var(--osdk-aip-agent-chat-section-gap)
|
|
151
|
+
var(--osdk-aip-agent-chat-section-gap);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.composerFooterLeft {
|
|
155
|
+
align-items: center;
|
|
156
|
+
display: flex;
|
|
157
|
+
flex: 1 1 auto;
|
|
158
|
+
gap: var(--osdk-aip-agent-chat-section-gap);
|
|
159
|
+
min-width: 0;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.modelPicker {
|
|
163
|
+
background: var(--osdk-background-primary);
|
|
164
|
+
border: 1px solid var(--osdk-surface-border-color-default);
|
|
165
|
+
border-radius: var(--osdk-aip-agent-chat-border-radius);
|
|
166
|
+
color: var(--osdk-typography-color-default-rest);
|
|
167
|
+
font-family: inherit;
|
|
168
|
+
font-size: var(--osdk-typography-size-body-small);
|
|
169
|
+
outline: none;
|
|
170
|
+
padding: calc(var(--osdk-surface-spacing) * 1)
|
|
171
|
+
calc(var(--osdk-surface-spacing) * 2);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.modelPicker:focus {
|
|
175
|
+
border-color: var(--osdk-emphasis-focus-color);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.modelPicker:disabled {
|
|
179
|
+
cursor: not-allowed;
|
|
180
|
+
opacity: 0.6;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.modelPickerLabel {
|
|
184
|
+
color: var(--osdk-typography-color-muted);
|
|
185
|
+
font-size: var(--osdk-typography-size-body-small);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.loader {
|
|
189
|
+
align-items: center;
|
|
190
|
+
color: var(--osdk-aip-agent-chat-loader-color);
|
|
191
|
+
display: inline-flex;
|
|
192
|
+
gap: var(--osdk-aip-agent-chat-loader-dot-gap);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.loaderDot {
|
|
196
|
+
animation-duration: 1.4s;
|
|
197
|
+
animation-iteration-count: infinite;
|
|
198
|
+
animation-name: aipAgentChatLoaderBounce;
|
|
199
|
+
animation-timing-function: ease-in-out;
|
|
200
|
+
background: currentColor;
|
|
201
|
+
border-radius: 50%;
|
|
202
|
+
display: inline-block;
|
|
203
|
+
height: var(--osdk-aip-agent-chat-loader-dot-size);
|
|
204
|
+
width: var(--osdk-aip-agent-chat-loader-dot-size);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.loaderDot:nth-child(1) {
|
|
208
|
+
animation-delay: 0s;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.loaderDot:nth-child(2) {
|
|
212
|
+
animation-delay: 0.2s;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.loaderDot:nth-child(3) {
|
|
216
|
+
animation-delay: 0.4s;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
@keyframes aipAgentChatLoaderBounce {
|
|
220
|
+
0%,
|
|
221
|
+
60%,
|
|
222
|
+
100% {
|
|
223
|
+
opacity: 0.3;
|
|
224
|
+
transform: translateY(0);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
30% {
|
|
228
|
+
opacity: 1;
|
|
229
|
+
transform: translateY(-25%);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// CSS Module proxy for AipAgentChat.module.css
|
|
2
|
+
const styles = {
|
|
3
|
+
"chat": "AipAgentChat-module__chat___8g7robE3",
|
|
4
|
+
"messageList": "AipAgentChat-module__messageList___EJT0wkUj",
|
|
5
|
+
"empty": "AipAgentChat-module__empty___U0ZZWxmq",
|
|
6
|
+
"emptyIcon": "AipAgentChat-module__emptyIcon___-xTDcCXC",
|
|
7
|
+
"emptyTitle": "AipAgentChat-module__emptyTitle___STng1--H",
|
|
8
|
+
"message": "AipAgentChat-module__message___n2npFl8B",
|
|
9
|
+
"userMessage": "AipAgentChat-module__userMessage___9gfztpI-",
|
|
10
|
+
"assistantMessage": "AipAgentChat-module__assistantMessage___Hd0kHNZz",
|
|
11
|
+
"systemMessage": "AipAgentChat-module__systemMessage___j1KBNC18",
|
|
12
|
+
"bubble": "AipAgentChat-module__bubble___ehxKR1xQ",
|
|
13
|
+
"userBubble": "AipAgentChat-module__userBubble___-LOIsBgf",
|
|
14
|
+
"assistantBubble": "AipAgentChat-module__assistantBubble___s-rbLzIp",
|
|
15
|
+
"systemBubble": "AipAgentChat-module__systemBubble___ujadzYgh",
|
|
16
|
+
"streamingPlaceholder": "AipAgentChat-module__streamingPlaceholder___Os6a8AJk",
|
|
17
|
+
"composer": "AipAgentChat-module__composer___Wh3s2x7e",
|
|
18
|
+
"inputWrapper": "AipAgentChat-module__inputWrapper___pRQ1RWF8",
|
|
19
|
+
"textarea": "AipAgentChat-module__textarea___ocjwiGty",
|
|
20
|
+
"inputActions": "AipAgentChat-module__inputActions___9WTDHiJb",
|
|
21
|
+
"composerFooterLeft": "AipAgentChat-module__composerFooterLeft___7INhMSpC",
|
|
22
|
+
"modelPicker": "AipAgentChat-module__modelPicker___rXMvrOZh",
|
|
23
|
+
"modelPickerLabel": "AipAgentChat-module__modelPickerLabel___Max6ajqc",
|
|
24
|
+
"loader": "AipAgentChat-module__loader___m79mDMns",
|
|
25
|
+
"loaderDot": "AipAgentChat-module__loaderDot___8E42Iyvu",
|
|
26
|
+
"aipAgentChatLoaderBounce": "AipAgentChat-module__aipAgentChatLoaderBounce___0vneIHI3"
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default styles;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AipAgentChatApi.js","names":[],"sources":["AipAgentChatApi.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { UIMessage } from \"@osdk/aip-core\";\nimport type { PlatformClient } from \"@osdk/client\";\nimport type * as React from \"react\";\n\n// TODO: replace `string` with a literal union of well-known LMS model API\n// names (mirrored from `quiver-language-model-service-utils`'\n// PREFERRED_MODEL_IDENTIFIERS) so consumers get IDE autocomplete on the\n// `model` / `defaultModel` / `availableModels` props. The union should\n// widen via `T | (string & {})` so registered-model API names still\n// type-check.\n\n/**\n * Props for {@link AipAgentChat}, an OSDK-aware chat surface backed by\n * Foundry's Language Model Service. Consumers do not need to import\n * `streamText` or `foundryModel` themselves — passing the platform\n * client is enough to render a working chat.\n *\n * If neither `model` nor `defaultModel` is supplied, the chat falls\n * back to the first entry of `availableModels` (when provided), or to\n * the LMS model API name `\"gpt-4o\"`.\n *\n * Default rendering is feature-complete with no overrides supplied;\n * render slots and `on*` listeners are layered on top of the built-in\n * behavior.\n */\nexport interface AipAgentChatProps {\n /**\n * Foundry platform client returned by `createPlatformClient` from\n * `@osdk/client`. Used internally to construct the LMS-backed model\n * for `useChat`.\n */\n client: PlatformClient;\n\n /**\n * Active LMS model API name (for example `\"gpt-4o\"`). Resolved\n * internally via `foundryModel({ client, model })`.\n *\n * Controlled mode: when provided, the consumer holds the model state.\n * Updates from the picker fire {@link AipAgentChatProps.onModelChange};\n * the consumer is expected to update this prop in response.\n *\n * Uncontrolled mode: omit and pass {@link AipAgentChatProps.defaultModel}\n * instead. If both are omitted, the chat falls back to the first\n * entry of {@link AipAgentChatProps.availableModels} (when provided),\n * or to `\"gpt-4o\"`.\n */\n model?: string;\n\n /**\n * Initial LMS model API name for uncontrolled mode. The component\n * manages model state internally, switching when the user picks a\n * different option from the picker. Ignored when\n * {@link AipAgentChatProps.model} is also provided (controlled mode\n * wins).\n *\n * @default the first entry of {@link AipAgentChatProps.availableModels}\n * when provided, otherwise `\"gpt-4o\"`.\n */\n defaultModel?: string;\n\n /**\n * When provided, the chat renders a model picker in the composer\n * footer populated with these API names.\n *\n * If omitted, no picker is rendered.\n */\n availableModels?: ReadonlyArray<string>;\n\n /**\n * Fires when the user selects a different model API name from the\n * picker.\n *\n * - **Controlled mode** (`model` is set): the consumer is expected to\n * update {@link AipAgentChatProps.model} in response.\n * - **Uncontrolled mode** (only `defaultModel` is set): a\n * non-controlling listener; the picker still mutates internal state\n * regardless. Use this for analytics or to persist the user's\n * choice.\n *\n * Has no effect unless {@link AipAgentChatProps.availableModels} is\n * provided.\n *\n * @param model The model API name the user just selected.\n */\n onModelChange?: (model: string) => void;\n\n /**\n * System prompt prepended to every request.\n */\n system?: string;\n\n /**\n * Seed messages — used as the initial conversation snapshot. Forwarded\n * to `useChat`'s `messages` option.\n */\n initialMessages?: ReadonlyArray<UIMessage>;\n\n /**\n * Additional CSS class name applied to the root chat container.\n */\n className?: string;\n\n /**\n * Placeholder text for the message composer input.\n *\n * @default \"Type a message...\"\n */\n placeholder?: string;\n\n /**\n * Whether the message list automatically scrolls to the most recent\n * message as the conversation grows.\n *\n * @default true\n */\n enableAutoScroll?: boolean;\n\n /**\n * Listener fired when the underlying chat hook surfaces an error\n * (for example a failed send or a dropped stream). Forwarded to\n * `useChat`'s `onError`.\n *\n * @param error The error reported by the chat backend.\n */\n onError?: (error: Error) => void;\n\n /**\n * Listener fired once after a stream completes successfully. Forwarded\n * to `useChat`'s `onFinish`.\n *\n * @param event The completed assistant message and the resulting\n * messages array.\n */\n onFinish?: (event: {\n message: UIMessage;\n messages: ReadonlyArray<UIMessage>;\n }) => void;\n\n /**\n * Render override for the empty state shown when no messages exist\n * yet. If omitted, a default welcome panel is rendered.\n *\n * @returns A React node rendered in place of the default empty state.\n */\n renderEmptyState?: () => React.ReactNode;\n\n /**\n * Render override for an individual message bubble. If omitted, the\n * default user/assistant bubble layout is used.\n *\n * @param message The {@link UIMessage} to render.\n * @returns A React node rendered in place of the default message\n * bubble.\n */\n renderMessage?: (message: UIMessage) => React.ReactNode;\n}\n"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import classNames from "classnames";
|
|
18
|
+
import * as React from "react";
|
|
19
|
+
import { ActionButton } from "../base-components/action-button/ActionButton.js";
|
|
20
|
+
import { Callout } from "../base-components/callout/Callout.js";
|
|
21
|
+
import styles from "./AipAgentChat.module.css.js";
|
|
22
|
+
import { AipAgentChatComposer } from "./components/AipAgentChatComposer.js";
|
|
23
|
+
import { AipAgentChatMessageList } from "./components/AipAgentChatMessageList.js";
|
|
24
|
+
/**
|
|
25
|
+
* OSDK-agnostic chat surface. Manages conversation state, streaming UI,
|
|
26
|
+
* and error display internally; the consumer provides the current state
|
|
27
|
+
* and callbacks for sending messages and managing state.
|
|
28
|
+
*/
|
|
29
|
+
export const BaseAipAgentChat = /*#__PURE__*/React.memo(function ({
|
|
30
|
+
messages,
|
|
31
|
+
status,
|
|
32
|
+
error,
|
|
33
|
+
onSendMessage,
|
|
34
|
+
onStop,
|
|
35
|
+
onClearError,
|
|
36
|
+
composerFooter,
|
|
37
|
+
className,
|
|
38
|
+
placeholder = "Type a message...",
|
|
39
|
+
enableAutoScroll = true,
|
|
40
|
+
renderEmptyState,
|
|
41
|
+
renderMessage
|
|
42
|
+
}) {
|
|
43
|
+
const isInFlight = status === "submitted" || status === "streaming";
|
|
44
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
45
|
+
className: classNames(styles.chat, className)
|
|
46
|
+
}, error != null && /*#__PURE__*/React.createElement(Callout, {
|
|
47
|
+
actions: /*#__PURE__*/React.createElement(ActionButton, {
|
|
48
|
+
onClick: onClearError,
|
|
49
|
+
type: "button"
|
|
50
|
+
}, "Dismiss"),
|
|
51
|
+
intent: "error",
|
|
52
|
+
title: "Something went wrong"
|
|
53
|
+
}, error.message.length > 0 ? error.message : "An unknown error occurred. Try again, or dismiss to keep the conversation."), /*#__PURE__*/React.createElement(AipAgentChatMessageList, {
|
|
54
|
+
enableAutoScroll: enableAutoScroll,
|
|
55
|
+
isStreaming: isInFlight,
|
|
56
|
+
messages: messages,
|
|
57
|
+
renderEmptyState: renderEmptyState,
|
|
58
|
+
renderMessage: renderMessage
|
|
59
|
+
}), /*#__PURE__*/React.createElement(AipAgentChatComposer, {
|
|
60
|
+
footerLeft: composerFooter,
|
|
61
|
+
isInFlight: isInFlight,
|
|
62
|
+
onSendMessage: onSendMessage,
|
|
63
|
+
onStop: onStop,
|
|
64
|
+
placeholder: placeholder
|
|
65
|
+
}));
|
|
66
|
+
});
|
|
67
|
+
//# sourceMappingURL=BaseAipAgentChat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseAipAgentChat.js","names":["classNames","React","ActionButton","Callout","styles","AipAgentChatComposer","AipAgentChatMessageList","BaseAipAgentChat","memo","messages","status","error","onSendMessage","onStop","onClearError","composerFooter","className","placeholder","enableAutoScroll","renderEmptyState","renderMessage","isInFlight","createElement","chat","actions","onClick","type","intent","title","message","length","isStreaming","footerLeft"],"sources":["BaseAipAgentChat.tsx"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { UIMessage } from \"@osdk/aip-core\";\nimport type { ChatStatus } from \"@osdk/react/experimental/aip\";\nimport classNames from \"classnames\";\nimport * as React from \"react\";\nimport { ActionButton } from \"../base-components/action-button/ActionButton.js\";\nimport { Callout } from \"../base-components/callout/Callout.js\";\nimport styles from \"./AipAgentChat.module.css\";\nimport { AipAgentChatComposer } from \"./components/AipAgentChatComposer.js\";\nimport { AipAgentChatMessageList } from \"./components/AipAgentChatMessageList.js\";\n\nexport interface BaseAipAgentChatProps {\n /**\n * Current messages in the conversation.\n */\n messages: ReadonlyArray<UIMessage>;\n\n /**\n * Current status of the chat lifecycle.\n */\n status: ChatStatus;\n\n /**\n * Current error, if any.\n */\n error: Error | undefined;\n\n /**\n * Called when the user sends a message. Should return a promise that\n * resolves when the message has been sent.\n *\n * @param text The text the user just submitted (already trimmed).\n */\n onSendMessage: (text: string) => Promise<void>;\n\n /**\n * Called to stop an in-flight request.\n */\n onStop: () => void;\n\n /**\n * Called to clear the current error.\n */\n onClearError: () => void;\n\n /**\n * Optional content rendered in the composer footer, to the left of\n * the send button. The OSDK wrapper uses this slot for the model\n * picker.\n */\n composerFooter?: React.ReactNode;\n\n className?: string;\n\n /**\n * @default \"Type a message...\"\n */\n placeholder?: string;\n\n /**\n * @default true\n */\n enableAutoScroll?: boolean;\n\n renderEmptyState?: () => React.ReactNode;\n renderMessage?: (message: UIMessage) => React.ReactNode;\n}\n\n/**\n * OSDK-agnostic chat surface. Manages conversation state, streaming UI,\n * and error display internally; the consumer provides the current state\n * and callbacks for sending messages and managing state.\n */\nexport const BaseAipAgentChat: React.NamedExoticComponent<\n BaseAipAgentChatProps\n> = React.memo(function BaseAipAgentChat({\n messages,\n status,\n error,\n onSendMessage,\n onStop,\n onClearError,\n composerFooter,\n className,\n placeholder = \"Type a message...\",\n enableAutoScroll = true,\n renderEmptyState,\n renderMessage,\n}) {\n const isInFlight = status === \"submitted\" || status === \"streaming\";\n\n return (\n <div className={classNames(styles.chat, className)}>\n {error != null && (\n <Callout\n actions={\n <ActionButton onClick={onClearError} type=\"button\">\n Dismiss\n </ActionButton>\n }\n intent=\"error\"\n title=\"Something went wrong\"\n >\n {error.message.length > 0\n ? error.message\n : \"An unknown error occurred. Try again, or dismiss to keep the conversation.\"}\n </Callout>\n )}\n <AipAgentChatMessageList\n enableAutoScroll={enableAutoScroll}\n isStreaming={isInFlight}\n messages={messages}\n renderEmptyState={renderEmptyState}\n renderMessage={renderMessage}\n />\n <AipAgentChatComposer\n footerLeft={composerFooter}\n isInFlight={isInFlight}\n onSendMessage={onSendMessage}\n onStop={onStop}\n placeholder={placeholder}\n />\n </div>\n );\n});\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA,OAAOA,UAAU,MAAM,YAAY;AACnC,OAAO,KAAKC,KAAK,MAAM,OAAO;AAC9B,SAASC,YAAY,QAAQ,kDAAkD;AAC/E,SAASC,OAAO,QAAQ,uCAAuC;AAC/D,OAAOC,MAAM,MAAM,2BAA2B;AAC9C,SAASC,oBAAoB,QAAQ,sCAAsC;AAC3E,SAASC,uBAAuB,QAAQ,yCAAyC;AA2DjF;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,gBAEZ,gBAAGN,KAAK,CAACO,IAAI,CAAC,UAA0B;EACvCC,QAAQ;EACRC,MAAM;EACNC,KAAK;EACLC,aAAa;EACbC,MAAM;EACNC,YAAY;EACZC,cAAc;EACdC,SAAS;EACTC,WAAW,GAAG,mBAAmB;EACjCC,gBAAgB,GAAG,IAAI;EACvBC,gBAAgB;EAChBC;AACF,CAAC,EAAE;EACD,MAAMC,UAAU,GAAGX,MAAM,KAAK,WAAW,IAAIA,MAAM,KAAK,WAAW;EAEnE,oBACET,KAAA,CAAAqB,aAAA;IAAKN,SAAS,EAAEhB,UAAU,CAACI,MAAM,CAACmB,IAAI,EAAEP,SAAS;EAAE,GAChDL,KAAK,IAAI,IAAI,iBACZV,KAAA,CAAAqB,aAAA,CAACnB,OAAO;IACNqB,OAAO,eACLvB,KAAA,CAAAqB,aAAA,CAACpB,YAAY;MAACuB,OAAO,EAAEX,YAAa;MAACY,IAAI,EAAC;IAAQ,GAAC,SAErC,CACf;IACDC,MAAM,EAAC,OAAO;IACdC,KAAK,EAAC;EAAsB,GAE3BjB,KAAK,CAACkB,OAAO,CAACC,MAAM,GAAG,CAAC,GACrBnB,KAAK,CAACkB,OAAO,GACb,4EACG,CACV,eACD5B,KAAA,CAAAqB,aAAA,CAAChB,uBAAuB;IACtBY,gBAAgB,EAAEA,gBAAiB;IACnCa,WAAW,EAAEV,UAAW;IACxBZ,QAAQ,EAAEA,QAAS;IACnBU,gBAAgB,EAAEA,gBAAiB;IACnCC,aAAa,EAAEA;EAAc,CAC9B,CAAC,eACFnB,KAAA,CAAAqB,aAAA,CAACjB,oBAAoB;IACnB2B,UAAU,EAAEjB,cAAe;IAC3BM,UAAU,EAAEA,UAAW;IACvBT,aAAa,EAAEA,aAAc;IAC7BC,MAAM,EAAEA,MAAO;IACfI,WAAW,EAAEA;EAAY,CAC1B,CACE,CAAC;AAEV,CAAC,CAAC","ignoreList":[]}
|