@osdk/react-components 0.33.0 → 0.34.0-main-d24cc61b1e7fde7722d8229ed2b6821f5ce1bf8a
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-N5NOB4G4.cjs → chunk-4SBWDLNA.cjs} +4 -4
- package/build/cjs/{chunk-N5NOB4G4.cjs.map → chunk-4SBWDLNA.cjs.map} +1 -1
- package/build/cjs/{chunk-PFGIO77A.cjs → chunk-5JPP5IKU.cjs} +4 -4
- package/build/cjs/{chunk-PFGIO77A.cjs.map → chunk-5JPP5IKU.cjs.map} +1 -1
- package/build/cjs/{chunk-56CFJTXV.cjs → chunk-73EYJP6Z.cjs} +6 -6
- package/build/cjs/{chunk-56CFJTXV.cjs.map → chunk-73EYJP6Z.cjs.map} +1 -1
- package/build/cjs/{chunk-XCZD54BD.cjs → chunk-ABKLMCWO.cjs} +4 -4
- package/build/cjs/{chunk-XCZD54BD.cjs.map → chunk-ABKLMCWO.cjs.map} +1 -1
- package/build/cjs/{chunk-QWFT3G4W.cjs → chunk-EOXGPHI7.cjs} +4 -4
- package/build/cjs/{chunk-QWFT3G4W.cjs.map → chunk-EOXGPHI7.cjs.map} +1 -1
- package/build/cjs/chunk-HM6F2PSA.cjs +11 -0
- package/build/cjs/{chunk-N7TOWLUY.cjs.map → chunk-HM6F2PSA.cjs.map} +1 -1
- package/build/cjs/chunk-ILBAVINW.cjs +11 -0
- package/build/cjs/{chunk-SUEZQS7M.cjs.map → chunk-ILBAVINW.cjs.map} +1 -1
- package/build/cjs/chunk-MSUA3D5M.cjs +11 -0
- package/build/cjs/{chunk-AEFCONAY.cjs.map → chunk-MSUA3D5M.cjs.map} +1 -1
- package/build/cjs/{chunk-4AGEVOFW.cjs → chunk-MV4WJDCS.cjs} +4 -4
- package/build/cjs/{chunk-4AGEVOFW.cjs.map → chunk-MV4WJDCS.cjs.map} +1 -1
- package/build/cjs/{chunk-LYAAHEAS.cjs → chunk-PSXAPQB3.cjs} +4 -4
- package/build/cjs/{chunk-LYAAHEAS.cjs.map → chunk-PSXAPQB3.cjs.map} +1 -1
- package/build/cjs/chunk-RCL5R3P4.cjs +11 -0
- package/build/cjs/{chunk-D6RQIMMX.cjs.map → chunk-RCL5R3P4.cjs.map} +1 -1
- package/build/cjs/{chunk-OTAWBR27.cjs → chunk-S7Z4MCUS.cjs} +4 -4
- package/build/cjs/{chunk-OTAWBR27.cjs.map → chunk-S7Z4MCUS.cjs.map} +1 -1
- package/build/cjs/{chunk-364UCCB2.cjs → chunk-WVRYCKJY.cjs} +3 -3
- package/build/cjs/chunk-WVRYCKJY.cjs.map +1 -0
- package/build/cjs/chunk-YNECVUTQ.cjs +11 -0
- package/build/cjs/{chunk-3MDT2TJK.cjs.map → chunk-YNECVUTQ.cjs.map} +1 -1
- 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 +24 -8
- 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
|
@@ -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";
|
|
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":[]}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { Input } from "@base-ui/react/input";
|
|
19
|
+
import classNames from "classnames";
|
|
20
|
+
import * as React from "react";
|
|
21
|
+
import { ActionButton } from "../../base-components/action-button/ActionButton.js";
|
|
22
|
+
import styles from "../AipAgentChat.module.css";
|
|
23
|
+
/**
|
|
24
|
+
* Textarea + send/stop button. Enter sends; Shift+Enter inserts a newline.
|
|
25
|
+
* The button toggles to "Stop" while a stream is in flight (when an
|
|
26
|
+
* `onStop` callback is provided).
|
|
27
|
+
*/
|
|
28
|
+
export function AipAgentChatComposer({
|
|
29
|
+
isInFlight,
|
|
30
|
+
onSendMessage,
|
|
31
|
+
onStop,
|
|
32
|
+
placeholder,
|
|
33
|
+
className,
|
|
34
|
+
footerLeft
|
|
35
|
+
}) {
|
|
36
|
+
const [draft, setDraft] = React.useState("");
|
|
37
|
+
const canSend = !isInFlight && draft.trim().length > 0;
|
|
38
|
+
const handleSend = React.useCallback(() => {
|
|
39
|
+
const trimmed = draft.trim();
|
|
40
|
+
if (trimmed.length === 0) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
// Absorb sync throws and unhandled rejections; chat-level errors are
|
|
44
|
+
// surfaced via `onError` on the upstream useChat hook.
|
|
45
|
+
try {
|
|
46
|
+
const result = onSendMessage(trimmed);
|
|
47
|
+
if (result instanceof Promise) {
|
|
48
|
+
result.catch(noop);
|
|
49
|
+
}
|
|
50
|
+
} catch {
|
|
51
|
+
// swallow sync throws
|
|
52
|
+
}
|
|
53
|
+
setDraft("");
|
|
54
|
+
}, [draft, onSendMessage]);
|
|
55
|
+
const handleKeyDown = React.useCallback(event => {
|
|
56
|
+
if (event.key === "Enter" && !event.shiftKey) {
|
|
57
|
+
event.preventDefault();
|
|
58
|
+
if (!isInFlight) {
|
|
59
|
+
handleSend();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}, [handleSend, isInFlight]);
|
|
63
|
+
|
|
64
|
+
// Attach the keydown handler in the `render` prop so it can be typed against
|
|
65
|
+
// the actual rendered <textarea> element rather than base-ui's HTMLInputElement.
|
|
66
|
+
const renderTextarea = React.useCallback(props => /*#__PURE__*/React.createElement("textarea", _extends({}, props, {
|
|
67
|
+
onKeyDown: handleKeyDown,
|
|
68
|
+
rows: 3
|
|
69
|
+
})), [handleKeyDown]);
|
|
70
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
71
|
+
className: classNames(styles.composer, className)
|
|
72
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
73
|
+
className: styles.inputWrapper
|
|
74
|
+
}, /*#__PURE__*/React.createElement(Input, {
|
|
75
|
+
"aria-label": "Message input",
|
|
76
|
+
className: styles.textarea,
|
|
77
|
+
onValueChange: setDraft,
|
|
78
|
+
placeholder: placeholder,
|
|
79
|
+
value: draft,
|
|
80
|
+
render: renderTextarea
|
|
81
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
82
|
+
className: styles.inputActions
|
|
83
|
+
}, isInFlight && onStop != null ? /*#__PURE__*/React.createElement(ActionButton, {
|
|
84
|
+
onClick: onStop,
|
|
85
|
+
type: "button"
|
|
86
|
+
}, "Stop") : /*#__PURE__*/React.createElement(ActionButton, {
|
|
87
|
+
disabled: !canSend,
|
|
88
|
+
onClick: handleSend,
|
|
89
|
+
type: "button",
|
|
90
|
+
variant: "primary"
|
|
91
|
+
}, "Send"))), footerLeft != null && /*#__PURE__*/React.createElement("div", {
|
|
92
|
+
className: styles.composerFooterLeft
|
|
93
|
+
}, footerLeft));
|
|
94
|
+
}
|
|
95
|
+
function noop() {}
|
|
96
|
+
//# sourceMappingURL=AipAgentChatComposer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AipAgentChatComposer.js","names":["Input","classNames","React","ActionButton","styles","AipAgentChatComposer","isInFlight","onSendMessage","onStop","placeholder","className","footerLeft","draft","setDraft","useState","canSend","trim","length","handleSend","useCallback","trimmed","result","Promise","catch","noop","handleKeyDown","event","key","shiftKey","preventDefault","renderTextarea","props","createElement","_extends","onKeyDown","rows","composer","inputWrapper","textarea","onValueChange","value","render","inputActions","onClick","type","disabled","variant","composerFooterLeft"],"sources":["AipAgentChatComposer.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 { Input } from \"@base-ui/react/input\";\nimport classNames from \"classnames\";\nimport * as React from \"react\";\nimport { ActionButton } from \"../../base-components/action-button/ActionButton.js\";\nimport styles from \"../AipAgentChat.module.css\";\n\nexport interface AipAgentChatComposerProps {\n isInFlight: boolean;\n onSendMessage: (text: string) => void;\n onStop?: () => void;\n placeholder?: string;\n className?: string;\n /**\n * Optional content rendered to the left of the send button (e.g. the\n * model picker passed in by the OSDK wrapper).\n */\n footerLeft?: React.ReactNode;\n}\n\n/**\n * Textarea + send/stop button. Enter sends; Shift+Enter inserts a newline.\n * The button toggles to \"Stop\" while a stream is in flight (when an\n * `onStop` callback is provided).\n */\nexport function AipAgentChatComposer({\n isInFlight,\n onSendMessage,\n onStop,\n placeholder,\n className,\n footerLeft,\n}: AipAgentChatComposerProps): React.ReactElement {\n const [draft, setDraft] = React.useState(\"\");\n\n const canSend = !isInFlight && draft.trim().length > 0;\n\n const handleSend = React.useCallback(() => {\n const trimmed = draft.trim();\n if (trimmed.length === 0) {\n return;\n }\n // Absorb sync throws and unhandled rejections; chat-level errors are\n // surfaced via `onError` on the upstream useChat hook.\n try {\n const result = onSendMessage(trimmed) as void | Promise<void>;\n if (result instanceof Promise) {\n result.catch(noop);\n }\n } catch {\n // swallow sync throws\n }\n setDraft(\"\");\n }, [draft, onSendMessage]);\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n if (!isInFlight) {\n handleSend();\n }\n }\n },\n [handleSend, isInFlight],\n );\n\n // Attach the keydown handler in the `render` prop so it can be typed against\n // the actual rendered <textarea> element rather than base-ui's HTMLInputElement.\n const renderTextarea = React.useCallback(\n (props: React.ComponentPropsWithRef<\"textarea\">) => (\n <textarea {...props} onKeyDown={handleKeyDown} rows={3} />\n ),\n [handleKeyDown],\n );\n\n return (\n <div className={classNames(styles.composer, className)}>\n <div className={styles.inputWrapper}>\n <Input\n aria-label=\"Message input\"\n className={styles.textarea}\n onValueChange={setDraft}\n placeholder={placeholder}\n value={draft}\n render={renderTextarea}\n />\n <div className={styles.inputActions}>\n {isInFlight && onStop != null\n ? (\n <ActionButton onClick={onStop} type=\"button\">\n Stop\n </ActionButton>\n )\n : (\n <ActionButton\n disabled={!canSend}\n onClick={handleSend}\n type=\"button\"\n variant=\"primary\"\n >\n Send\n </ActionButton>\n )}\n </div>\n </div>\n {footerLeft != null && (\n <div className={styles.composerFooterLeft}>{footerLeft}</div>\n )}\n </div>\n );\n}\n\nfunction noop(): void {}\n"],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,KAAK,QAAQ,sBAAsB;AAC5C,OAAOC,UAAU,MAAM,YAAY;AACnC,OAAO,KAAKC,KAAK,MAAM,OAAO;AAC9B,SAASC,YAAY,QAAQ,qDAAqD;AAClF,OAAOC,MAAM,MAAM,4BAA4B;AAe/C;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,oBAAoBA,CAAC;EACnCC,UAAU;EACVC,aAAa;EACbC,MAAM;EACNC,WAAW;EACXC,SAAS;EACTC;AACyB,CAAC,EAAsB;EAChD,MAAM,CAACC,KAAK,EAAEC,QAAQ,CAAC,GAAGX,KAAK,CAACY,QAAQ,CAAC,EAAE,CAAC;EAE5C,MAAMC,OAAO,GAAG,CAACT,UAAU,IAAIM,KAAK,CAACI,IAAI,CAAC,CAAC,CAACC,MAAM,GAAG,CAAC;EAEtD,MAAMC,UAAU,GAAGhB,KAAK,CAACiB,WAAW,CAAC,MAAM;IACzC,MAAMC,OAAO,GAAGR,KAAK,CAACI,IAAI,CAAC,CAAC;IAC5B,IAAII,OAAO,CAACH,MAAM,KAAK,CAAC,EAAE;MACxB;IACF;IACA;IACA;IACA,IAAI;MACF,MAAMI,MAAM,GAAGd,aAAa,CAACa,OAAO,CAAyB;MAC7D,IAAIC,MAAM,YAAYC,OAAO,EAAE;QAC7BD,MAAM,CAACE,KAAK,CAACC,IAAI,CAAC;MACpB;IACF,CAAC,CAAC,MAAM;MACN;IAAA;IAEFX,QAAQ,CAAC,EAAE,CAAC;EACd,CAAC,EAAE,CAACD,KAAK,EAAEL,aAAa,CAAC,CAAC;EAE1B,MAAMkB,aAAa,GAAGvB,KAAK,CAACiB,WAAW,CACpCO,KAA+C,IAAK;IACnD,IAAIA,KAAK,CAACC,GAAG,KAAK,OAAO,IAAI,CAACD,KAAK,CAACE,QAAQ,EAAE;MAC5CF,KAAK,CAACG,cAAc,CAAC,CAAC;MACtB,IAAI,CAACvB,UAAU,EAAE;QACfY,UAAU,CAAC,CAAC;MACd;IACF;EACF,CAAC,EACD,CAACA,UAAU,EAAEZ,UAAU,CACzB,CAAC;;EAED;EACA;EACA,MAAMwB,cAAc,GAAG5B,KAAK,CAACiB,WAAW,CACrCY,KAA8C,iBAC7C7B,KAAA,CAAA8B,aAAA,aAAAC,QAAA,KAAcF,KAAK;IAAEG,SAAS,EAAET,aAAc;IAACU,IAAI,EAAE;EAAE,EAAE,CAC1D,EACD,CAACV,aAAa,CAChB,CAAC;EAED,oBACEvB,KAAA,CAAA8B,aAAA;IAAKtB,SAAS,EAAET,UAAU,CAACG,MAAM,CAACgC,QAAQ,EAAE1B,SAAS;EAAE,gBACrDR,KAAA,CAAA8B,aAAA;IAAKtB,SAAS,EAAEN,MAAM,CAACiC;EAAa,gBAClCnC,KAAA,CAAA8B,aAAA,CAAChC,KAAK;IACJ,cAAW,eAAe;IAC1BU,SAAS,EAAEN,MAAM,CAACkC,QAAS;IAC3BC,aAAa,EAAE1B,QAAS;IACxBJ,WAAW,EAAEA,WAAY;IACzB+B,KAAK,EAAE5B,KAAM;IACb6B,MAAM,EAAEX;EAAe,CACxB,CAAC,eACF5B,KAAA,CAAA8B,aAAA;IAAKtB,SAAS,EAAEN,MAAM,CAACsC;EAAa,GACjCpC,UAAU,IAAIE,MAAM,IAAI,IAAI,gBAEzBN,KAAA,CAAA8B,aAAA,CAAC7B,YAAY;IAACwC,OAAO,EAAEnC,MAAO;IAACoC,IAAI,EAAC;EAAQ,GAAC,MAE/B,CAAC,gBAGf1C,KAAA,CAAA8B,aAAA,CAAC7B,YAAY;IACX0C,QAAQ,EAAE,CAAC9B,OAAQ;IACnB4B,OAAO,EAAEzB,UAAW;IACpB0B,IAAI,EAAC,QAAQ;IACbE,OAAO,EAAC;EAAS,GAClB,MAEa,CAEf,CACF,CAAC,EACLnC,UAAU,IAAI,IAAI,iBACjBT,KAAA,CAAA8B,aAAA;IAAKtB,SAAS,EAAEN,MAAM,CAAC2C;EAAmB,GAAEpC,UAAgB,CAE3D,CAAC;AAEV;AAEA,SAASa,IAAIA,CAAA,EAAS,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,43 @@
|
|
|
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 styles from "../AipAgentChat.module.css";
|
|
20
|
+
/**
|
|
21
|
+
* Three-dot bouncing animation rendered while the agent is responding.
|
|
22
|
+
*/
|
|
23
|
+
export function AipAgentChatLoader({
|
|
24
|
+
className,
|
|
25
|
+
label = "Assistant is responding"
|
|
26
|
+
}) {
|
|
27
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
28
|
+
"aria-label": label,
|
|
29
|
+
"aria-live": "polite",
|
|
30
|
+
className: classNames(styles.loader, className),
|
|
31
|
+
role: "status"
|
|
32
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
33
|
+
"aria-hidden": "true",
|
|
34
|
+
className: styles.loaderDot
|
|
35
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
36
|
+
"aria-hidden": "true",
|
|
37
|
+
className: styles.loaderDot
|
|
38
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
39
|
+
"aria-hidden": "true",
|
|
40
|
+
className: styles.loaderDot
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=AipAgentChatLoader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AipAgentChatLoader.js","names":["classNames","React","styles","AipAgentChatLoader","className","label","createElement","loader","role","loaderDot"],"sources":["AipAgentChatLoader.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 classNames from \"classnames\";\nimport * as React from \"react\";\nimport styles from \"../AipAgentChat.module.css\";\n\nexport interface AipAgentChatLoaderProps {\n className?: string;\n label?: string;\n}\n\n/**\n * Three-dot bouncing animation rendered while the agent is responding.\n */\nexport function AipAgentChatLoader(\n { className, label = \"Assistant is responding\" }: AipAgentChatLoaderProps,\n): React.ReactElement {\n return (\n <div\n aria-label={label}\n aria-live=\"polite\"\n className={classNames(styles.loader, className)}\n role=\"status\"\n >\n <span aria-hidden=\"true\" className={styles.loaderDot} />\n <span aria-hidden=\"true\" className={styles.loaderDot} />\n <span aria-hidden=\"true\" className={styles.loaderDot} />\n </div>\n );\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAOA,UAAU,MAAM,YAAY;AACnC,OAAO,KAAKC,KAAK,MAAM,OAAO;AAC9B,OAAOC,MAAM,MAAM,4BAA4B;AAO/C;AACA;AACA;AACA,OAAO,SAASC,kBAAkBA,CAChC;EAAEC,SAAS;EAAEC,KAAK,GAAG;AAAmD,CAAC,EACrD;EACpB,oBACEJ,KAAA,CAAAK,aAAA;IACE,cAAYD,KAAM;IAClB,aAAU,QAAQ;IAClBD,SAAS,EAAEJ,UAAU,CAACE,MAAM,CAACK,MAAM,EAAEH,SAAS,CAAE;IAChDI,IAAI,EAAC;EAAQ,gBAEbP,KAAA,CAAAK,aAAA;IAAM,eAAY,MAAM;IAACF,SAAS,EAAEF,MAAM,CAACO;EAAU,CAAE,CAAC,eACxDR,KAAA,CAAAK,aAAA;IAAM,eAAY,MAAM;IAACF,SAAS,EAAEF,MAAM,CAACO;EAAU,CAAE,CAAC,eACxDR,KAAA,CAAAK,aAAA;IAAM,eAAY,MAAM;IAACF,SAAS,EAAEF,MAAM,CAACO;EAAU,CAAE,CACpD,CAAC;AAEV","ignoreList":[]}
|
|
@@ -0,0 +1,60 @@
|
|
|
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 { getUIMessageText } from "@osdk/aip-core";
|
|
18
|
+
import classNames from "classnames";
|
|
19
|
+
import * as React from "react";
|
|
20
|
+
import styles from "../AipAgentChat.module.css";
|
|
21
|
+
/**
|
|
22
|
+
* Default rendering for a single chat message bubble. User messages are
|
|
23
|
+
* right-aligned with a primary background; assistant messages are
|
|
24
|
+
* left-aligned with a secondary background; system messages render
|
|
25
|
+
* centered in muted style.
|
|
26
|
+
*/
|
|
27
|
+
export function AipAgentChatMessage({
|
|
28
|
+
message
|
|
29
|
+
}) {
|
|
30
|
+
const text = getUIMessageText(message);
|
|
31
|
+
const role = message.role;
|
|
32
|
+
const styling = ROLE_STYLING[role];
|
|
33
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
34
|
+
"aria-label": styling.label,
|
|
35
|
+
className: classNames(styles.message, styling.container),
|
|
36
|
+
role: "group"
|
|
37
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
38
|
+
className: classNames(styles.bubble, styling.bubble)
|
|
39
|
+
}, text.length > 0 ? text : /*#__PURE__*/React.createElement("span", {
|
|
40
|
+
className: styles.streamingPlaceholder
|
|
41
|
+
}, "\u2026")));
|
|
42
|
+
}
|
|
43
|
+
const ROLE_STYLING = {
|
|
44
|
+
user: {
|
|
45
|
+
container: styles.userMessage,
|
|
46
|
+
bubble: styles.userBubble,
|
|
47
|
+
label: "User message"
|
|
48
|
+
},
|
|
49
|
+
assistant: {
|
|
50
|
+
container: styles.assistantMessage,
|
|
51
|
+
bubble: styles.assistantBubble,
|
|
52
|
+
label: "Assistant message"
|
|
53
|
+
},
|
|
54
|
+
system: {
|
|
55
|
+
container: styles.systemMessage,
|
|
56
|
+
bubble: styles.systemBubble,
|
|
57
|
+
label: "System message"
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=AipAgentChatMessage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AipAgentChatMessage.js","names":["getUIMessageText","classNames","React","styles","AipAgentChatMessage","message","text","role","styling","ROLE_STYLING","createElement","label","className","container","bubble","length","streamingPlaceholder","user","userMessage","userBubble","assistant","assistantMessage","assistantBubble","system","systemMessage","systemBubble"],"sources":["AipAgentChatMessage.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 { getUIMessageText, type UIMessage } from \"@osdk/aip-core\";\nimport classNames from \"classnames\";\nimport * as React from \"react\";\nimport styles from \"../AipAgentChat.module.css\";\n\nexport interface AipAgentChatMessageProps {\n message: UIMessage;\n}\n\n/**\n * Default rendering for a single chat message bubble. User messages are\n * right-aligned with a primary background; assistant messages are\n * left-aligned with a secondary background; system messages render\n * centered in muted style.\n */\nexport function AipAgentChatMessage(\n { message }: AipAgentChatMessageProps,\n): React.ReactElement {\n const text = getUIMessageText(message);\n const role = message.role;\n const styling = ROLE_STYLING[role];\n\n return (\n <div\n aria-label={styling.label}\n className={classNames(styles.message, styling.container)}\n role=\"group\"\n >\n <div className={classNames(styles.bubble, styling.bubble)}>\n {text.length > 0\n ? text\n : <span className={styles.streamingPlaceholder}>…</span>}\n </div>\n </div>\n );\n}\n\ninterface RoleStyling {\n container: string;\n bubble: string;\n label: string;\n}\n\nconst ROLE_STYLING: Record<UIMessage[\"role\"], RoleStyling> = {\n user: {\n container: styles.userMessage,\n bubble: styles.userBubble,\n label: \"User message\",\n },\n assistant: {\n container: styles.assistantMessage,\n bubble: styles.assistantBubble,\n label: \"Assistant message\",\n },\n system: {\n container: styles.systemMessage,\n bubble: styles.systemBubble,\n label: \"System message\",\n },\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,gBAAgB,QAAwB,gBAAgB;AACjE,OAAOC,UAAU,MAAM,YAAY;AACnC,OAAO,KAAKC,KAAK,MAAM,OAAO;AAC9B,OAAOC,MAAM,MAAM,4BAA4B;AAM/C;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,mBAAmBA,CACjC;EAAEC;AAAkC,CAAC,EACjB;EACpB,MAAMC,IAAI,GAAGN,gBAAgB,CAACK,OAAO,CAAC;EACtC,MAAME,IAAI,GAAGF,OAAO,CAACE,IAAI;EACzB,MAAMC,OAAO,GAAGC,YAAY,CAACF,IAAI,CAAC;EAElC,oBACEL,KAAA,CAAAQ,aAAA;IACE,cAAYF,OAAO,CAACG,KAAM;IAC1BC,SAAS,EAAEX,UAAU,CAACE,MAAM,CAACE,OAAO,EAAEG,OAAO,CAACK,SAAS,CAAE;IACzDN,IAAI,EAAC;EAAO,gBAEZL,KAAA,CAAAQ,aAAA;IAAKE,SAAS,EAAEX,UAAU,CAACE,MAAM,CAACW,MAAM,EAAEN,OAAO,CAACM,MAAM;EAAE,GACvDR,IAAI,CAACS,MAAM,GAAG,CAAC,GACZT,IAAI,gBACJJ,KAAA,CAAAQ,aAAA;IAAME,SAAS,EAAET,MAAM,CAACa;EAAqB,GAAC,QAAO,CACtD,CACF,CAAC;AAEV;AAQA,MAAMP,YAAoD,GAAG;EAC3DQ,IAAI,EAAE;IACJJ,SAAS,EAAEV,MAAM,CAACe,WAAW;IAC7BJ,MAAM,EAAEX,MAAM,CAACgB,UAAU;IACzBR,KAAK,EAAE;EACT,CAAC;EACDS,SAAS,EAAE;IACTP,SAAS,EAAEV,MAAM,CAACkB,gBAAgB;IAClCP,MAAM,EAAEX,MAAM,CAACmB,eAAe;IAC9BX,KAAK,EAAE;EACT,CAAC;EACDY,MAAM,EAAE;IACNV,SAAS,EAAEV,MAAM,CAACqB,aAAa;IAC/BV,MAAM,EAAEX,MAAM,CAACsB,YAAY;IAC3Bd,KAAK,EAAE;EACT;AACF,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,60 @@
|
|
|
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 { Chat } from "@blueprintjs/icons";
|
|
18
|
+
import { getUIMessageText } from "@osdk/aip-core";
|
|
19
|
+
import classNames from "classnames";
|
|
20
|
+
import * as React from "react";
|
|
21
|
+
import styles from "../AipAgentChat.module.css";
|
|
22
|
+
import { useChatAutoScroll } from "../hooks/useChatAutoScroll.js";
|
|
23
|
+
import { AipAgentChatLoader } from "./AipAgentChatLoader.js";
|
|
24
|
+
import { AipAgentChatMessage } from "./AipAgentChatMessage.js";
|
|
25
|
+
const DEFAULT_EMPTY_STATE = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Chat, {
|
|
26
|
+
className: styles.emptyIcon,
|
|
27
|
+
size: 64
|
|
28
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
29
|
+
className: styles.emptyTitle
|
|
30
|
+
}, "Start a conversation"), /*#__PURE__*/React.createElement("div", null, "Type a message below to chat with the assistant."));
|
|
31
|
+
export function AipAgentChatMessageList({
|
|
32
|
+
messages,
|
|
33
|
+
isStreaming,
|
|
34
|
+
enableAutoScroll,
|
|
35
|
+
className,
|
|
36
|
+
renderEmptyState,
|
|
37
|
+
renderMessage
|
|
38
|
+
}) {
|
|
39
|
+
const lastMessage = messages.at(-1);
|
|
40
|
+
const lastMessageTextLength = lastMessage != null ? getUIMessageText(lastMessage).length : 0;
|
|
41
|
+
const scrollSignal = `${messages.length}:${lastMessageTextLength}`;
|
|
42
|
+
const setContainerRef = useChatAutoScroll(scrollSignal, enableAutoScroll);
|
|
43
|
+
const isEmpty = messages.length === 0 && !isStreaming;
|
|
44
|
+
const showLoader = isStreaming && lastMessage?.role !== "assistant";
|
|
45
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
46
|
+
"aria-live": isEmpty ? undefined : "polite",
|
|
47
|
+
className: classNames(styles.messageList, isEmpty && styles.empty, className),
|
|
48
|
+
ref: setContainerRef,
|
|
49
|
+
role: isEmpty ? undefined : "log"
|
|
50
|
+
}, isEmpty ? renderEmptyState != null ? renderEmptyState() : DEFAULT_EMPTY_STATE : /*#__PURE__*/React.createElement(React.Fragment, null, messages.map(message => /*#__PURE__*/React.createElement(React.Fragment, {
|
|
51
|
+
key: message.id
|
|
52
|
+
}, renderMessage != null ? renderMessage(message) : /*#__PURE__*/React.createElement(AipAgentChatMessage, {
|
|
53
|
+
message: message
|
|
54
|
+
}))), showLoader && /*#__PURE__*/React.createElement("div", {
|
|
55
|
+
className: classNames(styles.message, styles.assistantMessage)
|
|
56
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
57
|
+
className: classNames(styles.bubble, styles.assistantBubble)
|
|
58
|
+
}, /*#__PURE__*/React.createElement(AipAgentChatLoader, null)))));
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=AipAgentChatMessageList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AipAgentChatMessageList.js","names":["Chat","getUIMessageText","classNames","React","styles","useChatAutoScroll","AipAgentChatLoader","AipAgentChatMessage","DEFAULT_EMPTY_STATE","createElement","Fragment","className","emptyIcon","size","emptyTitle","AipAgentChatMessageList","messages","isStreaming","enableAutoScroll","renderEmptyState","renderMessage","lastMessage","at","lastMessageTextLength","length","scrollSignal","setContainerRef","isEmpty","showLoader","role","undefined","messageList","empty","ref","map","message","key","id","assistantMessage","bubble","assistantBubble"],"sources":["AipAgentChatMessageList.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 { Chat } from \"@blueprintjs/icons\";\nimport { getUIMessageText, type UIMessage } from \"@osdk/aip-core\";\nimport classNames from \"classnames\";\nimport * as React from \"react\";\nimport styles from \"../AipAgentChat.module.css\";\nimport { useChatAutoScroll } from \"../hooks/useChatAutoScroll.js\";\nimport { AipAgentChatLoader } from \"./AipAgentChatLoader.js\";\nimport { AipAgentChatMessage } from \"./AipAgentChatMessage.js\";\n\nexport interface AipAgentChatMessageListProps {\n messages: ReadonlyArray<UIMessage>;\n isStreaming: boolean;\n enableAutoScroll: boolean;\n className?: string;\n renderEmptyState?: () => React.ReactNode;\n renderMessage?: (message: UIMessage) => React.ReactNode;\n}\n\nconst DEFAULT_EMPTY_STATE: React.ReactNode = (\n <>\n <Chat className={styles.emptyIcon} size={64} />\n <div className={styles.emptyTitle}>Start a conversation</div>\n <div>Type a message below to chat with the assistant.</div>\n </>\n);\n\nexport function AipAgentChatMessageList({\n messages,\n isStreaming,\n enableAutoScroll,\n className,\n renderEmptyState,\n renderMessage,\n}: AipAgentChatMessageListProps): React.ReactElement {\n const lastMessage = messages.at(-1);\n const lastMessageTextLength = lastMessage != null\n ? getUIMessageText(lastMessage).length\n : 0;\n const scrollSignal = `${messages.length}:${lastMessageTextLength}`;\n\n const setContainerRef = useChatAutoScroll<HTMLDivElement>(\n scrollSignal,\n enableAutoScroll,\n );\n\n const isEmpty = messages.length === 0 && !isStreaming;\n const showLoader = isStreaming && lastMessage?.role !== \"assistant\";\n\n return (\n <div\n aria-live={isEmpty ? undefined : \"polite\"}\n className={classNames(\n styles.messageList,\n isEmpty && styles.empty,\n className,\n )}\n ref={setContainerRef}\n role={isEmpty ? undefined : \"log\"}\n >\n {isEmpty\n ? (renderEmptyState != null ? renderEmptyState() : DEFAULT_EMPTY_STATE)\n : (\n <>\n {messages.map(message => (\n <React.Fragment key={message.id}>\n {renderMessage != null\n ? renderMessage(message)\n : <AipAgentChatMessage message={message} />}\n </React.Fragment>\n ))}\n {showLoader && (\n <div\n className={classNames(styles.message, styles.assistantMessage)}\n >\n <div\n className={classNames(styles.bubble, styles.assistantBubble)}\n >\n <AipAgentChatLoader />\n </div>\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,IAAI,QAAQ,oBAAoB;AACzC,SAASC,gBAAgB,QAAwB,gBAAgB;AACjE,OAAOC,UAAU,MAAM,YAAY;AACnC,OAAO,KAAKC,KAAK,MAAM,OAAO;AAC9B,OAAOC,MAAM,MAAM,4BAA4B;AAC/C,SAASC,iBAAiB,QAAQ,+BAA+B;AACjE,SAASC,kBAAkB,QAAQ,yBAAyB;AAC5D,SAASC,mBAAmB,QAAQ,0BAA0B;AAW9D,MAAMC,mBAAoC,gBACxCL,KAAA,CAAAM,aAAA,CAAAN,KAAA,CAAAO,QAAA,qBACEP,KAAA,CAAAM,aAAA,CAACT,IAAI;EAACW,SAAS,EAAEP,MAAM,CAACQ,SAAU;EAACC,IAAI,EAAE;AAAG,CAAE,CAAC,eAC/CV,KAAA,CAAAM,aAAA;EAAKE,SAAS,EAAEP,MAAM,CAACU;AAAW,GAAC,sBAAyB,CAAC,eAC7DX,KAAA,CAAAM,aAAA,cAAK,kDAAqD,CAC1D,CACH;AAED,OAAO,SAASM,uBAAuBA,CAAC;EACtCC,QAAQ;EACRC,WAAW;EACXC,gBAAgB;EAChBP,SAAS;EACTQ,gBAAgB;EAChBC;AAC4B,CAAC,EAAsB;EACnD,MAAMC,WAAW,GAAGL,QAAQ,CAACM,EAAE,CAAC,CAAC,CAAC,CAAC;EACnC,MAAMC,qBAAqB,GAAGF,WAAW,IAAI,IAAI,GAC7CpB,gBAAgB,CAACoB,WAAW,CAAC,CAACG,MAAM,GACpC,CAAC;EACL,MAAMC,YAAY,GAAG,GAAGT,QAAQ,CAACQ,MAAM,IAAID,qBAAqB,EAAE;EAElE,MAAMG,eAAe,GAAGrB,iBAAiB,CACvCoB,YAAY,EACZP,gBACF,CAAC;EAED,MAAMS,OAAO,GAAGX,QAAQ,CAACQ,MAAM,KAAK,CAAC,IAAI,CAACP,WAAW;EACrD,MAAMW,UAAU,GAAGX,WAAW,IAAII,WAAW,EAAEQ,IAAI,KAAK,WAAW;EAEnE,oBACE1B,KAAA,CAAAM,aAAA;IACE,aAAWkB,OAAO,GAAGG,SAAS,GAAG,QAAS;IAC1CnB,SAAS,EAAET,UAAU,CACnBE,MAAM,CAAC2B,WAAW,EAClBJ,OAAO,IAAIvB,MAAM,CAAC4B,KAAK,EACvBrB,SACF,CAAE;IACFsB,GAAG,EAAEP,eAAgB;IACrBG,IAAI,EAAEF,OAAO,GAAGG,SAAS,GAAG;EAAM,GAEjCH,OAAO,GACHR,gBAAgB,IAAI,IAAI,GAAGA,gBAAgB,CAAC,CAAC,GAAGX,mBAAmB,gBAEpEL,KAAA,CAAAM,aAAA,CAAAN,KAAA,CAAAO,QAAA,QACGM,QAAQ,CAACkB,GAAG,CAACC,OAAO,iBACnBhC,KAAA,CAAAM,aAAA,CAACN,KAAK,CAACO,QAAQ;IAAC0B,GAAG,EAAED,OAAO,CAACE;EAAG,GAC7BjB,aAAa,IAAI,IAAI,GAClBA,aAAa,CAACe,OAAO,CAAC,gBACtBhC,KAAA,CAAAM,aAAA,CAACF,mBAAmB;IAAC4B,OAAO,EAAEA;EAAQ,CAAE,CAC9B,CACjB,CAAC,EACDP,UAAU,iBACTzB,KAAA,CAAAM,aAAA;IACEE,SAAS,EAAET,UAAU,CAACE,MAAM,CAAC+B,OAAO,EAAE/B,MAAM,CAACkC,gBAAgB;EAAE,gBAE/DnC,KAAA,CAAAM,aAAA;IACEE,SAAS,EAAET,UAAU,CAACE,MAAM,CAACmC,MAAM,EAAEnC,MAAM,CAACoC,eAAe;EAAE,gBAE7DrC,KAAA,CAAAM,aAAA,CAACH,kBAAkB,MAAE,CAClB,CACF,CAEP,CAEH,CAAC;AAEV","ignoreList":[]}
|
|
@@ -0,0 +1,56 @@
|
|
|
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 styles from "../AipAgentChat.module.css";
|
|
20
|
+
/**
|
|
21
|
+
* Native-select model picker rendered in the composer footer when the
|
|
22
|
+
* OSDK wrapper is given an `availableModels` list. Operates on Foundry
|
|
23
|
+
* LMS model API names. Renders a read-only label when exactly one model
|
|
24
|
+
* is available so the active model stays visible without offering a
|
|
25
|
+
* dropdown the user can't act on; renders nothing when the list is empty.
|
|
26
|
+
*/
|
|
27
|
+
export function AipAgentChatModelPicker({
|
|
28
|
+
models,
|
|
29
|
+
activeModel,
|
|
30
|
+
onModelChange,
|
|
31
|
+
disabled,
|
|
32
|
+
className
|
|
33
|
+
}) {
|
|
34
|
+
const handleChange = React.useCallback(event => {
|
|
35
|
+
onModelChange(event.target.value);
|
|
36
|
+
}, [onModelChange]);
|
|
37
|
+
if (models.length === 0) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
if (models.length === 1) {
|
|
41
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
42
|
+
className: classNames(styles.modelPickerLabel, className)
|
|
43
|
+
}, "Model: ", activeModel);
|
|
44
|
+
}
|
|
45
|
+
return /*#__PURE__*/React.createElement("select", {
|
|
46
|
+
"aria-label": "Active model",
|
|
47
|
+
className: classNames(styles.modelPicker, className),
|
|
48
|
+
disabled: disabled,
|
|
49
|
+
onChange: handleChange,
|
|
50
|
+
value: activeModel
|
|
51
|
+
}, models.map(modelName => /*#__PURE__*/React.createElement("option", {
|
|
52
|
+
key: modelName,
|
|
53
|
+
value: modelName
|
|
54
|
+
}, modelName)));
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=AipAgentChatModelPicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AipAgentChatModelPicker.js","names":["classNames","React","styles","AipAgentChatModelPicker","models","activeModel","onModelChange","disabled","className","handleChange","useCallback","event","target","value","length","createElement","modelPickerLabel","modelPicker","onChange","map","modelName","key"],"sources":["AipAgentChatModelPicker.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 classNames from \"classnames\";\nimport * as React from \"react\";\nimport styles from \"../AipAgentChat.module.css\";\n\nexport interface AipAgentChatModelPickerProps {\n models: ReadonlyArray<string>;\n activeModel: string;\n onModelChange: (model: string) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * Native-select model picker rendered in the composer footer when the\n * OSDK wrapper is given an `availableModels` list. Operates on Foundry\n * LMS model API names. Renders a read-only label when exactly one model\n * is available so the active model stays visible without offering a\n * dropdown the user can't act on; renders nothing when the list is empty.\n */\nexport function AipAgentChatModelPicker({\n models,\n activeModel,\n onModelChange,\n disabled,\n className,\n}: AipAgentChatModelPickerProps): React.ReactElement | null {\n const handleChange = React.useCallback(\n (event: React.ChangeEvent<HTMLSelectElement>) => {\n onModelChange(event.target.value);\n },\n [onModelChange],\n );\n\n if (models.length === 0) {\n return null;\n }\n\n if (models.length === 1) {\n return (\n <span className={classNames(styles.modelPickerLabel, className)}>\n Model: {activeModel}\n </span>\n );\n }\n\n return (\n <select\n aria-label=\"Active model\"\n className={classNames(styles.modelPicker, className)}\n disabled={disabled}\n onChange={handleChange}\n value={activeModel}\n >\n {models.map(modelName => (\n <option key={modelName} value={modelName}>\n {modelName}\n </option>\n ))}\n </select>\n );\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAOA,UAAU,MAAM,YAAY;AACnC,OAAO,KAAKC,KAAK,MAAM,OAAO;AAC9B,OAAOC,MAAM,MAAM,4BAA4B;AAU/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,uBAAuBA,CAAC;EACtCC,MAAM;EACNC,WAAW;EACXC,aAAa;EACbC,QAAQ;EACRC;AAC4B,CAAC,EAA6B;EAC1D,MAAMC,YAAY,GAAGR,KAAK,CAACS,WAAW,CACnCC,KAA2C,IAAK;IAC/CL,aAAa,CAACK,KAAK,CAACC,MAAM,CAACC,KAAK,CAAC;EACnC,CAAC,EACD,CAACP,aAAa,CAChB,CAAC;EAED,IAAIF,MAAM,CAACU,MAAM,KAAK,CAAC,EAAE;IACvB,OAAO,IAAI;EACb;EAEA,IAAIV,MAAM,CAACU,MAAM,KAAK,CAAC,EAAE;IACvB,oBACEb,KAAA,CAAAc,aAAA;MAAMP,SAAS,EAAER,UAAU,CAACE,MAAM,CAACc,gBAAgB,EAAER,SAAS;IAAE,GAAC,SACxD,EAACH,WACJ,CAAC;EAEX;EAEA,oBACEJ,KAAA,CAAAc,aAAA;IACE,cAAW,cAAc;IACzBP,SAAS,EAAER,UAAU,CAACE,MAAM,CAACe,WAAW,EAAET,SAAS,CAAE;IACrDD,QAAQ,EAAEA,QAAS;IACnBW,QAAQ,EAAET,YAAa;IACvBI,KAAK,EAAER;EAAY,GAElBD,MAAM,CAACe,GAAG,CAACC,SAAS,iBACnBnB,KAAA,CAAAc,aAAA;IAAQM,GAAG,EAAED,SAAU;IAACP,KAAK,EAAEO;EAAU,GACtCA,SACK,CACT,CACK,CAAC;AAEb","ignoreList":[]}
|
|
@@ -0,0 +1,61 @@
|
|
|
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 * as React from "react";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Keeps a scrollable container pinned to its bottom whenever `signal` changes
|
|
21
|
+
* (typically a string encoding the messages array length and streaming token
|
|
22
|
+
* count).
|
|
23
|
+
*
|
|
24
|
+
* Disengages temporarily once the user scrolls up — pinning resumes when the
|
|
25
|
+
* user scrolls back near the bottom. Returns a callback ref to attach to the
|
|
26
|
+
* scrollable element; the listener follows the element across re-mounts.
|
|
27
|
+
*/
|
|
28
|
+
export function useChatAutoScroll(signal, enabled) {
|
|
29
|
+
const elRef = React.useRef(null);
|
|
30
|
+
const cleanupRef = React.useRef(null);
|
|
31
|
+
const isPinnedRef = React.useRef(true);
|
|
32
|
+
const setRef = React.useCallback(el => {
|
|
33
|
+
cleanupRef.current?.();
|
|
34
|
+
cleanupRef.current = null;
|
|
35
|
+
elRef.current = el;
|
|
36
|
+
if (el == null) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const onScroll = () => {
|
|
40
|
+
const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;
|
|
41
|
+
isPinnedRef.current = distanceFromBottom <= NEAR_BOTTOM_THRESHOLD_PX;
|
|
42
|
+
};
|
|
43
|
+
el.addEventListener("scroll", onScroll, {
|
|
44
|
+
passive: true
|
|
45
|
+
});
|
|
46
|
+
cleanupRef.current = () => el.removeEventListener("scroll", onScroll);
|
|
47
|
+
}, []);
|
|
48
|
+
React.useEffect(() => {
|
|
49
|
+
if (!enabled) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const el = elRef.current;
|
|
53
|
+
if (el == null || !isPinnedRef.current) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
el.scrollTop = el.scrollHeight;
|
|
57
|
+
}, [signal, enabled]);
|
|
58
|
+
return setRef;
|
|
59
|
+
}
|
|
60
|
+
const NEAR_BOTTOM_THRESHOLD_PX = 32;
|
|
61
|
+
//# sourceMappingURL=useChatAutoScroll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChatAutoScroll.js","names":["React","useChatAutoScroll","signal","enabled","elRef","useRef","cleanupRef","isPinnedRef","setRef","useCallback","el","current","onScroll","distanceFromBottom","scrollHeight","scrollTop","clientHeight","NEAR_BOTTOM_THRESHOLD_PX","addEventListener","passive","removeEventListener","useEffect"],"sources":["useChatAutoScroll.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 * as React from \"react\";\n\n/**\n * Keeps a scrollable container pinned to its bottom whenever `signal` changes\n * (typically a string encoding the messages array length and streaming token\n * count).\n *\n * Disengages temporarily once the user scrolls up — pinning resumes when the\n * user scrolls back near the bottom. Returns a callback ref to attach to the\n * scrollable element; the listener follows the element across re-mounts.\n */\nexport function useChatAutoScroll<T extends HTMLElement>(\n signal: string,\n enabled: boolean,\n): React.RefCallback<T> {\n const elRef = React.useRef<T | null>(null);\n const cleanupRef = React.useRef<(() => void) | null>(null);\n const isPinnedRef = React.useRef<boolean>(true);\n\n const setRef = React.useCallback<React.RefCallback<T>>((el) => {\n cleanupRef.current?.();\n cleanupRef.current = null;\n elRef.current = el;\n if (el == null) {\n return;\n }\n const onScroll = () => {\n const distanceFromBottom = el.scrollHeight - el.scrollTop\n - el.clientHeight;\n isPinnedRef.current = distanceFromBottom <= NEAR_BOTTOM_THRESHOLD_PX;\n };\n el.addEventListener(\"scroll\", onScroll, { passive: true });\n cleanupRef.current = () => el.removeEventListener(\"scroll\", onScroll);\n }, []);\n\n React.useEffect(() => {\n if (!enabled) {\n return;\n }\n const el = elRef.current;\n if (el == null || !isPinnedRef.current) {\n return;\n }\n el.scrollTop = el.scrollHeight;\n }, [signal, enabled]);\n\n return setRef;\n}\n\nconst NEAR_BOTTOM_THRESHOLD_PX = 32;\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAO,KAAKA,KAAK,MAAM,OAAO;;AAE9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAC/BC,MAAc,EACdC,OAAgB,EACM;EACtB,MAAMC,KAAK,GAAGJ,KAAK,CAACK,MAAM,CAAW,IAAI,CAAC;EAC1C,MAAMC,UAAU,GAAGN,KAAK,CAACK,MAAM,CAAsB,IAAI,CAAC;EAC1D,MAAME,WAAW,GAAGP,KAAK,CAACK,MAAM,CAAU,IAAI,CAAC;EAE/C,MAAMG,MAAM,GAAGR,KAAK,CAACS,WAAW,CAAwBC,EAAE,IAAK;IAC7DJ,UAAU,CAACK,OAAO,GAAG,CAAC;IACtBL,UAAU,CAACK,OAAO,GAAG,IAAI;IACzBP,KAAK,CAACO,OAAO,GAAGD,EAAE;IAClB,IAAIA,EAAE,IAAI,IAAI,EAAE;MACd;IACF;IACA,MAAME,QAAQ,GAAGA,CAAA,KAAM;MACrB,MAAMC,kBAAkB,GAAGH,EAAE,CAACI,YAAY,GAAGJ,EAAE,CAACK,SAAS,GACrDL,EAAE,CAACM,YAAY;MACnBT,WAAW,CAACI,OAAO,GAAGE,kBAAkB,IAAII,wBAAwB;IACtE,CAAC;IACDP,EAAE,CAACQ,gBAAgB,CAAC,QAAQ,EAAEN,QAAQ,EAAE;MAAEO,OAAO,EAAE;IAAK,CAAC,CAAC;IAC1Db,UAAU,CAACK,OAAO,GAAG,MAAMD,EAAE,CAACU,mBAAmB,CAAC,QAAQ,EAAER,QAAQ,CAAC;EACvE,CAAC,EAAE,EAAE,CAAC;EAENZ,KAAK,CAACqB,SAAS,CAAC,MAAM;IACpB,IAAI,CAAClB,OAAO,EAAE;MACZ;IACF;IACA,MAAMO,EAAE,GAAGN,KAAK,CAACO,OAAO;IACxB,IAAID,EAAE,IAAI,IAAI,IAAI,CAACH,WAAW,CAACI,OAAO,EAAE;MACtC;IACF;IACAD,EAAE,CAACK,SAAS,GAAGL,EAAE,CAACI,YAAY;EAChC,CAAC,EAAE,CAACZ,MAAM,EAAEC,OAAO,CAAC,CAAC;EAErB,OAAOK,MAAM;AACf;AAEA,MAAMS,wBAAwB,GAAG,EAAE","ignoreList":[]}
|
|
@@ -0,0 +1,65 @@
|
|
|
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 { Error as ErrorIcon, InfoSign, Tick, WarningSign } from "@blueprintjs/icons";
|
|
18
|
+
import classNames from "classnames";
|
|
19
|
+
import * as React from "react";
|
|
20
|
+
import styles from "./Callout.module.css";
|
|
21
|
+
const DEFAULT_ICONS = {
|
|
22
|
+
error: ErrorIcon,
|
|
23
|
+
warning: WarningSign,
|
|
24
|
+
success: Tick,
|
|
25
|
+
info: InfoSign
|
|
26
|
+
};
|
|
27
|
+
const INTENT_STYLES = {
|
|
28
|
+
error: styles.error,
|
|
29
|
+
warning: styles.warning,
|
|
30
|
+
success: styles.success,
|
|
31
|
+
info: styles.info
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A styled alert banner supporting four intent levels with an icon,
|
|
36
|
+
* title, message body, and action slot.
|
|
37
|
+
*/
|
|
38
|
+
export const Callout = /*#__PURE__*/React.memo(function ({
|
|
39
|
+
intent,
|
|
40
|
+
title,
|
|
41
|
+
children,
|
|
42
|
+
actions,
|
|
43
|
+
icon,
|
|
44
|
+
className
|
|
45
|
+
}) {
|
|
46
|
+
const IconComponent = icon ?? DEFAULT_ICONS[intent];
|
|
47
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
48
|
+
"aria-live": "polite",
|
|
49
|
+
className: classNames(styles.callout, INTENT_STYLES[intent], className),
|
|
50
|
+
role: "alert"
|
|
51
|
+
}, IconComponent != null && /*#__PURE__*/React.createElement("span", {
|
|
52
|
+
className: styles.icon
|
|
53
|
+
}, /*#__PURE__*/React.createElement(IconComponent, {
|
|
54
|
+
size: 16
|
|
55
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
56
|
+
className: styles.body
|
|
57
|
+
}, title != null && /*#__PURE__*/React.createElement("div", {
|
|
58
|
+
className: styles.title
|
|
59
|
+
}, title), children != null && /*#__PURE__*/React.createElement("div", {
|
|
60
|
+
className: styles.message
|
|
61
|
+
}, children)), actions != null && /*#__PURE__*/React.createElement("div", {
|
|
62
|
+
className: styles.actions
|
|
63
|
+
}, actions));
|
|
64
|
+
});
|
|
65
|
+
//# sourceMappingURL=Callout.js.map
|