takopi

repository·master·Indexed 21 days ago

https://github.com/banteg/takopi

A Telegram bridge for AI coding agents such as Codex, Claude Code, Opencode, and Pi. It enables developers to manage multiple projects and git worktrees via chat, stream progress, and resume sessions between Telegram and the terminal. The system features a lazy-loading plugin architecture for extending engines, transports, and commands, and utilizes a Resume Token mechanism to maintain conversation state.

Tokens
60.8K
Snippets
190
Records
289
Agent score
75%

What's inside takopi

  1. Use Takopi reference documentation

    master

    Takopi provides three distinct types of documentation to help you interact with the system:

    • Reference Docs: Use these for authoritative facts, schemas, and contracts (e.g., API signatures, configuration keys, and protocol specifications).
    • How-to Guides: Use these when you have a specific goal, such as "enabling topics" or "fetching a file."
    • Explanations: Use these when you need to understand the underlying concepts and the why behind the system's design.
  2. Understand thread serialization and concurrency

    master

    Takopi supports parallel execution across different threads, but prevents overlapping runs within a single thread through two layers of serialization:

    • Telegram Layer: Jobs are queued using a First-In-First-Out (FIFO) approach per thread.
    • Runner Layer: Runners enforce locks based on the resume-token. This ensures that the same session cannot be resumed concurrently by multiple processes.
  3. How the Takopi 3-event schema lifecycle works

    master

    The Takopi event model for Codex runners follows a strict lifecycle to ensure predictable serialization and data integrity.

    The Lifecycle

    1. started: This is the entry point. It must be emitted as soon as the resume token (the thread_id) is acquired. This allows consumers to track the session immediately.
    2. action: These are intermediate events. They represent the granular steps (turns and items) occurring within a session. They are streamed in order.
    3. completed: This is the terminal event. Even though the final answer might be known earlier (via an agent_message item), the completed event should only be emitted at the turn boundary (turn.completed or turn.failed).

    Why emit completed at the turn boundary?

    • Usage Data: You can only reliably attach usage statistics (turn.completed.usage) at the turn boundary.
    • Guaranteed Termination: It ensures completed is truly the last event in the stream.
    • Authoritative Payload: While agent_message provides the content, the completed event acts as the official container for the answer and the final status (ok: true/false).
  4. How context persistence works with worktrees

    master
    When a project or worktree context is active, Takopi appends a ctx: footer to its messages. When you reply to a message containing this footer, the context (including the project alias and branch) carries forward automatically. You typically do not need to repeat the /<project-alias> @branch prefix in subsequent replies within the same context.
  5. Understand the Takopi runner mental model

    master

    To implement a runner correctly, you must adhere to three core principles:

    1. Takopi owns the domain model

    Runners must not invent new event types. They are responsible for translating engine-specific output into the core types defined in takopi.model:

    • ResumeToken(engine, value)
    • StartedEvent(engine, resume, title?, meta?)
    • ActionEvent(engine, action, phase, ok?, message?, level?)
    • CompletedEvent(engine, ok, answer, resume?, error?, usage?)

    2. The runner contract (invariants)

    Every run must follow these lifecycle invariants:

    • Exactly one StartedEvent must be emitted.
    • Exactly one CompletedEvent must be emitted.
    • The CompletedEvent must be the last event in the sequence.
    • CompletedEvent.resume must match the StartedEvent.resume (using the same token).

    Note: A minimal runner only needs to emit StartedEventCompletedEvent. Adding ActionEvents is recommended for better progress UX.

    3. Resume lines are runner-owned

    The runner is the sole authority for managing how sessions are resumed in chat. You must implement logic for:

    • format_resume(): How the resume command looks in text.
    • extract_resume(): How to parse a token out of text.
    • is_resume_line(): How to reliably detect if a line is a resume command.
  6. Understand the context footer (`ctx:`) and context precedence

    master

    When a Takopi run has project context, it appends a footer to the message rendered as inline code. This footer is used to maintain context across replies.

    • With branch: `ctx: <project> @<branch>`
    • Without branch: `ctx: <project>`

    Precedence Rule: When replying to a message, Takopi parses this ctx: line and gives it precedence over any new directives provided in the reply message. This ensures continuity of the project/branch context.

  7. How Takopi resolves worktree paths

    master

    When the @branch directive is used, Takopi calculates the worktree location as follows:

    1. worktrees_root = <project.path> / <worktrees_dir>
    2. worktree_path = worktrees_root / <branch>

    Branch Creation Logic

    If the worktree_path does not exist, Takopi attempts to create it using git worktree add based on this priority:

    1. Local branch exists: git worktree add <path> <branch>
    2. Remote branch exists: git worktree add -b <branch> <path> origin/<branch>
    3. Fallback: git worktree add -b <branch> <path> <base> (where <base> is determined by the worktree_base config or git defaults).

    Branch Validation

    Branches must not start with / and must not contain .. path segments. They may include / for nested directory structures. The final resolved path must remain within the worktrees_root.

  8. Understand Takopi's core architecture and modules

    master

    Takopi is organized into several functional layers that handle everything from user interaction to engine execution. Understanding these layers helps in knowing where to look for specific functionality:

    • Entry Points: The system starts via cli.py (the Typer CLI) or telegram/backend.py (the Telegram-specific backend).
    • Orchestration & Routing: Manages the lifecycle of a task. runner_bridge.py handles per-message logic and progress, while router.py resolves resume tokens to find active runners. scheduler.py manages a FIFO job queue.
    • Domain Model: Defines the core data structures like resume tokens, events, actions, and run results in model.py.
    • Rendering & Progress: Handles how information is presented. progress.py tracks state, presenter.py converts state into transport-specific messages, and transport.py provides the abstraction for sending/editing/deleting messages.
    • Plugins: Uses entrypoints for discovery and lazy loading of engines, transports, and commands via plugins.py and api.py.
  9. Extend Takopi via the Plugin API

    master

    Takopi uses a plugin system based on entrypoints to discover and load new capabilities. The public boundary for interacting with these plugins is located in takopi.api.

    Key plugin-related modules include:

    • plugins.py: Handles discovery, lazy loading, and error capturing.
    • engines.py: Discovers engine backends.
    • transports.py: Discovers transport backends.
    • commands.py: Discovers command backends and provides execution helpers.
    • ids.py: Provides shared ID regex and collision checks to ensure plugin IDs and Telegram command names are valid.
  10. How Takopi resolves run context

    master

    Takopi uses run context to determine which project, git worktree/branch, and engine to use for a task. This is resolved via message directives or configuration.

    Context Components

    • Project: An alias for a repository (e.g., /z80). Projects allow you to run tasks in specific repository roots.
    • Worktree/Branch: Using the @branch directive allows Takopi to create or use a git worktree for a specific branch, isolating the run from the main checkout.
    • Engine: The execution engine (e.g., /codex).

    Resolution Logic

    1. Directives: Takopi parses the first line of a message for prefixes like /<engine-id>, /<project-alias>, or @<branch>.
    2. Context Footer (ctx:): If a message is a reply to a previous Takopi message containing a ctx: footer, Takopi ignores new directives and uses the context provided in that footer. This allows for seamless continuation of tasks in the same environment.
    3. Chat Mapping: If a message arrives in a chat where the chat_id matches projects.<alias>.chat_id, Takopi automatically defaults to that project context.
    4. Ambient Context: In non-topic chats, the /ctx command can bind a chat context that persists until cleared.
    /z80 @feat/streaming fix flaky test
  11. Understand the Takopi domain model and event types

    master

    Takopi's execution is driven by a structured domain model of events and actions. Understanding these types is essential for building plugins or interpreting logs.

    Core Entities

    • ResumeToken: Contains an engine (EngineId) and a value (str). It is used to resume a conversation session.
    • Action: Represents a discrete task performed by an agent. It includes an id, kind (see below), title, and detail (dict).

    ActionKinds

    An Action can have the following ActionKind values:

    • command
    • tool
    • file_change
    • web_search
    • subagent
    • note
    • turn
    • warning
    • telemetry

    Event Types

    • StartedEvent: Emitted when an engine starts. Includes the engine ID, a resume token, and an optional title.
    • ActionEvent: Emitted during an action's lifecycle. Includes the engine ID, the action object, the phase (started | updated | completed), and optional ok (bool) or message (str) fields.
    • CompletedEvent: Emitted when an engine finishes. Includes the engine ID, ok (bool), the final answer (str), an optional resume token, and optional usage (dict) data.