Packages
nous
0.14.2
0.17.0
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.8
0.15.7
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.17
0.12.16
0.12.15
0.12.14
0.12.13
0.12.12
0.12.11
0.12.9
0.12.7
0.12.6
0.12.5
0.12.3
0.12.2
0.12.0
0.11.3
0.11.0
0.10.1
0.10.0
0.9.0
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.5.0
AI agent framework for Elixir with multi-provider LLM support
Current section
Files
Jump to
Current section
Files
lib/nous/tools/bash.ex
defmodule Nous.Tools.Bash do
@moduledoc """
Shell command execution tool.
Uses `NetRunner` for safe process execution with automatic timeout
handling and output size limits. Zero zombie processes guaranteed.
## Security
Commands run as the current OS user. Use `Nous.Permissions` to gate
access to this tool in production.
"""
@behaviour Nous.Tool.Behaviour
@default_timeout 120_000
@max_output_size 1_000_000
@impl true
def metadata do
%{
name: "bash",
description: "Execute a shell command and return its output.",
category: :execute,
requires_approval: true,
parameters: %{
"type" => "object",
"properties" => %{
"command" => %{
"type" => "string",
"description" => "The shell command to execute"
},
"timeout" => %{
"type" => "integer",
"description" => "Timeout in milliseconds. Defaults to 120000 (2 minutes)."
}
},
"required" => ["command"]
}
}
end
@impl true
def execute(_ctx, %{"command" => command} = args) do
timeout = Map.get(args, "timeout", @default_timeout)
result =
NetRunner.run(["sh", "-c", command],
timeout: timeout,
max_output_size: @max_output_size
)
case result do
{:error, :timeout} ->
{:error, "Command timed out after #{timeout}ms"}
{:error, {:max_output_exceeded, partial}} ->
{:ok, "#{partial}\n\n[Output truncated at #{@max_output_size} bytes]"}
{:error, reason} ->
{:error, "Command failed: #{inspect(reason)}"}
{output, 0} ->
{:ok, output}
{output, exit_code} ->
{:ok, "Exit code: #{exit_code}\n#{output}"}
end
end
end