import {
  WarpGrepClient,
  formatResult
} from "./chunk-75F5XTPD.js";
import {
  CODEBASE_SEARCH_TOOL,
  SEND_MESSAGE_TOOL,
  getSystemPrompt
} from "./chunk-ZZ25FZG2.js";

// subagents/anthropic.ts
var DEFAULT_MAX_TURNS = {
  quick: 3,
  medium: 6,
  thorough: 12
};
function getMaxTurns(config) {
  return config.maxTurns ?? DEFAULT_MAX_TURNS[config.thoroughness ?? "medium"] ?? 6;
}
var TOOLS = [
  {
    name: CODEBASE_SEARCH_TOOL.name,
    description: CODEBASE_SEARCH_TOOL.description,
    input_schema: CODEBASE_SEARCH_TOOL.input_schema
  },
  {
    name: SEND_MESSAGE_TOOL.name,
    description: SEND_MESSAGE_TOOL.description,
    input_schema: SEND_MESSAGE_TOOL.input_schema
  }
];
function createExploreSubagent(config) {
  if (!config.repoRoot) {
    throw new Error("repoRoot is required for Explore subagent");
  }
  const warpGrep = new WarpGrepClient({
    morphApiKey: config.morphApiKey
  });
  const thoroughness = config.thoroughness ?? "medium";
  const maxTurns = getMaxTurns(config);
  const replyTimeout = config.replyTimeout ?? 3e4;
  async function runExplore(prompt, callbacks = {}) {
    const startTime = Date.now();
    const allContexts = [];
    let searchCount = 0;
    const timeoutMs = config.timeout;
    try {
      const messages = [{ role: "user", content: prompt }];
      let turns = 0;
      while (turns < maxTurns) {
        if (timeoutMs && Date.now() - startTime > timeoutMs) {
          return {
            success: false,
            summary: "",
            contexts: deduplicateContexts(allContexts),
            searchCount,
            durationMs: Date.now() - startTime,
            error: `Exploration timed out after ${timeoutMs}ms`
          };
        }
        const response = await config.client.messages.create({
          model: config.model,
          max_tokens: 4096,
          system: getSystemPrompt(thoroughness),
          tools: TOOLS,
          messages
        });
        turns++;
        if (response.stop_reason === "end_turn" || !response.content.some((b) => b.type === "tool_use")) {
          const textBlock = response.content.find((b) => b.type === "text");
          const summary = textBlock?.text || "Exploration completed but no summary was generated.";
          callbacks.onStep?.({
            step: searchCount,
            searchRequest: "",
            contextsFound: allContexts.length,
            isFinal: true
          });
          return {
            success: true,
            summary,
            contexts: deduplicateContexts(allContexts),
            searchCount,
            durationMs: Date.now() - startTime
          };
        }
        messages.push({ role: "assistant", content: response.content });
        const toolResults = [];
        for (const block of response.content) {
          if (block.type !== "tool_use") continue;
          if (block.name === "codebase_search") {
            searchCount++;
            const input = block.input;
            const warpResult = await warpGrep.execute({
              searchTerm: input.searchRequest,
              repoRoot: config.repoRoot,
              excludes: config.excludes,
              includes: config.includes
            });
            if (warpResult.contexts) {
              allContexts.push(...warpResult.contexts);
            }
            callbacks.onStep?.({
              step: searchCount,
              searchRequest: input.searchRequest,
              contextsFound: warpResult.contexts?.length ?? 0,
              isFinal: false
            });
            toolResults.push({
              type: "tool_result",
              tool_use_id: block.id,
              content: formatResult(warpResult)
            });
          } else if (block.name === "send_message") {
            const input = block.input;
            const subagentMsg = {
              from: "explore",
              content: input.message,
              timestamp: Date.now()
            };
            let replyText = "";
            if (callbacks.onMessage) {
              replyText = await Promise.race([
                new Promise((resolve) => {
                  callbacks.onMessage(subagentMsg, (text) => {
                    resolve(text);
                  });
                }),
                new Promise(
                  (resolve) => setTimeout(() => resolve(""), replyTimeout)
                )
              ]);
            }
            const toolResponse = replyText ? `Response from orchestrator: ${replyText}` : "No response. Continue with your best judgment.";
            toolResults.push({
              type: "tool_result",
              tool_use_id: block.id,
              content: toolResponse
            });
          }
        }
        messages.push({ role: "user", content: toolResults });
      }
      return {
        success: true,
        summary: "Exploration completed (max turns reached).",
        contexts: deduplicateContexts(allContexts),
        searchCount,
        durationMs: Date.now() - startTime
      };
    } catch (error) {
      return {
        success: false,
        summary: "",
        contexts: deduplicateContexts(allContexts),
        searchCount,
        durationMs: Date.now() - startTime,
        error: error instanceof Error ? error.message : String(error)
      };
    }
  }
  const exploreTool = Object.assign(
    {
      name: "explore",
      description: "Explore a codebase to answer questions about code structure, find implementations, trace call chains, and understand architecture. Returns a summary of findings.",
      input_schema: {
        type: "object",
        properties: {
          searchRequest: {
            type: "string",
            description: "What to explore in the codebase. Be specific about what you want to understand."
          }
        },
        required: ["searchRequest"]
      }
    },
    {
      execute: async (input) => {
        return runExplore(input.searchRequest);
      },
      formatResult: (result) => {
        if (!result.success) {
          return `Exploration failed: ${result.error}`;
        }
        return result.summary;
      }
    }
  );
  return {
    /** Anthropic Tool definition for use in parent agents */
    tool: exploreTool,
    /** Run exploration with messaging support */
    run(prompt) {
      const messageHandlers = [];
      const stepHandlers = [];
      let resultPromise = null;
      const session = {
        on(event, handler) {
          if (event === "message") messageHandlers.push(handler);
          if (event === "step") stepHandlers.push(handler);
          return session;
        },
        send(_text) {
        },
        get result() {
          if (!resultPromise) {
            resultPromise = runExplore(prompt, {
              onStep: (step) => {
                for (const handler of stepHandlers) handler(step);
              },
              onMessage: (msg, reply) => {
                if (messageHandlers.length > 0) {
                  for (const handler of messageHandlers) handler(msg, reply);
                } else {
                  reply("");
                }
              }
            });
          }
          return resultPromise;
        }
      };
      return session;
    },
    /** Stream exploration events as an async generator */
    async *stream(prompt) {
      const events = [];
      let resolveNext = null;
      let done = false;
      const resultPromise = runExplore(prompt, {
        onStep: (step) => {
          events.push({
            type: "step",
            step: step.step,
            searchRequest: step.searchRequest,
            contextsFound: step.contextsFound,
            isFinal: step.isFinal
          });
          resolveNext?.();
        },
        onMessage: (msg, reply) => {
          events.push({
            type: "message",
            from: msg.from,
            content: msg.content,
            timestamp: msg.timestamp
          });
          resolveNext?.();
          reply("Continue with your best judgment.");
        }
      });
      while (!done) {
        if (events.length > 0) {
          yield events.shift();
        } else {
          const raceResult = await Promise.race([
            resultPromise.then((r) => ({ type: "done", result: r })),
            new Promise((resolve) => {
              resolveNext = () => resolve({ type: "event" });
            })
          ]);
          if (raceResult.type === "done") {
            while (events.length > 0) {
              yield events.shift();
            }
            done = true;
            return raceResult.result;
          }
        }
      }
      return await resultPromise;
    }
  };
}
function deduplicateContexts(contexts) {
  const map = /* @__PURE__ */ new Map();
  for (const ctx of contexts) {
    const existing = map.get(ctx.file);
    if (!existing || ctx.content.length > existing.content.length) {
      map.set(ctx.file, ctx);
    }
  }
  return Array.from(map.values());
}

export {
  createExploreSubagent
};
//# sourceMappingURL=chunk-GF3IGJ77.js.map