@xtalpi/agentic-lab-skills 0.0.1

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.
Files changed (57) hide show
  1. package/README.md +1 -0
  2. package/package.json +14 -0
  3. package/skills/lab-flow-designer/SKILL.md +360 -0
  4. package/skills/lab-flow-designer/embedded-template/SKILL.md +84 -0
  5. package/skills/lab-flow-designer/embedded-template/pools//345/205/245/345/217/243/346/261/240.md +12 -0
  6. package/skills/lab-flow-designer/embedded-template/pools//345/207/272/345/217/243/346/261/240.md +12 -0
  7. package/skills/lab-flow-designer/embedded-template/scripts//347/244/272/344/276/213/346/225/260/346/215/256/344/270/216/346/240/241/351/252/214/351/227/250/346/216/247.js +149 -0
  8. package/skills/lab-flow-designer/embedded-template/valves//347/244/272/344/276/213/346/225/260/346/215/256/344/270/216/346/240/241/351/252/214/351/227/250/346/216/247.md +100 -0
  9. package/skills/lab-flow-designer/references/agentic-lab-processer.md +101 -0
  10. package/skills/lab-flow-designer/references/agentic-lab-sdk.md +440 -0
  11. package/skills/lab-flow-designer/references/rhea-api/README.md +7 -0
  12. package/skills/lab-flow-designer/references/rhea-api/execute_process_batch.md +58 -0
  13. package/skills/lab-flow-designer/references/skill-package-layout.md +199 -0
  14. package/skills/lab-flow-designer/references//344/270/232/345/212/241/346/265/201/347/250/213/346/226/207/346/241/243/346/240/207/345/207/206.md +208 -0
  15. package/skills/lab-orbit-component-builder/SKILL.md +305 -0
  16. package/skills/lab-orbit-component-builder/examples/xnb-component-template/.env.local.example +27 -0
  17. package/skills/lab-orbit-component-builder/examples/xnb-component-template/.eslintignore +7 -0
  18. package/skills/lab-orbit-component-builder/examples/xnb-component-template/.eslintrc.cjs +88 -0
  19. package/skills/lab-orbit-component-builder/examples/xnb-component-template/.nvmrc +1 -0
  20. package/skills/lab-orbit-component-builder/examples/xnb-component-template/AgenticAppAPI.md +268 -0
  21. package/skills/lab-orbit-component-builder/examples/xnb-component-template/Jenkinsfile +106 -0
  22. package/skills/lab-orbit-component-builder/examples/xnb-component-template/OrbitAPI.md +453 -0
  23. package/skills/lab-orbit-component-builder/examples/xnb-component-template/README.md +176 -0
  24. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/public/index.html +12 -0
  25. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/App.vue +151 -0
  26. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/components/DevOpenerLauncher.vue +143 -0
  27. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/global.d.ts +74 -0
  28. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/main.ts +305 -0
  29. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/mockXNBBitable.ts +119 -0
  30. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/shims-vue.d.ts +6 -0
  31. package/skills/lab-orbit-component-builder/examples/xnb-component-template/dev/src/utils/devOpenerHost.ts +75 -0
  32. package/skills/lab-orbit-component-builder/examples/xnb-component-template/index.html +13 -0
  33. package/skills/lab-orbit-component-builder/examples/xnb-component-template/package.json +57 -0
  34. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/api/agenticlabTickets.ts +110 -0
  35. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/entries/bitable.ts +4 -0
  36. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/entries/custom-page.ts +4 -0
  37. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/index.ts +1 -0
  38. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/styles/orbit-quasar-host.scss +19 -0
  39. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/types/context.ts +15 -0
  40. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/types/xnb-context.ts +70 -0
  41. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/use/useBitablePage.ts +180 -0
  42. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/use/useSuperCellDemo.ts +257 -0
  43. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/use/useSuperTableBitableLifecycle.ts +547 -0
  44. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/utils/openerInitParams.ts +158 -0
  45. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/utils/openerTicketIds.ts +32 -0
  46. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/utils/orbitHttpClient.ts +110 -0
  47. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/utils/request.ts +92 -0
  48. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/views/bitable.vue +65 -0
  49. package/skills/lab-orbit-component-builder/examples/xnb-component-template/src/views/custom-page.vue +140 -0
  50. package/skills/lab-orbit-component-builder/examples/xnb-component-template/tsconfig.json +48 -0
  51. package/skills/lab-orbit-component-builder/examples/xnb-component-template/vite.config.ts +165 -0
  52. package/skills/lab-orbit-component-builder/examples/xnb-component-template/vite.dev.config.ts +51 -0
  53. package/skills/lab-orbit-component-builder/references/flow-document-human-ui.md +65 -0
  54. package/skills/lab-orbit-component-builder/references/pool-schema-to-columns.md +67 -0
  55. package/skills/lab-orbit-component-builder/references/vue-template-checklist.md +113 -0
  56. package/skills/lab-orbit-component-builder/references/xnb-context-vue-props.md +49 -0
  57. package/skills/lab-orbit-component-builder/references/xnbitable-vue-parity.md +32 -0
@@ -0,0 +1,149 @@
1
+ /**
2
+ * 示例门控脚本:结构对齐本 skill 主 SKILL.md 与 embedded-template;API 对齐 references/agentic-lab-sdk.md
3
+ * 输入输出类型对齐 references/agentic-lab-processer.md(参数与返回值均为 snake_case)。
4
+ * 业务规则以用户提供的流程说明 Markdown 为准(「数据查询方式」「字段映射」「数据处理规则」等)。
5
+ *
6
+ * 门控执行顺序:前置处理(start) → 人工处理(页面) → 后置处理(complete)
7
+ *
8
+ * 列表类查询:流程说明未要求分页时,显式 limit/offset(见主 SKILL「门控脚本编写指引 → 分页与查全量」)。
9
+ *
10
+ * 类型安全:ticket.detail 值为任意 JSON 类型(string/number/null/array/object),
11
+ * 禁止直接调 .trim()/.split() 等 String 方法——须先 String() 转换(见「编写指引 §5」)。
12
+ */
13
+ const DEFAULT_QUERY_LIMIT = 999999;
14
+
15
+ // orbit_link 由流程文档门控脚本配置项中的 PageUrl 与门控前置处理中的 bookid 组合生成
16
+ const PAGE_URL = 'http://10.249.133.129:9048/?view=book&book={bookid}';
17
+ const BOOK_ID = '1';
18
+
19
+ // --- 类型安全辅助函数(detail 值可为任意 JSON 类型,须先转换再操作)---
20
+ function str(v) {
21
+ return v != null ? String(v) : '';
22
+ }
23
+ function num(v, fallback) {
24
+ const n = Number(v);
25
+ return Number.isFinite(n) ? n : (fallback !== undefined ? fallback : 0);
26
+ }
27
+
28
+ class Processer {
29
+ constructor(context) {
30
+ this.context = context;
31
+ }
32
+
33
+ // --- 前置处理 → start ---
34
+ // params: { valve_id, pool_ids }
35
+ // returns: { orbit_link, ticket_ids }
36
+ async start(params) {
37
+ const { valve_id, pool_ids } = params;
38
+ const { list: tickets } = await this.context.ticket.list({
39
+ pool_id__in: pool_ids,
40
+ limit: DEFAULT_QUERY_LIMIT,
41
+ offset: 0,
42
+ });
43
+
44
+ const compoundIdList = [
45
+ ...new Set(
46
+ tickets
47
+ .map((t) => t.detail?.cmpd_id || t.detail?.compound_id)
48
+ .filter(Boolean)
49
+ ),
50
+ ];
51
+
52
+ let chemicalRecords = [];
53
+ let stockRecords = [];
54
+ if (compoundIdList.length > 0) {
55
+ const filter = { cmpd_id: { $in: compoundIdList } };
56
+ chemicalRecords = await this.context.compound.getChemicalRecord({
57
+ filter,
58
+ limit: DEFAULT_QUERY_LIMIT,
59
+ offset: 0,
60
+ });
61
+ stockRecords = await this.context.compound.getStock({
62
+ filter,
63
+ limit: DEFAULT_QUERY_LIMIT,
64
+ offset: 0,
65
+ });
66
+ }
67
+
68
+ const stations = await this.context.station.list();
69
+ const processIds = tickets
70
+ .flatMap((t) => t.detail?.process_ids || [])
71
+ .filter(Boolean);
72
+ const processes =
73
+ processIds.length > 0
74
+ ? await this.context.process.list({
75
+ processIds,
76
+ limit: DEFAULT_QUERY_LIMIT,
77
+ offset: 0,
78
+ })
79
+ : [];
80
+
81
+ // --- 规则 1.1~1.4:按 valves/示例数据与校验门控.md「数据处理规则」写回 detail(以下为示意)---
82
+ for (const ticket of tickets) {
83
+ const d = ticket.detail || {};
84
+ const chem = chemicalRecords.find((r) => r.cmpd_id === d.cmpd_id);
85
+ const stock = stockRecords.filter((r) => r.cmpd_id === d.cmpd_id);
86
+
87
+ if (chem) {
88
+ d.chemist_property = str(chem.chemist_property);
89
+ d.dispensable = chem.dispensable;
90
+ d.dispensing_remark = str(chem.dispensing_remark);
91
+ }
92
+ if (stock.length) {
93
+ d.available_amount_mg = stock.reduce(
94
+ (s, r) => s + num(r.latest_amount_mg, 0),
95
+ 0
96
+ );
97
+ }
98
+ d._stations_count = stations.length;
99
+ d._processes_preview = processes;
100
+ ticket.detail = d;
101
+ }
102
+
103
+ await this.context.ticket.update(tickets);
104
+
105
+ const orbit_link = PAGE_URL.replace('{bookid}', BOOK_ID);
106
+
107
+ return {
108
+ orbit_link,
109
+ ticket_ids: tickets.map((t) => t.id),
110
+ };
111
+ }
112
+
113
+ // --- 后置处理 → complete ---
114
+ // params: { valve_id, tickets }
115
+ // returns: { new_tickets }
116
+ async complete(params) {
117
+ const { valve_id, tickets } = params;
118
+
119
+ const nextPools = await this.context.pool.getNext(valve_id);
120
+ const outPool = nextPools.find((p) => p.name === '出口池');
121
+
122
+ if (!outPool) {
123
+ throw new Error(
124
+ `未找到出口池;nextPools=${nextPools.map((p) => p.name).join(',')}`
125
+ );
126
+ }
127
+
128
+ // 将入口池的tickets更新为”已完成”状态,避免重复处理
129
+ const finished = tickets.map((t) => ({
130
+ ...t,
131
+ status: 'finished',
132
+ }));
133
+ await this.context.ticket.update(finished);
134
+
135
+ // 按出口池 schema 映射为新 tickets,由引擎自动创建(不在脚本内调用 ticket.append)
136
+ const new_tickets = finished.map((t) => ({
137
+ flow_id: t.flow_id,
138
+ pool_id: outPool.id,
139
+ order_id: t.order_id,
140
+ detail: t.detail,
141
+ status: 'created',
142
+ parent_ticket_id: t.id,
143
+ }));
144
+
145
+ return {
146
+ new_tickets,
147
+ };
148
+ }
149
+ }
@@ -0,0 +1,100 @@
1
+ # 示例数据与校验门控
2
+
3
+ ## 概述
4
+
5
+ 演示与真实 Fragment 门控相同的文档结构:**门控 YAML**、**化合物数据查询方式**、**字段映射**、**数据处理规则**、**start/complete 分工**。生成业务流程注册包时,按流程说明替换各节内容;脚本实现须对照 [references/agentic-lab-sdk.md](../../references/agentic-lab-sdk.md)。
6
+
7
+ ## 关联脚本
8
+
9
+ **脚本路径**: [scripts/示例数据与校验门控.js](scripts/示例数据与校验门控.js)
10
+
11
+ 该脚本导出 `Processer` 类,实现 `start` 和 `complete` 方法。
12
+
13
+ ## 门控 YAML(与流程说明对齐)
14
+
15
+ 流程说明中可能使用 `Stash:` 等键表示目标池;生成脚本时以 **`pool.name`**(或文档中的池显示名称)与 `pool.getNext(valve_id)` 返回值匹配(`valve_id` 来自 `Processer` 入参)。
16
+
17
+ ```yaml
18
+ valve_id: valve_example_1
19
+ name: 示例数据与校验门控
20
+ order: 1
21
+ input:
22
+ primary: 入口池
23
+ output:
24
+ - pool: 出口池
25
+ condition: 示例:校验通过且已回填必要字段
26
+ ```
27
+
28
+ ## 化合物数据查询方式(映射到 Agentic Lab SDK)
29
+
30
+ | 流程说明中的表述 | 推荐 SDK 调用 |
31
+ |----------------|---------------|
32
+ | 查 compound 表 / 可用量 / 库存汇总 | `context.compound.getStock({ filter, limit, offset })`;`filter` 为 NocoBase 条件;**流程未写分页时**建议 `limit: 999999`、`offset: 0`(见主 `SKILL.md` 门控脚本指引)。另见 [agentic-lab-sdk](../../references/agentic-lab-sdk.md)、[Filter Operators](https://docs.nocobase.com/api/database/operators) |
33
+ | 查 chemical_record / 知识库属性 | `context.compound.getChemicalRecord({ filter, limit, offset })`;同上,默认大 `limit` 防截断 |
34
+
35
+ ## 字段映射(示例:知识库 → ticket.detail)
36
+
37
+ > **仅供结构演示**:下表中的加工数据名、库侧列名、`detail` 键仅为说明「表格长什么样、如何对齐 snake_case」,**不**绑定任何具体业务;其它流程须整表替换为用户流程说明中的映射。
38
+
39
+ 流程说明中的「门控加工数据 ↔ 库字段」表,在脚本里写入 `ticket.detail` 时建议与 **pools Schema 的「字段」列(snake_case)** 对齐。以下为示意(真实以流程文档表格为准):
40
+
41
+ | 门控加工数据 | chemical_record(示例列名) | detail 键(示例) |
42
+ |-------------|------------------------------|------------------|
43
+ | 性状(Chemist) | chemistProperty | chemist_property |
44
+ | 可分装判断 | dispensable | dispensable |
45
+ | 可舀粉判断 | feasibilityOfDipensing | feasibility_of_dipensing |
46
+
47
+ (真实流程以用户提供的流程说明 Markdown 中表格为准。)
48
+
49
+ ## 数据处理规则(脚本注释应对齐序号)
50
+
51
+ > **同上**:`1.1` 等序号格式应对齐流程文档;下列规则摘要与动作为**占位示意**(偏分装场景),生成其它业务包时须按流程说明中的规则表重写。
52
+
53
+ | 序号 | 规则摘要 | 业务动作(示意) |
54
+ |------|----------|------------------|
55
+ | 1.1 | 汇总需求量 | `detail.requested_amount = sum(target_amount_n)` |
56
+ | 1.2 | 缺料判定 | 结合 `getStock` 汇总可用量与 `requested_amount` 比较 |
57
+ | 1.3 | 容差默认 | 目标量 >0 且容差空 → 默认 0.5 mg |
58
+ | 1.4 | 缺料标记 | `source_barcode` 空 → `是否缺料` = 缺料 |
59
+
60
+ ## 执行流程
61
+
62
+ **门控执行顺序:前置处理(脚本 `start`)→ 人工处理(页面)→ 后置处理(脚本 `complete`)**
63
+
64
+ ### 前置处理
65
+
66
+ | 配置项 | 类别 | 默认值 / 占位 | 说明 |
67
+ | ------ | ---- | -------------- | ---- |
68
+ | bookid | 参数 | 1 | Orbit 页面对应的 BookId,用于拼装 `orbit_link` |
69
+
70
+ | 规则摘要 | 条件要点 | 业务动作或结果 |
71
+ | -------- | -------- | -------------- |
72
+ | 查询入口池 | 门控启动 | `ticket.list({ pool_id__in: pool_ids, limit: 999999, offset: 0 })`,取返回体 `list` |
73
+ | 查化合物数据 | 有 compound 查询需求 | `compound.getChemicalRecord` / `compound.getStock`(同上默认大 `limit`) |
74
+ | 写回 detail | 查询完成 | 按映射表与规则表写回 `ticket.detail` → `ticket.update` |
75
+ | 拼装 orbit_link | 返回前 | `PageUrl.replace('{bookid}', bookid)` |
76
+
77
+ **start 返回**:`{ orbit_link, ticket_ids }`
78
+
79
+ ### 人工处理
80
+
81
+ ##### 界面形态与数据绑定
82
+
83
+ 1. **界面类型**:超级表格
84
+ 2. **数据来源**:前置处理写入 `ticket.detail` 的字段
85
+ 3. **操作按钮**:刷新 / 检查 / 提交(由 `studio-orbit-vue-component` 技能生成 UI)
86
+
87
+ ### 后置处理
88
+
89
+ | 规则摘要 | 条件要点 | 业务动作或结果 |
90
+ | -------- | -------- | -------------- |
91
+ | 获取出口池 | `pool.getNext(valve_id)` | 按 `pool.name` 匹配出口池 |
92
+ | 更新入口池状态 | 出口池确定 | 入口池 tickets 更新为 `status: 'finished'` → `ticket.update` |
93
+ | 映射出口池记录 | 状态更新完成 | 按出口池 Schema 构建 `new_tickets`(含 `flow_id`、`pool_id`、`order_id`、`detail`、`status: 'created'`、`parent_ticket_id`) |
94
+
95
+ **complete 返回**:`{ new_tickets }`(由引擎自动创建,脚本不调用 `ticket.append`)
96
+
97
+ ## 输入/输出
98
+
99
+ - **输入池**: 入口池
100
+ - **输出池**: 出口池(多出口时与 YAML 中各 `pool`/`Stash` 目标池名称一致)
@@ -0,0 +1,101 @@
1
+ > Agentic Lab 门控脚本
2
+
3
+ ### 类型定义
4
+
5
+ #### start
6
+
7
+ ```typescript
8
+ interface StartExecutionParams {
9
+ valve_id: number;
10
+ pool_ids: number[];
11
+ [propName: string]: any;
12
+ }
13
+
14
+ interface StartExecutionResult {
15
+ orbit_link: string;
16
+ ticket_ids: number[];
17
+ [propName: string]: any;
18
+ }
19
+
20
+ async start(params: StartExecutionParams): Promise<StartExecutionResult>
21
+ ```
22
+
23
+ #### complete
24
+
25
+ ```typescript
26
+ interface CompleteExecutionParams {
27
+ valve_id: number;
28
+ tickets: Record<string, any>[];
29
+ [propName: string]: any;
30
+ }
31
+
32
+ interface CompleteExecutionResult {
33
+ new_tickets?: Record<string, any>[]; // 待新增的tickets,由引擎创建到数据表
34
+ [propName: string]: any;
35
+ }
36
+
37
+ async complete(params: CompleteExecutionParams): Promise<CompleteExecutionResult>
38
+ ```
39
+
40
+
41
+ ### 示例
42
+
43
+ ```javascript
44
+ class Processer {
45
+ // context: 执行引擎提供的SDK
46
+ constructor(context) {
47
+ this.context = context;
48
+ }
49
+
50
+ // params: { valve_id, pool_ids }
51
+ async start(params) {
52
+ const tickets = await this.context.ticket.list({ pool_id__in: pool_ids });
53
+ const stations = await this.context.station.list();
54
+
55
+ const process_ids = []; // 从tickets detail 按需提取出process ids
56
+ const processes = await this.context.process.list({ process_ids });
57
+
58
+ // 基于stations、processes等数据源,筛选待处理tickets
59
+ const finalTickets = tickets.filter(ticket => ticket);
60
+
61
+ // 将processes更新到finalTickets detail中
62
+ finalTickets.forEach(ticket => { ticket.detail.processes = processes })
63
+ // 更新数据库中的tickets,以便Orbit视图获取最新数据
64
+ await this.context.ticket.update(finalTickets)
65
+
66
+ return {
67
+ orbit_link: 'https://orbit-sh.xtalpi.xyz/?view=book&book=3947',
68
+ ticket_ids: finalTickets.map(ticket => ticket.id),
69
+ }
70
+ }
71
+
72
+ // params: { valve_id, tickets }
73
+ async complete(params) {
74
+ // params.tickets 已包含本次待处理的人工录入数据,通常无需重新查询;如需补充数据库数据请按实际需求调用查询方法
75
+
76
+ // 获取当前门控的(一个或多个)出口池
77
+ const nextPools = this.context.pool.getNext(valveId);
78
+ const successPool = nextPools.find(pool => pool.name === 'xxx成功');
79
+ const failedPool = nextPools.find(pool => pool.name === 'xxx失败');
80
+
81
+ // 基于实时tickets,按实际业务场景(流程说明书中的相关定义),筛选出“可流入出口池”的tickets
82
+ const finalTickets = params.tickets.filter(ticket => ticket).map(t => ({ ...t, status: 'finished' }));
83
+
84
+ // 将入口池的tickets更新为“已完成”状态,避免重复处理
85
+ await this.context.ticket.update(finalTickets);
86
+
87
+ // 按实际的业务场景(流程说明书中的相关定义), 筛选出“可流入成功出口池”的tickets,并按出口池的schema 映射为新的tickets
88
+ const newSuccessTickets = finalTickets.filter(ticket => ticket).map(t => ({ ...t, status: 'created', pool_id: successPool.id }));
89
+ // 按实际的业务场景(流程说明书中的相关定义), 筛选出“可流入失败出口池”的tickets,并按出口池的schema 映射为新的tickets
90
+ const newFailedTickets = finalTickets.filter(ticket => ticket).map(t => ({ ...t, status: 'created', pool_id: failedPool.id }));
91
+
92
+ // 脚本不负责创建新ticket,交由引擎自动创建(需返回new_tickets)
93
+ return {
94
+ new_tickets: [
95
+ ...newSuccessTickets,
96
+ ...newFailedTickets
97
+ ]
98
+ }
99
+ }
100
+ }
101
+ ```