Merge branch 'main' into add_env

This commit is contained in:
Brace Sproul
2025-04-02 13:41:46 -07:00
committed by GitHub
3 changed files with 129 additions and 22 deletions

View File

@@ -65,3 +65,60 @@ To use these variables:
3. Restart the application 3. Restart the application
When these environment variables are set, the application will use them instead of showing the setup form. 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.

View File

@@ -0,0 +1,12 @@
export const GitHubSVG = ({ width = "100%", height = "100%" }) => (
<svg
role="img"
viewBox="0 0 24 24"
width={width}
height={height}
xmlns="http://www.w3.org/2000/svg"
>
<title>GitHub</title>
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
</svg>
);

View File

@@ -28,6 +28,13 @@ import { toast } from "sonner";
import { useMediaQuery } from "@/hooks/useMediaQuery"; import { useMediaQuery } from "@/hooks/useMediaQuery";
import { Label } from "../ui/label"; import { Label } from "../ui/label";
import { Switch } from "../ui/switch"; import { Switch } from "../ui/switch";
import { GitHubSVG } from "../icons/github";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "../ui/tooltip";
function StickyToBottomContent(props: { function StickyToBottomContent(props: {
content: ReactNode; content: ReactNode;
@@ -67,6 +74,27 @@ function ScrollToBottom(props: { className?: string }) {
); );
} }
function OpenGitHubRepo() {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<a
href="https://github.com/langchain-ai/agent-chat-ui"
target="_blank"
className="flex items-center justify-center"
>
<GitHubSVG width="24" height="24" />
</a>
</TooltipTrigger>
<TooltipContent side="left">
<p>Open GitHub repo</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}
export function Thread() { export function Thread() {
const [threadId, setThreadId] = useQueryState("threadId"); const [threadId, setThreadId] = useQueryState("threadId");
const [chatHistoryOpen, setChatHistoryOpen] = useQueryState( const [chatHistoryOpen, setChatHistoryOpen] = useQueryState(
@@ -218,19 +246,24 @@ export function Thread() {
> >
{!chatStarted && ( {!chatStarted && (
<div className="absolute top-0 left-0 w-full flex items-center justify-between gap-3 p-2 pl-4 z-10"> <div className="absolute top-0 left-0 w-full flex items-center justify-between gap-3 p-2 pl-4 z-10">
{(!chatHistoryOpen || !isLargeScreen) && ( <div>
<Button {(!chatHistoryOpen || !isLargeScreen) && (
className="hover:bg-gray-100" <Button
variant="ghost" className="hover:bg-gray-100"
onClick={() => setChatHistoryOpen((p) => !p)} variant="ghost"
> onClick={() => setChatHistoryOpen((p) => !p)}
{chatHistoryOpen ? ( >
<PanelRightOpen className="size-5" /> {chatHistoryOpen ? (
) : ( <PanelRightOpen className="size-5" />
<PanelRightClose className="size-5" /> ) : (
)} <PanelRightClose className="size-5" />
</Button> )}
)} </Button>
)}
</div>
<div className="absolute top-2 right-4 flex items-center">
<OpenGitHubRepo />
</div>
</div> </div>
)} )}
{chatStarted && ( {chatStarted && (
@@ -270,15 +303,20 @@ export function Thread() {
</motion.button> </motion.button>
</div> </div>
<TooltipIconButton <div className="flex items-center gap-4">
size="lg" <div className="flex items-center">
className="p-4" <OpenGitHubRepo />
tooltip="New thread" </div>
variant="ghost" <TooltipIconButton
onClick={() => setThreadId(null)} size="lg"
> className="p-4"
<SquarePen className="size-5" /> tooltip="New thread"
</TooltipIconButton> variant="ghost"
onClick={() => setThreadId(null)}
>
<SquarePen className="size-5" />
</TooltipIconButton>
</div>
<div className="absolute inset-x-0 top-full h-5 bg-gradient-to-b from-background to-background/0" /> <div className="absolute inset-x-0 top-full h-5 bg-gradient-to-b from-background to-background/0" />
</div> </div>