INTEGRITY Документация

Каналы

Канал представляет собой способ связи, через который агент Think общается: WebSocket браузера, webhook мессенджера (Telegram, Slack и так далее), голос или ваш собственный транспорт. Каналы обобщают мессенджеры в единый словарь, чтобы можно было применять политику для каждого канала (другой системный промпт, суженный набор инструментов, ограничение числа шагов) и доставлять уведомления out-of-band независимо от того, через какую поверхность пришёл ход.

У каждого Think agent всегда есть неявный web канал (WebSocket-чат, которым пользуются ваши клиенты в браузере). Дополнительные каналы вы объявляете, а также переопределяете web политику: с configureChannels(). Messenger, возвращённые из getMessengers() автоматически поглощаются как messenger каналы, поэтому существующие приложения-мессенджеры продолжают работать без изменений.

Настройка каналов

Переопределить configureChannels() чтобы вернуть отображение идентификатора канала на ChannelDefinition. С помощью id вы выбираете канал в рамках хода:

import { Think, messengerChannel } from "@cloudflare/think";
import { telegram } from "@chat-adapter/telegram";

export class Assistant extends Think {
	configureChannels() {
		return {
			// Override policy for the built-in web channel.
			web: {
				kind: "web",
				ingress: { transport: "websocket" },
				instructions: "You are chatting in a web app. Use markdown freely.",
			},
			// A voice channel with tighter limits.
			voice: {
				kind: "voice",
				ingress: { transport: "voice" },
				instructions: "Keep replies short and speakable. No markdown.",
				maxTurns: 3,
			},
			// A messenger channel (Chat SDK webhook).
			telegram: messengerChannel(telegram({/* adapter config */})),
		};
	}
}
import { Think, messengerChannel } from "@cloudflare/think";
import { telegram } from "@chat-adapter/telegram";

export class Assistant extends Think<Env> {
	configureChannels() {
		return {
			// Override policy for the built-in web channel.
			web: {
				kind: "web",
				ingress: { transport: "websocket" },
				instructions: "You are chatting in a web app. Use markdown freely.",
			},
			// A voice channel with tighter limits.
			voice: {
				kind: "voice",
				ingress: { transport: "voice" },
				instructions: "Keep replies short and speakable. No markdown.",
				maxTurns: 3,
			},
			// A messenger channel (Chat SDK webhook).
			telegram: messengerChannel(
				telegram({
					/* adapter config */
				}),
			),
		};
	}
}

A ChannelDefinition содержит следующие поля:

Поле Тип Описание
kind "web" | "messenger" | "voice" | "custom" Категория поверхности.
ingress { transport: "websocket" | "voice" } или спецификацию мессенджера webhook Как поступают ходы. messengerChannel() формирует форму webhook за вас.
instructions string | (ctx: ChannelContext) => string | Promise<string> Добавляется в начало системного промпта для ходов в этом канале.
tools (all: ToolSet) => ToolSet Сузьте собранный набор инструментов для этого канала (только фильтрация, инструменты добавлять нельзя).
maxTurns number Ограничение числа шагов модели на канал за один ход.
capabilities ChannelCapabilities Отображаемые возможности (потоковая передача, редактирование сообщений). По умолчанию для web.
conversation режим переписки в мессенджере или resolver Маршрутизация тредов мессенджера (см. Мессенджеры).
delivery политика доставки канала Политика доставки мессенджера.

Используйте defineChannels() вспомогательную функцию для вывода типов и messengerChannel() чтобы обернуть определение адаптера Chat SDK как kind: "messenger" канал.

Типы каналов

Тип Ingress Примечания
web { transport: "websocket" } Всегда присутствует. Объявите его в configureChannels() только для установки политики; удалить её нельзя.
messenger вебхук (messengerChannel(...)) Передаётся в рантайм messenger. Эквивалентно getMessengers() запись.
voice { transport: "voice" } Применяет политику и контекст хода; доставка out-of-band пока не подключена.
custom определяется приложением Для собственного транспорта. Те же ограничения доставки, что и у voice сегодня.

Политика для отдельных каналов

Политика канала применяется как переопределяемое значение по умолчанию перед beforeTurn выполняется, поэтому beforeTurn переопределение всё равно имеет приоритет:

Выберите канал для хода

Передайте channel к runTurn() (или chat()) для запуска хода в определённом канале. ID канала впечатывается в сообщение пользователя, поэтому продолженный или восстановленный ход заново определяет тот же канал и повторно применяет его политику:

export class Assistant extends Think {
	async speak() {
		await this.runTurn({ input: "Read this out loud", channel: "voice" });
	}
}
export class Assistant extends Think<Env> {
	async speak() {
		await this.runTurn({ input: "Read this out loud", channel: "voice" });
	}
}

Внутри хода активный канал доступен как this.activeChannel ( ChannelContext с channelId, kind, и подробности мессенджера, если это уместно). Ход без channel выполняется без контекста канала и не применяет никакой политики канала.

Доставка вне обычного канала

deliverNotice() отправляет сообщение в канал без в начале хода модели. Используйте его для обновлений статуса («ваш импорт завершён») или чтобы показать ход выполнения действия вложение ответа : не выполняет инференс, не попадает в очередь ходов, и поэтому его безопасно вызывать изнутри execute:

export class Assistant extends Think {
	async notify() {
		await this.deliverNotice("Your export is ready to download.");

		await this.deliverNotice("Background research finished.", {
			informModel: true, // also record it in the transcript so the next turn knows
		});
	}
}
export class Assistant extends Think<Env> {
	async notify() {
		await this.deliverNotice("Your export is ready to download.");

		await this.deliverNotice("Background research finished.", {
			informModel: true, // also record it in the transcript so the next turn knows
		});
	}
}
type DeliverNoticeOptions = {
	channel?: string; // defaults to the active turn's channel, else "web"
	informModel?: boolean; // also write to the model-visible transcript (default false)
	kind?: "final" | "interim" | "notice" | "command"; // wire tag (default "notice")
	thread?: string; // required for out-of-turn delivery to a multi-thread messenger
};

Поведение зависит от целевого канала:

Переопределить renderAttachment(attachment) чтобы превратить вложение с ответом на действие в уведомление; Think вызывает её в конце хода и передаёт отрисованный текст как завершающее interim уведомление. Верните undefined чтобы пропустить тип вложения.

Отношение к мессенджерам

configureChannels() оборачивает getMessengers() : не заменяет его. Каждое getMessengers() запись становится kind: "messenger" канал и всё, что в Мессенджеры руководство (настройка Telegram, маршрутизация вебхуков, цели диалогов, доставка и восстановление) продолжает действовать. ID канала в configureChannels() который конфликтует с getMessengers() id является ошибкой. Продолжайте использовать getMessengers() для приложений только для мессенджеров; используйте configureChannels() когда вам также нужен web/voice/custom политику или уведомления out-of-band.

Observability

Активность канала отображается на channel канал наблюдаемости:

import { subscribe } from "agents/observability";

const unsubscribe = subscribe("channel", (event) => {
	// event.type is one of:
	//   "channel:resolved"  — a turn resolved a registered channel
	//   "channel:delivered" — a turn's final reply was delivered
	//   "notice:delivered"  — deliverNotice() succeeded
	//   "notice:failed"     — deliverNotice() threw
});
import { subscribe } from "agents/observability";

const unsubscribe = subscribe("channel", (event) => {
	// event.type is one of:
	//   "channel:resolved"  — a turn resolved a registered channel
	//   "channel:delivered" — a turn's final reply was delivered
	//   "notice:delivered"  — deliverNotice() succeeded
	//   "notice:failed"     — deliverNotice() threw
});

Справочник

Участник Описание
configureChannels() Верните карту каналов. По умолчанию: {} (неявный web только канал).
deliverNotice(text, options?) Отправьте сообщение out-of-band в канал без хода модели.
activeChannel ChannelContext для выполняющегося хода, либо undefined.
renderAttachment(attachment) Сопоставить вложение ответа с текстом уведомления канала (или undefined чтобы пропустить).
defineChannels(channels) Вспомогательная функция идентификации для вывода типа channel-map.
messengerChannel(definition) Оберните адаптер Chat SDK как kind: "messenger" канал.