feat(ui): add Agents dashboard

This commit is contained in:
Gustavo Madeira Santana
2026-02-02 21:31:17 -05:00
parent c8af8e9555
commit 2a68bcbeb3
32 changed files with 3652 additions and 21 deletions

View File

@@ -4,6 +4,7 @@ import {
resolveAgentDir,
resolveAgentWorkspaceDir,
resolveSessionAgentId,
resolveAgentSkillsFilter,
} from "../../agents/agent-scope.js";
import { resolveModelRefFromString } from "../../agents/model-selection.js";
import { resolveAgentTimeoutMs } from "../../agents/timeout.js";
@@ -24,6 +25,31 @@ import { initSessionState } from "./session.js";
import { stageSandboxMedia } from "./stage-sandbox-media.js";
import { createTypingController } from "./typing.js";
function mergeSkillFilters(channelFilter?: string[], agentFilter?: string[]): string[] | undefined {
const normalize = (list?: string[]) => {
if (!Array.isArray(list)) {
return undefined;
}
return list.map((entry) => String(entry).trim()).filter(Boolean);
};
const channel = normalize(channelFilter);
const agent = normalize(agentFilter);
if (!channel && !agent) {
return undefined;
}
if (!channel) {
return agent;
}
if (!agent) {
return channel;
}
if (channel.length === 0 || agent.length === 0) {
return [];
}
const agentSet = new Set(agent);
return channel.filter((name) => agentSet.has(name));
}
export async function getReplyFromConfig(
ctx: MsgContext,
opts?: GetReplyOptions,
@@ -38,6 +64,12 @@ export async function getReplyFromConfig(
sessionKey: agentSessionKey,
config: cfg,
});
const mergedSkillFilter = mergeSkillFilters(
opts?.skillFilter,
resolveAgentSkillsFilter(cfg, agentId),
);
const resolvedOpts =
mergedSkillFilter !== undefined ? { ...opts, skillFilter: mergedSkillFilter } : opts;
const agentCfg = cfg.agents?.defaults;
const sessionCfg = cfg.session;
const { defaultProvider, defaultModel, aliasIndex } = resolveDefaultModel({
@@ -164,8 +196,8 @@ export async function getReplyFromConfig(
provider,
model,
typing,
opts,
skillFilter: opts?.skillFilter,
opts: resolvedOpts,
skillFilter: mergedSkillFilter,
});
if (directiveResult.kind === "reply") {
return directiveResult.reply;
@@ -216,7 +248,7 @@ export async function getReplyFromConfig(
sessionScope,
workspaceDir,
isGroup,
opts,
opts: resolvedOpts,
typing,
allowTextCommands,
inlineStatusRequested,
@@ -238,7 +270,7 @@ export async function getReplyFromConfig(
contextTokens,
directiveAck,
abortedLastRun,
skillFilter: opts?.skillFilter,
skillFilter: mergedSkillFilter,
});
if (inlineActionResult.kind === "reply") {
return inlineActionResult.reply;
@@ -284,7 +316,7 @@ export async function getReplyFromConfig(
perMessageQueueMode,
perMessageQueueOptions,
typing,
opts,
opts: resolvedOpts,
defaultProvider,
defaultModel,
timeoutMs,