import * as n from "zod";
import { C as y } from "./context-chat-message-DzjJbTBD.js";
import A, { isPathComplete as F } from "zod-stream";
import { I as Q } from "./stream-CtDBTPgX.js";
import { a as E } from "./logger-CTb8_yz9.js";
import { b as H, a as D } from "./hooks-Dmyvf9cL.js";
import { O as x, K as w } from "./shared-types-CIxCt9tj.js";
import { AsyncStream as P } from "./async-stream/index.js";
import { Utils as z } from "vscode-uri";
import { a as M } from "./tool-tags-NGeoUHCI.js";
import { W as R, a as K } from "./workspace-object-CspubCq6.js";
import { b as Y } from "./types-core-DBgLqCOQ.js";
import { F as $ } from "./file-lock-D4f90hJ2.js";
import { T as O, a as U } from "./tool-usage-meter-CBzE-MaZ.js";
import { c as B } from "./number-coercion-CeAOJ7Po.js";
import { T as V } from "./telemetry-Bf0GI6nJ.js";
function N(h) {
  return h instanceof Error && (h.name.includes("Abort") || h.message.includes("Aborted"));
}
function Ie(h) {
  const e = h instanceof Error ? h.name : "UnknownError";
  return N(h) ? "AbortedError" : e;
}
const Z = A.default ?? A;
async function* J(h, e) {
  for await (const t of h)
    yield e(t);
}
class L {
  /**
   * Creates a new ChunkStreamedTool
   * @param id - The name of the tool
   * @param description - The description of the tool
   * @param schema - The Zod schema for validating input
   * @param validationSchema - Takes over schema if provided, schema is only used for model tool structure.
   * @param tags - Optional array of tags for categorizing the tool
   */
  constructor(e, t, u, c, i = []) {
    this.id = e, this.description = t, this.schema = u, this.validationSchema = c, this.tags = i;
  }
  /**
   * Processes a stream of tool call chunks
   * @param state - The current graph state
   * @param toolUseId - The unique identifier for this tool use
   * @param requestMessageId - The unique identifier for the message containing this tool request.
   * @param input - The stream of tool call chunks
   * @returns The resulting graph state
   */
  async call(e, t, u, c) {
    const i = new Z();
    try {
      const r = await H(this.id, this.tags, {}, e);
      if (e = r.state, r.hookMessage) {
        const s = {
          id: t,
          name: this.id,
          requestMessageId: u,
          args: {}
        }, o = `Tool "${this.id}" was intercepted by PreToolUse hooks before execution.

Each <HOOK_INSTRUCTION> block below is a separate request that you must address:

${r.hookMessage}

The tool was NOT executed. Address each hook instruction, then decide whether to proceed with the original tool call, modify your approach, or take a different action. If the instructions show an ExitCode that is not 0, it means that the hook failed and you should not process with the origin tool call.`;
        return this.withToolMessage(e, s, o, !1);
      }
    } catch (r) {
      E.warn(
        `PreToolUse hook execution failed for ${this.id}: ${r instanceof Error ? r.message : String(r)}`
      );
    }
    try {
      const r = await i.create({
        completionPromise: () => {
          const o = new TextEncoder(), l = J(c, (a) => a.args ? o.encode(a.args) : new Uint8Array(0));
          return Promise.resolve(Q.fromAsyncGenerator(l));
        },
        response_model: { schema: this.validationSchema ?? this.schema }
      });
      let s = await this.handleInput(e, t, u, r);
      try {
        const o = s.context.messages.at(-1), l = o?.entries.find((p) => p.type === "toolUseResponse"), a = l?.type === "toolUseResponse" ? l.message ?? "" : "", d = l?.type === "toolUseResponse" ? l.success : !1, f = s.context.messages.flatMap((p) => p.entries).find((p) => p.type === "toolUse" && p.id === t), b = f?.type === "toolUse" ? f.args : {}, m = await D(
          this.id,
          this.tags,
          b,
          a,
          d,
          s
        );
        if (s = m.state, m.hookMessage) {
          const p = 'PostToolUse hooks have additional instructions after "' + this.id + `" completed.

Tool result: ` + (d ? "Success" : "Failed") + `

Each <HOOK_INSTRUCTION> block below is a separate request that you must address:

` + m.hookMessage;
          if (o) {
            const g = y.fromTool(o.messageId).withText(p);
            s = {
              ...s,
              context: s.context.withMergedMessage(g)
            };
          }
        }
      } catch (o) {
        E.warn(
          `PostToolUse hook execution failed for ${this.id}: ${o instanceof Error ? o.message : String(o)}`
        );
      }
      return s;
    } catch (r) {
      throw E.error(`Error in ChunkStreamedTool.call: ${r instanceof Error ? r.message : String(r)}`), r;
    }
  }
  withToolMessage(e, t, u, c, i) {
    if (!t)
      return { ...e, context: e.context.withNewMessage(y.fromHuman().withText(u)) };
    const { requestMessageId: r, ...s } = t, o = y.generateResponseMessageId(t.requestMessageId);
    let l = y.fromTool(o).withToolUseResponse({
      ...s,
      message: u,
      success: c
    });
    return i && (l = l.withEntry(i)), {
      ...e,
      context: e.context.withMergedMessage(l)
    };
  }
}
const _ = "50 lines", I = {
  id: "fsWrite",
  description: `A tool for creating files, will override the file at \`path\` if it already exists as a file, and otherwise create a new file. If the content is larger than ${_}, use create with part of the content and then use \`fsAppend\` to add more content.`,
  schema: n.object({
    path: n.string({
      description: "Path to file or directory, e.g. `file.py` or `repo`."
    }),
    text: n.string({
      description: "Contents to write into the file."
    })
  })
};
class Me extends L {
  static id = I.id;
  options;
  constructor(e = {}) {
    super(I.id, I.description, I.schema, void 0, [M.WRITE, M.BUILTIN]), this.options = e;
  }
  async handleInput(e, t, u, c) {
    const i = O.start(U.WriteFile);
    try {
      const r = await this.handleInputInternal(e, t, u, c);
      return i.recordToolSuccess(), r;
    } catch (r) {
      throw i.recordToolFault(r), r;
    }
  }
  async handleInputInternal(e, t, u, c) {
    const i = new P(), r = this.handleCreate(e, t, u, i), s = this.options.getStreamingTextPadForValidation?.() ?? 7;
    let o = "";
    const l = /* @__PURE__ */ new Set();
    try {
      for await (const a of c)
        a.text && (o += a.text), a.path && !l.has(a.path) && F(["path"], a) && (await this.options.checkProtectedPath?.(a.path, t, e), l.add(a.path)), a.path && (this.options.validateFileAccess?.(a.path), o && this.options.validateContent?.(a.path, o)), o = o.slice(-s), i.send(a);
      i.close();
    } catch (a) {
      E.debug("[fsWrite] Failed to write the file", a), a instanceof Error ? i.error(a) : i.error(new Error(String(a)));
    }
    return r;
  }
  async handleCreate(e, t, u, c) {
    let i;
    const r = () => ({
      id: t,
      name: this.id,
      requestMessageId: u,
      args: { path: i?.path, text: i?.text }
    });
    let s, o, l, a, d = !1, f = "";
    const b = new P();
    try {
      let m, p = "";
      for await (const g of c) {
        if (i = g, F(["path"], g) && g.path && !s) {
          try {
            s = await R.fromRelativePath(e.execution.workspace, g.path);
          } catch (S) {
            if (S instanceof K) {
              const { folders: q } = e.execution.workspace.listWorkspaceFolders();
              if (q.length > 0) {
                const G = this.joinPath(q[0].uri, g.path);
                s = R.fromUri(e.execution.workspace, G);
              } else
                throw S;
            } else
              throw S;
          }
          const k = s.uri;
          if (a = this.options.acquireLock ? await this.options.acquireLock(k) : await $.getInstance().acquireLock(k), d = this.options.fileExists ? await this.options.fileExists(k) : !1, d)
            try {
              const { content: S } = await e.execution.workspace.readFile({ file: s });
              f = S.text;
            } catch {
              f = "";
            }
          const v = await e.execution.workspace.writeFile({
            file: s,
            text: b,
            createFile: !0
          });
          m = v.write, o = v.original, l = v.modified, e.execution.emit({
            type: "AgentExecutionAction",
            executionId: e.execution.executionId,
            actionId: t,
            actionState: x.Running,
            actionType: d ? "write" : "create",
            input: {
              file: g.path,
              original: this.uriToString(o),
              modified: this.uriToString(l),
              local: this.uriToString(s.uri),
              originalContent: d ? f : "",
              modifiedContent: p
            }
          });
        }
        const T = g.text ?? "";
        T && T.length !== p.length && (b.send(T.substring(p.length)), p = T);
      }
      if (b.close(), m && s && p && (l = (await m).checkpointUri), !i)
        throw new X();
      if (!i.path)
        throw new ee();
      if (!i.text)
        throw new te();
      return e.execution.emit({
        type: "AgentExecutionAction",
        executionId: e.execution.executionId,
        actionId: t,
        actionState: e.execution.autonomyMode === Y.Autopilot ? x.Accepted : x.PendingAction,
        actionType: d ? "write" : "create",
        input: {
          file: s?.reference,
          original: this.uriToString(o),
          modified: this.uriToString(l),
          local: this.uriToString(s?.uri),
          originalContent: d ? f : "",
          modifiedContent: i.text
        }
      }), this.withToolMessage(e, r(), `Created the ${i.path} file.`, !0);
    } catch (m) {
      const p = N(m), g = m instanceof Error ? m : new Error(String(m));
      if (b.error(g), e.execution.emit({
        type: "AgentExecutionAction",
        executionId: e.execution.executionId,
        errorMessage: p ? "" : g.message,
        actionId: t,
        actionState: p ? x.Canceled : x.Error,
        actionType: d ? "write" : "create",
        input: {
          file: s?.reference,
          original: this.uriToString(o),
          modified: this.uriToString(l),
          local: this.uriToString(s?.uri),
          originalContent: d ? f : "",
          modifiedContent: i?.text
        }
      }), this.options.handleUnauthorizedAccess) {
        const T = this.options.handleUnauthorizedAccess(g, e, r());
        if (T !== e)
          return T;
      }
      return this.withToolMessage(e, r(), `Caught error in create mode: ${g.message}`, !1);
    } finally {
      a && (this.options.releaseLock ? this.options.releaseLock(a) : $.getInstance().releaseLock(a));
    }
  }
  joinPath(e, t) {
    return this.options.joinPath ? this.options.joinPath(e, t) : z.joinPath(e, t);
  }
  uriToString(e) {
    if (e) {
      if (typeof e == "string") return e;
      if (typeof e.toString == "function")
        return e.toString();
    }
  }
}
class C extends w {
  constructor(e) {
    super(`Provided input does not match the required schema for this tool: ${e.toString()}`);
  }
  /** Returns a user-friendly error message for display in the session. */
  get userFacingSessionErrorMessage() {
    return this.message;
  }
}
class X extends w {
  constructor() {
    super("Invalid tool arguments");
  }
  /** Returns a user-friendly error message for display in the session. */
  get userFacingSessionErrorMessage() {
    return "Invalid tool arguments";
  }
}
class ee extends w {
  constructor() {
    super("No path provided");
  }
  /** Returns a user-friendly error message for display in the session. */
  get userFacingSessionErrorMessage() {
    return "No file path provided";
  }
}
class te extends w {
  constructor() {
    super(
      `Either the text arg was not provided or text content provided exceeded the write file limit of ${_}`
    );
  }
  /** Returns a user-friendly error message for display in the session. */
  get userFacingSessionErrorMessage() {
    return "No text content provided";
  }
}
class ke extends w {
  constructor(e, t) {
    super(`String '${e}' not found in ${t}`);
  }
  /** Returns a user-friendly error message for display in the session. */
  get userFacingSessionErrorMessage() {
    return this.message;
  }
}
class ve extends w {
  constructor(e, t) {
    super(`String '${e}' found multiple times in ${t}`);
  }
  /** Returns a user-friendly error message for display in the session. */
  get userFacingSessionErrorMessage() {
    return this.message;
  }
}
class Oe extends w {
  constructor() {
    super("String replace input is missing");
  }
  /** Returns a user-friendly error message for display in the session. */
  get userFacingSessionErrorMessage() {
    return "String replace input is missing";
  }
}
class Ue extends w {
  constructor(e) {
    super(`Missing oldStr parameter for string replace in ${e}`);
  }
  /** Returns a user-friendly error message for display in the session. */
  get userFacingSessionErrorMessage() {
    return this.message;
  }
}
class qe extends w {
  constructor(e) {
    super(`Missing newStr parameter for string replace in ${e}`);
  }
  /** Returns a user-friendly error message for display in the session. */
  get userFacingSessionErrorMessage() {
    return this.message;
  }
}
class Ae extends w {
  constructor(e) {
    super(`User rejected modification of protected file ${e}`);
  }
  /** Returns a user-friendly error message for display in the session. */
  get userFacingSessionErrorMessage() {
    return this.message;
  }
}
class oe extends L {
  /**
   * Creates a new instance of AgentActionHandler
   * @param parameters - Configuration parameters for the action handler
   * @param parameters.id - Unique identifier for the action
   * @param parameters.description - Human readable description of what the action does
   * @param parameters.schema - Zod schema defining the expected input structure
   * @param parameters.validationSchema - Takes over schema if provided, schema is only used for model tool structure.
   * @param parameters.tags - Optional array of tags for categorizing the tool
   */
  constructor({ id: e, description: t, schema: u, validationSchema: c, tags: i }) {
    super(e, t, u, c, i ?? []);
  }
  /**
   * Wrapper to make sync tools looks like async tools.
   */
  async handleInput(e, t, u, c) {
    const i = {
      type: "toolUse",
      requestMessageId: u,
      id: t,
      name: this.id,
      args: {}
    };
    let r;
    for await (const o of c)
      r = o;
    if (!r)
      return this.withSyncToolMessage(e, i, "No input provided, at least an empty object is required", !1).state ?? e;
    i.args = r;
    let s;
    try {
      try {
        s = this.parseInput(r);
      } catch (o) {
        if (o instanceof C) {
          E.warn(`Schema validation failed for action ${this.id}, attempting to number coercion and try again`);
          const l = B(r, this.validationSchema ?? this.schema, this.id);
          s = this.parseInput(l);
        } else
          throw o;
      }
    } catch (o) {
      return this.withSyncToolMessage(e, i, o instanceof Error ? o.message : String(o), !1).state ?? e;
    }
    try {
      return (await this.handle({
        actionId: t,
        input: s,
        state: e,
        streamPosition: 0,
        toolUse: i
      })).state ?? e;
    } catch (o) {
      return this.withSyncToolMessage(e, i, o instanceof Error ? o.message : String(o), !1).state ?? e;
    }
  }
  /**
   * Called to parse the input data right before handling
   */
  parseInput(e) {
    const t = (this.validationSchema ?? this.schema).safeParse(e);
    if (t.error)
      throw new C(t.error);
    return e;
  }
  /**
   * Creates an agent action output with a tool message response
   * @param state - Current sync action handle event state
   * @param toolUse - Tool use entry from chat, undefined if not a tool response
   * @param message - Response message text
   * @param success - Boolean indicating whether the tool operation was successful
   * @param imageBase64Urls - Optional array of base64 encoded image URLs to include
   * @returns AgentActionOutput with updated context containing the new message
   */
  withSyncToolMessage(e, t, u, c, i) {
    if (!t)
      return {
        state: {
          ...e,
          context: e.context.withNewMessage(y.fromHuman().withText(u))
        }
      };
    const { requestMessageId: r, type: s, ...o } = t, l = y.generateResponseMessageId(t.requestMessageId);
    let a = y.fromTool(l).withToolUseResponse({
      ...o,
      message: u,
      success: c
    });
    return i && (a = y.fromTool(l).withToolUseResponse({
      ...o,
      message: u,
      success: c,
      imageBase64Urls: i
    })), {
      state: {
        ...e,
        context: e.context.withMergedMessage(a)
      }
    };
  }
}
var se = Object.defineProperty, ie = Object.getOwnPropertyDescriptor, re = (h, e, t, u) => {
  for (var c = ie(e, t), i = h.length - 1, r; i >= 0; i--)
    (r = h[i]) && (c = r(e, t, c) || c);
  return c && se(e, t, c), c;
};
const W = ["general-question"], j = {
  id: "userInput",
  description: `This tool allows you to get input from the user. You should use this tool if you are stuck and need user input to move forward, or if you want to get more details in addition to the user's request.
  The user has a free text box that they are able to reply to your questions in.

    * Tool Behavior:*
    - This tool enables interactive user input collection during execution
    - Use this tool when additional information is needed to proceed with a task
    - The user will be forced to answer or skip the question to proceed
    - If the user is ready to move on to the next phase, consider them to have answered your previous question in the affirmative and proceed
    
    * Question Formatting:*
    - Format your questions using markdown bold syntax (**question text**) to make them stand out to the user
    - This helps users quickly identify what you're asking them
    
    * Options Support:*
    - You can optionally provide predefined choices using the 'options' parameter
    - Users will see these as selectable options but can also provide free text responses
    - Use options when you want to guide the user toward specific choices while still allowing flexibility
    
    * Sub-Options Support:*
    - Options can have nested 'subOptions' that appear as toggles when the parent option is selected
    - Use subOptions to collect additional preferences when a specific option is chosen
    - The response will include selected sub-options in brackets, e.g., "Option [SubOption1, SubOption2]"`,
  tags: [M.SPEC, M.BUILTIN],
  schema: n.object({
    question: n.string().describe(
      "Describe the question you would like to ask the user. This question will be presented to the user when you use this tool. Format questions in bold using markdown syntax (**question text**) to make them stand out."
    ),
    options: n.array(
      n.union([
        n.string(),
        n.object({
          title: n.string().describe("The display title for this option"),
          description: n.string().describe("Optional detailed description of this option").optional(),
          recommended: n.boolean().describe("Whether this option is recommended").optional(),
          subOptions: n.array(
            n.object({
              title: n.string().describe("The display title for this sub-option"),
              description: n.string().describe("Optional description of this sub-option").optional()
            })
          ).describe("Nested toggle options shown when this option is selected").optional(),
          subOptionsLabel: n.string().describe("Label for the sub-options section").optional()
        })
      ])
    ).describe(
      "Optional array of predefined choices for the user to select from. Can be simple strings or objects with title, description, recommended, and subOptions fields. If provided, the user will see these as selectable options in addition to being able to provide free text."
    ).optional(),
    reason: n.enum(W).describe("The reason the user is being asked for input").optional(),
    metadata: n.object({
      featureName: n.string().nullish().describe('The feature name in kebab-case format (e.g., "user-authentication")')
    }).describe("Optional metadata for specific question types").optional()
  })
}, ne = n.enum(W).describe("The reason the user is being asked for input").optional();
n.object({
  questions: n.record(
    n.string().describe("A short, unique ID of the question"),
    n.object({
      question: n.string().describe(
        "Describe what you would like input on from the user. This question will be presented to the user when you use this action."
      ),
      options: n.array(
        n.union([
          n.string(),
          n.object({
            title: n.string().describe("The display title for this option"),
            description: n.string().describe("Optional detailed description of this option").optional(),
            recommended: n.boolean().describe("Whether this option is recommended").optional(),
            subOptions: n.array(
              n.object({
                title: n.string().describe("The display title for this sub-option"),
                description: n.string().describe("Optional description of this sub-option").optional()
              })
            ).optional(),
            subOptionsLabel: n.string().optional()
          })
        ])
      ).describe("Optional array of predefined choices for the user to select from").optional()
    })
  ),
  reason: ne,
  metadata: n.object({
    featureName: n.string().nullish()
  }).optional()
});
class ae extends oe {
  static id = j.id;
  constructor() {
    super(j);
  }
  async handle(e) {
    let { state: t } = e;
    const { actionId: u, input: c } = e, i = O.start(U.GetUserInput);
    try {
      await t.execution.acquireYield("get-user-input");
    } catch (l) {
      this.emitEvent({ state: t, actionId: u, actionState: x.Error }), i.recordToolFault(l);
      const a = `User input failed: ${l instanceof Error ? l.message : String(l)}`;
      return this.withSyncToolMessage(t, e.toolUse, a, !1), { state: t, output: { questions: [], reason: c.reason } };
    }
    this.emitEvent({ state: t, actionId: u, actionState: x.PendingAction });
    const r = this.getUserInput({
      ...e,
      input: {
        questions: { [u]: { question: c.question, options: c.options } },
        reason: c.reason
      }
    });
    this.emitEvent({ state: t, actionId: u, actionState: x.PendingAction, output: r.output }), t.execution.saveState(t);
    let s;
    try {
      const l = await t.execution.waitForAllQuestions();
      this.emitEvent({
        state: t,
        actionId: u,
        actionState: x.Success,
        output: r.output && {
          questions: r.output.questions.map((a) => l[a.id] ?? a)
        }
      }), s = ce(Object.values(l));
    } finally {
      try {
        await t.execution.releaseYield("get-user-input");
      } catch {
      }
    }
    const { state: o } = this.withSyncToolMessage(r.state ?? t, e.toolUse, s, !0);
    return o && (t = o), t.execution.saveState(t), i.recordToolSuccess(), { state: t, output: r.output };
  }
  /** Maps input questions to UserQuestion format and adds them to execution state. */
  getUserInput({
    state: e,
    input: t
  }) {
    const u = O.start(U.GetUserInput), c = [], i = e.execution.getPendingQuestions();
    for (const [s, o] of Object.entries(t.questions)) {
      if (s.length <= 0) continue;
      const l = { id: s, question: o.question };
      o.options && o.options.length > 0 && (l.options = o.options.map((a, d) => {
        if (typeof a == "string")
          return { id: `${s}-option-${d}`, label: a };
        const f = a;
        return {
          id: `${s}-option-${d}`,
          label: f.title,
          description: f.description,
          recommended: f.recommended ?? !1,
          subOptions: f.subOptions?.map((b, m) => ({
            id: `${s}-option-${d}-sub-${m}`,
            label: b.title,
            description: b.description
          })),
          subOptionsLabel: f.subOptionsLabel
        };
      })), c.push(l);
    }
    const r = {};
    return i.forEach((s) => {
      r[s.id] = s;
    }), c.forEach((s) => {
      r[s.id]?.response || e.execution.addQuestion(s);
    }), u.recordToolSuccess(), { state: e, output: { questions: c, reason: t.reason } };
  }
  emitEvent({
    state: e,
    actionId: t,
    output: u,
    actionState: c
  }) {
    e.execution.emit({
      type: "AgentExecutionAction",
      executionId: e.execution.executionId,
      actionId: t,
      actionState: c,
      actionType: "userInput",
      output: u
    });
  }
}
re([
  V.Trace("Tool.GetUserInput")
], ae.prototype, "handle");
function ce(h) {
  return h.map(
    (e) => `Question ID: ${e.id}
Response: ${e.response?.type === "next-phase" ? "User is ready to move on to the next phase" : e.response?.answer}`
  ).join(`

`);
}
export {
  Me as F,
  ae as G,
  C as I,
  ee as M,
  L as S,
  Ae as U,
  _ as W,
  X as a,
  te as b,
  ke as c,
  Oe as d,
  qe as e,
  Ue as f,
  ve as g,
  oe as h,
  N as i,
  Ie as m
};
//# sourceMappingURL=get-user-input-DpcT69UI.js.map
