If you run a multi-agent workload with Solon AI Harness, you've probably hit this: each agent talks to a model provider over HTTP, and you want all of those requests to carry the same User-Agent, go through the same proxy, or share a custom header. Before 4.0.5 you had to configure each agent individually — and if a new agent joined the team, you had to remember to configure it too.
Solon AI 4.0.5 (released 2026-08-11) closes that gap with a small but very useful feature: HTTP customization now propagates from the harness engine down to every model request, through the chain HarnessEngine → ReActAgent → ChatRequest.
The three layers
The feature is built on ModelOptionsAmend (the options base class in solon-ai-core, present since 3.8.4). It carries a Consumer<HttpUtils> hook that is applied right before the HTTP call to the model provider:
protected Consumer<HttpUtils> httpCustomize;
Three methods are involved:
-
httpCustomizeAdd(...)— append a hook; multiple hooks are chained withandThen -
httpCustomizeSet(...)— replace the hook -
httpCustomize()— read it back
The propagation happens because putAll() copies httpCustomize along with the rest of the options, and the agent internals forward it at each layer.
Engine-level: configure once, reach everywhere
At the top of the chain, HarnessEngine exposes the hook directly:
HarnessEngine engine = HarnessEngine.of()
.httpCustomizeAdd(http -> {
http.userAgent("my-company-ai/1.0");
http.timeout(60);
})
.build();
or, if you build the engine imperatively:
engine.addHttpCustomize(http -> http.proxy("127.0.0.1", 7890));
engine.setHttpCustomize(...); // replaces, doesn't append
Internally these delegate to HarnessOptions — an engine-level "generic HTTP hook", as the source comment puts it. There is also a per-agent override point at ChatOptions, which extends ModelOptionsAmend, so a specific agent can still fine-tune its own hook:
ChatOptions options = new ChatOptions()
.httpCustomizeAdd(http -> http.header("X-Tenant", "acme"));
The engine hook and the agent hook are combined — not replaced — so both apply to that agent's requests.
What actually gets applied
When AgentFactory builds a sub-agent, it injects the engine-level settings into the agent's model options:
builder.modelOptions(o -> {
if (engine.getCacheControl() != null) {
o.cacheControl(engine.getCacheControl());
}
o.httpCustomizeAdd(http -> {
if (Assert.isNotEmpty(engine.getUserAgent())) {
http.userAgent(engine.getUserAgent());
}
if (engine.getHttpProxy() != null) {
http.proxy(engine.getHttpProxy());
}
if (engine.getHttpCustomize() != null) {
engine.getHttpCustomize().accept(http);
}
});
});
Then, inside the agent runtime, the hook travels again: ReasonTask (the ReAct reasoning path) forwards the model options hook, SimpleAgent forwards its own, and finally ChatRequestDescDefault applies it at the moment of the HTTP call:
if (req.getOptions().httpCustomize() != null) {
req.getOptions().httpCustomize().accept(httpUtils);
}
That last line is where the hook finally touches the wire — once, for every request, from every agent in the harness.
A naming cleanup worth knowing
4.0.5 also deprecated one method: ChatOptions.httpCustomize(Consumer) is now marked @deprecated in favor of httpCustomizeAdd(...). The old name implied a setter but actually appended; the new name says what it does. Migration is a one-word rename.
A nice synergy with Solon 4.0.5
This lands in the same release cycle as Solon 4.0.5, which gave solon-net-httputils a default User-Agent (solon-http/<version>) and a global HttpConfiguration.setUserAgent(...) override. Between the two, HTTP-level hygiene for model calls is covered end to end: the framework's default UA for generic HTTP, and the AI layer's per-engine hook for model requests — both overridable in one place.
Also in 4.0.5
Beyond the headline feature, this release is mostly polish and fixes:
-
solon-ai-mcp— tolerate SSE messages without an event type -
solon-ai-dialect-openai— betteropenai-responsesdialect adaptation -
solon-ai-harness—TaskTalentgains amaxTaskslimit -
solon-ai-talent-web—CodeSearchTalentandWebsearchTalentadaptations -
solon-ai-talent-memory— improved prompts and search capability -
solon-ai-talent-cli— betterTerminalTalentprompts; fixed a Windows environment-variable mis-detection issue -
solon-ai-talent-mount—MountManageraddsdisallowSkills -
solon-ai-talent-gateway— fixed a potential infinite-recursion inOpenApiV2Resolver
Summary
If you run Solon AI Harness with multiple agents and ever wished the model requests could share one HTTP configuration, 4.0.5 is your release. Configure once at the engine, and the hook rides down through the ReAct agents to every ChatRequest — with per-agent composition when you need it.
Docs: https://solon.noear.org (Solon AI section) · Repo: https://github.com/opensolon/solon-ai
Top comments (0)