mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-27 01:11:40 +00:00
feat(web): add context window support to dashboard config
- Add GET /api/model/info endpoint that resolves model metadata using the same 10-step context-length detection chain the agent uses. Returns auto-detected context length, config override, effective value, and model capabilities (tools, vision, reasoning, max output, model family). - Surface model.context_length as model_context_length virtual field in the config normalize/denormalize cycle. 0 = auto-detect (default), positive value overrides. Writing 0 removes context_length from the model dict on disk. - Add ModelInfoCard component showing resolved context window (e.g. '1M auto-detected' or '500K override — auto: 1M'), max output tokens, and colored capability badges (Tools, Vision, Reasoning, model family). - Inject ModelInfoCard between model field and context_length override in ConfigPage General tab. Card re-fetches on model change and after save. - Insert model_context_length right after model in CONFIG_SCHEMA ordering so the three elements (model input → info card → override) are adjacent.
This commit is contained in:
parent
eabc0a2f66
commit
8fd3093f49
6 changed files with 293 additions and 5 deletions
|
|
@ -32,6 +32,7 @@ import { getNestedValue, setNestedValue } from "@/lib/nested";
|
|||
import { useToast } from "@/hooks/useToast";
|
||||
import { Toast } from "@/components/Toast";
|
||||
import { AutoField } from "@/components/AutoField";
|
||||
import { ModelInfoCard } from "@/components/ModelInfoCard";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
|
@ -87,6 +88,7 @@ export default function ConfigPage() {
|
|||
const [yamlLoading, setYamlLoading] = useState(false);
|
||||
const [yamlSaving, setYamlSaving] = useState(false);
|
||||
const [activeCategory, setActiveCategory] = useState<string>("");
|
||||
const [modelInfoRefreshKey, setModelInfoRefreshKey] = useState(0);
|
||||
const { toast, showToast } = useToast();
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
|
|
@ -174,6 +176,7 @@ export default function ConfigPage() {
|
|||
try {
|
||||
await api.saveConfig(config);
|
||||
showToast("Configuration saved", "success");
|
||||
setModelInfoRefreshKey((k) => k + 1);
|
||||
} catch (e) {
|
||||
showToast(`Failed to save: ${e}`, "error");
|
||||
} finally {
|
||||
|
|
@ -186,6 +189,7 @@ export default function ConfigPage() {
|
|||
try {
|
||||
await api.saveConfigRaw(yamlText);
|
||||
showToast("YAML config saved", "success");
|
||||
setModelInfoRefreshKey((k) => k + 1);
|
||||
api.getConfig().then(setConfig).catch(() => {});
|
||||
} catch (e) {
|
||||
showToast(`Failed to save YAML: ${e}`, "error");
|
||||
|
|
@ -238,6 +242,7 @@ export default function ConfigPage() {
|
|||
const renderFields = (fields: [string, Record<string, unknown>][], showCategory = false) => {
|
||||
let lastSection = "";
|
||||
let lastCat = "";
|
||||
const currentModel = config ? String(getNestedValue(config, "model") ?? "") : "";
|
||||
return fields.map(([key, s]) => {
|
||||
const parts = key.split(".");
|
||||
const section = parts.length > 1 ? parts[0] : "";
|
||||
|
|
@ -274,6 +279,12 @@ export default function ConfigPage() {
|
|||
onChange={(v) => setConfig(setNestedValue(config, key, v))}
|
||||
/>
|
||||
</div>
|
||||
{/* Inject model info card right after the model field */}
|
||||
{key === "model" && currentModel && (
|
||||
<div className="py-1">
|
||||
<ModelInfoCard currentModel={currentModel} refreshKey={modelInfoRefreshKey} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue