Metadata-Version: 2.4
Name: gede
Version: 0.4.37
Summary: A powerful CLI for interacting with multiple LLM providers. Support 10+ providers with smart chat management, encryption, MCP servers, and rich tools ecosystem.
Project-URL: Homepage, https://github.com/adow/gede
Project-URL: Documentation, https://github.com/adow/gede#readme
Project-URL: Repository, https://github.com/adow/gede.git
Project-URL: Bug Tracker, https://github.com/adow/gede/issues
Project-URL: Changelog, https://github.com/adow/gede/blob/main/CHANGELOG.md
Author-email: adow <reynoldqin@gmail.com>
Maintainer-email: adow <reynoldqin@gmail.com>
License: MIT
License-File: LICENSE
Keywords: AI,Anthropic,CLI,ChatGPT,DeepSeek,LLM,OpenAI
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: Chinese (Simplified)
Classifier: Natural Language :: English
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Utilities
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: anthropic>=0.77.0
Requires-Dist: anyio>=4.9.0
Requires-Dist: beautifulsoup4>=4.15.0
Requires-Dist: cryptography>=44.0.2
Requires-Dist: e2b-code-interpreter<3,>=2.8.1
Requires-Dist: fastapi>=0.115.0
Requires-Dist: httpx>=0.28.1
Requires-Dist: inquirer>=3.4.1
Requires-Dist: mcp>=1.12.4
Requires-Dist: openai-agents>=0.2.11
Requires-Dist: prompt-toolkit>=3.0.52
Requires-Dist: pydantic>=2.10.6
Requires-Dist: pyfiglet>=1.0.4
Requires-Dist: pytest-asyncio>=1.3.0
Requires-Dist: pytest>=9.0.2
Requires-Dist: python-dotenv>=1.2.1
Requires-Dist: python-multipart>=0.0.20
Requires-Dist: rich>=13.9.4
Requires-Dist: tena>=0.1.1
Requires-Dist: uvicorn>=0.34.0
Provides-Extra: arize-trace
Requires-Dist: arize-phoenix-otel>=0.13.1; extra == 'arize-trace'
Requires-Dist: openinference-instrumentation-openai-agents>=1.3.0; extra == 'arize-trace'
Description-Content-Type: text/markdown

# Gede

> 🚀 A powerful and feature-rich CLI for interacting with multiple LLM providers

Gede is a powerful command-line interface that seamlessly integrates with multiple
LLM providers including OpenAI, Anthropic, and DeepSeek. It features local chat
history management, built-in tool calling capabilities, and MCP (Model Context
Protocol) integration for enhanced AI interactions.

## Features

- 🤖 **Multi-Provider Support**: OpenAI, Anthropic, DeepSeek, Qwen, Baidu, OpenRouter, Moonshot, Ollama, and more
- 💬 **Chat Management**: Create public, private (encrypted), and cloned conversations
- 🛠️ **Rich Tools Ecosystem**: Built-in web search, URL reading, and custom tools
- 🔌 **MCP Server Integration**: Connect to Model Context Protocol servers
- 📦 **Profile Support**: Manage multiple configurations with profiles
- 🌐 **Web Search**: Enable AI model's built-in web search capability
- 🖥️ **API Server**: Built-in HTTP API server for GUI client integration

## Quick Start

### Prerequisites

- Python 3.10 or higher
- `uv` package manager

## Install

uv tool install gede

### Quick Example

```bash
# Start a new chat
gede

# Or start with a specific model
gede --model openai:gpt-4o

# Start in private mode
gede --private

# Use with tools enabled
gede --tools web_search,now
```

## Slash Commands

When using Gede, you can use slash commands to perform various operations. Type `/help` to see all commands, or `/help KEYWORD` to search for specific commands.

### Chat Management

| Command        | Description                                                                        |
| -------------- | ---------------------------------------------------------------------------------- |
| `/new`         | Start a new public chat (plain text)                                               |
| `/new-private` | Start a new private chat (password-encrypted)                                      |
| `/chat-info`   | Display current chat details (ID, title, model, message count, tools, MCP servers) |
| `/clone-chat`  | Create a new chat with same settings (instruction, model, parameters)              |
| `/quit`        | Exit the application (unsaved private chats won't persist)                         |

### Instruction & Prompt Management

| Command                   | Description                                                                |
| ------------------------- | -------------------------------------------------------------------------- |
| `/set-instruction <TEXT>` | Set system instruction. Use `\\` for multi-line mode (Esc+Enter to submit) |
| `/get-instruction`        | Display current system instruction                                         |
| `/select-instruction`     | Choose from predefined instructions in `~/.gede/instructions/`             |
| `/select-prompt`          | Select a predefined prompt as input message from `~/.gede/prompts/`        |

### Model Settings

| Command                                 | Description                                                                                                                              |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `/select-llm [PROVIDER] [--no-cache]`   | Switch AI model. Use `--no-cache` to refresh model list                                                                                  |
| `/set-message-num NUMBER`               | Control chat history length (0 = all messages)                                                                                           |
| `/set-model-settings KEY VALUE`         | Adjust parameters: temperature (0-2), top_p (0-1), max_tokens, frequency_penalty (-2 to 2), presence_penalty (-2 to 2), reasoning_effort |
| `/get-model-settings`                   | Display current model parameters                                                                                                         |
| `/set-model-reasoning <LEVEL>`          | Control reasoning depth: minimal, low, medium, high, auto, or off                                                                        |
| `/set-model-web-search <on\|off\|auto>` | Toggle web search capability                                                                                                             |

### File Operations

| Command              | Description                                                                                                                                                                                          |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/save`              | Save current chat. Public: auto-saved with generated title. Private: requires password                                                                                                               |
| `/load-chat`         | Load a public chat from `~/.gede/chats/public/` (interactive selection)                                                                                                                              |
| `/load-private-chat` | Load private chat from `~/.gede/chats/private/` (password required)                                                                                                                                  |
| `/export <FILEPATH>` | Export chat to text file. Relative paths save to `~/.gede/chats/exports/` or specificed file path.                                                                                                   |
| `/search-chats`      | Search through all saved public chats with a real-time interactive interface (fzf-style). Type a keyword to filter by title or message content, use ↑↓ to navigate, Enter to load the selected chat. |

### Image Input

Gede supports attaching images to your messages via two methods:

| Method                   | Description                                                                        |
| ------------------------ | ---------------------------------------------------------------------------------- |
| `Ctrl+Y`                 | Paste an image from the clipboard (macOS). Can be used multiple times per message. |
| `/add-image <PATH\|URL>` | Attach a local image file or an HTTP/HTTPS image URL to the next message.          |

**`/add-image` details:**

- **Local file**: provide an absolute or relative path (supports `~`). Supported formats: `jpg`, `jpeg`, `png`, `gif`, `webp`. The file is read and stored as base64.
- **Remote URL**: provide an `http://` or `https://` URL. The URL is passed directly to the LLM.
- Run the command multiple times to attach several images at once.
- A confirmation line is printed after each successful addition: `🖼  Image added #N | ...`
- All pending images are sent together with your next text message, then the queue is cleared.

```
You: /add-image ~/screenshots/diagram.png
🖼  Image added #1 | diagram.png | image/png | 128.4 KB

You: /add-image https://example.com/chart.jpg
🖼  Image added #2 | URL: https://example.com/chart.jpg

You: What do these images show?
```

### Keyboard Shortcuts

| Key      | When                          | Action                                              |
| -------- | ----------------------------- | --------------------------------------------------- |
| `Ctrl+Y` | Waiting for input             | Paste image or text from clipboard                  |
| `Esc`    | During streaming LLM response | **Interrupt** the response immediately              |
| `\`      | At the start of input         | Enter multi-line mode (submit with `Esc` + `Enter`) |

#### Interrupting a streaming response

Press **`Esc`** at any time while the assistant is generating a response to stop it immediately. The partial output will be discarded and will **not** be added to the conversation history — the next message you send will start from the last complete exchange.

### Tools

| Command         | Description                                                       |
| --------------- | ----------------------------------------------------------------- |
| `/select-tools` | Enable/disable built-in tools (Space to toggle, Enter to confirm) |
| `/select-mcp`   | Select enabled MCP servers for the current session                |

### Utility

| Command           | Description                            |
| ----------------- | -------------------------------------- |
| `/cleanup`        | Clear terminal screen                  |
| `/help [KEYWORD]` | Show all commands or search by keyword |

## CLI Usage

### Command Line Arguments

Gede supports the following command line arguments:

- `--profile <profile_name>`: Use specified configuration profile (default: default)
- `--log-level <level>`: Set log level, options: DEBUG, INFO, WARNING, ERROR, CRITICAL
- `--model <provider_id:model_id>`: Specify default model, e.g.: `openai:gpt-4o`
- `--instruction <text>`: Set system prompt
- `--private`: Start private session
- `--reasoning-effort <effort>`: Set reasoning mode, options: minimal, low, medium, high, off, auto
- `--web-search <mode>`: Enable or disable model's built-in web search, options: on, off, auto
- `--tools <tool_list>`: Set enabled tools list, multiple tools separated by commas, e.g.: `web_search,now,read_page`
- `--workspace-dir <directory>`: Set the initial working directory for `bash` and `local_python_execute`, and the file-access boundary for workspace-scoped tools (default: the current directory)
- `--prompt <text|->` / `--prompts <text|->`：Run headlessly: send a prompt directly and exit. Use `--prompt=-` to read the prompt from stdin (pipe mode). On success, stdout contains only the assistant answer; runtime errors are written to stderr with a non-zero exit code.
- `--trace`: Enable trace mode for analyzing detailed execution information of agent calls. Uses Arize Phoenix if the `arize-trace` extra is installed, otherwise uses OpenAI's default tracing (requires `OPENAI_API_KEY`)
- `--mcp-servers <server_list>`: Set the initially selected MCP servers, separated by commas

### Usage Examples

```bash
# Start with default configuration
gede

# Start with specified model
gede --model openai:gpt-4o

# Enable tools and private mode
gede --tools web_search,now --private

# Let text_editor access only this project directory
gede --tools text_editor --workspace-dir ~/projects/example

# Set reasoning mode and log level
gede --reasoning-effort high --log-level DEBUG

# Use specific profile
gede --profile my_profile

# Send a prompt directly and exit (headless)
gede --prompt="请用一句话解释量子计算"

# Pipe a prompt via stdin
echo "what is recursion?" | gede --prompt=-
```

## Configuration

### Storage

On first launch, Gede will automatically create a configuration directory at `~/.gede/` with:

- `config`
  - `.env` - Configuration file for API keys
  - `mcp.json` - MCP server confirugation
  - `profiles.json` - Profile confirugation
- `chats/public/` - Public chat storage
- `chats/private/` - Encrypted private chat storage
- `instructions/` - Custom system instructions
- `prompts/` - Predefined prompts

Gede uses environment variables to store API keys for various LLM providers. The configuration file is located at `~/.gede/config/.env`. Edit this file to add your actual API keys.

### Supported Providers

When you first run Gede, a default config file will be automatically created. Supported providers include:

- **302.ai**: `AI302_API_KEY`
- **OpenRouter**: `OPENROUTER_API_KEY`
- **OpenAI**: `OPENAI_API_KEY`
- **Anthropic**: `ANTHROPIC_API_KEY`
- **Baidu (ERNIE)**: `WENXIN_API_KEY`
- **SiliconFlow**: `SILICONFLOW_API_KEY`
- **Aliyun (Qwen)**: `QWEN_API_KEY`
- **VoiceEngine (Doubao)**: `DOUBAO_API_KEY`
- **DeepSeek**: `DEEPSEEK_API_KEY`
- **Moonshot (Kimi)**: `MOONSHOT_API_KEY`

The config file also supports:

- **Generate Title Model**: Use specific model for chat title generation
- **Phoenix Tracing**: Configure observability with Arize Phoenix

### Profile

Gede supports profile management to save and reuse your preferred configurations. The profile configuration file is located at `~/.gede/config/profiles.json`.

#### Profile Structure

Each profile can contain the following settings:

- `model`: Default model to use (format: `provider:model_id`)
- `instruction`: System instruction/prompt
- `private`: Whether to start in private mode (boolean)
- `tools`: List of enabled tools (e.g., `["web_search", "now", "read_page"]`)
- `mcp_servers`: List of initially selected MCP servers (e.g., `["filesystem"]`)
- `log_level`: Logging level (`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`)

#### Example Configuration

```json
{
  "default": {
    "model": "openai:gpt-4o",
    "instruction": "You are a helpful assistant.",
    "private": false,
    "tools": ["web_search", "now", "read_page"],
    "mcp_servers": ["filesystem"],
    "log_level": "INFO"
  },
  "coding": {
    "model": "anthropic:claude-sonnet-4-20250514",
    "instruction": "You are an expert programming assistant.",
    "tools": ["web_search", "read_page"],
    "log_level": "DEBUG"
  },
  "research": {
    "model": "openai:gpt-4o",
    "instruction": "You are a research assistant specialized in finding and analyzing information.",
    "tools": ["web_search", "read_page"]
  }
}
```

#### Usage

```bash
# Use default profile
gede

# Use specific profile
gede --profile coding

# Use profile and override settings
gede --profile research --model deepseek:deepseek-reasoner
```

**Note**: Command-line arguments will override profile settings for the current session.

### MCP

The MCP configuration file is located at `~/.gede/config/mcp.json`. It allows you to define multiple MCP servers that Gede can connect to.

The `enable` field is the global availability switch. Only servers with
`enable: true` appear in `/select-mcp` and can be selected. The
`--mcp-servers` argument and a profile's `mcp_servers` field define the
initial selection, like `--tools`; Gede connects those servers and caches their
tool lists before showing the first prompt. Selecting another server later
connects it once and reuses that connection until Gede exits. Only tools from
the currently selected servers are sent to the LLM.

#### STDIO Server

Connects to a local process via standard input/output.

- `command` (required): The executable command to run.
- `args` (optional): List of arguments for the command.
- `env` (optional): Dictionary of environment variables.
- `cwd` (optional): Working directory for the process.
- `tool_timeout` (optional, default: `120`): Maximum seconds to wait for one MCP tool response. Set to `0` to disable the limit.
- `enable` (optional, default: `true`): Whether this server is enabled.

#### Remote Server (SSE / Streamable HTTP)

Connects to a remote MCP server.

- `type` (required): Must be either `sse` or `streamable-http`.
- `url` (required): The URL of the server endpoint.
- `headers` (optional): Dictionary of HTTP headers.
- `note` (optional): Description or note for the server.
- `tool_timeout` (optional, default: `120`): Maximum seconds to wait for one MCP tool response. Set to `0` to disable the limit.
- `enable` (optional, default: `true`): Whether this server is enabled.

#### Example Configuration

```json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/username/Desktop"
      ],
      "enable": true
    },
    "remote-echo": {
      "type": "sse",
      "url": "https://example.com/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_TOKEN"
      },
      "note": "My remote MCP server",
      "enable": true
    }
  }
}
```

### Build-in Tools

| Tool          | Description                                                 |
| ------------- | ----------------------------------------------------------- |
| `web_search`  | Search the internet using Exa AI                            |
| `read_url`    | Read extracted text or the original HTML source from a URL  |
| `now`         | Get current date, time, and timezone information            |
| `bash`        | Execute bash shell commands on the local system (see below) |
| `image_gpt_tool` | Generate images with the GPT image model from text prompts and reference images |
| `image_grok_tool` | Generate images with the Grok image model from text prompts and reference images |
| `speech_tool` | Generate speech audio from text using Fish Audio            |
| `code_execute` | Execute stateful Python code in an isolated E2B sandbox      |
| `local_python_execute` | Execute approved Python locally in a managed uv environment |
| `subagent_tool` | Run up to four independent Gede headless subtasks concurrently |
| `text_editor` | View, create, and precisely edit UTF-8 text files inside a configured workspace |

#### text_editor

The `text_editor` tool follows Claude's text-editor command model while remaining a regular Gede built-in tool that works with every supported provider.

| Command       | Required parameters                      | Behavior |
| ------------- | ---------------------------------------- | -------- |
| `view`        | `path`                                   | View a file with line numbers or list one directory level; optionally accepts `view_range: [start, end]`, where `-1` means the final line |
| `create`      | `path`, `file_text`                      | Create a new UTF-8 file; the parent directory must exist and the target must not |
| `str_replace` | `path`, `old_str`, `new_str`             | Replace `old_str` only when it occurs exactly once |
| `insert`      | `path`, `insert_line`, `insert_text`     | Insert text after a line; line `0` means the start of the file |

Relative paths are resolved under `--workspace-dir`. Absolute paths are accepted only when they remain inside that directory after symbolic-link resolution. Path traversal and symbolic links that resolve outside the workspace are rejected. Files must be valid UTF-8 text; binary files are not supported. File and directory views are truncated after 10,000 characters, and file content can be read in smaller sections with `view_range`.

The workspace directory must already exist. It is resolved once at startup and does not change Gede's process working directory. If the argument is omitted, the startup working directory is used. The same directory is also used as the initial cwd of the `bash` tool.

```bash
gede --tools text_editor --workspace-dir ~/projects/example
```

Example tool arguments:

```json
{
  "command": "str_replace",
  "path": "src/app.py",
  "old_str": "debug = True",
  "new_str": "debug = False"
}
```

#### read_url

The `read_url` tool can extract webpage text or return the HTML source received
from the server.

| Parameter       | Required | Description |
| --------------- | -------- | ----------- |
| `url`           | Yes      | URL of the webpage to read |
| `query`         | No       | In text mode, return only paragraphs relevant to this query; omit it to extract the full body text |
| `output_format` | No       | `text` (default) extracts webpage text; `html` returns the fetched HTML source |

When `output_format` is `html`, `query` is ignored. The result is the HTTP
response source after redirects and decoding; Gede does not execute JavaScript
or return a browser-rendered DOM. HTML mode also bypasses BeautifulSoup and the
LLM-based text extraction step. Requests to `mp.weixin.qq.com` use a WeChat
mobile user agent and WeChat referer for compatibility; other sites use a
general desktop browser user agent without that referer.

Example tool arguments for reading HTML:

```json
{
  "url": "https://example.com",
  "query": null,
  "output_format": "html"
}
```

Text extraction uses the model configured by `READ_URL_MODEL` in
`~/.gede/config/.env`, using the `provider_id:model_id` format. HTML mode does
not require this setting.

```bash
READ_URL_MODEL="openai:gpt-4o"
```

Enable the tool with:

```bash
gede --tools read_url
```

#### image_gpt_tool and image_grok_tool

The `image_gpt_tool` and `image_grok_tool` use `tena` to generate images from a text prompt. They can also pass local file paths or HTTP/HTTPS image URLs as reference images.

Set the image model paths in `~/.gede/config/.env`:

```bash
GEDE_IMAGE_GPT_MODEL_PATH="openrouter/gpt-image-2"
GEDE_IMAGE_GROK_MODEL_PATH="openrouter/x-ai/grok-2-image"
GEDE_IMAGE_ACCESS_ENDPOINT="http://localhost:9127/public/generated_images"
```

The selected `tena` model still requires its corresponding API key, such as `OPENROUTER_API_KEY`, `ZENMUX_API_KEY`, `AI302_API_KEY`, or `GEMINI_API_KEY`.

Generated images are saved under `~/.gede/data/public/generated_images/`, and the tool result returns both saved file paths and HTTP URLs when `GEDE_IMAGE_ACCESS_ENDPOINT` is configured. If `gede-server` uses `--base-path /api/v1`, include that prefix in the endpoint, for example `http://localhost:9127/api/v1/public/generated_images`.

**Enable:**

```bash
gede --tools image_gpt_tool,image_grok_tool
```

#### speech_tool

The `speech_tool` uses the Fish Audio TTS API to generate an MP3 audio file from text.

Set the Fish Audio model, API key, voice reference ID, and optional public URL endpoint in `~/.gede/config/.env`:

```bash
FISH_AUDIO_MODEL_ID="s2.1-pro-free"
FISH_AUDIO_API_KEY="YOUR_FISH_AUDIO_API_KEY"
FISH_AUDIO_VOICE_ID="fd8438ddf6cc41caafc5cd10ece9a4f1"
GEDE_SPEECH_ACCESS_ENDPOINT="http://localhost:9127/public/generated_audio"
```

Generated audio files are saved under `~/.gede/data/public/generated_audio/`, and the tool result returns both the saved file path and HTTP URL when `GEDE_SPEECH_ACCESS_ENDPOINT` is configured. If `gede-server` uses `--base-path /api/v1`, include that prefix in the endpoint, for example `http://localhost:9127/api/v1/public/generated_audio`.

**Enable:**

```bash
gede --tools speech_tool
```

#### code_execute

The `code_execute` tool runs Python with E2B Code Interpreter. Variables, imports, functions, and files remain available across tool calls in the same chat while the Gede process is running. It does not expose arbitrary local files or host environment variables to the sandbox.

See [the `code_execute` execution-flow guide](docs/code-execute.md) for the sandbox lifecycle, attachment transfer, output-file export, and error handling details.

In API server mode, files uploaded through `/chat/upload` can be sent as `type: "file"` attachments in `/chat`. The model can also pass files inside the configured `--workspace-dir` through the optional `workspace_files` argument. Gede snapshots those selected workspace files, lazily uploads both input sources into the chat's sandbox, and exposes their metadata and sandbox paths as JSON in `os.environ["GEDE_INPUT_FILES"]`:

```python
import json
import os
import pandas as pd

inputs = json.loads(os.environ["GEDE_INPUT_FILES"])
df = pd.read_csv(inputs[0]["path"])
```

For example, a tool call can upload a workspace file before running Python:

```json
{
  "code": "import json, os, pandas as pd\ninputs = json.loads(os.environ['GEDE_INPUT_FILES'])\ndf = pd.read_excel(inputs[0]['path'])\nprint(df.shape)",
  "workspace_files": ["reports/expenses.xlsx"]
}
```

Workspace paths may be relative to `--workspace-dir` or absolute paths inside it. Missing files, directories, `..` traversal, and symbolic links resolving outside the workspace are rejected. Paths name exact files; glob expansion and recursive directory upload are not supported.

Uploaded inputs are stored under `/home/user/gede_inputs/<file_ref>/` in the sandbox. The same content hash is uploaded only once per sandbox, and previously registered inputs remain in the manifest for later calls in that chat.

Each execution receives a unique sandbox output directory in `os.environ["GEDE_OUTPUT_DIR"]`. Code should save files intended for the user there:

```python
import os
from pathlib import Path

output_dir = Path(os.environ["GEDE_OUTPUT_DIR"])
df.to_csv(output_dir / "result.csv", index=False)
(output_dir / "summary.txt").write_text("Done")
```

Configure E2B in `~/.gede/config/.env`:

```bash
E2B_API_KEY="e2b_..."
GEDE_E2B_SANDBOX_TIMEOUT_SECONDS="300"
GEDE_E2B_EXECUTION_TIMEOUT_SECONDS="120"
GEDE_CODE_EXECUTE_ACCESS_ENDPOINT="http://localhost:9127/public/code_interpreter"
```

The sandbox pauses after the configured idle timeout and resumes automatically on the next call. TUI chat switches and normal process shutdown permanently close the sandbox. API server mode keeps one sandbox per `chat_id` and serializes concurrent executions for the same chat. Sandbox IDs are not persisted, so restarting Gede starts fresh environments.

Python stdout, stderr, text results, errors, and execution counts are returned as JSON. All regular files under the execution's `GEDE_OUTPUT_DIR` are downloaded after execution, preserving subdirectories. E2B-rendered PNG/JPEG results are downloaded separately under `rendered-images/`. Artifacts are saved under `~/.gede/data/public/code_interpreter/`; the tool returns local paths, `/public/...` paths, and HTTP URLs. API server mode automatically builds an absolute URL from the current request, including `--base-path`. `GEDE_CODE_EXECUTE_ACCESS_ENDPOINT` overrides that URL when an external reverse-proxy address is required and is also needed for HTTP URLs in standalone TUI mode.

Input and output collection are each limited to 50 files, 50 MiB per file, and 200 MiB total. Symbolic links and paths outside `GEDE_OUTPUT_DIR` are ignored. Files remain available inside the sandbox for later calls until that chat's sandbox is closed.

**Enable:**

```bash
gede --tools code_execute
```

The tool does not require approval. Enabling it allows files explicitly selected through `workspace_files` to be sent to E2B, in addition to uploaded chat attachments. E2B sandboxes have internet access by default. A force-killed Gede process can leave a paused sandbox behind; remove such sandboxes from the E2B dashboard. Because session state is process-local, multi-worker API deployments cannot guarantee that requests for one `chat_id` reach the same sandbox.

#### local_python_execute

The `local_python_execute` tool runs Python on the Gede host after explicit
approval. It uses `--workspace-dir` as its working directory and starts a fresh
Python process for every call. Python variables do not persist between calls,
but files written to the workspace do. Interactive stdin is unavailable because
the tool sends the source code to Python through stdin.

See [the local Python execution-flow guide](docs/local-python-execute.md) for
the uv environment lifecycle, security boundary, output-file protocol, and
error handling details.

The first approved call lazily creates a shared uv-managed CPython 3.12
environment under `~/.gede/data/local_python/envs/`. Gede invokes that
environment's Python directly instead of modifying or activating the system or
project environment. The bundled, hash-locked environment includes NumPy,
pandas, SciPy, Matplotlib, seaborn, scikit-learn, openpyxl, Pillow, Requests,
and pypdf.

Code receives the absolute workspace path in
`os.environ["GEDE_WORKSPACE_DIR"]`. Files that should be returned to the client
must be written inside that directory and declared through `output_files`:

```json
{
  "code": "from pathlib import Path\nimport pandas as pd\nout = Path('reports/result.csv')\nout.parent.mkdir(parents=True, exist_ok=True)\npd.DataFrame({'value': [1, 2]}).to_csv(out, index=False)",
  "output_files": ["reports/result.csv"]
}
```

In API Server mode each valid declaration receives an authenticated workspace
file URL. The file is served directly from the workspace without being copied
to `~/.gede/data/public`. Configure `GEDE_SERVER_API_KEY`; workspace file access
is disabled when the key is absent. `GEDE_WORKSPACE_ACCESS_ENDPOINT` can
override the generated URL root when Gede is behind a reverse proxy.

```bash
GEDE_SERVER_API_KEY="replace-with-a-strong-secret"
GEDE_LOCAL_PYTHON_EXECUTION_TIMEOUT_SECONDS="120"
GEDE_LOCAL_PYTHON_SETUP_TIMEOUT_SECONDS="600"
# Optional:
GEDE_WORKSPACE_ACCESS_ENDPOINT="https://gede.example.com/api/v1/workspace/files"
```

**Enable:**

```bash
gede --tools local_python_execute --workspace-dir ~/projects/example
```

This environment isolates Python dependencies only. Approved code still runs
as the current operating-system user and can access local files outside the
workspace, the network, and local processes. Gede passes only a small
environment-variable allowlist and does not forward model API keys or
`PYTHONPATH`, but this is not an operating-system sandbox.

#### subagent_tool

The `subagent_tool` concurrently runs up to four independent Gede headless processes with the fixed model `openrouter:x-ai/grok-4.5`. It accepts a `tasks` array; each task has a unique `name`, a `prompt`, and a list of built-in `tools`.

Each valid task starts a fresh conversation and inherits only the current process environment and working directory. It does not inherit the parent conversation history, system instruction, attachments, MCP servers, private-session state, or `code_execute` sandbox. A task's tool list may be empty, but every supplied name must be registered as a built-in tool. Recursive use of `subagent_tool` is rejected. Gede passes the parent's configured workspace directory to the child process, so `bash` and `local_python_execute` start there while `text_editor` and `code_execute.workspace_files` keep the same file-access boundary.

All valid tasks run concurrently and each has its own 600-second timeout. Invalid tasks and subprocess failures are isolated and do not stop other tasks. Results are returned as a JSON array in input order with `name`, `status`, `result`, and `error` fields. Approval-required tools retain the existing headless behavior, so tools such as `bash` and `local_python_execute` are rejected inside a subtask rather than bypassing approval.

**Enable:**

```bash
gede --tools subagent_tool
```

Example tool arguments:

```json
{
  "tasks": [
    {
      "name": "生成密码",
      "prompt": "生成 10 个临时密码，并说明生成规则",
      "tools": ["code_execute"]
    },
    {
      "name": "检查规则",
      "prompt": "总结安全临时密码应满足的规则",
      "tools": []
    }
  ]
}
```

#### bash Tool

The `bash` tool allows the LLM to execute shell commands on your local machine.

**Features:**

- **Confirmation prompt**: Before every execution, you will be asked to approve the command — the AI cannot run anything without your explicit `y` consent
- **Unified tool approval**: TUI and API server mode both use the shared tool approval flow; headless mode rejects approval-required tools automatically
- **Safety restrictions**: Dangerous commands are automatically rejected (e.g., `rm -rf /`, `mkfs`, `dd` to disk devices, fork bombs, `shutdown`/`reboot`)
- **Working directory tracking**: Commands start in `--workspace-dir`; `cd` persists across calls for that chat without changing another chat's cwd
- **Non-interactive mode**: Subprocesses run with stdin closed, preventing commands from hanging while waiting for user input
- **Timeout protection**: Commands are killed after 30 seconds to prevent hangs
- **Output truncation**: Output is capped at 100 lines to avoid overwhelming the context
- **ANSI cleanup**: Terminal color codes are stripped from output

**Enable:**

```bash
gede --tools bash --workspace-dir ~/projects/example
```

`--workspace-dir` sets the initial cwd; it is not a filesystem sandbox for shell commands. The model can still use absolute paths or `cd` outside that directory after approval. Use `text_editor` when access must remain confined to the configured workspace.

**Example Profile (`~/.gede/config/profiles.json`):**

```json
{
  "dev": {
    "model": "openai:gpt-4o",
    "tools": ["bash", "read_url"]
  }
}
```

> ⚠️ **Security note**: Only enable the `bash` tool in sessions where you trust the AI model and the prompts being sent. Always review the command shown before approving execution.

### Optional Dependencies

Gede supports optional extensions for enhanced functionality:

#### Arize Phoenix Tracing (`arize-trace`)

Enable advanced tracing and observability with [Arize Phoenix](https://phoenix.arize.com/). This extension is used when you enable trace mode with the `--trace` flag.

**Installation:**

```bash
uv pip install "gede[arize-trace]"
```

**Usage:**

When the `arize-trace` extension is installed and `--trace` is enabled, Gede will automatically use Arize Phoenix for tracing:

```bash
gede --trace
```

If the extension is not installed, Gede will fall back to OpenAI's built-in tracing (if `OPENAI_API_KEY` is set).

**Configuration:**

To use Arize Phoenix, edit `~/.gede/config/.env` and configure:

```env
# Phoenix trace endpoint (customize with your project token if needed)
PHOENIX_COLLECTOR_ENDPOINT=https://app.phoenix.arize.com/s/your-project-token/v1/traces
```

If not configured, it defaults to `https://app.phoenix.arize.com`.

## Develop

```bash
# Clone the repository
git clone https://github.com/adow/gede.git
cd gede

# Install dependencies using uv
uv sync

# Run Gede
python3 -m gede.gede
```

### Project Structure

```
gede/
├── gede/
│   ├── commands/              # Slash command implementations
│   │   ├── base.py           # Command base class
│   │   ├── chat_commands.py  # Chat management commands
│   │   ├── model_commands.py # Model selection and settings
│   │   ├── file_commands.py  # File operations (save, load, export)
│   │   └── ...              # Other command modules
│   ├── llm/
│   │   ├── providers.py       # LLM provider registry
│   │   ├── *_provider.py     # Individual provider implementations
│   │   │   ├── openai_provider.py
│   │   │   ├── anthropic_provider.py
│   │   │   ├── deepseek_provider.py
│   │   │   └── ...          # Other providers
│   │   ├── tools/            # Built-in tools
│   │   │   ├── web_search.py
│   │   │   ├── read_url_tool.py
│   │   │   └── time_tool.py
│   │   └── mcp/              # Model Context Protocol integration
│   ├── chatcore.py           # Core chat logic
│   ├── gede.py             # Main CLI entry point
│   ├── server.py             # API server entry point
│   ├── config.py             # Configuration management
│   ├── encrypt.py            # Encryption utilities
│   ├── profiles.py           # Profile management
│   └── top.py                # Top-level utilities
├── CONTRIBUTING.md           # Contribution guidelines
├── CODE_OF_CONDUCT.md       # Community code of conduct
├── CHANGELOG.md             # Version history
├── LICENSE                  # MIT License
├── pyproject.toml           # Python project configuration
├── Dockerfile               # Docker configuration
└── README.md               # This file
```

## API Server

Gede includes a built-in HTTP API server (`gede-server`) built with FastAPI, designed for GUI client integration.

```bash
# Start the server (default port: 9127)
gede-server

# Custom port and base path
gede-server --port 8080 --base-path /api/v1 --workspace-dir ~/projects/example --log-level=INFO
```

See [docs/server-api.md](docs/server-api.md) for the full API reference.

## Technology Stack

- **Language**: Python 3.10+
- **CLI Framework**: rich, inquirer, prompt-toolkit,
- **Encryption**: cryptography
- **HTTP Client**: httpx
- **Agent Framework**: OpenAI Agent
- **Build**: uv

## Security

- Password-protected private chats with AES encryption
- User data stays local by default - chat history is ephemeral and only persisted when explicitly saved using `/save` command

## Community

- 📝 [Issues & Discussions](https://github.com/adow/gede/issues)
- 🤝 [Contributing Guidelines](CONTRIBUTING.md)
- 📖 [Code of Conduct](CODE_OF_CONDUCT.md)
- 📊 [Changelog](CHANGELOG.md)

## License

## Acknowledgments

Thanks to all contributors and the open-source community for support and feedback!

## Disclaimer

Gede is provided "as-is" for research and personal use. Users are responsible for complying with LLM provider terms of service and applicable laws when using this tool.
