Architecture

Multi-agent coordination without an SDK


Velqua is a local-first LLM proxy with persistent memory. This post covers the Mesh coordination layer specifically: how multiple agents share context without an SDK or cloud dependency. See the project page →

For a while I was running Blackreach, a Claude Code session, and a couple other tools at the same time. None of them knew the others existed. Blackreach would finish a research task and everything it found died when the session closed. 847 inscriptions downloaded, all the metadata extracted, gone. The next coding session started completely blind. I was manually copying results from one context to another, like passing notes between people who aren't allowed in the same room.

I looked at the multi-agent frameworks. LangGraph, CrewAI, AutoGen. They all want to solve this, but they all want to own the infrastructure too. You rewrite your agents around their SDK, their abstractions, their way of thinking about the problem. If you want Claude Code alongside a custom Python agent alongside an Ollama session, you're mostly out of luck. And none of them run fully local. I didn't want to rewrite everything around someone else's abstractions. I wanted a layer that existing tools just pass through without knowing it's there.

How the proxy works

Velqua sits between any app and its LLM provider. It intercepts every API call, injects persistent memory into the context, and forwards the request. The app doesn't know Velqua is there. You change one port number and that's it.

# Before: agent calls provider directly
curl http://localhost:11434/api/chat   # Ollama

# After: change one port number
curl http://localhost:11435/api/chat   # Velqua → Ollama, memory injected

The Mesh layer extends this. Instead of injecting one agent's personal memory, it injects shared knowledge from a pool all agents read and write to. Blackreach finishes a task and writes its findings to the pool. The next agent to make a request gets those findings in its context automatically. It doesn't know Blackreach exists. It just knows what Blackreach found.

The memory model

Every conversation gets summarized and stored. Before each new request, Velqua retrieves the most relevant memories and injects them into the system prompt. The tricky part is relevance. Injecting everything would just pollute the context with noise. Velqua scores memories by recency, explicit tags, and semantic similarity to the current message. A research agent asking about Linear A sign frequency gets the Linear A history injected; a coding agent working on a Python module doesn't, because it isn't relevant. The summaries are intentionally compressed: persistent memory that's slightly lossy is more useful than perfect memory that disappears when the session closes.

Agent identity without config

The first problem was figuring out which agent is making each request without requiring any change in the agent itself. If you require agents to identify themselves, you've already broken the "zero code changes" goal. Velqua Mesh uses a detection chain: an optional X-Velqua-Agent header first, then the user-agent string, then the port number, then an anonymous ID from connection fingerprint. Most of the time the port number alone is enough. One port per agent is a convention, not a requirement.

The noteboard

Shared memory is passive by design. Agents write to it and others pick it up on their next request. The noteboard is more intentional: an agent can leave a structured note for a specific agent, or broadcast to whoever picks up the next task.

POST /mesh/notes
{
  "from": "blackreach",
  "to": "any",
  "content": "847 Linear A inscriptions downloaded to /data/linear_a/.
              HT 31 shows unusual sign clustering worth looking at.",
  "tags": ["research", "complete"]
}

The receiving agent doesn't poll. The next time it makes any LLM request, Velqua checks for pending notes addressed to it and injects them alongside the memory context. It just shows up with the information already there. Velqua already injects memory on every request, so the noteboard is just one more thing to inject. No new mechanism needed.


If this is useful for something you're building, reach out.