> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# TCP 模式

> 说明如何在 Laravel Copilot SDK 中连接预先启动的 Copilot CLI 服务器，以低开销方式共享运行。

## TCP 模式

通常，SDK 会为每个请求启动新的 Copilot CLI 进程（stdio 模式）。
使用 TCP 模式后，可以连接到预先启动的 Copilot CLI 服务器。

## TCP 模式的优点

* **性能提升**: 没有进程启动开销
* **资源共享**: 多个 Laravel 进程可以共享同一个 CLI 服务器
* **进程管理**: 可以在 Laravel Forge / Laravel Cloud 中作为后台进程管理
* **部署适配**: 可以支持部署时的自动重启

## 使用方式

### 1. 启动 Copilot CLI 服务器

```shell theme={null}
copilot --headless --port 12345
```

### 2. 设置环境变量

```dotenv theme={null}
COPILOT_URL=tcp://127.0.0.1:12345
# COPILOT_URL=http://127.0.0.1:12345
# COPILOT_URL=127.0.0.1:12345
# COPILOT_URL=12345
# COPILOT_URL=127.0.0.1
# COPILOT_URL=localhost
```

仅此一步，SDK 就会从 stdio 模式自动切换到 TCP 模式。

* `tcp://` 是可选的。使用 `http://` 或没有 scheme 也可以工作。
* 也可以只指定端口。这种情况下 host 会自动为 `127.0.0.1`。
* 只指定 host 时仅 `127.0.0.1` 和 `localhost` 有效。这种情况下端口默认是 `12345`。

## 配置文件

可以在 `config/copilot.php` 中配置 TCP 连接。

```php theme={null}
return [
    // TCP 连接目标 URL（设置后进入 TCP 模式）
    'url' => env('COPILOT_URL'),

    // 以下仅在 stdio 模式下使用
    'cli_path' => env('COPILOT_CLI_PATH', 'copilot'),
    'cli_args' => [],
    'cwd' => null,
    'log_level' => env('COPILOT_LOG_LEVEL', 'info'),

    // 两种模式共通
    'timeout' => env('COPILOT_TIMEOUT', 60),
    'model' => env('COPILOT_MODEL'),
];
```

同时设置 `COPILOT_URL`（`cli_url`）和 `COPILOT_CLI_PATH` 时，TCP 模式优先。

## 运行时切换模式

通常会根据配置文件自动选择 TCP 模式或 stdio 模式。
也可以在代码中显式切换。

```php theme={null}
use Revolution\Copilot\Facades\Copilot;

// 切换到 TCP 模式
$response = Copilot::useTcp(url: 'tcp://127.0.0.1:12345')->run(prompt: 'Hello, TCP mode!');
// 省略时使用配置文件的值
$response = Copilot::useTcp()->run(prompt: 'Hello, TCP mode!');

// 切换到 stdio 模式
$stdioConfig = [
    'cli_path' => 'copilot',
    'cli_args' => [],
    'cwd' => base_path(),
    'log_level' => 'info',
];
$response = Copilot::useStdio($stdioConfig)->run(prompt: 'Hello, stdio mode!');

// 省略时使用配置文件的值
// 两种模式都配置时 TCP 优先，因此可用于临时覆盖
$response = Copilot::useStdio()->run(prompt: 'Hello, stdio mode!');
```

某些服务器上，TCP 模式可能无法正常工作。
也可以让队列处理用 TCP 模式、HTTP 请求内的处理用 stdio 模式，进行分场景使用。

## 在 Laravel Forge / Laravel Cloud 中的运行

### Laravel Forge

1. **创建 Daemon**: 在 Forge 管理界面创建 Daemon。

   ```
   Command: copilot --headless --port 12345
   User: forge
   Directory: /home/forge/your-app
   ```

2. **设置环境变量**: 在 `.env` 中添加 `COPILOT_URL`。

3. **部署时重启**: 在部署脚本中重启 Daemon。

在当前的 Forge 环境中，也许不需要。

```shell theme={null}
sudo supervisorctl restart daemon-123456:*
```

### Laravel Cloud

可以使用 Laravel Cloud 的 worker 功能，作为后台进程运行。

详情请参考 [在 Laravel Cloud 中的使用](/zh/packages/laravel-copilot-sdk/laravel-cloud)。

## 注意事项

### 安全

<Warning>
  TCP 服务器请尽可能使用本地绑定（`127.0.0.1`）。
  如需对外公开，请适当配置防火墙。
</Warning>

### 重连

当前版本没有自动重连功能。连接断开时会抛出异常。

### 确认当前模式

可以在程序内确认客户端处于哪种模式。

```php theme={null}
use Revolution\Copilot\Facades\Copilot;

$client = Copilot::client();

if ($client->isTcpMode()) {
    // TCP 模式
} else {
    // stdio 模式
}
```

## 故障排查

### 无法连接

1. 确认 Copilot CLI 服务器是否启动

```shell theme={null}
ps aux | grep copilot
```

2. 确认端口是否正确

```shell theme={null}
netstat -an | grep 12345
```

3. 确认防火墙配置

### 超时错误

请增大 `config/copilot.php` 中 `timeout` 的值。

```php theme={null}
'timeout' => 120, // 2 分钟
```

<Info>
  最新信息请参考 [GitHub 仓库](https://github.com/invokable/laravel-copilot-sdk)。
</Info>


## Related topics

- [GitHub token](/zh/packages/laravel-copilot-sdk/github-token.md)
- [Laravel Cloud - GitHub Copilot SDK for Laravel](/zh/packages/laravel-copilot-sdk/laravel-cloud.md)
- [会话生命周期事件](/zh/packages/laravel-copilot-sdk/session-lifecycle-event.md)
- [Remote Sessions](/zh/packages/laravel-copilot-sdk/remote-sessions.md)
- [认证 - GitHub Copilot SDK for Laravel](/zh/packages/laravel-copilot-sdk/auth.md)
