diff --git a/package.json b/package.json index 1fc2258b..10a9987c 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,8 @@ "@radix-ui/react-hover-card": "^1.1.2", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-label": "^2.1.0", + "@radix-ui/react-navigation-menu": "^1.2.1", + "@radix-ui/react-popover": "^1.1.2", "@radix-ui/react-progress": "^1.1.0", "@radix-ui/react-select": "^2.1.1", "@radix-ui/react-slider": "^1.2.1", @@ -64,6 +66,7 @@ "@vercel/kv": "^2.0.0", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", + "cmdk": "1.0.0", "date-fns": "^4.1.0", "dotenv": "^16.4.5", "eslint-plugin-unused-imports": "^4.1.4", diff --git a/src/agent/open-canvas/nodes/customAction.ts b/src/agent/open-canvas/nodes/customAction.ts index 31e2a610..762908f7 100644 --- a/src/agent/open-canvas/nodes/customAction.ts +++ b/src/agent/open-canvas/nodes/customAction.ts @@ -1,6 +1,5 @@ import { BaseMessage } from "@langchain/core/messages"; import { LangGraphRunnableConfig } from "@langchain/langgraph"; -import { getModelFromConfig } from "../../utils"; import { getArtifactContent } from "../../../contexts/utils"; import { isArtifactMarkdownContent } from "../../../lib/artifact_content_types"; import { @@ -10,7 +9,11 @@ import { CustomQuickAction, Reflections, } from "../../../types"; -import { ensureStoreInConfig, formatReflections } from "../../utils"; +import { + ensureStoreInConfig, + formatReflections, + getModelFromConfig, +} from "../../utils"; import { CUSTOM_QUICK_ACTION_ARTIFACT_CONTENT_PROMPT, CUSTOM_QUICK_ACTION_ARTIFACT_PROMPT_PREFIX, diff --git a/src/agent/open-canvas/nodes/generate-artifact/index.ts b/src/agent/open-canvas/nodes/generate-artifact/index.ts index 1058f4c8..2fbd1e53 100644 --- a/src/agent/open-canvas/nodes/generate-artifact/index.ts +++ b/src/agent/open-canvas/nodes/generate-artifact/index.ts @@ -1,16 +1,16 @@ -import { - OpenCanvasGraphAnnotation, - OpenCanvasGraphReturnType, -} from "../../state"; -import { LangGraphRunnableConfig } from "@langchain/langgraph"; import { getFormattedReflections, - getModelFromConfig, getModelConfig, + getModelFromConfig, optionallyGetSystemPromptFromConfig, } from "@/agent/utils"; -import { ARTIFACT_TOOL_SCHEMA } from "./schemas"; import { ArtifactV3 } from "@/types"; +import { LangGraphRunnableConfig } from "@langchain/langgraph"; +import { + OpenCanvasGraphAnnotation, + OpenCanvasGraphReturnType, +} from "../../state"; +import { ARTIFACT_TOOL_SCHEMA } from "./schemas"; import { createArtifactContent, formatNewArtifactPrompt } from "./utils"; /** diff --git a/src/agent/open-canvas/nodes/generatePath.ts b/src/agent/open-canvas/nodes/generatePath.ts index 20ea964d..2242a69c 100644 --- a/src/agent/open-canvas/nodes/generatePath.ts +++ b/src/agent/open-canvas/nodes/generatePath.ts @@ -1,3 +1,10 @@ +import { LangGraphRunnableConfig } from "@langchain/langgraph"; +import { z } from "zod"; +import { getArtifactContent } from "../../../contexts/utils"; +import { + formatArtifactContentWithTemplate, + getModelFromConfig, +} from "../../utils"; import { CURRENT_ARTIFACT_PROMPT, NO_ARTIFACT_PROMPT, @@ -6,11 +13,6 @@ import { ROUTE_QUERY_PROMPT, } from "../prompts"; import { OpenCanvasGraphAnnotation } from "../state"; -import { z } from "zod"; -import { formatArtifactContentWithTemplate } from "../../utils"; -import { getArtifactContent } from "../../../contexts/utils"; -import { getModelFromConfig } from "../../utils"; -import { LangGraphRunnableConfig } from "@langchain/langgraph"; /** * Routes to the proper node in the graph based on the user's query. diff --git a/src/agent/open-canvas/nodes/replyToGeneralInput.ts b/src/agent/open-canvas/nodes/replyToGeneralInput.ts index ad9ebd19..b75b0f2c 100644 --- a/src/agent/open-canvas/nodes/replyToGeneralInput.ts +++ b/src/agent/open-canvas/nodes/replyToGeneralInput.ts @@ -1,11 +1,11 @@ import { LangGraphRunnableConfig } from "@langchain/langgraph"; -import { getModelFromConfig } from "../../utils"; import { getArtifactContent } from "../../../contexts/utils"; import { Reflections } from "../../../types"; import { ensureStoreInConfig, formatArtifactContentWithTemplate, formatReflections, + getModelFromConfig, } from "../../utils"; import { CURRENT_ARTIFACT_PROMPT, NO_ARTIFACT_PROMPT } from "../prompts"; import { OpenCanvasGraphAnnotation, OpenCanvasGraphReturnType } from "../state"; diff --git a/src/agent/open-canvas/nodes/rewriteArtifactTheme.ts b/src/agent/open-canvas/nodes/rewriteArtifactTheme.ts index 3bb39e44..6df34ad4 100644 --- a/src/agent/open-canvas/nodes/rewriteArtifactTheme.ts +++ b/src/agent/open-canvas/nodes/rewriteArtifactTheme.ts @@ -1,9 +1,12 @@ import { LangGraphRunnableConfig } from "@langchain/langgraph"; -import { getModelFromConfig } from "../../utils"; import { getArtifactContent } from "../../../contexts/utils"; import { isArtifactMarkdownContent } from "../../../lib/artifact_content_types"; import { ArtifactV3, Reflections } from "../../../types"; -import { ensureStoreInConfig, formatReflections } from "../../utils"; +import { + ensureStoreInConfig, + formatReflections, + getModelFromConfig, +} from "../../utils"; import { ADD_EMOJIS_TO_ARTIFACT_PROMPT, CHANGE_ARTIFACT_LANGUAGE_PROMPT, diff --git a/src/agent/open-canvas/nodes/rewriteCodeArtifactTheme.ts b/src/agent/open-canvas/nodes/rewriteCodeArtifactTheme.ts index d8fe34e7..58e5f3da 100644 --- a/src/agent/open-canvas/nodes/rewriteCodeArtifactTheme.ts +++ b/src/agent/open-canvas/nodes/rewriteCodeArtifactTheme.ts @@ -1,8 +1,8 @@ import { LangGraphRunnableConfig } from "@langchain/langgraph"; -import { getModelFromConfig } from "../../utils"; import { getArtifactContent } from "../../../contexts/utils"; import { isArtifactCodeContent } from "../../../lib/artifact_content_types"; import { ArtifactCodeV3, ArtifactV3 } from "../../../types"; +import { getModelFromConfig } from "../../utils"; import { ADD_COMMENTS_TO_CODE_ARTIFACT_PROMPT, ADD_LOGS_TO_CODE_ARTIFACT_PROMPT, diff --git a/src/agent/open-canvas/nodes/updateArtifact.ts b/src/agent/open-canvas/nodes/updateArtifact.ts index 918b705b..928ccf41 100644 --- a/src/agent/open-canvas/nodes/updateArtifact.ts +++ b/src/agent/open-canvas/nodes/updateArtifact.ts @@ -1,15 +1,15 @@ -import { OpenCanvasGraphAnnotation, OpenCanvasGraphReturnType } from "../state"; -import { UPDATE_HIGHLIGHTED_ARTIFACT_PROMPT } from "../prompts"; +import { LangGraphRunnableConfig } from "@langchain/langgraph"; +import { getArtifactContent } from "../../../contexts/utils"; +import { isArtifactCodeContent } from "../../../lib/artifact_content_types"; +import { ArtifactCodeV3, ArtifactV3, Reflections } from "../../../types"; import { ensureStoreInConfig, formatReflections, getModelConfig, getModelFromConfig, } from "../../utils"; -import { ArtifactCodeV3, ArtifactV3, Reflections } from "../../../types"; -import { LangGraphRunnableConfig } from "@langchain/langgraph"; -import { getArtifactContent } from "../../../contexts/utils"; -import { isArtifactCodeContent } from "../../../lib/artifact_content_types"; +import { UPDATE_HIGHLIGHTED_ARTIFACT_PROMPT } from "../prompts"; +import { OpenCanvasGraphAnnotation, OpenCanvasGraphReturnType } from "../state"; /** * Update an existing artifact based on the user's query. diff --git a/src/agent/open-canvas/nodes/updateHighlightedText.ts b/src/agent/open-canvas/nodes/updateHighlightedText.ts index 8c135e93..173ebaf1 100644 --- a/src/agent/open-canvas/nodes/updateHighlightedText.ts +++ b/src/agent/open-canvas/nodes/updateHighlightedText.ts @@ -1,13 +1,13 @@ -import { OpenCanvasGraphAnnotation, OpenCanvasGraphReturnType } from "../state"; -import { ArtifactMarkdownV3 } from "../../../types"; -import { getArtifactContent } from "../../../contexts/utils"; -import { isArtifactMarkdownContent } from "../../../lib/artifact_content_types"; import { getModelConfig, getModelFromConfig } from "@/agent/utils"; -import { LangGraphRunnableConfig } from "@langchain/langgraph"; -import { RunnableBinding } from "@langchain/core/runnables"; import { BaseLanguageModelInput } from "@langchain/core/language_models/base"; import { AIMessageChunk } from "@langchain/core/messages"; +import { RunnableBinding } from "@langchain/core/runnables"; +import { LangGraphRunnableConfig } from "@langchain/langgraph"; import { ConfigurableChatModelCallOptions } from "langchain/chat_models/universal"; +import { getArtifactContent } from "../../../contexts/utils"; +import { isArtifactMarkdownContent } from "../../../lib/artifact_content_types"; +import { ArtifactMarkdownV3 } from "../../../types"; +import { OpenCanvasGraphAnnotation, OpenCanvasGraphReturnType } from "../state"; const PROMPT = `You are an expert AI writing assistant, tasked with rewriting some text a user has selected. The selected text is nested inside a larger 'block'. You should always respond with ONLY the updated text block in accordance with the user's request. You should always respond with the full markdown text block, as it will simply replace the existing block in the artifact. diff --git a/src/agent/utils.ts b/src/agent/utils.ts index 80c28167..7891260f 100644 --- a/src/agent/utils.ts +++ b/src/agent/utils.ts @@ -1,7 +1,8 @@ import { isArtifactCodeContent } from "@/lib/artifact_content_types"; +import { CustomModelConfig } from "@/types"; import { BaseStore, LangGraphRunnableConfig } from "@langchain/langgraph"; -import { ArtifactCodeV3, ArtifactMarkdownV3, Reflections } from "../types"; import { initChatModel } from "langchain/chat_models/universal"; +import { ArtifactCodeV3, ArtifactMarkdownV3, Reflections } from "../types"; export const formatReflections = ( reflections: Reflections, @@ -139,6 +140,7 @@ export const getModelConfig = ( ): { modelName: string; modelProvider: string; + modelConfig?: CustomModelConfig; azureConfig?: { azureOpenAIApiKey: string; azureOpenAIApiInstanceName: string; @@ -150,9 +152,9 @@ export const getModelConfig = ( baseUrl?: string; } => { const customModelName = config.configurable?.customModelName as string; - if (!customModelName) { - throw new Error("Model name is missing in config."); - } + if (!customModelName) throw new Error("Model name is missing in config."); + + const modelConfig = config.configurable?.modelConfig as CustomModelConfig; if (customModelName.startsWith("azure/")) { const actualModelName = customModelName.replace("azure/", ""); @@ -172,30 +174,35 @@ export const getModelConfig = ( }; } + const providerConfig = { + modelName: customModelName, + modelConfig, + }; + if (customModelName.includes("gpt-")) { return { - modelName: customModelName, + ...providerConfig, modelProvider: "openai", apiKey: process.env.OPENAI_API_KEY, }; } if (customModelName.includes("claude-")) { return { - modelName: customModelName, + ...providerConfig, modelProvider: "anthropic", apiKey: process.env.ANTHROPIC_API_KEY, }; } if (customModelName.includes("fireworks/")) { return { - modelName: customModelName, + ...providerConfig, modelProvider: "fireworks", apiKey: process.env.FIREWORKS_API_KEY, }; } if (customModelName.includes("gemini-")) { return { - modelName: customModelName, + ...providerConfig, modelProvider: "google-genai", apiKey: process.env.GOOGLE_API_KEY, }; @@ -225,9 +232,19 @@ export async function getModelFromConfig( maxTokens?: number; } ) { - const { temperature = 0.5, maxTokens } = extra || {}; - const { modelName, modelProvider, azureConfig, apiKey, baseUrl } = - getModelConfig(config); + const { + modelName, + modelProvider, + azureConfig, + apiKey, + baseUrl, + modelConfig, + } = getModelConfig(config); + const { temperature = 0.5, maxTokens } = { + temperature: modelConfig?.temperatureRange.current, + maxTokens: modelConfig?.maxTokens.current, + ...extra, + }; return await initChatModel(modelName, { modelProvider, diff --git a/src/components/canvas/canvas.tsx b/src/components/canvas/canvas.tsx index f8b36967..5a8cc640 100644 --- a/src/components/canvas/canvas.tsx +++ b/src/components/canvas/canvas.tsx @@ -1,8 +1,12 @@ "use client"; import { ArtifactRenderer } from "@/components/artifacts/ArtifactRenderer"; -import { ContentComposerChatInterface } from "./content-composer"; -import { ALL_MODEL_NAMES } from "@/constants"; +import { + ALL_MODEL_NAMES, + DEFAULT_MODEL_CONFIG, + DEFAULT_MODEL_NAME, +} from "@/constants"; +import { useGraphContext } from "@/contexts/GraphContext"; import { useToast } from "@/hooks/use-toast"; import { getLanguageTemplate } from "@/lib/get_language_template"; import { cn } from "@/lib/utils"; @@ -10,16 +14,17 @@ import { ArtifactCodeV3, ArtifactMarkdownV3, ArtifactV3, + CustomModelConfig, ProgrammingLanguageOptions, } from "@/types"; -import { useEffect, useState } from "react"; -import { useGraphContext } from "@/contexts/GraphContext"; -import React from "react"; +import React, { useEffect, useState } from "react"; +import { ContentComposerChatInterface } from "./content-composer"; export function CanvasComponent() { const { threadData, graphData, userData } = useGraphContext(); const { user } = userData; - const { threadId, clearThreadsWithNoValues, setModelName } = threadData; + const { threadId, clearThreadsWithNoValues, setModelName, setModelConfig } = + threadData; const { setArtifact } = graphData; const { toast } = useToast(); const [chatStarted, setChatStarted] = useState(false); @@ -88,9 +93,22 @@ export function CanvasComponent() { // Chat should only be "started" if there are messages present if ((thread.values as Record)?.messages?.length) { setChatStarted(true); - setModelName( - thread?.metadata?.customModelName as ALL_MODEL_NAMES - ); + if (thread?.metadata?.customModelName) { + setModelName( + thread.metadata.customModelName as ALL_MODEL_NAMES + ); + } else { + setModelName(DEFAULT_MODEL_NAME); + } + + if (thread?.metadata?.modelConfig) { + setModelConfig( + thread?.metadata?.customModelName as ALL_MODEL_NAMES, + thread.metadata?.modelConfig as CustomModelConfig + ); + } else { + setModelConfig(DEFAULT_MODEL_NAME, DEFAULT_MODEL_CONFIG); + } } else { setChatStarted(false); } diff --git a/src/components/chat-interface/model-selector/constants.ts b/src/components/chat-interface/model-selector/constants.ts new file mode 100644 index 00000000..1424eaa3 --- /dev/null +++ b/src/components/chat-interface/model-selector/constants.ts @@ -0,0 +1,13 @@ +import { + ANTHROPIC_MODELS, + OPENAI_MODELS, + FIREWORKS_MODELS, + GEMINI_MODELS, +} from "@/constants"; + +export const ALL_MODELS = [ + ...ANTHROPIC_MODELS, + ...OPENAI_MODELS, + ...FIREWORKS_MODELS, + ...GEMINI_MODELS, +]; diff --git a/src/components/chat-interface/model-selector/index.tsx b/src/components/chat-interface/model-selector/index.tsx index e31004be..bbfdb183 100644 --- a/src/components/chat-interface/model-selector/index.tsx +++ b/src/components/chat-interface/model-selector/index.tsx @@ -1,66 +1,61 @@ "use client"; import LLMIcon from "@/components/icons/svg/LLMIcon.svg"; -import NextImage from "next/image"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select"; import { - ALL_MODEL_NAMES, - ANTHROPIC_MODELS, - OPENAI_MODELS, - FIREWORKS_MODELS, - GEMINI_MODELS, - LS_HAS_SEEN_MODEL_DROPDOWN_ALERT, - AZURE_MODELS, - OLLAMA_MODELS, -} from "@/constants"; -import { Dispatch, SetStateAction, useState } from "react"; + Command, + CommandGroup, + CommandItem, + CommandList, +} from "@/components/ui/command"; +import { ALL_MODEL_NAMES, ALL_MODELS } from "@/constants"; +import { useCallback, useState } from "react"; import { AlertNewModelSelectorFeature } from "./alert-new-model-selector"; +import { ModelConfigPanel } from "./model-config-pannel"; import { IsNewBadge } from "./new-badge"; - -const allModels = [ - ...ANTHROPIC_MODELS, - ...OPENAI_MODELS, - ...FIREWORKS_MODELS, - ...GEMINI_MODELS, - ...AZURE_MODELS, - ...OLLAMA_MODELS, -]; - -const modelNameToLabel = (modelName: ALL_MODEL_NAMES) => { - const model = allModels.find((m) => m.name === modelName); - return model?.label ?? modelName; -}; +import { cn } from "@/lib/utils"; +import { CustomModelConfig } from "@/types"; +import { CaretSortIcon, GearIcon } from "@radix-ui/react-icons"; +import { + Popover, + PopoverTrigger, + PopoverContent, +} from "@radix-ui/react-popover"; +import { Check } from "lucide-react"; +import NextImage from "next/image"; interface ModelSelectorProps { modelName: ALL_MODEL_NAMES; - setModelName: Dispatch>; + setModelName: (name: ALL_MODEL_NAMES) => void; chatStarted: boolean; + modelConfig: CustomModelConfig; + setModelConfig: ( + modelName: ALL_MODEL_NAMES, + config: CustomModelConfig + ) => void; + modelConfigs: Record; } -export default function ModelSelector(props: ModelSelectorProps) { - const { modelName, setModelName } = props; +export default function ModelSelector({ + chatStarted, + modelName, + setModelConfig, + setModelName, + modelConfigs, +}: ModelSelectorProps) { const [showAlert, setShowAlert] = useState(false); + const [open, setOpen] = useState(false); + const [openConfigModelId, setOpenConfigModelId] = + useState(null); - const isSelectedModelNew = !!allModels.find( - (model) => model.name === modelName && model.isNew + const handleModelChange = useCallback( + async (newModel: ALL_MODEL_NAMES) => { + setModelName(newModel); + setOpen(false); + }, + [setModelName] ); - const handleModelChange = async (newModel: ALL_MODEL_NAMES) => { - // Create a new thread with the new model - setModelName(newModel); - if (showAlert) { - // Ensure the model is closed if the user selects a model - setShowAlert(false); - localStorage.setItem(LS_HAS_SEEN_MODEL_DROPDOWN_ALERT, "true"); - } - }; - const allAllowedModels = allModels.filter((model) => { + const allAllowedModels = ALL_MODELS.filter((model) => { if ( model.name.includes("fireworks/") && process.env.NEXT_PUBLIC_FIREWORKS_ENABLED === "false" @@ -102,42 +97,95 @@ export default function ModelSelector(props: ModelSelectorProps) { return true; }); + const selectedModelLabel = + ALL_MODELS.find((m) => m.name === modelName)?.label || modelName; + const isSelectedModelNew = ALL_MODELS.some( + (m) => m.name === modelName && m.isNew + ); + return (
- + + +
+ + + {selectedModelLabel} + {isSelectedModelNew && } + + +
+
+ + + + {allAllowedModels.map((model) => { + const config = + modelConfigs[model.name] || + modelConfigs[model.name.replace("azure/", "")]; + + return ( + + + + + {model.label} + {model.isNew && } + + + {openConfigModelId === model.name ? ( + + setOpenConfigModelId(open ? model.name : null) + } + onClick={(e) => e.stopPropagation()} + setModelConfig={setModelConfig} + /> + ) : ( + + )} + + + ); + })} + + + +
diff --git a/src/components/chat-interface/model-selector/model-config-pannel.tsx b/src/components/chat-interface/model-selector/model-config-pannel.tsx new file mode 100644 index 00000000..fb9df003 --- /dev/null +++ b/src/components/chat-interface/model-selector/model-config-pannel.tsx @@ -0,0 +1,150 @@ +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { CustomModelConfig, ModelConfigurationParams } from "@/types"; + +import { Button } from "@/components/ui/button"; +import { Slider } from "@/components/ui/slider"; +import { ALL_MODEL_NAMES } from "@/constants"; +import { cn } from "@/lib/utils"; +import { GearIcon, ResetIcon } from "@radix-ui/react-icons"; +import { useCallback } from "react"; + +interface ModelConfigPanelProps { + model: ModelConfigurationParams; + modelConfig: CustomModelConfig; + className?: string; + isOpen: boolean; + onOpenChange: (open: boolean) => void; + onClick: (e: any) => any; + setModelConfig: ( + modelName: ALL_MODEL_NAMES, + config: CustomModelConfig + ) => void; +} + +export function ModelConfigPanel({ + model, + modelConfig, + className, + isOpen, + onOpenChange, + onClick, + setModelConfig, +}: ModelConfigPanelProps) { + console.log("modelConfig ", modelConfig); + + const handleTemperatureChange = useCallback( + (value: number[]) => { + setModelConfig(model.name, { + ...modelConfig, + temperatureRange: { + ...modelConfig.temperatureRange, + current: value[0], + }, + }); + }, + [setModelConfig, modelConfig, model] + ); + + const handleMaxTokensChange = useCallback( + (value: number[]) => { + setModelConfig(model.name, { + ...modelConfig, + maxTokens: { + ...modelConfig.maxTokens, + current: value[0], + }, + }); + }, + [setModelConfig, modelConfig, model] + ); + + const handleReset = useCallback(() => { + setModelConfig(model.name, { + ...modelConfig, + temperatureRange: { + ...modelConfig.temperatureRange, + current: modelConfig.temperatureRange.default, + }, + maxTokens: { + ...modelConfig.maxTokens, + current: modelConfig.maxTokens.default, + }, + }); + }, [setModelConfig, modelConfig, model]); + + return ( + + + + + e.stopPropagation()} + > +
+ + + +
+
+
+ ); +} + +const ModelSettingSlider = ({ + title, + description, + value, + range, + onChange, +}: { + title: string; + description: string; + value: number; + range: { min: number; max: number; step: number }; + onChange: (value: number[]) => void; +}) => ( +
+

{title}

+

{description}

+ +
{value}
+
+); diff --git a/src/components/chat-interface/thread.tsx b/src/components/chat-interface/thread.tsx index eaf5b244..1b43e79d 100644 --- a/src/components/chat-interface/thread.tsx +++ b/src/components/chat-interface/thread.tsx @@ -1,19 +1,19 @@ +import { useGraphContext } from "@/contexts/GraphContext"; +import { useToast } from "@/hooks/use-toast"; +import { ProgrammingLanguageOptions } from "@/types"; import { ThreadPrimitive } from "@assistant-ui/react"; +import { Thread as ThreadType } from "@langchain/langgraph-sdk"; import { ArrowDownIcon, SquarePen } from "lucide-react"; import { Dispatch, FC, SetStateAction } from "react"; -import { TooltipIconButton } from "../ui/assistant-ui/tooltip-icon-button"; -import { ProgrammingLanguageOptions } from "@/types"; -import ModelSelector from "./model-selector"; import { ReflectionsDialog } from "../reflections-dialog/ReflectionsDialog"; -import { ThreadHistory } from "./thread-history"; +import { useLangSmithLinkToolUI } from "../tool-hooks/LangSmithLinkToolUI"; +import { TooltipIconButton } from "../ui/assistant-ui/tooltip-icon-button"; import { TighterText } from "../ui/header"; -import { Thread as ThreadType } from "@langchain/langgraph-sdk"; -import { ThreadWelcome } from "./welcome"; import { Composer } from "./composer"; import { AssistantMessage, UserMessage } from "./messages"; -import { useToast } from "@/hooks/use-toast"; -import { useLangSmithLinkToolUI } from "../tool-hooks/LangSmithLinkToolUI"; -import { useGraphContext } from "@/contexts/GraphContext"; +import ModelSelector from "./model-selector"; +import { ThreadHistory } from "./thread-history"; +import { ThreadWelcome } from "./welcome"; const ThreadScrollToBottom: FC = () => { return ( @@ -50,7 +50,14 @@ export const Thread: FC = (props: ThreadProps) => { const { toast } = useToast(); const { userData: { user }, - threadData: { createThread, modelName, setModelName }, + threadData: { + createThread, + modelName, + setModelName, + modelConfig, + setModelConfig, + modelConfigs, + }, assistantsData: { selectedAssistant }, graphData: { clearState, runId, feedbackSubmitted, setFeedbackSubmitted }, } = useGraphContext(); @@ -68,9 +75,10 @@ export const Thread: FC = (props: ThreadProps) => { return; } setModelName(modelName); + setModelConfig(modelName, modelConfig); clearState(); setChatStarted(false); - const thread = await createThread(modelName, user.id); + const thread = await createThread(modelName, modelConfig, user.id); if (!thread) { toast({ title: "Failed to create a new thread", @@ -93,6 +101,9 @@ export const Thread: FC = (props: ThreadProps) => { chatStarted={false} modelName={modelName} setModelName={setModelName} + modelConfig={modelConfig} + setModelConfig={setModelConfig} + modelConfigs={modelConfigs} /> )} @@ -142,6 +153,9 @@ export const Thread: FC = (props: ThreadProps) => { chatStarted={true} modelName={modelName} setModelName={setModelName} + modelConfig={modelConfig} + setModelConfig={setModelConfig} + modelConfigs={modelConfigs} /> diff --git a/src/components/ui/command.tsx b/src/components/ui/command.tsx new file mode 100644 index 00000000..8f23c713 --- /dev/null +++ b/src/components/ui/command.tsx @@ -0,0 +1,155 @@ +"use client"; + +import * as React from "react"; +import { type DialogProps } from "@radix-ui/react-dialog"; +import { MagnifyingGlassIcon } from "@radix-ui/react-icons"; +import { Command as CommandPrimitive } from "cmdk"; + +import { cn } from "@/lib/utils"; +import { Dialog, DialogContent } from "@/components/ui/dialog"; + +const Command = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +Command.displayName = CommandPrimitive.displayName; + +interface CommandDialogProps extends DialogProps {} + +const CommandDialog = ({ children, ...props }: CommandDialogProps) => { + return ( + + + + {children} + + + + ); +}; + +const CommandInput = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( +
+ + +
+)); + +CommandInput.displayName = CommandPrimitive.Input.displayName; + +const CommandList = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); + +CommandList.displayName = CommandPrimitive.List.displayName; + +const CommandEmpty = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>((props, ref) => ( + +)); + +CommandEmpty.displayName = CommandPrimitive.Empty.displayName; + +const CommandGroup = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); + +CommandGroup.displayName = CommandPrimitive.Group.displayName; + +const CommandSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +CommandSeparator.displayName = CommandPrimitive.Separator.displayName; + +const CommandItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); + +CommandItem.displayName = CommandPrimitive.Item.displayName; + +const CommandShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ); +}; +CommandShortcut.displayName = "CommandShortcut"; + +export { + Command, + CommandDialog, + CommandInput, + CommandList, + CommandEmpty, + CommandGroup, + CommandItem, + CommandShortcut, + CommandSeparator, +}; diff --git a/src/components/ui/popover.tsx b/src/components/ui/popover.tsx new file mode 100644 index 00000000..b7a19e9d --- /dev/null +++ b/src/components/ui/popover.tsx @@ -0,0 +1,33 @@ +"use client"; + +import * as React from "react"; +import * as PopoverPrimitive from "@radix-ui/react-popover"; + +import { cn } from "@/lib/utils"; + +const Popover = PopoverPrimitive.Root; + +const PopoverTrigger = PopoverPrimitive.Trigger; + +const PopoverAnchor = PopoverPrimitive.Anchor; + +const PopoverContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( + + + +)); +PopoverContent.displayName = PopoverPrimitive.Content.displayName; + +export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }; diff --git a/src/constants.ts b/src/constants.ts index 8989a910..0875c079 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,3 +1,5 @@ +import { CustomModelConfig, ModelConfigurationParams } from "./types"; + export const LANGGRAPH_API_URL = process.env.LANGGRAPH_API_URL ?? "http://localhost:54367"; // v2 is tied to the 'open-canvas-prod' deployment. @@ -25,19 +27,48 @@ export const DEFAULT_INPUTS = { customQuickActionId: undefined, }; -export const AZURE_MODELS = [ +export const AZURE_MODELS: ModelConfigurationParams[] = [ { name: "azure/gpt-4o-mini", - modelName: "gpt-4o-mini", label: "GPT-4o mini (Azure)", isNew: false, + config: { + provider: "azure_openai", + temperatureRange: { + min: 0, + max: 1, + default: 0.5, + current: 0.5, + }, + maxTokens: { + min: 1, + max: 4096, + default: 4096, + current: 4096, + }, + }, }, ]; -export const OPENAI_MODELS = [ +export const OPENAI_MODELS: ModelConfigurationParams[] = [ { name: "gpt-4o-mini", label: "GPT-4o mini", + config: { + provider: "openai", + temperatureRange: { + min: 0, + max: 1, + default: 0.5, + current: 0.5, + }, + maxTokens: { + min: 1, + max: 16384, + default: 4096, + current: 4096, + }, + }, isNew: false, }, ]; @@ -49,6 +80,21 @@ export const OLLAMA_MODELS = [ { name: "ollama-llama3.3", label: "Llama 3.3 70B (local)", + config: { + provider: "ollama", + temperatureRange: { + min: 0, + max: 1, + default: 0.5, + current: 0.5, + }, + maxTokens: { + min: 1, + max: 2048, + default: 2048, + current: 2048, + }, + }, isNew: true, }, ]; @@ -57,44 +103,124 @@ export const ANTHROPIC_MODELS = [ { name: "claude-3-5-haiku-20241022", label: "Claude 3.5 Haiku", + config: { + provider: "anthropic", + temperatureRange: { + min: 0, + max: 1, + default: 0.5, + current: 0.5, + }, + maxTokens: { + min: 1, + max: 8192, + default: 4096, + current: 4096, + }, + }, isNew: false, }, { name: "claude-3-haiku-20240307", label: "Claude 3 Haiku (old)", + config: { + provider: "anthropic", + temperatureRange: { + min: 0, + max: 1, + default: 0.5, + current: 0.5, + }, + maxTokens: { + min: 1, + max: 4096, + default: 4096, + current: 4096, + }, + }, isNew: false, }, - // { - // name: "claude-3-5-sonnet-20240620", - // label: "Claude 3.5 Sonnet", - // }, ]; -export const FIREWORKS_MODELS = [ +export const FIREWORKS_MODELS: ModelConfigurationParams[] = [ { name: "accounts/fireworks/models/llama-v3p1-70b-instruct", label: "Fireworks Llama 70B", + config: { + provider: "fireworks", + temperatureRange: { + min: 0, + max: 1, + default: 0.5, + current: 0.5, + }, + maxTokens: { + min: 1, + max: 16384, + default: 4096, + current: 4096, + }, + }, isNew: false, }, ]; -export const GEMINI_MODELS = [ +export const GEMINI_MODELS: ModelConfigurationParams[] = [ { name: "gemini-1.5-flash", label: "Gemini 1.5 Flash", + config: { + provider: "google-genai", + temperatureRange: { + min: 0, + max: 1, + default: 0.5, + current: 0.5, + }, + maxTokens: { + min: 1, + max: 8192, + default: 4096, + current: 4096, + }, + }, isNew: false, }, { name: "gemini-2.0-flash-exp", label: "Gemini 2.0 Flash", + config: { + provider: "google-genai", + temperatureRange: { + min: 0, + max: 1, + default: 0.5, + current: 0.5, + }, + maxTokens: { + min: 1, + max: 8192, + default: 4096, + current: 4096, + }, + }, isNew: true, }, ]; -export const DEFAULT_MODEL_NAME: ALL_MODEL_NAMES = "gpt-4o-mini"; + +export const ALL_MODELS: ModelConfigurationParams[] = [ + ...OPENAI_MODELS, + ...ANTHROPIC_MODELS, + ...FIREWORKS_MODELS, + ...GEMINI_MODELS, + ...AZURE_MODELS, + ...OLLAMA_MODELS, +]; + export type OPENAI_MODEL_NAMES = (typeof OPENAI_MODELS)[number]["name"]; export type ANTHROPIC_MODEL_NAMES = (typeof ANTHROPIC_MODELS)[number]["name"]; export type FIREWORKS_MODEL_NAMES = (typeof FIREWORKS_MODELS)[number]["name"]; export type GEMINI_MODEL_NAMES = (typeof GEMINI_MODELS)[number]["name"]; -export type AZURE_MODEL_NAMES = (typeof AZURE_MODELS)[number]["modelName"]; +export type AZURE_MODEL_NAMES = (typeof AZURE_MODELS)[number]["name"]; export type OLLAMA_MODEL_NAMES = (typeof OLLAMA_MODELS)[number]["name"]; export type ALL_MODEL_NAMES = | OPENAI_MODEL_NAMES @@ -103,3 +229,10 @@ export type ALL_MODEL_NAMES = | GEMINI_MODEL_NAMES | AZURE_MODEL_NAMES | OLLAMA_MODEL_NAMES; + +export const DEFAULT_MODEL_NAME: ALL_MODEL_NAMES = OPENAI_MODELS[0].name; +export const DEFAULT_MODEL_CONFIG: CustomModelConfig = { + ...OPENAI_MODELS[0].config, + temperatureRange: { ...OPENAI_MODELS[0].config.temperatureRange }, + maxTokens: { ...OPENAI_MODELS[0].config.maxTokens }, +}; diff --git a/src/contexts/GraphContext.tsx b/src/contexts/GraphContext.tsx index 4d0a35a3..834ea676 100644 --- a/src/contexts/GraphContext.tsx +++ b/src/contexts/GraphContext.tsx @@ -1,30 +1,18 @@ -import { - createContext, - useContext, - ReactNode, - useEffect, - useState, - useRef, - Dispatch, - SetStateAction, -} from "react"; -import { - convertToArtifactV3, - replaceOrInsertMessageChunk, - updateHighlightedCode, - updateHighlightedMarkdown, - updateRewrittenArtifact, - removeCodeBlockFormatting, - handleGenerateArtifactToolCallChunk, -} from "./utils"; import { useUser } from "@/hooks/useUser"; import { useThread } from "@/hooks/useThread"; -import { debounce } from "lodash"; +import { + isArtifactCodeContent, + isArtifactMarkdownContent, + isDeprecatedArtifactType, +} from "@/lib/artifact_content_types"; +import { setCookie } from "@/lib/cookies"; +import { reverseCleanContent } from "@/lib/normalize_string"; import { ArtifactLengthOptions, ArtifactType, ArtifactV3, CodeHighlight, + CustomModelConfig, LanguageOptions, ProgrammingLanguageOptions, ReadingLevelOptions, @@ -37,19 +25,33 @@ import { createClient } from "@/hooks/utils"; import { ALL_MODEL_NAMES, DEFAULT_INPUTS, + DEFAULT_MODEL_CONFIG, DEFAULT_MODEL_NAME, THREAD_ID_COOKIE_NAME, } from "@/constants"; import { Thread } from "@langchain/langgraph-sdk"; import { useToast } from "@/hooks/use-toast"; import { - isArtifactCodeContent, - isArtifactMarkdownContent, - isDeprecatedArtifactType, -} from "@/lib/artifact_content_types"; -import { reverseCleanContent } from "@/lib/normalize_string"; -import { setCookie } from "@/lib/cookies"; + createContext, + Dispatch, + ReactNode, + SetStateAction, + useContext, + useEffect, + useRef, + useState, +} from "react"; +import { + convertToArtifactV3, + handleGenerateArtifactToolCallChunk, + removeCodeBlockFormatting, + replaceOrInsertMessageChunk, + updateHighlightedCode, + updateHighlightedMarkdown, + updateRewrittenArtifact, +} from "./utils"; import { useAssistants } from "@/hooks/useAssistants"; +import { debounce } from "lodash"; interface GraphData { runId: string | undefined; @@ -316,6 +318,7 @@ export function GraphProvider({ children }: { children: ReactNode }) { config: { configurable: { customModelName: threadData.modelName, + modelConfig: threadData.modelConfigs[threadData.modelName], }, }, } @@ -875,8 +878,13 @@ export function GraphProvider({ children }: { children: ReactNode }) { threadData.setModelName( thread.metadata.customModelName as ALL_MODEL_NAMES ); + threadData.setModelConfig( + thread.metadata.customModelName as ALL_MODEL_NAMES, + thread.metadata.modelConfig as CustomModelConfig + ); } else { threadData.setModelName(DEFAULT_MODEL_NAME); + threadData.setModelConfig(DEFAULT_MODEL_NAME, DEFAULT_MODEL_CONFIG); } const castValues: { diff --git a/src/hooks/useThread.tsx b/src/hooks/useThread.tsx index 678b02f6..dc8035a9 100644 --- a/src/hooks/useThread.tsx +++ b/src/hooks/useThread.tsx @@ -1,12 +1,15 @@ import { ALL_MODEL_NAMES, + ALL_MODELS, + DEFAULT_MODEL_CONFIG, DEFAULT_MODEL_NAME, HAS_EMPTY_THREADS_CLEARED_COOKIE, THREAD_ID_COOKIE_NAME, } from "@/constants"; import { getCookie, setCookie } from "@/lib/cookies"; +import { CustomModelConfig } from "@/types"; import { Thread } from "@langchain/langgraph-sdk"; -import { useState } from "react"; +import { useMemo, useState } from "react"; import { createClient } from "./utils"; export function useThread() { @@ -16,21 +19,117 @@ export function useThread() { const [modelName, setModelName] = useState(DEFAULT_MODEL_NAME); + const [modelConfigs, setModelConfigs] = useState< + Record + >(() => { + // Initialize with default configs for all models + const initialConfigs: Record = + {} as Record; + + ALL_MODELS.forEach((model) => { + const modelKey = model.modelName || model.name; + + initialConfigs[modelKey] = { + ...model.config, + provider: model.config.provider, + temperatureRange: { + ...(model.config.temperatureRange || + DEFAULT_MODEL_CONFIG.temperatureRange), + }, + maxTokens: { + ...(model.config.maxTokens || DEFAULT_MODEL_CONFIG.maxTokens), + }, + ...(model.config.provider === "azure_openai" && { + azureConfig: { + azureOpenAIApiKey: process.env._AZURE_OPENAI_API_KEY || "", + azureOpenAIApiInstanceName: + process.env._AZURE_OPENAI_API_INSTANCE_NAME || "", + azureOpenAIApiDeploymentName: + process.env._AZURE_OPENAI_API_DEPLOYMENT_NAME || "", + azureOpenAIApiVersion: + process.env._AZURE_OPENAI_API_VERSION || "2024-08-01-preview", + azureOpenAIBasePath: process.env._AZURE_OPENAI_API_BASE_PATH, + }, + }), + }; + }); + return initialConfigs; + }); + + const modelConfig = useMemo(() => { + // Try exact match first, then try without azure/ prefix + return ( + modelConfigs[modelName] || modelConfigs[modelName.replace("azure/", "")] + ); + }, [modelName, modelConfigs]); + + const setModelConfig = ( + modelName: ALL_MODEL_NAMES, + config: CustomModelConfig + ) => { + setModelConfigs((prevConfigs) => ({ + ...prevConfigs, + [modelName]: { + ...config, + provider: config.provider, + temperatureRange: { + ...(config.temperatureRange || DEFAULT_MODEL_CONFIG.temperatureRange), + }, + maxTokens: { + ...(config.maxTokens || DEFAULT_MODEL_CONFIG.maxTokens), + }, + ...(config.provider === "azure_openai" && { + azureConfig: { + ...config.azureConfig, + azureOpenAIApiKey: + config.azureConfig?.azureOpenAIApiKey || + process.env._AZURE_OPENAI_API_KEY || + "", + azureOpenAIApiInstanceName: + config.azureConfig?.azureOpenAIApiInstanceName || + process.env._AZURE_OPENAI_API_INSTANCE_NAME || + "", + azureOpenAIApiDeploymentName: + config.azureConfig?.azureOpenAIApiDeploymentName || + process.env._AZURE_OPENAI_API_DEPLOYMENT_NAME || + "", + azureOpenAIApiVersion: + config.azureConfig?.azureOpenAIApiVersion || "2024-08-01-preview", + azureOpenAIBasePath: + config.azureConfig?.azureOpenAIBasePath || + process.env._AZURE_OPENAI_API_BASE_PATH, + }, + }), + }, + })); + }; + const createThread = async ( customModelName: ALL_MODEL_NAMES = DEFAULT_MODEL_NAME, + customModelConfig: CustomModelConfig = modelConfig, userId: string ): Promise => { const client = createClient(); + try { const thread = await client.threads.create({ metadata: { supabase_user_id: userId, customModelName, + modelConfig: { + ...customModelConfig, + // Ensure Azure config is included if needed + ...(customModelConfig.provider === "azure_openai" && { + azureConfig: customModelConfig.azureConfig, + }), + }, }, }); setThreadId(thread.thread_id); setCookie(THREAD_ID_COOKIE_NAME, thread.thread_id); setModelName(customModelName); + console.log("setting model config", customModelConfig); + setModelConfig(customModelName, customModelConfig); await getUserThreads(userId); return thread; } catch (e) { @@ -66,7 +165,7 @@ export function useThread() { const searchOrCreateThread = async (userId: string) => { const threadIdCookie = getCookie(THREAD_ID_COOKIE_NAME); if (!threadIdCookie) { - await createThread(modelName, userId); + await createThread(modelName, modelConfig, userId); return; } @@ -81,7 +180,7 @@ export function useThread() { return threadIdCookie; } else { // Current thread has activity. Create a new thread. - await createThread(modelName, userId); + await createThread(modelName, modelConfig, userId); return; } }; @@ -155,7 +254,20 @@ export function useThread() { const client = createClient(); const thread = await client.threads.get(id); if (thread.metadata && thread.metadata.customModelName) { - setModelName(thread.metadata.customModelName as ALL_MODEL_NAMES); + if (thread.metadata.customModelName) { + setModelName(thread.metadata.customModelName as ALL_MODEL_NAMES); + } else { + setModelName(DEFAULT_MODEL_NAME); + } + + if (thread.metadata.modelConfig) { + setModelConfig( + thread.metadata.customModelName as ALL_MODEL_NAMES, + thread.metadata.modelConfig as CustomModelConfig + ); + } else { + setModelConfig(DEFAULT_MODEL_NAME, DEFAULT_MODEL_CONFIG); + } } return thread; } catch (e) { @@ -179,7 +291,7 @@ export function useThread() { // Create a new thread. Use .then to avoid blocking the UI. // Once completed, `createThread` will re-fetch all user // threads to update UI. - void createThread(modelName, userId); + void createThread(modelName, modelConfig, userId); } const client = createClient(); try { @@ -194,6 +306,8 @@ export function useThread() { userThreads, isUserThreadsLoading, modelName, + modelConfig, + modelConfigs, createThread, clearThreadsWithNoValues, searchOrCreateThread, @@ -202,5 +316,6 @@ export function useThread() { getThreadById, setThreadId, setModelName, + setModelConfig, }; } diff --git a/src/types.ts b/src/types.ts index a028a494..49e096cc 100644 --- a/src/types.ts +++ b/src/types.ts @@ -266,6 +266,37 @@ export type RewriteArtifactMetaToolResponse = language: ProgrammingLanguageOptions; }; +export interface CustomModelConfig { + provider: string; + temperatureRange: { + min: number; + max: number; + default: number; + current: number; + }; + maxTokens: { + min: number; + max: number; + default: number; + current: number; + }; + azureConfig?: { + azureOpenAIApiKey: string; + azureOpenAIApiInstanceName: string; + azureOpenAIApiDeploymentName: string; + azureOpenAIApiVersion: string; + azureOpenAIBasePath?: string; + }; +} + +export interface ModelConfigurationParams { + name: string; + label: string; + modelName?: string; + config: CustomModelConfig; + isNew: boolean; +} + export interface ModelConfig { temperature?: number; modelProvider: string; diff --git a/yarn.lock b/yarn.lock index 431e57e3..1eaa035a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -70,6 +70,13 @@ zod-to-json-schema "^3.23.3" zustand "^4.5.5" +"@babel/runtime@^7.13.10": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1" + integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@^7.14.6", "@babel/runtime@^7.17.2", "@babel/runtime@^7.18.6": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.7.tgz#7ffb53c37a8f247c8c4d335e89cdf16a2e0d0fb6" @@ -1160,6 +1167,13 @@ resolved "https://registry.yarnpkg.com/@radix-ui/number/-/number-1.1.0.tgz#1e95610461a09cdf8bb05c152e76ca1278d5da46" integrity sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ== +"@radix-ui/primitive@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.1.tgz#e46f9958b35d10e9f6dc71c497305c22e3e55dbd" + integrity sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive@1.1.0", "@radix-ui/primitive@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.1.0.tgz#42ef83b3b56dccad5d703ae8c42919a68798bbe2" @@ -1216,11 +1230,25 @@ "@radix-ui/react-primitive" "2.0.0" "@radix-ui/react-slot" "1.1.0" +"@radix-ui/react-compose-refs@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz#7ed868b66946aa6030e580b1ffca386dd4d21989" + integrity sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-compose-refs@1.1.0", "@radix-ui/react-compose-refs@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz#656432461fc8283d7b591dcf0d79152fae9ecc74" integrity sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw== +"@radix-ui/react-context@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.1.tgz#fe46e67c96b240de59187dcb7a1a50ce3e2ec00c" + integrity sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-context@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.0.tgz#6df8d983546cfd1999c8512f3a8ad85a6e7fcee8" @@ -1231,6 +1259,27 @@ resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.1.tgz#82074aa83a472353bb22e86f11bcbd1c61c4c71a" integrity sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q== +"@radix-ui/react-dialog@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz#71657b1b116de6c7a0b03242d7d43e01062c7300" + integrity sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-dismissable-layer" "1.0.5" + "@radix-ui/react-focus-guards" "1.0.1" + "@radix-ui/react-focus-scope" "1.0.4" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-portal" "1.0.4" + "@radix-ui/react-presence" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-slot" "1.0.2" + "@radix-ui/react-use-controllable-state" "1.0.1" + aria-hidden "^1.1.1" + react-remove-scroll "2.5.5" + "@radix-ui/react-dialog@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.1.2.tgz#d9345575211d6f2d13e209e84aec9a8584b54d6c" @@ -1256,6 +1305,18 @@ resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.1.0.tgz#a7d39855f4d077adc2a1922f9c353c5977a09cdc" integrity sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg== +"@radix-ui/react-dismissable-layer@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz#3f98425b82b9068dfbab5db5fff3df6ebf48b9d4" + integrity sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-escape-keydown" "1.0.3" + "@radix-ui/react-dismissable-layer@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz#2cd0a49a732372513733754e6032d3fb7988834e" @@ -1291,6 +1352,13 @@ "@radix-ui/react-primitive" "2.0.0" "@radix-ui/react-use-controllable-state" "1.1.0" +"@radix-ui/react-focus-guards@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz#1ea7e32092216b946397866199d892f71f7f98ad" + integrity sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-focus-guards@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz#8e9abb472a9a394f59a1b45f3dd26cfe3fc6da13" @@ -1301,6 +1369,16 @@ resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz#8635edd346304f8b42cae86b05912b61aef27afe" integrity sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg== +"@radix-ui/react-focus-scope@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz#2ac45fce8c5bb33eb18419cdc1905ef4f1906525" + integrity sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-focus-scope@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz#ebe2891a298e0a33ad34daab2aad8dea31caf0b2" @@ -1330,6 +1408,14 @@ resolved "https://registry.yarnpkg.com/@radix-ui/react-icons/-/react-icons-1.3.0.tgz#c61af8f323d87682c5ca76b856d60c2312dbcb69" integrity sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw== +"@radix-ui/react-id@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.1.tgz#73cdc181f650e4df24f0b6a5b7aa426b912c88c0" + integrity sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-use-layout-effect" "1.0.1" + "@radix-ui/react-id@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.1.0.tgz#de47339656594ad722eb87f94a6b25f9cffae0ed" @@ -1368,6 +1454,26 @@ aria-hidden "^1.1.1" react-remove-scroll "2.6.0" +"@radix-ui/react-navigation-menu@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.1.tgz#31989e026adecfbb2f7bd1108ee6fffb830b2ec1" + integrity sha512-egDo0yJD2IK8L17gC82vptkvW1jLeni1VuqCyzY727dSJdk5cDjINomouLoNk8RVF7g2aNIfENKWL4UzeU9c8Q== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-collection" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.1" + "@radix-ui/react-direction" "1.1.0" + "@radix-ui/react-dismissable-layer" "1.1.1" + "@radix-ui/react-id" "1.1.0" + "@radix-ui/react-presence" "1.1.1" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-callback-ref" "1.1.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + "@radix-ui/react-use-layout-effect" "1.1.0" + "@radix-ui/react-use-previous" "1.1.0" + "@radix-ui/react-visually-hidden" "1.1.0" + "@radix-ui/react-popover@^1.0.7", "@radix-ui/react-popover@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@radix-ui/react-popover/-/react-popover-1.1.2.tgz#a0cab25f69aa49ad0077d91e9e9dcd323758020c" @@ -1405,6 +1511,14 @@ "@radix-ui/react-use-size" "1.1.0" "@radix-ui/rect" "1.1.0" +"@radix-ui/react-portal@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.4.tgz#df4bfd353db3b1e84e639e9c63a5f2565fb00e15" + integrity sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-portal@1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.1.1.tgz#1957f1eb2e1aedfb4a5475bd6867d67b50b1d15f" @@ -1421,6 +1535,15 @@ "@radix-ui/react-primitive" "2.0.0" "@radix-ui/react-use-layout-effect" "1.1.0" +"@radix-ui/react-presence@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.1.tgz#491990ba913b8e2a5db1b06b203cb24b5cdef9ba" + integrity sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-use-layout-effect" "1.0.1" + "@radix-ui/react-presence@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.1.0.tgz#227d84d20ca6bfe7da97104b1a8b48a833bfb478" @@ -1437,6 +1560,14 @@ "@radix-ui/react-compose-refs" "1.1.0" "@radix-ui/react-use-layout-effect" "1.1.0" +"@radix-ui/react-primitive@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz#d49ea0f3f0b2fe3ab1cb5667eb03e8b843b914d0" + integrity sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-slot" "1.0.2" + "@radix-ui/react-primitive@2.0.0", "@radix-ui/react-primitive@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz#fe05715faa9203a223ccc0be15dc44b9f9822884" @@ -1538,6 +1669,14 @@ "@radix-ui/react-use-previous" "1.1.0" "@radix-ui/react-use-size" "1.1.0" +"@radix-ui/react-slot@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.0.2.tgz#a9ff4423eade67f501ffb32ec22064bc9d3099ab" + integrity sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-slot@1.1.0", "@radix-ui/react-slot@^1.0.2", "@radix-ui/react-slot@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.1.0.tgz#7c5e48c36ef5496d97b08f1357bb26ed7c714b84" @@ -1622,11 +1761,26 @@ "@radix-ui/react-use-controllable-state" "1.1.0" "@radix-ui/react-visually-hidden" "1.1.0" +"@radix-ui/react-use-callback-ref@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz#f4bb1f27f2023c984e6534317ebc411fc181107a" + integrity sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-use-callback-ref@1.1.0", "@radix-ui/react-use-callback-ref@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz#bce938ca413675bc937944b0d01ef6f4a6dc5bf1" integrity sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw== +"@radix-ui/react-use-controllable-state@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz#ecd2ced34e6330caf89a82854aa2f77e07440286" + integrity sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-controllable-state@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz#1321446857bb786917df54c0d4d084877aab04b0" @@ -1634,6 +1788,14 @@ dependencies: "@radix-ui/react-use-callback-ref" "1.1.0" +"@radix-ui/react-use-escape-keydown@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz#217b840c250541609c66f67ed7bab2b733620755" + integrity sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-escape-keydown@1.1.0", "@radix-ui/react-use-escape-keydown@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz#31a5b87c3b726504b74e05dac1edce7437b98754" @@ -1641,6 +1803,13 @@ dependencies: "@radix-ui/react-use-callback-ref" "1.1.0" +"@radix-ui/react-use-layout-effect@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz#be8c7bc809b0c8934acf6657b577daf948a75399" + integrity sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-use-layout-effect@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz#3c2c8ce04827b26a39e442ff4888d9212268bd27" @@ -3081,6 +3250,14 @@ clsx@^2.1.1: resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== +cmdk@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cmdk/-/cmdk-1.0.0.tgz#0a095fdafca3dfabed82d1db78a6262fb163ded9" + integrity sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q== + dependencies: + "@radix-ui/react-dialog" "1.0.5" + "@radix-ui/react-primitive" "1.0.3" + codemirror@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-6.0.1.tgz#62b91142d45904547ee3e0e0e4c1a79158035a29" @@ -5176,7 +5353,7 @@ kleur@^4.0.3: zod "^3.22.4" zod-to-json-schema "^3.22.3" -"langsmith@>=0.2.8 <0.4.0", langsmith@^0.3.2: +"langsmith@>=0.2.8 <0.4.0": version "0.3.2" resolved "https://registry.yarnpkg.com/langsmith/-/langsmith-0.3.2.tgz#7c744e7f9330480fa9a3fda0078e955907522c89" integrity sha512-QUaO6KdinTpts/vBsyPro/R0/Iop+TwTyEYYX8aSIvzwj5EVZY2/VxOefll51t1/E6sISEnra1EwdSCS74Y5NA== @@ -5189,6 +5366,19 @@ kleur@^4.0.3: semver "^7.6.3" uuid "^10.0.0" +langsmith@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/langsmith/-/langsmith-0.3.3.tgz#fcb61454842cf2f85c937f536fa0729544c7c467" + integrity sha512-B9B0ThaPYwNdTg9ck6bWF2Mjd1TJvVKLfLedufIudmO8aPDslcc2uVlyPEtskZFEdmfjfVHEqDnhnuAhyifrZQ== + dependencies: + "@types/uuid" "^10.0.0" + chalk "^4.1.2" + console-table-printer "^2.12.1" + p-queue "^6.6.2" + p-retry "4" + semver "^7.6.3" + uuid "^10.0.0" + language-subtag-registry@^0.3.20: version "0.3.23" resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz#23529e04d9e3b74679d70142df3fd2eb6ec572e7" @@ -7088,7 +7278,7 @@ react-number-format@^5.3.1: resolved "https://registry.yarnpkg.com/react-number-format/-/react-number-format-5.4.2.tgz#aec282241f36cee31da13dc5e0f364c0fc6902ab" integrity sha512-cg//jVdS49PYDgmcYoBnMMHl4XNTMuV723ZnHD2aXYtWWWqbVF3hjQ8iB+UZEuXapLbeA8P8H+1o6ZB1lcw3vg== -react-remove-scroll-bar@^2.3.4, react-remove-scroll-bar@^2.3.6: +react-remove-scroll-bar@^2.3.3, react-remove-scroll-bar@^2.3.4, react-remove-scroll-bar@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz#3e585e9d163be84a010180b18721e851ac81a29c" integrity sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g== @@ -7096,6 +7286,17 @@ react-remove-scroll-bar@^2.3.4, react-remove-scroll-bar@^2.3.6: react-style-singleton "^2.2.1" tslib "^2.0.0" +react-remove-scroll@2.5.5: + version "2.5.5" + resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz#1e31a1260df08887a8a0e46d09271b52b3a37e77" + integrity sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw== + dependencies: + react-remove-scroll-bar "^2.3.3" + react-style-singleton "^2.2.1" + tslib "^2.1.0" + use-callback-ref "^1.3.0" + use-sidecar "^1.1.2" + react-remove-scroll@2.5.7: version "2.5.7" resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz#15a1fd038e8497f65a695bf26a4a57970cac1ccb" @@ -7716,16 +7917,7 @@ streamsearch@^1.1.0: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -7813,14 +8005,7 @@ stringify-entities@^4.0.0: character-entities-html4 "^2.0.0" character-entities-legacy "^3.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==