fix: default Hermes model from /v1/models and retry chat completions without client tools on HTTP 400 (v2.0.2)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Wn5VX9HNbJ7N54hR24u9Y
This commit is contained in:
Claude committed 2026-09-03 15:40:21 +00:00
1 parent b5357c5abd
commit 2a471e11a4
3 files changed
+19 -5

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "eveflow",
"version": "2.0.1",
"version": "2.0.2",
"description": "JARVIS-style desktop HUD for Hermes Agent: voice, streaming runs, scheduled jobs, skills and telemetry",
"main": "dist-electron/main.js",
"private": true,
+12 -3
View File
@@ -397,9 +397,10 @@ export class HermesClient {
});
let fullText = '';
let toolsAllowed = useTools;
for (let iteration = 0; iteration < 6 && !aborted; iteration++) {
const payload: Rec = { model: this.config.model || 'hermes-agent', messages, stream: true };
if (useTools) {
if (toolsAllowed) {
payload.tools = options.localToolDefinitions;
payload.tool_choice = 'auto';
}
@@ -435,7 +436,15 @@ export class HermesClient {
currentHandle = handle;
if (!handle.start.ok) {
await handle.done.catch(() => undefined);
throw new HttpError(handle.start.status, errorMessage(handle.start.status, errorChunks.join('')));
const detail = errorMessage(handle.start.status, errorChunks.join(''));
// Some Hermes builds reject client-side tool definitions: retry once without them.
if (toolsAllowed && handle.start.status === 400 && iteration === 0) {
Log.warn('hermes', `chat completions rejected the tools payload (${detail}); retrying without local tools`);
toolsAllowed = false;
iteration--;
continue;
}
throw new HttpError(handle.start.status, detail);
}
ready = true;
const rotated = handle.start.headers['x-hermes-session-id'];
@@ -445,7 +454,7 @@ export class HermesClient {
parser.end();
fullText += iterationText;
if (finishReason === 'tool_calls' && useTools && toolCalls.size > 0 && !aborted) {
if (finishReason === 'tool_calls' && toolsAllowed && toolCalls.size > 0 && !aborted) {
const calls = [...toolCalls.values()];
messages.push({
role: 'assistant',
+6 -1
View File
@@ -91,7 +91,12 @@ export const useHermes = create<HermesStore>((set, get) => ({
webhook: null,
busy: false,
client: () => new HermesClient(useSettings.getState().settings.hermes),
client: () => {
const config = useSettings.getState().settings.hermes;
// Without an explicit model, use the alias advertised by /v1/models (Hermes rejects unknown names).
const model = config.model.trim() || get().models[0]?.id || '';
return new HermesClient({ ...config, model });
},
connect: async () => {
const config = useSettings.getState().settings.hermes;