@xpert-ai/plugin-sdk 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs.d.ts +1 -0
- package/index.cjs.js +307977 -0
- package/index.esm.d.ts +1 -0
- package/index.esm.js +307944 -0
- package/package.json +3 -3
- package/src/index.d.ts +12 -0
- package/src/lib/core/file-system.d.ts +42 -0
- package/src/lib/core/index.d.ts +3 -0
- package/src/lib/core/permissions.d.ts +74 -0
- package/src/lib/core/schema.d.ts +22 -0
- package/src/lib/integration/index.d.ts +3 -0
- package/src/lib/integration/strategy.decorator.d.ts +2 -0
- package/src/lib/integration/{strategy.interface.ts → strategy.interface.d.ts} +5 -7
- package/src/lib/integration/strategy.registry.d.ts +6 -0
- package/src/lib/knowledge/index.d.ts +3 -0
- package/src/lib/knowledge/knowledge-strategy.decorator.d.ts +2 -0
- package/src/lib/knowledge/knowledge-strategy.interface.d.ts +15 -0
- package/src/lib/knowledge/knowledge-strategy.registry.d.ts +12 -0
- package/src/lib/logger.d.ts +2 -0
- package/src/lib/plugin-metadata.d.ts +17 -0
- package/src/lib/plugin.d.ts +8 -0
- package/src/lib/{plugin.hook.ts → plugin.hook.d.ts} +0 -4
- package/src/lib/plugin.interface.d.ts +59 -0
- package/src/lib/rag/image/index.d.ts +3 -0
- package/src/lib/rag/image/strategy.decorator.d.ts +5 -0
- package/src/lib/rag/image/strategy.interface.d.ts +36 -0
- package/src/lib/rag/image/strategy.registry.d.ts +6 -0
- package/src/lib/rag/index.d.ts +6 -0
- package/src/lib/rag/retriever/index.d.ts +3 -0
- package/src/lib/rag/retriever/strategy.decorator.d.ts +5 -0
- package/src/lib/rag/retriever/strategy.interface.d.ts +30 -0
- package/src/lib/rag/retriever/strategy.registry.d.ts +6 -0
- package/src/lib/rag/source/index.d.ts +3 -0
- package/src/lib/rag/source/strategy.decorator.d.ts +5 -0
- package/src/lib/rag/source/strategy.interface.d.ts +26 -0
- package/src/lib/rag/source/strategy.registry.d.ts +6 -0
- package/src/lib/rag/textsplitter/index.d.ts +3 -0
- package/src/lib/rag/textsplitter/strategy.decorator.d.ts +2 -0
- package/src/lib/rag/textsplitter/strategy.interface.d.ts +24 -0
- package/src/lib/rag/textsplitter/strategy.registry.d.ts +6 -0
- package/src/lib/rag/transformer/index.d.ts +3 -0
- package/src/lib/rag/transformer/strategy.decorator.d.ts +5 -0
- package/src/lib/rag/transformer/strategy.interface.d.ts +40 -0
- package/src/lib/rag/transformer/strategy.registry.d.ts +6 -0
- package/src/lib/rag/types.d.ts +29 -0
- package/src/lib/strategy.d.ts +12 -0
- package/src/lib/toolset/builtin.d.ts +54 -0
- package/src/lib/toolset/index.d.ts +5 -0
- package/src/lib/toolset/strategy.decorator.d.ts +5 -0
- package/src/lib/toolset/strategy.interface.d.ts +28 -0
- package/src/lib/toolset/strategy.registry.d.ts +6 -0
- package/src/lib/toolset/toolset.d.ts +53 -0
- package/src/lib/types.d.ts +47 -0
- package/src/lib/vectorstore/index.d.ts +3 -0
- package/src/lib/vectorstore/strategy.decorator.d.ts +2 -0
- package/src/lib/vectorstore/strategy.interface.d.ts +24 -0
- package/src/lib/vectorstore/strategy.registry.d.ts +6 -0
- package/src/lib/workflow/index.d.ts +2 -0
- package/src/lib/workflow/node/index.d.ts +3 -0
- package/src/lib/workflow/node/strategy.decorator.d.ts +5 -0
- package/src/lib/workflow/node/strategy.interface.d.ts +40 -0
- package/src/lib/workflow/node/strategy.registry.d.ts +9 -0
- package/src/lib/workflow/trigger/index.d.ts +3 -0
- package/src/lib/workflow/trigger/strategy.decorator.d.ts +2 -0
- package/src/lib/workflow/trigger/strategy.interface.d.ts +22 -0
- package/src/lib/workflow/trigger/strategy.registry.d.ts +6 -0
- package/.eslintrc.json +0 -30
- package/.swcrc +0 -29
- package/PERMISSIONS.md +0 -181
- package/README.md +0 -19
- package/SCHEMA_SPECIFICATION.md +0 -332
- package/jest.config.ts +0 -28
- package/project.json +0 -29
- package/src/index.ts +0 -12
- package/src/lib/core/file-system.ts +0 -96
- package/src/lib/core/index.ts +0 -3
- package/src/lib/core/permissions.ts +0 -97
- package/src/lib/core/schema.ts +0 -23
- package/src/lib/integration/index.ts +0 -3
- package/src/lib/integration/strategy.decorator.ts +0 -6
- package/src/lib/integration/strategy.registry.ts +0 -12
- package/src/lib/knowledge/index.ts +0 -3
- package/src/lib/knowledge/knowledge-strategy.decorator.ts +0 -6
- package/src/lib/knowledge/knowledge-strategy.interface.ts +0 -15
- package/src/lib/knowledge/knowledge-strategy.registry.ts +0 -36
- package/src/lib/logger.ts +0 -18
- package/src/lib/plugin-metadata.ts +0 -20
- package/src/lib/plugin.interface.ts +0 -67
- package/src/lib/plugin.ts +0 -32
- package/src/lib/rag/image/index.ts +0 -3
- package/src/lib/rag/image/strategy.decorator.ts +0 -9
- package/src/lib/rag/image/strategy.interface.ts +0 -42
- package/src/lib/rag/image/strategy.registry.ts +0 -17
- package/src/lib/rag/index.ts +0 -6
- package/src/lib/rag/retriever/index.ts +0 -3
- package/src/lib/rag/retriever/strategy.decorator.ts +0 -9
- package/src/lib/rag/retriever/strategy.interface.ts +0 -32
- package/src/lib/rag/retriever/strategy.registry.ts +0 -12
- package/src/lib/rag/source/index.ts +0 -3
- package/src/lib/rag/source/strategy.decorator.ts +0 -9
- package/src/lib/rag/source/strategy.interface.ts +0 -28
- package/src/lib/rag/source/strategy.registry.ts +0 -17
- package/src/lib/rag/textsplitter/index.ts +0 -3
- package/src/lib/rag/textsplitter/strategy.decorator.ts +0 -6
- package/src/lib/rag/textsplitter/strategy.interface.ts +0 -28
- package/src/lib/rag/textsplitter/strategy.registry.ts +0 -17
- package/src/lib/rag/transformer/index.ts +0 -3
- package/src/lib/rag/transformer/strategy.decorator.ts +0 -9
- package/src/lib/rag/transformer/strategy.interface.ts +0 -48
- package/src/lib/rag/transformer/strategy.registry.ts +0 -14
- package/src/lib/rag/types.ts +0 -86
- package/src/lib/strategy.ts +0 -37
- package/src/lib/toolset/builtin.ts +0 -111
- package/src/lib/toolset/index.ts +0 -5
- package/src/lib/toolset/strategy.decorator.ts +0 -9
- package/src/lib/toolset/strategy.interface.ts +0 -32
- package/src/lib/toolset/strategy.registry.ts +0 -17
- package/src/lib/toolset/toolset.ts +0 -76
- package/src/lib/types.ts +0 -47
- package/src/lib/vectorstore/index.ts +0 -3
- package/src/lib/vectorstore/strategy.decorator.ts +0 -6
- package/src/lib/vectorstore/strategy.interface.ts +0 -25
- package/src/lib/vectorstore/strategy.registry.ts +0 -17
- package/src/lib/workflow/index.ts +0 -2
- package/src/lib/workflow/node/index.ts +0 -3
- package/src/lib/workflow/node/strategy.decorator.ts +0 -9
- package/src/lib/workflow/node/strategy.interface.ts +0 -49
- package/src/lib/workflow/node/strategy.registry.ts +0 -18
- package/src/lib/workflow/trigger/index.ts +0 -3
- package/src/lib/workflow/trigger/strategy.decorator.ts +0 -6
- package/src/lib/workflow/trigger/strategy.interface.ts +0 -27
- package/src/lib/workflow/trigger/strategy.registry.ts +0 -17
- package/tsconfig.json +0 -22
- package/tsconfig.lib.json +0 -10
- package/tsconfig.spec.json +0 -9
package/SCHEMA_SPECIFICATION.md
DELETED
|
@@ -1,332 +0,0 @@
|
|
|
1
|
-
# 🔧 Schema UI 扩展规范
|
|
2
|
-
|
|
3
|
-
:::tip
|
|
4
|
-
设计一套 通用的 schema UI 扩展规范
|
|
5
|
-
:::
|
|
6
|
-
|
|
7
|
-
👌好的,我来帮你设计一套 **通用的 Schema UI 扩展规范**,可以应用在你的插件系统所有配置 schema 中,让前端渲染时有统一的规则。
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
在 JSON Schema 基础上扩展一个保留字段:
|
|
12
|
-
|
|
13
|
-
```json
|
|
14
|
-
"x-ui": { ... }
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
前端 UI 渲染器根据 `x-ui` 的内容决定用什么组件、怎么展示、怎么动态联动。
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## 1. 基础字段
|
|
22
|
-
|
|
23
|
-
| 字段名 | 类型 | 说明 |
|
|
24
|
-
| -------------- | ------ | ------------------------------------------------------------------------------------------------------------------------ |
|
|
25
|
-
| `component` | string | 指定 UI 组件类型,如 `textInput`, `textarea`, `select`, `switch`, `slider`, `promptEditor`, `modelProviderSelect`, `modelSelect` |
|
|
26
|
-
| `label` | string | UI 展示的标签 |
|
|
27
|
-
| `description` | string | UI 展示的帮助文本,优先覆盖 schema.description |
|
|
28
|
-
| `placeholder` | string | 输入占位符 |
|
|
29
|
-
| `defaultValue` | any | 默认值,优先覆盖 schema.default |
|
|
30
|
-
| `order` | number | 字段在 UI 中的展示顺序 |
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## 2. 数据源相关
|
|
35
|
-
|
|
36
|
-
| 字段名 | 类型 | 说明 |
|
|
37
|
-
| ------------ | ------ | ---------------------------------------------------------- |
|
|
38
|
-
| `options` | array | 静态选项(下拉框、多选框等),形如 `[{ label: 'OpenAI', value: 'openai' }]` |
|
|
39
|
-
| `dataSource` | string | 动态选项来源标识,如 `"system.providers"`, `"system.models"` |
|
|
40
|
-
| `dependency` | string | 依赖其他字段的值来过滤选项,如 `"provider"` |
|
|
41
|
-
| `mapping` | object | 映射关系,例如 `{ label: 'name', value: 'id' }` |
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## 3. 验证与交互
|
|
46
|
-
|
|
47
|
-
| 字段名 | 类型 | 说明 |
|
|
48
|
-
| ------------- | ------- | -------------------------------------------- |
|
|
49
|
-
| `required` | boolean | 是否必填(优先覆盖 schema.required) |
|
|
50
|
-
| `visibleWhen` | object | 条件渲染,只有满足条件才显示字段,例如 `{ provider: 'openai' }` |
|
|
51
|
-
| `enabledWhen` | object | 条件启用,例如 `{ useCustomPrompt: true }` |
|
|
52
|
-
| `maxLength` | number | 输入最大长度 |
|
|
53
|
-
| `minLength` | number | 输入最小长度 |
|
|
54
|
-
| `regex` | string | 自定义正则校验规则 |
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## 4. 特殊组件约定
|
|
59
|
-
|
|
60
|
-
### `modelProviderSelect`
|
|
61
|
-
|
|
62
|
-
* 用于选择模型提供商(OpenAI、Anthropic、Azure、Ollama 等)
|
|
63
|
-
* `dataSource = "system.providers"`
|
|
64
|
-
|
|
65
|
-
### `modelSelect`
|
|
66
|
-
|
|
67
|
-
* 用于选择具体模型
|
|
68
|
-
* 需要依赖 `provider`
|
|
69
|
-
* `dataSource = "system.models"`
|
|
70
|
-
* `dependency = "provider"`
|
|
71
|
-
|
|
72
|
-
### `promptEditor`
|
|
73
|
-
|
|
74
|
-
* 用于编辑 Prompt,支持多行、语法高亮、变量插值
|
|
75
|
-
|
|
76
|
-
### `jsonEditor`
|
|
77
|
-
|
|
78
|
-
* 用于编辑 JSON 对象,带格式校验
|
|
79
|
-
|
|
80
|
-
### `codeEditor`
|
|
81
|
-
|
|
82
|
-
* 用于编辑代码(支持语言高亮,如 js, ts, python)
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## 5. 示例 Schema
|
|
87
|
-
|
|
88
|
-
```ts
|
|
89
|
-
configSchema: {
|
|
90
|
-
type: 'object',
|
|
91
|
-
properties: {
|
|
92
|
-
provider: {
|
|
93
|
-
type: 'string',
|
|
94
|
-
description: '模型提供商',
|
|
95
|
-
enum: ['openai', 'anthropic', 'azure', 'ollama'],
|
|
96
|
-
'x-ui': {
|
|
97
|
-
component: 'modelProviderSelect',
|
|
98
|
-
label: 'Provider',
|
|
99
|
-
order: 1,
|
|
100
|
-
dataSource: 'system.providers'
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
model: {
|
|
104
|
-
type: 'string',
|
|
105
|
-
description: '大模型名称',
|
|
106
|
-
default: 'gpt-4-vision-preview',
|
|
107
|
-
'x-ui': {
|
|
108
|
-
component: 'modelSelect',
|
|
109
|
-
label: 'Model',
|
|
110
|
-
order: 2,
|
|
111
|
-
dependency: 'provider',
|
|
112
|
-
dataSource: 'system.models'
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
|
-
prompt: {
|
|
116
|
-
type: 'string',
|
|
117
|
-
default: 'Describe this image in detail.',
|
|
118
|
-
description: '提示词',
|
|
119
|
-
'x-ui': {
|
|
120
|
-
component: 'promptEditor',
|
|
121
|
-
label: 'Prompt',
|
|
122
|
-
order: 3,
|
|
123
|
-
placeholder: '请输入提示词,可使用 {{variables}} 占位符'
|
|
124
|
-
}
|
|
125
|
-
},
|
|
126
|
-
temperature: {
|
|
127
|
-
type: 'number',
|
|
128
|
-
default: 0.7,
|
|
129
|
-
'x-ui': {
|
|
130
|
-
component: 'slider',
|
|
131
|
-
label: 'Temperature',
|
|
132
|
-
order: 4,
|
|
133
|
-
min: 0,
|
|
134
|
-
max: 1,
|
|
135
|
-
step: 0.1
|
|
136
|
-
}
|
|
137
|
-
},
|
|
138
|
-
advanced: {
|
|
139
|
-
type: 'object',
|
|
140
|
-
'x-ui': {
|
|
141
|
-
component: 'jsonEditor',
|
|
142
|
-
label: 'Advanced Config',
|
|
143
|
-
order: 5,
|
|
144
|
-
visibleWhen: { provider: 'openai' }
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
},
|
|
148
|
-
required: ['provider', 'model']
|
|
149
|
-
}
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
---
|
|
153
|
-
|
|
154
|
-
这样一来:
|
|
155
|
-
|
|
156
|
-
* 前端 UI 渲染器只需要识别 `x-ui.component`,其余逻辑由 `x-ui` 字段驱动。
|
|
157
|
-
* 插件开发者只需写 schema,就能自动获得智能化配置体验。
|
|
158
|
-
* 扩展性强,可以统一适配未来的 Embedding、OCR、VLM、VectorStore 插件。
|
|
159
|
-
|
|
160
|
-
## 如何表示 SECRET 的input 字段
|
|
161
|
-
|
|
162
|
-
好问题 👍,**SECRET 类型的字段**(比如 API Key、Token、密码)在 schema UI 里需要特殊处理:
|
|
163
|
-
|
|
164
|
-
1. **前端渲染时要显示为密码输入框**(`type="password"` 或遮罩)。
|
|
165
|
-
2. **存储时需要区分**:不回显原始值,而是用 `"******"` 或空值占位。
|
|
166
|
-
3. **Schema 中可以显式标记**,让前端 UI 渲染器知道这是一个密钥字段。
|
|
167
|
-
|
|
168
|
-
---
|
|
169
|
-
|
|
170
|
-
## 扩展规范方案
|
|
171
|
-
|
|
172
|
-
在 `x-ui` 里增加 `component: "secretInput"`,并支持以下属性:
|
|
173
|
-
|
|
174
|
-
| 字段名 | 类型 | 说明 |
|
|
175
|
-
| ------------- | ------- | --------------------------- |
|
|
176
|
-
| `component` | string | 固定为 `"secretInput"`,渲染密码输入框 |
|
|
177
|
-
| `label` | string | 字段标签 |
|
|
178
|
-
| `description` | string | 字段说明 |
|
|
179
|
-
| `placeholder` | string | 占位符(如 `请输入 API Key`) |
|
|
180
|
-
| `revealable` | boolean | 是否允许用户点按钮临时查看明文 |
|
|
181
|
-
| `maskSymbol` | string | 遮罩符号(默认 `*`) |
|
|
182
|
-
| `persist` | boolean | 是否持久保存,false 时表示仅运行时使用,不落盘 |
|
|
183
|
-
|
|
184
|
-
---
|
|
185
|
-
|
|
186
|
-
## 示例 Schema
|
|
187
|
-
|
|
188
|
-
```ts
|
|
189
|
-
configSchema: {
|
|
190
|
-
type: 'object',
|
|
191
|
-
properties: {
|
|
192
|
-
apiKey: {
|
|
193
|
-
type: 'string',
|
|
194
|
-
description: 'OpenAI API Key',
|
|
195
|
-
'x-ui': {
|
|
196
|
-
component: 'secretInput',
|
|
197
|
-
label: 'API Key',
|
|
198
|
-
placeholder: '请输入您的 OpenAI API Key',
|
|
199
|
-
revealable: true,
|
|
200
|
-
maskSymbol: '*',
|
|
201
|
-
persist: true
|
|
202
|
-
}
|
|
203
|
-
},
|
|
204
|
-
provider: {
|
|
205
|
-
type: 'string',
|
|
206
|
-
enum: ['openai', 'anthropic', 'azure'],
|
|
207
|
-
'x-ui': {
|
|
208
|
-
component: 'modelProviderSelect',
|
|
209
|
-
label: 'Provider'
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
},
|
|
213
|
-
required: ['apiKey', 'provider']
|
|
214
|
-
}
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
|
-
## 前端渲染效果
|
|
220
|
-
|
|
221
|
-
* `apiKey` 显示为 **密码输入框**,默认遮罩显示。
|
|
222
|
-
* 如果 `revealable: true`,UI 上有 👁 按钮,用户可切换显示/隐藏。
|
|
223
|
-
* 编辑配置时,如果后端返回 `"******"` 代表已有值,用户不改就继续使用原值。
|
|
224
|
-
|
|
225
|
-
---
|
|
226
|
-
|
|
227
|
-
## 额外安全考虑
|
|
228
|
-
|
|
229
|
-
* 前端表单提交时,如果 `apiKey === "******"`,表示不修改,后端应保留旧值。
|
|
230
|
-
* 如果提交了新值,则后端替换旧值。
|
|
231
|
-
* 日志、导出配置时跳过 SECRET 字段。
|
|
232
|
-
|
|
233
|
-
---
|
|
234
|
-
|
|
235
|
-
要不要我帮你把 **SECRET 字段** 再抽象成一个通用接口(比如 `ISchemaSecretField`),这样和普通字段区分得更清晰?
|
|
236
|
-
|
|
237
|
-
## 抽象成一个通用接口
|
|
238
|
-
|
|
239
|
-
👌好的,我们把 **SECRET 字段**抽象成一个通用接口,既能和普通字段保持一致,又能明确标识“这是一个需要特殊处理的敏感字段”。
|
|
240
|
-
|
|
241
|
-
---
|
|
242
|
-
|
|
243
|
-
# 🔐 通用接口设计
|
|
244
|
-
|
|
245
|
-
```ts
|
|
246
|
-
/**
|
|
247
|
-
* 通用 UI Schema 字段定义
|
|
248
|
-
*/
|
|
249
|
-
export interface ISchemaUIBase {
|
|
250
|
-
component: string; // UI 组件类型
|
|
251
|
-
label?: string; // 字段标签
|
|
252
|
-
description?: string; // 字段说明
|
|
253
|
-
placeholder?: string; // 输入占位符
|
|
254
|
-
order?: number; // UI 显示顺序
|
|
255
|
-
required?: boolean; // 是否必填
|
|
256
|
-
visibleWhen?: Record<string, any>; // 条件渲染
|
|
257
|
-
enabledWhen?: Record<string, any>; // 条件启用
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Secret 字段扩展
|
|
262
|
-
*/
|
|
263
|
-
export interface ISchemaSecretField extends ISchemaUIBase {
|
|
264
|
-
component: 'secretInput'; // 固定组件类型
|
|
265
|
-
revealable?: boolean; // 是否允许明文显示(👁 按钮)
|
|
266
|
-
maskSymbol?: string; // 遮罩符号(默认 *)
|
|
267
|
-
persist?: boolean; // 是否持久保存,false 表示仅运行时使用
|
|
268
|
-
}
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
这样 SECRET 字段就和普通 UI 字段继承同一套规范,只是 **多了一些敏感信息处理的扩展属性**。
|
|
272
|
-
|
|
273
|
-
---
|
|
274
|
-
|
|
275
|
-
# 🔧 使用示例
|
|
276
|
-
|
|
277
|
-
```ts
|
|
278
|
-
configSchema: {
|
|
279
|
-
type: 'object',
|
|
280
|
-
properties: {
|
|
281
|
-
apiKey: {
|
|
282
|
-
type: 'string',
|
|
283
|
-
description: 'OpenAI API Key',
|
|
284
|
-
'x-ui': <ISchemaSecretField>{
|
|
285
|
-
component: 'secretInput',
|
|
286
|
-
label: 'API Key',
|
|
287
|
-
placeholder: '请输入您的 OpenAI API Key',
|
|
288
|
-
revealable: true,
|
|
289
|
-
maskSymbol: '*',
|
|
290
|
-
persist: true
|
|
291
|
-
}
|
|
292
|
-
},
|
|
293
|
-
provider: {
|
|
294
|
-
type: 'string',
|
|
295
|
-
enum: ['openai', 'anthropic', 'azure'],
|
|
296
|
-
'x-ui': {
|
|
297
|
-
component: 'modelProviderSelect',
|
|
298
|
-
label: 'Provider'
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
},
|
|
302
|
-
required: ['apiKey', 'provider']
|
|
303
|
-
}
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
---
|
|
307
|
-
|
|
308
|
-
# 🔒 前端处理规范
|
|
309
|
-
|
|
310
|
-
1. **渲染时**:
|
|
311
|
-
|
|
312
|
-
* `secretInput` 渲染为密码框(`type=password`)。
|
|
313
|
-
* 如果 `revealable: true`,增加 👁 切换按钮。
|
|
314
|
-
|
|
315
|
-
2. **加载配置时**:
|
|
316
|
-
|
|
317
|
-
* 后端返回 `******` 代表已有值,前端不展示真实内容。
|
|
318
|
-
|
|
319
|
-
3. **保存配置时**:
|
|
320
|
-
|
|
321
|
-
* 如果提交的值仍为 `******` → 保持旧值不变。
|
|
322
|
-
* 如果提交了新值 → 更新存储并覆盖旧值。
|
|
323
|
-
|
|
324
|
-
4. **导出配置/日志**:
|
|
325
|
-
|
|
326
|
-
* 忽略 SECRET 字段或输出 `******`,避免泄露。
|
|
327
|
-
|
|
328
|
-
---
|
|
329
|
-
|
|
330
|
-
这样以后 `secretInput` 就是一个 **一级公民 UI 组件**,和 `textInput`、`select` 一样可以被 schema 统一驱动。
|
|
331
|
-
|
|
332
|
-
要不要我再帮你定义一个 **完整的 ISchemaUIComponent 联合类型**,把所有 `x-ui` 组件(select、slider、secretInput、promptEditor 等)都规范起来?
|
package/jest.config.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
import { readFileSync } from 'fs'
|
|
3
|
-
|
|
4
|
-
// Reading the SWC compilation config and remove the "exclude"
|
|
5
|
-
// for the test files to be compiled by SWC
|
|
6
|
-
const { exclude: _, ...swcJestConfig } = JSON.parse(readFileSync(`${__dirname}/.swcrc`, 'utf-8'))
|
|
7
|
-
|
|
8
|
-
// disable .swcrc look-up by SWC core because we're passing in swcJestConfig ourselves.
|
|
9
|
-
// If we do not disable this, SWC Core will read .swcrc and won't transform our test files due to "exclude"
|
|
10
|
-
if (swcJestConfig.swcrc === undefined) {
|
|
11
|
-
swcJestConfig.swcrc = false
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// Uncomment if using global setup/teardown files being transformed via swc
|
|
15
|
-
// https://nx.dev/packages/jest/documents/overview#global-setup/teardown-with-nx-libraries
|
|
16
|
-
// jest needs EsModule Interop to find the default exported setup/teardown functions
|
|
17
|
-
// swcJestConfig.module.noInterop = false;
|
|
18
|
-
|
|
19
|
-
export default {
|
|
20
|
-
displayName: 'plugin-sdk',
|
|
21
|
-
preset: '../../jest.preset.js',
|
|
22
|
-
transform: {
|
|
23
|
-
'^.+\\.[tj]s$': ['@swc/jest', swcJestConfig]
|
|
24
|
-
},
|
|
25
|
-
moduleFileExtensions: ['ts', 'js', 'html'],
|
|
26
|
-
testEnvironment: 'node',
|
|
27
|
-
coverageDirectory: '../../coverage/packages/plugin-sdk'
|
|
28
|
-
}
|
package/project.json
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "plugin-sdk",
|
|
3
|
-
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
-
"sourceRoot": "packages/plugin-sdk/src",
|
|
5
|
-
"projectType": "library",
|
|
6
|
-
"tags": [],
|
|
7
|
-
"targets": {
|
|
8
|
-
"build": {
|
|
9
|
-
"executor": "@nx/rollup:rollup",
|
|
10
|
-
"outputs": ["{options.outputPath}"],
|
|
11
|
-
"options": {
|
|
12
|
-
"outputPath": "dist/packages/plugin-sdk",
|
|
13
|
-
"main": "packages/plugin-sdk/src/index.ts",
|
|
14
|
-
"tsConfig": "packages/plugin-sdk/tsconfig.lib.json",
|
|
15
|
-
"assets": [],
|
|
16
|
-
"project": "packages/plugin-sdk/package.json",
|
|
17
|
-
"compiler": "swc",
|
|
18
|
-
"format": ["cjs", "esm"]
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
"test": {
|
|
22
|
-
"executor": "@nx/jest:jest",
|
|
23
|
-
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
|
24
|
-
"options": {
|
|
25
|
-
"jestConfig": "packages/plugin-sdk/jest.config.ts"
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export * from './lib/plugin'
|
|
2
|
-
export * from './lib/plugin.interface'
|
|
3
|
-
export * from './lib/plugin-metadata'
|
|
4
|
-
export * from './lib/types'
|
|
5
|
-
export * from './lib/logger'
|
|
6
|
-
export * from './lib/knowledge'
|
|
7
|
-
export * from './lib/integration/index'
|
|
8
|
-
export * from './lib/workflow/index'
|
|
9
|
-
export * from './lib/vectorstore/index'
|
|
10
|
-
export * from './lib/rag/index'
|
|
11
|
-
export * from './lib/toolset/index'
|
|
12
|
-
export * from './lib/core/index'
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import fsPromises from 'fs/promises'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import { FileSystemPermission } from './permissions'
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Restricted FileSystem based on granted permissions
|
|
8
|
-
*/
|
|
9
|
-
export class XpFileSystem {
|
|
10
|
-
private allowedOps: Set<'read' | 'write' | 'delete' | 'list'>
|
|
11
|
-
private scope: string[] | undefined
|
|
12
|
-
|
|
13
|
-
constructor(permission: FileSystemPermission, private basePath: string, private baseUrl: string) {
|
|
14
|
-
this.allowedOps = new Set(permission.operations)
|
|
15
|
-
this.scope = permission.scope
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Check if operation is allowed
|
|
20
|
-
*/
|
|
21
|
-
private ensureAllowed(op: 'read' | 'write' | 'delete' | 'list') {
|
|
22
|
-
if (!this.allowedOps.has(op)) {
|
|
23
|
-
throw new Error(`Permission denied: ${op} operation not allowed`)
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Check if path is within scope
|
|
29
|
-
*/
|
|
30
|
-
private ensureInScope(targetPath: string) {
|
|
31
|
-
if (!this.scope || this.scope.length === 0) return
|
|
32
|
-
const resolved = path.resolve(targetPath)
|
|
33
|
-
for (const s of this.scope) {
|
|
34
|
-
const absScope = path.resolve(s)
|
|
35
|
-
if (resolved.startsWith(absScope)) return
|
|
36
|
-
}
|
|
37
|
-
throw new Error(`Permission denied: path "${targetPath}" is out of scope`)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
fullPath(filePath: string): string {
|
|
41
|
-
return path.join(this.basePath, filePath)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Read file contents
|
|
46
|
-
*/
|
|
47
|
-
async readFile(filePath: string, encoding: BufferEncoding = 'utf-8') {
|
|
48
|
-
this.ensureAllowed('read')
|
|
49
|
-
const fullPath = this.fullPath(filePath)
|
|
50
|
-
this.ensureInScope(fullPath)
|
|
51
|
-
return await fsPromises.readFile(fullPath)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Write file contents
|
|
56
|
-
*/
|
|
57
|
-
async writeFile(filePath: string, content: string | Buffer): Promise<string> {
|
|
58
|
-
this.ensureAllowed('write')
|
|
59
|
-
const fullPath = this.fullPath(filePath)
|
|
60
|
-
this.ensureInScope(fullPath)
|
|
61
|
-
await fsPromises.mkdir(path.dirname(fullPath), { recursive: true })
|
|
62
|
-
await fsPromises.writeFile(fullPath, content)
|
|
63
|
-
const url = new URL(filePath, this.baseUrl)
|
|
64
|
-
return url.href
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Delete a file
|
|
69
|
-
*/
|
|
70
|
-
async deleteFile(filePath: string): Promise<void> {
|
|
71
|
-
this.ensureAllowed('delete')
|
|
72
|
-
this.ensureInScope(filePath)
|
|
73
|
-
await fsPromises.unlink(filePath)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* List directory contents
|
|
78
|
-
*/
|
|
79
|
-
async listDir(dirPath: string): Promise<string[]> {
|
|
80
|
-
this.ensureAllowed('list')
|
|
81
|
-
this.ensureInScope(dirPath)
|
|
82
|
-
return fsPromises.readdir(dirPath)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Utility: check if a file or directory exists
|
|
87
|
-
*/
|
|
88
|
-
async exists(targetPath: string): Promise<boolean> {
|
|
89
|
-
try {
|
|
90
|
-
await fsPromises.access(targetPath)
|
|
91
|
-
return true
|
|
92
|
-
} catch {
|
|
93
|
-
return false
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
package/src/lib/core/index.ts
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ===============================
|
|
3
|
-
* Unified Permissions Definition
|
|
4
|
-
* ===============================
|
|
5
|
-
* Used by Agent / Plugin developers to declare required capabilities.
|
|
6
|
-
* Core system will check and inject allowed resources accordingly.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Base Permission type
|
|
11
|
-
*/
|
|
12
|
-
export interface BasePermission {
|
|
13
|
-
type: string; // Discriminator
|
|
14
|
-
description?: string; // Optional description for UI
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* 1. LLM Permission
|
|
19
|
-
* Example: { type: 'llm', provider: 'openai', capability: 'vision' }
|
|
20
|
-
*/
|
|
21
|
-
export interface LLMPermission extends BasePermission {
|
|
22
|
-
type: 'llm';
|
|
23
|
-
provider?: string; // e.g. "openai", "anthropic", "azure", "ollama"
|
|
24
|
-
capability: 'text' | 'chat' | 'vision' | 'embedding';
|
|
25
|
-
scope?: string[]; // Allowed model names, e.g. ["gpt-4", "gpt-4-vision-preview"]
|
|
26
|
-
maxTokens?: number; // Maximum output tokens allowed
|
|
27
|
-
rateLimit?: { rps: number }; // Rate limit per second
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* 2. Vector Store Permission
|
|
32
|
-
* Example: { type: 'vectorstore', provider: 'pinecone', operations: ['insert', 'query'] }
|
|
33
|
-
*/
|
|
34
|
-
export interface VectorStorePermission extends BasePermission {
|
|
35
|
-
type: 'vectorstore';
|
|
36
|
-
provider: string; // "pinecone" | "milvus" | "chromadb" | ...
|
|
37
|
-
operations: Array<'insert' | 'query' | 'delete'>;
|
|
38
|
-
scope?: string[]; // Restrict to index / collection
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* 3. Knowledge Base Permission
|
|
43
|
-
* Example: { type: 'knowledge', operations: ['read', 'write'], scope: ['kb_123'] }
|
|
44
|
-
*/
|
|
45
|
-
export interface KnowledgePermission extends BasePermission {
|
|
46
|
-
type: 'knowledge';
|
|
47
|
-
operations: Array<'read' | 'write' | 'update' | 'delete'>;
|
|
48
|
-
scope?: string[]; // Restrict to certain KB IDs
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* 4. File System Permission
|
|
53
|
-
* Example: { type: 'filesystem', operations: ['read', 'write'], scope: ['/documents', '/images'] }
|
|
54
|
-
*/
|
|
55
|
-
export interface FileSystemPermission extends BasePermission {
|
|
56
|
-
type: 'filesystem';
|
|
57
|
-
operations: Array<'read' | 'write' | 'delete' | 'list'>;
|
|
58
|
-
scope?: string[]; // Restrict to certain directories or file types
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* 5. Integration Permission
|
|
63
|
-
* Example: { type: 'integration', service: 'feishu', operations: ['read', 'write'] }
|
|
64
|
-
*/
|
|
65
|
-
export interface IntegrationPermission extends BasePermission {
|
|
66
|
-
type: 'integration';
|
|
67
|
-
service: string; // e.g. 'slack', 'feishu', 'jira', 'sap', etc.
|
|
68
|
-
operations?: Array<'read' | 'write' | 'update' | 'delete'>;
|
|
69
|
-
scope?: string[];
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// /**
|
|
73
|
-
// * 4. Document Permission
|
|
74
|
-
// * Example: { type: 'document', formats: ['pdf'], operations: ['load', 'transform'] }
|
|
75
|
-
// */
|
|
76
|
-
// export interface DocumentPermission extends BasePermission {
|
|
77
|
-
// type: 'document';
|
|
78
|
-
// formats: string[]; // ['pdf', 'pptx', 'docx', 'image', 'html', 'md']
|
|
79
|
-
// operations: Array<'load' | 'transform' | 'ocr' | 'imageUnderstanding'>;
|
|
80
|
-
// }
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Union type for all permissions
|
|
84
|
-
*/
|
|
85
|
-
export type Permission =
|
|
86
|
-
| LLMPermission
|
|
87
|
-
| VectorStorePermission
|
|
88
|
-
| KnowledgePermission
|
|
89
|
-
| FileSystemPermission
|
|
90
|
-
| IntegrationPermission
|
|
91
|
-
// | DocumentPermission
|
|
92
|
-
// | ExternalPermission;
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Permissions array type
|
|
96
|
-
*/
|
|
97
|
-
export type Permissions = Permission[];
|
package/src/lib/core/schema.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 通用 UI Schema 字段定义
|
|
3
|
-
*/
|
|
4
|
-
export interface ISchemaUIBase {
|
|
5
|
-
component: string; // UI 组件类型
|
|
6
|
-
label?: string; // 字段标签
|
|
7
|
-
description?: string; // 字段说明
|
|
8
|
-
placeholder?: string; // 输入占位符
|
|
9
|
-
order?: number; // UI 显示顺序
|
|
10
|
-
required?: boolean; // 是否必填
|
|
11
|
-
visibleWhen?: Record<string, any>; // 条件渲染
|
|
12
|
-
enabledWhen?: Record<string, any>; // 条件启用
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Secret 字段扩展
|
|
17
|
-
*/
|
|
18
|
-
export interface ISchemaSecretField extends ISchemaUIBase {
|
|
19
|
-
component: 'secretInput'; // 固定组件类型
|
|
20
|
-
revealable?: boolean; // 是否允许明文显示(👁 按钮)
|
|
21
|
-
maskSymbol?: string; // 遮罩符号(默认 *)
|
|
22
|
-
persist?: boolean; // 是否持久保存,false 表示仅运行时使用
|
|
23
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@nestjs/common'
|
|
2
|
-
import { DiscoveryService, Reflector } from '@nestjs/core'
|
|
3
|
-
import { BaseStrategyRegistry } from '../strategy'
|
|
4
|
-
import { INTEGRATION_STRATEGY } from './strategy.decorator'
|
|
5
|
-
import { IntegrationStrategy } from './strategy.interface'
|
|
6
|
-
|
|
7
|
-
@Injectable()
|
|
8
|
-
export class IntegrationStrategyRegistry extends BaseStrategyRegistry<IntegrationStrategy> {
|
|
9
|
-
constructor(discoveryService: DiscoveryService, reflector: Reflector) {
|
|
10
|
-
super(INTEGRATION_STRATEGY, discoveryService, reflector)
|
|
11
|
-
}
|
|
12
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { IIntegration } from '@metad/contracts'
|
|
2
|
-
import { Document } from 'langchain/document'
|
|
3
|
-
|
|
4
|
-
export type TKnowledgeStrategyParams = {
|
|
5
|
-
query: string;
|
|
6
|
-
k: number;
|
|
7
|
-
filter: Record<string, any>
|
|
8
|
-
options: {
|
|
9
|
-
knowledgebaseId: string
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface KnowledgeStrategy {
|
|
14
|
-
execute(integration: IIntegration, payload: TKnowledgeStrategyParams): Promise<{ chunks: [Document, number][] }>
|
|
15
|
-
}
|