diff --git a/README.md b/README.md index 3097bb0..c6f10ea 100644 --- a/README.md +++ b/README.md @@ -65,3 +65,60 @@ To use these variables: 3. Restart the application When these environment variables are set, the application will use them instead of showing the setup form. + + +## Hiding Messages in the Chat + +You can control the visibility of messages within the Agent Chat UI in two main ways: + +**1. Prevent Live Streaming:** + +To stop messages from being displayed _as they stream_ from an LLM call, add the `langsmith:nostream` tag to the chat model's configuration. The UI normally uses `on_chat_model_stream` events to render streaming messages; this tag prevents those events from being emitted for the tagged model. + +_Python Example:_ + +```python +from langchain_anthropic import ChatAnthropic + +# Add tags via the .with_config method +model = ChatAnthropic().with_config( + config={"tags": ["langsmith:nostream"]} +) +``` + +_TypeScript Example:_ + +```typescript +import { ChatAnthropic } from "@langchain/anthropic"; + +const model = new ChatAnthropic() + // Add tags via the .withConfig method + .withConfig({ tags: ["langsmith:nostream"] }); +``` + +**Note:** Even if streaming is hidden this way, the message will still appear after the LLM call completes if it's saved to the graph's state without further modification. + +**2. Hide Messages Permanently:** + +To ensure a message is _never_ displayed in the chat UI (neither during streaming nor after being saved to state), prefix its `id` field with `do-not-render-` _before_ adding it to the graph's state, along with adding the `langsmith:do-not-render` tag to the chat model's configuration. The UI explicitly filters out any message whose `id` starts with this prefix. + +_Python Example:_ + +```python +result = model.invoke([messages]) +# Prefix the ID before saving to state +result.id = f"do-not-render-{result.id}" +return {"messages": [result]} +``` + +_TypeScript Example:_ + +```typescript +const result = await model.invoke([messages]); +// Prefix the ID before saving to state +result.id = `do-not-render-${result.id}`; +return { messages: [result] }; +``` + +This approach guarantees the message remains completely hidden from the user interface. + diff --git a/src/components/icons/github.tsx b/src/components/icons/github.tsx new file mode 100644 index 0000000..168f15c --- /dev/null +++ b/src/components/icons/github.tsx @@ -0,0 +1,12 @@ +export const GitHubSVG = ({ width = "100%", height = "100%" }) => ( + + GitHub + + +); diff --git a/src/components/thread/index.tsx b/src/components/thread/index.tsx index fd46266..8ea169d 100644 --- a/src/components/thread/index.tsx +++ b/src/components/thread/index.tsx @@ -28,6 +28,13 @@ import { toast } from "sonner"; import { useMediaQuery } from "@/hooks/useMediaQuery"; import { Label } from "../ui/label"; import { Switch } from "../ui/switch"; +import { GitHubSVG } from "../icons/github"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "../ui/tooltip"; function StickyToBottomContent(props: { content: ReactNode; @@ -67,6 +74,27 @@ function ScrollToBottom(props: { className?: string }) { ); } +function OpenGitHubRepo() { + return ( + + + + + + + + +

Open GitHub repo

+
+
+
+ ); +} + export function Thread() { const [threadId, setThreadId] = useQueryState("threadId"); const [chatHistoryOpen, setChatHistoryOpen] = useQueryState( @@ -218,19 +246,24 @@ export function Thread() { > {!chatStarted && (
- {(!chatHistoryOpen || !isLargeScreen) && ( - - )} +
+ {(!chatHistoryOpen || !isLargeScreen) && ( + + )} +
+
+ +
)} {chatStarted && ( @@ -270,15 +303,20 @@ export function Thread() { - setThreadId(null)} - > - - +
+
+ +
+ setThreadId(null)} + > + + +