Back to Blog
Hermes & TheaNovember 6, 20266 min read

Two AIs. One conversation. Both directions.

Hermes runs on your machine. Thea runs on a server. Now either one can hand a thread to the other - and a missing API key no longer kills the turn.

next-vibe runs anywhere: on your laptop, on a VPS, on both at once. Connect two instances and they become one system. We call ours Hermes and Thea.

This release closes the loop: remote threads now run in both directions, and the instance without a provider key no longer blocks anything.

Meet the pair

Same codebase. Different jobs.

Local

Hermes

Runs on your own computer. Sits next to your files, your terminal and your coding agents. Your daily driver.
Cloud

Thea

Runs on a server. Always online, reachable from anywhere. Watches the platform and delegates work.

Each instance owns its own data and tasks. The connection relays events between them - nothing more, nothing less.

Threads now cross in both directions

Remote-folder and private threads execute on the other instance - from Thea to Hermes and from Hermes to Thea.

Put a thread in a remote folder and the instance on the other side runs the full AI turn: model, system prompt, tools. You keep writing where you are. The conversation mirrors back to you.

One turn, end to end

1

You write

A message in a remote thread on Hermes.

2

The connection relays it

Over one persistent WebSocket, or a direct HTTP call when the peer is publicly reachable.

3

Thea runs the loop

With her model, her prompt, her tools.

4

Tools go where they live

A tool that exists only on Hermes is called back on Hermes. The result returns to Thea's loop.

5

The turn lands on both sides

The finished conversation syncs back to your mirror.

No API key? The turn still finishes.

The instance that runs a turn needs the model provider's API key. Not every instance has one.

Before an instance takes over a turn, it checks for the provider key on its own node. Missing? It fails fast with a clear marker - it does not hang, and it does not half-write the thread.

The calling side recognises the marker, rolls back its relay bookkeeping and runs the loop itself. The remote's prompt and tools still apply; tool calls round-trip back over the connection.

Who runs the loop?

Remote has the keyThe remote runs the turn. Tools round-trip back.
Remote has no keyRemote fails fast. The caller runs the turn with the remote's prompt and tools.
Inference-provider modeThe provider instance runs the model. The caller needs no key.
Inference-provider mode needs no key at all. Use the connected instance as your model provider and your side never touches a provider key. The connection is the model pipe.

Under the hood

For the people who read the diff.

Transport is negotiated at connect time, never configured by hand. The target pings the initiator with an authenticated health check (5 seconds max). Reachable: direct HTTP. Behind NAT: the hidden side opens one outbound WebSocket and every relay multiplexes over it.

The connector reconnects with exponential backoff from 1 to 30 seconds and re-reads the connection on every retry. This release hardens that path.

The marker a keyless receiver sends back:

relay/receiver.ts
// relay/constants.ts
export const RELAY_RECEIVER_NO_PROVIDER_KEY =
  "[relay-receiver-no-provider-key]";

// receiver: no provider key on this node? fail fast, let the caller run it
if (ctx.mode === "relay" && data.model) {
  const missingKey = getMissingProviderKeyMessage(getChatModelById(data.model));
  if (missingKey !== null) {
    return fail({ /* ...marker + reason... */ });
  }
}

Also in this release

  • Stale-lead warning: a frame addressed to a lead this instance no longer knows is dropped with a warning instead of silently - re-authenticating the connection fixes it.
  • Database timestamps in UTC, pooled Postgres and PGlite alike, so default-stamped rows sort correctly across instances.
  • The stream writer seeds the thread id, so peers no longer drop events with an empty thread id.
  • Revival turns sync with the peer, so tool results backfilled in place reach the mirror.

Try it

Self-host an instance, then add the connection under Admin → Remote Connections. Only admins can create one; the other side gets its entry automatically.

Run your own Hermes.

Self-host next-vibe on your machine, connect it to a server, and let them share the work.

Back to Blog