NeoGraph 0.10.0
A C++17 Graph Agent Engine Library — LangGraph for C++
Loading...
Searching...
No Matches
neograph::acp::ACPServer Class Reference

HTTP-less, stdio-first ACP server hosting a NeoGraph engine. More...

#include <server.h>

Public Types

using NotificationSink = std::function< void(const neograph::json &)>
 Sink for agent→client notifications (session/update).
 

Public Member Functions

 ACPServer (std::shared_ptr< neograph::graph::GraphEngine > engine, neograph::json info, std::shared_ptr< ACPGraphAdapter > adapter={})
 
void attach_client (std::shared_ptr< ACPClient > c)
 Install a pre-constructed client and bind it to this server.
 
neograph::json call_client (std::string method, neograph::json params, std::chrono::milliseconds timeout=std::chrono::seconds(30))
 Issue a JSON-RPC request to the connected client and block until a response arrives.
 
AgentCapabilitiescapabilities ()
 Mutable access to the capabilities advertised in initialize.
 
std::shared_ptr< ACPClientclient ()
 Handle for issuing agent→client requests (fs/*, etc.).
 
neograph::json handle_message (const neograph::json &envelope)
 Process exactly one parsed JSON-RPC envelope.
 
bool initialized () const
 True after at least one initialize has been processed.
 
bool is_running () const
 True while run() is actively reading from its input stream.
 
void run ()
 Convenience overload — uses std::cin / std::cout.
 
void run (std::istream &in, std::ostream &out)
 Drive the server loop reading newline-delimited JSON-RPC envelopes from in and writing them to out.
 
void set_notification_sink (NotificationSink sink)
 Where session/update notifications go.
 
void stop ()
 Signal a running run() loop to exit at the next message boundary.
 

Detailed Description

HTTP-less, stdio-first ACP server hosting a NeoGraph engine.

Lifecycle:

ACPServer server(engine, info); server.run(); // blocks: reads std::cin, writes std::cout

The single-shot handle_message form is provided for testing and for embedding inside a custom transport (HTTP, WebSocket, in-process pipe). It takes one parsed JSON-RPC envelope and returns the response envelope (or a null json for notifications); side-effect notifications (session/update) are delivered through the NotificationSink set on the server.

Definition at line 185 of file server.h.

Member Typedef Documentation

◆ NotificationSink

using neograph::acp::ACPServer::NotificationSink = std::function<void(const neograph::json&)>

Sink for agent→client notifications (session/update).

Receives the fully-formed JSON-RPC envelope ready to be written to the transport.

Definition at line 190 of file server.h.

Constructor & Destructor Documentation

◆ ACPServer()

neograph::acp::ACPServer::ACPServer ( std::shared_ptr< neograph::graph::GraphEngine engine,
neograph::json  info,
std::shared_ptr< ACPGraphAdapter adapter = {} 
)
Parameters
engineThe graph engine that handles incoming prompts.
infoFree-form agent_info bag returned in initialize. Typically {"name":"my-agent","version":"0.1.0"}.
adapterOptional input/output mapping override.

Member Function Documentation

◆ attach_client()

void neograph::acp::ACPServer::attach_client ( std::shared_ptr< ACPClient c)

Install a pre-constructed client and bind it to this server.

Useful when the engine's nodes captured a client at compile() time before the server existed: pass that same shared_ptr here to make it usable. Replaces any previously cached client.

◆ call_client()

neograph::json neograph::acp::ACPServer::call_client ( std::string  method,
neograph::json  params,
std::chrono::milliseconds  timeout = std::chrono::seconds(30) 
)

Issue a JSON-RPC request to the connected client and block until a response arrives.

Used internally by ACPClient; exposed publicly so user code can issue protocol extensions (e.g. session/request_permission once that surface is added). Throws on transport not yet connected, on error envelope, and on timeout.

◆ capabilities()

AgentCapabilities & neograph::acp::ACPServer::capabilities ( )

Mutable access to the capabilities advertised in initialize.

Defaults: load_session=false, no prompt extras, no MCP transports (stdio is required by spec — its presence is implicit).

◆ client()

std::shared_ptr< ACPClient > neograph::acp::ACPServer::client ( )

Handle for issuing agent→client requests (fs/*, etc.).

On first call lazily creates a client bound to this server and caches it. Subsequent calls return the same instance. Nodes in the graph capture this handle to talk back to the editor.

◆ handle_message()

neograph::json neograph::acp::ACPServer::handle_message ( const neograph::json &  envelope)

Process exactly one parsed JSON-RPC envelope.

Returns:

  • the response envelope for requests ({ "jsonrpc","id","result"|"error" })
  • a null json (no value) for notifications. Side-effect notifications go to the sink set via set_notification_sink.

◆ is_running()

bool neograph::acp::ACPServer::is_running ( ) const

True while run() is actively reading from its input stream.

Set on entry, cleared on exit. Mirrors neograph::a2a::A2AServer::is_running so a generic supervisor can poll either without protocol-specific casing.

◆ run()

void neograph::acp::ACPServer::run ( std::istream &  in,
std::ostream &  out 
)

Drive the server loop reading newline-delimited JSON-RPC envelopes from in and writing them to out.

Returns when in reaches EOF or stop() is called from another thread.

Lifecycle parallel with neograph::a2a::A2AServer: run() here is the synchronous read-loop equivalent of A2A's start() (also synchronous, blocks until shutdown). Neither server exposes a built-in async-spawn helper because the host embedder usually picks the threading model; spawn run() on a std::thread if you want it to run in the background.

◆ set_notification_sink()

void neograph::acp::ACPServer::set_notification_sink ( NotificationSink  sink)

Where session/update notifications go.

Default: dropped on the floor (test-friendly). When run() is driving, the sink is set to write to the output stream automatically.

◆ stop()

void neograph::acp::ACPServer::stop ( )

Signal a running run() loop to exit at the next message boundary.

Cancellation semantics: ACP session/cancel flips a flag that the server consults after engine->run() naturally returns — it does NOT preempt an in-flight graph turn. The session/prompt response will carry StopReason::Cancelled if the flag was set by the time the graph finished, but a long-running LLM call inside a node still completes in full. Wire cancel into your nodes (or set a tight max_steps on RunConfig) for shorter cancel latency.

Destructor semantics: ~ACPServer joins all in-flight session/prompt worker threads before returning. Each worker blocks until its engine->run() completes, so destroying the server during a 60-second LLM call blocks the destroying thread for the full duration. Drain or cancel before destruction if you need a bounded-latency teardown.


The documentation for this class was generated from the following file: