How the ACN Package Functions as Magnitude's Server-Side Daemon
The ACN (Agent Coordination Network) package implements Magnitude's long-running server-side daemon using Effect-TS and Bun, exposing an RPC boundary that coordinates AI sessions, model catalogs, and system resources through a composable, layer-based architecture.
The ACN package serves as the backbone of the Magnitude ecosystem, providing a robust, Bun-based daemon built on Effect-TS and @effect/platform-bun. Unlike traditional Node.js servers, this server-side daemon leverages functional programming patterns and dependency injection to manage complex stateful operations including inference hardware allocation, session lifecycle management, and file system interactions.
Core Architecture
The ACN daemon's architecture centers on Effect-TS Layers, which provide lazy construction, explicit scoping, and automatic disposal during shutdown. This design makes the daemon restartable and testable while keeping side effects explicit.
HTTP Server Bootstrap
The entry point for the daemon is packages/acn/src/serve.ts, which invokes launchAcnServer defined in packages/acn/src/server.ts. This function creates a BunHttpServer listening on ACN_PUBLIC_PORT (default 10,100), configures CORS handling, and establishes the health endpoint at /health. The server initialization wraps all services in a Scope that can be closed cleanly during shutdown.
RPC Boundary Implementation
The concrete API surface is implemented in packages/acn/src/boundary/acn.ts as AcnBoundaryLive. This layer maps incoming RPC calls to internal services, wrapping each method with error-logging helpers. It exposes operations for session management, model catalog queries, and system introspection through the AcnBoundary protocol defined in the @magnitudedev/acn-protocol package.
Service Layer Composition
All business logic is organized into discrete service layers composed via makeAcnServicesBase inside server.ts. This function merges:
ProviderModelCatalogLive– manages available AI modelsModelSlotControllerLive– handles inference hardware allocationSessionLifecycleLive– coordinates session creation and teardown- File system and storage layers for persistent state
Process Lifecycle Management
The AcnProcessHandlersLive layer registers process-level listeners for uncaughtException, unhandledRejection, and OS signals. When triggered, these handlers invoke AcnServiceLifecycle.beginStopping, ensuring all Effect-TS layers are properly disposed of before the process exits. This prevents resource leaks and ensures graceful termination of active inference sessions.
Observability and Introspection
The daemon exposes telemetry through TracingLayer and custom HTTP routes installed via installAcnIntrospectionRoutes. The packages/acn/src/identity.ts module generates unique daemon instance IDs and constructs health check responses, while packages/acn/src/tracing.ts configures OpenTelemetry integration for distributed tracing.
Daemon Bootstrapping Flow
The startup sequence follows a precise functional composition:
serve.tscallslaunchAcnServer({debug: false})with runtime configuration.launchAcnServerconstructs the layered environment by invokingmakeAcnServicesBase, which combines storage, provider, model, and session services.- HTTP Server instantiation creates the Bun server on the configured port with CORS middleware.
- RPC Wiring instantiates
AcnBoundaryLiveviaRpcServer.make, binding the boundary to the HTTP transport. - Process handlers attach via
AcnProcessHandlersLive, monitoring for fatal errors or SIGTERM/SIGINT signals. - Scope activation starts the server and returns a
Scopehandle for programmatic shutdown control.
Practical Implementation Examples
Starting the Daemon from Command Line
# From the repository root
bun run packages/acn/src/serve.ts
This executes the minimal entry point that launches launchAcnServer with default configuration (debug disabled, data directory inferred from the current working directory).
Programmatic Server Launch
import { launchAcnServer } from "@magnitudedev/acn";
import { BunContext } from "@effect/platform-bun";
import { Effect } from "effect";
const server = launchAcnServer({
debug: true,
port: 10100,
dataDir: "/tmp/magnitude-data",
});
// Provide the Bun context and run
Effect.provide(BunContext.layer)(server).runPromise();
The BunContext.layer is required for platform-specific effects like file system access and HTTP server creation.
Invoking ACN RPC Methods
import { AcnRpc, AcnBoundary } from "@magnitudedev/acn-protocol";
import { Effect } from "effect";
const client = AcnRpc.client(AcnBoundary);
// List all active sessions
const list = client.ListSessions({ includeArchived: false });
list.pipe(
Effect.tap((sessions) => console.log("Active sessions:", sessions)),
Effect.catchAll((err) => Effect.succeed(console.error("RPC error:", err)))
).runPromise();
The AcnRpc client communicates with the AcnBoundary implementation running in the daemon process.
Graceful Shutdown Handling
import { Scope, Exit } from "effect";
// Assuming serverScope is returned by launchAcnServer
Scope.close(serverScope, Exit.void).runPromise();
Closing the scope triggers the shutdown sequence, disposing of all service layers and terminating the HTTP server.
Key Implementation Files
-
packages/acn/src/server.ts– ContainslaunchAcnServer, the core bootstrapping logic, HTTP server configuration, and service layer composition viamakeAcnServicesBase. -
packages/acn/src/serve.ts– Minimal entry point that callslaunchAcnServerand executes it throughBunRuntime.runMain. -
packages/acn/src/boundary/acn.ts– ImplementsAcnBoundaryLive, the concrete RPC service that exposes ACN operations to clients. -
packages/acn/src/tracing.ts– Configures the OpenTelemetry tracing layer used for observability. -
packages/acn/src/identity.ts– Manages daemon instance identification and health response generation. -
packages/acn/src/version.ts– DefinesACN_VERSIONandACN_REVISIONconstants for API versioning.
Summary
- The ACN package implements Magnitude's server-side daemon as an Effect-TS application running on the Bun runtime, providing superior performance and type safety compared to traditional Node.js servers.
- The architecture uses composable Layers to manage dependencies, enabling lazy initialization and automatic resource cleanup during shutdown.
launchAcnServerinpackages/acn/src/server.tsorchestrates the entire bootstrap process, from HTTP server creation to RPC boundary wiring.- Graceful shutdown is guaranteed through
AcnProcessHandlersLive, which captures process signals and exceptions to trigger ordered service termination. - The RPC boundary (
AcnBoundaryLive) exposes a type-safe interface for clients to manage AI sessions, query model catalogs, and interact with the file system.
Frequently Asked Questions
What runtime does the ACN daemon use?
The ACN daemon runs exclusively on Bun using the @effect/platform-bun runtime. This choice enables high-performance HTTP handling and native TypeScript execution without transpilation, as implemented in packages/acn/src/serve.ts via BunRuntime.runMain.
How does the ACN package handle graceful shutdown?
The daemon registers process handlers through AcnProcessHandlersLive that listen for SIGTERM, SIGINT, uncaughtException, and unhandledRejection events. When triggered, these handlers invoke AcnServiceLifecycle.beginStopping, which closes the Effect-TS Scope and ensures all service layers are disposed of in reverse dependency order.
What is the default port for the ACN server?
By default, the ACN server listens on port 10,100 (defined by the ACN_PUBLIC_PORT constant). This can be overridden by passing a custom port option to launchAcnServer in packages/acn/src/server.ts.
How are services organized in the ACN architecture?
Services follow a layered architecture pattern from Effect-TS. Concrete implementations (suffix Live) such as ProviderModelCatalogLive and SessionLifecycleLive are composed into a base environment via makeAcnServicesBase. These layers are merged and provided to the RPC boundary, enabling dependency injection and testability without side effects.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →