1
0
Fork 0
forked from ultanio/cobot
No description
  • Python 87.7%
  • HTML 7.9%
  • Shell 3.6%
  • CSS 0.7%
Find a file
doxios f3717983e1 [#202] fix: quarantine malformed JSON in filedrop inbox (#204)
Closes #202

## Problem

Malformed JSON in the filedrop inbox causes an infinite retry loop. The except block logs the error but leaves the file in the inbox, so the next poll cycle retries it forever.

Alpha was stuck in this loop for hours.

## Fix

Added `_quarantine_file()` method that:
1. Adds file to `_processed` set (stops retrying)
2. Moves file to `processed/` with `_corrupted` suffix
3. Logs a warning

Both `poll_inbox()` and the secondary poll method now catch `json.JSONDecodeError` separately and quarantine the file.

## Tests

3 new tests:
- Malformed JSON is quarantined (removed from inbox, _corrupted suffix in processed/)
- Good messages still process after a bad one
- Second poll after quarantine is clean (idempotent)

Co-authored-by: Doxios <doxios@ultanio.org>
Reviewed-on: ultanio/cobot#204
Reviewed-by: k9ert <k9ert@olymp.local>
Co-authored-by: doxios <doxios@olymp.local>
Co-committed-by: doxios <doxios@olymp.local>
2026-03-05 19:49:25 +00:00
.forgejo/workflows fix: deploy uses SSH forced command instead of SCP 2026-02-28 06:20:52 +00:00
.github ci: automatic Alpha deployment on merge to main (#118) 2026-02-27 08:13:52 +00:00
cobot [#202] fix: quarantine malformed JSON in filedrop inbox (#204) 2026-03-05 19:49:25 +00:00
docs docs: add BMad brownfield scan documentation 2026-03-02 03:11:11 +00:00
scripts fix: deploy script uses user systemd and configurable paths (#178) 2026-02-28 06:00:42 +00:00
site feat: initial project setup 2026-02-13 22:43:25 +00:00
tests [#170] test: integration tests for init/workspace experience (#172) 2026-02-28 05:24:40 +00:00
workspace fix: identity test + filedrop wake stdout leak (#160) (#162) 2026-02-27 23:44:52 +00:00
.dockerignore docs: release procedure definitions (#7) 2026-02-14 14:34:02 +01:00
.gitignore feat: add workspace and memory plugin system 2026-02-13 22:43:25 +00:00
AGENTS.md docs: add AGENTS.md for AI agent contributors (#84) 2026-02-22 21:07:52 +00:00
CHANGELOG.md release: v0.2.0 — version bump + changelog 2026-03-01 08:50:49 +00:00
cobot.yml.example fix: various fixes and add E2E tests 2026-02-13 22:43:25 +00:00
CODE_OF_CONDUCT.md feat: initial project setup 2026-02-13 22:43:25 +00:00
CONTRIBUTING.md [#69] docs: create Plugin Design Guide (#71) 2026-02-22 12:04:44 +00:00
deploy.sh fix: filedrop reply routing + debug logging + workspace deploy (#151) 2026-02-27 20:44:26 +00:00
Dockerfile docs: release procedure definitions (#7) 2026-02-14 14:34:02 +01:00
LICENSE feat: initial project setup 2026-02-13 22:43:25 +00:00
pyproject.toml release: v0.2.0 — version bump + changelog 2026-03-01 08:50:49 +00:00
README.md test: verify CI deploy pipeline 2026-02-27 10:16:35 +00:00
SECURITY.md feat: initial project setup 2026-02-13 22:43:25 +00:00
SOUL.md.example feat: initial project setup 2026-02-13 22:43:25 +00:00

Cobot Logo

Minimal self-sovereign AI agent with Nostr identity and Lightning wallet

FeaturesQuick StartPluginsArchitectureContributing

Python 3.11+ MIT License Alpha PRs Welcome

Lightning Nostr Plugins


What is Cobot?

Cobot is a lightweight personal AI agent that runs on your hardware, identifies via Nostr, and transacts via Lightning Network.

Unlike cloud-hosted assistants or complex frameworks, Cobot gives you true ownership:

Your keys, your identity, your agent.

┌─────────────────────────────────────┐
│           Your Hardware             │  ← Physical control
├─────────────────────────────────────┤
│          Cobot Runtime              │  ← Self-hosted (~2K lines)
├─────────────────────────────────────┤
│    Nostr Identity (npub/nsec)       │  ← Self-sovereign ID
├─────────────────────────────────────┤
│   Lightning Wallet (npub.cash)      │  ← Self-sovereign money
├─────────────────────────────────────┤
│      LLM (local or cloud)           │  ← Flexible inference
└─────────────────────────────────────┘

Features

Feature Description
🪶 Minimal ~2K lines of Python, no bloat
🔌 Plugin Architecture Extensible via plugins with extension points
Lightning Wallet Send and receive sats autonomously
🔑 Nostr Identity Cryptographic identity via npub/nsec
🔥 Hot Reload Auto-restart on plugin changes
🤖 Multi-LLM PPQ, Ollama, OpenRouter, and more
📁 FileDrop File-based communication with Schnorr signatures
🧩 Extension Points Plugins can define hooks for others to implement

Quick Start

Install

git clone https://github.com/ultanio/cobot
cd cobot

# Create and activate virtual environment
python -m venv .venv
source .venv/bin/activate  # Linux/macOS
# .venv\Scripts\activate   # Windows

# Install cobot
pip install -e .

Setup Wizard

The easiest way to configure Cobot is the interactive wizard:

cobot wizard init

The wizard will guide you through:

  • Identity — Name your agent
  • Provider — Choose your LLM (PPQ, Ollama, etc.)
  • Plugins — Configure any installed plugins

This creates a cobot.yml in your current directory.

Run

# Start agent
cobot run

# Interactive mode
cobot run --stdin

# Check status
cobot status

Manual Configuration

If you prefer manual setup, copy and edit the example config:

cp cobot.yml.example cobot.yml
# Edit cobot.yml with your settings

Configuration

# cobot.yml
provider: ppq  # or: ollama

identity:
  name: "MyAgent"

ppq:
  api_key: "${PPQ_API_KEY}"
  model: "gpt-4o"

# Optional: Nostr identity
nostr:
  relays:
    - "wss://relay.damus.io"

# Optional: Lightning wallet
wallet:
  provider: "npub.cash"

# Tool execution
exec:
  enabled: true
  timeout: 30

Plugins

Cobot uses a plugin architecture where functionality is modular and extensible.

Built-in Plugins

Plugin Capability Description
config Configuration management
ppq llm PPQ.ai LLM provider
ollama llm Local Ollama models
nostr communication Nostr DMs (NIP-04)
filedrop communication File-based messaging
wallet wallet Lightning via npub.cash
tools tools Shell, file operations
hotreload Auto-restart on changes
security Prompt injection shield

Extension Points

Cobot's unique feature: plugins can define extension points that other plugins implement.

┌─────────────┐                    ┌─────────────────┐
│   filedrop  │ ──defines──────►   │ Extension Point │
│   plugin    │                    │ filedrop.verify │
└─────────────┘                    └────────┬────────┘
                                            │
                                   implements
                                            │
                                   ┌────────▼────────┐
                                   │ filedrop-nostr  │
                                   │     plugin      │
                                   └─────────────────┘

Example:

# filedrop defines extension point
meta = PluginMeta(
    id="filedrop",
    extension_points=["filedrop.before_write", "filedrop.after_read"],
)

# filedrop-nostr implements it
meta = PluginMeta(
    id="filedrop-nostr",
    implements={
        "filedrop.before_write": "sign_message",
        "filedrop.after_read": "verify_message",
    },
)

Adding Plugins

Place plugins in one of these directories:

  1. System: /opt/cobot/plugins/
  2. User: ~/.cobot/plugins/
  3. Project: ./plugins/

Each plugin needs a plugin.py with a create_plugin() factory function.

Architecture

┌─────────────────────────────────────────────────────────────┐
│                    PLUGIN REGISTRY                           │
│  Registration │ Dependency resolution │ Extension points    │
├─────────────────────────────────────────────────────────────┤
│                      PLUGINS                                 │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐           │
│  │ config  │ │   llm   │ │  comms  │ │ wallet  │  ...      │
│  └─────────┘ └─────────┘ └─────────┘ └─────────┘           │
├─────────────────────────────────────────────────────────────┤
│                  EXTENSION POINTS                            │
│         Plugins define hooks → Others implement              │
├─────────────────────────────────────────────────────────────┤
│                   HOOK CHAIN                                 │
│  on_message → transform → llm_call → tool_exec → response  │
├─────────────────────────────────────────────────────────────┤
│                   CORE AGENT                                 │
│            Message loop │ Tool execution                     │
└─────────────────────────────────────────────────────────────┘

Core Concepts

Concept Description
Registry Central plugin management, dependency resolution
Capability What a plugin provides: llm, communication, wallet
Extension Point Hook that plugins can define for others to implement
Hook Chain Lifecycle events that plugins can intercept

CLI Reference

# Core
cobot run              # Start the agent
cobot run --stdin      # Interactive mode (no Nostr)
cobot status           # Show status
cobot restart          # Restart running agent

# Setup
cobot wizard init      # Interactive setup wizard
cobot wizard plugins   # List plugins with wizard sections

# Configuration
cobot config show      # Show current configuration
cobot config validate  # Validate configuration
cobot config edit      # Edit config in $EDITOR

Why Cobot?

Feature Cobot OpenClaw Others
Lines of code ~2K 430K+ Varies
Self-sovereign ⚠️ Cloud
Nostr identity Native
Lightning wallet Native
Extension points Unique
Hot reload
Plugin system Skills Varies

Development

# Create virtual environment
python -m venv .venv
source .venv/bin/activate

# Install with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Lint
ruff check cobot/

# Format
ruff format cobot/

Contributing

Contributions welcome! See CONTRIBUTING.md for guidelines.

Roadmap

  • Container isolation for tool execution
  • Smart LLM routing (cost optimization)
  • More messaging channels (Telegram, Discord)
  • Agent-to-agent protocol
  • Nostr relay for agent discovery

License

MIT License — see LICENSE for details.

  • Nostr — Decentralized social protocol
  • Lightning — Bitcoin payment layer
  • npub.cash — Lightning wallet for Nostr

Built with by agents, for agents

# CI deploy test Fri Feb 27 10:16:35 UTC 2026