Channel Descriptor

Let a channel plugin declare its config, prompt hint, and setup wizard in one place.

A channel plugin declares — in one place — everything the gateway needs to treat it as first-class: its own config keys, a system-prompt hint, an optional setup wizard, and an optional standalone sender.

Diagram

📇 ChannelDescriptor

⚙️ Config Schema

🧙 Onboarding Wizard

🤖 Agent Prompt

📤 Standalone Sender

Quick Start

  1. Declare a descriptor

    List your channel’s config fields and a prompt hint on a small descriptor class:

    python
    from praisonaiagents.bots import ChannelField
    
    class IRCDescriptor:
        config_fields = [
            ChannelField("server", required=True, prompt="IRC server host"),
            ChannelField("nickserv_password", secret=True, env="IRC_NICKSERV_PASSWORD"),
        ]
        system_prompt_hint = (
            "You are replying on IRC: plain text only, one short line."
        )
  2. Register the platform

    Pass the descriptor when you register the adapter — the gateway wires config, onboarding, and prompt for you:

    python
    from praisonai.bots._registry import register_platform
    
    register_platform("irc", IRCBot, descriptor=IRCDescriptor())

How It Works

One declaration feeds five consumers when the channel is active.

Diagram
AgentGateway (_create_bot)CLI (bot run)Agent PromptOnboarding WizardConfig SchemaRegistryPluginAgentGateway (_create_bot)CLI (bot run)Agent PromptOnboarding WizardConfig SchemaRegistryPluginregister_platform(“irc”, IRCBot, descriptor=…)read config_fields → keep plugin keyslist_platforms() → prompt for each fieldget_platform_descriptor(“irc”) → –field-name flagsget_channel_system_prompt_hint(“irc”)“You are replying on IRC: plain text only, one short line.”append hint to backstory + rebuild system_prompt
ConsumerReadsEffect
Config schemaconfig_fieldsPlugin keys validate instead of being dropped
Onboarding wizardconfig_fields (+ optional setup)Prompts for each field, using env as fallback
Agent promptsystem_prompt_hintAppended to the agent’s backstory and the rebuilt system_prompt at per-channel bot construction
CLI (bot run)config_fieldsEach field becomes a --field-name flag (underscore → hyphen). Unknown flags exit 2.
Scheduler (gateway-less)standalone_sender (optional)Scheduled deliver: targets reach the channel when no gateway is resident (OS cron, CI, scale-to-zero)

CLI flags are generated from config_fields

A channel’s declared config_fields are accepted on praisonai bot run as --field-name flags, so the same declaration drives YAML, the wizard, the agent prompt hint, and the CLI.

bash
# IRC plugin declaring `server` and `nickserv_password`
praisonai bot run --platform irc --server irc.libera.chat --nickserv-password $NICK_PW

See praisonai bot run for syntax and the exit-code-2 error on unknown flags.

How the hint reaches the model

The gateway resolves the descriptor’s hint and appends it to the cloned agent’s backstory, then rebuilds system_prompt — the runtime prompt builder reads those, not the construction-only instructions.

Diagram
Agent_registryGatewayAgent_registryGatewayget_channel_system_prompt_hint(“irc”)“plain text only, one short line.”append to backstory, rebuild system_prompthint now on every turn
python
from praisonaiagents.bots import ChannelField
from praisonai.bots._registry import register_platform

class IRCDescriptor:
    config_fields = [
        ChannelField("server", required=True, prompt="IRC server host"),
    ]
    # This hint now actually reaches the model on every turn.
    system_prompt_hint = "You are replying on IRC: plain text only, one short line."

register_platform("irc", IRCBot, descriptor=IRCDescriptor())

ChannelField Options

Each ChannelField describes one config key the channel needs.

FieldTypeDefaultDescription
namestr—Config key name (as it appears under channels.<platform>); also the bot run CLI flag (bridge_url → --bridge-url)
requiredboolFalseWhether the field must be provided
secretboolFalseWhether the value is sensitive (masked in prompts/logs)
promptstr""Human-friendly prompt shown by the onboarding wizard
envOptional[str]NoneEnvironment-variable name used as a fallback source

Interactive Setup

Add an optional setup(io) hook for multi-step flows that a flat field list can’t express — the wizard calls it when present and merges the returned values.

python
from praisonaiagents.bots import ChannelField
from praisonai.bots._registry import register_platform

class IRCDescriptor:
    config_fields = [
        ChannelField("server", required=True, prompt="IRC server host"),
    ]
    system_prompt_hint = "You are replying on IRC: plain text only, one short line."

    def setup(self, io) -> dict:
        channels = io.prompt("Which channels to join? (comma-separated)")
        return {"channels": [c.strip() for c in channels.split(",") if c.strip()]}

register_platform("irc", IRCBot, descriptor=IRCDescriptor())

Gateway-less scheduled delivery

Declare an optional standalone_sender and your channel also receives scheduled briefs when no gateway is resident, just like the five bundled channels.

python
class IRCDescriptor:
    config_fields = [
        ChannelField("server", required=True, prompt="IRC server host"),
    ]
    system_prompt_hint = "You are replying on IRC: plain text only, one short line."

    async def standalone_sender(self, target, text):
        await post_to_irc(target.channel_id, text)  # raises on failure

class IRCBot:
    channel_descriptor = IRCDescriptor()  # found by `praisonai schedule tick`
    ...

Best Practices

Mark secrets with secret=True

Set secret=True on tokens and passwords so the wizard masks them and logs never print the value.

Provide an env fallback for secrets

Add env="IRC_NICKSERV_PASSWORD" so operators can supply credentials via environment variables instead of prompts.

Keep the prompt hint short and concrete

State the platform and its constraints in one line — for example plain text only, one short line — so the agent adapts its replies.

Use setup only when fields aren't enough

Reach for setup(io) for bespoke, multi-step flows. Declarative config_fields cover the common case with no code.

Pair standalone_sender with env-backed secrets

The sender runs out of process (OS cron, CI, serverless) and the onboarding wizard never runs there. Give every secret it needs an env= fallback on its ChannelField. See Standalone Sender for Custom Channels.

Pick CLI-friendly field names

Avoid names that clash with fixed bot run flags (token, port, agent, model, platform). A field named like a handler parameter (e.g. an IRC adapter’s channel) is routed through channel.model_extra so it still reaches the adapter, but unambiguous names are clearer for users.

Idempotency & prompt-cache safety

The gateway appends the hint as a single trailing line, so injection is deterministic and the prompt prefix stays cache-stable across turns. A hint already present on the agent’s backstory is a no-op on hot-reload, so re-clones never duplicate it.


Related