Metadata-Version: 2.4
Name: gede
Version: 0.4.45
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: e2b-desktop<3,>=2.3.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: pyyaml>=6.0.2
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 regular, unencrypted chat                                              |
| `/new-private`       | Start a new private chat (password-encrypted)                                      |
| `/chat-info`         | Display current chat details (ID, title, model, message count, tools, MCP servers) |
| `/set-workspace DIR` | Switch the current Chat to an existing readable and writable directory             |
| `/clone-chat`        | Create a new chat that inherits the current workspace and settings                 |
| `/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 regular chat from the SQLite database (interactive selection)                                                                                                                                |
| `/load-private-chat` | Load an encrypted private chat from the SQLite database (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 regular 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. Any partial assistant text is saved to the conversation history with a Gede system note that records the user cancellation, so the next message can use that incomplete response as context.

### 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                |

### Agent Skills

Gede automatically discovers Agent Skills from:

- `~/.gede/skills/*/SKILL.md` for user-level skills.
- `<workspace>/.gede/skills/*/SKILL.md` for workspace-level skills.

Skills are enabled by default. Start either application with
`--disable-skills` to skip discovery, omit all Skill instructions from the
temporary system context, and remove the internal `activate_skill` and
`read_skill_resource` tools:

```bash
gede --disable-skills
GEDE_SERVER_API_KEY="replace-with-a-strong-secret" gede-server --disable-skills
```

This is a process-wide startup setting, not a per-request tool selection or
Server API field. Existing active Skill snapshots remain stored in their chats
but are not injected while Skills are disabled; restarting without the flag
enables them again. The ordinary workspace, attachments, and artifacts runtime
context is still injected.

A workspace skill overrides a user-level skill with the same `name`. Skills are
not selected through `/select-tools`: when a request matches an available skill,
the model can call the internal `activate_skill` tool. Activated instructions are
snapshotted for the conversation and injected into the single system message on
every model request, including later requests after the chat is reloaded.

Each `SKILL.md` must be UTF-8, no larger than 256 KiB, and contain YAML
frontmatter followed by Markdown instructions:

```markdown
---
name: pdf-processing
description: Create, inspect, and transform PDF documents.
compatibility: Requires a PDF-producing tool when generating files.
---

# PDF processing

Follow these instructions when working with PDF files.
```

Skills may contain supporting UTF-8 files such as `references/format.md` or
`scripts/export.py`. After activation, the model can read them through the
internal, read-only `read_skill_resource` tool. That tool accepts only relative
paths contained by the activated skill directory. Passing `path: "."` without
line parameters lists the Skill root; paths to UTF-8 files return line-numbered
content and optionally accept `start_line` and `end_line`. Line parameters sent
for a directory are ignored with a warning. The tool does not execute scripts.
Execution still requires an explicitly enabled tool such as Bash and follows
that tool's existing approval and permission rules. Skills never grant extra
filesystem, network, or execution permissions.

When Bash is enabled, the model probes Python and npm dependencies named by an
activated Skill before using them. Missing runtime-scoped dependencies may be
installed into the shared Gede Bash runtime through the normal Bash approval
flow, then retried. Python packages use `python -m pip install` without `--user`
or other destination overrides. Node libraries use `npm install -g`; `npx` is
reserved for one-off CLIs. Generic Skill examples using `pip --user` or
non-global `npm install` are adapted to these Gede commands. Gede does not
silently install operating-system programs such as LibreOffice, Pandoc, or
Poppler. The model probes those executables, reports a missing prerequisite,
and skips optional verification rather than claiming it succeeded.

Activated skills accumulate within a conversation. Forked chats inherit their
snapshots; new chats, cloned chats, and workspace changes start with no active
skills. Public chats store snapshots as JSON, while private chats encrypt them
with the chat password.

See [Agent Skills Design and Implementation](docs/skills.md) for the complete
discovery, prompt construction, tool, persistence, and security design.

### 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 chat's workspace (default: `~/.gede/data/workspace/default`); the directory must already exist when explicitly supplied
- `--disable-skills`: Disable Agent Skills discovery, context injection, and internal tools for this process
- `--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

# Bind the initial chat to this project directory
gede --tools text_editor --workspace-dir ~/projects/example

# Start without Agent Skills context or tools
gede --disable-skills

# 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
- `data/chats.db` - Regular and encrypted private chat metadata/messages
- `data/attachments/<chat_id>/` - Content-addressed user uploads
- `data/workspace/default/` - Shared default private tool workspace
- `data/artifacts/<chat_id>/` - Public generated files grouped by chat and type
- `data/public/` - Read-only compatibility storage for legacy generated files
- `data/local_python/envs/` - Gede-managed local Python environments
- `logs/` - Application logs
- `instructions/` - Custom system instructions
- `prompts/` - Predefined prompts
- `skills/<skill-name>/SKILL.md` - User-level Agent Skills
- `runtime/bash/` - Shared Bash Python/npm runtime, prepared lazily on first approved use

Every chat persists an absolute workspace path. When no path is supplied, Gede
creates and uses the shared `data/workspace/default/`; a custom workspace may be
any existing, readable, writable directory. Existing saved chats keep their
persisted workspace paths. Workspace files are never exposed through an HTTP
file route. In the TUI, `/set-workspace DIR` switches the current Chat and resets
its Bash cwd, local Python session, Code Interpreter sandbox, and Computer
session. `/clone-chat` inherits the current Chat's workspace path without
copying its contents. Relative paths resolve from the current workspace; quote a
path containing spaces.

On the first approved Bash call, Gede lazily creates a shared package runtime
under `~/.gede/runtime/bash/`. Its uv-managed Python 3.12 environment,
Python CLI tools, npm global prefix, and package caches are separate from the
host, Gede's own environment, and workspace project environments. All chats,
workspaces, TUI sessions, and Server requests for the same operating-system
user reuse this runtime. Gede does not run `uv init` or reuse a project `.venv`.

Generated files intended for a frontend are written to `data/artifacts/` and
are served without authentication. Attachments are also previewable without
authentication. Local tools can modify the current chat's workspace,
attachments, and artifacts, so an attachment's hash-shaped `file_ref` only
describes its original upload after such a modification. Do not place sensitive
data in attachments or artifacts, including from private chats.

Before every model request, Gede appends an ephemeral runtime file environment
to the first system message. It includes `chat_id`, the absolute workspace,
attachments and artifacts directories, and the resolved artifacts HTTP endpoint
(or `null`). This context is sent even when no file tool is enabled, so these
local paths are disclosed to the configured model provider. It is not persisted
to the database and does not change the configured instruction. Relative paths
refer to the workspace; generated user-facing files belong to artifacts, not
the workspace. Responses should use the exact tool-returned `url`, falling back
to `artifact_path`, and should not expose server absolute paths unless requested
for diagnostics.

The `workspace:`, `attachments:`, and `artifacts:` forms are internal tool path
syntax, not browser links. Every regular file anywhere below
`data/artifacts/<chat_id>/` is anonymously accessible. The injected runtime
context includes that Chat's canonical `/artifacts/<chat_id>` path and, when
available, its complete HTTP base URL. Models must use that HTTP URL in
user-facing links; they must never emit Markdown links such as
`(artifacts:report.pdf)`.

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      |
| `computer` | Control a stateful Chrome desktop in an isolated E2B Desktop 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 files in the current chat's file roots |
| `view_image` | Load a local or HTTP/HTTPS image as multimodal tool output |

#### 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 resolve under the current chat workspace. Use
`workspace:<path>`, `attachments:<path>`, or `artifacts:<path>` to select a root
explicitly. Absolute paths are accepted only inside one of those three roots.
Traversal and symbolic links escaping the selected root are rejected. Files
must be UTF-8 text; binary files are not supported.

```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"
}
```

#### view_image

The `view_image` tool loads an image and returns it to the selected vision model
as multimodal tool output. Its `path` parameter accepts HTTP/HTTPS URLs and the
same workspace-scoped local path forms as `text_editor`. It also accepts
`scratch:<path>` and absolute paths below the current chat's Bash
`GEDE_SCRATCH_DIR`. JPEG, PNG, GIF, and WebP images are supported, with a 10 MiB
limit per image.

URL images are downloaded asynchronously and cached by their complete URL under
`~/.gede/cache/view_image/`. A later call with the same URL reuses the cached
file without downloading it again. The cache has no automatic expiration.

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

Example tool arguments:

```json
{
  "path": "artifacts:charts/summary.png"
}
```

Only the image metadata appears in the textual tool result; image base64 is
kept in the internal multimodal result passed to the model.

#### 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_ARTIFACTS_ACCESS_ENDPOINT="http://localhost:9127/artifacts"
```

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/artifacts/<chat_id>/generated_image/<generation_id>/`. Local references accept the same workspace/attachments/artifacts path forms as `text_editor`; HTTP/HTTPS references remain supported. In standalone TUI mode, configure `GEDE_ARTIFACTS_ACCESS_ENDPOINT` to return HTTP URLs. API server mode derives the endpoint from the current request.

**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_ARTIFACTS_ACCESS_ENDPOINT="http://localhost:9127/artifacts"
```

Generated audio files are saved under `~/.gede/data/artifacts/<chat_id>/generated_audio/<generation_id>/` and use the same artifacts endpoint as every other generated file.

**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 select files from the current chat's workspace, attachments, or artifacts through `input_files`. Gede snapshots selected host files, lazily uploads them into the 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 files from two chat roots 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)",
  "input_files": [
    {"source": "workspace", "path": "reports/expenses.xlsx"},
    {"source": "artifacts", "path": "exports/reference.csv"}
  ]
}
```

Each path is relative to its selected chat root. Missing files, directories,
`..` traversal, and escaping symbolic links are rejected. `workspace_files`
remains available for one compatibility version as a deprecated workspace-only
alias. Remote changes are never written back to host files.

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_ARTIFACTS_ACCESS_ENDPOINT="http://localhost:9127/artifacts"
```

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/artifacts/<chat_id>/code_interpreter/<execution_id>/`; the tool returns local paths, `/artifacts/...` paths, and HTTP URLs. Remote changes are never written back to the workspace.

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 `input_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.

#### computer

The `computer` tool controls a dedicated E2B Desktop sandbox with Chrome, mouse and keyboard actions, screenshots, and an authenticated interactive VNC URL. It is separate from the `code_execute` sandbox, so files and runtime state are not shared.

Each call accepts an ordered batch of 1–8 deterministic actions and returns one screenshot after the batch. For example:

```json
{
  "actions": [
    {"action": "keypress", "keys": ["CTRL", "L"]},
    {"action": "type", "text": "https://example.com"},
    {"action": "keypress", "keys": ["ENTER"]},
    {"action": "wait", "duration_ms": 2000}
  ]
}
```

API attachments are uploaded into the desktop's `Gede Inputs` folder. The
tool also accepts the same three-root `input_files` objects and deprecated
`workspace_files` alias as `code_execute`. Files intended for the user must be saved or
moved into `Gede Outputs`; every regular file currently in that folder is
downloaded and returned after each call. Chrome's default `Downloads` folder
is not exported.

Configure and enable it with:

```bash
E2B_API_KEY="e2b_..."
GEDE_E2B_COMPUTER_SANDBOX_TIMEOUT_SECONDS="300"
GEDE_ARTIFACTS_ACCESS_ENDPOINT="http://localhost:9127/artifacts"
gede --tools computer
```

`GEDE_ARTIFACTS_ACCESS_ENDPOINT` is optional and lets standalone TUI mode return
HTTP artifact URLs. API server mode derives `/artifacts/...` URLs from the
request automatically.

The timeout is reset at the start of every call. Calls for the same chat reuse the desktop before it expires; after expiration, the next call creates a fresh desktop and previous browser state is lost.

The selected model must support both tool calling and image input. The tool does not require per-action approval and the desktop has internet access by default. See [the computer-use guide](docs/computer-use.md) for its complete action schema, batching guidance, VNC security boundary, lifecycle, and error behavior.

To control the current macOS desktop instead of an isolated E2B sandbox, Gede
can connect to the official Cua Driver MCP server. This is configured as an MCP
server rather than an alternative backend for the built-in `computer` tool. See
[the Cua Driver guide](docs/cua-driver-computer-use.md) for installation,
macOS permissions, standard and bounded daemon management, and MCP
configuration.

#### local_python_execute

The `local_python_execute` tool runs Python on the Gede host after explicit
approval. It uses the current chat workspace 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 three chat roots in `GEDE_WORKSPACE_DIR`,
`GEDE_ATTACHMENTS_DIR`, and `GEDE_ARTIFACTS_DIR`, plus a per-execution public
output directory in `GEDE_OUTPUT_DIR`.
Code may explicitly modify project files in the workspace after approval, but
files returned to the client must be written under `GEDE_OUTPUT_DIR` and
declared through `output_files`:

```json
{
  "code": "import os\nfrom pathlib import Path\nimport pandas as pd\nout = Path(os.environ['GEDE_OUTPUT_DIR']) / '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"]
}
```

Each valid declaration receives public artifact metadata and, when available,
an absolute artifact URL. Workspace files are never exposed directly through
the API server.

```bash
GEDE_LOCAL_PYTHON_EXECUTION_TIMEOUT_SECONDS="120"
GEDE_LOCAL_PYTHON_SETUP_TIMEOUT_SECONDS="600"
GEDE_ARTIFACTS_ACCESS_ENDPOINT="https://gede.example.com/api/artifacts"
```

**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 the parent chat's workspace setting. The subprocess cwd is not changed. It does not inherit the parent conversation history, system instruction, attachments, artifacts, MCP servers, private-session state, or remote sandbox. Recursive use is rejected. Tools inside the child use the passed workspace, while the child's attachments and artifacts belong to its fresh conversation.

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.
See [Bash and Bash Runtime design and implementation](docs/bash-runtime.md) for
the complete execution, isolation, policy, concurrency, and lifecycle details.

**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 rejected, and package-manager commands that escape the shared Gede Bash runtime are rejected before approval
- **Working directory tracking**: Commands start in the chat workspace; `cd` persists until that chat switches workspace
- **Shared package runtime**: The first approved Bash call lazily prepares `~/.gede/runtime/bash/`, including an isolated uv-managed Python 3.12 environment and npm/uv/pipx directories shared by every chat and workspace
- **Serialized package changes**: Commands that install, uninstall, upgrade, or populate shared CLI caches are serialized across chats and Gede processes; ordinary Bash commands retain per-chat concurrency
- **Non-interactive mode**: Subprocesses run with stdin closed, preventing commands from hanging while waiting for user input
- **Timeout protection**: Commands are killed after 600 seconds by default to prevent hangs while allowing dependency installation
- **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
```

The Bash runtime never activates a workspace project's `.venv` and filters
Gede's own virtual environment from `PATH`. Standard `pip`, `python -m pip`,
`uv pip`, `uv tool`, `pipx`, `npm -g`, and `npx` operations use directories
below `~/.gede/runtime/bash/`. Global npm modules are exposed to CommonJS
scripts through the protected `NODE_PATH`, so a library installed with
`npm install -g` can be loaded with `require()` from any chat workspace. `npx`
remains a one-off CLI mechanism and does not install a library for later
`require()` calls. Node's on-disk module compile cache is shared across chats at
`<bash-runtime>/node-compile-cache/` through the protected
`NODE_COMPILE_CACHE`, instead of being duplicated in each chat scratch
directory. Set `GEDE_BASH_RUNTIME_DIR` to an alternative path; `~` is expanded
and relative values resolve from the Gede process working directory. If Python
setup fails, Python package
installation is rejected instead of falling back to the host interpreter; npm
and non-Python commands can continue with the sanitized environment. Override
the 600-second command timeout or the 600-second setup and shared-package-lock
timeout with:

```bash
GEDE_BASH_EXECUTION_TIMEOUT_SECONDS="600"
GEDE_BASH_PYTHON_SETUP_TIMEOUT_SECONDS="600"
GEDE_BASH_RUNTIME_DIR="/path/to/gede-bash-runtime"
```

To keep Skill prerequisites out of the workspace project's dependency state,
Gede rejects project-mutating package commands such as `uv add`, `uv sync`,
bare `npm install`, and `npm ci`. It also rejects privilege elevation,
system/user pip targets, package-manager path overrides, shell configuration
updates, and attempts to replace or remove the protected runtime environment
variables. Global npm operations are allowed only with `-g` or `--global`,
which points at the shared Gede Bash runtime rather than the host prefix.
Mutating commands from common operating-system package managers, including
Homebrew, MacPorts, apt, dnf/yum, pacman, zypper, apk, winget, Chocolatey, and
Scoop, are also rejected before approval. Read-only package queries remain
available.

Every approved Bash call also receives a persistent per-chat scratch directory:

```text
<bash-runtime>/tmp/<chat-id>/
```

`GEDE_SCRATCH_DIR`, `TMPDIR`, `TMP`, and `TEMP` point to this directory. Skill
workflows should place temporary scripts, logs, unpacked files, and other
intermediates there instead of `/tmp` or the workspace. User-facing deliverables
still belong under `GEDE_ARTIFACTS_DIR`. Scratch directories survive chat and
workspace switches and application restarts; Gede does not automatically delete
them. They are not encrypted or exposed by the artifacts HTTP route. After
confirming the contents are no longer useful, remove stale directories below
`<bash-runtime>/tmp/` manually. Per-chat `node-compile-cache` directories created
by earlier versions are not migrated or deleted automatically and can also be
removed after upgrading.

Packages and CLIs installed in this runtime are intentionally visible to every
chat and workspace, including private chats. Upgrades and removals therefore
affect all of them, and the package files are not encrypted chat state. Existing
`<workspace>/.gede/runtime/`, `~/.gede/data/bash/runtime/`, and the older
default workspace `.venv` from previous development versions are not migrated
or deleted automatically; after confirming they are no longer needed, remove
them manually.

The chat workspace is the initial cwd, not an operating-system sandbox. These
rules prevent normal package-manager commands and common mistakes from
polluting the host or project environments, but an executed CLI or deliberately
crafted shell script still runs as the Gede process account and can access local
paths, the network, environment variables, and processes. Their environment
includes all three current-chat root paths. Workspace remains the private cwd
and editable project root; artifacts remains the per-chat, HTTP-accessible
delivery root.

**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); the API key is mandatory
GEDE_SERVER_API_KEY="replace-with-a-strong-secret" gede-server

# Custom port and base path
GEDE_SERVER_API_KEY="replace-with-a-strong-secret" gede-server --port 8080 --base-path /api/v1 --log-level=INFO

# Start the API server without Agent Skills
GEDE_SERVER_API_KEY="replace-with-a-strong-secret" gede-server --disable-skills
```

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.
