Developer Dashboard

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

TaskRecommended AvalAI path
Run deterministic CLI toolsApp-managed shell or hosted Shell after route verification
Inspect repository or text filesLocal sandbox with read-only mounts where possible
Generate reports or artifactsWrite to controlled temp storage, then copy approved files to durable storage
Install packages or access the networkRequire an allowlist, approval, and audit logging
Execute user-provided commandsAvoid 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.

python
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)
javascript
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);
  }
}
bash
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, and domain_secrets are 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 patternAvalAI-safe adaptation
Hosted skill_referenceKeep reviewed workflow instructions in repo docs or local files; mount them only in a trusted runtime you control.
Local shell skillsPass the relevant SKILL.md excerpt or file path to your own runner; do not assume hosted skill upload support.
apply_patch_callValidate and apply diffs in your patch harness, then return apply_patch_call_output with success or failure.
Patch + shell loopRun 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:

json
{
  "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:

  1. Match commands against an allowlist; do not execute raw model text.
  2. Run with a clean environment, no inherited secrets, read-only mounts when possible, and short CPU/memory/time limits.
  3. Capture stdout, stderr, exit code, timeout state, and artifact metadata.
  4. Return compact results as function_call_output; store large files in your own storage and return signed URLs only after scanning.
  5. 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.