Compare commits
14
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b8cf79c96 | ||
|
|
493a846f07 | ||
|
|
447ea5c5ae | ||
|
|
fdc0c1b933 | ||
|
|
b80407a9a6 | ||
|
|
d4375300cd | ||
|
|
1b04a34bbc | ||
|
|
c8266fef42 | ||
|
|
ed579bf29c | ||
|
|
f8b77c0d02 | ||
|
|
0b3392acea | ||
|
|
90b57477bb | ||
|
|
6bdc4f2ada | ||
|
|
cafd9a54e5 |
+15
-1
@@ -42,7 +42,7 @@ func sampleMessage() Message {
|
||||
ID: "msg_abc123def456", ConversationID: "cnv_abc123def456", RunID: "run_abc123def456",
|
||||
Role: RoleAssistant,
|
||||
Parts: []Part{
|
||||
{Type: PartThinking, Text: "考虑先检索…", Process: true},
|
||||
{Type: PartThinking, Text: "考虑先检索…", Process: true, DurationMs: 1500},
|
||||
{Type: PartToolCall, Process: true, ToolCall: &ToolCallPart{ID: "call_1", Name: "history_search", Arguments: `{"q":"部署"}`, Duration: 12.5}},
|
||||
{Type: PartToolResult, Process: true, ToolResult: &ToolResultPart{CallID: "call_1", Status: "ok", Summary: "3 条命中"}},
|
||||
{Type: PartText, Text: "根据历史记录……"},
|
||||
@@ -60,6 +60,14 @@ func sampleRun() Run {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoldenPromptModule(t *testing.T) {
|
||||
golden(t, "prompt_module_subagent", PromptModule{
|
||||
ID: "agent.sub.explore", Layer: LayerAgent, Version: 1,
|
||||
Title: "探索子代理", Body: "只读检索。",
|
||||
Tools: []string{"knowledge_search", "web_search"}, Model: "lightweight", MaxTurns: 8,
|
||||
})
|
||||
}
|
||||
|
||||
func TestGoldenDomain(t *testing.T) {
|
||||
golden(t, "message", sampleMessage())
|
||||
golden(t, "run", sampleRun())
|
||||
@@ -125,6 +133,12 @@ func TestGoldenCardEvents(t *testing.T) {
|
||||
Payload: json.RawMessage(`{"cardId":"card_abc123def456","actionId":"escalate"}`)})
|
||||
}
|
||||
|
||||
func TestGoldenProjectStreamEvent(t *testing.T) {
|
||||
// 项目流(D50):伪会话键 "project:<projectId>" 复用会话流机制;信封带 ProjectID。
|
||||
golden(t, "event_project_stream", StreamEvent{Seq: 47, ConversationID: "project:prj_abc123def456", ProjectID: "prj_abc123def456", TS: "2026-09-30T11:00:00Z", V: 1, Type: EvCardCreated,
|
||||
Payload: json.RawMessage(`{"card":{"id":"card_def456abc789","projectId":"prj_abc123def456","kind":"result","title":"项目级卡","status":"done","createdAt":"2026-09-30T11:00:00Z","updatedAt":"2026-09-30T11:00:00Z"}}`)})
|
||||
}
|
||||
|
||||
func TestGoldenUIVocabularies(t *testing.T) {
|
||||
golden(t, "ui_avatar", []UINode{
|
||||
{Type: UIAvatar, Avatar: &UIAvatarSpec{Name: "weichen", Sub: "OWNER"}},
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
package core
|
||||
|
||||
import "encoding/json"
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 事件信封:后端 → 前端的唯一增量通道(SSE),持久化后转发,Seq 在会话内单调。
|
||||
// 消费方对未知 Type 静默忽略(原则 6 前向兼容)。
|
||||
// 项目流(D50):项目频道事件以伪会话键 "project:<projectId>" 复用同一机制
|
||||
//(独立 seq、持久化、断线重放),信封以 ProjectID 标识归属(会话流事件为空)。
|
||||
type StreamEvent struct {
|
||||
Seq int64 `json:"seq"`
|
||||
RunID ID `json:"runId,omitempty"`
|
||||
ConversationID ID `json:"conversationId"`
|
||||
ProjectID ID `json:"projectID,omitempty"` // 项目流事件的项目归属(D50;只增不删)
|
||||
TS string `json:"ts"` // RFC3339
|
||||
V int `json:"v"`
|
||||
Type StreamEventType `json:"type"`
|
||||
@@ -16,6 +22,19 @@ type StreamEvent struct {
|
||||
|
||||
type StreamEventType string
|
||||
|
||||
// 项目流频道约定(D50):项目频道以伪会话键 "project:<projectId>" 复用会话
|
||||
// 事件的持久化/seq/重放机制;信封 ProjectID 由该键派生(发布与重放同源)。
|
||||
const projectChannelPrefix = "project:"
|
||||
|
||||
// ProjectChannelKey 返回项目流的事件频道键。
|
||||
func ProjectChannelKey(projectID ID) ID { return ID(projectChannelPrefix + string(projectID)) }
|
||||
|
||||
// ProjectFromChannel 反解项目流频道键;非项目流频道返回 false。
|
||||
func ProjectFromChannel(key ID) (ID, bool) {
|
||||
pid, ok := strings.CutPrefix(string(key), projectChannelPrefix)
|
||||
return ID(pid), ok && pid != ""
|
||||
}
|
||||
|
||||
const (
|
||||
EvMessageDelta StreamEventType = "message.delta"
|
||||
EvThinkingDelta StreamEventType = "thinking.delta"
|
||||
|
||||
@@ -89,6 +89,10 @@ type Part struct {
|
||||
|
||||
// 过程标记:true 的部件在 run 终态后由前端折叠为摘要行(4.2)。
|
||||
Process bool `json:"process,omitempty"`
|
||||
|
||||
// DurationMs 是 thinking 部件的思考时长(毫秒,从首个推理增量到最后一个)。
|
||||
// 工具耗时在 ToolCallPart.Duration,不复用本字段。
|
||||
DurationMs float64 `json:"durationMs,omitempty"`
|
||||
}
|
||||
|
||||
type ToolCallPart struct {
|
||||
|
||||
@@ -8,35 +8,44 @@ import "encoding/json"
|
||||
const PluginAPIVersion = "1.0"
|
||||
|
||||
type PluginManifest struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
APIVersion string `json:"apiVersion"`
|
||||
Requires PluginRequires `json:"requires,omitempty"`
|
||||
Provides PluginProvides `json:"provides"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
APIVersion string `json:"apiVersion"`
|
||||
Requires PluginRequires `json:"requires,omitempty"`
|
||||
Provides PluginProvides `json:"provides"`
|
||||
Scope PluginScope `json:"scope,omitzero"`
|
||||
Backend PluginBackend `json:"backend,omitzero"`
|
||||
}
|
||||
|
||||
type PluginRequires struct {
|
||||
Network []string `json:"network,omitempty"` // 允许访问的域名(展示用,v1 自装自审)
|
||||
Network []string `json:"network,omitempty"` // 出站域名白名单;v2 空名单拒绝出站,v1 空名单保持放行
|
||||
}
|
||||
|
||||
type PluginProvides struct {
|
||||
Tools []string `json:"tools,omitempty"` // tools/ 目录下的资产名
|
||||
Workflows []string `json:"workflows,omitempty"`
|
||||
Intents []string `json:"intents,omitempty"`
|
||||
Prompts []string `json:"prompts,omitempty"`
|
||||
Panels []string `json:"panels,omitempty"`
|
||||
Cards []string `json:"cards,omitempty"`
|
||||
Settings []string `json:"settings,omitempty"`
|
||||
Commands []string `json:"commands,omitempty"` // commands/ 资产名(spec 权威在 Agent-Command 库)
|
||||
Tools []string `json:"tools,omitempty"` // tools/ 目录下的资产名
|
||||
Workflows []string `json:"workflows,omitempty"`
|
||||
Intents []string `json:"intents,omitempty"`
|
||||
Prompts []string `json:"prompts,omitempty"`
|
||||
Panels []string `json:"panels,omitempty"`
|
||||
Cards []string `json:"cards,omitempty"`
|
||||
Settings []string `json:"settings,omitempty"`
|
||||
Commands []string `json:"commands,omitempty"` // commands/ 资产名(spec 权威在 Agent-Command 库)
|
||||
Workspaces []string `json:"workspaces,omitempty"` // workspaces/ 资产名(工作区弹层)
|
||||
Skills []string `json:"skills,omitempty"`
|
||||
MCPServers []string `json:"mcpServers,omitempty"`
|
||||
Knowledge []string `json:"knowledge,omitempty"`
|
||||
Parsers []string `json:"parsers,omitempty"`
|
||||
Agents []string `json:"agents,omitempty"`
|
||||
Channels []string `json:"channels,omitempty"`
|
||||
Pages []string `json:"pages,omitempty"`
|
||||
}
|
||||
|
||||
// PluginPanel:右栏面板声明(UI schema 静态骨架 + 可选数据提供者)。
|
||||
type PluginPanel struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Icon string `json:"icon,omitempty"`
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Icon string `json:"icon,omitempty"`
|
||||
Body []UINode `json:"body"`
|
||||
// Tool 绑定:面板挂载时调用该工具刷新 Body 中的动态区(v1 简化为整体刷新)。
|
||||
RefreshTool string `json:"refreshTool,omitempty"`
|
||||
@@ -44,23 +53,23 @@ type PluginPanel struct {
|
||||
|
||||
// WorkflowDef:工作流即数据(4.6)。Step 可产 HITL 卡片、调工具、产出工件。
|
||||
type WorkflowDef struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description,omitempty"`
|
||||
IntentID string `json:"intentId,omitempty"` // 绑定意图(命中即启动)
|
||||
Steps []WorkflowStep `json:"steps"`
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description,omitempty"`
|
||||
IntentID string `json:"intentId,omitempty"` // 绑定意图(命中即启动)
|
||||
Steps []WorkflowStep `json:"steps"`
|
||||
}
|
||||
|
||||
type WorkflowStep struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Kind string `json:"kind"` // prompt | tool | hitl | artifact | card
|
||||
Prompt string `json:"prompt,omitempty"` // prompt: 发给模型的指令模板
|
||||
Tool string `json:"tool,omitempty"` // tool: 工具名
|
||||
Args json.RawMessage `json:"args,omitempty"` // tool: 参数模板
|
||||
Hitl *HITLCardTemplate `json:"hitl,omitempty"` // hitl: 卡片模板
|
||||
Artifact string `json:"artifact,omitempty"` // artifact: 产出工件名模板
|
||||
Card *ActivityCardTemplate `json:"card,omitempty"` // card: 产收件箱任务卡
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Kind string `json:"kind"` // prompt | tool | hitl | artifact | card
|
||||
Prompt string `json:"prompt,omitempty"` // prompt: 发给模型的指令模板
|
||||
Tool string `json:"tool,omitempty"` // tool: 工具名
|
||||
Args json.RawMessage `json:"args,omitempty"` // tool: 参数模板
|
||||
Hitl *HITLCardTemplate `json:"hitl,omitempty"` // hitl: 卡片模板
|
||||
Artifact string `json:"artifact,omitempty"` // artifact: 产出工件名模板
|
||||
Card *ActivityCardTemplate `json:"card,omitempty"` // card: 产收件箱任务卡
|
||||
}
|
||||
|
||||
// ActivityCardTemplate:工作流步骤产卡模板(kind=card)——步骤执行时生成
|
||||
@@ -76,20 +85,20 @@ type ActivityCardTemplate struct {
|
||||
// PluginWorkspace:工作区弹层声明(深读与治理视图;Esc/遮罩关闭回对话现场,
|
||||
// 不承载任何唯一步骤——每个操作必须另有命令路径,提案 D31)。
|
||||
type PluginWorkspace struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Icon string `json:"icon,omitempty"`
|
||||
Shortcut string `json:"shortcut,omitempty"` // "1"–"9"(⌘N / Ctrl+N 召出)
|
||||
BadgeTool string `json:"badgeTool,omitempty"` // 角标提供者工具:返回 {count,tone}
|
||||
Body []UINode `json:"body"`
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Icon string `json:"icon,omitempty"`
|
||||
Shortcut string `json:"shortcut,omitempty"` // "1"–"9"(⌘N / Ctrl+N 召出)
|
||||
BadgeTool string `json:"badgeTool,omitempty"` // 角标提供者工具:返回 {count,tone}
|
||||
Body []UINode `json:"body"`
|
||||
// RefreshTool:挂载时调用刷新 Body 动态区(与 Panel 同机制,v1 整体刷新)。
|
||||
RefreshTool string `json:"refreshTool,omitempty"`
|
||||
}
|
||||
|
||||
type HITLCardTemplate struct {
|
||||
Question string `json:"question"`
|
||||
Kind HITLKind `json:"kind"`
|
||||
Choices []HITLChoice `json:"choices,omitempty"`
|
||||
AllowFreeInput bool `json:"allowFreeInput"`
|
||||
FreeInputHint string `json:"freeInputHint,omitempty"`
|
||||
Question string `json:"question"`
|
||||
Kind HITLKind `json:"kind"`
|
||||
Choices []HITLChoice `json:"choices,omitempty"`
|
||||
AllowFreeInput bool `json:"allowFreeInput"`
|
||||
FreeInputHint string `json:"freeInputHint,omitempty"`
|
||||
}
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
package core
|
||||
|
||||
// PluginAPIVersionExperimental 是插件契约 v2 的实验窗口。
|
||||
// 1.0 清单继续有效;v2 只增加可选字段,不收紧 1.0 已有资产。
|
||||
const PluginAPIVersionExperimental = "2.0-experimental"
|
||||
|
||||
// PluginAPIAccepted 报告宿主是否接受该 apiVersion。空值由宿主填成 PluginAPIVersion。
|
||||
func PluginAPIAccepted(v string) bool {
|
||||
switch v {
|
||||
case PluginAPIVersion, PluginAPIVersionExperimental:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// PluginScope 限制插件对哪些租户/项目可见。两者都空 = 全部可见。
|
||||
type PluginScope struct {
|
||||
Tenants []string `json:"tenants,omitempty"`
|
||||
Projects []string `json:"projects,omitempty"`
|
||||
}
|
||||
|
||||
// Allows 判断 owner/project 是否落在作用域内。
|
||||
func (s PluginScope) Allows(owner, project string) bool {
|
||||
if len(s.Tenants) > 0 && !scopeContains(s.Tenants, owner) {
|
||||
return false
|
||||
}
|
||||
if len(s.Projects) > 0 && !scopeContains(s.Projects, project) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func scopeContains(xs []string, v string) bool {
|
||||
for _, x := range xs {
|
||||
if x == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// PluginBackend 声明进程内或 sidecar 代码档。SchemaVersion 是插件自有数据的迁移版本。
|
||||
type PluginBackend struct {
|
||||
Mode string `json:"mode,omitempty"` // inproc | sidecar
|
||||
Command string `json:"command,omitempty"`
|
||||
Args []string `json:"args,omitempty"`
|
||||
SchemaVersion int `json:"schemaVersion,omitempty"`
|
||||
}
|
||||
|
||||
// PluginSkill 是 skills/<name>.md 的装载结果(SKILL.md 正文)。
|
||||
type PluginSkill struct {
|
||||
Name string `json:"name"`
|
||||
Body string `json:"body"`
|
||||
}
|
||||
|
||||
// PluginMCPServer 是 mcpServers/<name>.json,字段与 agent-native MCP ServerConfig 对齐。
|
||||
type PluginMCPServer struct {
|
||||
Name string `json:"name"`
|
||||
Command string `json:"command,omitempty"`
|
||||
Args []string `json:"args,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// PluginKnowledgeSet 是知识数据集声明(数据在插件侧,检索引擎在基座)。
|
||||
type PluginKnowledgeSet struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// PluginParserDecl 是解析器声明。实现可以是内置名或 sidecar 工具名。
|
||||
type PluginParserDecl struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
MIME string `json:"mime,omitempty"`
|
||||
Tool string `json:"tool,omitempty"`
|
||||
}
|
||||
|
||||
// PluginAgentDecl 是画像/子代理声明。
|
||||
type PluginAgentDecl struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Instructions string `json:"instructions,omitempty"`
|
||||
Tools []string `json:"tools,omitempty"`
|
||||
}
|
||||
|
||||
// PluginChannelDecl 是渠道适配器声明(飞书等由下游实现,基座只登记入口)。
|
||||
type PluginChannelDecl struct {
|
||||
ID string `json:"id"`
|
||||
Kind string `json:"kind"`
|
||||
Title string `json:"title,omitempty"`
|
||||
}
|
||||
|
||||
// PluginPageDecl 是前端 ESM 页面。Module 相对插件目录或绝对 URL。
|
||||
type PluginPageDecl struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Module string `json:"module"`
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package core
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestPluginAPIAccepted(t *testing.T) {
|
||||
if !PluginAPIAccepted(PluginAPIVersion) || !PluginAPIAccepted(PluginAPIVersionExperimental) {
|
||||
t.Fatal("current and experimental windows must be accepted")
|
||||
}
|
||||
if PluginAPIAccepted("0.9") || PluginAPIAccepted("") {
|
||||
t.Fatal("unknown or empty apiVersion must be rejected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPluginScopeAllows(t *testing.T) {
|
||||
open := PluginScope{}
|
||||
if !open.Allows("a", "p") {
|
||||
t.Fatal("empty scope is visible to everyone")
|
||||
}
|
||||
scoped := PluginScope{Tenants: []string{"acme"}, Projects: []string{"p1"}}
|
||||
if !scoped.Allows("acme", "p1") {
|
||||
t.Fatal("matching tenant and project should pass")
|
||||
}
|
||||
if scoped.Allows("other", "p1") || scoped.Allows("acme", "p2") {
|
||||
t.Fatal("scope must reject mismatches")
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,10 @@ type PromptModule struct {
|
||||
BasedOnVersion int `json:"basedOnVersion,omitempty"` // 用户副本基于的内置版本
|
||||
Drifted bool `json:"drifted,omitempty"` // 用户副本落后于当前内置版本(提示用,不阻断)
|
||||
Disabled bool `json:"disabled,omitempty"` // 用户停用
|
||||
// 子代理 profile。只对 agent.sub.* 有意义;空字段表示沿用内置。
|
||||
Tools []string `json:"tools,omitempty"`
|
||||
Model string `json:"model,omitempty"` // lightweight | chat
|
||||
MaxTurns int `json:"maxTurns,omitempty"`
|
||||
}
|
||||
|
||||
// PromptTrigger 触发条件;模块命中 = 任一 trigger 命中(再过 RequiresAttachments)。
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"seq": 47,
|
||||
"conversationId": "project:prj_abc123def456",
|
||||
"projectID": "prj_abc123def456",
|
||||
"ts": "2026-09-30T11:00:00Z",
|
||||
"v": 1,
|
||||
"type": "card.created",
|
||||
"payload": {
|
||||
"card": {
|
||||
"id": "card_def456abc789",
|
||||
"projectId": "prj_abc123def456",
|
||||
"kind": "result",
|
||||
"title": "项目级卡",
|
||||
"status": "done",
|
||||
"createdAt": "2026-09-30T11:00:00Z",
|
||||
"updatedAt": "2026-09-30T11:00:00Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+2
-1
@@ -7,7 +7,8 @@
|
||||
{
|
||||
"type": "thinking",
|
||||
"text": "考虑先检索…",
|
||||
"process": true
|
||||
"process": true,
|
||||
"durationMs": 1500
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"id": "agent.sub.explore",
|
||||
"layer": "agent",
|
||||
"version": 1,
|
||||
"title": "探索子代理",
|
||||
"description": "",
|
||||
"body": "只读检索。",
|
||||
"tools": [
|
||||
"knowledge_search",
|
||||
"web_search"
|
||||
],
|
||||
"model": "lightweight",
|
||||
"maxTurns": 8
|
||||
}
|
||||
@@ -20,6 +20,9 @@ type ToolDesc struct {
|
||||
Source SourceKind `json:"source"`
|
||||
PluginID string `json:"pluginId,omitempty"`
|
||||
HTTP *HTTPToolSpec `json:"http,omitempty"` // 声明式 HTTP 工具(无代码)
|
||||
// Hidden 预留能力形态:默认不对模型与 /api/tools 列表可见,须运行时开关
|
||||
// (如 runtime.fsTools)或管理动作开启后可用(提案 2026-09-30-file-preview-and-reserved-capabilities)。
|
||||
Hidden bool `json:"hidden,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPToolSpec:无代码自定义工具(4.8)。模板变量 {{param.x}} 从调用参数注入。
|
||||
|
||||
+11
@@ -35,6 +35,7 @@ export interface Part {
|
||||
card?: { kind: string; data: UINode[]; cardId?: ID }; // cardId 非空 = 收件箱卡片引用部件(submit_card)
|
||||
error?: { code: string; message: string };
|
||||
process?: boolean; // run 终态后折叠为摘要行
|
||||
durationMs?: number; // thinking 部件的思考时长(毫秒);工具耗时在 toolCall.durationMs
|
||||
}
|
||||
|
||||
export interface Message {
|
||||
@@ -208,6 +209,8 @@ export interface PromptModule {
|
||||
body: string; outputContract?: string;
|
||||
source?: 'builtin' | 'plugin' | 'user'; owner?: string;
|
||||
basedOnVersion?: number; drifted?: boolean; disabled?: boolean;
|
||||
/** 子代理 profile。只对 agent.sub.* 有意义;空字段表示沿用内置。 */
|
||||
tools?: string[]; model?: string; maxTurns?: number;
|
||||
}
|
||||
|
||||
export interface PromptBlock { moduleId: string; version: number; layer: string; body: string; }
|
||||
@@ -247,7 +250,11 @@ export interface PluginManifest {
|
||||
tools?: string[]; workflows?: string[]; intents?: string[];
|
||||
prompts?: string[]; panels?: string[]; cards?: string[]; settings?: string[];
|
||||
commands?: string[]; workspaces?: string[];
|
||||
skills?: string[]; mcpServers?: string[]; knowledge?: string[];
|
||||
parsers?: string[]; agents?: string[]; channels?: string[]; pages?: string[];
|
||||
};
|
||||
scope?: { tenants?: string[]; projects?: string[] };
|
||||
backend?: { mode?: 'inproc' | 'sidecar'; command?: string; args?: string[]; schemaVersion?: number };
|
||||
}
|
||||
|
||||
export interface PluginPanel {
|
||||
@@ -259,6 +266,10 @@ export interface PluginWorkspace {
|
||||
badgeTool?: string; body: UINode[]; refreshTool?: string;
|
||||
}
|
||||
|
||||
export interface PluginPageDecl {
|
||||
id: string; title: string; module: string;
|
||||
}
|
||||
|
||||
// ---- 摄取 / 检索 ----
|
||||
|
||||
export interface ParsedDocument {
|
||||
|
||||
Reference in New Issue
Block a user