fix: wire modelAliases fetch into HermesAgentToolCard (#7151) (#7195)

This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-07-14 21:21:52 -03:00
committed by GitHub
parent 17de0913de
commit 3a92236d7a
3 changed files with 63 additions and 0 deletions

View File

@@ -0,0 +1 @@
- fix(dashboard): wire modelAliases fetch into HermesAgentToolCard so OpenRouter and other passthrough providers appear in the Hermes Agent role picker (#7151)

View File

@@ -47,6 +47,10 @@ export default function HermesAgentToolCard({
const [previewYaml, setPreviewYaml] = useState<string | null>(null);
const [isPreviewLoading, setIsPreviewLoading] = useState(false);
const [firstSetupAt, setFirstSetupAt] = useState<string | null>(null);
// Model aliases drive the passthrough provider groups (OpenRouter, Requesty,
// DGrid, AgentRouter, Charm Hyper, ...) in ModelSelectModal — without them,
// those providers never surface in the Hermes Agent role picker (#7151).
const [modelAliases, setModelAliases] = useState({});
// Track whether we have already seeded from batchStatus on this expand
const seededFromBatchRef = useRef(false);
@@ -109,8 +113,19 @@ export default function HermesAgentToolCard({
});
}
loadCurrentConfig();
fetchModelAliases();
}, [isExpanded, batchStatus, loadCurrentConfig]);
const fetchModelAliases = async () => {
try {
const res = await fetch("/api/models/alias");
const data = await res.json();
if (res.ok) setModelAliases(data.aliases || {});
} catch (error) {
console.warn("Error fetching model aliases:", error);
}
};
const setRoleSelection = (roleId: string, model: string, provider = "OmniRoute") => {
setSelections((prev) => ({ ...prev, [roleId]: { model, provider } }));
};
@@ -522,6 +537,7 @@ export default function HermesAgentToolCard({
showCombos={true}
activeProviders={activeProviders}
alwaysIncludeProviders={HERMES_AGENT_ZERO_CONFIG_PROVIDERS}
modelAliases={modelAliases}
/>
</Card>
);

View File

@@ -0,0 +1,46 @@
import { describe, expect, it } from "vitest";
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname, resolve } from "node:path";
// Regression probe for issue #7151: OpenRouter (and every other
// `passthroughModels` provider — requesty, dgrid, agentrouter, charm-hyper,
// etc.) never appears in the Hermes Agent role model picker.
//
// Root cause: <ModelSelectModal> derives a passthrough provider's model list
// from the `modelAliases` prop (ModelSelectModal.tsx groupedModels →
// buildPassthroughAliasModels(modelAliases, providerId)). When `modelAliases`
// is `{}` (the component default), that helper returns `[]` and the provider
// group is skipped entirely — see modelSelectModalHelpers.ts. Every sibling
// CLI tool card (Codex, Claude, Cline, Kilo, Droid, OpenClaw, Antigravity)
// fetches `/api/models/alias` and passes the result through, but
// HermesAgentToolCard never does, so OpenRouter's managed-available-model
// aliases (synced automatically after the connection is tested — see
// syncManagedAvailableModelAliases in src/lib/providerModels/managedAvailableModels.ts)
// are invisible to it.
const __dirname = dirname(fileURLToPath(import.meta.url));
const CARD_PATH = resolve(
__dirname,
"../../../src/app/(dashboard)/dashboard/cli-code/components/HermesAgentToolCard.tsx"
);
describe("HermesAgentToolCard model alias wiring (#7151)", () => {
const source = readFileSync(CARD_PATH, "utf8");
it("declares modelAliases state", () => {
expect(source).toMatch(/const \[modelAliases, setModelAliases\] = useState\(\{\}\)/);
});
it("fetches /api/models/alias when expanded", () => {
expect(source).toContain('fetch("/api/models/alias")');
});
it("passes modelAliases prop to ModelSelectModal", () => {
// Regression guard: this prop is what unlocks passthrough provider groups
// (OpenRouter, Requesty, DGrid, AgentRouter, Charm Hyper, ...) in the
// Hermes Agent role picker. Without it, OpenRouter is silently absent
// from the "Select" modal for every role (Default, Delegation, ...).
expect(source).toMatch(/modelAliases=\{modelAliases\}/);
});
});