@anvia/react-ui 1.0.0-rc.1 → 1.0.0-rc.11

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.
Files changed (72) hide show
  1. package/README.md +52 -39
  2. package/dist/attachment/index.d.ts +5 -5
  3. package/dist/attachment/index.js +4 -4
  4. package/dist/{attachment-BP597fV3.d.ts → attachment-mbjsroli.d.ts} +1 -1
  5. package/dist/chat/index.d.ts +13 -12
  6. package/dist/chat/index.js +11 -9
  7. package/dist/chat-tfA570mg.d.ts +86 -0
  8. package/dist/{chunk-7RMRM7W3.js → chunk-647LAYRV.js} +90 -65
  9. package/dist/chunk-647LAYRV.js.map +1 -0
  10. package/dist/chunk-6XOJFLX4.js +22 -0
  11. package/dist/chunk-6XOJFLX4.js.map +1 -0
  12. package/dist/chunk-CKA4CE26.js +25 -0
  13. package/dist/chunk-CKA4CE26.js.map +1 -0
  14. package/dist/{chunk-JWZDNM5D.js → chunk-CRXNFZRW.js} +145 -125
  15. package/dist/chunk-CRXNFZRW.js.map +1 -0
  16. package/dist/{chunk-7HR34SOF.js → chunk-CVXLQCDI.js} +13 -21
  17. package/dist/chunk-CVXLQCDI.js.map +1 -0
  18. package/dist/{chunk-ULGJLLZE.js → chunk-F6AKBUO3.js} +12 -12
  19. package/dist/chunk-F6AKBUO3.js.map +1 -0
  20. package/dist/{chunk-FABSIZZ7.js → chunk-HWJIMLHC.js} +97 -90
  21. package/dist/chunk-HWJIMLHC.js.map +1 -0
  22. package/dist/{chunk-SBYUKODG.js → chunk-MISX4WUT.js} +10 -15
  23. package/dist/chunk-MISX4WUT.js.map +1 -0
  24. package/dist/{chunk-R3NA6BWW.js → chunk-OQE6SHZE.js} +54 -56
  25. package/dist/chunk-OQE6SHZE.js.map +1 -0
  26. package/dist/{chunk-VEYJNQVW.js → chunk-S4XLE2RN.js} +11 -16
  27. package/dist/chunk-S4XLE2RN.js.map +1 -0
  28. package/dist/{chunk-43U2XQP2.js → chunk-SOG2GVE4.js} +69 -25
  29. package/dist/chunk-SOG2GVE4.js.map +1 -0
  30. package/dist/{chunk-56CV6S76.js → chunk-UCBAG42A.js} +9 -21
  31. package/dist/chunk-UCBAG42A.js.map +1 -0
  32. package/dist/completion/index.d.ts +4 -3
  33. package/dist/completion/index.js +4 -4
  34. package/dist/completion-input-DHlwrhxB.d.ts +24 -0
  35. package/dist/{composer-CzsbDFPt.d.ts → composer-CigccTLT.d.ts} +19 -7
  36. package/dist/human-input/index.d.ts +10 -8
  37. package/dist/human-input/index.js +5 -4
  38. package/dist/human-input-D7jgYsfM.d.ts +27 -0
  39. package/dist/image/index.d.ts +6 -6
  40. package/dist/image/index.js +4 -4
  41. package/dist/{image-DanUxcl2.d.ts → image-VZv6Ddsn.d.ts} +1 -1
  42. package/dist/index.d.ts +19 -18
  43. package/dist/index.js +60 -64
  44. package/dist/index.js.map +1 -1
  45. package/dist/message/index.d.ts +12 -11
  46. package/dist/message/index.js +8 -6
  47. package/dist/{message-CkEnKhAn.d.ts → message-CNRnZQwU.d.ts} +1 -1
  48. package/dist/selection-toolbar/index.d.ts +2 -2
  49. package/dist/selection-toolbar/index.js +5 -4
  50. package/dist/shared.d.ts +9 -8
  51. package/dist/shared.js +1 -1
  52. package/dist/stream/index.d.ts +2 -0
  53. package/dist/stream/index.js +1 -1
  54. package/dist/{thread-uEm8hH0s.d.ts → thread-Bz6-1zaJ.d.ts} +1 -0
  55. package/dist/thread-list/index.d.ts +3 -3
  56. package/dist/thread-list/index.js +6 -6
  57. package/package.json +17 -17
  58. package/dist/chat-B3kucz1w.d.ts +0 -13
  59. package/dist/chunk-43U2XQP2.js.map +0 -1
  60. package/dist/chunk-56CV6S76.js.map +0 -1
  61. package/dist/chunk-7HR34SOF.js.map +0 -1
  62. package/dist/chunk-7RMRM7W3.js.map +0 -1
  63. package/dist/chunk-FABSIZZ7.js.map +0 -1
  64. package/dist/chunk-JWZDNM5D.js.map +0 -1
  65. package/dist/chunk-R3NA6BWW.js.map +0 -1
  66. package/dist/chunk-SBYUKODG.js.map +0 -1
  67. package/dist/chunk-ULGJLLZE.js.map +0 -1
  68. package/dist/chunk-VEYJNQVW.js.map +0 -1
  69. package/dist/completion-input-WjK6kUyG.d.ts +0 -23
  70. package/dist/human-input-CydeYm_7.d.ts +0 -20
  71. package/dist/stream/styles.css +0 -17
  72. package/dist/styles.css +0 -130
package/README.md CHANGED
@@ -3,11 +3,19 @@
3
3
  Composable React UI primitives for Anvia chat and completion experiences.
4
4
 
5
5
  ```tsx
6
+ import { createHttpClientTransport } from "@anvia/client";
6
7
  import { useChat } from "@anvia/react";
7
- import { ChatProvider, Composer, Message, Thread } from "@anvia/react-ui";
8
+ import {
9
+ ChatProvider,
10
+ ComposerPrimitive,
11
+ MessagePrimitive,
12
+ ThreadPrimitive,
13
+ } from "@anvia/react-ui";
8
14
 
9
15
  export function SupportChat() {
10
- const chat = useChat({ endpoint: "/api/chat" });
16
+ const chat = useChat({
17
+ transport: createHttpClientTransport({ endpoint: "/api/chat" }),
18
+ });
11
19
  const triggers = [
12
20
  {
13
21
  id: "people",
@@ -18,54 +26,56 @@ export function SupportChat() {
18
26
 
19
27
  return (
20
28
  <ChatProvider controller={chat}>
21
- <Thread.Root>
22
- <Thread.Viewport>
23
- <Thread.Empty>Start a conversation.</Thread.Empty>
24
- <Thread.Suggestions />
25
- <Thread.Messages>
26
- <Message.Root>
27
- <Message.Content>
28
- <Message.Parts />
29
- </Message.Content>
30
- <Message.Actions />
31
- </Message.Root>
32
- </Thread.Messages>
33
- <Thread.Error />
34
- <Thread.ScrollToBottom>Jump to latest</Thread.ScrollToBottom>
35
- </Thread.Viewport>
36
- <Composer.Root triggers={triggers}>
37
- <Composer.Attachments />
38
- <Composer.AddAttachment>Attach</Composer.AddAttachment>
39
- <Composer.Input maxRows={6} placeholder="Send a message..." />
40
- <Composer.TriggerMenu />
41
- <Composer.Stop>Stop</Composer.Stop>
42
- <Composer.Submit>Send</Composer.Submit>
43
- </Composer.Root>
44
- </Thread.Root>
29
+ <ThreadPrimitive.Root>
30
+ <ThreadPrimitive.Viewport>
31
+ <ThreadPrimitive.Empty>Start a conversation.</ThreadPrimitive.Empty>
32
+ <ThreadPrimitive.Suggestions />
33
+ <ThreadPrimitive.Messages>
34
+ <MessagePrimitive.Root>
35
+ <MessagePrimitive.Content>
36
+ <MessagePrimitive.Parts />
37
+ </MessagePrimitive.Content>
38
+ <MessagePrimitive.Actions />
39
+ </MessagePrimitive.Root>
40
+ </ThreadPrimitive.Messages>
41
+ <ThreadPrimitive.Error />
42
+ <ThreadPrimitive.ScrollToBottom>Jump to latest</ThreadPrimitive.ScrollToBottom>
43
+ </ThreadPrimitive.Viewport>
44
+ <ComposerPrimitive.Root triggers={triggers}>
45
+ <ComposerPrimitive.Attachments />
46
+ <ComposerPrimitive.AddAttachment>Attach</ComposerPrimitive.AddAttachment>
47
+ <ComposerPrimitive.Input maxRows={6} placeholder="Send a message..." />
48
+ <ComposerPrimitive.TriggerMenu />
49
+ <ComposerPrimitive.Stop>Stop</ComposerPrimitive.Stop>
50
+ <ComposerPrimitive.Submit>Send</ComposerPrimitive.Submit>
51
+ </ComposerPrimitive.Root>
52
+ </ThreadPrimitive.Root>
45
53
  </ChatProvider>
46
54
  );
47
55
  }
48
56
  ```
49
57
 
50
- Import `@anvia/react-ui/styles.css` for a small default stylesheet, or style the stable
51
- `data-anvia-*` attributes directly.
58
+ The primitives are headless: pass `className` or `asChild` for design-system integration. Their
59
+ small semantic DOM contract consists of ARIA attributes, `data-state`, and `data-role`; there is no
60
+ package stylesheet. For editable, styled application components, run
61
+ `pnpm dlx @anvia/cli add chat`.
52
62
 
53
- The primitives are headless by default: pass `className` or `asChild` for design-system
54
- integration, control `Composer.Root` with `input`/`attachments` props when needed, and use
63
+ Control `ComposerPrimitive.Root` with `input`/`attachments` props when needed, and use
55
64
  `submitMessage` for custom composer payloads. Use `keepMounted` on optional collections when empty
56
65
  wrappers are useful for layout.
57
66
 
58
- `Composer.Input` is a Tiptap-backed rich composer. Configure `Composer.Root` with `triggers` to
67
+ `ComposerPrimitive.Input` is a Tiptap-backed rich composer. Configure `ComposerPrimitive.Root` with `triggers` to
59
68
  support inline `@`, `/`, `$`, or other entity chips; selected entities are submitted under
60
- `metadata.composer.entities`. Use `Composer.TextareaInput` when you need the previous native
61
- textarea behavior.
69
+ `metadata.composer.entities`. Entity `data` must be finite strict JSON; class instances, sparse or
70
+ custom-prototype arrays, accessors, symbols, cycles, `undefined`, and non-finite numbers are
71
+ rejected. Use `ComposerPrimitive.TextareaInput` when you need the previous native textarea behavior.
62
72
 
63
73
  Streaming smoothing is opt-in and display-only. Keep `useChat` as the owner of transport and
64
74
  `UIMessage[]` state. Keep the lifecycle mounted after streaming stops so its buffered tail drains;
65
- `Message.Parts` also keeps later tool parts behind text that has not been revealed yet:
75
+ `MessagePrimitive.Parts` also keeps later tool parts behind text that has not been revealed yet:
66
76
 
67
77
  ```tsx
68
- <Message.Parts
78
+ <MessagePrimitive.Parts
69
79
  stream={{
70
80
  isStreaming:
71
81
  chat.status === "streaming" &&
@@ -75,10 +85,13 @@ Streaming smoothing is opt-in and display-only. Keep `useChat` as the owner of t
75
85
  flushImmediately: chat.status === "error",
76
86
  }}
77
87
  >
78
- {(part) => (part.type === "text" ? <Message.Markdown /> : <Message.Part />)}
79
- </Message.Parts>
88
+ {(part) =>
89
+ part.type === "text" ? <MessagePrimitive.Markdown /> : <MessagePrimitive.Part />
90
+ }
91
+ </MessagePrimitive.Parts>
80
92
  ```
81
93
 
82
94
  For app-owned text state, `StreamMarkdown` is available from `@anvia/react-ui/stream`. It is a
83
- context-free renderer: pass the already displayed text as `content`, set `live` only for its growing
84
- tail, and import `@anvia/react-ui/stream/styles.css` for the settle animation.
95
+ context-free renderer: pass the already displayed text as `content` and set `live` only for its
96
+ growing tail. Style `[data-state="revealing"]` in the owning application; `@anvia/cli` installs this
97
+ animation with its `markdown`, `message`, `thread`, and `chat` items.
@@ -1,11 +1,11 @@
1
- import * as _anvia_react from '@anvia/react';
1
+ import * as _anvia_client from '@anvia/client';
2
2
  import * as react from 'react';
3
- export { A as AttachmentContextValue, u as useAttachment } from '../attachment-BP597fV3.js';
3
+ export { A as AttachmentContextValue, u as useAttachment } from '../attachment-mbjsroli.js';
4
4
  import { P as PrimitiveProps } from '../render-CRKWam2v.js';
5
5
 
6
- declare const Attachment: {
6
+ declare const AttachmentPrimitive: {
7
7
  readonly Root: react.ForwardRefExoticComponent<Omit<PrimitiveProps<"div">, "children"> & {
8
- children?: react.ReactNode | ((attachment: _anvia_react.UIAttachment) => react.ReactNode);
8
+ children?: react.ReactNode | ((attachment: _anvia_client.UIAttachment) => react.ReactNode);
9
9
  } & react.RefAttributes<HTMLDivElement>>;
10
10
  readonly Name: react.ForwardRefExoticComponent<Omit<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref">, "asChild"> & {
11
11
  asChild?: boolean;
@@ -18,4 +18,4 @@ declare const Attachment: {
18
18
  } & react.RefAttributes<HTMLButtonElement>>;
19
19
  };
20
20
 
21
- export { Attachment };
21
+ export { AttachmentPrimitive };
@@ -1,12 +1,12 @@
1
1
  import {
2
- Attachment
3
- } from "../chunk-SBYUKODG.js";
2
+ AttachmentPrimitive
3
+ } from "../chunk-MISX4WUT.js";
4
4
  import "../chunk-T3ZFZ3NP.js";
5
5
  import {
6
6
  useAttachment
7
- } from "../chunk-43U2XQP2.js";
7
+ } from "../chunk-SOG2GVE4.js";
8
8
  export {
9
- Attachment,
9
+ AttachmentPrimitive,
10
10
  useAttachment
11
11
  };
12
12
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,4 @@
1
- import { UIAttachment } from '@anvia/react';
1
+ import { UIAttachment } from '@anvia/client';
2
2
 
3
3
  type AttachmentContextValue = {
4
4
  attachment: UIAttachment;
@@ -1,26 +1,27 @@
1
- import { C as ChatController } from '../chat-B3kucz1w.js';
2
- export { a as ChatProvider, b as ChatProviderProps, u as useChatContext } from '../chat-B3kucz1w.js';
3
- import { d as ComposerEntity, g as ComposerQuote, h as ComposerTriggerDefinition, l as ComposerTriggerState, i as ComposerTriggerItem } from '../composer-CzsbDFPt.js';
4
- export { C as ComposerAttachmentInput, a as ComposerAttachmentsUpdate, b as ComposerContextValue, c as ComposerEntitiesUpdate, e as ComposerEntityData, f as ComposerMessageMetadata, j as ComposerTriggerItems, k as ComposerTriggerItemsArgs, m as ComposerTriggerStateUpdate, u as useComposer } from '../composer-CzsbDFPt.js';
5
- export { T as ThreadContextValue, u as useThread } from '../thread-uEm8hH0s.js';
1
+ import { C as ChatController } from '../chat-tfA570mg.js';
2
+ export { a as ChatProvider, b as ChatProviderProps, u as useChatContext } from '../chat-tfA570mg.js';
3
+ import { d as ComposerEntity, g as ComposerQuote, h as ComposerTriggerDefinition, l as ComposerTriggerState, i as ComposerTriggerItem } from '../composer-CigccTLT.js';
4
+ export { C as ComposerAttachmentInput, a as ComposerAttachmentsUpdate, b as ComposerContextValue, c as ComposerEntitiesUpdate, e as ComposerEntityData, f as ComposerMessageMetadata, j as ComposerTriggerItems, k as ComposerTriggerItemsArgs, m as ComposerTriggerStateUpdate, u as useComposer } from '../composer-CigccTLT.js';
5
+ export { T as ThreadContextValue, u as useThread } from '../thread-Bz6-1zaJ.js';
6
6
  import * as react from 'react';
7
7
  import { ReactNode } from 'react';
8
- import { UIAttachment, UIMessage, UseChatStatus, ChatSuggestion } from '@anvia/react';
8
+ import { UIAttachment, ClientDataMap, ClientMetadata, UIMessage } from '@anvia/client';
9
9
  import { P as PrimitiveProps } from '../render-CRKWam2v.js';
10
+ import { UseChatStatus, ChatSuggestion } from '@anvia/react';
10
11
 
11
- type ComposerSubmitMessageArgs<TEvent = unknown> = {
12
+ type ComposerSubmitMessageArgs<TData extends ClientDataMap = ClientDataMap> = {
12
13
  input: string;
13
14
  attachments: UIAttachment[];
14
15
  entities: ComposerEntity[];
15
- chat: ChatController<TEvent>;
16
+ chat: ChatController<ClientMetadata, TData>;
16
17
  quote?: ComposerQuote | undefined;
17
18
  clear(): void;
18
19
  };
19
- type ComposerSubmitMessage<TEvent = unknown> = (args: ComposerSubmitMessageArgs<TEvent>) => Promise<void> | void;
20
+ type ComposerSubmitMessage<TData extends ClientDataMap = ClientDataMap> = (args: ComposerSubmitMessageArgs<TData>) => Promise<void> | void;
20
21
  type ComposerTriggerMenuChildren = ReactNode | ((trigger: ComposerTriggerState) => ReactNode);
21
22
  type ComposerTriggerItemChildren = ReactNode | ((item: ComposerTriggerItem, trigger: ComposerTriggerState) => ReactNode);
22
23
  type ComposerAttachmentsChildren = ReactNode | ((attachment: UIAttachment) => ReactNode);
23
- declare const Composer: {
24
+ declare const ComposerPrimitive: {
24
25
  readonly Root: react.ForwardRefExoticComponent<Omit<Omit<react.DetailedHTMLProps<react.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>, "ref">, "asChild"> & {
25
26
  asChild?: boolean;
26
27
  } & {
@@ -98,7 +99,7 @@ declare const Composer: {
98
99
 
99
100
  type ThreadMessagesChildren = ReactNode | ((message: UIMessage) => ReactNode);
100
101
  type ThreadSuggestionChildren = ReactNode | ((suggestion: ChatSuggestion) => ReactNode);
101
- declare const Thread: {
102
+ declare const ThreadPrimitive: {
102
103
  readonly Root: react.ForwardRefExoticComponent<Omit<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "asChild"> & {
103
104
  asChild?: boolean;
104
105
  } & react.RefAttributes<HTMLDivElement>>;
@@ -140,4 +141,4 @@ declare const Thread: {
140
141
  } & react.RefAttributes<HTMLButtonElement>>;
141
142
  };
142
143
 
143
- export { ChatController, Composer, ComposerEntity, ComposerQuote, type ComposerSubmitMessage, type ComposerSubmitMessageArgs, ComposerTriggerDefinition, ComposerTriggerItem, ComposerTriggerState, Thread };
144
+ export { ChatController, ComposerEntity, ComposerPrimitive, ComposerQuote, type ComposerSubmitMessage, type ComposerSubmitMessageArgs, ComposerTriggerDefinition, ComposerTriggerItem, ComposerTriggerState, ThreadPrimitive };
@@ -1,21 +1,23 @@
1
1
  import {
2
- Composer,
3
- Thread
4
- } from "../chunk-FABSIZZ7.js";
5
- import "../chunk-JWZDNM5D.js";
6
- import "../chunk-ULGJLLZE.js";
7
- import "../chunk-SBYUKODG.js";
2
+ ComposerPrimitive,
3
+ ThreadPrimitive
4
+ } from "../chunk-HWJIMLHC.js";
5
+ import "../chunk-CRXNFZRW.js";
6
+ import "../chunk-6XOJFLX4.js";
7
+ import "../chunk-F6AKBUO3.js";
8
+ import "../chunk-MISX4WUT.js";
9
+ import "../chunk-CKA4CE26.js";
8
10
  import "../chunk-T3ZFZ3NP.js";
9
11
  import {
10
12
  ChatProvider,
11
13
  useChatContext,
12
14
  useComposer,
13
15
  useThread
14
- } from "../chunk-43U2XQP2.js";
16
+ } from "../chunk-SOG2GVE4.js";
15
17
  export {
16
18
  ChatProvider,
17
- Composer,
18
- Thread,
19
+ ComposerPrimitive,
20
+ ThreadPrimitive,
19
21
  useChatContext,
20
22
  useComposer,
21
23
  useThread
@@ -0,0 +1,86 @@
1
+ import { ClientMetadata, ClientDataMap, ClientTransport, ClientStreamRequest } from '@anvia/client';
2
+ import { UseChatResult } from '@anvia/react';
3
+ import { ReactNode, ReactElement } from 'react';
4
+
5
+ type JsonPrimitive = string | number | boolean | null;
6
+ type JsonValue = JsonPrimitive | JsonObject | readonly JsonValue[];
7
+ type JsonObject = {
8
+ [key: string]: JsonValue;
9
+ };
10
+ type ToolQuestionAnswer = Readonly<{
11
+ questionId: string;
12
+ value: string;
13
+ }>;
14
+
15
+ type AgentQuestionChoice = Readonly<{
16
+ label: string;
17
+ value: string;
18
+ }>;
19
+ type AgentQuestionPrompt = Readonly<{
20
+ id: string;
21
+ text: string;
22
+ choices?: readonly AgentQuestionChoice[];
23
+ allowCustom?: boolean;
24
+ }>;
25
+ type AgentQuestionAnswer = ToolQuestionAnswer;
26
+ type AgentInteractionRequestBase = Readonly<{
27
+ id: string;
28
+ toolName: string;
29
+ toolCallId: string;
30
+ callId?: string;
31
+ internalCallId: string;
32
+ }>;
33
+ type AgentToolApprovalRequest = AgentInteractionRequestBase & Readonly<{
34
+ type: "tool-approval";
35
+ input: JsonValue;
36
+ reason?: string;
37
+ }>;
38
+ type AgentToolQuestionRequest = AgentInteractionRequestBase & Readonly<{
39
+ type: "tool-question";
40
+ questions: readonly AgentQuestionPrompt[];
41
+ }>;
42
+ type AgentInteractionRequest = AgentToolApprovalRequest | AgentToolQuestionRequest;
43
+
44
+ type ChatController<Metadata extends ClientMetadata = ClientMetadata, Data extends ClientDataMap = ClientDataMap> = UseChatResult<ClientTransport<ClientStreamRequest, Data, Metadata>>;
45
+ type ChatProviderProps<Metadata extends ClientMetadata = ClientMetadata, Data extends ClientDataMap = ClientDataMap> = {
46
+ controller: ChatController<Metadata, Data>;
47
+ children?: ReactNode;
48
+ };
49
+ declare function ChatProvider<Metadata extends ClientMetadata = ClientMetadata, Data extends ClientDataMap = ClientDataMap>({ controller, children }: ChatProviderProps<Metadata, Data>): ReactElement;
50
+ declare function useChatContext<Metadata extends ClientMetadata = ClientMetadata, Data extends ClientDataMap = ClientDataMap>(): ChatController<Metadata, Data>;
51
+ declare function useHumanInput(): {
52
+ approvals: {
53
+ all: (Readonly<{
54
+ request: AgentInteractionRequest;
55
+ runId: string;
56
+ status: "pending" | "responded" | "cancelled";
57
+ }> & {
58
+ request: AgentToolApprovalRequest;
59
+ })[];
60
+ pending: (Readonly<{
61
+ request: AgentInteractionRequest;
62
+ runId: string;
63
+ status: "pending" | "responded" | "cancelled";
64
+ }> & {
65
+ request: AgentToolApprovalRequest;
66
+ })[];
67
+ };
68
+ questions: {
69
+ all: (Readonly<{
70
+ request: AgentInteractionRequest;
71
+ runId: string;
72
+ status: "pending" | "responded" | "cancelled";
73
+ }> & {
74
+ request: AgentToolQuestionRequest;
75
+ })[];
76
+ pending: (Readonly<{
77
+ request: AgentInteractionRequest;
78
+ runId: string;
79
+ status: "pending" | "responded" | "cancelled";
80
+ }> & {
81
+ request: AgentToolQuestionRequest;
82
+ })[];
83
+ };
84
+ };
85
+
86
+ export { type AgentToolApprovalRequest as A, type ChatController as C, ChatProvider as a, type ChatProviderProps as b, useHumanInput as c, type AgentToolQuestionRequest as d, type AgentQuestionAnswer as e, type AgentQuestionPrompt as f, useChatContext as u };
@@ -1,31 +1,61 @@
1
1
  import {
2
+ composeRefs,
2
3
  renderPrimitive
3
4
  } from "./chunk-T3ZFZ3NP.js";
4
5
  import {
5
6
  InternalThreadListItemProvider,
7
+ InternalThreadListRootProvider,
8
+ useInternalThreadListRoot,
6
9
  useThreadList,
7
10
  useThreadListItem
8
- } from "./chunk-43U2XQP2.js";
11
+ } from "./chunk-SOG2GVE4.js";
9
12
 
10
13
  // src/thread-list/parts.tsx
11
14
  import {
12
15
  forwardRef,
13
- useCallback
16
+ useCallback,
17
+ useMemo,
18
+ useRef
14
19
  } from "react";
15
20
  import { jsx } from "react/jsx-runtime";
16
21
  var ThreadListRoot = forwardRef(function ThreadListRoot2({ onKeyDown, ...props }, ref) {
17
22
  const threadList = useThreadList();
23
+ const rootRef = useRef(null);
24
+ const newButtonRef = useRef(null);
25
+ const itemElements = useRef(/* @__PURE__ */ new Map());
26
+ const triggerElements = useRef(/* @__PURE__ */ new Map());
27
+ const registerItem = useCallback((threadId, element) => {
28
+ if (element === null) itemElements.current.delete(threadId);
29
+ else itemElements.current.set(threadId, element);
30
+ }, []);
31
+ const registerTrigger = useCallback((threadId, element) => {
32
+ if (element === null) triggerElements.current.delete(threadId);
33
+ else triggerElements.current.set(threadId, element);
34
+ }, []);
35
+ const rootContext = useMemo(
36
+ () => ({
37
+ rootRef,
38
+ newButtonRef,
39
+ itemElements,
40
+ triggerElements,
41
+ registerItem,
42
+ registerTrigger
43
+ }),
44
+ [registerItem, registerTrigger]
45
+ );
46
+ const composedRef = useMemo(
47
+ () => composeRefs(ref, (node) => {
48
+ rootRef.current = node;
49
+ }),
50
+ [ref]
51
+ );
18
52
  const handleKeyDown = useCallback(
19
53
  (event) => {
20
54
  onKeyDown?.(event);
21
55
  if (event.defaultPrevented || !["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
22
56
  return;
23
57
  }
24
- const triggers = Array.from(
25
- event.currentTarget.querySelectorAll(
26
- "[data-anvia-thread-list-trigger]:not(:disabled)"
27
- )
28
- );
58
+ const triggers = orderedEnabledTriggers(rootContext);
29
59
  if (triggers.length === 0) {
30
60
  return;
31
61
  }
@@ -35,22 +65,28 @@ var ThreadListRoot = forwardRef(function ThreadListRoot2({ onKeyDown, ...props }
35
65
  const nextIndex = nextTriggerIndex(event.key, currentIndex, triggers.length);
36
66
  triggers[nextIndex]?.focus();
37
67
  },
38
- [onKeyDown]
68
+ [onKeyDown, rootContext]
39
69
  );
40
- return renderPrimitive(
70
+ return /* @__PURE__ */ jsx(InternalThreadListRootProvider, { value: rootContext, children: renderPrimitive(
41
71
  "div",
42
72
  {
43
73
  ...props,
44
74
  onKeyDown: handleKeyDown,
45
- "data-anvia-thread-list": "",
46
75
  "data-state": threadList.status ?? "idle"
47
76
  },
48
- ref
49
- );
77
+ composedRef
78
+ ) });
50
79
  });
51
80
  var ThreadListNew = forwardRef(
52
81
  function ThreadListNew2({ onClick, ...props }, ref) {
53
82
  const threadList = useThreadList();
83
+ const root = useInternalThreadListRoot();
84
+ const composedRef = useMemo(
85
+ () => composeRefs(ref, (node) => {
86
+ root.newButtonRef.current = node;
87
+ }),
88
+ [ref, root.newButtonRef]
89
+ );
54
90
  const handleClick = useCallback(
55
91
  (event) => {
56
92
  onClick?.(event);
@@ -68,10 +104,9 @@ var ThreadListNew = forwardRef(
68
104
  children: props.children ?? "New chat",
69
105
  onClick: handleClick,
70
106
  type: props.type ?? "button",
71
- "data-anvia-thread-list-new": "",
72
107
  "data-state": props.disabled ? "disabled" : "enabled"
73
108
  },
74
- ref
109
+ composedRef
75
110
  );
76
111
  }
77
112
  );
@@ -94,9 +129,7 @@ var ThreadListItems = forwardRef(function ThreadListItems2({ archived = false, c
94
129
  },
95
130
  thread.id
96
131
  )),
97
- "data-anvia-thread-list-items": "",
98
- "data-archived": archived ? "" : void 0,
99
- "data-empty": empty ? "" : void 0
132
+ "data-state": empty ? "empty" : "populated"
100
133
  },
101
134
  ref
102
135
  );
@@ -113,8 +146,7 @@ var ThreadListEmpty = forwardRef(function ThreadListEmpty2({ archived = false, .
113
146
  "div",
114
147
  {
115
148
  ...props,
116
- children: props.children ?? "No conversations.",
117
- "data-anvia-thread-list-empty": ""
149
+ children: props.children ?? "No conversations."
118
150
  },
119
151
  ref
120
152
  );
@@ -122,15 +154,18 @@ var ThreadListEmpty = forwardRef(function ThreadListEmpty2({ archived = false, .
122
154
  var ThreadListItemRoot = forwardRef(
123
155
  function ThreadListItemRoot2(props, ref) {
124
156
  const item = useThreadListItem();
157
+ const root = useInternalThreadListRoot();
158
+ const composedRef = useMemo(
159
+ () => composeRefs(ref, (node) => root.registerItem(item.thread.id, node)),
160
+ [item.thread.id, ref, root]
161
+ );
125
162
  return renderPrimitive(
126
163
  "div",
127
164
  {
128
165
  ...props,
129
- "data-anvia-thread-list-item": "",
130
- "data-active": item.active ? "" : void 0,
131
- "data-thread-id": item.thread.id
166
+ "data-state": item.active ? "active" : "inactive"
132
167
  },
133
- ref
168
+ composedRef
134
169
  );
135
170
  }
136
171
  );
@@ -138,7 +173,12 @@ var ThreadListItemTrigger = forwardRef(
138
173
  function ThreadListItemTrigger2({ onClick, ...props }, ref) {
139
174
  const threadList = useThreadList();
140
175
  const item = useThreadListItem();
176
+ const root = useInternalThreadListRoot();
141
177
  const disabled = props.disabled ?? false;
178
+ const composedRef = useMemo(
179
+ () => composeRefs(ref, (node) => root.registerTrigger(item.thread.id, node)),
180
+ [item.thread.id, ref, root]
181
+ );
142
182
  const handleClick = useCallback(
143
183
  (event) => {
144
184
  onClick?.(event);
@@ -158,10 +198,9 @@ var ThreadListItemTrigger = forwardRef(
158
198
  onClick: handleClick,
159
199
  type: props.type ?? "button",
160
200
  "aria-current": item.active ? "true" : void 0,
161
- "data-anvia-thread-list-trigger": "",
162
201
  "data-state": disabled ? "disabled" : "enabled"
163
202
  },
164
- ref
203
+ composedRef
165
204
  );
166
205
  }
167
206
  );
@@ -172,17 +211,17 @@ var ThreadListItemTitle = forwardRef(
172
211
  "span",
173
212
  {
174
213
  ...props,
175
- children: props.children ?? thread.title ?? fallback,
176
- "data-anvia-thread-list-title": ""
214
+ children: props.children ?? thread.title ?? fallback
177
215
  },
178
216
  ref
179
217
  );
180
218
  }
181
219
  );
182
- function createThreadListItemAction(action, defaultLabel, dataAttribute) {
220
+ function createThreadListItemAction(action, defaultLabel) {
183
221
  return forwardRef(function ThreadListItemAction({ onClick, ...props }, ref) {
184
222
  const threadList = useThreadList();
185
223
  const { thread } = useThreadListItem();
224
+ const root = useInternalThreadListRoot();
186
225
  const actionHandler = threadList[action];
187
226
  const disabled = props.disabled ?? actionHandler === void 0;
188
227
  const handleClick = useCallback(
@@ -191,10 +230,10 @@ function createThreadListItemAction(action, defaultLabel, dataAttribute) {
191
230
  if (event.defaultPrevented || disabled) {
192
231
  return;
193
232
  }
194
- focusAfterThreadItemRemoval(event.currentTarget);
233
+ focusAfterThreadItemRemoval(thread.id, root);
195
234
  void actionHandler?.(thread.id);
196
235
  },
197
- [actionHandler, disabled, onClick, thread.id]
236
+ [actionHandler, disabled, onClick, root, thread.id]
198
237
  );
199
238
  return renderPrimitive(
200
239
  "button",
@@ -204,28 +243,15 @@ function createThreadListItemAction(action, defaultLabel, dataAttribute) {
204
243
  disabled,
205
244
  onClick: handleClick,
206
245
  type: props.type ?? "button",
207
- [dataAttribute]: "",
208
246
  "data-state": disabled ? "disabled" : "enabled"
209
247
  },
210
248
  ref
211
249
  );
212
250
  });
213
251
  }
214
- var ThreadListItemArchive = createThreadListItemAction(
215
- "archiveThread",
216
- "Archive",
217
- "data-anvia-thread-list-archive"
218
- );
219
- var ThreadListItemUnarchive = createThreadListItemAction(
220
- "unarchiveThread",
221
- "Unarchive",
222
- "data-anvia-thread-list-unarchive"
223
- );
224
- var ThreadListItemDelete = createThreadListItemAction(
225
- "deleteThread",
226
- "Delete",
227
- "data-anvia-thread-list-delete"
228
- );
252
+ var ThreadListItemArchive = createThreadListItemAction("archiveThread", "Archive");
253
+ var ThreadListItemUnarchive = createThreadListItemAction("unarchiveThread", "Unarchive");
254
+ var ThreadListItemDelete = createThreadListItemAction("deleteThread", "Delete");
229
255
  function DefaultThreadItem() {
230
256
  return /* @__PURE__ */ jsx(ThreadListItemRoot, { children: /* @__PURE__ */ jsx(ThreadListItemTrigger, {}) });
231
257
  }
@@ -244,38 +270,37 @@ function nextTriggerIndex(key, currentIndex, triggerCount) {
244
270
  }
245
271
  return (currentIndex + 1) % triggerCount;
246
272
  }
247
- function focusAfterThreadItemRemoval(actionButton) {
248
- const root = actionButton.closest("[data-anvia-thread-list]");
249
- const currentItem = actionButton.closest("[data-anvia-thread-list-item]");
250
- if (root === null || currentItem === null || !currentItem.contains(root.ownerDocument.activeElement)) {
273
+ function focusAfterThreadItemRemoval(threadId, rootContext) {
274
+ const root = rootContext.rootRef.current;
275
+ const currentItem = rootContext.itemElements.current.get(threadId);
276
+ if (root === null || currentItem === void 0 || !currentItem.contains(root.ownerDocument.activeElement)) {
251
277
  return;
252
278
  }
253
- const triggers = Array.from(
254
- root.querySelectorAll("[data-anvia-thread-list-trigger]:not(:disabled)")
255
- );
256
- const currentTrigger = currentItem.querySelector(
257
- "[data-anvia-thread-list-trigger]"
258
- );
259
- const currentIndex = currentTrigger === null ? -1 : triggers.indexOf(currentTrigger);
279
+ const triggers = orderedEnabledTriggers(rootContext);
280
+ const currentTrigger = rootContext.triggerElements.current.get(threadId);
281
+ const currentIndex = currentTrigger === void 0 ? -1 : triggers.indexOf(currentTrigger);
260
282
  const remainingTriggers = triggers.filter((trigger) => !currentItem.contains(trigger));
261
- const fallback = root.querySelector(
262
- "[data-anvia-thread-list-new]:not(:disabled)"
263
- );
283
+ const fallback = rootContext.newButtonRef.current;
264
284
  const focusTarget = remainingTriggers[Math.min(Math.max(currentIndex, 0), remainingTriggers.length - 1)] ?? fallback ?? root;
265
285
  if (focusTarget === root && !root.hasAttribute("tabindex")) {
266
286
  root.tabIndex = -1;
267
287
  }
268
288
  focusTarget.focus();
269
289
  }
290
+ function orderedEnabledTriggers(rootContext) {
291
+ return [...rootContext.triggerElements.current.values()].filter((trigger) => trigger.isConnected && !trigger.disabled).sort(
292
+ (left, right) => left.compareDocumentPosition(right) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1
293
+ );
294
+ }
270
295
 
271
296
  // src/thread-list/index.ts
272
- var ThreadList = {
297
+ var ThreadListPrimitive = {
273
298
  Root: ThreadListRoot,
274
299
  New: ThreadListNew,
275
300
  Items: ThreadListItems,
276
301
  Empty: ThreadListEmpty
277
302
  };
278
- var ThreadListItem = {
303
+ var ThreadListItemPrimitive = {
279
304
  Root: ThreadListItemRoot,
280
305
  Trigger: ThreadListItemTrigger,
281
306
  Title: ThreadListItemTitle,
@@ -285,7 +310,7 @@ var ThreadListItem = {
285
310
  };
286
311
 
287
312
  export {
288
- ThreadList,
289
- ThreadListItem
313
+ ThreadListPrimitive,
314
+ ThreadListItemPrimitive
290
315
  };
291
- //# sourceMappingURL=chunk-7RMRM7W3.js.map
316
+ //# sourceMappingURL=chunk-647LAYRV.js.map