fix: register tools via setTools(), add Tools/Code capability badges
Some checks are pending
CI / build-check-test (push) Waiting to run
Some checks are pending
CI / build-check-test (push) Waiting to run
- Fix 'Tool browser not found': createTools callback was silently ignored by Agent constructor. Now uses agent.setTools() after instantiation. - Add Wrench (Tools) and Code icons + filter buttons to ModelSelector alongside existing Brain (Reasoning) and Image (Vision). - Add refreshSidebar() call in createAgent for session list updates.
This commit is contained in:
parent
fedc60fd0f
commit
11af96265a
2 changed files with 51 additions and 16 deletions
|
|
@ -405,10 +405,10 @@ Persist information across sessions. Use to save important context, user prefere
|
||||||
}
|
}
|
||||||
renderApp();
|
renderApp();
|
||||||
},
|
},
|
||||||
createTools: async (runtimeProvidersFactory: any) => {
|
});
|
||||||
|
// Register tools with the agent
|
||||||
const replTool = createJavaScriptReplTool();
|
const replTool = createJavaScriptReplTool();
|
||||||
replTool.runtimeProvidersFactory = runtimeProvidersFactory;
|
agent.setTools([
|
||||||
return [
|
|
||||||
replTool,
|
replTool,
|
||||||
createWebSearchTool(),
|
createWebSearchTool(),
|
||||||
createBashTool(),
|
createBashTool(),
|
||||||
|
|
@ -416,9 +416,7 @@ Persist information across sessions. Use to save important context, user prefere
|
||||||
createImageGenTool(),
|
createImageGenTool(),
|
||||||
createTTSTool(),
|
createTTSTool(),
|
||||||
...createMemoryTools(),
|
...createMemoryTools(),
|
||||||
];
|
]);
|
||||||
},
|
|
||||||
});
|
|
||||||
costTracker.bindAgent(agent);
|
costTracker.bindAgent(agent);
|
||||||
chatPanel?.setAgent(agent);
|
chatPanel?.setAgent(agent);
|
||||||
// Hook: live model badge + immediate empty state hide
|
// Hook: live model badge + immediate empty state hide
|
||||||
|
|
@ -438,6 +436,7 @@ Persist information across sessions. Use to save important context, user prefere
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!currentSessionId) currentSessionId = crypto.randomUUID();
|
if (!currentSessionId) currentSessionId = crypto.randomUUID();
|
||||||
|
await refreshSidebar();
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadSession = async (sessionId: string): Promise<boolean> => {
|
const loadSession = async (sessionId: string): Promise<boolean> => {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { DialogBase } from "@mariozechner/mini-lit/dist/DialogBase.js";
|
||||||
import { html, type PropertyValues, type TemplateResult } from "lit";
|
import { html, type PropertyValues, type TemplateResult } from "lit";
|
||||||
import { customElement, state } from "lit/decorators.js";
|
import { customElement, state } from "lit/decorators.js";
|
||||||
import { createRef, ref } from "lit/directives/ref.js";
|
import { createRef, ref } from "lit/directives/ref.js";
|
||||||
import { Brain, Image as ImageIcon } from "lucide";
|
import { Brain, Code, Globe, Image as ImageIcon, Wrench } from "lucide";
|
||||||
import { Input } from "../components/Input.js";
|
import { Input } from "../components/Input.js";
|
||||||
import { getAppStorage } from "../storage/app-storage.js";
|
import { getAppStorage } from "../storage/app-storage.js";
|
||||||
import type { AutoDiscoveryProviderType } from "../storage/stores/custom-providers-store.js";
|
import type { AutoDiscoveryProviderType } from "../storage/stores/custom-providers-store.js";
|
||||||
|
|
@ -52,6 +52,8 @@ export class ModelSelector extends DialogBase {
|
||||||
@state() searchQuery = "";
|
@state() searchQuery = "";
|
||||||
@state() filterThinking = false;
|
@state() filterThinking = false;
|
||||||
@state() filterVision = false;
|
@state() filterVision = false;
|
||||||
|
@state() filterTools = false;
|
||||||
|
@state() filterCode = false;
|
||||||
@state() private filterProvider = "";
|
@state() private filterProvider = "";
|
||||||
@state() customProvidersLoading = false;
|
@state() customProvidersLoading = false;
|
||||||
@state() selectedIndex = 0;
|
@state() selectedIndex = 0;
|
||||||
|
|
@ -246,6 +248,12 @@ export class ModelSelector extends DialogBase {
|
||||||
if (this.filterVision) {
|
if (this.filterVision) {
|
||||||
filteredModels = filteredModels.filter(({ model }) => model.input.includes("image"));
|
filteredModels = filteredModels.filter(({ model }) => model.input.includes("image"));
|
||||||
}
|
}
|
||||||
|
if (this.filterTools) {
|
||||||
|
filteredModels = filteredModels.filter(({ model }) => (model as any).tags?.includes("tools"));
|
||||||
|
}
|
||||||
|
if (this.filterCode) {
|
||||||
|
filteredModels = filteredModels.filter(({ model }) => (model as any).tags?.includes("code") || (model as any).tags?.includes("optimized-for-code"));
|
||||||
|
}
|
||||||
if (this.filterProvider) {
|
if (this.filterProvider) {
|
||||||
filteredModels = filteredModels.filter(({ provider }) => provider === this.filterProvider);
|
filteredModels = filteredModels.filter(({ provider }) => provider === this.filterProvider);
|
||||||
}
|
}
|
||||||
|
|
@ -378,6 +386,32 @@ export class ModelSelector extends DialogBase {
|
||||||
className: "rounded-full",
|
className: "rounded-full",
|
||||||
children: html`<span class="inline-flex items-center gap-1">${icon(ImageIcon, "sm")} ${i18n("Vision")}</span>`,
|
children: html`<span class="inline-flex items-center gap-1">${icon(ImageIcon, "sm")} ${i18n("Vision")}</span>`,
|
||||||
})}
|
})}
|
||||||
|
${Button({
|
||||||
|
variant: this.filterTools ? "default" : "secondary",
|
||||||
|
size: "sm",
|
||||||
|
onClick: () => {
|
||||||
|
this.filterTools = !this.filterTools;
|
||||||
|
this.selectedIndex = 0;
|
||||||
|
if (this.scrollContainerRef.value) {
|
||||||
|
this.scrollContainerRef.value.scrollTop = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
className: "rounded-full",
|
||||||
|
children: html`<span class="inline-flex items-center gap-1">${icon(Wrench, "sm")} Tools</span>`,
|
||||||
|
})}
|
||||||
|
${Button({
|
||||||
|
variant: this.filterCode ? "default" : "secondary",
|
||||||
|
size: "sm",
|
||||||
|
onClick: () => {
|
||||||
|
this.filterCode = !this.filterCode;
|
||||||
|
this.selectedIndex = 0;
|
||||||
|
if (this.scrollContainerRef.value) {
|
||||||
|
this.scrollContainerRef.value.scrollTop = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
className: "rounded-full",
|
||||||
|
children: html`<span class="inline-flex items-center gap-1">${icon(Code, "sm")} Code</span>`,
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
${this.renderProviderTabs()}
|
${this.renderProviderTabs()}
|
||||||
|
|
@ -411,8 +445,10 @@ export class ModelSelector extends DialogBase {
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between text-xs text-muted-foreground">
|
<div class="flex items-center justify-between text-xs text-muted-foreground">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class="${model.reasoning ? "" : "opacity-30"}">${icon(Brain, "sm")}</span>
|
<span class="${model.reasoning ? "" : "opacity-30"}" title="Reasoning">${icon(Brain, "sm")}</span>
|
||||||
<span class="${model.input.includes("image") ? "" : "opacity-30"}">${icon(ImageIcon, "sm")}</span>
|
<span class="${model.input.includes("image") ? "" : "opacity-30"}" title="Vision">${icon(ImageIcon, "sm")}</span>
|
||||||
|
<span class="${(model as any).tags?.includes("tools") ? "" : "opacity-30"}" title="Tool Use">${icon(Wrench, "sm")}</span>
|
||||||
|
<span class="${(model as any).tags?.includes("code") || (model as any).tags?.includes("optimized-for-code") ? "" : "opacity-30"}" title="Code">${icon(Code, "sm")}</span>
|
||||||
<span>${this.formatTokens(model.contextWindow)}K/${this.formatTokens(model.maxTokens)}K</span>
|
<span>${this.formatTokens(model.contextWindow)}K/${this.formatTokens(model.maxTokens)}K</span>
|
||||||
</div>
|
</div>
|
||||||
<span>${formatModelCost(model.cost)}</span>
|
<span>${formatModelCost(model.cost)}</span>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue