> ## 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 也可運作。
* 也可以只指定 port。此時 host 會自動設為 `127.0.0.1`。
* 只指定 host 時僅支援 `127.0.0.1` 與 `localhost`。此時 port 預設為 `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 模式下可能無法正常運作。
也可以分開使用,例如 Queue 處理使用 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-TW/packages/laravel-copilot-sdk/laravel-cloud)。

## 注意事項

### 安全性

<Warning>
  TCP 伺服器盡量使用本機綁定(`127.0.0.1`)。
  若要對外開放,請適當設定防火牆。
</Warning>

### 重新連線

目前版本沒有自動重新連線功能。連線中斷時會拋出例外。

### 確認目前模式

可在程式中確認 Client 目前使用哪種模式。

```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. 確認 port 是否正確

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

- [Concurrency](/zh-TW/packages/laravel-copilot-sdk/concurrency.md)
- [GitHub Token](/zh-TW/packages/laravel-copilot-sdk/github-token.md)
- [Laravel Cloud - GitHub Copilot SDK for Laravel](/zh-TW/packages/laravel-copilot-sdk/laravel-cloud.md)
- [Session 生命週期事件](/zh-TW/packages/laravel-copilot-sdk/session-lifecycle-event.md)
- [認證 - GitHub Copilot SDK for Laravel](/zh-TW/packages/laravel-copilot-sdk/auth.md)
