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

// subagents/vercel.ts
import { tool, generateText, stepCountIs } from "ai";
import { z } from "zod";
var DEFAULT_MAX_TURNS = {
  quick: 3,
  medium: 6,
  thorough: 12
};
function getMaxTurns(config) {
  return config.maxTurns ?? DEFAULT_MAX_TURNS[config.thoroughness ?? "medium"] ?? 6;
}
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 replyTimeout = config.replyTimeout ?? 3e4;
  async function runExplore(prompt, callbacks = {}) {
    const startTime = Date.now();
    const allContexts = [];
    let searchCount = 0;
    const timeoutMs = config.timeout;
    const timeoutPromise = timeoutMs ? new Promise(
      (_, reject) => setTimeout(() => reject(new Error(`Exploration timed out after ${timeoutMs}ms`)), timeoutMs)
    ) : null;
    const runPromise = (async () => {
      try {
        const codebaseSearchSchema = z.object({
          searchRequest: z.string().describe("Natural language description of what to search for")
        });
        const sendMessageSchema = z.object({
          message: z.string().describe("The message to send to the orchestrator")
        });
        const result = await generateText({
          model: config.model,
          system: getSystemPrompt(thoroughness),
          prompt,
          tools: {
            codebase_search: tool({
              description: CODEBASE_SEARCH_TOOL.description,
              inputSchema: codebaseSearchSchema,
              execute: async (params) => {
                searchCount++;
                const warpResult = await warpGrep.execute({
                  searchTerm: params.searchRequest,
                  repoRoot: config.repoRoot,
                  excludes: config.excludes,
                  includes: config.includes
                });
                if (warpResult.contexts) {
                  allContexts.push(...warpResult.contexts);
                }
                callbacks.onStep?.({
                  step: searchCount,
                  searchRequest: params.searchRequest,
                  contextsFound: warpResult.contexts?.length ?? 0,
                  isFinal: false
                });
                return formatResult(warpResult);
              }
            }),
            send_message: tool({
              description: SEND_MESSAGE_TOOL.description,
              inputSchema: sendMessageSchema,
              execute: async (params) => {
                const subagentMsg = {
                  from: "explore",
                  content: params.message,
                  timestamp: Date.now()
                };
                const replyPromise = new Promise((resolve) => {
                  if (callbacks.onMessage) {
                    callbacks.onMessage(subagentMsg, (replyText) => {
                      resolve(replyText);
                    });
                  } else {
                    setTimeout(() => resolve(""), replyTimeout);
                  }
                });
                const reply = await Promise.race([
                  replyPromise,
                  new Promise(
                    (resolve) => setTimeout(() => resolve(""), replyTimeout)
                  )
                ]);
                if (reply) {
                  return `Response from orchestrator: ${reply}`;
                }
                return "No response. Continue with your best judgment.";
              }
            })
          },
          stopWhen: stepCountIs(getMaxTurns(config))
        });
        callbacks.onStep?.({
          step: searchCount,
          searchRequest: "",
          contextsFound: allContexts.length,
          isFinal: true
        });
        const uniqueContexts = deduplicateContexts(allContexts);
        return {
          success: true,
          summary: result.text || "Exploration completed but no summary was generated.",
          contexts: uniqueContexts,
          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)
        };
      }
    })();
    if (timeoutPromise) {
      try {
        return await Promise.race([runPromise, timeoutPromise]);
      } catch (error) {
        return {
          success: false,
          summary: "",
          contexts: deduplicateContexts(allContexts),
          searchCount,
          durationMs: Date.now() - startTime,
          error: error instanceof Error ? error.message : String(error)
        };
      }
    }
    return runPromise;
  }
  const exploreToolSchema = z.object({
    searchRequest: z.string().describe("What to explore in the codebase. Be specific about what you want to understand.")
  });
  const exploreTool = tool({
    description: "Explore a codebase to answer questions about code structure, find implementations, trace call chains, and understand architecture. Returns a summary of findings. Use this for broad exploration rather than pinpoint keyword searches.",
    inputSchema: exploreToolSchema,
    execute: async (params) => {
      const result = await runExplore(params.searchRequest);
      return {
        success: result.success,
        summary: result.summary,
        searchCount: result.searchCount,
        error: result.error
      };
    }
  });
  return {
    /** Vercel AI SDK tool for use as a tool 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-S6UA55CG.js.map