Обзор
Когда streaming: true он настроен на сессию, SDK в реальном времени излучает эфемерные события (дельты, обновления прогресса) вместе с сохраненными событиями (полные сообщения, результаты инструментов). Все события имеют общую оболочку и несут полезную data нагрузку, форма которой зависит от события type.

| Концепция | Description |
|---|---|
| Эфемерное событие | Transient; Транслировался в реальном времени, но не сохранялся в журнале сессии. Не повторяется в резюме сессии. |
| Сохраняющееся событие | Сохранено в журнале событий сессии на диске. Повторяется при возобновлении сессии. |
| Событие Delta | Эфемерный потоковой фрагмент (текст или рассуждение). Накапливайте дельты для создания полного контента. |
parentId Цепь | Каждое событие parentId указывает на предыдущее, образуя связанный список, по которому можно пройтись. |
Оболочка событий
Каждое событие сессии, независимо от типа, включает следующие поля:
| Поле | Тип | Description |
|---|---|---|
id | ||
string (UUID версии 4) | Уникальный идентификатор события | |
timestamp | ||
string (ISO 8601) | Когда было создано событие | |
parentId | string | null | ID предыдущего события в цепочке; null для первого этапа |
agentId | string? | Идентификатор экземпляра субагентов для событий, связанных с субагентом; отсутствует для событий корневого или основного агента и уровня сеанса |
ephemeral | boolean? | |
true для временных событий; отсутствует или false из-за сохраняющихся событий | ||
type | string | Дискриминатор типа события (см. таблицы ниже) |
data | object | Полезная нагрузка, специфичная для конкретного события |
Подписка на события
Языки кода navigation
// All events
session.on((event) => {
console.log(event.type, event.data);
});
// Specific event type — data is narrowed automatically
session.on("assistant.message_delta", (event) => {
process.stdout.write(event.data.deltaContent);
});
from copilot.session_events import SessionEventType
def handle(event):
if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
print(event.data.delta_content, end="", flush=True)
session.on(handle)
session.On(func(event copilot.SessionEvent) {
if d, ok := event.Data.(*copilot.AssistantMessageDeltaData); ok {
fmt.Print(d.DeltaContent)
}
})
session.On<SessionEvent>(evt =>
{
if (evt is AssistantMessageDeltaEvent delta)
{
Console.Write(delta.Data.DeltaContent);
}
});
// All events
session.on(event -> System.out.println(event.getType()));
// Specific event type — data is narrowed to the matching class
session.on(AssistantMessageDeltaEvent.class, event ->
System.out.print(event.getData().deltaContent())
);
Совет
(Python / Go) Эти пакеты SDK используют отдельные типы данных для каждого события (например, AssistantMessageDeltaDataпоэтому только соответствующие поля существуют в каждом типе).
(.NET) SDK .NET использует отдельные, сильно типированные классы данных для каждого события (например, AssistantMessageDeltaData), поэтому для каждого типа существуют только соответствующие поля.
(TypeScript) SDK TypeScript использует дискриминированное объединение — при совпадении на event.type, data полезная нагрузка автоматически сужается до нужной формы.
Подписка перед началом сеанса
Сеанс может выдавать события до возврата вызова создания или возобновления. Агент может уже работать , особенно в возобновлении с continuePendingWorkсобытиями и временными событиями, такими как session.idle никогда не записываются в журнал сеансов, поэтому getMessages их невозможно восстановить после этого. Подписка, установленная после того, как дескриптор сеанса отсутствует в этом окне запуска.
Совет
(Rust)Client::prepare_session и Client::prepare_resume_session возвращает PreparedSession канал событий сеанса перед выполнением любого действия протокола. Сначала подпишитесь, а затем вызовите start().
use github_copilot_sdk::{Client, SessionConfig};
async fn create_without_missing_startup_events(
client: &Client,
) -> Result<(), github_copilot_sdk::Error> {
let prepared = client.prepare_session(
SessionConfig::default().with_event_buffer_capacity(2048),
)?;
// Installed before any wire activity: nothing is dropped for lack of a receiver.
let mut events = prepared.subscribe();
tokio::spawn(async move {
while let Ok(event) = events.recv().await {
println!("{}", event.event_type);
}
});
let session = prepared.start().await?;
let _ = session;
Ok(())
}
prepare_* является синхронным и инертным: он проверяет емкость буфера, выделяет локальный канал и не делает ничего другого. Сеанс не зарегистрирован и ничего не достигает интерфейса командной строки до start() первого опроса. Удаление подготовленного сеанса, которое никогда не было запущено, не оставляет состояния позади и закрывает свои подписки; start() удаление будущего отменяет запуск во время полета и отменяет регистрацию сеанса, поэтому повторная попытка с тем же идентификатором сеанса успешно выполнена. Очистка ограничена точной регистрацией заброшенного запуска, поэтому она не может вытеснить повторную попытку, которая уже взяла на себя тот же идентификатор сеанса.
Буферизация запуска стоит планировать для:
- Буфер событий является конечным — 512 событий, если
event_buffer_capacityон не переопределяется. Емкость0отклоняется с ошибкой недопустимой конфигурации, а не зажатой. - Медленные подписчики наблюдают за ошибкой, сообщая
Laggedо количестве пропущенных событий. Они никогда не применяют обратную прессу к циклу событий сеанса. - Потребители, которые нуждаются в потере представления большого запуска при запуске, должны настроить емкость, которая охватывает ее или слив подписку одновременно с
start().
Примечание.
Для облачных сеансов, где сервер назначает идентификатор сеанса, пакет SDK не может направлять уведомления до тех пор, пока не появится ответ создания, и идентификатор будет известен. События, создаваемые до этой точки, не могут быть перенаправлены в любой сеанс. Гарантия является более узкой: перенаправленные события никогда не удаляются из-за отсутствия установленного приемника. Закрепление session_id конфигурации для получения маршрутизации (и полного покрытия до отклика) из первого байта.
Отрисовка только ответа родительского агента
События субагентов совместно используют родительский поток сеансов и включают уровень agentIdконверта. События корневого или основного агента и события уровня сеанса опущены agentId, поэтому отрисовщики основного чата могут игнорировать события помощника, где agentId задано и перенаправляйте эти события в трассировку или пользовательский интерфейс выполнения.
import type { CopilotSession } from "@github/copilot-sdk";
export function subscribeParentResponse(session: CopilotSession): void {
session.on("assistant.message_delta", (event) => {
if (!event.agentId) {
process.stdout.write(event.data.deltaContent);
}
});
}
from copilot import CopilotSession, SessionEvent, SessionEventType
from copilot.session_events import AssistantMessageDeltaData
def subscribe_parent_response(session: CopilotSession) -> None:
def handle(event: SessionEvent) -> None:
if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA and event.agent_id is None:
data = event.data
if isinstance(data, AssistantMessageDeltaData):
print(data.delta_content, end="", flush=True)
session.on(handle)
package example
import (
"fmt"
copilot "github.com/github/copilot-sdk/go"
)
func subscribeParentResponse(session *copilot.Session) {
session.On(func(event copilot.SessionEvent) {
if event.AgentID != nil {
return
}
if d, ok := event.Data.(*copilot.AssistantMessageDeltaData); ok {
fmt.Print(d.DeltaContent)
}
})
}
using System;
using GitHub.Copilot;
static class ParentAgentResponseExample
{
public static void SubscribeParentResponse(CopilotSession session)
{
session.On<AssistantMessageDeltaEvent>(evt =>
{
if (evt.AgentId is null)
{
Console.Write(evt.Data.DeltaContent);
}
});
}
}
import com.github.copilot.CopilotSession;
import com.github.copilot.generated.AssistantMessageDeltaEvent;
final class ParentAgentResponseExample {
static void subscribeParentResponse(CopilotSession session) {
session.on(AssistantMessageDeltaEvent.class, event -> {
if (event.getAgentId() == null) {
System.out.print(event.getData().deltaContent());
}
});
}
}
use github_copilot_sdk::session::Session;
async fn subscribe_parent_response(session: &Session) {
let mut events = session.subscribe();
while let Ok(event) = events.recv().await {
if event.event_type == "assistant.message_delta" && event.agent_id.is_none() {
if let Some(delta) = event.data.get("deltaContent").and_then(|v| v.as_str()) {
print!("{delta}");
}
}
}
}
Соревнования ассистентов
Эти события отслеживают жизненный цикл реакции агента — от запуска ходов через потоковые фрагменты до финального сообщения.
assistant.turn_start
Излучается, когда агент начинает обрабатывать ход.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
turnId | string | ✅ | Идентификатор поворота (обычно строчный номер хода) |
interactionId | string | ||
| Идентификатор взаимодействия CAPI для корреляции телеметрии |
assistant.intent
Эфемерно. Краткое описание того, чем сейчас занимается агент, обновляется по мере работы.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
intent | string | ✅ | Человекочитаемый намерение (например, «Исследование кодовой базы») |
assistant.reasoning
Полный расширенный размышленный блок из модели. Выпущено после завершения рассуждений.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
reasoningId | string | ✅ | Уникальный идентификатор для этого блока рассуждения |
content | string | ✅ | Полный расширенный текст мышления |
assistant.reasoning_delta
Эфемерно. Постепенная часть расширенного мышления модели, транслируемая в реальном времени.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
reasoningId | string | ✅ | Совпадает с соответствующим assistant.reasoning событием |
deltaContent | string | ✅ | Текст для добавления к содержанию рассуждения |
assistant.message
Полный ответ ассистента на этот звонок LLM. Может содержать запросы на вызов инструментов.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
messageId | string | ✅ | Уникальный идентификатор для этого сообщения |
content | string | ✅ | Ответ ассистента в тексте |
toolRequests | ToolRequest[] | ||
| Вызовы инструментов, которые хочет сделать ассистент (см. ниже) | |||
reasoningOpaque | string | ||
| Зашифрованное расширенное мышление (антропные модели); Привязанный к сеансам | |||
reasoningText | string | ||
| Читаемый текст рассуждений из расширенного мышления | |||
encryptedContent | string | ||
| Зашифрованное рассуждение (модели OpenAI); Привязанный к сеансам | |||
phase | string | ||
Фаза генерации (например, "thinking" против "response") | |||
outputTokens | number | ||
| Фактическое количество токенов вывода из ответа API | |||
interactionId | string | ||
| Идентификатор взаимодействия CAPI для телеметрии | |||
parentToolCallId | string | ||
Deprecated. Использование уровня agentId конверта для присвоения субагентов |
**
ToolRequest Области:**
| Поле | Тип | Обязательный | Description |
|---|---|---|---|
toolCallId | string | ✅ | Уникальный идентификатор для этого вызова инструмента |
name | string | ✅ | Название инструмента (например, "bash", "edit", "grep") |
arguments | object | ||
| Проанализированные аргументы в пользу инструмента | |||
type | "function" | "custom" | ||
Тип вызова; по "function" умолчанию — когда отсутствует |
assistant.message_delta
Эфемерно. Постепенный фрагмент ответа ассистента в реальном времени.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
messageId | string | ✅ | Совпадает с соответствующим assistant.message событием |
deltaContent | string | ✅ | Текстовый фрагмент для добавления к сообщению |
parentToolCallId | string | ||
Deprecated. Использование уровня agentId конверта для присвоения субагентов |
assistant.turn_end
Издаётся после завершения хода агентом (выполнение всех инструментов завершено, финальный ответ получен).
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
turnId | string | ✅ | Совпадает с соответствующим assistant.turn_start событием |
assistant.usage
Эфемерно. Информация об использовании токена и стоимости для отдельного вызова API.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
model | string | ✅ | Идентификатор модели (например, "gpt-5.4") |
inputTokens | number | ||
| Расходуемые входные токены | |||
outputTokens | number | ||
| Выпускные токены | |||
reasoningTokens | number | ||
Выходные маркеры, используемые для рассудка или цепочки мысли (подмножество outputTokens) | |||
cacheReadTokens | number | ||
| Токены, читаемые из кэша prompt | |||
cacheWriteTokens | number | ||
| Токены, записываемые для кэша prompt | |||
cacheExpiresAt | string | ||
| Метка времени ISO 8601 при истечении срока действия кэша запросов для вызова модели | |||
content | boolean | ||
Заблокировано или усечено ли ответ с помощью фильтрации содержимого (finish_reason === 'content_filter') | |||
finishReason | string | ||
Причина завершения модели (например, , "stop"``"length", , ) "tool_calls"``"content_filter" | |||
cost | number | ||
| Стоимость мультипликатора модели для выставления счетов | |||
duration | number | ||
| Длительность вызова API в миллисекундах | |||
time | number | ||
| Время от отправки запроса к первому маркеру (задержка потоковой передачи) | |||
inter | number | ||
| Средняя задержка между последовательными маркерами (пропускная способность потоковой передачи) | |||
reasoningEffort | string | ||
Уровень усилий, используемый для этого вызова (например, , "low", "medium") "high" | |||
initiator | string | ||
Что спровоцировало этот вызов (например, "sub-agent"); отсутствует для инициированного пользователем | |||
apiCallId | string | ||
Идентификатор завершения от провайдера (например, chatcmpl-abc123) | |||
serviceRequestId | string | ||
Copilot идентификатор запроса службы (x-copilot-service-request-id) для корреляции журнала CAPI | |||
apiEndpoint | "/ | ||
| API-конечная точка, используемая для вызова модели; Полезно для атрибуции наблюдаемости и стоимости. | |||
ws:/responses является вариантом websocket API ответов | |||
providerCallId | string | ||
GitHub запросить трассировочный идентификатор (x-github-request-id) | |||
parentToolCallId | string | ||
Deprecated. Использование уровня agentId конверта для присвоения субагентов | |||
quotaSnapshots | Record<string, QuotaSnapshot> | ||
| Использование ресурсов по квотам, определяемое идентификатором квоты | |||
copilotUsage | CopilotUsage | ||
| Детализированная разбивка стоимости токена из API |
assistant.streaming_delta
Эфемерно. Низкоуровневый индикатор прогресса сети — общее количество байт, полученных от ответа потокового API.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
total | number | ✅ | Совокупные байты, полученные на данный момент |
События выполнения инструментов
Эти события отслеживают полный жизненный цикл каждого вызова инструмента — от запроса вызова инструмента моделью до его выполнения.
tool.execution_start
Испускается, когда инструмент начинает работать.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
toolCallId | string | ✅ | Уникальный идентификатор для этого вызова инструмента |
toolName | string | ✅ | Название инструмента (например, "bash", "edit", "grep") |
arguments | object | ||
| Анализированные аргументы, передаваемые инструменту | |||
mcpServerName | string | ||
| Имя сервера MCP, когда инструмент предоставляется сервером MCP | |||
mcpToolName | string | ||
| Оригинальное имя инструмента на сервере MCP | |||
parentToolCallId | string | ||
Deprecated. Использование уровня agentId конверта для присвоения субагентов |
tool.execution_partial_result
Эфемерно. Инкрементальный вывод от запускающегося инструмента (например, потоковой выход bash).
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
toolCallId | string | ✅ | Совпадает с соответствующими tool.execution_start |
partialOutput | string | ✅ | Инкрементальный выходной блок |
tool.execution_progress
Эфемерно. Читаемый человеком статус прогресса из запускаемого инструмента (например, уведомления о прогрессе сервера MCP).
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
toolCallId | string | ✅ | Совпадает с соответствующими tool.execution_start |
progressMessage | string | ✅ | Сообщение о статусе прогресса |
tool.execution_complete
Издаётся, когда инструмент завершает выполнение — успешно или с ошибкой.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
toolCallId | string | ✅ | Совпадает с соответствующими tool.execution_start |
success | boolean | ✅ | Была ли казнь успешной |
model | string | ||
| Модель, которая сгенерировала этот вызов инструмента | |||
interactionId | string | ||
| Идентификатор взаимодействия CAPI | |||
isUserRequested | boolean | ||
true когда пользователь явно запросил этот вызов инструмента | |||
result | Result | ||
| Представление об успехе (см. ниже) | |||
error | { message, code? } | ||
| Присутствует при неисправности | |||
toolTelemetry | object | ||
| Телеметрия, специфичная для инструмента (например, подсчёт проверок CodeQL) | |||
parentToolCallId | string | ||
Deprecated. Использование уровня agentId конверта для присвоения субагентов |
**
Result Области:**
| Поле | Тип | Обязательный | Description |
|---|---|---|---|
content | string | ✅ | Краткий результат отправляется в LLM (может быть урезан для повышения эффективности токенов) |
detailedContent | string | ||
| Полный результат для отображения, сохраняя полный контент, например, diff | |||
contents | ContentBlock[] | ||
| Структурированные блоки контента (текст, терминал, изображение, аудио, ресурс) |
tool.user_requested
Издаётся, когда пользователь явно запрашивает вызов инструмента (вместо того чтобы модель выбирает вызов инструмента).
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
toolCallId | string | ✅ | Уникальный идентификатор для этого вызова инструмента |
toolName | string | ✅ | Название инструмента, который пользователь хочет вызвать |
arguments | object | ||
| Аргументы в пользу призыва |
События жизненного цикла сессии
session.idle
Эфемерно. Агент завершил всю обработку и готов к следующему сообщению. Это сигнал о полном завершении поворота.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
aborted | boolean | ||
| Значение true, когда предыдущий поворот был отменен через сигнал прерывания |
session.error
Во время обработки сессии произошла ошибка.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
errorType | string | ✅ | Категория ошибок (например, "authentication", "quota", "rate_limit") |
message | string | ✅ | Сообщение об ошибке, читаемое человеком |
stack | string | ||
| Трассировка стека ошибок | |||
statusCode | number | ||
| Статус HTTP-кода из восходящего запроса | |||
providerCallId | string | ||
| GitHub трассирующий идентификатор запросов для корреляции логов на сервере |
session.compaction_start
Началось уплотнение контекстного окна.
Полезная нагрузка данных пуста ({}).
session.compaction_complete
Уплотнение контекстного окна завершено.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
success | boolean | ✅ | Удалось ли уплотнение |
error | string | ||
| Сообщение об ошибке при неудачном уплотнении | |||
pre | number | ||
| Токены до уплотнения | |||
post | number | ||
| Токены после уплотнения | |||
pre | number | ||
| Количество сообщений до уплотнения | |||
messagesRemoved | number | ||
| Сообщения удалены | |||
tokensRemoved | number | ||
| Жетоны удалены | |||
summaryContent | string | ||
| LLM-генерируемое резюме компактной истории | |||
checkpointNumber | number | ||
| Номер снимка контрольной точки для восстановления | |||
checkpointPath | string | ||
| Путь файла, где хранился контрольный пункт | |||
compaction | { input, output, cachedInput } | ||
| Использование токена для вызова компрессионного LLM | |||
requestId | string | ||
| GitHub запрос идентификатора трассировки для вызова компрессии |
session.title_changed
Эфемерно. Автоматически сгенерированное название сессии было обновлено.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
title | string | ✅ | Новое название сессии |
session.context_changed
Рабочий каталог или контекст репозитория сессии изменились.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
cwd | string | ✅ | Текущий рабочий справочник |
gitRoot | string | ||
| Корень репозитория Git | |||
repository | string | ||
Репозиторий в "owner/name" формате | |||
branch | string | ||
| Текущая ветка git |
session.usage_info
Эфемерно. Снимок использования контекстного окна.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
tokenLimit | number | ✅ | Максимальное количество токенов для контекстного окна модели |
currentTokens | number | ✅ | Текущие токены в контекстном окне |
messagesLength | number | ✅ | Текущее количество сообщений в разговоре |
session.session_limits_changed
Лимиты сессий изменились для текущего бухгалтерского окна. Значение null``sessionLimits означает, что ограничения не активны.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
sessionLimits | Session | ✅ | Текущие ограничения сессий, или null когда ограничения не активны |
session | number | ||
| Максимальное количество кредитов ИИ, разрешенное в течение текущего бухгалтерского окна сессии |
session.usage_checkpoint
Долговечная контрольная точка использования агрегата, используемая для восстановления учёта при возобновлении сессии.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
totalNanoAiu | number | ✅ | Накопленные нано-ИИ единицы на протяжении всей сессии стоят во время контрольной точки |
total | number | ||
| Общее количество премиум-запросов API, используемых на момент контрольной точки |
session.task_complete
Агент выполнил назначенную задачу.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
summary | string | ||
| Краткое содержание выполненной задачи |
session.shutdown
Сессия закончилась.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
shutdownType | "routine" | "error" | ✅ | Обычное отключение или сбой |
errorReason | string | ||
Описание ошибки, когда shutdownType равна "error" | |||
total | number | ✅ | Общее количество используемых премиум-запросов API |
total | number | ✅ | Кумулятивное время вызова API в миллисекундах |
sessionStartTime | number | ✅ | Unix timestamp (ms) при начале сессии |
codeChanges | { linesAdded, linesRemoved, filesModified } | ✅ | Метрики агрегированных изменений кода |
modelMetrics | Record<string, ModelMetric> | ✅ | Распределение использования по моделям |
currentModel | string | ||
| Модель выбрана во время отключения |
Разрешения и события ввода пользователя
Эти события возникают, когда агенту требуется одобрение или ввод от пользователя перед продолжением.
permission.requested
Агенту требуется разрешение на выполнение действия (запуск команды, записи файла и т.д.).
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
requestId | string | ✅ | Используйте это, чтобы ответить через session.respond |
permissionRequest | PermissionRequest | ✅ | Детали запрашиваемого разрешения |
Это permissionRequest дискриминационный союз на kind:
kind | Поля ключа | Description |
|---|---|---|
"shell" | ||
fullCommandText, , intention``commands[]``possible | Выполните команду shell | |
"write" | ||
fileName, , diff``intention``new | Запись/изменение файла | |
"read" | ||
path, intention | Прочитайте файл или каталог | |
"mcp" | ||
serverName, , tool, args?``readOnly | Вызовите инструмент MCP | |
"url" | ||
url, intention | Получить URL | |
"memory" | ||
subject, , fact``citations | Сохранить память | |
"custom-tool" | ||
toolName, , tool | Вызовите пользовательский инструмент |
Все kind варианты также включают опциональную toolCallId связь с вызовом инструмента, который инициировал запрос.
permission.completed
Запрос на разрешение был урегулирован.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
requestId | string | ✅ | Совпадает с соответствующими permission.requested |
result.kind | string | ✅ | Один из: "approved", "denied-by-rules", "denied-interactively-by-user", "denied-no-approval-rule-and-could-not-request-from-user", "denied-by-content-exclusion-policy" |
user_input.requested
Эфемерно. Агент задаёт пользователю вопрос.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
requestId | string | ✅ | Используйте это, чтобы ответить через session.respond |
question | string | ✅ | Вопрос, который стоит задать пользователю |
choices | string[] | ||
| Предопределённые варианты для пользователя | |||
allowFreeform | boolean | ||
| Разрешен ли ввод свободного текста |
user_input.completed
Эфемерно. Запрос пользователя был решен.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
requestId | string | ✅ | Совпадает с соответствующими user_input.requested |
elicitation.requested
Эфемерно. Агенту нужен структурированный ввод формы от пользователя (протокол идентификации MCP).
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
requestId | string | ✅ | Используйте это, чтобы ответить через session.respond |
message | string | ✅ | Описание необходимой информации |
mode | "form" | ||
Режим вызова (пока только "form") | |||
requestedSchema | { type: "object", properties, required? } | ✅ | Схема JSON, описывающая поля формы |
elicitation.completed
Эфемерно. Запрос на расследование был урегулирован.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
requestId | string | ✅ | Совпадает с соответствующими elicitation.requested |
События субагентов и навыков
subagent.started
Был вызван таможенный агент как субагент.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
toolCallId | string | ✅ | Родительский вызов инструмента, который породил этот подагент |
agentName | string | ✅ | Внутреннее имя субагента |
agentDisplayName | string | ✅ | Отображение, читаемое человеком |
agentDescription | string | ✅ | Описание того, что делает субагент |
model | string | ||
| Модель субагентов будет выполняться с, когда известно при запуске |
subagent.completed
Субагент успешно закончил.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
toolCallId | string | ✅ | Совпадает с соответствующими subagent.started |
agentName | string | ✅ | Внутреннее имя |
agentDisplayName | string | ✅ | Показать имя |
model | string | ||
| Модель, используемая вложенным агентом | |||
durationMs | number | ||
| Длительность выполнения стенных часов в миллисекундах | |||
totalTokens | number | ||
| Общее количество используемых входных и выходных маркеров | |||
totalToolCalls | number | ||
| Всего вызовов инструментов |
subagent.failed
Субагент столкнулся с ошибкой.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
toolCallId | string | ✅ | Совпадает с соответствующими subagent.started |
agentName | string | ✅ | Внутреннее имя |
agentDisplayName | string | ✅ | Показать имя |
error | string | ✅ | Сообщение об ошибке |
model | string | ||
| Модель, выбранная для субагентов, когда известная | |||
durationMs | number | ||
| Длительность выполнения стенных часов в миллисекундах | |||
totalTokens | number | ||
| Общее количество входных и выходных маркеров, потребляемых до сбоя | |||
totalToolCalls | number | ||
| Всего вызовов инструментов, выполненных до сбоя |
subagent.selected
Был выбран (вывод) пользовательский агент для обработки текущего запроса.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
agentName | string | ✅ | Внутреннее имя выбранного агента |
agentDisplayName | string | ✅ | Показать имя |
tools | string[] | null | ✅ | Имена инструментов, доступные этому агенту; null для всех инструментов |
subagent.deselected
Пользовательский агент был снят с выбора и вернулся к стандартному агенту.
Полезная нагрузка данных пуста ({}).
skill.invoked
Для текущего разговора был активирован навык.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
name | string | ✅ | Название навыка |
path | string | ✅ | Путь файла к определению SKILL.md |
content | string | ✅ | В разговор добавляется полный контент по навыкам |
allowedTools | string[] | ||
| Инструменты автоматически одобряются, пока этот навык активен | |||
pluginName | string | ||
| Плагин, из которого возник навык | |||
pluginVersion | string | ||
| Версия плагина |
Другие события
abort
Текущий поворот был прерван.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
reason | string | ✅ | Почему ход был прерван (например, "user initiated") |
user.message
Пользователь отправил сообщение. Записано для хронологии сессии.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
content | string | ✅ | Текст сообщения пользователя |
transformed | string | ||
| Трансформированная версия после предварительной обработки | |||
attachments | Attachment[] | ||
| Файлы, каталоги, выбор, blob или вложения на GitHub | |||
source | string | ||
| Идентификатор источника сообщения | |||
agentMode | string | ||
Режим агента: "interactive", "plan", "autopilot", или "shell" | |||
interactionId | string | ||
| Идентификатор взаимодействия CAPI |
system.message
В разговор вводился подсказка системы или разработчика.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
content | string | ✅ | Текст запроса |
role | "system" | "developer" | ✅ | Роль сообщения |
name | string | ||
| Идентификатор источника | |||
metadata | { promptVersion?, variables? } | ||
| Метаданные шаблона запросов |
external_tool.requested
Агент хочет вызвать внешний инструмент (предоставленный потребителем SDK).
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
requestId | string | ✅ | Используйте это, чтобы ответить через session.respond |
sessionId | string | ✅ | Сессия, к которой принадлежит этот запрос |
toolCallId | string | ✅ | Идентификатор вызова инструмента для этого вызова |
toolName | string | ✅ | Название внешнего инструмента |
arguments | object | ||
| Аргументы в пользу инструмента |
external_tool.completed
Запрос на внешний инструмент был урегулирован.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
requestId | string | ✅ | Совпадает с соответствующими external_tool.requested |
exit_plan_mode.requested
Эфемерно. Агент составил план и хочет выйти из режима плана.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
requestId | string | ✅ | Используйте это, чтобы ответить через session.respond |
summary | string | ✅ | Краткое содержание плана |
planContent | string | ✅ | Полный файл плана |
actions | string[] | ✅ | Доступные действия пользователя (например, одобрить, отредактировать, отклонить) |
recommendedAction | string | ✅ | Рекомендуемое действие |
exit_plan_mode.completed
Эфемерно. Запрос на режим выхода был урегулирован.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
requestId | string | ✅ | Совпадает с соответствующими exit_plan_mode.requested |
command.queued
Эфемерно. Для выполнения была поставлена слэш-команда.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
requestId | string | ✅ | Используйте это, чтобы ответить через session.respond |
command | string | ✅ | Текст команды по косой черте (например, /help, /clear) |
command.completed
Эфемерно. Была решена очередная команда.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
requestId | string | ✅ | Совпадает с соответствующими command.queued |
session_limits_exhausted.requested
Эфемерно. Текущий бюджет сессии был исчерпан, и время выполнения требует решения пользователя перед продолжением.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
requestId | string | ✅ | Используйте этот идентификатор при ответе на ожидающий запрос с исчерпанным лимитом |
maxAiCredits | number | ✅ | Настроен максимальный AI Credits для текущего бухгалтерского окна |
usedAiCredits | number | ✅ | Кредиты ИИ, уже использованные в текущем бухгалтерском окне |
session_limits_exhausted.completed
Эфемерно. Был урегулирован неожиданный запрос по исчерпанному лимиту.
| Поле данных | Тип | Обязательный | Description |
|---|---|---|---|
requestId | string | ✅ | Совпадает с соответствующим session_limits_ событием |
response.action | "add" | "set" | "unset" | "cancel" | ✅ | Выбрано действие для запроса с исчерпанным лимитом |
response.additional | number | ||
Кредиты ИИ, которые можно добавить к текущему максимуму, когда response.action``"add" | |||
response.max | number | ||
Новые абсолютные максимальные ИИ-кредиты, когда response.action это "set" |
Краткая справка: агентный поток поворотов
Типичный агентный ход генерирует события в следующем порядке:
assistant.turn_start → Turn begins
├── assistant.intent → What the agent plans to do (ephemeral)
├── assistant.reasoning_delta → Streaming thinking chunks (ephemeral, repeated)
├── assistant.reasoning → Complete thinking block
├── assistant.message_delta → Streaming response chunks (ephemeral, repeated)
├── assistant.message → Complete response (may include toolRequests)
├── assistant.usage → Token usage for this API call (ephemeral)
│
├── [If tools were requested:]
│ ├── permission.requested → Needs user approval
│ ├── permission.completed → Approval result
│ ├── tool.execution_start → Tool begins
│ ├── tool.execution_partial_result → Streaming tool output (ephemeral, repeated)
│ ├── tool.execution_progress → Progress updates (ephemeral, repeated)
│ ├── tool.execution_complete → Tool finished
│ │
│ └── [Agent loops: more reasoning → message → tool calls...]
│
assistant.turn_end → Turn complete
session.idle → Ready for next message (ephemeral)
Все типы событий одним взглядом
В этой таблице перечислены ключевые data полезные поля. Общие поля конверта описаны выше.
| Тип события | Эфемерный | Категория | Ключевые поля данных |
|---|---|---|---|
assistant.turn_start | |||
| Помощник | |||
turnId, interactionId? | |||
assistant.intent | ✅ | Помощник | intent |
assistant.reasoning | |||
| Помощник | |||
reasoningId, content | |||
assistant.reasoning_delta | ✅ | Помощник | |
reasoningId, deltaContent | |||
assistant.streaming_delta | ✅ | Помощник | total |
assistant.message | |||
| Помощник | |||
messageId, , content``tool, output | |||
assistant.message_delta | ✅ | Помощник | |
messageId, deltaContent | |||
assistant.turn_end | |||
| Помощник | turnId | ||
assistant.usage | ✅ | Помощник | |
model, , api,duration? | |||
tool.user_requested | |||
| инструмент | |||
toolCallId, , tool | |||
tool.execution_start | |||
| инструмент | |||
toolCallId, , tool | |||
tool.execution_partial_ | ✅ | инструмент | |
toolCallId, partialOutput | |||
tool.execution_progress | ✅ | инструмент | |
toolCallId, progressMessage | |||
tool.execution_complete | |||
| инструмент | |||
toolCallId, , success``result?``error? | |||
session.idle | ✅ | Session | aborted? |
session.error | |||
| Session | |||
errorType, , message``status | |||
session.compaction_start | |||
| Session | |||
| (пусто) | |||
session.compaction_complete | |||
| Session | |||
success, , pre | |||
session.title_changed | ✅ | Session | title |
session.context_changed | |||
| Session | |||
cwd, , git | |||
session.usage_info | ✅ | Session | |
tokenLimit, , current | |||
session.session_limits_ | |||
| Session | sessionLimits | ||
session.usage_checkpoint | |||
| Session | |||
totalNanoAiu, total | |||
session.task_complete | |||
| Session | summary? | ||
session.shutdown | |||
| Session | |||
shutdownType, , code | |||
permission.requested | |||
| Разрешение | |||
requestId, permissionRequest | |||
permission.completed | |||
| Разрешение | |||
requestId, result.kind | |||
user_input.requested | ✅ | Входные данные пользователя | |
requestId, , question``choices? | |||
user_input.completed | ✅ | Входные данные пользователя | requestId |
elicitation.requested | ✅ | Входные данные пользователя | |
requestId, , message``requested | |||
elicitation.completed | ✅ | Входные данные пользователя | requestId |
subagent.started | |||
| Sub-Agent | |||
toolCallId, , agent | |||
subagent.completed | |||
| Sub-Agent | |||
toolCallId, agentName, agent, durationMs?, totalTokens?, totalToolCalls? | |||
subagent.failed | |||
| Sub-Agent | |||
toolCallId, agentName, error``model?, durationMs?, totalTokens?, totalToolCalls? | |||
subagent.selected | |||
| Sub-Agent | |||
agentName, , agent | |||
subagent.deselected | |||
| Sub-Agent | |||
| (пусто) | |||
skill.invoked | |||
| Skill | |||
name, , path``content``allowed | |||
abort | |||
| Управление | reason | ||
user.message | |||
| Пользователь | |||
content, , attachments?``agent | |||
system.message | |||
| System | |||
content, role | |||
external_tool.requested | |||
| Внешний инструмент | |||
requestId, , tool | |||
external_tool.completed | |||
| Внешний инструмент | requestId | ||
command.queued | ✅ | Command | |
requestId, command | |||
command.completed | ✅ | Command | requestId |
session_limits_ | ✅ | Session | |
requestId, , max | |||
session_limits_ | ✅ | Session | |
requestId, response.action | |||
exit_plan_mode.requested | ✅ | Режим планирования | |
requestId, , summary``plan | |||
exit_plan_mode.completed | ✅ | Режим планирования | requestId |