Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.svantic.com/llms.txt

Use this file to discover all available pages before exploring further.

Agent Connectivity

Every dispatch the mesh sends must reach your agent. Svantic supports two connectivity modes that you pick per-instance at registration time:
  • Connected (default) — your agent dials Svantic over a persistent WebSocket and the mesh pushes dispatches down that socket. Works anywhere outbound HTTPS/WSS works — behind firewalls, NATs, corporate egress-only networks, laptops, CI runners, or ephemeral containers without stable DNS. This is the default because it is table stakes for a great out-of-the-box experience.
  • Hosted — your agent exposes a public HTTPS surface the mesh calls into. Opt in when your agent already runs as an HTTP service on infrastructure that can accept inbound traffic and you want a pure request/response shape.
You choose once, per instance_id. Deployment mode is not a deploy-time topology concern (see Deployment Models for that) — it’s a statement about how the mesh reaches this particular instance. Two instances of the same agent type can use different modes.

Connected mode (default)

Connected mode: agent dials Svantic via WebSocket, dispatches pushed bidirectionally How it works. Connected mode is the default — you get it by calling new MeshConnector(agent, { svantic_url, client_id, client_secret }) with no deployment_mode set and no public_url. The edge routes the single svantic_url to the gateway for registration and to the mesh for dispatch — you never hardcode service-specific hosts. The gateway registration response carries back a connect_url; the SDK dials it immediately and keeps the WebSocket open for the agent’s lifetime. The mesh pushes dispatch frames down the socket; your agent pushes dispatch_result frames back. Full protocol details live in WebSocket API: agents/connect. When it’s right (almost always).
  • The agent runs behind a firewall, NAT, or a corporate proxy with no inbound exception.
  • The agent runs on a developer laptop, a CI runner, an ephemeral container, or any host without a stable DNS entry.
  • You want zero inbound exposure — outbound-only is a compliance win.
  • You want the easiest onboarding path: no ingress, no TLS cert, no reverse proxy.
What it costs.
  • One WebSocket per live instance. Idle connections still cost a pod-local file descriptor; plan capacity like you would SSE.
  • Reconnect semantics are the SDK’s responsibility. The SDK handles it automatically (bounded backoff, resume cursor, outbox replay) — your handler code is oblivious — but long-term disconnects will surface as AgentDisconnectedError on the caller.
  • The WebSocket JWT authenticates the transport (who opened the socket). Per-invocation authentication still flows through the dispatch_auth envelope; see Dispatch auth below.

Hosted mode

Hosted mode: Svantic sends HTTPS dispatch to agent, agent returns response How it works. Opt in by passing a public_url at registration (or setting deployment_mode: hosted explicitly). The gateway probes GET {public_url}/.well-known/agent-card.json to confirm the agent is reachable and publishing a valid card, then admits the instance. Every subsequent dispatch is an HTTPS POST from the mesh to {public_url}/send, authenticated per the dispatch_auth block you chose. When to pick it.
  • Your agent already runs as a long-lived HTTP service on infrastructure that accepts inbound traffic and you don’t want to hold a socket open.
  • You have an existing ingress, LB, or API gateway you want to reuse.
  • You prefer the simplest request/response mental model and control the infra on both sides.
Requirements.
  • Publicly reachable HTTPS URL (ingress through your own LB or API gateway is fine).
  • /.well-known/agent-card.json served at the root of that URL.
  • TLS terminated by you. The mesh will not call http:// endpoints.
Dispatch authentication. See the Dispatch auth section below — the same model applies to hosted and connected agents.

Dispatch auth

Regardless of transport, every dispatch carries a per-invocation authentication envelope when the mesh runs with SVANTIC_DISPATCH_AUTH_ENABLED=true. Three schemes:
  • svantic_jwt (default) — the mesh mints a short-lived HS256 JWT against its SIGNING_SECRET and the SDK verifies with the same secret. No per-agent credential management; rotating the secret rotates every agent.
  • shared_secret — you supply a raw secret at registration time under a vault:// reference. The mesh stores it encrypted, resolves it at dispatch time, and attaches it to the envelope; the SDK compares against its local copy. Use this when the agent must prove possession of an account-minted secret.
  • mtls — reserved, not implemented.
The envelope is fail-closed: if resolution fails (signing secret missing, vault unreachable, stale credentials_ref), the dispatch fails with AgentUnhealthyError and no frame reaches the agent. See Registering Agents — Dispatch Auth for the step-by-step setup and Mesh Security — Dispatch Auth for the security rationale.

Strict control plane / data plane split

Regardless of mode, these operations are always plain HTTPS calls to the gateway, never WebSocket:
  • POST /agents/register, POST /agents/deregister
  • POST /sessions/init
  • File uploads, knowledge ingestion, credential rotation
  • Any administrative action visible in the dashboard
The WebSocket carries only real-time messaging: dispatches, streaming chunks, status updates, heartbeats. This is a deliberate split so that the control plane remains inspectable, auditable, and version-skew tolerant — and so a dropped socket never loses control state.

Choosing a mode: quick guide

You have…Pick
A public HTTPS servicehosted
Corporate firewall, egress-only allowedconnected
Ephemeral containers (Fly, Vercel CI)connected
Kubernetes pod with Ingresshosted
Developer laptop for demosconnected
Agent that must be callable from outside Svantichosted
You can migrate an existing agent-type from one mode to another by registering a new instance_id with the target mode and draining traffic off the old one. Svantic rejects an in-place mode switch on the same instance_id with 409 DEPLOYMENT_MODE_MISMATCH.

Observability

Both modes populate the same last_dispatch_error snapshot on the instance detail — same status codes, same error taxonomy — so dashboards and alerts work uniformly regardless of transport. Trace context (W3C traceparent, baggage) also propagates identically: the SDK parses it off the dispatch payload and exposes it on CapabilitySessionContext whether the dispatch arrived via HTTPS or WebSocket.

Connection-state endpoints

The gateway exposes two read endpoints for live transport state:
  • POST /agents/get_connection — returns a unified envelope for one instance_id. Shape is identical for hosted and connected agents: the consumer switches on transport (callback vs. ws) and connection_status (online / healthy / degraded / offline / unknown).
  • POST /agents/get_connection_stats — returns fleet-wide aggregates grouped by deployment_mode, connection_status, and transport. Optional agent_type filter.
The dashboard uses these endpoints to display agent health panels.

Events

The mesh emits transport-lifecycle events in real time so dashboards update without polling:
  • agent.connected — WebSocket upgrade accepted.
  • agent.disconnected — WebSocket closed.
Time-based transitions (stale heartbeat → unhealthy) remain the reaper’s job. See Agent Health for the full split and the status value catalog.

Metrics

Every mesh pod exposes GET /metrics in Prometheus exposition format with per-transport dispatch counters, WebSocket-connection gauges, inter-pod routing latency, and event-loop lag. Per-instance state is deliberately not labeled on /metrics — use the connection endpoints above for that. See the API documentation for the full metrics schema.

See also