Skip to content

Latest commit

 

History

History
265 lines (187 loc) · 9.39 KB

File metadata and controls

265 lines (187 loc) · 9.39 KB

Talk

Talk is a lightweight, batteries-included orchestration engine that lets multiple LLM-powered agents collaborate on a codebase autonomously.
It was inspired by systems like Aider but rebuilt around a compositional “blackboard” pattern for maximum transparency and hackability.

✨ Key Ideas

  • Blackboard pattern – every agent writes its output to a shared, structured datastore. Nothing is hidden in “agent-to-agent” chats.
  • Specialised agents – minimal, single-responsibility agents (CodeAgent, FileAgent, TestAgent) do one thing well.
  • Deterministic workflow – an explicit PlanRunner executes a graph of Steps so you can see exactly what happens and when.
  • Filesystem-first – Talk works on plain files, no remote sandboxes or proprietary formats.

🏗 Architecture

┌────────────┐        write          ┌──────────────┐       read
│ CodeAgent  │ ───────────────▶     │              │◀─────────────┐
│ (LLM diff) │                      │   Blackboard │              │
└────────────┘◀───────────────      │  (in-memory) │      write   │
         ▲          read            └──────────────┘              │
         │                                                     ┌──▼─────────┐
         │                      read / write                   │ TestAgent  │
         │                                                     │ (pytest)   │
   ┌─────▼───────┐       apply diff      ┌────────────┐        └────────────┘
   │ FileAgent   │──────────────────────▶│   Files    │
   │ (patch)     │                       └────────────┘
   └─────────────┘
  1. CodeAgent takes the task & current files → emits a unified diff.
  2. FileAgent applies the diff to disk (with automatic backups).
  3. TestAgent runs tests (pytest by default) and reports structured results.
  4. The PlanRunner decides which step comes next based on success / failure.

Everything each agent does is appended to the Blackboard (BlackboardEntry), giving you full provenance and an easy way to inspect or replay sessions.


🔑 Features

  • Autonomous code generation (LLM-driven diffs).
  • Safe patch application with automatic file backups.
  • Test execution with timeout & detailed parsing of results.
  • Versioned working directories (talk1/, talk2/, …) so nothing is overwritten.
  • Interactive or fully automatic mode.
  • 30-minute default timeout guard.
  • Works with any OpenAI-compatible LLM; configurable provider list out-of-the-box (OpenAI, Anthropic, Gemini, Perplexity, Fireworks, …).

🐍 Python Path and Imports

PYTHONPATH Configuration

IMPORTANT: The PYTHONPATH environment variable MUST be set to the Talk installation directory (usually ~/talk, but may differ based on installation location).

# Typical setup
export PYTHONPATH=~/talk

# Or wherever Talk is installed
export PYTHONPATH=/path/to/talk

Import Convention

ALL imports in the Talk codebase are relative to the PYTHONPATH root. This means:

# CORRECT - imports relative to ~/talk
from agent.agent import Agent
from special_agents.code_agent import CodeAgent
from tests.utilities.test_output_writer import TestOutputWriter

# WRONG - do not use relative imports or sys.path manipulation
import sys
sys.path.insert(0, '../../../')  # Never do this!
from ..agent import Agent  # Don't use relative imports

For Claude Code and AI Assistants

CRITICAL:

  • DO NOT set or modify PYTHONPATH in code
  • DO NOT use sys.path.insert() or other path manipulations
  • If PYTHONPATH is not set correctly, ask the user to:
    1. Set PYTHONPATH to the Talk installation directory
    2. Resume the conversation with --resume

Example check:

import os
if 'PYTHONPATH' not in os.environ or not os.environ['PYTHONPATH'].endswith('talk'):
    print("Please set PYTHONPATH to your Talk installation directory and --resume")
    sys.exit(1)

⚙️ Mocking

In general, do not create any new mocking or monkey patching code. Strive to build production ready code, and only fall back as a last resort and after requesting specific permission to do so.

⚙️ Configuration

Talk uses a thin Pydantic-powered settings layer (agent/settings.py).
Configuration values come from four sources — in order of precedence (highest → lowest):

  1. Runtime overrides – e.g. CodeAgent(overrides={...})
  2. Environment variables – prefixed with TALK_… (see below)
  3. Global force override – TALK_FORCE_MODEL short-circuits every other model field
  4. Built-in defaults – provider=google, model=gemini-1.5-flash

Default model

Built-in:

# agent/settings.py
class GoogleSettings(BaseSettings):
    model_name: str = "gemini-1.5-flash"

Environment variable overrides

# change only Google provider’s default
export TALK_GOOGLE_MODEL_NAME="gemini-1.5-pro"

# override *all* providers everywhere
export TALK_FORCE_MODEL="gemini-2.0-flash"

CLI override

# one-off per run
python talk/talk.py --task "Add logging" --model gemini-1.5-pro

Putting it together

Priority order for the model used by CodeAgent: --model CLI flag ▶ TALK_FORCE_MODEL ▶ TALK_GOOGLE_MODEL_NAME ▶ built-in default.

If you prefer OpenAI models:

export TALK_LLM_PROVIDER="openai"
export TALK_OPENAI_MODEL_NAME="gpt-4o-mini"

Everything else (paths, logging cadence, debug flags) follows the same pattern:
TALK_<SECTION>_<FIELD> environment variables override the defaults.

📦 Installation

see code/docs/INSTALL.md

🚀 Usage

Automatic mode (fire-and-forget)

python talk/talk.py --task "Add a Fibonacci function with tests"

Talk will:

  1. Create a directory talkN/
  2. Generate diffs
  3. Apply them
  4. Run tests until they pass or the timeout hits

Interactive mode

python talk/talk.py -t "Refactor utils.py for PEP-8" -i

You’ll be prompted before each step and can inspect / edit files in another editor before continuing.

Custom model & directory

python talk/talk.py \
  --task "Implement CLI argument parsing" \
  --model gpt-4o-mini \
  --dir ./my_project

🧩 Specialized Agents

Agent Responsibility Important Methods
CodeAgent Prompt an LLM to output unified diffs run(prompt_str)
FileAgent Apply diffs, backup originals, list/read files run(diff), list_files()
TestAgent Run pytest/unittest, parse results run("pytest"), discover_tests()

All inherit from the generic Agent facade and therefore support switch_provider, conversation logging, and provenance IDs.

The Agent contract is prompt in ==> completion out. That is it. Any other communication is done through the agent's tools. For example, a json could be sent by creating .talk/scratch/xyz.json, and then the model would have the filepath in its completion so the next agent can find the data. The scratch folder is dedicated to this type of "side effect" communication and should be used whenever an agent wants to create and send a file to another agent (subdirs to scratch and uuids used in the filenames should be used to prevent collisions). If a file already existed, or was created as part of a project or existing directory structure, the Agent should just reference that existing file and not make a copy of it in the scratch folder.


🔄 Execution Plan

generate_code  ─▶ apply_changes ─▶ run_tests ─▶ check_results
       ▲                            │
       └──────── (on failure) ◀─────┘

Implementation: four Step objects wired together; executed by runtime.plan_runner.PlanRunner.


🧪 Running Tests

The suite uses pytest + unittest.mock.

pytest -q

Coverage:

pytest --cov=talk --cov-report=term-missing

🛠 Troubleshooting

Symptom Fix
patch: command not found Install patch and make sure it’s on PATH
OPENAI_API_KEY missing Export the key in your shell or .env file
“Execution timed out” Increase --timeout or break your task into smaller units
Diff fails to apply Check conflicting local edits; run in -i mode and fix manually

Enable verbose logging by setting env var:

export TALK_LOG_LEVEL=DEBUG

🤝 Contributing

  1. Fork the repo & create a branch.
  2. Run pre-commit install to get black/ruff hooks.
  3. Add or adjust tests for every new feature or bug-fix.
  4. Ensure pytest && pytest -q passes.
  5. Submit a PR — include a concise description and reference any issues.

All contributions welcome: features, bug reports, docs, or just ideas!
Feel free to open a discussion if you’re unsure.


📄 License

MIT – see LICENSE file for details.