API Reference
This page is generated by Documenter.jl from docstrings. It is only useful when the docs are rendered — the raw Markdown source contains only the @autodocs directive, not the actual symbols.
To view the rendered API reference locally:
julia --project=docs docs/make.jl
# then open docs/build/api/index.htmlThe exported surface includes:
- Server:
serve,serve_multi,serve_mcp,server_port,server_socket_path,AbstractServerHandle,MultiListenerServer,ServerState - Sessions:
SessionManager,get_or_create_named_session!,sweep_idle_sessions!,session_id,SessionState,SessionIdle,SessionRunning,SessionClosed - Transport:
AbstractTransport,JSONTransport,send!,receive - MCP adapter:
mcp_initialize_result,mcp_tools,mcp_call_tool,mcp_eval_request,mcp_ensure_default_session!,mcp_new_session_result,mcp_list_sessions_result,mcp_close_session_result,collect_reply_stream,reply_stream_to_mcp_result - Constants:
MCP_PROTOCOL_VERSION,MCP_DEFAULT_SESSION_NAME,MCP_EPHEMERAL_SESSION,DEFAULT_COLLECT_TIMEOUT_SECONDS,DEFAULT_CLOSE_GRACE_SECONDS,DEFAULT_MAX_REPR_BYTES,DEFAULT_MAX_MESSAGE_BYTES,OUTPUT_TRUNCATION_MARKER
REPLy.MAX_SESSION_HISTORY_SIZE — Constant
Maximum number of entries kept in each NamedSession's history vector.
REPLy.MAX_STDIN_BUFFER_SIZE — Constant
Maximum number of buffered stdin strings per session before back-pressure applies.
REPLy._interrupt_session_eval — Method
_interrupt_session_eval(session; interrupt_id=nothing) -> (interrupted, interrupted_id)Attempt to interrupt the running eval in session.
interrupt_id: if provided (non-nothing), only interrupt when the running eval's ID matches. If there is a mismatch (the targeted eval already finished), returns no-op success([], nothing).- Returns
(interrupted::Vector{String}, interrupted_id::Union{Int,Nothing})whereinterruptedcontainssession.nameon a real interrupt andinterrupted_idholds the eval ID that was interrupted (ornothingwhen no interrupt was sent).
REPLy._maybe_revise! — Method
_maybe_revise!()Call Main.Revise.revise() if Revise is loaded in Main and defines a callable revise function. Any error thrown by revise() is caught and logged with @warn — it must never abort the eval that follows.
The entire check-and-call is dispatched via Base.invokelatest so that Main.Revise bindings created after REPLy was compiled (including test mocks) are always visible regardless of the current world age.
REPLy._revise_if_present — Method
_revise_if_present()Inner implementation for the Revise hook: checks whether Main.Revise and Main.Revise.revise are defined in the current world age and, if so, calls revise().
This function is intended to be invoked via Base.invokelatest (see _maybe_revise!) so that it executes in the latest world — necessary when Revise (or a test mock) was loaded after the REPLy module was compiled.
Security: only calls revise() when Main.Revise is the authentic Revise package (verified via Base.loaded_modules). A shadow module eval'd into Main under the name Revise will not appear in Base.loaded_modules with the correct PkgId and is silently ignored.
REPLy._total_session_count_unlocked — Method
_total_session_count_unlocked(manager)Return total session count without acquiring the lock. Callers must hold manager.lock.
REPLy.begin_eval! — Method
begin_eval!(session, task)Atomically transition session from SessionIdle to SessionRunning, assign task, and update last_active_at. Throws ArgumentError if not in SessionIdle.
Prefer this over calling transition_session_state! and _set_eval_task! separately.
REPLy.clamp_history! — Function
clamp_history!(session, max_size=MAX_SESSION_HISTORY_SIZE)Drop the oldest entries from session.history so it does not exceed max_size. Called after each history push.
REPLy.clone_named_session! — Method
clone_named_session!(manager, source_id_or_name, dest_name)Create a new named session with the alias dest_name by copying the module bindings from the session identified by source_id_or_name (UUID or alias). The clone gets its own UUID and anonymous module so mutations in the clone do not affect the original.
Returns the new NamedSession, or nothing if source_id_or_name is not found.
Throws ArgumentError if dest_name alias already exists — callers must check or close the existing session first.
REPLy.collect_reply_stream — Method
Collect Reply messages for request_id until the terminal done status arrives.
Messages for other request ids are buffered into pending, allowing callers to safely reuse the same transport across interleaved request streams.
If no terminal message arrives within timeout_seconds, the transport is closed and a one-element collection containing a synthetic ["done", "timeout"] terminal message is returned. A positive timeout_seconds is required.
REPLy.create_ephemeral_session! — Method
create_ephemeral_session!(manager)Create and register a new ephemeral session backed by an anonymous module.
REPLy.create_ephemeral_session_if_within_limit! — Method
create_ephemeral_session_if_within_limit!(manager, max_sessions) -> Union{ModuleSession, Nothing}Atomically check the total session count against max_sessions and create a new ephemeral session if below the limit. Returns nothing when the limit is already reached. The check and creation occur under a single manager.lock acquisition, preventing the TOCTOU race that exists when they are separate.
REPLy.create_named_session! — Method
create_named_session!(manager, name; id=nothing)Create and register a persistent named session. The session is keyed by its UUID in named_sessions and will appear in list_named_sessions output. If name is non-empty it is also registered in name_to_uuid as an alias.
Throws ArgumentError if name is non-empty and an alias with that name already exists — callers must destroy the existing session first (via destroy_named_session!) before registering a new one under the same alias. This prevents detached session objects: a caller holding a reference to the old session would otherwise still be able to mutate it after replacement.
If a session with the same id already exists it is silently replaced.
Name and id validation is the caller's responsibility. An explicit id may be supplied (for testing); otherwise a fresh UUID is generated.
REPLy.create_named_session_if_within_limit! — Method
create_named_session_if_within_limit!(manager, name, max_sessions; id) -> Union{NamedSession, Nothing}Atomically check the total session count against max_sessions and create a new named session if below the limit. Returns nothing when the limit is reached. Throws ArgumentError if a non-empty name alias already exists.
REPLy.descriptor — Method
descriptor(mw::AbstractMiddleware) -> MiddlewareDescriptorReturn the MiddlewareDescriptor for mw. The default makes no claims. Override to declare what ops a middleware provides/requires.
REPLy.destroy_named_session! — Method
destroy_named_session!(manager, id_or_name) -> BoolRemove the named session identified by UUID or name alias. Returns true if a session was removed, false if no such session existed. This operation is idempotent — calling it when no such session exists is safe.
Close blocks until any in-flight eval on the session completes: eval_lock is acquired before the state transition so that end_eval! can never race against a SessionClosed transition. The manager lock is released between the resolve and the eval drain to avoid holding it during a potentially long eval.
REPLy.destroy_session! — Method
destroy_session!(manager, session)Remove session from manager. This operation is idempotent so cleanup code can call it safely from both success and error paths.
REPLy.dispatch_middleware — Method
dispatch_middleware(stack::Vector{<:AbstractMiddleware}, index::Int, msg, ctx::RequestContext)Recursively process msg through the middleware stack starting at index. Each middleware piece can choose to forward the message to the next piece in the chain or handle it immediately and return early. The final responses are typically accumulated in ctx.emitted or returned directly.
REPLy.end_eval! — Method
end_eval!(session)Atomically transition session from SessionRunning to SessionIdle, clear the eval task, and update last_active_at. Throws ArgumentError if not in SessionRunning.
Prefer this over calling transition_session_state! and _set_eval_task! separately.
REPLy.get_or_create_named_session! — Method
get_or_create_named_session!(manager, name) -> NamedSessionReturn the existing named session registered under the name alias name, or atomically create and register one if absent. The check-and-create is performed under a single manager.lock acquisition to prevent concurrent callers from each creating a session and silently replacing the other's work.
REPLy.list_named_sessions — Method
list_named_sessions(manager)Return all registered persistent named sessions. Ephemeral sessions are never included — this is the authoritative source for ls-sessions.
REPLy.lookup_named_session — Method
lookup_named_session(manager, id_or_name)Return the NamedSession registered under the given UUID or name alias, or nothing if no such session exists.
Resolution order:
- Try
id_or_nameas a UUID key innamed_sessions. - Try
id_or_nameas a name alias inname_to_uuid, then look up the UUID.
REPLy.mcp_call_tool — Method
mcp_call_tool(tool_name, args, manager; max_sessions=typemax(Int)) -> CallToolResultDispatch an MCP tools/call request to the appropriate adapter helper.
Routes session lifecycle tools (julia_new_session, julia_list_sessions, julia_close_session) to their respective lifecycle helpers. Returns a stub error for tools that are not yet implemented (julia_complete, julia_lookup, julia_load_file, julia_interrupt). Returns an error for julia_eval (which requires a live transport and is handled by the full adapter loop) and for unknown tool names.
max_sessions is forwarded to mcp_new_session_result to enforce the server session limit when creating sessions from the MCP adapter.
REPLy.mcp_close_session_result — Method
mcp_close_session_result(manager, session_name) -> CallToolResultClose the session identified by UUID or name alias and return a non-error CallToolResult. Returns an error result if the session does not exist. The existence check and removal are performed atomically via destroy_named_session!, which returns true only when it actually removed an entry.
REPLy.mcp_ensure_default_session! — Method
mcp_ensure_default_session!(manager; name=MCP_DEFAULT_SESSION_NAME) -> StringEnsure the adapter's persistent default session exists in manager. Creates it if absent; returns the canonical UUID of the session (whether newly created or already existing). The name alias is registered so the session can also be found by name, but the UUID is the canonical identity used for routing. Thread-safe: the check-and-create is performed atomically under a single lock acquisition via get_or_create_named_session!.
REPLy.mcp_eval_request — Method
Build a Reply eval request from MCP julia_eval arguments.
When session is omitted, the adapter routes to default_session. When session == "ephemeral", the Reply request omits the session field. This helper rejects invalid adapter inputs before emitting a Reply message.
REPLy.mcp_initialize_result — Method
Return the MCP initialize result advertised by the reference adapter helpers.
REPLy.mcp_list_sessions_result — Method
mcp_list_sessions_result(manager) -> CallToolResultList all named sessions in manager and return their canonical UUIDs (with optional name aliases) as a CallToolResult. Returns "[]" when no sessions exist. Each line is "<uuid>" for unnamed sessions or "<uuid> (<name>)" for sessions that have a name alias.
REPLy.mcp_new_session_result — Method
mcp_new_session_result(manager; max_sessions=typemax(Int)) -> CallToolResultCreate a new unnamed session and return its canonical UUID in a non-error CallToolResult. The UUID is the spec-compliant identity for all subsequent ops. Returns an error result when the session limit is reached.
REPLy.mcp_stub_result — Method
Return a standard MCP 'not yet implemented' error result for stub tools.
REPLy.mcp_tools — Method
Return the static MCP tool catalog exposed by the reference adapter.
REPLy.protocol_name — Method
Return the canonical protocol name for this package.
REPLy.read_bounded_line — Method
read_bounded_line(io, max_bytes) -> StringRead bytes from io up to the next newline (\n), returning the line content without the trailing newline. Throws MessageTooLargeError(max_bytes) if more than max_bytes bytes are read before a newline is found.
Unlike readline(), memory use is proportional to min(actual_bytes, max_bytes) rather than the full payload size.
REPLy.reply_stream_to_mcp_result — Method
Map a complete Reply response stream to an MCP CallToolResult.
Status precedence is timeout > interrupted > error > success so terminal non-success modes produce deterministic MCP output even when Reply status arrays contain multiple flags.
REPLy.resolve_module — Method
resolve_module(module_path) -> Module or nothingResolve a dotted module path (e.g. "Main.Foo.Bar") by walking the module hierarchy starting from Main. Returns nothing if any segment is missing or not a Module.
Limitation: only Main-rooted paths are supported. Modules created inside a named session's anonymous module cannot be addressed via this function.
REPLy.serve — Method
serve(; host=ip"127.0.0.1", port=5555, socket_path=nothing, manager=SessionManager(), middleware=default_middleware_stack(), limits=ResourceLimits(), max_message_bytes=DEFAULT_MAX_MESSAGE_BYTES)Start the REPLy JSON-RPC server. If socket_path is provided, a Unix domain socket server is created at that path. Otherwise, a TCP server is started on the given host and port.
Arguments
host: The IP address to listen on (default:127.0.0.1).port: The port to listen on (default:5555).socket_path: An optional path for a Unix domain socket server. Mutually exclusive withhost/port.manager: TheSessionManagerused to track state across sessions.middleware: A vector of middleware handlers to process incoming requests.limits: AResourceLimitsstruct with server-wide resource constraints (default:ResourceLimits()).max_message_bytes: Maximum allowed inbound message size in bytes. Requests exceeding this limit are rejected with a structured error response and the connection is closed (default:DEFAULT_MAX_MESSAGE_BYTES, 1 MiB).
Returns
A server handle (TCPServerHandle or UnixServerHandle) which can be closed with close(server).
REPLy.serve_mcp — Method
serve_mcp(; manager=SessionManager(), middleware=default_middleware_stack(), limits=ResourceLimits(), max_message_bytes=DEFAULT_MAX_MESSAGE_BYTES)Start a stdio-based MCP server. This function blocks, reading JSON-RPC 2.0 messages from stdin and writing responses to stdout.
It automatically:
- Starts a background REPLy TCP server on a random loopback port.
- Handles the MCP
initializeandtools/listhandshake. - Dispatches
tools/callrequests. - Routes
julia_evalto the background REPLy server. - Logs internal errors and diagnostic info to
stderr.
Use this as the entry point for integrating REPLy with MCP clients like Claude Desktop or VS Code extensions.
REPLy.serve_multi — Method
serve_multi(specs...; manager, middleware, limits, max_message_bytes)Start multiple listeners (TCP and/or Unix domain socket) that share one session namespace and one resource-limit domain.
Each spec is a named tuple with either:
(; port=N)or(; host=..., port=N)for a TCP listener(; socket_path="...")for a Unix domain socket listener
Returns a MultiListenerServer which can be closed with close(server).
REPLy.session_count — Method
session_count(manager)Return the number of registered ephemeral sessions. Named sessions are not counted here; use length(list_named_sessions(manager)) for those.
REPLy.session_created_at — Method
session_created_at(session)Return the Unix timestamp (seconds) at which the NamedSession was created.
REPLy.session_eval_count — Method
session_eval_count(session)Return the number of eval operations that have completed on session. Thread-safe.
REPLy.session_eval_id — Method
session_eval_id(session)Return the monotonic eval ID for the most recently started (or currently running) eval on session. Starts at 0 (no eval has started yet); increments at the start of each eval so the running eval always has a known, stable ID. Thread-safe.
REPLy.session_eval_task — Method
session_eval_task(session)Return the Task currently evaluating in session, or nothing if idle. Thread-safe.
REPLy.session_id — Method
session_id(session)Return the canonical UUID string that identifies a persistent NamedSession.
REPLy.session_last_active_at — Method
session_last_active_at(session)Return the Unix timestamp (seconds) of the most recent activity on session. Thread-safe.
REPLy.session_module — Method
session_module(session)Return the anonymous module that backs session.
REPLy.session_module — Method
session_module(session)Return the anonymous module that backs a NamedSession.
REPLy.session_module_name — Method
session_module_name(session)Return the module name for session. Always "<anonymous>" for light sessions, since they are backed by gensym'd anonymous modules.
REPLy.session_name — Method
session_name(session)Return the optional alias name for a persistent NamedSession. May be an empty string if no alias was provided at creation.
REPLy.session_state — Method
session_state(session)Return the current SessionState of a NamedSession. Thread-safe.
REPLy.sweep_idle_sessions! — Method
sweep_idle_sessions!(manager; max_idle_seconds) -> Vector{String}Destroy all SessionIdle named sessions whose last_active_at is more than max_idle_seconds seconds in the past. Running and closed sessions are skipped.
Returns the name alias of each removed session, or its UUID if the session had no alias, in the order they were swept.
Runs in three phases to avoid TOCTOU races:
- Snapshot session references under
manager.lock(no session locks held). - Check state under each
session.lockalone (manager is unblocked during this). - Re-acquire both locks per candidate; re-verify identity and state before destroying.
Phase 3 is necessary because a session can be recreated under the same name (invalidating identity) or transitioned to SessionRunning (invalidating state) between phases 1/2 and the actual destruction.
REPLy.total_session_count — Method
total_session_count(manager)Return the total number of active sessions: ephemeral + named. Used for max_sessions enforcement.
REPLy.transition_session_state! — Method
transition_session_state!(session, new_state)Transition session between SessionIdle and SessionRunning. Throws ArgumentError for any other edge, including transitions to/from SessionClosed (which is terminal and reachable only through destroy_named_session!) and self-transitions.
REPLy.try_begin_eval! — Method
try_begin_eval!(session, task) -> BoolAttempt to atomically transition session from SessionIdle to SessionRunning, assign task, and update last_active_at. Returns true on success.
Returns false (without throwing) if the session is in SessionClosed, making this safe to call after a concurrent destroy_named_session! without a separate closed-session check.
Throws ArgumentError for SessionRunning — callers must hold session.eval_lock to prevent double-acquisition, which is the only way this state can occur here.
REPLy.validate_session_name — Method
validate_session_name(name) -> Union{Nothing, String}Return nothing if name is a valid session name, or an error message string if not. Valid names are non-empty, non-whitespace-only, match [a-zA-Z0-9_-]+, and are at most MAX_SESSION_NAME_BYTES bytes.
REPLy.validate_stack — Method
validate_stack(stack) -> Vector{String}Validate a middleware stack and return a (possibly empty) list of error strings.
Checks:
- Duplicate provides: two or more middlewares claiming the same op name.
- Unsatisfied requires: a middleware requiring a name not provided by any earlier middleware.
Note: validate_stack is not called automatically by build_handler. Call it explicitly at server startup (or in tests) to verify a custom stack before use.
REPLy.version_string — Method
Return a human-readable package version string.
REPLy.with_session_eval — Method
with_session_eval(f, ctx, request_id)Shared lifecycle wrapper used by eval_responses and load_file_responses.
Creates an ephemeral session when ctx.session is nothing, resolves the active session, then dispatches based on type:
NamedSession: acquireseval_lock, guards withtry_begin_eval!(returning a "session was closed" error if the session was concurrently destroyed), runsf(session)under atry/finallythat callsend_eval!, then releases the lock.ModuleSession(ephemeral): callsf(session)directly without locking.
Destroys the ephemeral session in a finally block so cleanup is guaranteed on both success and error paths.
f receives the active session and must return a Vector{Dict{String,Any}}.
REPLy.AbstractServerHandle — Type
AbstractServerHandleAbstract supertype for single-listener server handles. Subtypes (TCPServerHandle, UnixServerHandle) must have fields: listener, accept_task, client_tasks, clients, clients_lock, handler, middleware, closing, state.
REPLy.AuditMiddleware — Type
AuditMiddleware(log; client_id, source_ip)Middleware that records every request to an AuditLog. Place it first in the stack so all operations (eval, session ops, describe, etc.) are captured.
client_id and source_ip are per-connection identifiers; they default to a nil UUID and an empty string. Pass them explicitly when per-connection identity is available (e.g. from the transport layer).
REPLy.CallToolResult — Type
Type alias for the MCP CallToolResult dict shape returned by adapter helpers.
REPLy.CompleteMiddleware — Type
CompleteMiddlewareMiddleware that handles op == "complete" requests. Uses Julia's built-in REPL completion engine to return candidates at the given cursor position. Out-of-range positions return an empty completions array rather than an error. All other ops are forwarded to the next middleware.
REPLy.DescribeMiddleware — Type
DescribeMiddleware(ops_catalog)Middleware that handles op == "describe" requests. Returns a single terminal response containing the ops catalog (built dynamically from middleware descriptors by build_handler), Julia and Reply versions, and encoding support. All other ops are forwarded to the next middleware.
Construct with no arguments for an empty catalog (useful in unit tests that only check top-level fields, versions, or forwarding). Use build_handler() to get a fully populated catalog derived from the active middleware stack.
REPLy.EvalMiddleware — Type
EvalMiddleware(; max_repr_bytes=DEFAULT_MAX_REPR_BYTES)Middleware that handles op == "eval" requests. Executes Julia code in the active session module with captured stdout/stderr, truncates the repr of the return value at max_repr_bytes, and returns a sequence of response messages (out, err, value, done). Passes all other ops to the next middleware.
Named sessions are serialized per session via session.eval_lock (FIFO within a session; independent across sessions). Ephemeral sessions have no cross-request state and need no serialization.
REPLy.HandlerContext — Type
HandlerContext(manager::SessionManager)Context shared across the entire lifespan of a connection or server handler. Contains the SessionManager that tracks all active sessions.
REPLy.InterruptMiddleware — Type
InterruptMiddlewareMiddleware that handles op == "interrupt" requests. Looks up the named session specified by the session field, throws InterruptException to the eval task if one is running, and returns an interrupted array in the response.
- Running eval:
interruptedcontains the session name; the eval task receivesInterruptExceptionand will terminate withstatus:["done","interrupted"]. - Idle or already-completed session:
interruptedis empty (idempotent).
All other ops are forwarded to the next middleware.
REPLy.LoadFileMiddleware — Type
LoadFileMiddleware(; load_file_allowlist=nothing)Middleware that handles op == "load-file" requests. Reads file from disk and evaluates its content in the active session module using Base.include_string so that stack traces reference the source file path and line numbers.
load_file_allowlist must be a function (path::String) -> Bool that returns true for permitted paths. When not provided, all file load requests are denied by default — pass load_file_allowlist = _ -> true to allow all files (insecure). Returning false causes the request to fail with a path-not-allowed error before any file I/O occurs, preventing path enumeration.
All other ops are forwarded to the next middleware.
REPLy.LookupMiddleware — Type
LookupMiddlewareMiddleware that handles op == "lookup" requests. Resolves the symbol field in the optional module context (defaulting to the session module or Main), returns documentation and method signatures when found, and returns "found" => false when the symbol does not exist. All other ops are forwarded.
REPLy.MiddlewareDescriptor — Type
MiddlewareDescriptor(; provides, requires, expects, op_info)Metadata describing a middleware's interface contract used for startup validation and dynamic describe responses.
provides::Set{String}— operation names (e.g."eval") this middleware handles.requires::Set{String}— names that must be provided by some earlier middleware in the stack.expects::Vector{String}— human-readable ordering constraints (informational; not enforced byvalidate_stack).op_info::Dict{String, Dict{String, Any}}— per-op metadata (doc, requires, optional, returns) used to build describe responses dynamically.
REPLy.ModuleSession — Type
ModuleSessionEphemeral REPL session backed by an anonymous Julia Module.
REPLy.RequestContext — Type
RequestContext(manager, emitted, session, server_state)Context associated with a single incoming request. Tracks the manager, the list of emitted responses generated so far, the session active for the request (if any), and the server_state (shared server-wide limits and counters). server_state is nothing when build_handler is called without a state argument (e.g. in unit tests that don't need limit enforcement).
REPLy.ResourceLimits — Type
ResourceLimits(; max_repr_bytes, max_eval_time_ms, max_output_bytes, max_session_history, max_sessions, max_concurrent_evals, rate_limit_per_min, max_connections, revise_hook_enabled)Immutable configuration struct for resource limits applied to eval requests and sessions.
Fields:
max_repr_bytes::Int— maximum byte length forreproutput (default:DEFAULT_MAX_REPR_BYTES, 10 KB). Active: used byEvalMiddleware.max_eval_time_ms::Int— maximum wall-clock eval time in milliseconds (default: 30 000). Enforced byEvalMiddleware(Phase 7C).max_output_bytes::Int— maximum captured stdout/stderr bytes per eval (default: 1 000 000). Enforced byEvalMiddleware(truncates stdout and stderr independently).max_session_history::Int— maximum entries in a named session's history vector (default:MAX_SESSION_HISTORY_SIZE, 1000). Enforced by_update_history!viaclamp_history!.max_sessions::Int— maximum total active sessions (named + ephemeral) allowed at one time (default: 100). Enforced bySessionMiddlewareandSessionOpsMiddleware.max_concurrent_evals::Int— maximum number of eval operations that may run concurrently server-wide (default: 10). Enforced byEvalMiddleware.rate_limit_per_min::Int— maximum number of requests a single connection may send per 60-second sliding window (default: 600). Enforced by the transport layer (Phase 7B).max_connections::Int— maximum number of simultaneous TCP/Unix connections (default: 100). When the limit is reached, new connections are immediately closed.revise_hook_enabled::Bool— whentrue(default),EvalMiddlewarecallsMain.Revise.revise()before each named-session eval ifReviseis loaded inMain. Set tofalseto disable the hook entirely.
REPLy.ServerState — Type
ServerStateShared mutable state that lives at the server level (above any individual connection). Holds the configured ResourceLimits and runtime counters that span all client sessions.
limits::ResourceLimits— resource limits configured atserve()time.max_message_bytes::Int— maximum inbound message size (bytes).active_evals::Threads.Atomic{Int}— number of eval operations currently in flight server-wide.
REPLy.ServerState — Method
ServerState(limits, max_message_bytes) -> ServerStateConstruct a ServerState with all counters initialised to zero.
REPLy.SessionLimitReachedError — Type
SessionLimitReachedError()Thrown by clone_named_session! when the session limit is reached inside a lock, so callers can distinguish a limit hit from a missing source session without changing the function's return type.
REPLy.SessionManager — Type
SessionManagerTrack ephemeral ModuleSessions and persistent NamedSessions separately.
ephemeral_sessions— short-lived sessions created per eval request;session_countreflects this vector for leak detection.named_sessions— persistent sessions keyed by UUID; the only sessions that appear inls-sessionsoutput.name_to_uuid— optional alias-to-UUID index; allows callers to look up sessions by human-readable name in addition to canonical UUID.
The invariant that ephemeral sessions never appear in list_named_sessions is enforced by keeping the two registries strictly separate.
REPLy.SessionOpsMiddleware — Type
SessionOpsMiddlewareHandle session management operations: new-session, ls-sessions, close-session/close, and clone-session/clone. These ops manipulate the named-session registry directly and never delegate to downstream middleware.
The canonical op names (per OpenSpec protocol) are "close" and "clone". The hyphenated forms "close-session" and "clone-session" are deprecated aliases kept for backward compatibility — they emit a deprecation warning when used.
This middleware must appear after SessionMiddleware in the stack so that requests carrying a "session" key for named-session routing are resolved first, and before UnknownOpMiddleware so these ops are not rejected.
REPLy.SessionState — Type
SessionStateLifecycle state of a NamedSession. Valid transitions via transition_session_state!:
SessionIdle→SessionRunning(eval starts)SessionRunning→SessionIdle(eval completes or errors)
SessionClosed is a terminal state reached only through destroy_named_session!. No transition out of SessionClosed is possible.
REPLy.StdinMiddleware — Type
StdinMiddlewareMiddleware that handles op == "stdin" requests. Puts input text into the named session's stdin_channel, where a per-eval feeder task picks it up and writes it to the eval's redirected stdin pipe.
- Running eval (SessionRunning):
deliveredcontains the session name. - Idle session (SessionIdle):
bufferedcontains the session name; input waits in the channel for the next eval's feeder to consume. - Closed or unknown session: returns an error response.
All other ops are forwarded to the next middleware.