import { tool } from "@langchain/core/tools";
import { z } from "zod/v4";
//#region src/tools/shell.ts
const ShellActionSchema = z.object({
	commands: z.array(z.string()).describe("Array of shell commands to execute"),
	timeout_ms: z.number().optional().describe("Optional timeout in milliseconds for the commands"),
	max_output_length: z.number().optional().describe("Optional maximum number of characters to return from each command")
});
const TOOL_NAME = "shell";
/**
* Creates a Shell tool that allows models to run shell commands through your integration.
*
* The shell tool allows the model to interact with your local computer through a controlled
* command-line interface. The model proposes shell commands; your integration executes them
* and returns the outputs. This creates a simple plan-execute loop that lets models inspect
* the system, run utilities, and gather data until they can finish the task.
*
* **Important**: The shell tool is available through the Responses API for use with `GPT-5.1`.
* It is not available on other models, or via the Chat Completions API.
*
* **When to use**:
* - **Automating filesystem or process diagnostics** – For example, "find the largest PDF
*   under ~/Documents" or "show running gunicorn processes."
* - **Extending the model's capabilities** – Using built-in UNIX utilities, python runtime
*   and other CLIs in your environment.
* - **Running multi-step build and test flows** – Chaining commands like `pip install` and `pytest`.
* - **Complex agentic coding workflows** – Using other tools like `apply_patch` to complete
*   workflows that involve complex file operations.
*
* **How it works**:
* The tool operates in a continuous loop:
* 1. Model sends shell commands (`shell_call` with `commands` array)
* 2. Your code executes the commands (can be concurrent)
* 3. You return stdout, stderr, and outcome for each command
* 4. Repeat until the task is complete
*
* **Security Warning**: Running arbitrary shell commands can be dangerous.
* Always sandbox execution or add strict allow/deny-lists before forwarding
* a command to the system shell.
*
* @see {@link https://platform.openai.com/docs/guides/tools-shell | OpenAI Shell Documentation}
* @see {@link https://github.com/openai/codex | Codex CLI} for reference implementation.
*
* @param options - Configuration for the Shell tool
* @returns A Shell tool that can be passed to `bindTools`
*
* @example
* ```typescript
* import { ChatOpenAI, tools } from "@langchain/openai";
* import { exec } from "child_process/promises";
*
* const model = new ChatOpenAI({ model: "gpt-5.1" });
*
* // With execute callback for automatic command handling
* const shellTool = tools.shell({
*   execute: async (action) => {
*     const outputs = await Promise.all(
*       action.commands.map(async (cmd) => {
*         try {
*           const { stdout, stderr } = await exec(cmd, {
*             timeout: action.timeout_ms ?? undefined,
*           });
*           return {
*             stdout,
*             stderr,
*             outcome: { type: "exit" as const, exit_code: 0 },
*           };
*         } catch (error) {
*           const timedOut = error.killed && error.signal === "SIGTERM";
*           return {
*             stdout: error.stdout ?? "",
*             stderr: error.stderr ?? String(error),
*             outcome: timedOut
*               ? { type: "timeout" as const }
*               : { type: "exit" as const, exit_code: error.code ?? 1 },
*           };
*         }
*       })
*     );
*     return {
*       output: outputs,
*       maxOutputLength: action.max_output_length,
*     };
*   },
* });
*
* const llmWithShell = model.bindTools([shellTool]);
* const response = await llmWithShell.invoke(
*   "Find the largest PDF file in ~/Documents"
* );
* ```
*
* @example
* ```typescript
* // Full shell loop example
* async function shellLoop(model, task) {
*   let response = await model.invoke(task, {
*     tools: [tools.shell({ execute: myExecutor })],
*   });
*
*   while (true) {
*     const shellCall = response.additional_kwargs.tool_outputs?.find(
*       (output) => output.type === "shell_call"
*     );
*
*     if (!shellCall) break;
*
*     // Execute commands (with proper sandboxing!)
*     const result = await executeCommands(shellCall.action);
*
*     // Send output back to model
*     response = await model.invoke([
*       response,
*       {
*         type: "shell_call_output",
*         call_id: shellCall.call_id,
*         output: result.output,
*         max_output_length: result.maxOutputLength,
*       },
*     ], {
*       tools: [tools.shell({ execute: myExecutor })],
*     });
*   }
*
*   return response;
* }
* ```
*
* @remarks
* - Only available through the Responses API (not Chat Completions)
* - Designed for use with `gpt-5.1` model
* - Commands are provided as an array of strings that can be executed concurrently
* - Action includes: `commands`, `timeout_ms`, `max_output_length`
* - Always sandbox or validate commands before execution
* - The `timeout_ms` from the model is only a hint—enforce your own limits
* - If `max_output_length` exists in the action, always pass it back in the output
* - Many CLI tools return non-zero exit codes for warnings; still capture stdout/stderr
*/
function shell(options) {
	const executeWrapper = async (action) => {
		const result = await options.execute(action);
		return JSON.stringify({
			output: result.output,
			max_output_length: result.maxOutputLength
		});
	};
	const shellTool = tool(executeWrapper, {
		name: TOOL_NAME,
		description: "Execute shell commands in a managed environment. Commands can be run concurrently.",
		schema: ShellActionSchema
	});
	shellTool.extras = {
		...shellTool.extras ?? {},
		providerToolDefinition: { type: "shell" }
	};
	return shellTool;
}
//#endregion
export { shell };

//# sourceMappingURL=shell.js.map