File size: 2,777 Bytes
9332ccf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/**
 * @license
 * Copyright 2026 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

import { type ToolVisibilityContext } from '@google/gemini-cli-core';
import { CoreToolCallStatus } from '../types.js';
import type {
  HistoryItem,
  HistoryItemWithoutId,
  HistoryItemToolGroup,
  IndividualToolCallDisplay,
} from '../types.js';

/**
 * Maps an IndividualToolCallDisplay from the CLI to a ToolVisibilityContext for core logic.
 */
export function buildToolVisibilityContextFromDisplay(
  tool: IndividualToolCallDisplay,
): ToolVisibilityContext {
  return {
    name: tool.originalRequestName ?? tool.name,
    displayName: tool.name, // In CLI, 'name' is usually the resolved display name
    status: tool.status,
    hasResult: !!tool.resultDisplay,
    approvalMode: tool.approvalMode,
    isClientInitiated: tool.isClientInitiated,
    parentCallId: tool.parentCallId,
  };
}

export function getLastTurnToolCallIds(
  history: HistoryItem[],
  pendingHistoryItems: HistoryItemWithoutId[],
): string[] {
  const targetToolCallIds: string[] = [];

  // Find the boundary of the last user prompt
  let lastUserPromptIndex = -1;
  for (let i = history.length - 1; i >= 0; i--) {
    const type = history[i].type;
    if (type === 'user' || type === 'user_shell') {
      lastUserPromptIndex = i;
      break;
    }
  }

  // Collect IDs from history after last user prompt
  history.forEach((item, index) => {
    if (index > lastUserPromptIndex && item.type === 'tool_group') {
      item.tools.forEach((t) => {
        if (t.callId) targetToolCallIds.push(t.callId);
      });
    }
  });

  // Collect IDs from pending items
  pendingHistoryItems.forEach((item) => {
    if (item.type === 'tool_group') {
      item.tools.forEach((t) => {
        if (t.callId) targetToolCallIds.push(t.callId);
      });
    }
  });

  return targetToolCallIds;
}

export function isToolExecuting(
  pendingHistoryItems: HistoryItemWithoutId[],
): boolean {
  return pendingHistoryItems.some((item) => {
    if (item && item.type === 'tool_group') {
      return item.tools.some(
        (tool) => CoreToolCallStatus.Executing === tool.status,
      );
    }
    return false;
  });
}

export function isToolAwaitingConfirmation(
  pendingHistoryItems: HistoryItemWithoutId[],
): boolean {
  return pendingHistoryItems
    .filter((item): item is HistoryItemToolGroup => item.type === 'tool_group')
    .some((item) =>
      item.tools.some(
        (tool) => CoreToolCallStatus.AwaitingApproval === tool.status,
      ),
    );
}

export function getAllToolCalls(
  historyItems: HistoryItemWithoutId[],
): IndividualToolCallDisplay[] {
  return historyItems
    .filter((item): item is HistoryItemToolGroup => item.type === 'tool_group')
    .flatMap((group) => group.tools);
}