feat(controller): 工具仓库、Skills 录入、多轮追问与终端运行日志

- 插件/MCP 改为通用工具仓库:内置、HTTP MCP、本机命令(stdio)三类工具,可增删改、
  按 Agent 分配;定义变更自动提升下发版本并重发,删除即回收分配并通知 Agent 清空。
- 旧 desktop-filesystem 降级为仓库中的一个内置条目;本机预设工具改为总控只展示、
  Agent 默认启用,任务执行来源新增 builtin(审计 task.builtin_tool_execution)。
- Skills 补齐录入闭环:新建或按名称覆盖更新,并可从旧版技能目录(SKILL.md + skill.json)
  批量导入;同名更新保持标识不变并自动重新应用,旧包入口脚本只提示不执行。
- 单独指派支持基于某条已完成任务的多轮追问:任务内容框仍下发无上下文的一次性任务,
  追问时由总控组装历史(仅成功轮次、默认最近 50 轮 / 约 6 万字符),会话按 Agent 隔离;
  执行动态把同一会话合并为一条记录,任务详情弹窗底部提供继续对话输入框。
- 任务详情支持运行中观测:打开期间每 2 秒刷新,终端风格输出全部事件并自动滚动;
  progress 事件不改变任务状态且顺延无进展超时,避免正在执行工具的任务被误判超时。
- 修复 build.ps1 缺 UTF-8 BOM 导致 build.bat 在 PowerShell 5.1 下语法报错。
This commit is contained in:
toot
2026-09-16 15:30:50 +08:00
parent 8a6c55d94a
commit aa57ea69de
19 changed files with 1977 additions and 154 deletions
+143 -28
View File
@@ -18,34 +18,6 @@ export namespace controlplane {
this.lastSeenAt = source["lastSeenAt"];
}
}
export class AgentDeploymentStatus {
agentID: string;
llmProfile: string;
llmStatus: string;
skillTotal: number;
skillApplied: number;
skillFailed: number;
mcpStatus: string;
mcpError: string;
lastUpdatedAt: string;
static createFrom(source: any = {}) {
return new AgentDeploymentStatus(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.agentID = source["agentID"];
this.llmProfile = source["llmProfile"];
this.llmStatus = source["llmStatus"];
this.skillTotal = source["skillTotal"];
this.skillApplied = source["skillApplied"];
this.skillFailed = source["skillFailed"];
this.mcpStatus = source["mcpStatus"];
this.mcpError = source["mcpError"];
this.lastUpdatedAt = source["lastUpdatedAt"];
}
}
export class AgentDirectoryFilter {
page: number;
pageSize: number;
@@ -172,6 +144,40 @@ export namespace controlplane {
this.updatedAt = source["updatedAt"];
}
}
export class AgentMCPStatus {
agentID: string;
agentName: string;
toolID: string;
toolName: string;
kind: string;
endpoint: string;
command: string;
version: string;
deployVersion: number;
applyStatus: string;
lastError: string;
updatedAt: string;
static createFrom(source: any = {}) {
return new AgentMCPStatus(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.agentID = source["agentID"];
this.agentName = source["agentName"];
this.toolID = source["toolID"];
this.toolName = source["toolName"];
this.kind = source["kind"];
this.endpoint = source["endpoint"];
this.command = source["command"];
this.version = source["version"];
this.deployVersion = source["deployVersion"];
this.applyStatus = source["applyStatus"];
this.lastError = source["lastError"];
this.updatedAt = source["updatedAt"];
}
}
export class DeploymentFailure {
resource: string;
reason: string;
@@ -238,6 +244,7 @@ export namespace controlplane {
error: string;
execution: string;
attachmentCount: number;
sessionID: string;
static createFrom(source: any = {}) {
return new Task(source);
@@ -260,6 +267,7 @@ export namespace controlplane {
this.error = source["error"];
this.execution = source["execution"];
this.attachmentCount = source["attachmentCount"];
this.sessionID = source["sessionID"];
}
}
export class AgentOperationalDetail {
@@ -391,6 +399,22 @@ export namespace controlplane {
return a;
}
}
export class CreateTaskSessionResult {
taskID: string;
sessionID: string;
turns: number;
static createFrom(source: any = {}) {
return new CreateTaskSessionResult(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.taskID = source["taskID"];
this.sessionID = source["sessionID"];
this.turns = source["turns"];
}
}
export class LLMProfile {
id: string;
@@ -442,6 +466,62 @@ export namespace controlplane {
this.apiKey = source["apiKey"];
}
}
export class MCPTool {
id: string;
name: string;
description: string;
kind: string;
endpoint: string;
command: string;
args: string[];
version: string;
updatedAt: string;
agentCount: number;
static createFrom(source: any = {}) {
return new MCPTool(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.id = source["id"];
this.name = source["name"];
this.description = source["description"];
this.kind = source["kind"];
this.endpoint = source["endpoint"];
this.command = source["command"];
this.args = source["args"];
this.version = source["version"];
this.updatedAt = source["updatedAt"];
this.agentCount = source["agentCount"];
}
}
export class MCPToolInput {
id: string;
name: string;
description: string;
kind: string;
endpoint: string;
command: string;
args: string[];
version: string;
static createFrom(source: any = {}) {
return new MCPToolInput(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.id = source["id"];
this.name = source["name"];
this.description = source["description"];
this.kind = source["kind"];
this.endpoint = source["endpoint"];
this.command = source["command"];
this.args = source["args"];
this.version = source["version"];
}
}
export class MentionTask {
line: number;
mention: string;
@@ -689,6 +769,41 @@ export namespace controlplane {
this.timeoutSeconds = source["timeoutSeconds"];
}
}
export class TaskSessionTurn {
instruction: string;
answer: string;
createdAt: string;
static createFrom(source: any = {}) {
return new TaskSessionTurn(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.instruction = source["instruction"];
this.answer = source["answer"];
this.createdAt = source["createdAt"];
}
}
}
export namespace main {
export class SkillImportResult {
imported: number;
notes: string[];
static createFrom(source: any = {}) {
return new SkillImportResult(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.imported = source["imported"];
this.notes = source["notes"];
}
}
}