import {
  AGENT_CONFIG
} from "./chunk-I3J46TSB.js";

// tools/warp_grep/agent/tools/grep.ts
async function toolGrep(provider, args) {
  const res = await provider.grep(args);
  if (res.error) {
    return { output: res.error };
  }
  if (!res.lines.length) {
    return { output: "no matches" };
  }
  return { output: res.lines.join("\n") };
}

// tools/warp_grep/agent/tools/read.ts
function isValidRange(start, end) {
  return typeof start === "number" && typeof end === "number" && Number.isFinite(start) && Number.isFinite(end) && start > 0 && end >= start;
}
async function toolRead(provider, args) {
  if (args.lines && Array.isArray(args.lines) && args.lines.length > 0) {
    const validRanges = [];
    for (const range of args.lines) {
      if (Array.isArray(range) && range.length >= 2 && isValidRange(range[0], range[1])) {
        validRanges.push([range[0], range[1]]);
      }
    }
    if (validRanges.length === 0) {
      const res2 = await provider.read({ path: args.path });
      if (res2.error) return res2.error;
      if (!res2.lines.length) return "(empty file)";
      return res2.lines.join("\n");
    }
    const chunks = [];
    for (const [start, end] of validRanges) {
      const res2 = await provider.read({ path: args.path, start, end });
      if (res2.error) return res2.error;
      chunks.push(res2.lines.join("\n"));
    }
    if (chunks.every((c) => c === "")) return "(empty file)";
    return chunks.join("\n...\n");
  }
  const res = await provider.read({ path: args.path, start: args.start, end: args.end });
  if (res.error) {
    return res.error;
  }
  if (!res.lines.length) return "(empty file)";
  return res.lines.join("\n");
}

// tools/warp_grep/agent/tools/list_directory.ts
import path from "path";
async function toolListDirectory(provider, args, repoRoot) {
  const maxResults = args.maxResults ?? AGENT_CONFIG.MAX_LIST_RESULTS;
  const maxDepth = args.maxDepth ?? AGENT_CONFIG.MAX_LIST_DEPTH;
  const entries = await provider.listDirectory({
    path: args.path,
    pattern: args.pattern ?? null,
    maxResults,
    maxDepth
  });
  if (!entries.length) return "empty";
  if (repoRoot) {
    const absRoot = repoRoot;
    const lines = entries.map((e) => path.join(absRoot, e.path));
    return lines.join("\n");
  }
  return entries.map((e) => e.path).join("\n");
}

// tools/warp_grep/agent/tools/glob.ts
async function toolGlob(provider, args) {
  const res = await provider.glob(args);
  if (res.error) {
    return res.error;
  }
  if (!res.files.length) {
    return "no matches";
  }
  const header = `Found ${res.totalFound} file(s) matching "${args.pattern}" within ${res.searchDir}, sorted by modification time (newest first):`;
  const body = res.files.join("\n");
  const truncated = res.totalFound > res.files.length ? `
[${res.totalFound - res.files.length} files truncated]` : "";
  return `${header}
---
${body}
---${truncated}`;
}

// tools/warp_grep/agent/tools/finish.ts
function isValidRange2(range) {
  return Array.isArray(range) && range.length >= 2 && typeof range[0] === "number" && typeof range[1] === "number" && Number.isFinite(range[0]) && Number.isFinite(range[1]) && range[0] > 0 && range[1] >= range[0];
}
function extractValidRanges(lines) {
  if (!Array.isArray(lines)) return null;
  const valid = [];
  for (const range of lines) {
    if (isValidRange2(range)) {
      valid.push([range[0], range[1]]);
    }
  }
  return valid.length > 0 ? valid : null;
}
function normalizeFinishFiles(files) {
  return files.map((f) => {
    if (f.lines === "*") return { path: f.path, lines: "*" };
    const validRanges = extractValidRanges(f.lines);
    if (!validRanges) return { path: f.path, lines: "*" };
    return { path: f.path, lines: mergeRanges(validRanges) };
  });
}
async function readFinishFiles(repoRoot, files, reader) {
  const out = [];
  for (const f of files) {
    const validRanges = f.lines === "*" ? null : extractValidRanges(f.lines);
    if (f.lines === "*" || !validRanges) {
      const lines = await reader(f.path);
      out.push({ path: f.path, ranges: "*", content: lines.join("\n") });
    } else {
      const ranges = mergeRanges(validRanges);
      const chunks = [];
      for (let i = 0; i < ranges.length; i++) {
        const [s, e] = ranges[i];
        if (i === 0 && s > 1) {
          chunks.push(`// ... existing code, block starting at line ${s} ...`);
        } else if (i > 0) {
          chunks.push(`// ... existing code, block starting at line ${s} ...`);
        }
        const lines = await reader(f.path, s, e);
        chunks.push(lines.join("\n"));
      }
      out.push({ path: f.path, ranges, content: chunks.join("\n") });
    }
  }
  return out;
}
function mergeRanges(ranges) {
  if (!ranges.length) return [];
  const sorted = [...ranges].sort((a, b) => a[0] - b[0]);
  const merged = [];
  let [cs, ce] = sorted[0];
  for (let i = 1; i < sorted.length; i++) {
    const [s, e] = sorted[i];
    if (s <= ce + 1) {
      ce = Math.max(ce, e);
    } else {
      merged.push([cs, ce]);
      cs = s;
      ce = e;
    }
  }
  merged.push([cs, ce]);
  return merged;
}

// tools/warp_grep/agent/helpers.ts
import path2 from "path";
var TRUNCATED_MARKER = "[truncated for context limit]";
function getMessageSize(m) {
  if (m.role === "tool") return m.content.length;
  if (m.role === "assistant") {
    let size = typeof m.content === "string" ? m.content.length : 0;
    if (m.tool_calls) {
      size += m.tool_calls.reduce((s, tc) => s + tc.function.name.length + tc.function.arguments.length, 0);
    }
    return size;
  }
  return m.content.length;
}
function formatTurnMessage(turnsUsed, maxTurns) {
  const turnsRemaining = maxTurns - turnsUsed;
  if (turnsRemaining === 1) {
    return `
You have used ${turnsUsed} turns, you only have 1 turn remaining. You have run out of turns to explore the code base and MUST call the finish tool now`;
  }
  return `
You have used ${turnsUsed} turn${turnsUsed === 1 ? "" : "s"} and have ${turnsRemaining} remaining`;
}
function calculateContextBudget(messages) {
  const totalChars = messages.reduce((sum, m) => sum + getMessageSize(m), 0);
  const maxChars = AGENT_CONFIG.MAX_CONTEXT_CHARS;
  const percent = Math.floor(totalChars / maxChars * 100);
  const usedK = Math.floor(totalChars / 1e3);
  const maxK = Math.floor(maxChars / 1e3);
  return `<context_budget>${percent}% (${usedK}K/${maxK}K chars)</context_budget>`;
}
async function buildInitialState(repoRoot, searchTerm, provider, options) {
  const budget = calculateContextBudget([]);
  const turnTag = `You have used 0 turns and have ${AGENT_CONFIG.MAX_TURNS} remaining`;
  const treeDepth = options?.search_type === "node_modules" ? 1 : 2;
  const absRoot = repoRoot;
  try {
    const entries = await provider.listDirectory({
      path: ".",
      maxResults: AGENT_CONFIG.MAX_OUTPUT_LINES,
      maxDepth: treeDepth
    });
    const lines = [absRoot];
    for (const e of entries) {
      lines.push(path2.join(absRoot, e.path));
    }
    return `<repo_structure>
${lines.join("\n")}
</repo_structure>

<search_string>
${searchTerm}
</search_string>
${budget}
${turnTag}`;
  } catch {
    return `<repo_structure>
${absRoot}
</repo_structure>

<search_string>
${searchTerm}
</search_string>
${budget}
${turnTag}`;
  }
}
function formatListDirectoryTree(entries) {
  if (!entries.length) return "empty";
  return entries.map((e) => {
    const indent = "  ".repeat(e.depth);
    const name = e.type === "dir" ? `${e.name}/` : e.name;
    return `${indent}${name}`;
  }).join("\n");
}
function enforceContextLimit(messages, maxChars = AGENT_CONFIG.MAX_CONTEXT_CHARS) {
  const getTotalChars = () => messages.reduce((sum, m) => sum + getMessageSize(m), 0);
  if (getTotalChars() <= maxChars) {
    return messages;
  }
  const truncatableIndices = [];
  let firstUserSkipped = false;
  for (let i = 0; i < messages.length; i++) {
    const m = messages[i];
    if (m.role === "tool") {
      truncatableIndices.push(i);
    } else if (m.role === "user") {
      if (!firstUserSkipped) {
        firstUserSkipped = true;
        continue;
      }
      truncatableIndices.push(i);
    }
  }
  for (const idx of truncatableIndices) {
    if (getTotalChars() <= maxChars) {
      break;
    }
    const m = messages[idx];
    if (m.role === "tool" && m.content !== TRUNCATED_MARKER) {
      messages[idx] = { role: "tool", tool_call_id: m.tool_call_id, content: TRUNCATED_MARKER };
    } else if (m.role === "user" && m.content !== TRUNCATED_MARKER) {
      messages[idx] = { role: "user", content: TRUNCATED_MARKER };
    }
  }
  return messages;
}

export {
  toolGrep,
  toolRead,
  toolListDirectory,
  toolGlob,
  normalizeFinishFiles,
  readFinishFiles,
  formatTurnMessage,
  calculateContextBudget,
  buildInitialState,
  formatListDirectoryTree,
  enforceContextLimit
};
//# sourceMappingURL=chunk-VNAGVCSP.js.map