Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

108 lines
4.1 KiB
TypeScript

import type { JSX } from "react";
import { MessageSquareMoreIcon } from "../../../../app/renderer/components/icons/MessageSquareMoreIcon";
import { translate } from "../../../../i18n/index";
import {
ToolMarkdownBlock,
ToolSection,
type AgentToolRendererProps
} from "./agentToolContentShared";
export function AgentAskUserQuestionContent({
call,
onLinkClick
}: AgentToolRendererProps): JSX.Element | null {
"use memo";
const questions = call.askUserQuestion?.questions ?? [];
const outputText = stringValue(call.output?.text);
if (questions.length === 0) {
return null;
}
return (
<div className="workspace-agents-status-panel__detail-tool-body">
<ToolSection title={translate("agentHost.agentTool.details.questions")}>
<div className="workspace-agents-status-panel__detail-tool-stack">
{questions.map((question) => {
const body =
question.question ||
question.header ||
translate("agentHost.agentTool.details.questionFallback");
const answer = formatAnswer(question.answer);
const questionKey =
question.id.trim() ||
`${question.header}:${question.question}:${question.options.map((option) => option.label).join("|")}`;
return (
<div
key={questionKey}
className="workspace-agents-status-panel__detail-tool-stack-item"
>
<div className="workspace-agents-status-panel__detail-tool-question">
{body}
</div>
{question.options.length > 0 ? (
<div className="workspace-agents-status-panel__detail-tool-stack">
{question.options.map((option) => (
<div
key={`${questionKey}-option-${option.label}:${option.description}`}
className="workspace-agents-status-panel__detail-tool-stack-item"
>
<div className="workspace-agents-status-panel__detail-tool-summary">
{option.label}
</div>
{option.description ? (
<div className="workspace-agents-status-panel__detail-tool-answer workspace-agents-status-panel__detail-tool-answer--muted">
{option.description}
</div>
) : null}
</div>
))}
</div>
) : null}
{answer ? (
<div className="workspace-agents-status-panel__detail-tool-answer">
{translate("agentHost.agentTool.details.answerPrefix", {
answer
})}
</div>
) : (
<div className="workspace-agents-status-panel__detail-tool-answer workspace-agents-status-panel__detail-tool-answer--muted inline-flex items-center gap-1.5">
<MessageSquareMoreIcon
size={14}
active
aria-hidden="true"
className="shrink-0"
/>
{translate("agentHost.agentTool.details.waitingForAnswer")}
</div>
)}
</div>
);
})}
</div>
</ToolSection>
{outputText ? (
<ToolSection title={translate("agentHost.agentTool.details.output")}>
<ToolMarkdownBlock
content={outputText}
onLinkClick={onLinkClick}
collapsible
/>
</ToolSection>
) : null}
</div>
);
}
function formatAnswer(
answer: string | string[] | null | undefined
): string | null {
if (Array.isArray(answer)) {
return answer.filter((value) => value.trim()).join(", ") || null;
}
return typeof answer === "string" && answer.trim() ? answer.trim() : null;
}
function stringValue(value: unknown): string | null {
return typeof value === "string" && value.trim() ? value.trim() : null;
}