1386 lines · 41.1 KB · TypeScript
RawDownload
import { ApprovalRequestId, isToolLifecycleItemType } from "@t3tools/contracts";import type {  OrchestrationLatestTurn,  OrchestrationThread,  OrchestrationThreadActivity,  ToolLifecycleItemType,  TurnId,  UserInputQuestion,} from "@t3tools/contracts";import { formatDuration } from "@t3tools/shared/orchestrationTiming"; import * as Arr from "effect/Array";import * as Order from "effect/Order"; export interface PendingApproval {  readonly requestId: ApprovalRequestId;  readonly requestKind: "command" | "file-read" | "file-change";  readonly createdAt: string;  readonly detail?: string;} export interface PendingUserInput {  readonly requestId: ApprovalRequestId;  readonly createdAt: string;  readonly questions: ReadonlyArray<UserInputQuestion>;} export interface PendingUserInputDraftAnswer {  readonly selectedOptionLabel?: string;  readonly customAnswer?: string;} export interface ThreadFeedActivity {  readonly id: string;  readonly createdAt: string;  readonly turnId: TurnId | null;  readonly summary: string;  readonly detail: string | null;  readonly fullDetail: string | null;  readonly copyText: string;  readonly icon:    | "agent"    | "alert"    | "check"    | "command"    | "edit"    | "eye"    | "globe"    | "hammer"    | "message"    | "warning"    | "wrench"    | "zap";  readonly toolLike: boolean;  readonly status: "success" | "failure" | "neutral" | null;} const MAX_VISIBLE_WORK_LOG_ENTRIES = 1; type WorkLogToolLifecycleStatus = "inProgress" | "completed" | "failed" | "declined" | "stopped"; interface WorkLogEntry {  id: string;  createdAt: string;  turnId: TurnId | null;  label: string;  detail?: string;  command?: string;  rawCommand?: string;  changedFiles?: ReadonlyArray<string>;  tone: "thinking" | "tool" | "info" | "error";  toolTitle?: string;  itemType?: ToolLifecycleItemType;  requestKind?: PendingApproval["requestKind"];  toolLifecycleStatus?: WorkLogToolLifecycleStatus;  toolData?: unknown;} interface DerivedWorkLogEntry extends WorkLogEntry {  activityKind: OrchestrationThreadActivity["kind"];  collapseKey?: string;} type RawThreadFeedEntry =  | {      readonly type: "message";      readonly id: string;      readonly createdAt: string;      readonly message: OrchestrationThread["messages"][number];    }  | {      readonly type: "activity";      readonly id: string;      readonly createdAt: string;      readonly turnId: TurnId | null;      readonly activity: ThreadFeedActivity;    }; export type ThreadFeedEntry =  | Extract<RawThreadFeedEntry, { type: "message" }>  | {      readonly type: "working";      readonly id: string;      readonly createdAt: string;    }  | {      readonly type: "activity-group";      readonly id: string;      readonly createdAt: string;      readonly turnId: TurnId | null;      readonly activities: ReadonlyArray<ThreadFeedActivity>;    }  | {      readonly type: "work-toggle";      readonly id: string;      readonly createdAt: string;      readonly turnId: TurnId | null;      readonly groupId: string;      readonly hiddenCount: number;      readonly expanded: boolean;      readonly onlyToolActivities: boolean;    }  | {      readonly type: "turn-fold";      readonly id: string;      readonly createdAt: string;      readonly turnId: TurnId;      readonly label: string;      readonly expanded: boolean;    }; export type ThreadFeedLatestTurn = Pick<  OrchestrationLatestTurn,  "turnId" | "state" | "startedAt" | "completedAt">; function requestKindFromRequestType(requestType: unknown): PendingApproval["requestKind"] | null {  switch (requestType) {    case "command_execution_approval":    case "exec_command_approval":      return "command";    case "file_read_approval":      return "file-read";    case "file_change_approval":    case "apply_patch_approval":      return "file-change";    default:      return null;  }} function isStalePendingRequestFailureDetail(detail: string | undefined): boolean {  const normalized = detail?.toLowerCase();  if (!normalized) {    return false;  }  return (    normalized.includes("stale pending approval request") ||    normalized.includes("stale pending user-input request") ||    normalized.includes("unknown pending approval request") ||    normalized.includes("unknown pending permission request") ||    normalized.includes("unknown pending user-input request")  );} function parseApprovalRequestId(value: unknown): ApprovalRequestId | null {  return typeof value === "string" && value.length > 0 ? ApprovalRequestId.make(value) : null;} function parseUserInputQuestions(  payload: Record<string, unknown> | null,): ReadonlyArray<UserInputQuestion> | null {  const questions = payload?.questions;  if (!Array.isArray(questions)) {    return null;  }   const parsed = questions    .map<UserInputQuestion | null>((entry) => {      if (!entry || typeof entry !== "object") return null;      const question = entry as Record<string, unknown>;      if (        typeof question.id !== "string" ||        typeof question.header !== "string" ||        typeof question.question !== "string" ||        !Array.isArray(question.options)      ) {        return null;      }      const options = question.options        .map<UserInputQuestion["options"][number] | null>((option) => {          if (!option || typeof option !== "object") return null;          const record = option as Record<string, unknown>;          if (typeof record.label !== "string" || typeof record.description !== "string") {            return null;          }          return {            label: record.label,            description: record.description,          };        })        .filter((option): option is UserInputQuestion["options"][number] => option !== null);      if (options.length === 0) {        return null;      }      return {        id: question.id,        header: question.header,        question: question.question,        options,        multiSelect: question.multiSelect === true,      };    })    .filter((question): question is UserInputQuestion => question !== null);   return parsed.length > 0 ? parsed : null;} function normalizeDraftAnswer(value: string | undefined): string | null {  if (typeof value !== "string") {    return null;  }  const trimmed = value.trim();  return trimmed.length > 0 ? trimmed : null;} function resolvePendingUserInputAnswer(  draft: PendingUserInputDraftAnswer | undefined,): string | null {  const customAnswer = normalizeDraftAnswer(draft?.customAnswer);  if (customAnswer) {    return customAnswer;  }  return normalizeDraftAnswer(draft?.selectedOptionLabel);} function deriveWorkLogEntries(  activities: ReadonlyArray<OrchestrationThreadActivity>,): DerivedWorkLogEntry[] {  const ordered = Arr.sort(activities, activityOrder);  const entries: DerivedWorkLogEntry[] = [];  for (const activity of ordered) {    if (activity.kind === "tool.started") continue;    if (activity.kind === "task.started") continue;    if (activity.kind === "context-window.updated") continue;    if (activity.summary === "Checkpoint captured") continue;    if (isPlanBoundaryToolActivity(activity)) continue;    entries.push(toDerivedWorkLogEntry(activity));  }  return collapseDerivedWorkLogEntries(entries);} function isPlanBoundaryToolActivity(activity: OrchestrationThreadActivity): boolean {  if (activity.kind !== "tool.updated" && activity.kind !== "tool.completed") {    return false;  }   const payload =    activity.payload && typeof activity.payload === "object"      ? (activity.payload as Record<string, unknown>)      : null;  return typeof payload?.detail === "string" && payload.detail.startsWith("ExitPlanMode:");} function toDerivedWorkLogEntry(activity: OrchestrationThreadActivity): DerivedWorkLogEntry {  const payload =    activity.payload && typeof activity.payload === "object"      ? (activity.payload as Record<string, unknown>)      : null;  const commandPreview = extractToolCommand(payload);  const changedFiles = extractChangedFiles(payload);  const title = extractToolTitle(payload);  const isTaskActivity = activity.kind === "task.progress" || activity.kind === "task.completed";  const taskSummary =    isTaskActivity && typeof payload?.summary === "string" && payload.summary.length > 0      ? payload.summary      : null;  const taskDetailAsLabel =    isTaskActivity &&    !taskSummary &&    typeof payload?.detail === "string" &&    payload.detail.length > 0      ? payload.detail      : null;  const taskLabel = taskSummary || taskDetailAsLabel;  const entry: DerivedWorkLogEntry = {    id: activity.id,    createdAt: activity.createdAt,    turnId: activity.turnId,    label: taskLabel || activity.summary,    tone:      activity.kind === "task.progress"        ? "thinking"        : activity.tone === "approval"          ? "info"          : activity.tone,    activityKind: activity.kind,  };  const itemType = extractWorkLogItemType(payload);  const requestKind = extractWorkLogRequestKind(payload);  if (    !taskDetailAsLabel &&    payload &&    typeof payload.detail === "string" &&    payload.detail.length > 0  ) {    const detail = stripTrailingExitCode(payload.detail).output;    if (detail) {      entry.detail = detail;    }  }  if (commandPreview.command) {    entry.command = commandPreview.command;  }  if (commandPreview.rawCommand) {    entry.rawCommand = commandPreview.rawCommand;  }  if (changedFiles.length > 0) {    entry.changedFiles = changedFiles;  }  if (title) {    entry.toolTitle = title;  }  if (itemType === "mcp_tool_call") {    const data = asRecord(payload?.data);    if (data?.item !== undefined) {      entry.toolData = data.item;    }  }  if (itemType) {    entry.itemType = itemType;  }  if (requestKind) {    entry.requestKind = requestKind;  }  let toolLifecycleStatus = extractWorkLogToolLifecycleStatus(payload);  if (!toolLifecycleStatus && activity.kind === "tool.completed") {    toolLifecycleStatus = "completed";  }  if (toolLifecycleStatus) {    entry.toolLifecycleStatus = toolLifecycleStatus;  }  const collapseKey = deriveToolLifecycleCollapseKey(entry);  if (collapseKey) {    entry.collapseKey = collapseKey;  }  return entry;} function collapseDerivedWorkLogEntries(  entries: ReadonlyArray<DerivedWorkLogEntry>,): DerivedWorkLogEntry[] {  const collapsed: DerivedWorkLogEntry[] = [];  for (const entry of entries) {    const previous = collapsed.at(-1);    if (previous && shouldCollapseToolLifecycleEntries(previous, entry)) {      collapsed[collapsed.length - 1] = mergeDerivedWorkLogEntries(previous, entry);      continue;    }    collapsed.push(entry);  }  return collapsed;} function shouldCollapseToolLifecycleEntries(  previous: DerivedWorkLogEntry,  next: DerivedWorkLogEntry,): boolean {  if (previous.activityKind !== "tool.updated" && previous.activityKind !== "tool.completed") {    return false;  }  if (next.activityKind !== "tool.updated" && next.activityKind !== "tool.completed") {    return false;  }  if (previous.activityKind === "tool.completed") {    return false;  }  return previous.collapseKey !== undefined && previous.collapseKey === next.collapseKey;} function mergeDerivedWorkLogEntries(  previous: DerivedWorkLogEntry,  next: DerivedWorkLogEntry,): DerivedWorkLogEntry {  const changedFiles = mergeChangedFiles(previous.changedFiles, next.changedFiles);  const detail = next.detail ?? previous.detail;  const command = next.command ?? previous.command;  const rawCommand = next.rawCommand ?? previous.rawCommand;  const toolTitle = next.toolTitle ?? previous.toolTitle;  const itemType = next.itemType ?? previous.itemType;  const requestKind = next.requestKind ?? previous.requestKind;  const collapseKey = next.collapseKey ?? previous.collapseKey;  const toolLifecycleStatus = next.toolLifecycleStatus ?? previous.toolLifecycleStatus;  const toolData = next.toolData ?? previous.toolData;  return {    ...previous,    ...next,    ...(detail ? { detail } : {}),    ...(command ? { command } : {}),    ...(rawCommand ? { rawCommand } : {}),    ...(changedFiles.length > 0 ? { changedFiles } : {}),    ...(toolTitle ? { toolTitle } : {}),    ...(itemType ? { itemType } : {}),    ...(requestKind ? { requestKind } : {}),    ...(collapseKey ? { collapseKey } : {}),    ...(toolLifecycleStatus ? { toolLifecycleStatus } : {}),    ...(toolData !== undefined ? { toolData } : {}),  };} function mergeChangedFiles(  previous: ReadonlyArray<string> | undefined,  next: ReadonlyArray<string> | undefined,): string[] {  const merged = [...(previous ?? []), ...(next ?? [])];  if (merged.length === 0) {    return [];  }  return [...new Set(merged)];} function deriveToolLifecycleCollapseKey(entry: DerivedWorkLogEntry): string | undefined {  if (entry.activityKind !== "tool.updated" && entry.activityKind !== "tool.completed") {    return undefined;  }  const normalizedLabel = normalizeCompactToolLabel(entry.toolTitle ?? entry.label);  const detail = entry.detail?.trim() ?? "";  const itemType = entry.itemType ?? "";  if (normalizedLabel.length === 0 && detail.length === 0 && itemType.length === 0) {    return undefined;  }  return [itemType, normalizedLabel, detail].join("\u001f");} function normalizeCompactToolLabel(value: string): string {  return value.replace(/\s+(?:complete|completed)\s*$/i, "").trim();} function workLogEntryIsToolLike(entry: WorkLogEntry): boolean {  if (entry.tone === "tool" || entry.tone === "thinking" || entry.tone === "error") {    return true;  }  if (entry.command !== undefined && entry.command.trim().length > 0) {    return true;  }  if (entry.requestKind !== undefined) {    return true;  }  return entry.itemType !== undefined && isToolLifecycleItemType(entry.itemType);} function toolDetailTextLooksLikeFailure(text: string): boolean {  const normalized = text.toLowerCase();  return (    normalized.includes("file not found") ||    normalized.includes("no files found") ||    normalized.includes("enoent") ||    normalized.includes("no such file or directory") ||    normalized.includes("no such file") ||    normalized.includes("commandnotfoundexception") ||    normalized.includes("command not found") ||    (normalized.includes("cannot find path") && normalized.includes("because it does not exist")) ||    (normalized.includes("is not recognized") && normalized.includes("the term '")) ||    /<exited with exit code\s+[1-9]\d*\s*>/i.test(text) ||    /exit(?:ed)? with exit code\s+[1-9]\d*/i.test(text) ||    /exit code\s*[:\s]\s*[1-9]\d*\b/i.test(text)  );} function workEntryIndicatesToolFailure(entry: WorkLogEntry): boolean {  if (entry.tone === "error") {    return true;  }  if (entry.toolLifecycleStatus === "failed" || entry.toolLifecycleStatus === "declined") {    return true;  }  if (!workLogEntryIsToolLike(entry)) {    return false;  }  return toolDetailTextLooksLikeFailure([entry.detail, entry.command].filter(Boolean).join("\n"));} function workEntryIndicatesToolSuccess(entry: WorkLogEntry): boolean {  if (!workLogEntryIsToolLike(entry) || workEntryIndicatesToolFailure(entry)) {    return false;  }  if (entry.tone === "thinking") {    return false;  }  return (    entry.toolLifecycleStatus !== "inProgress" &&    entry.toolLifecycleStatus !== "stopped" &&    entry.toolLifecycleStatus !== "failed" &&    entry.toolLifecycleStatus !== "declined"  );} function workEntryStatus(entry: WorkLogEntry): ThreadFeedActivity["status"] {  if (!workLogEntryIsToolLike(entry)) {    return null;

Lines 1–500 of 1386.