* 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.
80 lines
2.5 KiB
TypeScript
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",
|
|
};
|
|
}
|