{"id":44304523,"url":"https://github.com/synth-laboratories/Horizons","last_synced_at":"2026-02-23T07:00:35.078Z","repository":{"id":336763320,"uuid":"1150784833","full_name":"synth-laboratories/Horizons","owner":"synth-laboratories","description":"Open Source Agent Execution","archived":false,"fork":false,"pushed_at":"2026-02-21T05:21:35.000Z","size":6847,"stargazers_count":71,"open_issues_count":0,"forks_count":4,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-21T12:38:43.983Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.usesynth.ai","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/synth-laboratories.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","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":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-05T17:28:37.000Z","updated_at":"2026-02-21T05:21:37.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/synth-laboratories/Horizons","commit_stats":null,"previous_names":["synth-laboratories/horizons"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/synth-laboratories/Horizons","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synth-laboratories%2FHorizons","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synth-laboratories%2FHorizons/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synth-laboratories%2FHorizons/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synth-laboratories%2FHorizons/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/synth-laboratories","download_url":"https://codeload.github.com/synth-laboratories/Horizons/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synth-laboratories%2FHorizons/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29739024,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-23T04:51:08.365Z","status":"ssl_error","status_checked_at":"2026-02-23T04:49:15.865Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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-02-11T03:00:36.268Z","updated_at":"2026-02-23T07:00:35.073Z","avatar_url":"https://github.com/synth-laboratories.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003eHorizons\u003c/h1\u003e\n  \u003cp\u003eSelf-hostable agent platform. Define agents, give them tools, run them in sandboxes, govern their actions.\u003c/p\u003e\n  \u003cp\u003e\u003ca href=\"https://www.usesynth.ai\"\u003ehttps://www.usesynth.ai\u003c/a\u003e\u003c/p\u003e\n  \u003cp\u003e\n    \u003ca href=\"https://github.com/synth-laboratories/Horizons/actions/workflows/ci.yml?query=branch%3Adev\"\u003e\u003cimg alt=\"CI\" src=\"https://github.com/synth-laboratories/Horizons/actions/workflows/ci.yml/badge.svg?branch=dev\"\u003e\u003c/a\u003e\n    \u003ca href=\"LICENSE.md\"\u003e\u003cimg alt=\"License\" src=\"https://img.shields.io/badge/license-FSL--1.1--Apache--2.0-blue\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://crates.io/crates/horizons-ai\"\u003e\u003cimg alt=\"crates.io\" src=\"https://img.shields.io/crates/v/horizons-ai\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://pypi.org/project/horizons/\"\u003e\u003cimg alt=\"PyPI\" src=\"https://img.shields.io/pypi/v/horizons\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/package/@horizons-ai/sdk\"\u003e\u003cimg alt=\"npm\" src=\"https://img.shields.io/npm/v/@horizons-ai/sdk\"\u003e\u003c/a\u003e\n  \u003c/p\u003e\n  \u003cp\u003e\n    \u003ca href=\"#quickstart\"\u003eQuickstart\u003c/a\u003e ·\n    \u003ca href=\"#built-on-horizons\"\u003eBuilt on Horizons\u003c/a\u003e ·\n    \u003ca href=\"#features\"\u003eFeatures\u003c/a\u003e ·\n    \u003ca href=\"#install-the-sdks\"\u003eInstall the SDKs\u003c/a\u003e ·\n    \u003ca href=\"#from-source\"\u003eFrom source\u003c/a\u003e ·\n    \u003ca href=\"#api-overview\"\u003eAPI overview\u003c/a\u003e ·\n    \u003ca href=\"#repo-layout\"\u003eRepo layout\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n---\n\n## SDLC Usage (Internal Development)\n\nFor internal PR workflows, run SDLC gates from `../synth-bazel`:\n\n```bash\ncd ../synth-bazel\n./scripts/ci_dev_gate.sh\n```\n\nIf integration dependencies are unavailable locally:\n\n```bash\n./scripts/ci_dev_gate.sh --skip-integration\n```\n\n## Features\n\n### Agents and actions\n\nRegister agents as declarative specs (name, sandbox image, allowed tools, schedule). Run them on-demand or on cron. Agents propose actions; actions go through approval gates (auto-approve, AI review, or human review) before execution. Every action is recorded in an append-only audit log.\n\n### MCP gateway (stdio + HTTP)\n\nBuilt-in [MCP](https://modelcontextprotocol.io) gateway supporting stdio and HTTP transports. Requests to `POST /api/v1/mcp/call` derive identity from verified auth (Bearer API keys) by default.\n\nNote: v0.x has the plumbing for scope checks, but does not yet have full RBAC-backed scope assignment and enforcement end-to-end.\n\n- Configure MCP servers: `POST /api/v1/mcp/config`\n- List available tools: `GET /api/v1/mcp/tools`\n- Call a tool: `POST /api/v1/mcp/call`\n\n### Secrets management\n\nPer-org encrypted credential storage (AES-256-GCM). Store API keys, database credentials, service tokens. Secrets are injected at runtime via token resolution (`$cred:connector_id.key`) — agents never see raw credentials in config.\n\n### Sandboxed execution\n\nAgents run in isolated containers via the Rhodes adapter. Supports Docker (local dev) and Daytona (cloud, with snapshotted images for ~3s provisioning). Filesystem overrides let you inject files (AGENTS.md, skills files, config) and environment variables into the sandbox before the agent starts.\n\n### Event-driven orchestration\n\nBidirectional event bus (Redis pub/sub + Postgres event store). Publish/subscribe with routing rules, retry policies, dead-letter queues, and webhook delivery. Agents, connectors, and pipelines communicate through events.\n\n### Context refresh\n\nConnectors ingest external data into durable, per-org context stores. Agents read from these stores at runtime. Built-in connectors for common services; write your own as a simple trait impl.\n\n### Graph execution engine\n\nDAG-based execution engine for structured agent workflows. LLM nodes, Python function nodes, tool-call nodes. Built-in verifier graph registry (rubric scoring, contrastive verification, few-shot, RLM). Define graphs in YAML, execute via API.\n\n### Multi-tenant by default\n\nAll data and operations are org-scoped. In local dev you can use `x-org-id` (and optional `x-project-id`) headers; in secure mode, org + identity are derived from `Authorization: Bearer ...` API keys (recommended).\n\n### API-first, SDKs in three languages\n\nREST API (Axum). SDKs for Python, TypeScript, and Rust. No UI required — everything is programmable.\n\n---\n\n## Install\n\n### Homebrew (macOS \u0026 Linux)\n\n```bash\nbrew install synth-laboratories/tap/horizons\n```\n\n### Docker\n\n```bash\ndocker compose up\n```\n\nStarts the Horizons server on http://localhost:8000 with persistent local storage. No external services required.\n\nTo create an API key for mutating `/api/v1/*` calls:\n\n```bash\nORG_ID=$(uuidgen)\ndocker compose exec horizons horizons create-api-key --data-dir /data --org-id \"$ORG_ID\" --name dev\n```\n\n### Observability (OTLP, Laminar)\n\nHorizons emits OpenTelemetry traces (OTLP). You can point it at any OTLP collector, including a self-hosted Laminar stack.\n\n- Laminar self-host guide: `docs/LAMINAR.md`\n\n### From source\n\nPrerequisites: **Rust 1.85+** (edition 2024 support).\n\n```bash\ncargo build --release -p horizons_server --features all\n./target/release/horizons_server serve\n```\n\n### Pre-built binaries\n\nDownload from [GitHub Releases](https://github.com/synth-laboratories/Horizons/releases). Binaries are available for:\n\n- `x86_64-apple-darwin` (Intel Mac)\n- `aarch64-apple-darwin` (Apple Silicon)\n- `x86_64-unknown-linux-gnu`\n- `aarch64-unknown-linux-gnu`\n\n---\n\n## Quickstart\n\n```bash\n# Install\nbrew install synth-laboratories/tap/horizons\n\n# Start the server (local dev mode — SQLite + local filesystem, no external services)\nhorizons serve\n\n# Verify\ncurl http://localhost:8000/health\n```\n\n### Golden path: first agent + approval + audit\n\nUse this flow to validate the core execution loop in minutes:\n\n1. Start server and create an API key\n2. Create a project\n3. Run an agent\n4. Propose an action\n5. Approve the action\n6. Inspect pending actions and audit trail\n\n```bash\n# Set tenant + auth\nORG_ID=$(uuidgen)\nhorizons create-api-key --org-id \"$ORG_ID\" --name dev\nHORIZONS_API_KEY=\"hzn_...\"\n\n# Create project\nPROJECT_JSON=$(curl -sS -X POST \"http://localhost:8000/api/v1/projects\" \\\n  -H \"Authorization: Bearer $HORIZONS_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}')\nPROJECT_ID=$(printf '%s' \"$PROJECT_JSON\" | jq -r '.project_id')\n\n# Run a simple agent\ncurl -sS -X POST \"http://localhost:8000/api/v1/agents/run\" \\\n  -H \"Authorization: Bearer $HORIZONS_API_KEY\" \\\n  -H \"x-project-id: $PROJECT_ID\" \\\n  -H \"x-agent-id: agent:demo\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"agent_id\":\"dev.noop\",\"inputs\":{\"prompt\":\"hello\"}}'\n\n# Propose an action\nACTION_ID=$(curl -sS -X POST \"http://localhost:8000/api/v1/actions/propose\" \\\n  -H \"Authorization: Bearer $HORIZONS_API_KEY\" \\\n  -H \"x-project-id: $PROJECT_ID\" \\\n  -H \"x-agent-id: agent:demo\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"agent_id\":\"agent:demo\",\n    \"action_type\":\"demo.notify\",\n    \"payload\":{\"message\":\"hello from readme\"},\n    \"risk_level\":\"low\",\n    \"context\":{\"source\":\"readme\"},\n    \"dedupe_key\":\"readme-demo-action-v1\"\n  }' | jq -r '.action_id')\n\n# Approve action\ncurl -sS -X POST \"http://localhost:8000/api/v1/actions/$ACTION_ID/approve\" \\\n  -H \"Authorization: Bearer $HORIZONS_API_KEY\" \\\n  -H \"x-project-id: $PROJECT_ID\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"reason\":\"readme demo\"}'\n\n# Verify queue + audit\ncurl -sS \"http://localhost:8000/api/v1/actions/pending?limit=20\" \\\n  -H \"Authorization: Bearer $HORIZONS_API_KEY\" \\\n  -H \"x-project-id: $PROJECT_ID\"\ncurl -sS \"http://localhost:8000/api/v1/audit?limit=20\" \\\n  -H \"Authorization: Bearer $HORIZONS_API_KEY\" \\\n  -H \"x-project-id: $PROJECT_ID\"\n```\n\n### Auth (recommended for any mutating API calls)\n\nBy default, mutating requests under `/api/v1/*` (POST/PUT/PATCH/DELETE) require verified auth.\n\nCreate an org + API key in the dev Central DB and use it as a Bearer token:\n\n```bash\nORG_ID=$(uuidgen)\nhorizons create-api-key --org-id \"$ORG_ID\" --name dev\n\n# Use the printed token (format: hzn_\u003cuuid\u003e.\u003csecret\u003e)\nHORIZONS_API_KEY=\"hzn_...\"\n\ncurl -sS -X POST \"http://localhost:8000/api/v1/events/publish\" \\\n  -H \"Authorization: Bearer $HORIZONS_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"direction\": \"outbound\",\n    \"topic\": \"demo.hello\",\n    \"source\": \"readme\",\n    \"payload\": { \"hello\": \"world\" },\n    \"dedupe_key\": \"demo.hello.v1\"\n  }'\n```\n\n### Insecure local dev (escape hatch)\n\nIf you want to use header-based org/identity for mutating endpoints in local dev, set:\n- `HORIZONS_ALLOW_INSECURE_HEADERS=true`\n- `HORIZONS_ALLOW_INSECURE_MUTATING_REQUESTS=true`\n\n### CLI commands\n\n```\nhorizons serve              # Start the HTTP server (default)\nhorizons migrate            # Run database migrations (Postgres)\nhorizons create-api-key     # Create an API key in the central DB (Bearer auth)\nhorizons validate-graph     # Validate a graph definition (YAML/JSON)\nhorizons list-graphs        # List built-in graphs from the registry\nhorizons config             # Print current configuration (secrets redacted)\nhorizons check              # Health check configured backends\n```\n\n### Python execution backends\n\n- Default: local `python3` subprocess.\n- Optional: embedded interpreter via [pydantic/monty](https://github.com/pydantic/monty) (requires `--features graph_monty` and `HORIZONS_GRAPH_PYTHON_BACKEND=monty`).\n\n---\n\n## Built on Horizons\n\nReal applications are already running on top of Horizons as the control plane.\n\n### OpenRevenue (public)\n\nRevenue operations app built on Horizons traits and APIs:\n- signal ingestion + scoring\n- context refresh connectors\n- agent sessions with streaming progress\n- action approvals and audit workflow\n\nRepo: [OpenRevenue](https://github.com/synth-laboratories/OpenRevenue)\n\n### Dhakka (private/internal)\n\nPersonal ops + communication app built as a separate workspace on Horizons:\n- iMessage/email/calendar connectors\n- permissioned actions via approvals\n- outbox/event-driven execution\n- one-command local startup (`./run.sh`)\n\nLocal repo: `../Dhakka` (see `README.md` there)\n\n---\n\n## Install the SDKs\n\n### Python\n\n```bash\npip install horizons\n```\n\n### TypeScript / JavaScript\n\n```bash\nnpm install @horizons-ai/sdk\n```\n\n### Rust\n\n```bash\ncargo add horizons-ai\n```\n\n## API overview\n\nHorizons is org-scoped:\n- If you use `Authorization: Bearer ...`, org/identity are derived from the token.\n- For local dev/read-only usage, many endpoints also accept `x-org-id` (and optional `x-project-id`) headers.\n- Mutating `/api/v1/*` endpoints require verified auth by default (see Quickstart above).\n\n| Area | Endpoints | Description |\n|------|-----------|-------------|\n| **Agents** | `POST /api/v1/agents/run`, `POST /api/v1/agents/chat` (SSE), `GET /api/v1/agents` | Run agents, stream agent chat, list registered agents |\n| **Actions** | `POST /api/v1/actions/propose`, `POST /api/v1/actions/:id/approve`, `POST /api/v1/actions/:id/deny`, `GET /api/v1/actions/pending` | Action proposal and approval lifecycle |\n| **MCP** | `POST /api/v1/mcp/config`, `GET /api/v1/mcp/tools`, `POST /api/v1/mcp/call` | MCP server configuration and tool execution |\n| **Engine** | `POST /api/v1/engine/run`, `POST /api/v1/engine/start`, `GET /api/v1/engine/:id/events` (SSE) | Sandbox provisioning and agent execution |\n| **Events** | `POST /api/v1/events/publish`, `GET /api/v1/events`, `POST /api/v1/subscriptions`, `GET /api/v1/subscriptions`, `DELETE /api/v1/subscriptions/{id}` | Event bus publish/query + subscription lifecycle |\n| **Graph** | `POST /api/v1/graph/execute`, `POST /api/v1/graph/validate`, `GET /api/v1/graph/registry` | DAG execution and verifier registry |\n| **Context Refresh** | `POST /api/v1/connectors`, `GET /api/v1/connectors`, `POST /api/v1/context-refresh/run`, `GET /api/v1/context-refresh/status` | Connector source registration + refresh runs |\n| **Pipelines** | `POST /api/v1/pipelines/run`, `GET /api/v1/pipelines/runs/{id}`, `POST /api/v1/pipelines/runs/{id}/approve/{step_id}`, `POST /api/v1/pipelines/runs/{id}/cancel` | Multi-step pipeline orchestration |\n| **Project DB** | `POST /api/v1/projects/{id}/query`, `POST /api/v1/projects/{id}/execute` | Raw SQL query/execute against a project DB (guardrailed; writes disabled by default) |\n| **Files** | `PUT /api/v1/files/{*key}`, `GET /api/v1/files/{*key}`, `DELETE /api/v1/files/{*key}` | Per-org file storage |\n| **Projects** | `POST /api/v1/projects`, `GET /api/v1/projects` | Project provisioning + listing |\n| **Audit** | `GET /api/v1/audit` | Append-only audit trail |\n| **Assets** | `POST /api/v1/assets/resources`, `GET /api/v1/assets/resources`, `POST /api/v1/assets/operations`, `GET /api/v1/assets/operations` | Managed resources + operations (non-UI) |\n| **Credentials** | `GET /api/v1/credentials`, `PUT /api/v1/credentials/{connector_id}` | Encrypted credential storage (non-UI) |\n| **Config** | `GET /api/v1/config`, `PUT /api/v1/config` | Runtime configuration |\n\nOptional feature-gated endpoints (compile with `--features memory`, `optimization`, `evaluation`, or `all`):\n\n| Feature | Endpoints | Description |\n|---------|-----------|-------------|\n| **Memory** | `/api/v1/memory/*` | Embed, retrieve, rank (Voyager) |\n| **Optimization** | `/api/v1/optimization/*` | Prompt/policy optimization (MIPRO v2) |\n| **Evaluation** | `/api/v1/evaluation/*` | Reward verification (RLM) |\n\n## Repo layout\n\n### Crates\n\n| Crate | Version | Description |\n|-------|---------|-------------|\n| `horizons_server` | 0.1.0 | Axum HTTP API server |\n| `horizons-ai` (`horizons_rs/`) | 0.1.0 | Rust SDK client — [crates.io](https://crates.io/crates/horizons-ai) |\n| `horizons_core` | 0.1.0 | Core domain models and backend traits (events, projects DB, agents/actions, pipelines, sandbox runtime) |\n| `horizons_graph` | 0.1.0 | DAG execution engine (LLM/tool/python nodes) with built-in verifier graph registry |\n| `horizons_integrations` | 0.1.0 | Infrastructure adapters (vector store, queue backends, observability sinks) |\n| `voyager` | 0.1.0 | Memory — embed/retrieve/rank |\n| `mipro_v2` | 0.1.0 | Optimization — prompt/policy optimization engine |\n| `rlm` | 0.1.0 | Evaluation — reward signals, weighted scoring, pass/fail verification |\n\nAll crates use Rust **edition 2024**.\n\n### SDKs\n\n| SDK | Version | Path |\n|-----|---------|------|\n| Python (`horizons`) | 0.1.0 | `horizons_py/` — [PyPI](https://pypi.org/project/horizons/) |\n| TypeScript (`@horizons-ai/sdk`) | 0.1.0 | `horizons_ts/` — [npm](https://www.npmjs.com/package/@horizons-ai/sdk) |\n| Rust (`horizons-ai`) | 0.1.0 | `horizons_rs/` — [crates.io](https://crates.io/crates/horizons-ai) |\n\n## Testing\n\nHorizons keeps test code out of the repo. See [synth-laboratories/testing](https://github.com/synth-laboratories/testing) (`horizons-tests/`) for unit, property-based, mocked integration, and opt-in live-LLM tests.\n\n## Specs\n\nHorizons platform specs and implementation plans live in the separate `specifications/` repo under `horizons/`.\n\n## License\n\n[FSL-1.1-Apache-2.0](LICENSE.md) (the Sentry license) — Copyright 2026 Synth Incorporated.\n\nFree to use, modify, and redistribute for any purpose except building a competing product. Converts to Apache 2.0 after two years.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynth-laboratories%2FHorizons","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsynth-laboratories%2FHorizons","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynth-laboratories%2FHorizons/lists"}