vools-actus 0.7.8__py3-none-any.whl
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.
- vools/actus/ACTUS_SCHEMA_SPEC.md +518 -0
- vools/actus/README.md +46 -0
- vools/actus/__init__.py +136 -0
- vools/actus/actions/__init__.py +47 -0
- vools/actus/actions/basics/__init__.py +32 -0
- vools/actus/actions/basics/calculator.py +46 -0
- vools/actus/actions/basics/image_viewer.py +46 -0
- vools/actus/actions/basics/text_editor.py +46 -0
- vools/actus/actions/basics/todo_list.py +46 -0
- vools/actus/adapter.py +701 -0
- vools/actus/author.py +368 -0
- vools/actus/bugreport.py +273 -0
- vools/actus/calllog.py +297 -0
- vools/actus/cli.py +2423 -0
- vools/actus/concurrency.py +143 -0
- vools/actus/constants.py +30 -0
- vools/actus/cost.py +83 -0
- vools/actus/dependency.py +765 -0
- vools/actus/desktop.py +176 -0
- vools/actus/errors.py +30 -0
- vools/actus/eventbus.py +180 -0
- vools/actus/evolution.py +651 -0
- vools/actus/executor.py +772 -0
- vools/actus/export.py +196 -0
- vools/actus/frontmatter.py +113 -0
- vools/actus/health.py +247 -0
- vools/actus/highlight.py +263 -0
- vools/actus/importsys.py +331 -0
- vools/actus/indexer.py +191 -0
- vools/actus/installer.py +646 -0
- vools/actus/intent.py +175 -0
- vools/actus/jump.py +545 -0
- vools/actus/loophelpers.py +217 -0
- vools/actus/mcp_server.py +2140 -0
- vools/actus/mcp_sse.py +160 -0
- vools/actus/mdtest.py +363 -0
- vools/actus/model.py +255 -0
- vools/actus/notify.py +351 -0
- vools/actus/omega.py +767 -0
- vools/actus/omega_strong.py +469 -0
- vools/actus/panel.py +261 -0
- vools/actus/panel_init.py +5 -0
- vools/actus/process_state.py +21 -0
- vools/actus/project.py +676 -0
- vools/actus/project_io.py +235 -0
- vools/actus/pytest_compat.py +346 -0
- vools/actus/records.py +288 -0
- vools/actus/registry.py +705 -0
- vools/actus/runtimes.py +579 -0
- vools/actus/sandbox.py +142 -0
- vools/actus/scaffold.py +347 -0
- vools/actus/security.py +466 -0
- vools/actus/selfdrive.py +435 -0
- vools/actus/selfdrive_worker.py +245 -0
- vools/actus/selfheal.py +321 -0
- vools/actus/template.py +390 -0
- vools/actus/tkdialog.py +797 -0
- vools/actus/triggers.py +719 -0
- vools/actus/trust.py +52 -0
- vools/actus/trust_model.py +616 -0
- vools/actus/validate.py +443 -0
- vools/actus/vault.py +356 -0
- vools/actus/visibility.py +567 -0
- vools/actus/viz.py +323 -0
- vools/actus/webhook.py +531 -0
- vools/actus/webhook_server.py +134 -0
- vools/actus/winstyle.py +67 -0
- vools/actus/workflow.py +773 -0
- vools_actus-0.7.8.dist-info/METADATA +435 -0
- vools_actus-0.7.8.dist-info/RECORD +74 -0
- vools_actus-0.7.8.dist-info/WHEEL +5 -0
- vools_actus-0.7.8.dist-info/entry_points.txt +2 -0
- vools_actus-0.7.8.dist-info/licenses/LICENSE +201 -0
- vools_actus-0.7.8.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
# `.actus.schema.md` 硬性约定格式规范
|
|
2
|
+
|
|
3
|
+
> **状态**: v0.1 — 内部规范草案
|
|
4
|
+
> **替代目标**: `contracts/action.schema.json`、`#!cfg` 内联元数据块、`#!entry` 等文件级指令
|
|
5
|
+
> **核心原则**: 单一 `.md` 文件 = 完全自包含的动作定义,**无 JSON 文件、无外部 schema 引用**
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. 文件命名与位置
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
actions/
|
|
13
|
+
convert-file-to-markdown.actus.schema.md
|
|
14
|
+
send-email.actus.schema.md
|
|
15
|
+
scrape-webpage.actus.schema.md
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- 后缀固定为 `.actus.schema.md`
|
|
19
|
+
- 放置在 `actions/` 子目录中(按平台/功能可再分子目录)
|
|
20
|
+
- 文件名本身不参与动作标识,`id` 字段由 front-matter 定义
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 2. 文件结构总览(顺序不可调换)
|
|
25
|
+
|
|
26
|
+
一个合法的 `.actus.schema.md` 文件**必须**按以下顺序组成:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
┌─────────────────────────────────────────────┐
|
|
30
|
+
│ 区域 0: AIGC 合规 front-matter (YAML) │ ← strip_frontmatter 剥离
|
|
31
|
+
├─────────────────────────────────────────────┤
|
|
32
|
+
│ 区域 1: 动作元数据 (YAML front-matter) │ ← 替代 #!cfg JSON
|
|
33
|
+
├─────────────────────────────────────────────┤
|
|
34
|
+
│ 区域 2: 描述文档 (Markdown 正文) │ ← 人类可读说明
|
|
35
|
+
├─────────────────────────────────────────────┤
|
|
36
|
+
│ 区域 3: 输入契约 (JSON Schema 代码块) │ ← 替代 args JSON
|
|
37
|
+
├─────────────────────────────────────────────┤
|
|
38
|
+
│ 区域 4: 依赖声明 (YAML 代码块) │ ← pip 依赖 / 系统依赖
|
|
39
|
+
├─────────────────────────────────────────────┤
|
|
40
|
+
│ 区域 5: 触发器声明 (YAML 代码块) │ ← cron/watch/webhook/hotkey
|
|
41
|
+
├─────────────────────────────────────────────┤
|
|
42
|
+
│ 区域 6: 权限声明 (YAML 代码块) │ ← 所需权限白名单
|
|
43
|
+
├─────────────────────────────────────────────┤
|
|
44
|
+
│ 区域 7: 实现代码 (带 tag 的代码块) │ ← 替代 #!entry 指向的块
|
|
45
|
+
└─────────────────────────────────────────────┘
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 3. 区域 0: AIGC 合规 front-matter
|
|
51
|
+
|
|
52
|
+
```markdown
|
|
53
|
+
---
|
|
54
|
+
aigc: true
|
|
55
|
+
generated-by: atomcode
|
|
56
|
+
generated-at: 2026-09-15T10:30:00Z
|
|
57
|
+
---
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**规则**:
|
|
61
|
+
- 必须位于文件**第一行**
|
|
62
|
+
- 以 `---` 开始、`---` 结束
|
|
63
|
+
- 由 `strip_frontmatter()` 剥离,**不参与动作解析**
|
|
64
|
+
- 仅作合规留痕,不影响动作语义
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 4. 区域 1: 动作元数据 (YAML front-matter)
|
|
69
|
+
|
|
70
|
+
```markdown
|
|
71
|
+
---
|
|
72
|
+
id: convert-file-to-markdown
|
|
73
|
+
name: Convert File to Markdown
|
|
74
|
+
version: 1.0.0
|
|
75
|
+
trust: sandbox
|
|
76
|
+
entry: main
|
|
77
|
+
description: Convert PDF/Word/PPT/Excel/image/audio files to Markdown via MarkItDown
|
|
78
|
+
author: vools
|
|
79
|
+
platform: desktop
|
|
80
|
+
tags: [convert, markdown, ocr, document]
|
|
81
|
+
max_instances: 1
|
|
82
|
+
deprecated: false
|
|
83
|
+
---
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**规则**:
|
|
87
|
+
|
|
88
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
89
|
+
|------|------|------|------|
|
|
90
|
+
| `id` | string | ✅ | 全局唯一动作标识,kebab-case |
|
|
91
|
+
| `name` | string | ✅ | 人类可读名称 |
|
|
92
|
+
| `version` | string | ✅ | semver 格式 |
|
|
93
|
+
| `trust` | enum | ✅ | `audit` / `trusted` / `sandbox` |
|
|
94
|
+
| `entry` | string | ✅ | 实现代码块的 tag 名 |
|
|
95
|
+
| `description` | string | ✅ | 一句话描述 |
|
|
96
|
+
| `author` | string | ❌ | 作者标识 |
|
|
97
|
+
| `platform` | enum | ❌ | `desktop` / `web` / `macos` / `harmonyos` / `linux` |
|
|
98
|
+
| `tags` | list | ❌ | 分类标签 |
|
|
99
|
+
| `max_instances` | int | ❌ | 最大并发实例数,0=无上限 |
|
|
100
|
+
| `deprecated` | bool | ❌ | 是否已弃用 |
|
|
101
|
+
|
|
102
|
+
**硬性约束**:
|
|
103
|
+
- 此 front-matter 是**唯一权威元数据来源**,不再读取 `#!cfg` JSON 块
|
|
104
|
+
- `entry` 值必须匹配区域 7 中某个代码块的 `tag`
|
|
105
|
+
- `trust` 取值必须在 `('audit', 'trusted', 'sandbox')` 中
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 5. 区域 2: 描述文档 (Markdown 正文)
|
|
110
|
+
|
|
111
|
+
```markdown
|
|
112
|
+
# Convert File to Markdown
|
|
113
|
+
|
|
114
|
+
Convert any supported file format to Markdown using Microsoft's MarkItDown library.
|
|
115
|
+
|
|
116
|
+
## Supported Formats
|
|
117
|
+
|
|
118
|
+
- PDF (.pdf)
|
|
119
|
+
- Word (.docx)
|
|
120
|
+
- PowerPoint (.pptx)
|
|
121
|
+
- Excel (.xlsx)
|
|
122
|
+
- Images (.jpg, .png, .gif) — with OCR
|
|
123
|
+
- Audio (.mp3, .wav) — with transcription
|
|
124
|
+
- HTML, CSV, JSON, XML, EPub
|
|
125
|
+
|
|
126
|
+
## Usage
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
result = convert_file_to_markdown("report.pdf", enable_ocr=True)
|
|
130
|
+
print(result)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Notes
|
|
134
|
+
|
|
135
|
+
- Requires `pip install markitdown[all]`
|
|
136
|
+
- OCR requires additional system dependencies (tesseract)
|
|
137
|
+
- Audio transcription requires whisper
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**规则**:
|
|
141
|
+
- 自由格式 Markdown,人类可读
|
|
142
|
+
- 由 `vools.md` 解析器处理
|
|
143
|
+
- 不参与机器校验,但建议包含 Supported Formats / Usage / Notes 段
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 6. 区域 3: 输入契约 (JSON Schema 代码块)
|
|
148
|
+
|
|
149
|
+
```markdown
|
|
150
|
+
## Input Schema
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"type": "object",
|
|
155
|
+
"properties": {
|
|
156
|
+
"file_path": {
|
|
157
|
+
"type": "string",
|
|
158
|
+
"description": "输入文件路径(绝对或相对路径)"
|
|
159
|
+
},
|
|
160
|
+
"enable_ocr": {
|
|
161
|
+
"type": "boolean",
|
|
162
|
+
"default": false,
|
|
163
|
+
"description": "是否启用 OCR 识别图片中的文字"
|
|
164
|
+
},
|
|
165
|
+
"output_path": {
|
|
166
|
+
"type": "string",
|
|
167
|
+
"description": "输出 Markdown 文件路径(可选,默认返回字符串)"
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
"required": ["file_path"]
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**规则**:
|
|
176
|
+
- 代码块语言标记为 `json`
|
|
177
|
+
- 代码块指令为 `#!args`(或 `#!input`)
|
|
178
|
+
- 内容必须是合法的 JSON Schema (Draft-7)
|
|
179
|
+
- 由 `check_args_schema()` 校验
|
|
180
|
+
- 运行时由 executor 用于参数校验和 UI 表单生成
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## 7. 区域 4: 依赖声明 (YAML 代码块)
|
|
185
|
+
|
|
186
|
+
```markdown
|
|
187
|
+
## Dependencies
|
|
188
|
+
|
|
189
|
+
```yaml
|
|
190
|
+
pip:
|
|
191
|
+
- markitdown[all]>=0.0.1
|
|
192
|
+
system:
|
|
193
|
+
- tesseract-ocr # 可选,OCR 时需要
|
|
194
|
+
- ffmpeg # 可选,音频转写时需要
|
|
195
|
+
env:
|
|
196
|
+
- MARKITDOWN_CACHE_DIR=/tmp/markitdown
|
|
197
|
+
```
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**规则**:
|
|
201
|
+
- 代码块语言标记为 `yaml`
|
|
202
|
+
- 代码块指令为 `#!deps` 或 `#!dependencies`
|
|
203
|
+
- `pip`: pip 包列表(支持版本约束)
|
|
204
|
+
- `system`: 系统包名(仅作声明,不自动安装)
|
|
205
|
+
- `env`: 环境变量声明
|
|
206
|
+
- 由 `dependency.py` 解析
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 8. 区域 5: 触发器声明 (YAML 代码块)
|
|
211
|
+
|
|
212
|
+
```markdown
|
|
213
|
+
## Triggers
|
|
214
|
+
|
|
215
|
+
```yaml
|
|
216
|
+
- type: watch
|
|
217
|
+
path: ./inbox/
|
|
218
|
+
pattern: "*.pdf"
|
|
219
|
+
debounce_ms: 1000
|
|
220
|
+
|
|
221
|
+
- type: cron
|
|
222
|
+
expr: "0 9 * * 1-5"
|
|
223
|
+
timezone: Asia/Shanghai
|
|
224
|
+
|
|
225
|
+
- type: webhook
|
|
226
|
+
path: "/hooks/convert"
|
|
227
|
+
secret_header: "X-Actus-Secret"
|
|
228
|
+
```
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**规则**:
|
|
232
|
+
- 代码块语言标记为 `yaml`
|
|
233
|
+
- 代码块指令为 `#!triggers`
|
|
234
|
+
- 每个触发器必须是合法对象:
|
|
235
|
+
- `cron`: 5 字段 cron 表达式
|
|
236
|
+
- `watch`: 有效路径字符串
|
|
237
|
+
- `webhook`: 可选 `secret_header`
|
|
238
|
+
- `hotkey`: 非空 `key`
|
|
239
|
+
- `on_startup`: 无额外字段
|
|
240
|
+
- 由 `check_triggers()` 校验
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## 9. 区域 6: 权限声明 (YAML 代码块)
|
|
245
|
+
|
|
246
|
+
```markdown
|
|
247
|
+
## Permissions
|
|
248
|
+
|
|
249
|
+
```yaml
|
|
250
|
+
permissions:
|
|
251
|
+
- files:read
|
|
252
|
+
- files:write
|
|
253
|
+
- process:spawn
|
|
254
|
+
```
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**规则**:
|
|
258
|
+
- 代码块语言标记为 `yaml`
|
|
259
|
+
- 代码块指令为 `#!permissions`
|
|
260
|
+
- 每个权限必须在 `PERMISSIONS` 白名单中
|
|
261
|
+
- 由 `check_secrets()` / `check_permissions()` 校验
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## 10. 区域 7: 实现代码 (带 tag 的代码块)
|
|
266
|
+
|
|
267
|
+
```markdown
|
|
268
|
+
## Implementation
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
# tag: main
|
|
272
|
+
from markitdown import MarkItDown
|
|
273
|
+
from pathlib import Path
|
|
274
|
+
|
|
275
|
+
def convert_file_to_markdown(file_path: str, enable_ocr: bool = False, output_path: str = None) -> str:
|
|
276
|
+
"""Convert a file to Markdown."""
|
|
277
|
+
md = MarkItDown(enable_plugins=enable_ocr)
|
|
278
|
+
result = md.convert(file_path)
|
|
279
|
+
|
|
280
|
+
if output_path:
|
|
281
|
+
Path(output_path).write_text(result.markdown, encoding='utf-8')
|
|
282
|
+
|
|
283
|
+
return result.markdown
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
```python
|
|
287
|
+
# tag: helper
|
|
288
|
+
def _validate_file(path: str) -> bool:
|
|
289
|
+
"""Validate file exists and is supported."""
|
|
290
|
+
p = Path(path)
|
|
291
|
+
if not p.exists():
|
|
292
|
+
raise FileNotFoundError(f"File not found: {path}")
|
|
293
|
+
return True
|
|
294
|
+
```
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
**规则**:
|
|
298
|
+
- 代码块语言标记为实际语言(`python` / `javascript` / `bash` 等)
|
|
299
|
+
- 代码块指令为 `#tag: <name>`(定义块标签)
|
|
300
|
+
- `entry` 字段值必须匹配某个代码块的 `tag`
|
|
301
|
+
- 由 `check_entry_block()` 校验
|
|
302
|
+
- 支持多代码块,通过 tag 区分入口和辅助函数
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## 11. 完整示例
|
|
307
|
+
|
|
308
|
+
```markdown
|
|
309
|
+
---
|
|
310
|
+
aigc: true
|
|
311
|
+
generated-by: atomcode
|
|
312
|
+
generated-at: 2026-09-15T10:30:00Z
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
id: convert-file-to-markdown
|
|
317
|
+
name: Convert File to Markdown
|
|
318
|
+
version: 1.0.0
|
|
319
|
+
trust: sandbox
|
|
320
|
+
entry: main
|
|
321
|
+
description: Convert PDF/Word/PPT/Excel/image/audio files to Markdown via MarkItDown
|
|
322
|
+
author: vools
|
|
323
|
+
platform: desktop
|
|
324
|
+
tags: [convert, markdown, ocr, document]
|
|
325
|
+
max_instances: 1
|
|
326
|
+
deprecated: false
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
# Convert File to Markdown
|
|
330
|
+
|
|
331
|
+
Convert any supported file format to Markdown using Microsoft's MarkItDown library.
|
|
332
|
+
|
|
333
|
+
## Supported Formats
|
|
334
|
+
|
|
335
|
+
- PDF, Word, PowerPoint, Excel
|
|
336
|
+
- Images (with OCR)
|
|
337
|
+
- Audio (with transcription)
|
|
338
|
+
- HTML, CSV, JSON, XML, EPub
|
|
339
|
+
|
|
340
|
+
## Usage
|
|
341
|
+
|
|
342
|
+
```python
|
|
343
|
+
result = convert_file_to_markdown("report.pdf", enable_ocr=True)
|
|
344
|
+
print(result)
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Input Schema
|
|
348
|
+
|
|
349
|
+
```json
|
|
350
|
+
{
|
|
351
|
+
"type": "object",
|
|
352
|
+
"properties": {
|
|
353
|
+
"file_path": {
|
|
354
|
+
"type": "string",
|
|
355
|
+
"description": "输入文件路径"
|
|
356
|
+
},
|
|
357
|
+
"enable_ocr": {
|
|
358
|
+
"type": "boolean",
|
|
359
|
+
"default": false,
|
|
360
|
+
"description": "是否启用 OCR"
|
|
361
|
+
},
|
|
362
|
+
"output_path": {
|
|
363
|
+
"type": "string",
|
|
364
|
+
"description": "输出 Markdown 文件路径(可选)"
|
|
365
|
+
}
|
|
366
|
+
},
|
|
367
|
+
"required": ["file_path"]
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## Dependencies
|
|
372
|
+
|
|
373
|
+
```yaml
|
|
374
|
+
pip:
|
|
375
|
+
- markitdown[all]>=0.0.1
|
|
376
|
+
system:
|
|
377
|
+
- tesseract-ocr
|
|
378
|
+
env:
|
|
379
|
+
- MARKITDOWN_CACHE_DIR=/tmp/markitdown
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
## Triggers
|
|
383
|
+
|
|
384
|
+
```yaml
|
|
385
|
+
- type: watch
|
|
386
|
+
path: ./inbox/
|
|
387
|
+
pattern: "*.pdf"
|
|
388
|
+
debounce_ms: 1000
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
## Permissions
|
|
392
|
+
|
|
393
|
+
```yaml
|
|
394
|
+
permissions:
|
|
395
|
+
- files:read
|
|
396
|
+
- files:write
|
|
397
|
+
- process:spawn
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
## Implementation
|
|
401
|
+
|
|
402
|
+
```python
|
|
403
|
+
# tag: main
|
|
404
|
+
from markitdown import MarkItDown
|
|
405
|
+
from pathlib import Path
|
|
406
|
+
|
|
407
|
+
def convert_file_to_markdown(file_path: str, enable_ocr: bool = False, output_path: str = None) -> str:
|
|
408
|
+
"""Convert a file to Markdown."""
|
|
409
|
+
md = MarkItDown(enable_plugins=enable_ocr)
|
|
410
|
+
result = md.convert(file_path)
|
|
411
|
+
|
|
412
|
+
if output_path:
|
|
413
|
+
Path(output_path).write_text(result.markdown, encoding='utf-8')
|
|
414
|
+
|
|
415
|
+
return result.markdown
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
```python
|
|
419
|
+
# tag: helper
|
|
420
|
+
def _validate_file(path: str) -> bool:
|
|
421
|
+
"""Validate file exists and is supported."""
|
|
422
|
+
p = Path(path)
|
|
423
|
+
if not p.exists():
|
|
424
|
+
raise FileNotFoundError(f"File not found: {path}")
|
|
425
|
+
return True
|
|
426
|
+
```
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
## 12. 校验流水线适配
|
|
432
|
+
|
|
433
|
+
现有 7 步校验流水线需适配新格式:
|
|
434
|
+
|
|
435
|
+
| 步骤 | 原逻辑 | 新逻辑 |
|
|
436
|
+
|------|--------|--------|
|
|
437
|
+
| 1. parse_cfg | 解析 `#!cfg` JSON 块 | 解析 YAML front-matter |
|
|
438
|
+
| 2. schema_validate | 对照 `action.schema.json` | 对照内置 YAML schema 校验 |
|
|
439
|
+
| 3. entry_block | 检查 `#!entry` 与 tag 一致 | 检查 `entry` 字段与 tag 一致 |
|
|
440
|
+
| 4. args_schema | 校验 args JSON Schema | 校验 `Input Schema` 代码块 |
|
|
441
|
+
| 5. graph_validate | 依赖图无环 | 依赖图无环(不变) |
|
|
442
|
+
| 6. dry_run | 展示将要执行的块 | 展示将要执行的块(不变) |
|
|
443
|
+
| 7. sandbox_trial | 沙箱试跑 | 沙箱试跑(不变) |
|
|
444
|
+
|
|
445
|
+
---
|
|
446
|
+
|
|
447
|
+
## 13. 迁移路径
|
|
448
|
+
|
|
449
|
+
1. **新动作**: 直接按本规范编写 `.actus.schema.md`
|
|
450
|
+
2. **旧动作**: 提供迁移脚本 `migrate_actus_format.py`
|
|
451
|
+
- 读取 `#!cfg` JSON → 提取为 YAML front-matter
|
|
452
|
+
- 读取 `#!entry` → 写入 `entry` 字段
|
|
453
|
+
- 读取 `args` JSON → 写入 `## Input Schema` 代码块
|
|
454
|
+
- 保留原文件作为 `.bak`
|
|
455
|
+
3. **兼容性**: 过渡期同时支持 `#!cfg` 和 front-matter,优先 front-matter
|
|
456
|
+
|
|
457
|
+
---
|
|
458
|
+
|
|
459
|
+
## 14. 硬性约束清单
|
|
460
|
+
|
|
461
|
+
| # | 约束 | 校验位置 |
|
|
462
|
+
|---|------|----------|
|
|
463
|
+
| C01 | 文件后缀必须为 `.actus.schema.md` | 文件扫描器 |
|
|
464
|
+
| C02 | 区域 0 front-matter 必须存在 | `strip_frontmatter()` |
|
|
465
|
+
| C03 | 区域 1 front-matter 必须存在且合法 | `parse_cfg()` |
|
|
466
|
+
| C04 | `id` 必填、全局唯一 | `validate_action()` |
|
|
467
|
+
| C05 | `trust` ∈ {audit, trusted, sandbox} | `validate_action()` |
|
|
468
|
+
| C06 | `entry` 值必须匹配某个代码块的 tag | `check_entry_block()` |
|
|
469
|
+
| C07 | `## Input Schema` 代码块必须是合法 JSON Schema | `check_args_schema()` |
|
|
470
|
+
| C08 | `## Dependencies` 代码块必须是合法 YAML | `check_dependencies()` |
|
|
471
|
+
| C09 | `## Triggers` 代码块中每个触发器必须合法 | `check_triggers()` |
|
|
472
|
+
| C10 | `## Permissions` 代码块中每个权限必须在白名单 | `check_permissions()` |
|
|
473
|
+
| C11 | 区域 7 必须存在至少一个代码块 | `check_entry_block()` |
|
|
474
|
+
| C12 | 代码块 tag 必须唯一 | `validate_action()` |
|
|
475
|
+
|
|
476
|
+
---
|
|
477
|
+
|
|
478
|
+
## 15. 与现有系统的关系
|
|
479
|
+
|
|
480
|
+
```
|
|
481
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
482
|
+
│ 旧系统 │
|
|
483
|
+
│ ┌──────────────┐ ┌────────────────┐ ┌──────────────┐ │
|
|
484
|
+
│ │ #!cfg JSON │ │ action.schema │ │ #!entry │ │
|
|
485
|
+
│ │ (内联元数据) │ │ .json (外部) │ │ (文件级指令) │ │
|
|
486
|
+
│ └──────────────┘ └────────────────┘ └──────────────┘ │
|
|
487
|
+
└─────────────────────────────────────────────────────────────┘
|
|
488
|
+
│
|
|
489
|
+
▼ 迁移
|
|
490
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
491
|
+
│ 新系统 │
|
|
492
|
+
│ ┌──────────────────────────────────────────────────────────┐│
|
|
493
|
+
│ │ .actus.schema.md (单一文件) ││
|
|
494
|
+
│ │ ├── YAML front-matter (元数据) ││
|
|
495
|
+
│ │ ├── ## Input Schema (JSON Schema 代码块) ││
|
|
496
|
+
│ │ ├── ## Dependencies (YAML 代码块) ││
|
|
497
|
+
│ │ ├── ## Triggers (YAML 代码块) ││
|
|
498
|
+
│ │ ├── ## Permissions (YAML 代码块) ││
|
|
499
|
+
│ │ └── ## Implementation (带 tag 的代码块) ││
|
|
500
|
+
│ └──────────────────────────────────────────────────────────┘│
|
|
501
|
+
└─────────────────────────────────────────────────────────────┘
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
## 16. 常见问题
|
|
507
|
+
|
|
508
|
+
**Q: 为什么不用 JSON 文件?**
|
|
509
|
+
A: JSON 无法内联注释,无法承载 Markdown 文档,无法自描述。`.actus.schema.md` 是单一来源,diff 友好,PR review 友好。
|
|
510
|
+
|
|
511
|
+
**Q: 为什么不用纯 YAML?**
|
|
512
|
+
A: YAML 无法承载代码块语法高亮,无法直接嵌入 JSON Schema。Markdown 是超集。
|
|
513
|
+
|
|
514
|
+
**Q: 区域 0 和区域 1 都是 front-matter,为什么分开?**
|
|
515
|
+
A: 区域 0 是 AIGC 合规留痕(机器生成标记),区域 1 是动作语义元数据。剥离区域 0 后,区域 1 成为正文的第一个 front-matter,由 `parse_cfg()` 处理。
|
|
516
|
+
|
|
517
|
+
**Q: 旧动作需要手动迁移吗?**
|
|
518
|
+
A: 提供迁移脚本 `migrate_actus_format.py`,一键转换。过渡期双格式兼容。
|
vools/actus/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# vools.actus — Actus 动作引擎核心
|
|
2
|
+
|
|
3
|
+
迁移自 Actus engine/actuscore/,提供完整的动作执行引擎。
|
|
4
|
+
|
|
5
|
+
## 核心模块
|
|
6
|
+
|
|
7
|
+
| 模块 | 能力 |
|
|
8
|
+
|------|------|
|
|
9
|
+
| `model` | 动作数据模型(Action)、配置解析 |
|
|
10
|
+
| `executor` | 动作执行器、预览、执行ID生成 |
|
|
11
|
+
| `workflow` | 工作流引擎、DAG调度、运行工作流 |
|
|
12
|
+
| `registry` | 动作注册表、搜索、构建索引 |
|
|
13
|
+
| `vault` | 密钥管理、密钥解析 |
|
|
14
|
+
| `trust` | 信任决策、权限检查 |
|
|
15
|
+
| `security` | 安全扫描、审计日志、敏感信息检测 |
|
|
16
|
+
| `sandbox` | 沙箱环境、写保护、清理 |
|
|
17
|
+
| `runtime` | 运行时注册、块执行 |
|
|
18
|
+
| `dependency` | 依赖解析、依赖图 |
|
|
19
|
+
| `adapter` | CLI/HTTP/Quicker/MCP 适配器 |
|
|
20
|
+
| `eventbus` | 事件总线、事件类型 |
|
|
21
|
+
| `evolution` | 进化引擎 |
|
|
22
|
+
| `selfheal` | 自愈引擎 |
|
|
23
|
+
| `installer` | 动作安装器 |
|
|
24
|
+
| `notify` | 通知管理 |
|
|
25
|
+
| `highlight` | 代码高亮 |
|
|
26
|
+
| `project` | 项目编排、导入导出 |
|
|
27
|
+
| `health` | 健康检查 |
|
|
28
|
+
| `webhook` | Webhook接收 |
|
|
29
|
+
| `triggers` | 触发器引擎、定时调度 |
|
|
30
|
+
| `intent` | 意图路由 |
|
|
31
|
+
|
|
32
|
+
## 使用示例
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from vools.actus import Action, execute, Vault
|
|
36
|
+
|
|
37
|
+
# 创建动作
|
|
38
|
+
action = Action(name="demo", command="echo hello", trust_level="low")
|
|
39
|
+
|
|
40
|
+
# 执行
|
|
41
|
+
result = execute(action)
|
|
42
|
+
|
|
43
|
+
# 密钥管理
|
|
44
|
+
Vault.set_key("api_key", "xxx")
|
|
45
|
+
key = Vault.get_key("api_key")
|
|
46
|
+
```
|
vools/actus/__init__.py
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""vools.actus — Actus 动作引擎核心。
|
|
2
|
+
|
|
3
|
+
迁移自 Actus engine/actuscore/,提供:
|
|
4
|
+
- 动作数据模型(Action)
|
|
5
|
+
- 元数据解析(parse_cfg)
|
|
6
|
+
- 错误类型(ActionError)
|
|
7
|
+
- 平台常量(TRUST_LEVELS, PLATFORMS)
|
|
8
|
+
- Frontmatter 剥离
|
|
9
|
+
- 依赖解析
|
|
10
|
+
- 执行器、工作流、注册表等核心功能
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from .errors import ActionError, ERROR_CODES
|
|
14
|
+
from .constants import TRUST_LEVELS, PLATFORMS, PERMISSIONS, ALLOWED_PLATFORM_DIRS, SCOPE_LEVELS
|
|
15
|
+
from .frontmatter import strip_frontmatter
|
|
16
|
+
from .model import Action, parse_cfg, parse_cfg_from_file
|
|
17
|
+
from .dependency import Dependency, DependencyResolver, get_resolver
|
|
18
|
+
from .executor import execute, preview, new_exec_id
|
|
19
|
+
from .validate import validate_action, validate_graph
|
|
20
|
+
from .trust import decide, check_permissions
|
|
21
|
+
from .vault import Vault, set_key, get_key, delete_key, list_keys, resolve_secrets
|
|
22
|
+
from .runtimes import RuntimeRegistry, execute_block, get_available_runtimes
|
|
23
|
+
from .workflow import Workflow, WorkflowExecutor, DAGScheduler, run_workflow
|
|
24
|
+
from .registry import ActionRegistry, RegistryEntry, build_registry, search_registry
|
|
25
|
+
from .indexer import scan_actions, load_index, get_action, _repo_root
|
|
26
|
+
from .records import write_run_record, append_log, load_run_record, load_status
|
|
27
|
+
from .omega import verify_output, compute_output_fingerprint
|
|
28
|
+
from .concurrency import get_manager
|
|
29
|
+
from .eventbus import EventBus, EventType, get_event_bus
|
|
30
|
+
from .sandbox import prepare, sandbox_env, guard_write, cleanup
|
|
31
|
+
from .scaffold import scaffold_action, list_templates, match_template
|
|
32
|
+
from .trust_model import TrustEvaluator, KeyManager, SignatureVerifier, ScopeEnforcer
|
|
33
|
+
from .visibility import VisibilityEngine
|
|
34
|
+
from .security import SecurityScanner, AuditLogger, SensitiveInfoDetector
|
|
35
|
+
from .adapter import AdapterSpec, CLIAdapter, HTTPAdapter, QuickerAdapter, MCPAdapter
|
|
36
|
+
from .installer import ActionInstaller
|
|
37
|
+
from .evolution import EvolutionEngine
|
|
38
|
+
from .selfheal import SelfHealingEngine
|
|
39
|
+
from .template import create_action_from_template, list_templates
|
|
40
|
+
from .export import export_history
|
|
41
|
+
from .project import ProjectOrchestrator, ProjectConfig, detect_and_init
|
|
42
|
+
from .project_io import export_project, import_project
|
|
43
|
+
from .viz import visualize_workflow
|
|
44
|
+
from .notify import NotificationManager, get_notification_manager
|
|
45
|
+
from .health import run_health_check, HealthChecker
|
|
46
|
+
from .highlight import highlight_code
|
|
47
|
+
from .importsys import ImportResolver, resolve_imports_for_action, check_imports_available
|
|
48
|
+
from .jump import push, pull, sync, compute_sync_plan
|
|
49
|
+
from .webhook import WebhookReceiver, create_receiver, start_webhook
|
|
50
|
+
from .triggers import TriggerEngine, CronScheduler, FileWatcher, parse_triggers, validate_trigger
|
|
51
|
+
from .intent import IntentRouter
|
|
52
|
+
from .author import author_action, publish_action, Pipeline, run_pipeline
|
|
53
|
+
from .loophelpers import fingerprint, clipboard_write, clipboard_clear, focus_window, run_playback
|
|
54
|
+
|
|
55
|
+
# 分组导出(便于维护,__all__ 在下方聚合)
|
|
56
|
+
_base = [
|
|
57
|
+
'ActionError', 'ERROR_CODES',
|
|
58
|
+
'TRUST_LEVELS', 'PLATFORMS', 'PERMISSIONS', 'ALLOWED_PLATFORM_DIRS', 'SCOPE_LEVELS',
|
|
59
|
+
'strip_frontmatter',
|
|
60
|
+
]
|
|
61
|
+
_model = [
|
|
62
|
+
'Action', 'parse_cfg', 'parse_cfg_from_file',
|
|
63
|
+
'Dependency', 'DependencyResolver', 'get_resolver',
|
|
64
|
+
]
|
|
65
|
+
_exec = [
|
|
66
|
+
'execute', 'preview', 'new_exec_id',
|
|
67
|
+
'validate_action', 'validate_graph',
|
|
68
|
+
'decide', 'check_permissions',
|
|
69
|
+
'Vault', 'set_key', 'get_key', 'delete_key', 'list_keys', 'resolve_secrets',
|
|
70
|
+
'RuntimeRegistry', 'execute_block', 'get_available_runtimes',
|
|
71
|
+
]
|
|
72
|
+
_workflow = [
|
|
73
|
+
'Workflow', 'WorkflowExecutor', 'DAGScheduler', 'run_workflow',
|
|
74
|
+
]
|
|
75
|
+
_registry = [
|
|
76
|
+
'ActionRegistry', 'RegistryEntry', 'build_registry', 'search_registry',
|
|
77
|
+
'scan_actions', 'load_index', 'get_action',
|
|
78
|
+
]
|
|
79
|
+
_records = [
|
|
80
|
+
'write_run_record', 'append_log', 'load_run_record', 'load_status',
|
|
81
|
+
'verify_output', 'compute_output_fingerprint',
|
|
82
|
+
]
|
|
83
|
+
_concurrency = [
|
|
84
|
+
'get_manager',
|
|
85
|
+
'EventBus', 'EventType', 'get_event_bus',
|
|
86
|
+
]
|
|
87
|
+
_sandbox = [
|
|
88
|
+
'prepare', 'sandbox_env', 'guard_write', 'cleanup',
|
|
89
|
+
]
|
|
90
|
+
_trust = [
|
|
91
|
+
'TrustEvaluator', 'KeyManager', 'SignatureVerifier', 'ScopeEnforcer',
|
|
92
|
+
]
|
|
93
|
+
_security = [
|
|
94
|
+
'VisibilityEngine',
|
|
95
|
+
'SecurityScanner', 'AuditLogger', 'SensitiveInfoDetector',
|
|
96
|
+
]
|
|
97
|
+
_adapter = [
|
|
98
|
+
'AdapterSpec', 'CLIAdapter', 'HTTPAdapter', 'QuickerAdapter', 'MCPAdapter',
|
|
99
|
+
]
|
|
100
|
+
_install = [
|
|
101
|
+
'ActionInstaller',
|
|
102
|
+
'EvolutionEngine',
|
|
103
|
+
]
|
|
104
|
+
_selfheal = [
|
|
105
|
+
'SelfHealingEngine',
|
|
106
|
+
'create_action_from_template', 'list_templates',
|
|
107
|
+
]
|
|
108
|
+
_project = [
|
|
109
|
+
'export_history',
|
|
110
|
+
'ProjectOrchestrator', 'ProjectConfig', 'detect_and_init',
|
|
111
|
+
'export_project', 'import_project',
|
|
112
|
+
]
|
|
113
|
+
_notify = [
|
|
114
|
+
'visualize_workflow',
|
|
115
|
+
'NotificationManager', 'get_notification_manager',
|
|
116
|
+
]
|
|
117
|
+
_health = [
|
|
118
|
+
'run_health_check', 'HealthChecker',
|
|
119
|
+
'highlight_code',
|
|
120
|
+
]
|
|
121
|
+
_jump = [
|
|
122
|
+
'push', 'pull', 'sync', 'compute_sync_plan',
|
|
123
|
+
]
|
|
124
|
+
_webhook = [
|
|
125
|
+
'WebhookReceiver', 'create_receiver', 'start_webhook',
|
|
126
|
+
]
|
|
127
|
+
_intent = [
|
|
128
|
+
'IntentRouter',
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
__all__ = (
|
|
132
|
+
_base + _model + _exec + _workflow + _registry + _records
|
|
133
|
+
+ _concurrency + _sandbox + _trust + _security + _adapter
|
|
134
|
+
+ _install + _selfheal + _project + _notify + _health
|
|
135
|
+
+ _jump + _webhook + _intent
|
|
136
|
+
)
|