Shell Tool
The Shell tool lets a model request terminal commands for deterministic work such as inspecting files, running scripts, transforming data, or generating artifacts. OpenAI documents both hosted shell containers and local shell runtimes through /v1/responses.
Adapted from OpenAI's official Shell tool guide, with AvalAI endpoint, API key, model, and availability notes.
Warning
In AvalAI, hosted Shell is route-, model-, and account-dependent. Use the hosted tools: [{"type": "shell", ...}] shape only after the selected /v1/responses route explicitly supports it. Otherwise, run commands in your own sandbox and return results through a strict function tool or shell-call loop.
When to Use Shell
| Task | Recommended AvalAI path |
|---|---|
| Run deterministic CLI tools | App-managed shell or hosted Shell after route verification |
| Inspect repository or text files | Local sandbox with read-only mounts where possible |
| Generate reports or artifacts | Write to controlled temp storage, then copy approved files to durable storage |
| Install packages or access the network | Require an allowlist, approval, and audit logging |
| Execute user-provided commands | Avoid by default; require validation, sandboxing, and explicit consent |
Do not use Shell for ordinary text generation, simple math, unrestricted web access, secrets handling, interactive TTY workflows, or destructive commands without human approval.
Hosted Responses Shape
Use this shape only after staging confirms hosted Shell support for the selected AvalAI route.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["AVALAI_API_KEY"],
base_url="https://api.avalai.ir/v1",
)
response = client.responses.create(
model=os.getenv("AVALAI_MODEL", "gpt-5.5"),
instructions=(
"Use the shell only for safe, read-only inspection unless the user "
"explicitly approves a write. Keep commands non-interactive."
),
input="List the current working directory and show the Python version.",
tools=[
{
"type": "shell",
"environment": {"type": "container_auto"},
}
],
tool_choice="auto",
)
print(response.output_text)
for item in response.output:
if item.type == "shell_call":
print("Shell call:", item.call_id, item.action)import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.AVALAI_API_KEY,
baseURL: "https://api.avalai.ir/v1",
});
const response = await client.responses.create({
model: process.env.AVALAI_MODEL ?? "gpt-5.5",
instructions:
"Use the shell only for safe, read-only inspection unless the user explicitly approves a write. Keep commands non-interactive.",
input: "List the current working directory and show the Python version.",
tools: [
{
type: "shell",
environment: { type: "container_auto" },
},
],
tool_choice: "auto",
});
console.log(response.output_text);
for (const item of response.output ?? []) {
if (item.type === "shell_call") {
console.log("Shell call:", item.call_id, item.action);
}
}curl https://api.avalai.ir/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AVALAI_API_KEY" \
-d '{
"model": "gpt-5.5",
"instructions": "Use the shell only for safe, read-only inspection unless the user explicitly approves a write. Keep commands non-interactive.",
"input": "List the current working directory and show the Python version.",
"tools": [
{
"type": "shell",
"environment": { "type": "container_auto" }
}
],
"tool_choice": "auto"
}'Hosted Runtime Notes
OpenAI's hosted shell containers are ephemeral Linux environments. In AvalAI, treat every detail below as a route-specific capability to verify:
- Hosted Shell is a Responses API tool, not a Chat Completions tool.
- Hosted containers can write temporary files and may expose downloadable artifacts when the route supports container/file APIs.
- Reusable containers,
container_reference, attached skill bundles, inline files, anddomain_secretsare hosted-runtime features, not portable guarantees. - Network access should be disabled by default. If enabled, use an organization allowlist plus a narrower request-level
network_policy. - Any third-party endpoint contacted by a shell command has its own data-retention and residency rules.
Skills and Apply Patch
OpenAI's Shell, Skills, and Apply Patch docs describe a richer hosted editing runtime: Skills mount reusable instructions/files, Shell discovers and tests, and apply_patch emits structured file operations. In AvalAI, use that combination only after the selected /v1/responses route explicitly supports each tool. Otherwise, keep the runtime in your own backend and expose narrow function tools.
| OpenAI pattern | AvalAI-safe adaptation |
|---|---|
Hosted skill_reference | Keep reviewed workflow instructions in repo docs or local files; mount them only in a trusted runtime you control. |
| Local shell skills | Pass the relevant SKILL.md excerpt or file path to your own runner; do not assume hosted skill upload support. |
apply_patch_call | Validate and apply diffs in your patch harness, then return apply_patch_call_output with success or failure. |
| Patch + shell loop | Run tests in a sandbox, feed command failures back to the model, and require approval for writes or destructive commands. |
Review Skills as privileged code and instructions. A malicious or overly broad Skill can change tool choices, leak data through shell/network access, or encourage destructive automation. Do not expose an open Skill catalog to end users; map approved Skills to bounded product workflows and approval rules.
App-Managed Shell Fallback
When hosted Shell is not enabled, keep execution in your backend. The safest portable pattern is a strict function tool that asks for a small command plan, not arbitrary shell text:
{
"type": "function",
"name": "run_safe_shell_task",
"description": "Run an approved, non-interactive shell task in a locked-down sandbox.",
"parameters": {
"type": "object",
"properties": {
"task": {
"type": "string"
},
"allowed_command": {
"type": "string"
},
"working_directory": {
"type": "string"
}
},
"required": [
"task",
"allowed_command",
"working_directory"
],
"additionalProperties": false
},
"strict": true
}Implementation checklist:
- Match commands against an allowlist; do not execute raw model text.
- Run with a clean environment, no inherited secrets, read-only mounts when possible, and short CPU/memory/time limits.
- Capture
stdout,stderr, exit code, timeout state, and artifact metadata. - Return compact results as
function_call_output; store large files in your own storage and return signed URLs only after scanning. - Require approval for package installs, network access, writes, deletes, uploads, emails, payments, or anything that changes external state.
Safety Checklist
- Treat command output and fetched web content as untrusted input.
- Never pass API keys, database URLs, SSH keys, or OAuth tokens through prompts, command arguments, stdout, or durable logs.
- Use non-interactive commands only; reject TTY prompts, password prompts, and long-running daemons unless the workflow is explicitly designed for them.
- Log user ID,
x-request-id, model, command plan, policy decision, exit outcome, touched files, and artifact IDs. - Keep hosted Shell, Code Interpreter, and Computer Use separate in product docs: they have different execution models, approval needs, and artifact behavior.