feat(agent): add connected channels section to system prompt

Add ChannelInfo type and buildChannelsSection() that informs the LLM
about connected messaging channels and their capabilities (e.g. send
files). Wire through SystemPromptOptions and runner.ts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jiayuan Zhang 2026-02-13 01:37:29 +08:00
parent 01b89ed488
commit 0ebd9d6b22
5 changed files with 50 additions and 0 deletions

View file

@ -1192,6 +1192,7 @@ export class Agent {
tools: toolNames,
skillsPrompt,
runtime,
channels: this.toolsOptions.channels,
});
}
}

View file

@ -10,6 +10,7 @@ import type {
SystemPromptReport,
} from "./types.js";
import {
buildChannelsSection,
buildHeartbeatSection,
buildConditionalToolSections,
buildExtraPromptSection,
@ -51,6 +52,7 @@ export function buildSystemPromptWithReport(options: SystemPromptOptions): {
skillsPrompt,
runtime,
subagent,
channels,
extraSystemPrompt,
includeSafety = true,
} = options;
@ -70,6 +72,7 @@ export function buildSystemPromptWithReport(options: SystemPromptOptions): {
{ name: "runtime", lines: buildRuntimeSection(runtime, mode) },
{ name: "time-awareness", lines: buildTimeAwarenessSection(tools, mode) },
{ name: "profile-dir", lines: buildProfileDirSection(profileDir, mode) },
{ name: "channels", lines: buildChannelsSection(channels, mode) },
{ name: "subagent", lines: buildSubagentSection(subagent, mode) },
{ name: "extra", lines: buildExtraPromptSection(extraSystemPrompt, mode) },
];

View file

@ -8,6 +8,7 @@ export { formatPromptReport } from "./report.js";
export { SAFETY_CONSTITUTION } from "./constitution.js";
export type {
ChannelInfo,
ProfileContent,
PromptSection,
RuntimeInfo,

View file

@ -8,6 +8,7 @@ import { SAFETY_CONSTITUTION } from "./constitution.js";
import { formatRuntimeLine } from "./runtime-info.js";
import { resolveHeartbeatPrompt } from "../../heartbeat/heartbeat-text.js";
import type {
ChannelInfo,
ProfileContent,
RuntimeInfo,
SubagentContext,
@ -461,6 +462,40 @@ export function buildSubagentSection(
return lines;
}
/**
* Connected channels section tells the agent which messaging channels are active
* and what capabilities they have (e.g. send files). Full mode only.
*/
export function buildChannelsSection(
channels: ChannelInfo[] | undefined,
mode: SystemPromptMode,
): string[] {
if (mode !== "full" || !channels || channels.length === 0) return [];
const lines: string[] = ["## Connected Channels", ""];
for (const ch of channels) {
lines.push(`- **${ch.name}**`);
if (ch.canSendMedia) {
lines.push(
" Capabilities: receive text/voice/image/video/document, send text, send files (photo, document, video, audio)",
);
lines.push(" Use the `send_file` tool to send files to channel users.");
} else {
lines.push(" Capabilities: receive text, send text");
}
}
lines.push(
"",
"Messages from channels are prefixed with `[ChannelName · private]` or `[ChannelName · group]`.",
"When responding to channel messages, adapt your formatting for messaging platforms (shorter paragraphs, no complex markdown).",
"",
);
return lines;
}
/**
* Extra system prompt appended at the end if provided.
*/

View file

@ -37,6 +37,14 @@ export interface RuntimeInfo {
cwd?: string | undefined;
}
/** Describes a connected messaging channel and its capabilities */
export interface ChannelInfo {
/** Human-readable channel name (e.g. "Telegram") */
name: string;
/** Whether the channel supports outbound media via send_file */
canSendMedia: boolean;
}
/** Subagent context for minimal/none modes */
export interface SubagentContext {
/** Parent session that spawned this subagent */
@ -77,6 +85,8 @@ export interface SystemPromptOptions {
subagent?: SubagentContext | undefined;
/** Workspace directory path (for agent working directory info) */
workspaceDir?: string | undefined;
/** Connected messaging channels (for channel awareness section) */
channels?: ChannelInfo[] | undefined;
/** Extra system prompt to append */
extraSystemPrompt?: string | undefined;
/** Whether to include the safety constitution (default: true) */