Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 57 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,13 @@ pipx ensurepath
sudo apt install pipx # Debian/Ubuntu
pipx ensurepath

# Windows (PowerShell)
python -m pip install --user pipx
python -m pipx ensurepath
# Restart PowerShell after installation

# After installation, restart your terminal or run:
source ~/.bashrc # or ~/.zshrc
source ~/.bashrc # or ~/.zshrc (macOS/Linux)
```

We offer two usage modes - choose based on your needs:
Expand All @@ -86,7 +91,12 @@ Perfect for users who want to quickly try Mini Agent without cloning the reposit
pipx install git+https://github.com/MiniMax-AI/Mini-Agent.git

# 2. Run setup script (automatically creates config files)
# macOS/Linux:
curl -fsSL https://raw.githubusercontent.com/MiniMax-AI/Mini-Agent/main/scripts/setup-config.sh | bash

# Windows (PowerShell):
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/MiniMax-AI/Mini-Agent/main/scripts/setup-config.ps1" -OutFile "$env:TEMP\setup-config.ps1"
powershell -ExecutionPolicy Bypass -File "$env:TEMP\setup-config.ps1"
```

> 💡 **Tip**: If you want to develop locally or modify code, use "Development Mode" below
Expand Down Expand Up @@ -129,16 +139,34 @@ git clone https://github.com/MiniMax-AI/Mini-Agent.git
cd Mini-Agent

# 2. Install uv (if you haven't)
# macOS/Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell):
irm https://astral.sh/uv/install.ps1 | iex
# Restart terminal after installation

# 3. Sync dependencies
uv sync

# Alternative: Install dependencies manually (if not using uv)
# pip install -r requirements.txt
# Or install required packages:
# pip install tiktoken pyyaml httpx pydantic requests prompt-toolkit mcp

# 4. Initialize Claude Skills (Optional)
git submodule update --init --recursive

# 5. Copy config template
```

**macOS/Linux:**
```bash
cp mini_agent/config/config-example.yaml mini_agent/config/config.yaml
```

**Windows:**
```powershell
Copy-Item mini_agent\config\config-example.yaml mini_agent\config\config.yaml

# 6. Edit config file
vim mini_agent/config/config.yaml # Or use your preferred editor
Expand Down Expand Up @@ -220,6 +248,34 @@ pytest tests/test_agent.py tests/test_note_tool.py -v
- ✅ **External Services** - Git MCP Server loading


## Troubleshooting

### SSL Certificate Error

If you encounter `[SSL: CERTIFICATE_VERIFY_FAILED]` error:

**Quick fix for testing** (modify `mini_agent/llm.py`):
```python
# Line 50: Add verify=False to AsyncClient
async with httpx.AsyncClient(timeout=120.0, verify=False) as client:
```

**Production solution**:
```bash
# Update certificates
pip install --upgrade certifi

# Or configure system proxy/certificates
```

### Module Not Found Error

Make sure you're running from the project directory:
```bash
cd Mini-Agent
python -m mini_agent.cli
```

## Related Documentation

- [Development Guide](docs/DEVELOPMENT_GUIDE.md) - Detailed development and configuration guidance
Expand Down
58 changes: 57 additions & 1 deletion README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,13 @@ pipx ensurepath
sudo apt install pipx # Debian/Ubuntu
pipx ensurepath

# Windows (PowerShell)
python -m pip install --user pipx
python -m pipx ensurepath
# 安装后需要重启 PowerShell

# 安装完成后,重启终端或运行:
source ~/.bashrc # 或 ~/.zshrc
source ~/.bashrc # 或 ~/.zshrc (macOS/Linux)
```

### 2. 选择使用模式
Expand All @@ -86,7 +91,12 @@ source ~/.bashrc # 或 ~/.zshrc
pipx install git+https://github.com/MiniMax-AI/Mini-Agent.git

# 2. 运行配置脚本(自动创建配置文件)
# macOS/Linux:
curl -fsSL https://raw.githubusercontent.com/MiniMax-AI/Mini-Agent/main/scripts/setup-config.sh | bash

# Windows (PowerShell):
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/MiniMax-AI/Mini-Agent/main/scripts/setup-config.ps1" -OutFile "$env:TEMP\setup-config.ps1"
powershell -ExecutionPolicy Bypass -File "$env:TEMP\setup-config.ps1"
```

> 💡 **提示**:如果您希望在本地进行开发或修改代码,请使用下方的“开发模式”。
Expand Down Expand Up @@ -129,16 +139,34 @@ git clone https://github.com/MiniMax-AI/Mini-Agent.git
cd Mini-Agent

# 2. 安装 uv(如果尚未安装)
# macOS/Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell):
irm https://astral.sh/uv/install.ps1 | iex
# 安装后需要重启终端

# 3. 同步依赖
uv sync

# 替代方案: 手动安装依赖(如果不使用 uv)
# pip install -r requirements.txt
# 或者安装必需的包:
# pip install tiktoken pyyaml httpx pydantic requests prompt-toolkit mcp

# 4. 初始化 Claude Skills(可选)
git submodule update --init --recursive

# 5. 复制配置模板
```

**macOS/Linux:**
```bash
cp mini_agent/config/config-example.yaml mini_agent/config/config.yaml
```

**Windows:**
```powershell
Copy-Item mini_agent\config\config-example.yaml mini_agent\config\config.yaml

# 6. 编辑配置文件
vim mini_agent/config/config.yaml # 或使用您偏好的编辑器
Expand Down Expand Up @@ -221,6 +249,34 @@ pytest tests/test_agent.py tests/test_note_tool.py -v
- ✅ **外部服务** - Git MCP 服务器加载


## 常见问题

### SSL 证书错误

如果遇到 `[SSL: CERTIFICATE_VERIFY_FAILED]` 错误:

**测试环境快速修复** (修改 `mini_agent/llm.py`):
```python
# 第 50 行: 给 AsyncClient 添加 verify=False
async with httpx.AsyncClient(timeout=120.0, verify=False) as client:
```

**生产环境解决方案**:
```bash
# 更新证书
pip install --upgrade certifi

# 或配置系统代理/证书
```

### 模块未找到错误

确保从项目目录运行:
```bash
cd Mini-Agent
python -m mini_agent.cli
```

## 相关文档

- [开发指南](docs/DEVELOPMENT_GUIDE_CN.md) - 详细的开发和配置指引
Expand Down
91 changes: 75 additions & 16 deletions mini_agent/tools/bash_tool.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
"""Bash command execution tool with background process management."""
"""Shell command execution tool with background process management.

Supports both bash (Unix/Linux/macOS) and PowerShell (Windows).
"""

import asyncio
import platform
import re
import time
import uuid
Expand Down Expand Up @@ -211,15 +215,45 @@ async def terminate(cls, bash_id: str) -> BackgroundShell:


class BashTool(Tool):
"""Execute bash commands in foreground or background."""
"""Execute shell commands in foreground or background.

Automatically detects OS and uses appropriate shell:
- Windows: PowerShell
- Unix/Linux/macOS: bash
"""

def __init__(self):
"""Initialize BashTool with OS-specific shell detection."""
self.is_windows = platform.system() == "Windows"
self.shell_name = "PowerShell" if self.is_windows else "bash"

@property
def name(self) -> str:
return "bash"

@property
def description(self) -> str:
return """Execute bash commands in foreground or background.
shell_examples = {
"Windows": """Execute PowerShell commands in foreground or background.

For terminal operations like git, npm, docker, etc. DO NOT use for file operations - use specialized tools.

Parameters:
- command (required): PowerShell command to execute
- timeout (optional): Timeout in seconds (default: 120, max: 600) for foreground commands
- run_in_background (optional): Set true for long-running commands (servers, etc.)

Tips:
- Quote file paths with spaces: cd "My Documents"
- Chain dependent commands with semicolon: git add . ; git commit -m "msg"
- Use absolute paths instead of cd when possible
- For background commands, monitor with bash_output and terminate with bash_kill

Examples:
- git status
- npm test
- python -m http.server 8080 (with run_in_background=true)""",
"Unix": """Execute bash commands in foreground or background.

For terminal operations like git, npm, docker, etc. DO NOT use for file operations - use specialized tools.

Expand All @@ -238,15 +272,18 @@ def description(self) -> str:
- git status
- npm test
- python3 -m http.server 8080 (with run_in_background=true)"""
}
return shell_examples["Windows"] if self.is_windows else shell_examples["Unix"]

@property
def parameters(self) -> dict[str, Any]:
cmd_desc = f"The {self.shell_name} command to execute. Quote file paths with spaces using double quotes."
return {
"type": "object",
"properties": {
"command": {
"type": "string",
"description": "The bash command to execute. Quote file paths with spaces using double quotes.",
"description": cmd_desc,
},
"timeout": {
"type": "integer",
Expand All @@ -268,10 +305,10 @@ async def execute(
timeout: int = 120,
run_in_background: bool = False,
) -> ToolResult:
"""Execute bash command with optional background execution.
"""Execute shell command with optional background execution.

Args:
command: The bash command to execute
command: The shell command to execute
timeout: Timeout in seconds (default: 120, max: 600)
run_in_background: Set true to run command in background

Expand All @@ -286,16 +323,31 @@ async def execute(
elif timeout < 1:
timeout = 120

# Prepare shell-specific command execution
if self.is_windows:
# Windows: Use PowerShell with appropriate encoding
shell_cmd = ["powershell.exe", "-NoProfile", "-Command", command]
else:
# Unix/Linux/macOS: Use bash
shell_cmd = command

if run_in_background:
# Background execution: Create isolated process
bash_id = str(uuid.uuid4())[:8]

# Start background process with combined stdout/stderr
process = await asyncio.create_subprocess_shell(
command,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.STDOUT, # Redirect stderr to stdout
)
if self.is_windows:
process = await asyncio.create_subprocess_exec(
*shell_cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.STDOUT,
)
else:
process = await asyncio.create_subprocess_shell(
shell_cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.STDOUT,
)

# Create background shell and add to manager
bg_shell = BackgroundShell(bash_id=bash_id, command=command, process=process, start_time=time.time())
Expand All @@ -319,11 +371,18 @@ async def execute(

else:
# Foreground execution: Create isolated process
process = await asyncio.create_subprocess_shell(
command,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
if self.is_windows:
process = await asyncio.create_subprocess_exec(
*shell_cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
else:
process = await asyncio.create_subprocess_shell(
shell_cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)

try:
stdout, stderr = await asyncio.wait_for(process.communicate(), timeout=timeout)
Expand Down
Loading