Skip to content

Latest commit

 

History

History
276 lines (207 loc) · 9.05 KB

File metadata and controls

276 lines (207 loc) · 9.05 KB

Coglet

Fractal asynchronous control for distributed agent systems.

What is Coglet?

Coglet is a framework built on two primitives:

  • COG (Create, Observe, Guide) — slow, reflective supervisor
  • LET (Listen, Enact, Transmit) — fast, reactive executor

Every Coglet is both: a LET under its parent COG, and a COG over its children. This forms a recursive temporal hierarchy where layers share a uniform interface and differ only in cadence and scope.

Project Structure

src/coglet/          # Framework
  coglet.py          # Base class + @listen/@enact/transmit decorators
  channel.py         # Async pub/sub channel bus
  handle.py          # CogletHandle, CogBase, Command
  runtime.py         # CogletRuntime — boots and manages Coglet trees
  lifelet.py         # LifeLet mixin — on_start/on_stop lifecycle
  ticklet.py         # TickLet mixin — @every periodic scheduling
  proglet.py         # ProgLet mixin — unified program table with executors
  llm_executor.py    # LLMExecutor — multi-turn LLM conversations
  gitlet.py          # GitLet mixin — repo-as-policy with git patches
  loglet.py          # LogLet mixin — separate log stream
  mullet.py          # MulLet mixin — fan-out N children behind one handle
  suppresslet.py     # SuppressLet mixin — COG-controlled output gating
  weblet.py          # WebLet mixin — register with CogWeb UI for visualization

src/cogweb/          # CogWeb graph visualization UI
  ui/
    server.py        # FastAPI + WebSocket server
    static/
      index.html     # Interactive SVG graph frontend

cogames/             # CvC (Cogs vs Clips) game player
  cvc/
    cvc_policy.py    # PolicyCoglet: LLM brain + Python heuristic
    policy/
      anthropic_pilot.py  # CogletAgentPolicy — optimized per-agent heuristic
      semantic_cog.py     # Base semantic policy from cogora (~1300 lines)
      helpers/            # Geometry, resources, targeting, types
  coach.py           # Coach: orchestrates games, maintains changelog
  player.py          # PlayerCoglet: GitLet COG over PolicyCoglets
  gamelet.py         # GameLet: bridge to cogames CLI
  setup_policy.py    # Tournament sandbox setup (installs anthropic SDK)

docs/                # Architecture design docs
  coglet.md          # COG/LET primitives, communication model, mixins
  tournament.md      # Tournament system hierarchy and pseudocode

Quick Start

CLI — Runtime Daemon

# Start the runtime
coglet runtime start

# Create coglets from .cog directories
coglet create examples/counter.cog     # -> counter-a3f1
coglet create examples/doubler.cog     # -> doubler-b2c4
coglet create examples/printer.cog     # -> printer-d5e6

# List a coglet's channels
coglet link counter-a3f1               # shows transmit + listen channels

# Wire channels together (id:channel syntax)
coglet link counter-a3f1:count doubler-b2c4:count
coglet link doubler-b2c4:doubled printer-d5e6:doubled

# Push data directly into a channel
coglet transmit doubler-b2c4:count 42

# Subscribe to channel output
coglet observe printer-d5e6:log --follow

# Send @enact command
coglet enact printer-d5e6 reset

# Inspect
coglet links                           # list all wires
coglet runtime status                  # tree + coglets + channels + links

# Tear down
coglet unlink counter-a3f1:count doubler-b2c4:count
coglet stop counter-a3f1
coglet runtime stop

REST API

The runtime exposes a FastAPI server (default port 4510):

POST /create?cog_dir=PATH              spawn coglet, returns id
POST /stop/{id}                        stop a coglet
POST /transmit/{id}/{channel}?data=... push data into a channel
POST /enact/{id}?command=...&data=...  send @enact command
GET  /observe/{id}/{channel}           SSE stream of channel events
POST /link?src_id=...&src_channel=...  wire channels
     &dest_id=...&dest_channel=...
DELETE /link (same params)             remove wire
GET  /links                            list all wires
GET  /channels/{id}                    list coglet's channels
GET  /status                           tree + coglets + links
GET  /tree                             ASCII tree
POST /shutdown                         stop everything

MCP

The runtime serves an MCP endpoint at /mcp. Connect any MCP client (Claude Code, etc.) to http://localhost:4510/mcp to use all API endpoints as tools.

One-Shot Mode

Run a .cog directory directly without the daemon:

coglet run examples/multi.cog --trace events.jsonl

Framework — Python API

from coglet import Coglet, LifeLet, TickLet, CogBase, every, listen, enact
from coglet.runtime import CogletRuntime

class MyCoglet(Coglet, LifeLet, TickLet):
    async def on_start(self):
        print("started")

    @listen("obs")
    async def handle_obs(self, data):
        await self.transmit("action", self.decide(data))

    @enact("reload")
    async def reload(self, config):
        self.load(config)

    @every(10, "s")
    async def heartbeat(self):
        await self.transmit("status", "alive")

# Boot
runtime = CogletRuntime()
handle = await runtime.run(CogBase(cls=MyCoglet))

Play a CvC Game

cogames play -m machina_1 -p class=cvc.cvc_policy.CogletPolicy -c 8 --seed 42

Upload to Tournament

cogames upload -p class=cvc.cvc_policy.CogletPolicy -n coglet-v0 \
  -f cvc -f mettagrid_sdk -f setup_policy.py \
  --setup-script setup_policy.py --season beta-cvc

Architecture

See docs/coglet.md for the full architecture design.

LET Interface

Decorator Plane Purpose
@listen(channel) Data Handle messages from a named channel
@enact(command_type) Control Handle commands from supervising COG
transmit(channel, data) Output Push results outbound

COG Interface

Method Purpose
create(config) Spawn a child Coglet
observe(handle, channel) Subscribe to a child's transmit stream
guide(handle, command) Send a command to a child (fire-and-forget)

Mixins

Mixin Purpose
LifeLet on_start() / on_stop() lifecycle hooks
TickLet @every(interval, unit) periodic scheduling
ProgLet Unified program table with pluggable executors
GitLet Repo-as-policy — patches applied as git commits
LogLet Separate log stream from transmit stream
MulLet Fan-out N identical children with map/reduce
SuppressLet COG-controlled output gating (subsumption)
WebLet Register with CogWeb UI for graph visualization

CvC Player Stack

Coach (Claude Code session — NOT a Coglet)
  ├── Runs games via cogames CLI
  ├── Reads learnings from PolicyCoglet
  ├── Maintains changelog (coach_log.jsonl)
  └── Commits improvements to repo

PlayerCoglet (GitLet COG)
  └── Manages PolicyCoglets across games
      └── Reads learnings, accumulates experience

PolicyCoglet (CogletPolicy)
  ├── Python heuristic (CogletAgentPolicy) — handles every step
  ├── LLM brain (Claude) — analyzes ~14x per episode
  └── Writes learnings to disk on episode end

CogWeb — Graph Visualization

CogWeb provides a browser-based UI for visualizing live coglet supervision trees.

Setup

Add WebLet to any coglet and pass a shared CogWebRegistry:

from coglet import Coglet, CogBase, CogletRuntime, LifeLet
from coglet.weblet import CogWebRegistry, WebLet
from cogweb.ui import CogWebUI

class Supervisor(Coglet, WebLet, LifeLet):
    async def on_start(self):
        await super().on_start()
        await self.create(CogBase(cls=Worker, kwargs={"cogweb": self._cogweb}))

class Worker(Coglet, WebLet, LifeLet):
    pass

# Boot
registry = CogWebRegistry()
ui = CogWebUI(registry, port=8787)
rt = CogletRuntime()

await ui.start()
await rt.spawn(CogBase(cls=Supervisor, kwargs={"cogweb": registry}))
# Open http://localhost:8787

Features

  • Live graph — nodes auto-register on start, deregister on stop
  • Hierarchical layout — parent COGs above, child LETs below
  • Interactive — pan, zoom, drag nodes, click to inspect
  • Inspector panel — shows class, mixins, @listen/@enact handlers, channels, children, restart config
  • WebSocket updates — graph refreshes automatically as coglets start/stop
  • REST APIGET /api/graph returns JSON snapshot

Without the UI

Use CogWebRegistry standalone for programmatic introspection:

registry = CogWebRegistry()
# ... spawn WebLet-enabled coglets ...
snap = registry.snapshot()
print(snap.to_dict())  # {"nodes": {...}, "edges": [...]}

How Scoring Works

CvC runs 10,000 steps per episode with 8 agents per team. Only 5 actions exist: noop + 4 cardinal moves. All interactions happen through movement (walking into extractors, junctions, enemies). Score = aligned junctions held per tick.

The Python heuristic handles fast-path decisions (role assignment, pathfinding, resource gathering, junction alignment). The LLM brain runs every ~500-1000 steps to analyze strategy and log insights. The Coach reads these post-game and commits code improvements.