Connectors and reply targets
Kheish separates transport configuration from output routing. That split is intentional:- a connector is a daemon-managed transport resource such as one Telegram bot, one Slack bot, one HTTP webhook definition, or one external sidecar bridge
- a reply target is one normalized output destination attached to a session, run, or connector
Connectors
Connectors live at the daemon level, not inside one session. They own transport-specific configuration such as:- ingress behavior such as Telegram polling versus webhook mode
- connector-local auth such as Slack signing secrets or HTTP bearer tokens
- transport defaults such as self-output and additional reply targets
- stable connector identifiers used by ingress routes and structured reply-target requests
telegramslackhttpexternal
Reply targets
Reply targets are the normalized delivery destinations used by the output pipeline. They are stored asReplyHandle records:
pluginaddress
- one Telegram reply route names a connector and chat or topic coordinates
- one Slack reply route names a connector and channel or thread coordinates
- one HTTP reply route names a URL and optional headers
- one external reply route names a connector plus one opaque sidecar-defined route payload
Where routing lives
Kheish keeps routing at three levels:- connector defaults
- session reply-target defaults
- run snapshots
thread.pathrouting_key- or one connector-level
fixed_session_id
fixed_session_id across those connectors. Read Multiple input connectors in one session for the exact pattern and tradeoffs.
Session reply-target defaults are durable, session-scoped routing preferences stored in session metadata. They are edited through the session control plane and reused for future work in that session.
Run reply targets are immutable snapshots captured when concrete work is created. They are used by:
- normal input runs
- scheduled input materialized into runs
- parent clarification flows
Prospective, not retroactive
Changing a session’s reply-target defaults does not rewrite work that already exists. That means a session-level reply-target update affects:- future session inputs
- future background shell tasks created after the change
- future schedule fires when the schedule request does not already carry explicit reply routing
- future daemon-owned output that falls back to the session defaults
- an active run
- a queued run
- a suspended run waiting for approval or user input
- an already materialized run created from a schedule fire
- an already created background shell task
- an already queued delivery item
Structured session reply targets
The session control plane accepts structured reply-target requests for the built-in connectors:- Telegram: connector plus chat and optional thread or reply ids
- Slack: connector plus channel and optional thread timestamp
- HTTP: URL plus optional headers
plugin plus address pairs when they need one plugin-specific route that the structured forms do not cover.
Connectors and the secret store
Daemon-managed connectors do not expose raw secret values on read APIs. Instead:- connector reads return redacted secret metadata such as
configured,source,secret_ref, andenv - connector writes can point at an existing
secret_ref - connector writes can also include a write-only secret
value, which the daemon stores into the secret store before binding the connector to that slot
Deletion safety
Connectors are not deleted blindly. The daemon rejects connector deletion when the connector is still referenced by:- another connector’s configured reply targets
- a stored schedule payload
Recovery model
The runtime connector inventory and session reply-target defaults both survive restart.- daemon-managed connectors are stored under the state root in the runtime connector store
- session reply-target defaults live in session metadata and are also cached in the compact daemon index
Recommended mental model
Use this split consistently:- connector = transport definition owned by the daemon
- reply target = concrete routing destination used by one session or run
