From a6769d5b779995574249bf1e5fe2ccd6fb4851f6 Mon Sep 17 00:00:00 2001 From: Simon Farshid Date: Thu, 20 Jun 2024 11:29:41 -0700 Subject: [PATCH] feat: ContentPartComponent types (#260) --- .changeset/friendly-feet-work.md | 6 +++ .../integrations/react-hook-form.mdx | 4 +- apps/www/pages/reference/runtime.mdx | 2 +- .../react-hook-form/src/useAssistantForm.tsx | 6 +-- .../context/stores/AssistantToolRenderers.ts | 11 ++--- packages/react/src/experimental.ts | 11 +++++ .../src/model-config/ToolRenderComponent.tsx | 8 ---- .../src/model-config/useAssistantTool.tsx | 4 +- .../model-config/useAssistantToolRenderer.tsx | 4 +- .../message/ContentPartComponentTypes.tsx | 41 ++++++++++++++++++ .../src/primitives/message/MessageContent.tsx | 43 ++++++------------- 11 files changed, 85 insertions(+), 55 deletions(-) create mode 100644 .changeset/friendly-feet-work.md delete mode 100644 packages/react/src/model-config/ToolRenderComponent.tsx create mode 100644 packages/react/src/primitives/message/ContentPartComponentTypes.tsx diff --git a/.changeset/friendly-feet-work.md b/.changeset/friendly-feet-work.md new file mode 100644 index 0000000000..8fc964034b --- /dev/null +++ b/.changeset/friendly-feet-work.md @@ -0,0 +1,6 @@ +--- +"@assistant-ui/react-hook-form": patch +"@assistant-ui/react": patch +--- + +feat: ContentPartComponent types diff --git a/apps/www/pages/reference/integrations/react-hook-form.mdx b/apps/www/pages/reference/integrations/react-hook-form.mdx index 8bea5de180..d7188ccbc7 100644 --- a/apps/www/pages/reference/integrations/react-hook-form.mdx +++ b/apps/www/pages/reference/integrations/react-hook-form.mdx @@ -50,7 +50,7 @@ Drop-in replacement hook for `useForm` that adds support for `@assistant-ui/reac parameters: [ { name: "renderer", - type: "ToolContentPartRenderer<{ name: string; value: string; }, {}>", + type: "ToolCallContentPartComponent<{ name: string; value: string; }, {}>", description: "The component to render when set_form_field is called.", }, @@ -67,7 +67,7 @@ Drop-in replacement hook for `useForm` that adds support for `@assistant-ui/reac parameters: [ { name: "renderer", - type: "ToolContentPartRenderer<{}, {}>", + type: "ToolCallContentPartComponent<{}, {}>", description: "The component to render when submit_form is called.", }, diff --git a/apps/www/pages/reference/runtime.mdx b/apps/www/pages/reference/runtime.mdx index 94e08e8848..ba6f6e3368 100644 --- a/apps/www/pages/reference/runtime.mdx +++ b/apps/www/pages/reference/runtime.mdx @@ -24,7 +24,7 @@ const MyApp = () => { }; ``` -### Properties +#### Properties , unknown >; }; submit_form?: { - render?: ToolRenderComponent< + render?: ToolCallContentPartComponent< z.ZodType, unknown >; diff --git a/packages/react/src/context/stores/AssistantToolRenderers.ts b/packages/react/src/context/stores/AssistantToolRenderers.ts index 42fc261c8c..a548c7eba3 100644 --- a/packages/react/src/context/stores/AssistantToolRenderers.ts +++ b/packages/react/src/context/stores/AssistantToolRenderers.ts @@ -1,22 +1,19 @@ "use client"; import { create } from "zustand"; -import type { ToolRenderComponent } from "../../model-config/ToolRenderComponent"; +import type { ToolCallContentPartComponent } from "../../primitives/message/ContentPartComponentTypes"; export type AssistantToolRenderersState = { - // biome-ignore lint/suspicious/noExplicitAny: intentional any - getToolRenderer: (name: string) => ToolRenderComponent | null; + getToolRenderer: (name: string) => ToolCallContentPartComponent | null; setToolRenderer: ( name: string, - // biome-ignore lint/suspicious/noExplicitAny: intentional any - render: ToolRenderComponent, + render: ToolCallContentPartComponent, ) => () => void; }; export const makeAssistantToolRenderersStore = () => create((set) => { - // biome-ignore lint/suspicious/noExplicitAny: intentional any - const renderers = new Map[]>(); + const renderers = new Map(); return { getToolRenderer: (name) => { diff --git a/packages/react/src/experimental.ts b/packages/react/src/experimental.ts index 5293ad129d..d1b8f6421e 100644 --- a/packages/react/src/experimental.ts +++ b/packages/react/src/experimental.ts @@ -9,6 +9,17 @@ export type { ModelConfig, } from "./utils/ModelConfigTypes"; +export type { + TextContentPartProps, + TextContentPartComponent, + ImageContentPartProps, + ImageContentPartComponent, + UIContentPartProps, + UIContentPartComponent, + ToolCallContentPartProps, + ToolCallContentPartComponent, +} from "./primitives/message/ContentPartComponentTypes"; + export * from "./context"; export { useAssistantInstructions } from "./model-config/useAssistantInstructions"; export { useAssistantTool } from "./model-config/useAssistantTool"; diff --git a/packages/react/src/model-config/ToolRenderComponent.tsx b/packages/react/src/model-config/ToolRenderComponent.tsx deleted file mode 100644 index 1754b015bd..0000000000 --- a/packages/react/src/model-config/ToolRenderComponent.tsx +++ /dev/null @@ -1,8 +0,0 @@ -"use client"; -import type { ComponentType } from "react"; -import type { ToolCallContentPart } from "../experimental"; - -export type ToolRenderComponent = ComponentType<{ - part: ToolCallContentPart; - status: "done" | "in_progress" | "error"; -}>; diff --git a/packages/react/src/model-config/useAssistantTool.tsx b/packages/react/src/model-config/useAssistantTool.tsx index 317c5ac160..15addf75a3 100644 --- a/packages/react/src/model-config/useAssistantTool.tsx +++ b/packages/react/src/model-config/useAssistantTool.tsx @@ -2,12 +2,12 @@ import { useEffect } from "react"; import { useAssistantContext } from "../context/AssistantContext"; +import type { ToolCallContentPartComponent } from "../primitives/message/ContentPartComponentTypes"; import type { Tool } from "../utils/ModelConfigTypes"; -import type { ToolRenderComponent } from "./ToolRenderComponent"; export type UseAssistantTool = Tool & { name: string; - render?: ToolRenderComponent; + render?: ToolCallContentPartComponent; }; export const useAssistantTool = ( diff --git a/packages/react/src/model-config/useAssistantToolRenderer.tsx b/packages/react/src/model-config/useAssistantToolRenderer.tsx index 2cb081aa25..172f7ad111 100644 --- a/packages/react/src/model-config/useAssistantToolRenderer.tsx +++ b/packages/react/src/model-config/useAssistantToolRenderer.tsx @@ -1,11 +1,11 @@ "use client"; import { useEffect } from "react"; import { useAssistantContext } from "../context/AssistantContext"; -import type { ToolRenderComponent } from "./ToolRenderComponent"; +import type { ToolCallContentPartComponent } from "../primitives/message/ContentPartComponentTypes"; type UseAssistantToolRenderer = { name: string; - render: ToolRenderComponent; + render: ToolCallContentPartComponent; }; export const useAssistantToolRenderer = ( diff --git a/packages/react/src/primitives/message/ContentPartComponentTypes.tsx b/packages/react/src/primitives/message/ContentPartComponentTypes.tsx new file mode 100644 index 0000000000..4238aa1b41 --- /dev/null +++ b/packages/react/src/primitives/message/ContentPartComponentTypes.tsx @@ -0,0 +1,41 @@ +"use client"; +import type { ComponentType } from "react"; +import type { + ImageContentPart, + TextContentPart, + ToolCallContentPart, + UIContentPart, +} from "../../utils/AssistantTypes"; + +type ContentPartStatus = "done" | "in_progress" | "error"; + +export type TextContentPartProps = { + part: TextContentPart; + status: ContentPartStatus; +}; +export type TextContentPartComponent = ComponentType; + +export type ImageContentPartProps = { + part: ImageContentPart; + status: ContentPartStatus; +}; +export type ImageContentPartComponent = ComponentType; + +export type UIContentPartProps = { + part: UIContentPart; + status: ContentPartStatus; +}; +export type UIContentPartComponent = ComponentType; + +// biome-ignore lint/suspicious/noExplicitAny: intentional any +export type ToolCallContentPartProps = { + part: ToolCallContentPart; + status: ContentPartStatus; +}; + +export type ToolCallContentPartComponent< + // biome-ignore lint/suspicious/noExplicitAny: intentional any + TArgs = any, + // biome-ignore lint/suspicious/noExplicitAny: intentional any + TResult = any, +> = ComponentType>; diff --git a/packages/react/src/primitives/message/MessageContent.tsx b/packages/react/src/primitives/message/MessageContent.tsx index d3671b9bb9..7b45f62584 100644 --- a/packages/react/src/primitives/message/MessageContent.tsx +++ b/packages/react/src/primitives/message/MessageContent.tsx @@ -4,42 +4,25 @@ import { type ComponentType, type FC, memo } from "react"; import { useAssistantContext, useContentPartContext } from "../../context"; import { useMessageContext } from "../../context/MessageContext"; import { ContentPartProvider } from "../../context/providers/ContentPartProvider"; -import type { - ImageContentPart, - TextContentPart, - ToolCallContentPart, - UIContentPart, -} from "../../utils/AssistantTypes"; import { ContentPartDisplay } from "../contentPart/ContentPartDisplay"; import { ContentPartInProgressIndicator } from "../contentPart/ContentPartInProgressIndicator"; import { ContentPartText } from "../contentPart/ContentPartText"; +import type { + ImageContentPartComponent, + TextContentPartComponent, + ToolCallContentPartComponent, + ToolCallContentPartProps, + UIContentPartComponent, +} from "./ContentPartComponentTypes"; -type MessageContentProps = { +export type MessageContentProps = { components?: { - Text?: ComponentType<{ - part: TextContentPart; - status: "done" | "in_progress" | "error"; - }>; - Image?: ComponentType<{ - part: ImageContentPart; - status: "done" | "in_progress" | "error"; - }>; - UI?: ComponentType<{ - part: UIContentPart; - status: "done" | "in_progress" | "error"; - }>; + Text?: TextContentPartComponent; + Image?: ImageContentPartComponent; + UI?: UIContentPartComponent; tools?: { - by_name?: Record< - string, - ComponentType<{ - part: ToolCallContentPart; - status: "done" | "in_progress" | "error"; - }> - >; - Fallback?: ComponentType<{ - part: ToolCallContentPart; - status: "done" | "in_progress" | "error"; - }>; + by_name?: Record; + Fallback?: ComponentType; }; }; };