@@ -538,6 +576,8 @@ export function renderToolCard(
opts: {
expanded: boolean;
onToggleExpanded: (id: string) => void;
+ sessionKey?: string;
+ agentId?: string;
onOpenSidebar?: (content: SidebarContent) => void;
canvasPluginSurfaceUrl?: string | null;
embedSandboxMode?: EmbedSandboxMode;
@@ -570,6 +610,7 @@ export function renderToolCard(
${renderExpandedToolCardContent(
card,
+ opts.sessionKey,
opts.onOpenSidebar,
opts.canvasPluginSurfaceUrl,
opts.embedSandboxMode ?? "scripts",
@@ -584,6 +625,7 @@ export function renderToolCard(
export function renderExpandedToolCardContent(
card: ToolCard,
+ sessionKey?: string,
onOpenSidebar?: (content: SidebarContent) => void,
canvasPluginSurfaceUrl?: string | null,
embedSandboxMode: EmbedSandboxMode = "scripts",
@@ -595,12 +637,17 @@ export function renderExpandedToolCardContent(
const hasInput = Boolean(card.inputText?.trim());
const isError = isToolCardError(card);
const canOpenSidebar = Boolean(onOpenSidebar);
+ const fullMessageRequest = buildToolSidebarFullMessageRequest(card, sessionKey);
const previewSidebarContent =
card.preview?.kind === "canvas"
- ? buildPreviewSidebarContent(card.preview, card.outputText)
+ ? buildPreviewSidebarContent(card.preview, card.outputText, { fullMessageRequest })
: null;
const sidebarActionContent =
- previewSidebarContent ?? buildSidebarContent(buildToolCardSidebarContent(card));
+ previewSidebarContent ??
+ buildSidebarContent(buildToolCardSidebarContent(card), {
+ fullMessageRequest,
+ rawText: card.outputText ?? null,
+ });
const visiblePreview = card.preview
? renderToolPreview(card.preview, "chat_tool", {
onOpenSidebar,
@@ -665,6 +712,7 @@ export function renderToolCardSidebar(
onOpenSidebar?: (content: SidebarContent) => void,
canvasPluginSurfaceUrl?: string | null,
embedSandboxMode: EmbedSandboxMode = "scripts",
+ options?: { sessionKey?: string; agentId?: string },
) {
const display = resolveToolDisplay({ name: card.name, args: card.args });
const detail = formatToolDetail(display);
@@ -672,11 +720,20 @@ export function renderToolCardSidebar(
const hasText = Boolean(card.outputText?.trim());
const hasPreview = Boolean(preview);
const isError = isToolCardError(card);
+ const fullMessageRequest = buildToolSidebarFullMessageRequest(card, options?.sessionKey);
const sidebarContent =
preview?.kind === "canvas"
- ? buildPreviewSidebarContent(preview, card.outputText)
- : buildSidebarContent(buildToolCardSidebarContent(card));
- const actionContent = sidebarContent ?? buildSidebarContent(buildToolCardSidebarContent(card));
+ ? buildPreviewSidebarContent(preview, card.outputText, { fullMessageRequest })
+ : buildSidebarContent(buildToolCardSidebarContent(card), {
+ fullMessageRequest,
+ rawText: card.outputText ?? null,
+ });
+ const actionContent =
+ sidebarContent ??
+ buildSidebarContent(buildToolCardSidebarContent(card), {
+ fullMessageRequest,
+ rawText: card.outputText ?? null,
+ });
const canClick = Boolean(onOpenSidebar);
const handleClick = canClick ? () => onOpenSidebar?.(actionContent) : undefined;
const isShort = hasText && !hasPreview && (card.outputText?.length ?? 0) <= 240;
diff --git a/ui/src/ui/sidebar-content.ts b/ui/src/ui/sidebar-content.ts
index adad3a23f0b..a46b6df5130 100644
--- a/ui/src/ui/sidebar-content.ts
+++ b/ui/src/ui/sidebar-content.ts
@@ -1,7 +1,16 @@
+export type SidebarFullMessageRequest = {
+ sessionKey: string;
+ agentId?: string;
+ messageId: string;
+ kind: "assistant_message" | "tool_output";
+};
+
export type MarkdownSidebarContent = {
kind: "markdown";
content: string;
rawText?: string | null;
+ fullMessageRequest?: SidebarFullMessageRequest;
+ unavailableReason?: "not_found" | "oversized" | "not_visible" | null;
};
export type CanvasSidebarContent = {
@@ -11,6 +20,8 @@ export type CanvasSidebarContent = {
entryUrl: string;
preferredHeight?: number;
rawText?: string | null;
+ fullMessageRequest?: SidebarFullMessageRequest;
+ unavailableReason?: "not_found" | "oversized" | "not_visible" | null;
};
export type SidebarContent = MarkdownSidebarContent | CanvasSidebarContent;
diff --git a/ui/src/ui/types/chat-types.ts b/ui/src/ui/types/chat-types.ts
index e8ba3b28d0d..7ae50ff2ec1 100644
--- a/ui/src/ui/types/chat-types.ts
+++ b/ui/src/ui/types/chat-types.ts
@@ -78,6 +78,7 @@ export type ToolCard = {
inputText?: string;
outputText?: string;
isError?: boolean;
+ messageId?: string;
preview?: {
kind: "canvas";
surface: "assistant_message";
diff --git a/ui/src/ui/views/chat.test.ts b/ui/src/ui/views/chat.test.ts
index 2eb14bc5ea7..9db23b42154 100644
--- a/ui/src/ui/views/chat.test.ts
+++ b/ui/src/ui/views/chat.test.ts
@@ -1248,6 +1248,25 @@ describe("chat sidebar raw content", () => {
rawText: rawMarkdown,
});
});
+
+ it("does not carry full-message requests into raw views", () => {
+ const raw = buildRawSidebarContent({
+ kind: "markdown",
+ content: "Rendered",
+ rawText: "Raw",
+ fullMessageRequest: {
+ sessionKey: "main",
+ messageId: "msg-raw",
+ kind: "assistant_message",
+ },
+ });
+
+ expect(raw).toEqual({
+ kind: "markdown",
+ content: "```\nRaw\n```",
+ rawText: "Raw",
+ });
+ });
});
describe("chat welcome", () => {
diff --git a/ui/src/ui/views/chat.ts b/ui/src/ui/views/chat.ts
index 605ec3a96da..9777d59d40c 100644
--- a/ui/src/ui/views/chat.ts
+++ b/ui/src/ui/views/chat.ts
@@ -165,6 +165,7 @@ export type ChatProps = {
defaultId?: string;
} | null;
currentAgentId: string;
+ fullMessageAgentId?: string;
onAgentChange: (agentId: string) => void;
onNavigateToAgent?: () => void;
onSessionSelect?: (sessionKey: string) => void;
@@ -1262,6 +1263,8 @@ export function renderChat(props: ChatProps) {
}
return renderMessageGroup(item, {
onOpenSidebar: props.onOpenSidebar,
+ sessionKey: props.sessionKey,
+ agentId: props.fullMessageAgentId,
showReasoning,
showToolCalls: props.showToolCalls,
autoExpandToolCalls: Boolean(props.autoExpandToolCalls),
diff --git a/ui/src/ui/views/markdown-sidebar.ts b/ui/src/ui/views/markdown-sidebar.ts
index 819efc8136e..a6da1f9b49f 100644
--- a/ui/src/ui/views/markdown-sidebar.ts
+++ b/ui/src/ui/views/markdown-sidebar.ts
@@ -49,14 +49,18 @@ export function renderMarkdownSidebar(props: MarkdownSidebarProps) {
${props.error
? html`
${props.error}
-
+ ${content?.rawText?.trim()
+ ? html`
+
+ `
+ : nothing}
`
: content
? content.kind === "canvas"