- {attachments.map((file) => (
+ {contextValue.attachments.map((file) => (
))}
diff --git a/src/react/components/chat/chat/composition/chat-composer.types.ts b/src/react/components/chat/chat/composition/chat-composer.types.ts
index 1e42f59a30..1213c580f0 100644
--- a/src/react/components/chat/chat/composition/chat-composer.types.ts
+++ b/src/react/components/chat/chat/composition/chat-composer.types.ts
@@ -138,12 +138,19 @@ export interface ChatInputToolbarProps extends React.HTMLAttributes
;
}
-/** Props accepted by `ChatInput`. */
+/**
+ * Props accepted by `ChatInput`.
+ *
+ * Every prop is optional: omitted state falls back to the surrounding
+ * `ChatContext` (``), so a propless `` wires
+ * itself to the shared session. Explicit props always win, and a standalone
+ * composer outside a `` still supplies its own `input`/`onChange`.
+ */
export interface ChatInputProps {
- /** Current text value of the composer input (controlled). */
- input: string;
- /** Fired as the user edits the input. */
- onChange: (e: React.ChangeEvent) => void;
+ /** Current text value of the composer input (controlled). Falls back to `ChatContext.input`. */
+ input?: string;
+ /** Fired as the user edits the input. Falls back to `ChatContext.setInput`. */
+ onChange?: (e: React.ChangeEvent) => void;
/**
* Update the controlled input value for headless consumers. The preset wires
* this automatically. Direct consumers must provide it before calling
diff --git a/src/react/components/chat/chat/composition/chat-root.tsx b/src/react/components/chat/chat/composition/chat-root.tsx
index 65fb2216cf..ac43bbb734 100644
--- a/src/react/components/chat/chat/composition/chat-root.tsx
+++ b/src/react/components/chat/chat/composition/chat-root.tsx
@@ -9,7 +9,7 @@
import * as React from "react";
import { ChatContainer } from "#veryfront/react/primitives/index.ts";
-import type { ChatMessage, ChatStatus } from "#veryfront/agent/react";
+import type { ChatMessage, ChatStatus, UseChatResult } from "#veryfront/agent/react";
import type { ChatTheme } from "../../theme.ts";
import { useDocumentNonce } from "../../../ui/csp-nonce.ts";
import {
@@ -26,16 +26,31 @@ import type { Source } from "../components/sources.tsx";
import type { BranchInfo } from "#veryfront/agent/react";
import { ChatContextProvider } from "../contexts/chat-context.tsx";
import type { ChatContextValue } from "../contexts/chat-context.tsx";
+import { attachmentsToFileParts, hasPendingAttachments } from "../chat-attachments.ts";
-/** Props accepted by chat root. */
+/**
+ * Props accepted by chat root.
+ *
+ * Supply either `chat` (a `useChat()` session) or the flat props
+ * (`messages`, `input`, `onSubmit`, …). Both are optional so the two modes can
+ * mix, but a `` given neither renders an empty chat whose
+ * `setInput`/`onSubmit` are inert no-ops.
+ */
export interface ChatRootProps extends Omit, "children"> {
children: React.ReactNode;
/** React 19: ref is a regular prop. */
ref?: React.Ref;
+ /**
+ * Drive the chat surface from a `useChat()` session you own:
+ * ``. Folds the session state into the shared
+ * context; the flat props below stay as an explicit override path.
+ */
+ chat?: UseChatResult;
+
// Messages
- messages: ChatMessage[];
+ messages?: ChatMessage[];
isLoading?: boolean;
/** Streaming lifecycle of the current turn (`useChat().status`). */
status?: ChatStatus;
@@ -44,7 +59,7 @@ export interface ChatRootProps extends Omit
error?: Error | null;
// Input
- input: string;
+ input?: string;
setInput?: (value: string) => void;
// Submit / Stop
@@ -87,26 +102,27 @@ export interface ChatRootProps extends Omit
export function ChatRoot(
{
children,
- messages,
- isLoading = false,
- status,
- streamingMessageId,
- error = null,
- input,
- setInput,
- onSubmit,
- onStop,
- onReload,
- model,
+ chat,
+ messages: messagesProp,
+ isLoading: isLoadingProp,
+ status: statusProp,
+ streamingMessageId: streamingMessageIdProp,
+ error: errorProp,
+ input: inputProp,
+ setInput: setInputProp,
+ onSubmit: onSubmitProp,
+ onStop: onStopProp,
+ onReload: onReloadProp,
+ model: modelProp,
models = [],
- onModelChange,
+ onModelChange: onModelChangeProp,
agent,
attachments = [],
onAttach,
onRemoveAttachment,
- editMessage,
- getBranches,
- switchBranch,
+ editMessage: editMessageProp,
+ getBranches: getBranchesProp,
+ switchBranch: switchBranchProp,
onFeedback,
onSourceClick,
theme: userTheme,
@@ -117,6 +133,63 @@ export function ChatRoot(
...containerProps
}: ChatRootProps,
): React.ReactElement {
+ // `chat` folds the session's flat state into the context; each explicit flat
+ // prop wins over the session value (issue #69's override path).
+ const messages = messagesProp ?? chat?.messages ?? [];
+ const isLoading = isLoadingProp ?? chat?.isLoading ?? false;
+ const status = statusProp ?? chat?.status;
+ // Nullable props compare against `undefined`, not nullish: `error={null}` and
+ // `streamingMessageId={null}` are explicit overrides that clear the session
+ // value, so `??` would wrongly restore it from `chat`.
+ const streamingMessageId = streamingMessageIdProp !== undefined
+ ? streamingMessageIdProp
+ : chat?.streamingMessageId;
+ const error = errorProp !== undefined ? errorProp : (chat?.error ?? null);
+ const input = inputProp ?? chat?.input ?? "";
+ const setInput = setInputProp ?? chat?.setInput;
+ const model = modelProp ?? chat?.model;
+ const hasFlatSubmitState = inputProp !== undefined || setInputProp !== undefined ||
+ isLoadingProp !== undefined || modelProp !== undefined;
+ const submitSession = React.useCallback((e?: React.FormEvent) => {
+ if (!chat) return;
+ if (hasPendingAttachments(attachments)) {
+ e?.preventDefault();
+ return;
+ }
+ const files = attachmentsToFileParts(attachments);
+ if (files.length === 0 && !hasFlatSubmitState) return chat.handleSubmit(e);
+
+ e?.preventDefault();
+ if (isLoading) return;
+ const text = input.trim();
+ if (!text && files.length === 0) return;
+
+ setInput?.("");
+ for (const attachment of attachments) {
+ if (attachment.url) onRemoveAttachment?.(attachment.id);
+ }
+ return chat.sendMessage({
+ text,
+ ...(files.length > 0 ? { files } : {}),
+ ...(model !== undefined ? { model } : {}),
+ });
+ }, [
+ attachments,
+ chat,
+ hasFlatSubmitState,
+ input,
+ isLoading,
+ model,
+ onRemoveAttachment,
+ setInput,
+ ]);
+ const onSubmit = onSubmitProp ?? (chat ? submitSession : undefined);
+ const onStop = onStopProp ?? chat?.stop;
+ const onReload = onReloadProp ?? chat?.reload;
+ const onModelChange = onModelChangeProp ?? chat?.setModel;
+ const editMessage = editMessageProp ?? chat?.editMessage;
+ const getBranches = getBranchesProp ?? chat?.getBranches;
+ const switchBranch = switchBranchProp ?? chat?.switchBranch;
const theme = React.useMemo(() => mergeThemes(defaultChatTheme, userTheme), [userTheme]);
const nonce = useDocumentNonce();
const tokenCSS = React.useMemo(() => generateTokenCSS(), []);
@@ -140,6 +213,7 @@ export function ChatRoot(
input,
setInput: setInput ?? (() => {}),
onSubmit: onSubmit ?? (() => {}),
+ sendMessage: onSubmitProp === undefined ? chat?.sendMessage : undefined,
onStop,
onReload,
model,
@@ -168,6 +242,8 @@ export function ChatRoot(
input,
setInput,
onSubmit,
+ chat?.sendMessage,
+ onSubmitProp,
onStop,
onReload,
model,
diff --git a/src/react/components/chat/chat/composition/use-composer-value.ts b/src/react/components/chat/chat/composition/use-composer-value.ts
index 23877dfb9c..8db84820af 100644
--- a/src/react/components/chat/chat/composition/use-composer-value.ts
+++ b/src/react/components/chat/chat/composition/use-composer-value.ts
@@ -7,6 +7,7 @@
import * as React from "react";
import type { ChatFilePart } from "#veryfront/agent/react";
+import { useChatContextOptional } from "../contexts/chat-context.tsx";
import type { ChatInputContextValue } from "../contexts/composer-context.tsx";
import type { ModelOption } from "../../model-selector.tsx";
import type { AttachmentInfo } from "../components/attachment-pill.tsx";
@@ -14,8 +15,10 @@ import { attachmentsToFileParts, hasPendingAttachments } from "../chat-attachmen
/** State shared by controlled and composer-owned submit modes. */
interface ComposerStateBaseProps {
- input: string;
- onChange: (
+ /** Falls back to the surrounding `ChatContext` input when omitted. */
+ input?: string;
+ /** Falls back to `ChatContext.setInput` when omitted. */
+ onChange?: (
e: React.ChangeEvent,
) => void;
/** Clear pending attachments after a composer-owned submit sends. */
@@ -51,7 +54,7 @@ interface ComposerSubmitProps {
* Send directly through composer-owned submission. When supplied, `setInput`
* clears the controlled input after this handler runs.
*/
- sendMessage?: (message: { text: string; files?: ChatFilePart[] }) => void;
+ sendMessage?: (message: { text: string; files?: ChatFilePart[]; model?: string }) => void;
/** Update the controlled input value for headless context consumers. */
setInput?: (value: string) => void;
}
@@ -69,7 +72,39 @@ function missingSetInput(): never {
);
}
-export function useComposerValue(p: ComposerStateProps): ChatInputContextValue {
+export function useComposerValue(props: ComposerStateProps): ChatInputContextValue {
+ // One shared chat context (issue #69): when a `` is above,
+ // omitted props fall back to its `ChatContext` (the shared session), so a
+ // propless `` wires itself. Explicit props always win, and a
+ // standalone composer (no ChatContext) keeps the props-only behavior.
+ const chat = useChatContextOptional();
+ const resolvedSetInput = props.setInput ?? chat?.setInput;
+ const fallbackOnChange = React.useCallback(
+ (e: React.ChangeEvent) =>
+ resolvedSetInput?.(e.target.value),
+ [resolvedSetInput],
+ );
+ const hasExplicitSubmitState = props.input !== undefined ||
+ props.setInput !== undefined || props.attachments !== undefined ||
+ props.onRemoveAttachment !== undefined || props.onClearAttachments !== undefined ||
+ props.isLoading !== undefined || props.model !== undefined;
+ const p = {
+ ...props,
+ input: props.input ?? chat?.input ?? "",
+ onChange: props.onChange ?? fallbackOnChange,
+ setInput: resolvedSetInput,
+ onSubmit: props.onSubmit ?? chat?.onSubmit,
+ sendMessage: props.sendMessage ??
+ (props.onSubmit === undefined && hasExplicitSubmitState ? chat?.sendMessage : undefined),
+ isLoading: props.isLoading ?? chat?.isLoading,
+ stop: props.stop ?? chat?.onStop,
+ model: props.model ?? chat?.model,
+ models: props.models ?? chat?.models,
+ onModelChange: props.onModelChange ?? chat?.onModelChange,
+ attachments: props.attachments ?? chat?.attachments,
+ onAttach: props.onAttach ?? chat?.onAttach,
+ onRemoveAttachment: props.onRemoveAttachment ?? chat?.onRemoveAttachment,
+ };
const hasResolvedAttachment = p.attachments?.some((attachment) =>
Boolean(attachment.url) &&
attachment.state !== "uploading" &&
@@ -83,7 +118,7 @@ export function useComposerValue(p: ComposerStateProps): ChatInputContextValue {
// When `sendMessage` is supplied the composer owns submit: trim, wait for
// in-flight uploads, fold resolved attachments into file parts, send, clear.
// Otherwise fall back to the caller's explicit `onSubmit` (controlled mode).
- const { sendMessage, setInput, onClearAttachments, onSubmit } = p;
+ const { sendMessage, setInput, onClearAttachments, onSubmit, onRemoveAttachment } = p;
const onSubmitEffective = React.useCallback((e?: React.FormEvent) => {
if (!sendMessage) {
onSubmit?.(e);
@@ -95,10 +130,30 @@ export function useComposerValue(p: ComposerStateProps): ChatInputContextValue {
const text = p.input.trim();
const files = attachmentsToFileParts(attachments);
if (!text && files.length === 0) return;
- sendMessage({ text, ...(files.length > 0 ? { files } : {}) });
+ sendMessage({
+ text,
+ ...(files.length > 0 ? { files } : {}),
+ ...(p.model !== undefined ? { model: p.model } : {}),
+ });
setInput?.("");
- onClearAttachments?.();
- }, [canSubmit, sendMessage, onSubmit, setInput, onClearAttachments, p.input, p.attachments]);
+ if (onClearAttachments) {
+ onClearAttachments();
+ } else {
+ for (const attachment of attachments) {
+ if (attachment.url) onRemoveAttachment?.(attachment.id);
+ }
+ }
+ }, [
+ canSubmit,
+ sendMessage,
+ onSubmit,
+ setInput,
+ onClearAttachments,
+ onRemoveAttachment,
+ p.input,
+ p.attachments,
+ p.model,
+ ]);
return React.useMemo(() => ({
input: p.input,
diff --git a/src/react/components/chat/chat/contexts/chat-context.tsx b/src/react/components/chat/chat/contexts/chat-context.tsx
index 2860e14549..d1b01467a1 100644
--- a/src/react/components/chat/chat/contexts/chat-context.tsx
+++ b/src/react/components/chat/chat/contexts/chat-context.tsx
@@ -8,7 +8,7 @@
import * as React from "react";
import { createStrictContext } from "../../../create-strict-context.ts";
-import type { ChatMessage, ChatStatus } from "#veryfront/agent/react";
+import type { ChatFilePart, ChatMessage, ChatStatus } from "#veryfront/agent/react";
import type { ChatTheme } from "../../theme.ts";
import type { ModelOption } from "../../model-selector.tsx";
import type { AttachmentInfo } from "../components/attachment-pill.tsx";
@@ -37,6 +37,10 @@ export interface ChatContextValue {
// Submit / Stop
onSubmit: (e?: React.FormEvent) => void | Promise;
+ /** Send resolved composer text, attachments, and an optional request model through the session. */
+ sendMessage?: (message: { text: string; files?: ChatFilePart[]; model?: string }) =>
+ | void
+ | Promise;
onStop?: () => void;
onReload?: () => void;
diff --git a/src/server/handlers/dev/framework-candidates.generated.ts b/src/server/handlers/dev/framework-candidates.generated.ts
index 49894794c2..7bc028d4e3 100644
--- a/src/server/handlers/dev/framework-candidates.generated.ts
+++ b/src/server/handlers/dev/framework-candidates.generated.ts
@@ -86,6 +86,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"!cancelled",
"!candidate.matches(",
"!cardVisible",
+ "!chat)",
"!child)",
"!childTool)",
"!complete",
@@ -175,6 +176,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"!h-auto",
"!hasError",
"!hasFinalText)",
+ "!hasFlatSubmitState)",
"!hasInput",
"!hasLegacyButtonSemantics",
"!hasOutput)",
@@ -1047,6 +1049,8 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"64px).",
"65,536.",
"65_536,",
+ "69's",
+ "69):",
"6;",
"6FB57C",
"6v14a2",
@@ -2226,7 +2230,10 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"ChatContainerProps",
"ChatContainerProps>(",
"ChatContext",
+ "ChatContext)",
"ChatContext.Provider;",
+ "ChatContext.input",
+ "ChatContext.setInput",
"ChatContextProvider",
"ChatContextProvider,",
"ChatContextProvider>",
@@ -2281,6 +2288,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"ChatFilePart",
"ChatFilePart,",
"ChatFilePart[]",
+ "ChatFilePart[];",
"ChatGPT).",
"ChatIdleView",
"ChatIf",
@@ -3715,6 +3723,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"Focus-trapped",
"FocusEvent)",
"Fold",
+ "Folds",
"Follow",
"Follows",
"Footer",
@@ -4835,6 +4844,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"Notifications",
"Notified",
"November",
+ "Nullable",
"Number",
"Number(declaredLength);",
"Number(draft.trim());",
@@ -4948,6 +4958,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"Omit,",
"Omit",
+ "chat={",
"chat={chat}",
"chat={props.chat}",
"chat={useChat()}",
"chat={useChat()}>",
"chat?.agent?.avatarUrl",
"chat?.agent?.name",
+ "chat?.attachments,",
"chat?.editMessage;",
+ "chat?.error",
"chat?.getBranches;",
+ "chat?.input",
+ "chat?.isLoading",
+ "chat?.isLoading,",
+ "chat?.messages",
+ "chat?.model,",
+ "chat?.model;",
+ "chat?.models,",
+ "chat?.onAttach,",
"chat?.onFeedback;",
+ "chat?.onModelChange,",
"chat?.onReload;",
+ "chat?.onRemoveAttachment,",
"chat?.onSourceClick}",
+ "chat?.onStop,",
+ "chat?.onSubmit,",
+ "chat?.reload;",
+ "chat?.sendMessage",
+ "chat?.sendMessage,",
+ "chat?.setInput;",
+ "chat?.setModel;",
"chat?.status",
"chat?.status,",
+ "chat?.status;",
+ "chat?.stop;",
"chat?.streamingMessageId",
+ "chat?.streamingMessageId;",
"chat?.switchBranch;",
"chat?.theme.message?.assistant",
"chat?.theme.message?.user",
@@ -9985,6 +10020,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"common",
"compact",
"companion",
+ "compare",
"compat",
"compatibility",
"compatibility.",
@@ -10289,6 +10325,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"context-bound",
"context-free",
"context-menu.tsx",
+ "context-resolved",
"context.",
"context.activeConversation",
"context.activeConversation.id",
@@ -10373,6 +10410,8 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"contextOwnsId,",
"contextValue",
"contextValue,",
+ "contextValue.attachments.length",
+ "contextValue.attachments.map((file)",
"contextValue:",
"contextmenu",
"contexts",
@@ -11818,6 +11857,8 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"editMessage:",
"editMessage={editMessage}",
"editMessage?:",
+ "editMessageProp",
+ "editMessageProp,",
"editValue.trim();",
"edited.",
"editing)",
@@ -12098,6 +12139,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"error:",
"error;",
"error={error}",
+ "error={null}",
"error?:",
"errorId",
"errorId,",
@@ -12110,6 +12152,8 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"errorPresent",
"errorPresent,",
"errorPresent:",
+ "errorProp",
+ "errorProp,",
"errorText",
"errorText,",
"errorText:",
@@ -12389,6 +12433,8 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"fallbackHeadingId",
"fallbackIds,",
"fallbackIds:",
+ "fallbackOnChange",
+ "fallbackOnChange,",
"fallbackResponse",
"fallbackResponse;",
"fallbacks",
@@ -12702,6 +12748,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"focuses",
"focusin",
"fold",
+ "folds",
"follow",
"following,",
"follows",
@@ -12885,6 +12932,8 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"getBranches={getBranches}",
"getBranches?.(message.id)",
"getBranches?:",
+ "getBranchesProp",
+ "getBranchesProp,",
"getChatInputActionType(",
"getChatInputActionType,",
"getChatTokensCSS",
@@ -13255,7 +13304,10 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"hasError",
"hasError,",
"hasError:",
+ "hasExplicitSubmitState",
"hasFinalText",
+ "hasFlatSubmitState",
+ "hasFlatSubmitState,",
"hasGroups",
"hasHeading",
"hasInput,",
@@ -13272,6 +13324,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"hasOwn(value,",
"hasPendingAttachment",
"hasPendingAttachments",
+ "hasPendingAttachments(attachments))",
"hasPendingAttachments(items:",
"hasPendingAttachments(p.attachments",
"hasPendingAttachments(submittedAttachments))",
@@ -13806,6 +13859,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"input.getSubmitProps()}>Send",
"input.name",
"input.trim(),",
+ "input.trim();",
"input.tsx",
"input.type",
"input/button",
@@ -13826,6 +13880,8 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"inputMode,",
"inputMode=",
"inputMode={resolvedInputMode}",
+ "inputProp",
+ "inputProp,",
"inputProps",
"inputProps}",
"inputRef",
@@ -14103,11 +14159,14 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"isListening?:",
"isLoaded",
"isLoading",
+ "isLoading)",
"isLoading,",
"isLoading:",
"isLoading={Boolean(isLoading)}",
"isLoading={isLoading}",
"isLoading?:",
+ "isLoadingProp",
+ "isLoadingProp,",
"isMessageCreatedAtPath(path:",
"isMessageStreaming)",
"isMessageStreaming,",
@@ -14199,6 +14258,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"isn't",
"isolated",
"isolation",
+ "issue",
"issued",
"it",
"it's",
@@ -15333,6 +15393,8 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"messages:",
"messages={messages}",
"messages?:",
+ "messagesProp",
+ "messagesProp,",
"messages[messages.length",
"metadata",
"metadata.",
@@ -15354,6 +15416,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"microtask",
"mid-load:",
"mid-stream.",
+ "mid-turn).",
"midnight.",
"migration",
"migration.",
@@ -15414,6 +15477,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"mistake",
"mistake:",
"mistaken",
+ "mix,",
"ml-0.5",
"ml-auto",
"mobile",
@@ -15487,6 +15551,8 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"model?.value.split(",
"model?:",
"modelId:",
+ "modelProp",
+ "modelProp,",
"modelValue:",
"modeled",
"modelled",
@@ -15508,6 +15574,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"models?:",
"models[0];",
"model}",
+ "modes",
"modes.",
"modified:",
"module",
@@ -15782,6 +15849,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"no-explicit-any",
"no-files",
"no-op",
+ "no-ops.",
"no-persistence)",
"no-referrer",
"no-state)",
@@ -15915,6 +15983,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"null>;",
"null>>",
"null>>;",
+ "nullish:",
"null}",
"num",
"num(u.inputTokens),",
@@ -16011,7 +16080,6 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"onAttach",
"onAttach(e.target.files);",
"onAttach(event.target.files);",
- "onAttach));",
"onAttach,",
"onAttach:",
"onAttach={effectiveOnAttach}",
@@ -16087,8 +16155,9 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"onCitationClick:",
"onCitationClick?.(index);",
"onCitationClick?:",
+ "onClearAttachments();",
+ "onClearAttachments)",
"onClearAttachments,",
- "onClearAttachments?.();",
"onClearAttachments?:",
"onClick",
"onClick(e,",
@@ -16289,10 +16358,13 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"onManage?.();",
"onManage?:",
"onManage]);",
+ "onModelChange",
"onModelChange,",
"onModelChange:",
"onModelChange={onModelChange}",
"onModelChange?:",
+ "onModelChangeProp",
+ "onModelChangeProp,",
"onMouseDown,",
"onMouseDown={(event)",
"onMouseDown?.(event);",
@@ -16382,11 +16454,14 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"onRegenerate],",
"onReload",
"onReload,",
+ "onReload:",
"onReload={reload}",
"onReload?:",
+ "onReloadProp",
+ "onReloadProp,",
"onRemove",
"onRemove,",
- "onRemove={onRemoveAttachment}",
+ "onRemove={contextValue.onRemoveAttachment}",
"onRemove?.(attachment.id)}",
"onRemove?:",
"onRemoveAttachment",
@@ -16394,6 +16469,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"onRemoveAttachment:",
"onRemoveAttachment={effectiveOnRemove}",
"onRemoveAttachment={manageAttachments",
+ "onRemoveAttachment?.(attachment.id);",
"onRemoveAttachment?:",
"onRemoveUpload",
"onRemoveUpload(attachment.id)}",
@@ -16453,11 +16529,14 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"onSourceClick={onSourceClick",
"onSourceClick={onSourceClick}",
"onSourceClick?:",
+ "onStop",
"onStop();",
"onStop,",
"onStop:",
"onStop={stop}",
"onStop?:",
+ "onStopProp",
+ "onStopProp,",
"onSubmit",
"onSubmit();",
"onSubmit()}",
@@ -16474,6 +16553,8 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"onSubmit?:",
"onSubmitEffective",
"onSubmitEffective,",
+ "onSubmitProp",
+ "onSubmitProp,",
"onSuggestionClick",
"onSuggestionClick,",
"onSuggestionClick={onSuggestionClick}",
@@ -16669,6 +16750,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"optionLabels]);",
"optional",
"optional.",
+ "optional:",
"optionalBoolean(record,",
"optionalBoolean(record:",
"optionalBoolean(value,",
@@ -16913,7 +16995,6 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"p.attachments",
"p.attachments,",
"p.attachments?.some((attachment)",
- "p.attachments]);",
"p.input,",
"p.input.trim().length",
"p.input.trim();",
@@ -16921,6 +17002,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"p.isListening,",
"p.isLoading",
"p.isLoading,",
+ "p.model",
"p.model,",
"p.models",
"p.models,",
@@ -17132,6 +17214,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"patched",
"path",
"path))",
+ "path).",
"path);",
"path,",
"path.",
@@ -17655,14 +17738,17 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"propertyPath),",
"propertyPath);",
"propertyPath,",
+ "propless",
"props",
"props)",
"props**",
"props,",
"props-based",
+ "props-only",
"props.",
"props.activeId",
"props.asChild",
+ "props.attachments",
"props.chat",
"props.children))",
"props.children.props.id;",
@@ -17670,13 +17756,26 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"props.conversations",
"props.id",
"props.id;",
+ "props.input",
+ "props.isLoading",
+ "props.model",
+ "props.models",
+ "props.onAttach",
+ "props.onChange",
+ "props.onClearAttachments",
"props.onDelete",
+ "props.onModelChange",
"props.onNew",
+ "props.onRemoveAttachment",
"props.onRename",
"props.onSelect",
+ "props.onSubmit",
"props.ref",
"props.renderItem;",
+ "props.sendMessage",
+ "props.setInput",
"props.skeleton",
+ "props.stop",
"props/ref.",
"props:",
"props;",
@@ -18675,6 +18774,9 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"resolvedAnchor",
"resolvedAnchor,",
"resolvedAnchor;",
+ "resolvedAttach",
+ "resolvedAttach);",
+ "resolvedAttach,",
"resolvedContentId",
"resolvedContentId]);",
"resolvedDescribedBy",
@@ -18692,6 +18794,9 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"resolvedMode:",
"resolvedMode;",
"resolvedMode={resolvedMode}",
+ "resolvedSetInput",
+ "resolvedSetInput,",
+ "resolvedSetInput?.(e.target.value),",
"resolvedStreaming",
"resolvedStreaming,",
"resolved[key]",
@@ -19381,8 +19486,11 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"serverNonce;",
"session",
"session's",
+ "session)",
+ "session),",
"session,",
"session.",
+ "session;",
"sessionChat,",
"sessionChat:",
"sessionKey",
@@ -19520,6 +19628,8 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"setInput={setValue}",
"setInput?.(",
"setInput?:",
+ "setInputProp",
+ "setInputProp,",
"setInstructionsOpen(phase",
"setInstructionsOpen]",
"setInternal((current)",
@@ -20239,7 +20349,6 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"state.maxBytes",
"state.maxBytes}",
"state.nodes",
- "state.onAttach,",
"state.toast,",
"state.toast;",
"state.toast],",
@@ -20289,6 +20398,8 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"status?:",
"statusPresentation(",
"statusPresentation(status);",
+ "statusProp",
+ "statusProp,",
"statusProps",
"statusProps}",
"stay",
@@ -20404,8 +20515,11 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"streamingMessageId",
"streamingMessageId,",
"streamingMessageId:",
+ "streamingMessageId={null}",
"streamingMessageId={streamingMessageId}",
"streamingMessageId?:",
+ "streamingMessageIdProp",
+ "streamingMessageIdProp,",
"streams",
"stretched",
"strict",
@@ -20505,6 +20619,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"submit:",
"submit={manageAttachments",
"submit?:",
+ "submitSession",
"submitWithAttachments",
"submits",
"submitted",
@@ -20639,6 +20754,8 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"switchBranch:",
"switchBranch={switchBranch}",
"switchBranch?:",
+ "switchBranchProp",
+ "switchBranchProp,",
"switchThumbVariants",
"switchTrackVariants",
"switchTrackVariants,",
@@ -21994,7 +22111,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"useComposerContextOptional;",
"useComposerContext]",
"useComposerValue",
- "useComposerValue(p:",
+ "useComposerValue(props:",
"useComposerValue(state);",
"useComposerValue({",
"useConversation",
@@ -22039,7 +22156,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"useDrawer:",
"useDropZone",
"useDropZone(",
- "useDropZone(withFocus(onDrop",
+ "useDropZone(withFocus(onDrop)",
"useDropZone}.",
"useEffectHook",
"useEffectHook(effect,",
@@ -22667,8 +22784,11 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"will",
"will.",
"win",
+ "win,",
+ "win.",
"window",
"window.open.",
+ "wins",
"wins,",
"wins.",
"wins;",
@@ -22685,6 +22805,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"with.",
"with?",
"withFocus",
+ "withFocus(baseCtxValue.onAttach);",
"withFocus(onAttach);",
"within",
"without",
@@ -22734,6 +22855,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"writers",
"writes",
"wrong",
+ "wrongly",
"x)",
"x,",
"x-axis",
@@ -22806,4 +22928,5 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"zero-size",
"zero-size,",
"zone",
+ "zone.",
];