{"id":6307,"date":"2026-06-29T20:22:53","date_gmt":"2026-06-29T13:22:53","guid":{"rendered":"https:\/\/daiilynews.cu.ma\/?p=6307"},"modified":"2026-06-29T20:22:53","modified_gmt":"2026-06-29T13:22:53","slug":"dylanneve1-talon-%f0%9f%a6%85-multi-platform-agentic-ai-harness-runs-on-telegram-discord-teams-terminal-with-a-pluggable-backend-claude-kilo-opencode-codex-openai-agents-full-mcp","status":"publish","type":"post","link":"https:\/\/daiilynews.cu.ma\/?p=6307","title":{"rendered":"dylanneve1\/talon: \ud83e\udd85 Multi-platform agentic AI harness \u2014 runs on Telegram, Discord, Teams &#038; Terminal with a pluggable backend (Claude, Kilo, OpenCode, Codex, OpenAI Agents), full MCP tool access, and persistent background agents (Goals, Heartbeat, Dream). \u00b7 GitHub"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<p>Multi-platform agentic AI harness. Runs on Telegram, Discord, Microsoft Teams, and the Terminal, with a pluggable backend (Claude Agent SDK, Kilo, OpenCode, Codex, or OpenAI Agents) and full tool access through MCP.<\/p>\n<p>Multi-frontend<br \/>\nTelegram (Grammy + GramJS userbot), Discord (discord.js), Microsoft Teams (Bot Framework), Terminal with live tool visibility<\/p>\n<p>Pluggable backend<br \/>\nClaude Agent SDK, Kilo, OpenCode, Codex, OpenAI Agents \u2014 selectable per-process via backend config. Streaming, model fallback, context-overflow recovery.<\/p>\n<p>MCP tools<br \/>\nMessaging, media, history, search, web fetch, cron jobs, triggers, goals, stickers, file system, admin controls<\/p>\n<p>Plugins<br \/>\nHot-reloadable plugin system. Built-in: GitHub, MemPalace, Playwright, Brave Search<\/p>\n<p>Background agents<br \/>\nHeartbeat (hourly by default \u2014 advances goals, proactively messages when something matters) and Dream (memory consolidation + diary)<\/p>\n<p>Goals<br \/>\nPersistent multi-day objectives the agent commits to in chat; every heartbeat run re-reads them, makes progress, and records what it did<\/p>\n<p>Skills<br \/>\nAgent-authored reusable scripts (bash\/python\/node) \u2014 procedures worked out once get saved and replayed locally at zero token cost<\/p>\n<p>Triggers<br \/>\nSelf-authored watcher scripts (bash\/python\/node) that wake the bot when conditions are met<\/p>\n<p>Per-chat settings<br \/>\nModel, effort level, and pulse toggle per conversation via inline keyboard<\/p>\n<p>Model registry<br \/>\nModels discovered from the active backend at startup \u2014 new models appear in all pickers automatically<\/p>\n<p>git clone https:\/\/github.com\/dylanneve1\/talon.git &#038;&#038; cd talon<br \/>\nnpm install<\/p>\n<p># Interactive setup (select frontend, configure tokens, pick model)<br \/>\nnpx talon setup<\/p>\n<p># Start<br \/>\nnpx talon start       # configured frontend (daemon mode)<br \/>\nnpx talon chat        # terminal chat mode<br \/>\nPrerequisites:<\/p>\n<p>Node.js 24+<br \/>\nBackend-specific:<\/p>\n<p>claude backend: Claude Code installed and authenticated (claude CLI on PATH).<br \/>\nkilo backend: nothing extra \u2014 @kilocode\/sdk spawns a local server. Free models are accessible without auth; routed models use Kilo&#8217;s own credentials.<br \/>\nopencode backend: nothing extra \u2014 @opencode-ai\/sdk spawns a local server.<br \/>\ncodex backend: install the codex CLI (npm i -g @openai\/codex) and authenticate with codex login, CODEX_API_KEY, TALON_CODEX_KEY, or codexApiKey. OPENAI_API_KEY is used only as a fallback when no Codex login exists.<\/p>\n<p>Talon runs from a normal source or package install; standalone compiled binaries are not supported.<\/p>\n<p>index.ts                    Composition root<br \/>\n  |<br \/>\n  +&#8211; core\/                 Platform-agnostic engine<br \/>\n  |   +&#8211; agent-runtime\/    Backend capability interfaces, events, stores<br \/>\n  |   +&#8211; models\/           Model layer: catalog, per-chat active model,<br \/>\n  |   |                     reasoning-effort vocabulary<br \/>\n  |   +&#8211; prompt\/           System-prompt assembly + prompts\/system templates<br \/>\n  |   +&#8211; background\/       Agents that run without a user message:<br \/>\n  |   |                     heartbeat, dream, pulse, cron, triggers<br \/>\n  |   +&#8211; tools\/            MCP tool definitions + spawn\/env contract<br \/>\n  |   +&#8211; engine\/           Message flow: dispatcher (per-chat serial,<br \/>\n  |   |                     cross-chat parallel), HTTP gateway for MCP<br \/>\n  |   |                     tool calls, backend lifecycle controller<br \/>\n  |   +&#8211; plugin.ts         Plugin loader, registry, hot-reload<br \/>\n  |<br \/>\n  +&#8211; backend\/<br \/>\n  |   +&#8211; registry.ts       Bootstrap-decoupled backend lookup<br \/>\n  |   +&#8211; shared\/           Cross-backend helpers (stream state, flow violation,<br \/>\n  |   |                     delivery contract, metrics, prompt format,<br \/>\n  |   |                     model retry, system prompt, usage)<br \/>\n  |   +&#8211; remote-server\/    Shared infrastructure for agent-server backends<br \/>\n  |   |                     (MCP registration, sessions, providers, lifecycle)<br \/>\n  |   +&#8211; claude-sdk\/       Claude Agent SDK (in-process MCP, hooks)<br \/>\n  |   +&#8211; kilo\/             Kilo HTTP server backend (streaming via SSE)<br \/>\n  |   +&#8211; opencode\/         OpenCode HTTP server backend<br \/>\n  |   +&#8211; codex\/            Codex CLI backend (`@openai\/codex-sdk`)<br \/>\n  |   +&#8211; openai-agents\/    OpenAI Agents SDK backend (Responses API)<br \/>\n  |<br \/>\n  +&#8211; frontend\/<br \/>\n  |   +&#8211; shared\/           Cross-frontend presentation helpers<br \/>\n  |   +&#8211; telegram\/         Grammy bot + GramJS userbot<br \/>\n  |   +&#8211; discord\/          discord.js v14<br \/>\n  |   +&#8211; teams\/            Bot Framework + Graph API<br \/>\n  |   +&#8211; terminal\/         Readline CLI with tool call visibility<br \/>\n  |<br \/>\n  +&#8211; storage\/              Sessions, history, chat settings,<br \/>\n  |                         cron jobs, media index, daily logs<br \/>\n  +&#8211; util\/                 Config, logging, workspace, paths, time<\/p>\n<p>Dependency rule: core\/ imports nothing from frontend\/ or backend\/. Frontends and backends depend on core types, never on each other. All five backends (Claude SDK, Kilo, OpenCode, Codex, OpenAI Agents) implement the same Backend capability interface from core\/agent-runtime\/capabilities.ts. Kilo and OpenCode additionally share the remote-server\/ infrastructure because they wrap forks of the same upstream HTTP agent server.<br \/>\nPrompts: everything the model reads at session start is assembled by core\/prompt\/ from the files in prompts\/ \u2014 see prompts\/README.md for the assembly order, file ownership (user-editable vs package-owned templates), and the per-backend delivery contracts.<\/p>\n<p>Select via the backend field in ~\/.talon\/config.json. All backends implement the same Backend capability interface \u2014 heartbeat, dream, and chat handlers are backend-agnostic.<\/p>\n<p>Backend<br \/>\nbackend value<br \/>\nTransport<br \/>\nNotes<\/p>\n<p>Claude SDK<br \/>\n&#8220;claude&#8221;<br \/>\nIn-process via @anthropic-ai\/claude-agent-sdk<br \/>\nRequires the claude CLI on PATH. Hook-based turn termination.<\/p>\n<p>Kilo<br \/>\n&#8220;kilo&#8221;<br \/>\nLocal HTTP server via @kilocode\/sdk<br \/>\nSSE-streamed turns. Routes to many model providers via Kilo&#8217;s auth.<\/p>\n<p>OpenCode<br \/>\n&#8220;opencode&#8221;<br \/>\nLocal HTTP server via @opencode-ai\/sdk<br \/>\nSSE-streamed turns; same MCP and session shape as Kilo (upstream fork).<\/p>\n<p>Codex<br \/>\n&#8220;codex&#8221;<br \/>\nPer-turn subprocess via @openai\/codex-sdk<br \/>\nRequires the codex CLI from @openai\/codex and Codex auth (codex login, CODEX_API_KEY, TALON_CODEX_KEY, or codexApiKey). MCP servers configured via TOML overrides at thread start.<\/p>\n<p>OpenAI Agents<br \/>\n&#8220;openai-agents&#8221;<br \/>\nIn-process via @openai\/agents<br \/>\nResponses API (or any OpenAI-compatible endpoint via TALON_AGENTS_URL \/ openaiBaseUrl). Persistent per-chat MCP bundles.<\/p>\n<p>The Kilo and OpenCode backends share infrastructure (backend\/remote-server\/) since the upstream HTTP API is the same; each backend supplies its own SDK client, port, and delivery suffix. Codex is its own integration on top of the Codex CLI&#8217;s JSONL event stream.<\/p>\n<p>GitHub API access via the official GitHub MCP server. Gives the agent access to repositories, issues, PRs, code search, and more.<br \/>\nRequirements: Docker installed and running.<br \/>\n{<br \/>\n  &#8220;github&#8221;: {<br \/>\n    &#8220;enabled&#8221;: true,<br \/>\n    &#8220;token&#8221;: &#8220;ghp_&#8230;&#8221;<br \/>\n  }<br \/>\n}<br \/>\nThe token is optional &#8212; defaults to the output of gh auth token if the GitHub CLI is authenticated.<\/p>\n<p>Structured long-term memory with vector search. The agent can store, search, and retrieve memories semantically. Integrates with Dream mode for automatic memory consolidation and personal diary entries.<br \/>\nRequirements: Python 3.10+ with the mempalace package.<br \/>\n# Set up a Python environment<br \/>\npython -m venv ~\/.talon\/mempalace-venv<br \/>\n~\/.talon\/mempalace-venv\/bin\/pip install mempalace    # Unix<br \/>\n# or: ~\/.talon\/mempalace-venv\/Scripts\/pip install mempalace   # Windows<br \/>\n{<br \/>\n  &#8220;mempalace&#8221;: {<br \/>\n    &#8220;enabled&#8221;: true,<br \/>\n    &#8220;palacePath&#8221;: &#8220;~\/.talon\/workspace\/palace&#8221;,<br \/>\n    &#8220;pythonPath&#8221;: &#8220;~\/.talon\/mempalace-venv\/bin\/python&#8221;<br \/>\n  }<br \/>\n}<br \/>\nBoth paths are optional &#8212; defaults to ~\/.talon\/workspace\/palace\/ and the venv Python respectively.<\/p>\n<p>Headless browser automation via the Playwright MCP server. The agent can browse websites, take screenshots, generate PDFs, fill forms, and scrape content.<br \/>\nRequirements: None &#8212; @playwright\/mcp is bundled with Talon.<br \/>\n{<br \/>\n  &#8220;playwright&#8221;: {<br \/>\n    &#8220;enabled&#8221;: true,<br \/>\n    &#8220;browser&#8221;: &#8220;chromium&#8221;,<br \/>\n    &#8220;headless&#8221;: true<br \/>\n  }<br \/>\n}<br \/>\nSupported browsers: chromium (default), chrome, firefox, webkit, msedge.<\/p>\n<p>Web search via the Brave Search MCP server. Replaces the built-in WebSearch\/WebFetch tools with higher-quality search results.<br \/>\n{<br \/>\n  &#8220;braveApiKey&#8221;: &#8220;BSA&#8230;&#8221;<br \/>\n}<br \/>\nGet an API key at brave.com\/search\/api.<\/p>\n<p>Plugins add MCP tools and gateway actions without modifying core code. SOLID interface &#8212; only name is required.<br \/>\n{<br \/>\n  &#8220;plugins&#8221;: ({ &#8220;path&#8221;: &#8220;\/path\/to\/my-plugin&#8221;, &#8220;config&#8221;: { &#8220;apiKey&#8221;: &#8220;&#8230;&#8221; } })<br \/>\n}<br \/>\nexport default {<br \/>\n  name: &#8220;my-plugin&#8221;,<br \/>\n  version: &#8220;1.0.0&#8221;,<br \/>\n  mcpServerPath: resolve(import.meta.dirname, &#8220;tools.ts&#8221;),<br \/>\n  validateConfig(config) {<br \/>\n    \/* return errors or undefined *\/<br \/>\n  },<br \/>\n  getEnvVars(config) {<br \/>\n    return { MY_KEY: config.apiKey };<br \/>\n  },<br \/>\n  handleAction(body, chatId) {<br \/>\n    \/* gateway action handler *\/<br \/>\n  },<br \/>\n  getSystemPromptAddition(config) {<br \/>\n    return &#8220;## My Plugin\\n&#8230;&#8221;;<br \/>\n  },<br \/>\n  init(config) {<br \/>\n    \/* one-time setup *\/<br \/>\n  },<br \/>\n  destroy() {<br \/>\n    \/* cleanup *\/<br \/>\n  },<br \/>\n};<br \/>\nPlugins support hot-reload via the reload_plugins MCP tool &#8212; no restart required.<\/p>\n<p>talon setup     Interactive setup wizard<br \/>\ntalon start     Start as a background daemon<br \/>\ntalon stop      Stop the daemon<br \/>\ntalon chat      Terminal chat mode (always available)<br \/>\ntalon status    Health, sessions, plugins, disk usage<br \/>\ntalon config    View or edit configuration<br \/>\ntalon logs      Tail structured log file<br \/>\ntalon doctor    Validate environment and dependencies<\/p>\n<p>Config file: ~\/.talon\/config.json<\/p>\n<p>Field<br \/>\nDefault<br \/>\nDescription<\/p>\n<p>frontend<br \/>\n&#8220;telegram&#8221;<br \/>\n&#8220;telegram&#8221;, &#8220;discord&#8221;, &#8220;teams&#8221;, &#8220;terminal&#8221;, or an array<\/p>\n<p>backend<br \/>\n&#8220;claude&#8221;<br \/>\n&#8220;claude&#8221;, &#8220;kilo&#8221;, &#8220;opencode&#8221;, &#8220;codex&#8221;, or &#8220;openai-agents&#8221;<\/p>\n<p>botToken<br \/>\n&#8212;<br \/>\nTelegram bot token<\/p>\n<p>model<br \/>\n&#8220;default&#8221;<br \/>\nDefault model. Interpretation depends on the active backend.<\/p>\n<p>codexApiKey<br \/>\n&#8212;<br \/>\nCodex-only OpenAI API key. Prefer this over openaiApiKey for Codex API-key auth. codex login takes precedence over shared openaiApiKey.<\/p>\n<p>concurrency<br \/>\n1<br \/>\nMax concurrent AI queries (1&#8211;20)<\/p>\n<p>pulse<br \/>\ntrue<br \/>\nPeriodic group engagement<\/p>\n<p>heartbeat<br \/>\nfalse<br \/>\nBackground maintenance agent<\/p>\n<p>heartbeatIntervalMinutes<br \/>\n60<br \/>\nHeartbeat interval<\/p>\n<p>braveApiKey<br \/>\n&#8212;<br \/>\nBrave Search API key<\/p>\n<p>timezone<br \/>\n&#8212;<br \/>\nIANA timezone (e.g. &#8220;Europe\/London&#8221;)<\/p>\n<p>plugins<br \/>\n()<br \/>\nExternal plugin packages<\/p>\n<p>disabledToolTags<br \/>\n&#8212;<br \/>\nHide whole tool groups from the model (e.g. (&#8220;stickers&#8221;, &#8220;web&#8221;)) \u2014 each registered tool costs context tokens per session<\/p>\n<p>disabledTools<br \/>\n&#8212;<br \/>\nHide individual tools by name (end_turn cannot be disabled)<\/p>\n<p>adminUserId<br \/>\n&#8212;<br \/>\nTelegram user ID for \/admin commands<\/p>\n<p>allowedUsers<br \/>\n&#8212;<br \/>\nWhitelist of Telegram user IDs<\/p>\n<p>apiId \/ apiHash<br \/>\n&#8212;<br \/>\nTelegram API credentials for full message history<\/p>\n<p>github<br \/>\n&#8212;<br \/>\nGitHub plugin config (see above)<\/p>\n<p>mempalace<br \/>\n&#8212;<br \/>\nMemPalace plugin config (see above)<\/p>\n<p>playwright<br \/>\n&#8212;<br \/>\nPlaywright plugin config (see above)<\/p>\n<p>Tool calls shown in real-time with parameters. Streaming phase indicators (thinking \/ responding \/ using tools). Per-turn stats: duration, tokens, cache hit rate, tool count.<br \/>\nCommands: \/model, \/effort, \/reset, \/status, \/help<\/p>\n<p>Docker:<\/p>\n<p>Systemd: unit file at packaging\/systemd\/talon.service \u2014 copy to \/etc\/systemd\/system\/, set User= and WorkingDirectory=, then systemctl enable &#8211;now talon.<br \/>\nHealth endpoint: GET http:\/\/localhost:19876\/health returns JSON with uptime, memory, queue depth, active sessions, and last activity timestamp.<br \/>\nLogging: Structured JSON via pino to ~\/.talon\/talon.log. Rotated on startup when the file exceeds 10MB.<br \/>\nResilience: Dynamic model fallback on overload, session auto-retry on expiry, rate limit handling with backoff, atomic file writes, graceful shutdown with 15-second drain timeout.<\/p>\n<p>npm run dev              # watch mode<br \/>\nnpm test                 # 2300+ tests across unit \/ SDK-stub \/ MCP-functional \/ integration tiers<br \/>\nnpm run test:coverage    # with coverage report<br \/>\nnpm run typecheck        # tsc &#8211;noEmit<br \/>\nnpm run lint             # oxlint<br \/>\nnpm run format           # prettier &#8211;write<\/p>\n<p>MIT<br \/>\n<br \/><br \/>\n<br \/><a href=\"https:\/\/github.com\/dylanneve1\/talon\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Multi-platform agentic AI harness. Runs on Telegram, Discord, Microsoft Teams, and the Terminal, with a pluggable backend (Claude Agent SDK, Kilo, OpenCode, Codex, or OpenAI Agents) and full tool access through MCP. Multi-frontend Telegram (Grammy + GramJS userbot), Discord (discord.js), Microsoft Teams (Bot Framework), Terminal with live tool visibility Pluggable backend Claude Agent SDK, Kilo, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":6308,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[676],"tags":[],"class_list":["post-6307","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tech-ai"],"_links":{"self":[{"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=\/wp\/v2\/posts\/6307","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6307"}],"version-history":[{"count":0,"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=\/wp\/v2\/posts\/6307\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=\/wp\/v2\/media\/6308"}],"wp:attachment":[{"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6307"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6307"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6307"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}