Skip to content
Rishiraj-YadavPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

NervOS

NervOS is a self-hosted AI-agent runtime and management platform. Stages A through G are complete, externally accepted and merged. Stage I0 architecture and I1 hosted Marketplace foundation are complete and externally accepted. The intentional order is G → bounded/pre-H I → H hardening; Stage H has not started.

The A1 repository/tooling foundation, A2 API/configuration/database foundation, A3 local-authentication boundary, A4 React dashboard foundation, A5 deterministic browser journey, and A6 continuous-integration/security-scanning milestone are implemented. The browser supports first-run setup, cookie-backed login/session restoration, a protected minimal dashboard, and server-confirmed logout.

Stage B implemented the trusted nervos.chat@1 Agent Instance and Run surface plus Anthropic/OpenAI portability. Stage C1 added the durable Job/Attempt/RunEvent schema, C2 activated asynchronous submission plus a separate Worker process, C3 added a durable Worker registry and expired-lease reconciliation: work lost before the execution-start boundary is recovered and re-queued, and work lost after it is closed as ambiguous rather than replayed. One submission is one independent Run: the API returns 202 Accepted after durable queueing, and a capable Worker executes the immutable provider/model snapshot later. C4 added the automatic execution retry engine: a failure the provider positively declined (a normalized rate limit) becomes a durable retry_wait obligation with a stored due instant, and a later compatible Worker executes it with a fresh Attempt — surviving restarts with no scheduler — while ambiguous outcomes such as timeouts stay terminal and are never replayed. C5 added owner cancellation: an owner can cancel a queued, retrying, or running Run, the cancellation is durable before the request returns and does not depend on a live Worker, and a cancelled Run is a distinct terminal lifecycle rather than a failure. C5 also added the Attempt execution-timeout watchdog, which keeps a timed-out Attempt AMBIGUOUS and never replays it. Cancellation revokes NervOS authority only — it makes no claim that the remote provider stopped or that billing stopped. C6 made execution concurrency authoritative: global, per-Agent-Instance, and per-provider limits are enforced together at claim time from Jobs that hold a live lease, so no Worker's local configuration can raise the system ceiling, and selection is durable least-recently-served per Agent Instance rather than global FIFO, so a continuously eligible Agent is not bypassed by a backlog that merely happens to be older. A partition that is saturated, or whose provider a Worker cannot run, is skipped instead of blocking the queue head, and admission is bounded by global, per-Agent, and per-provider pending limits. C7 made the kernel observable to its owner without giving observability any authority: GET /api/v1/runs/{run_id}/events returns a Run's durable execution timeline, owner-scoped by the same rule as the Run itself, ordered by the Run-local sequence the writers allocated and paginated by a keyset cursor rather than an offset. Run responses also carry a derived read-only execution phase — the Job's own durable status, verbatim — which finally distinguishes a Run that is executing now from one waiting out a retry, and the dashboard shows the timeline incrementally with a polling lifetime that no longer abandons a live Run. C7 added no migration: the existing UNIQUE(run_id, sequence) index already serves the pagination query. C8 proved the finished engine composes — integrated acceptance across recovery, retry, cancellation, timeout, all three concurrency dimensions, fairness and backpressure; restart and re-composition; multi-Worker composition; a bounded deterministic 120-Job stress soak; SQLite integrity; and security acceptance. NervOS does not guarantee exactly-once remote provider execution: it guarantees fenced durable authority, no blind replay of ambiguous execution, safe retry only for a positively safe outcome, and protection against stale late writes — while remote provider processing, billing, and side effects may still occur after an ambiguous crash, a cancellation, or a timeout.

Stage D — the tool and MCP layer — is COMPLETE. D1 added durable tool, capability, and audit schema; D2 added capability grants and the call-time permission decision; D3 added the tool registry, canonical schema, and the first built-in tools; D4 added provider-neutral tool calling and the Think → Act → Observe loop; D5 added the MCP client/gateway and connection lifecycle; D6 added tool audit, failure semantics, and C3–C6 integration; D7 added integrated acceptance and Stage-D closeout.

Stage E — scheduling, events, and triggers — is COMPLETE. E0 froze architecture, protocol, and safety; E1 added the durable trigger/occurrence domain and migration 0008; E2 added the scheduler engine (one-time/interval/cron, timezone, misfire, multi-instance, restart); E3 added secure webhook ingress, secret authentication, rotation, and idempotency; E4 added internal events, trigger management, occurrence history, and minimal Automations UI; E5 added integrated acceptance and Stage-E closeout.

Stage F — Conversations, context, and memory — is COMPLETE. F0 froze architecture, protocol, safety, and lifecycle; F1 added durable Conversations, Turns, Messages, and Run linkage; F2 added ContextBuilder, mandatory RunContextSnapshot, deterministic compaction, and context bounds; F3 added scoped AGENT/USER Memory, provenance, and deterministic retrieval; F4 added Conversation and memory lifecycle, versioned editing, deletion, active-data invalidation, retention semantics, and minimal UI; F5 added integrated acceptance and Stage-F closeout.

See implementation status for the verified current state and architecture for target boundaries.

Prerequisites

  • Git
  • Python 3.12 or newer (the workspace is pinned to Python 3.12)
  • uv 0.9.15 or newer
  • Node.js 22.12–24.x; CI runs Node 24 (declared in .node-version), which is the upper bound of the supported range
  • pnpm 10.x (the repository pins pnpm 10.28.1)
  • GNU Make only if using the optional Make facade

The bootstrap script never installs global or system packages.

Bootstrap

From the repository root:

python scripts/bootstrap.py

On Windows, an explicit Python 3.12 launcher is also supported:

py -3.12 scripts\bootstrap.py

Bootstrap installs the frozen Python and JavaScript dependency sets, then provisions the locked Playwright-managed Chromium browser. It never installs global or system packages, creates a NervOS database, runs migrations, or starts services. To install dependencies without the browser, pass --skip-browser; CI's browser-free job uses this so routine checks never download Chromium. To repair only the browser prerequisite, run:

pnpm --dir apps/web exec playwright install chromium

Do not use --with-deps locally; Stage A bootstrap provisions Chromium only. The CI runner installs its own Playwright system libraries, which is a runner-only concern.

Foundation commands

make bootstrap
make dev-api
make dev-worker
make dev-web
make lint
make typecheck
make test
make security
make test-e2e
make check
make clean-check

GNU Make is not required. The equivalent cross-platform commands are:

python scripts/bootstrap.py
uv run python scripts/dev.py api
uv run python scripts/dev.py worker
uv run python scripts/dev.py web
uv run python scripts/check.py lint
uv run python scripts/check.py typecheck
uv run python scripts/check.py test
uv run python scripts/check.py security
uv run python scripts/check.py e2e
uv run python scripts/check.py check
uv run python scripts/clean_check.py

For local development, start dev-api, then dev-worker, then dev-web in separate terminals; the API migrates the database, while the Worker only validates the existing schema before claiming Jobs.

check is the routine gate and covers lint, typecheck, tests and the tracked-file security scan. It is deliberately not the whole story: the deterministic browser journey lives in the separate e2e group because it needs Chromium and spawns API, Worker, and Web services. Full verification is therefore check then e2e, which is exactly what CI runs. See continuous integration.

Start the A2 API development server with:

uv run python scripts/dev.py api

The API launcher validates configuration, runs Alembic upgrade head, and starts Uvicorn on http://127.0.0.1:8000. Liveness is available at GET /api/v1/health and returns {"status":"ok"}. Start the A4 web application separately with:

uv run python scripts/dev.py web

Open exactly http://localhost:5173. Vite proxies relative /api/v1/... requests to the local API so the browser remains same-origin and satisfies A3's exact-Origin policy. A4 consumes the A3 setup/authentication routes through one credentialed API client; authentication remains in the HttpOnly server session cookie and is restored through /auth/me. User management remains unimplemented.

Browser E2E

Run the A5 journey with uv run python scripts/check.py e2e (or make test-e2e where GNU Make is available). The supervisor creates a unique temporary SQLite database, migrates it with Alembic before starting services, selects dynamic 127.0.0.1 API and Vite ports, aligns the exact browser Origin and Vite proxy, waits with bounded HTTP readiness checks, and owns the API, Vite, Playwright, and Chromium process trees. The journey uses no MSW or external service and covers setup, logout, login, reload session restoration, and protected-route redirect after final logout.

Since Stage C the same single journey also drives the durable execution engine end to end: it observes an accepted Run queued before any Worker may claim it, a pre-start Worker loss recovered exactly once, a scripted rate limit retried after its due instant, an owner cancelling genuinely in-flight work, and the resulting execution timeline rendered in the browser row by row and rebuilt identically after a reload. It never contacts a real provider.

check deliberately remains E2E-free, because routine work must never require Chromium; full local verification is check then e2e, and CI runs both. Failure traces and screenshots are ignored under Playwright output paths. If Chromium is missing, rerun the documented Chromium-only provisioning command above. API/Vite early-exit and port-handoff diagnostics are written through the supervisor's bounded logs; do not substitute localhost for its 127.0.0.1 test Origin.

Continuous integration and security scanning

.github/workflows/ci.yml runs on pull requests, pushes to main, and manually. It has three jobs, each invoking repository-owned commands only:

  • check — frozen dependencies via bootstrap.py --skip-browser, then scripts/check.py check. No browser, no spawned services.
  • e2e — full bootstrap including Chromium, the CI-only Playwright system libraries, then scripts/check.py e2e.
  • marketplace-integration — frozen dependencies and disposable PostgreSQL 18/SeaweedFS services, then scripts/check.py marketplace-integration.

.github/workflows/security.yml runs the repository-owned tracked-file scanner on pull requests, pushes to main, and a weekly schedule. It needs no project dependencies because the scanner is standard-library only.

Both workflows declare permissions: contents: read, reference no secrets, use pull_request rather than pull_request_target, and pin every action to a verified full-length commit SHA. No live AI provider or cloud credentials are required. Marketplace integration uses disposable local PostgreSQL and S3-compatible services. See continuous integration for the pinning policy, cache strategy, and scanner rules.

Workspace boundaries

Python uv workspace members:

  • apps/api
  • apps/cli
  • apps/marketplace
  • apps/scheduler
  • apps/worker
  • packages/nervos-core
  • packages/nervos-mcp
  • packages/nervos-models
  • packages/nervos-sdk
  • packages/nervos-package-host

pnpm workspace members:

  • apps/web

apps/worker is the active Stage C execution plane: a real process entrypoint that owns no HTTP surface, never runs Alembic, and holds provider credentials exclusively. It durably registers its process incarnation, heartbeats that registration, reconciles expired Job claims, claims queued Jobs, renews leases, executes the immutable Run snapshot, and terminalizes Attempt, Job, and Run. packages/nervos-sdk supplies the public package Agent contract and packages/nervos-mcp implements the mediated MCP integration. The separate hosted read-only Marketplace service is implemented and externally accepted in I1; see its development guide. Local Marketplace integration remains future work under Stage I and ADRs 0027–0030. packages/nervos-core holds the domain/application logic and packages/nervos-models holds the concrete model-provider adapters, canonical anthropic, openai, and gemini (Google Gemini Developer API).

Configuration and security

A2 reads NERVOS_ENVIRONMENT, NERVOS_DATABASE_PATH, NERVOS_APP_ORIGIN, and NERVOS_LOG_LEVEL from the process environment. It does not automatically load .env.example or any real .env file. See configuration and database foundation. Real environment files, local databases, generated output, credentials, and local tool state must remain untracked.

Production requires HTTPS: the session cookie is Secure whenever production mode or an HTTPS NERVOS_APP_ORIGIN is configured, and it is always HttpOnly. Initialize NervOS while it is bound to loopback or otherwise reachable only through a trusted interface. The process-local Argon2 work bound returns a recoverable 429 under saturation but is not a substitute for rate limiting — any deployment exposed beyond loopback must enforce its own reverse-proxy or network rate limits. See authentication and sessions.

License

License selection is pending an owner decision. The empty LICENSE placeholder is not a grant of permission or a statement of redistribution terms.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages