fix(copilot): render error state in ConnectIntegrationTool

When part.state is 'output-error', show the error message from the
backend (ErrorResponse.message) in red text below the status line.
Without this, errors from unknown/unsupported providers were silently
discarded, leaving the user without any feedback.
This commit is contained in:
Zamil Majdy
2026-03-15 23:51:09 +07:00
parent ec6974e3b8
commit bef292033e

View File

@@ -24,15 +24,36 @@ function parseOutput(raw: unknown): SetupRequirementsResponse | null {
return null;
}
function parseError(raw: unknown): string | null {
try {
let parsed: unknown = raw;
if (typeof raw === "string") {
parsed = JSON.parse(raw);
}
if (parsed && typeof parsed === "object" && "message" in parsed) {
return String((parsed as { message: unknown }).message);
}
} catch {
// ignore parse errors
}
return null;
}
export function ConnectIntegrationTool({ part }: Props) {
const isStreaming =
part.state === "input-streaming" || part.state === "input-available";
const isError = part.state === "output-error";
const output =
part.state === "output-available"
? parseOutput((part as { output?: unknown }).output)
: null;
const errorMessage = isError
? (parseError((part as { output?: unknown }).output) ??
"Failed to connect integration")
: null;
const providerName =
output?.setup_info?.agent_name ??
(part as { input?: { provider?: string } }).input?.provider ??
@@ -40,16 +61,25 @@ export function ConnectIntegrationTool({ part }: Props) {
const label = isStreaming
? `Connecting ${providerName}`
: output
? `Connect ${output.setup_info?.agent_name ?? providerName}`
: `Connect ${providerName}`;
: isError
? `Failed to connect ${providerName}`
: output
? `Connect ${output.setup_info?.agent_name ?? providerName}`
: `Connect ${providerName}`;
return (
<div className="py-2">
<div className="flex items-center gap-2 text-sm text-muted-foreground">
<MorphingTextAnimation text={label} />
<MorphingTextAnimation
text={label}
className={isError ? "text-red-500" : undefined}
/>
</div>
{isError && errorMessage && (
<p className="mt-1 text-sm text-red-500">{errorMessage}</p>
)}
{output && (
<div className="mt-2">
<SetupRequirementsCard