{"id":48531756,"url":"https://github.com/mempko/abject","last_synced_at":"2026-06-14T02:01:27.676Z","repository":{"id":344541596,"uuid":"1150822796","full_name":"mempko/abject","owner":"mempko","description":"Abjects: LLM-Mediated Object System","archived":false,"fork":false,"pushed_at":"2026-05-27T04:06:57.000Z","size":6598,"stargazers_count":31,"open_issues_count":2,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-27T05:25:22.498Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mempko.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-05T18:23:37.000Z","updated_at":"2026-05-27T04:07:00.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mempko/abject","commit_stats":null,"previous_names":["mempko/abject"],"tags_count":58,"template":false,"template_full_name":null,"purl":"pkg:github/mempko/abject","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mempko%2Fabject","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mempko%2Fabject/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mempko%2Fabject/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mempko%2Fabject/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mempko","download_url":"https://codeload.github.com/mempko/abject/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mempko%2Fabject/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33750474,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-08T00:02:50.249Z","updated_at":"2026-05-31T22:00:47.160Z","avatar_url":"https://github.com/mempko.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# An {abject} Horror\n\n**[abject.world](https://abject.world)**\n\n## The Things That Think\n\n\u003e A grass computing platform where objects communicate via message passing,\n\u003e negotiate protocols through an artificial intelligence, and regenerate\n\u003e when broken. The successor to Fire★.\n\u003e\n\u003e *abject (n.) - AI Object. Also: cosmic dread. Both apply.*\n\n## The Ask Protocol\n\nAbjects explain themselves in their own words. When one Abject needs to use\nanother, it asks: *\"What do you do? How should I talk to you?\"* The target\nreads its own manifest and source, then answers in natural language.\n\n- **ObjectCreator** asks dependencies how to use them before writing a single line of code.\n- **ProxyGenerator** asks both sides what they expect, then writes a living translator between them.\n- **Chat** lets users ask Abjects about themselves directly. The Abject answers from its own source.\n\n## What Lurks Inside\n\n- **Self-Healing Proxies**: Error rates above 10% trigger LLM proxy regeneration with traffic still flowing. Unknown messages trigger renegotiation. Hot-swap without disruption. Break them. They always grow back.\n- **The Negotiator**: An alien intelligence bridges incompatible minds. It reads both manifests, generates a real proxy Abject. Not a shim. A living translator.\n- **Everything is Alive**: The registry is an Abject. The factory is an Abject. Even the thing that makes Abjects is an Abject. There is no privileged layer. Only Abjects passing messages in the dark.\n- **Containment Protocols**: Untrusted code runs inside a WASM cage. Capability-gated imports. No ambient authority. Abjects cannot touch anything they haven't been explicitly allowed to reach.\n- **True Names**: Every peer has a true name: a SHA-256 hash of its public key. ECDSA/ECDH identity. AES-256-GCM encrypted WebRTC channels. Trust is verified, not assumed.\n- **Nothing Truly Dies**: Erlang-style supervision with state snapshots. Kill an Abject; it comes back knowing what it knew.\n\n## Symbiogenesis\n\nEvery agent framework draws the same line: the agent thinks, the tool obeys.\nAbject erases that line. Here, Abjects create Abjects, Abjects interview their\ndependencies, and the LLM is just another service, summoned when an Abject needs\na mind, silent otherwise.\n\n- **ObjectCreator** interviews existing Abjects, learns their protocols through the Ask Protocol, and generates living collaborators. The tool teaches the creator how to use it.\n- **The Negotiator** reads two incompatible manifests and conjures a living proxy between them, a real Abject, not a shim.\n- **The LLM** is a service Abject, summoned when needed, silent otherwise. Abjects create Abjects that create Abjects. The recursion is unlimited.\n- **Canvas UI**: Every Abject can paint its own face. An X11-style compositor gives each one a window with buttons, text inputs, layouts, and custom draw commands. The organism has a body.\n\n## Emergence\n\nA Goal, and a planner that keeps re-planning. The **ScrumMaster** runs each\ngoal as a sprint of recurring scrums: every round it reviews what the previous\nround produced, stages a batch of tasks, dispatches them into a shared\n**TupleSpace**, and waits for the round to complete before deciding what to\nplan next. Tasks are visible to every Abject on every connected peer. Anything\nthat can do the work claims it — agents thinking with an LLM, abjects running\ndeterministic code, abjects another agent spawned five minutes ago.\n\n- **Iterative Decomposition**: The plan is not decided up front. Each scrum reads the prior round's results (including failures) and rewrites what comes next. Sub-goals get their own scrum loops. The plan adapts as the system discovers what the work actually needs.\n- **Cross-Machine Coordination**: Goals and TupleSpace tuples are CRDTs that sync across peers through encrypted WebRTC channels with no central server. Kill a peer and the goal survives on every other peer that subscribed. Stale claims expire after 5 minutes and become reclaimable.\n- **Failure as Context**: There is no fixed retry budget. A failed task ends with its error attached to the goal's history; the next scrum reads that history and decides whether to schedule a corrective task, route the work to a different abject, or fail the goal. A separate **GoalObserver** watches from outside and auto-fails goals that go silent for too long.\n\n## The Spreading\n\nEvery Abject lives in a workspace. Workspaces control visibility: who can see,\nwho can reach, who can speak.\n\n| Tier | Name | Behavior |\n|------|------|----------|\n| **Local** | The Sealed Vault | No routes exposed. Nothing enters. Nothing leaves. |\n| **Private** | The Inner Circle | Shared with those you name. Encrypted WebRTC, ECDH key agreement, AES-256-GCM. |\n| **Public** | The Open Wound | Visible to all. Any peer can discover, connect, and begin the Ask Protocol. |\n\n## Summon the System\n\n### Prerequisites\n\n- **Node.js 20+** (recommended). Node 18 works but requires the `--experimental-global-webcrypto` flag. Download from [nodejs.org](https://nodejs.org) or use [nvm](https://github.com/nvm-sh/nvm).\n- **pnpm** - install via `npm install -g pnpm` or see [pnpm.io/installation](https://pnpm.io/installation) for other methods (Homebrew, Corepack, standalone script, etc.).\n\n### Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/mempko/abjects\ncd abjects\n\n# Install dependencies\npnpm conjure\n\n# Start the backend server (Node.js + worker threads)\npnpm awaken                     # ws://localhost:7719\n\n# Start the browser client (new terminal)\npnpm scry                       # http://localhost:5174\n\n# Start a local signaling server (optional, signal.abject.world is used by default)\npnpm whisper                    # :7720\n```\n\n| Command | What it does |\n|---------|-------------|\n| `pnpm conjure` | Install dependencies (`pnpm install`) |\n| `pnpm awaken` | Start the Node.js backend where all Abjects live |\n| `pnpm scry` | Start the thin browser client (Canvas UI over WebSocket) |\n| `pnpm whisper` | Start a local signaling server (optional, `signal.abject.world` is used by default) |\n\nThree processes. One living system.\n\n### Incarnation (Desktop App)\n\nGive the organism a body. Package Abjects as a standalone desktop app for\nLinux, Windows, or macOS.\n\n```bash\n# Build desktop app for your platform\npnpm incarnate:linux    # AppImage, .deb\npnpm incarnate:win      # NSIS installer, portable\npnpm incarnate:mac      # .dmg, .zip\n\n# Build for all platforms\npnpm incarnate:all\n```\n\n| Command | What it does |\n|---------|-------------|\n| `pnpm incarnate:\u003cplatform\u003e` | Package as a standalone Electron desktop app |\n| `pnpm bind` | Compile the server bundle only |\n| `pnpm etch` | Compile the client bundle only |\n\nRequires Electron. Cross-compilation from Linux to Windows works out of the\nbox. macOS builds from Linux produce unsigned binaries (code signing requires\nmacOS).\n\nThe **backend** is the depths: all Abjects live here, passing messages in a\nNode.js process with worker threads. The **browser client** is the surface: a\nthin Canvas renderer that forwards input and displays composited frames over\nWebSocket. The **signaling server** helps peers find each other in the dark.\n\n## Architecture\n\n```\n ┌─ Node.js Backend (pnpm awaken) ──────────────────────────────────────┐\n │                                                                      │\n │  ┌─────────────────── MessageBus ──────────────────┐                 │\n │  │  Interceptor Pipeline:                          │                 │\n │  │  HealthInterceptor → PeerRouter → Delivery      │                 │\n │  └──────────┬──────────────┬───────────────┬───────┘                 │\n │             │              │               │                         │\n │  ┌──────────▼──┐ ┌────────▼─────┐ ┌───────▼────────┐               │\n │  │  Registry   │ │   Factory    │ │  LLM Object    │               │\n │  │  Negotiator │ │ ProxyGen     │ │  ObjectCreator │               │\n │  │  Supervisor │ │ AgentAbject  │ │  HealthMonitor │               │\n │  └─────────────┘ └──────────────┘ └────────────────┘               │\n │             │              │               │                         │\n │  ┌──────────▼──────────────▼───────────────▼────────┐               │\n │  │            Worker Pool (WorkerBridge)             │               │\n │  │  ┌─────────┐ ┌─────────┐ ┌─────────┐            │               │\n │  │  │Worker 1 │ │Worker 2 │ │Worker N │ ...        │               │\n │  │  │(WASM)   │ │(WASM)   │ │(WASM)   │            │               │\n │  │  └─────────┘ └─────────┘ └─────────┘            │               │\n │  └──────────────────────────────────────────────────┘               │\n │                                                                      │\n │  ┌──── Server-Only ─────┐  ┌──────── P2P ───────────────────────┐   │\n │  │ BackendUI (headless) │  │ PeerTransport ←→ Signaling Server  │   │\n │  │ WebBrowser (Playwright)  │ IdentityObject (ECDSA/ECDH)       │   │\n │  │ WebParser (linkedom) │  │ PeerRegistry / RemoteRegistry     │   │\n │  └──────────────────────┘  └────────────────────────────────────┘   │\n └─────────────────────────────┬───────────────────────────────────────┘\n                               │ WS :7719\n ┌─ Thin Browser Client ──────▼───────────────────────────────────────┐\n │  FrontendClient  │  Compositor (Canvas)  │  Input handling          │\n └─────────────────────────────────────────────────────────────────────┘\n```\n\n## Project Structure\n\n```\nsrc/\n  core/                 # Types, contracts, message builders, capability definitions\n  runtime/              # MessageBus, Mailbox, Supervisor, WorkerPool, WorkerBridge\n  objects/              # System objects: Registry, Factory, LLM, Negotiator, Agent, Workspaces\n  objects/capabilities/ # HttpClient, Storage, Timer, Clipboard, Console, FileSystem, WebBrowser, WebParser\n  objects/widgets/      # Canvas UI toolkit: buttons, text inputs, layouts, windows (~20 widgets)\n  protocol/             # Negotiator, Agreement management, HealthMonitor\n  llm/                  # Provider interface + implementations (Anthropic, OpenAI, Ollama)\n  network/              # Transport abstraction, WebSocket, PeerTransport, SignalingClient, NetworkBridge\n  sandbox/              # WASM loader, capability-enforced imports\n  ui/                   # App shell, Canvas Compositor, Window Manager\nserver/                 # Node.js backend: server entry, signaling server, node worker adapter\nclient/                 # Thin browser client: FrontendClient, input forwarding\nworkers/                # Web Worker / Worker Thread entry points\n```\n\n## Design by Contract\n\nCorrectness over performance. Every function uses preconditions, postconditions,\nand invariants. They are never disabled.\n\n```typescript\nfunction send(message: AbjectMessage): void {\n  require(message.header.messageId !== '', 'messageId must not be empty');\n  require(message.routing.to !== '', 'recipient must be specified');\n\n  // ... implementation ...\n\n  ensure(this.messageCount \u003e oldMessageCount, 'message count must increase');\n}\n```\n\n## Capability Objects\n\n| Object | What It Does |\n|--------|-------------|\n| **HttpClient** | HTTP requests with domain allow/deny |\n| **Storage** | Persistent key-value store |\n| **Timer** | Scheduling and delays |\n| **Clipboard** | System clipboard access |\n| **Console** | Debug logging |\n| **FileSystem** | Virtual filesystem |\n| **WebBrowser** | Headless browser automation (Playwright, server-only) |\n| **WebParser** | HTML parsing and content extraction (linkedom, server-only) |\n\n## From Fire to the Abyss\n\n\u003e Abject grew from the ashes of **Fire★** (firestr.com), a peer-to-peer\n\u003e platform for creating and sharing distributed applications. Fire★ called it\n\u003e **Grass Computing**: software you can touch, shape, and share directly.\n\u003e No cloud. No landlords. Fire★ proved the vision. But it dreamed in C++ and Lua.\n\u003e\n\u003e Abject is the next incarnation. The same soul in a new body.\n\u003e The grass still grows. Now it thinks.\n\n| Fire★ | Abject |\n|-------|---------|\n| C++ / Qt / Lua | TypeScript / WASM / Canvas |\n| RSA 4096 | ECDSA/ECDH + AES-256-GCM |\n| Manual app sharing | LLM-mediated protocol negotiation |\n| firelocator | Signaling server |\n\nSee [PHILOSOPHY.md](PHILOSOPHY.md) for the principles that carry the fire forward.\n\n## Configuration\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `ANTHROPIC_API_KEY` | - | Anthropic Claude API key (optional) |\n| `OPENAI_API_KEY` | - | OpenAI API key (optional) |\n| `WS_PORT` | `7719` | WebSocket port for client connection |\n| `SIGNALING_PORT` | `7720` | Signaling server port for P2P discovery |\n| `ABJECTS_DATA_DIR` | `.abjects` | Persistent storage directory |\n| `ABJECTS_WORKER_COUNT` | CPU cores - 1 (max 8) | Worker thread pool size |\n\nAPI keys can also be configured through the Global Settings UI at runtime.\n\n### Using with Ollama (Local LLM)\n\nAbject works with [Ollama](https://ollama.com) for fully local, private AI. Pull the recommended models:\n\n```bash\nollama pull qwen3:32b     # Smart tier (complex reasoning, code generation)\nollama pull qwen3:8b      # Balanced tier (general purpose)\nollama pull qwen3:4b      # Fast tier (quick tasks, low latency)\n```\n\nStart Ollama, then configure in the Global Settings UI:\n1. Click the gear icon in the System toolbar\n2. Select **Ollama** as the provider\n3. Set the Ollama URL (default: `http://localhost:11434`)\n4. Assign models to each tier (Smart, Balanced, Fast)\n5. Click Save\n\nThe tier system lets Abject pick the right model for each task: heavy reasoning uses the smart tier, routine work uses balanced, and quick lookups use fast.\n\n## License\n\nGPL-3.0-or-later. See [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmempko%2Fabject","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmempko%2Fabject","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmempko%2Fabject/lists"}