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

# 会话上下文与过滤

> 说明如何使用 Laravel Copilot SDK 的 SessionContext 与 SessionListFilter 按工作目录和 Git 信息查看与筛选会话。

## 会话上下文与过滤

从 GitHub Copilot SDK v0.1.24 开始，会话中新增了包含工作目录和 Git 信息的上下文，可以在会话列表中进行过滤。

## SessionContext

`SessionContext` 保存会话创建时的工作目录和 Git 仓库信息。

### 属性

* `cwd` (`string`): 工作目录的绝对路径
* `gitRoot` (`?string`): Git 仓库的根目录（在 Git 仓库之外为 `null`）
* `repository` (`?string`): GitHub 仓库（`owner/repo` 格式，如 `invokable/laravel-copilot-sdk`）
* `branch` (`?string`): 当前的 Git 分支名

### 使用示例

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

// 获取会话列表
$sessions = Copilot::client()->listSessions();

foreach ($sessions as $metadata) {
    echo "Session: {$metadata->sessionId}\n";

    if ($metadata->context !== null) {
        echo "  工作目录: {$metadata->context->cwd}\n";

        if ($metadata->context->repository !== null) {
            echo "  仓库: {$metadata->context->repository}\n";
            echo "  分支: {$metadata->context->branch}\n";
        }
    }
}
```

## SessionListFilter

使用 `SessionListFilter` 可以只获取特定工作目录或仓库的会话。

### 属性

* `cwd` (`?string`): 按工作目录完全匹配过滤
* `gitRoot` (`?string`): 按 Git 根目录过滤
* `repository` (`?string`): 按仓库（`owner/repo` 格式）过滤
* `branch` (`?string`): 按分支名过滤

### 使用示例

#### 用数组指定过滤器

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

// 只获取特定仓库的会话
$sessions = Copilot::client()->listSessions([
    'repository' => 'invokable/laravel-copilot-sdk',
]);

// 获取在特定分支上工作的会话
$sessions = Copilot::client()->listSessions([
    'repository' => 'owner/repo',
    'branch' => 'feature/new-feature',
]);

// 获取特定工作目录的会话
$sessions = Copilot::client()->listSessions([
    'cwd' => '/home/user/projects/my-app',
]);
```

#### 使用 SessionListFilter 类

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

$filter = new SessionListFilter(
    repository: 'owner/repo',
    branch: 'main',
);

$sessions = Copilot::client()->listSessions($filter);
```

## `session.context_changed` 事件

在会话过程中，如果工作目录发生变化，会触发 `session.context_changed` 事件。

### 事件类型

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

SessionEventType::SESSION_CONTEXT_CHANGED; // 'session.context_changed'
```

### 事件数据

事件数据包含更新后的上下文信息。

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

Copilot::start(function ($session) {
    $session->on(function ($event) {
        if ($event->type === 'session.context_changed') {
            $data = $event->data;

            echo "工作目录已变更\n";
            echo "  cwd: {$data['cwd']}\n";
            echo "  repository: {$data['repository']}\n";
            echo "  branch: {$data['branch']}\n";
        }
    });

    $response = $session->sendAndWait(
        prompt: 'Change to a different directory and list files',
    );
});
```

## SessionMetadata

`SessionMetadata` 中新增了 `context` 属性。

### 新属性

* `context` (`?SessionContext`): 会话的工作目录和 Git 信息

### 使用示例

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

$sessions = Copilot::client()->listSessions();

foreach ($sessions as $metadata) {
    echo "Session ID: {$metadata->sessionId}\n";
    echo "开始时间: {$metadata->startTime}\n";

    // context 是可选的，需要进行 null 检查
    if ($metadata->context !== null) {
        echo "上下文:\n";
        echo "  工作目录: {$metadata->context->cwd}\n";

        if ($metadata->context->repository !== null) {
            echo "  仓库: {$metadata->context->repository}\n";
        }

        if ($metadata->context->branch !== null) {
            echo "  分支: {$metadata->context->branch}\n";
        }
    }

    echo "\n";
}
```

## 实用示例

### 获取特定项目的会话

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

// 只获取 Laravel Copilot SDK 项目的会话
$sessions = Copilot::client()->listSessions([
    'repository' => 'invokable/laravel-copilot-sdk',
]);

// 显示工作中的会话
foreach ($sessions as $metadata) {
    echo "{$metadata->sessionId}: {$metadata->summary}\n";
    echo "  分支: {$metadata->context->branch}\n";
}
```

### 管理功能分支的会话

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

$sessions = Copilot::client()->listSessions();

$featureSessions = array_filter($sessions, function ($metadata) {
    return $metadata->context !== null
        && str_starts_with($metadata->context->branch ?? '', 'feature/');
});

// 按功能分支对会话进行分组
$byBranch = [];
foreach ($featureSessions as $metadata) {
    $branch = $metadata->context->branch;
    $byBranch[$branch][] = $metadata;
}

foreach ($byBranch as $branch => $sessions) {
    echo "{$branch}: " . count($sessions) . " 个会话\n";
}
```

### 按工作目录整理会话

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

$sessions = Copilot::client()->listSessions();

// 按工作目录分组
$byCwd = [];
foreach ($sessions as $metadata) {
    if ($metadata->context !== null) {
        $cwd = $metadata->context->cwd;
        $byCwd[$cwd][] = $metadata;
    }
}

// 显示每个目录的会话数
foreach ($byCwd as $cwd => $sessions) {
    echo "{$cwd}: " . count($sessions) . " 个会话\n";
}
```

## 注意事项

* 只有在 Git 仓库内创建的会话，`context` 才会包含 Git 相关信息（`gitRoot`、`repository`、`branch`）。
* `context` 字段在 Copilot CLI v0.0.409 及以上可用。在旧版本上会返回 `null`。
* 过滤是完全匹配的方式工作。不支持部分匹配或通配符。
* `SessionListFilter` 的所有字段都是可选的。不指定过滤器时会返回所有会话。

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


## Related topics

- [Laravel AI SDK](/zh/ai-sdk.md)
- [Context（上下文）](/zh/context.md)
- [会话钩子](/zh/packages/laravel-copilot-sdk/hooks.md)
- [用于 Laravel AI SDK 的 Amazon Bedrock 驱动](/zh/packages/laravel-amazon-bedrock.md)
- [会话恢复](/zh/packages/laravel-copilot-sdk/resume.md)
