Files
paseo/packages/app/src/tool-calls/presentation.ts
T
Mohamed BoudraandGitHub 53c14d9855 Extract client SDK package (#1052)
* Extract client SDK package

* Polish SDK client identity defaults

* Build client before dependent CI jobs

* Restore daemon client server export

* Extract protocol and client SDK packages

* Fix provider override schema validation

* Fix app test daemon client imports

* Simplify workspace build targets

* Fix CLI test server build bootstrap

* Run SDK package tests in CI

* Fix rebase package split drift

* Restore lockfile registry metadata

* Update SDK config test for prompt default

* Move terminal stream router test to client package

* Fix rebase drift for protocol imports

* Fix SDK agent capability fixture

* Restore legacy server client exports

* Fix server export compatibility test

* Advertise custom mode icon client capability

* Remove server daemon-client exports

* Format rebased mode control import

* Fix rebase drift for protocol imports

Files added by upstream PRs (#893, #1147, #1154) referenced the pre-split
shared/ paths that this branch moves into @getpaseo/protocol. Redirect
those imports to the protocol package so typecheck stays green after the
rebase.
2026-05-28 01:58:18 +08:00

80 lines
2.5 KiB
TypeScript

import type { ComponentType } from "react";
import type { ToolCallDetail } from "@getpaseo/protocol/agent-types";
import type { ToolCallDisplayInput } from "@/utils/tool-call-display";
import { buildToolCallDisplayModel } from "@/utils/tool-call-display";
import { extractToolCallFilePath } from "@/utils/extract-tool-call-file-path";
import {
hasMeaningfulToolCallDetail,
isPendingToolCallDetail,
} from "@/utils/tool-call-detail-state";
type ToolCallStatus = "executing" | "running" | "completed" | "failed" | "canceled";
export type ToolCallPresentationIcon = ComponentType<{ size?: number; color?: string }>;
interface BuildToolCallPresentationInput {
toolName: string;
status: ToolCallStatus;
error: unknown;
detail?: ToolCallDetail;
cwd?: string;
metadata?: Record<string, unknown>;
resolveIcon: ToolCallIconResolver;
}
export interface ToolCallPresentation {
displayName: string;
summary?: string;
errorText?: string;
icon: ToolCallPresentationIcon;
isLoadingDetails: boolean;
hasDetails: boolean;
canOpenDetails: boolean;
openFilePath: string | null;
isPlan: boolean;
}
export type ToolCallIconResolver = (
toolName: string,
detail: ToolCallDetail | undefined,
) => ToolCallPresentationIcon;
function displayStatus(status: ToolCallStatus): ToolCallDisplayInput["status"] {
return status === "executing" ? "running" : status;
}
function displayDetail(detail: ToolCallDetail | undefined): ToolCallDetail {
return detail ?? { type: "unknown", input: null, output: null };
}
export function buildToolCallPresentation(
input: BuildToolCallPresentationInput,
): ToolCallPresentation {
const detailForDisplay = displayDetail(input.detail);
const displayModel = buildToolCallDisplayModel({
name: input.toolName,
status: displayStatus(input.status),
error: input.error ?? null,
detail: detailForDisplay,
metadata: input.metadata,
cwd: input.cwd,
});
const isLoadingDetails = isPendingToolCallDetail({
detail: input.detail,
status: input.status,
error: input.error,
});
const hasDetails = Boolean(input.error) || hasMeaningfulToolCallDetail(input.detail);
return {
displayName: displayModel.displayName,
summary: displayModel.summary,
errorText: displayModel.errorText,
icon: input.resolveIcon(input.toolName, input.detail),
isLoadingDetails,
hasDetails,
canOpenDetails: hasDetails || isLoadingDetails,
openFilePath: extractToolCallFilePath(input.detail),
isPlan: input.detail?.type === "plan",
};
}