diff --git a/packages/core/src/agent/runner.ts b/packages/core/src/agent/runner.ts index 3e7c2f22..92ce68dd 100644 --- a/packages/core/src/agent/runner.ts +++ b/packages/core/src/agent/runner.ts @@ -1192,6 +1192,7 @@ export class Agent { tools: toolNames, skillsPrompt, runtime, + channels: this.toolsOptions.channels, }); } } diff --git a/packages/core/src/agent/system-prompt/builder.ts b/packages/core/src/agent/system-prompt/builder.ts index 82d01860..f7120d72 100644 --- a/packages/core/src/agent/system-prompt/builder.ts +++ b/packages/core/src/agent/system-prompt/builder.ts @@ -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) }, ]; diff --git a/packages/core/src/agent/system-prompt/index.ts b/packages/core/src/agent/system-prompt/index.ts index 6c1a9ffe..5944eb39 100644 --- a/packages/core/src/agent/system-prompt/index.ts +++ b/packages/core/src/agent/system-prompt/index.ts @@ -8,6 +8,7 @@ export { formatPromptReport } from "./report.js"; export { SAFETY_CONSTITUTION } from "./constitution.js"; export type { + ChannelInfo, ProfileContent, PromptSection, RuntimeInfo, diff --git a/packages/core/src/agent/system-prompt/sections.ts b/packages/core/src/agent/system-prompt/sections.ts index 99573cbd..60caee95 100644 --- a/packages/core/src/agent/system-prompt/sections.ts +++ b/packages/core/src/agent/system-prompt/sections.ts @@ -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. */ diff --git a/packages/core/src/agent/system-prompt/types.ts b/packages/core/src/agent/system-prompt/types.ts index cf1cc1ba..0741a80e 100644 --- a/packages/core/src/agent/system-prompt/types.ts +++ b/packages/core/src/agent/system-prompt/types.ts @@ -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) */