openxiangda-skill-kit 2.3.39 → 2.3.41
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/package.json +2 -2
- package/skills/openxiangda-v2/references/administration.md +63 -0
- package/skills/openxiangda-v2/references/managed-concurrency-frontend.md +8 -3
- package/skills/openxiangda-v2/references/managed-concurrency.md +10 -0
- package/skills/openxiangda-v2/references/workflow-events.md +24 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openxiangda-skill-kit",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.41",
|
|
4
4
|
"description": "OpenXiangda 2.0 中文 AI 技能的校验、分发与安装。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"README.md"
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"openxiangda-devkit-core": "2.
|
|
20
|
+
"openxiangda-devkit-core": "2.36.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"tsx": "4.23.12",
|
|
@@ -25,3 +25,66 @@ MCP 对应 `workflow_node_configurations`。workflowCode 来自当前应用声
|
|
|
25
25
|
确有业务需要时,使用 `openxiangda/core` 的角色管理 SDK。目录提供可管理角色、动作与授权范围;业务角色只能维护管理员已委托的范围。进一步委托要求 management.delegate,并受已有目标角色及动作子集限制。
|
|
26
26
|
|
|
27
27
|
成员和委托修改带 UUID operationId、原因,更新/撤销带最新 expectedRevision;冲突后重新读取。应用不另建授权表、选择 actor 或自行保存权限快照。SDK 和当前用户数据边界见[权限](data-authz.md)。
|
|
28
|
+
|
|
29
|
+
## 可读流程图与实例路径 {#workflow-graph}
|
|
30
|
+
|
|
31
|
+
管理员在流程目录检索全部定义,查看指定版本的分支顺序、默认路径、变量类型/单位及来源。拓扑和条件由开发者发布;图和列表只用于查看。当前有效配置只叠加在匹配的激活定义上;历史实例使用固定定义和节点进入时的人员/配置,尚未执行的节点不计入执行路径。
|
|
32
|
+
|
|
33
|
+
目录进入独立流程图地址,刷新及浏览器返回保留所查看流程/版本。共享组件按需加载 React Flow 与 ELK 正交布局:所有线段横平竖直、转角为直角;支持画布平移、滚轮缩放、适应全图、聚焦选中和缩略导航。分支标签可选中,详情保留完整条件、顺序和来源;窄屏采用同源节点列表,方向键/Home/End 定位节点。画布布局上限为 200 节点、1024 连线,不提供拖改、删除或连线编辑。
|
|
34
|
+
|
|
35
|
+
应用自定义管理页面可复用当前用户客户端和共享图组件:
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import { useEffect, useState } from 'react';
|
|
39
|
+
import { WorkflowDiagram } from 'openxiangda/react';
|
|
40
|
+
import { loadWorkflowDefinitionGraph, type WorkflowGraphReadResult } from 'openxiangda/core';
|
|
41
|
+
|
|
42
|
+
export function ReadableWorkflow({ workflowCode, version }: {
|
|
43
|
+
workflowCode: string; version: number;
|
|
44
|
+
}) {
|
|
45
|
+
const [result, setResult] = useState<WorkflowGraphReadResult>();
|
|
46
|
+
const [selected, setSelected] = useState('');
|
|
47
|
+
const [error, setError] = useState('');
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
let cancelled = false;
|
|
50
|
+
setResult(undefined); setError('');
|
|
51
|
+
loadWorkflowDefinitionGraph(workflowCode, version).then(value => {
|
|
52
|
+
if (!cancelled) { setResult(value); setSelected(value.graph.startAt); }
|
|
53
|
+
}).catch(error => { if (!cancelled) setError(error.message); });
|
|
54
|
+
return () => { cancelled = true; };
|
|
55
|
+
}, [workflowCode, version]);
|
|
56
|
+
if (error) return <p role="alert">{error}</p>;
|
|
57
|
+
if (!result) return <p>正在读取流程</p>;
|
|
58
|
+
return <WorkflowDiagram graph={result.graph} selectedNodeId={selected} onSelectNode={setSelected} />;
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
组件运行在平台应用作用域内,SDK 使用当前用户,凭据及环境继续由平台管理。`loadWorkflowInstanceGraph(instanceId)` 返回固定版本、序列及持久访问记录,传入组件 `visits` 即可查看实际路径。两种管理读取都受服务端授权;不能给普通申请页暴露整个管理读面。
|
|
63
|
+
|
|
64
|
+
`titles`、`summaries` 只用于匹配版本的有效配置或进入快照;不能将今天的模式叠加到旧实例。可选 `selectedEdgeId/onSelectEdge` 将图上分支选择关联到自定义详情;它们不修改条件。实际边由访问记录的 `transition/matchedBranch` 确认,两个节点先后出现不能证明中间所有连线都被执行。
|
|
65
|
+
|
|
66
|
+
## 有界节点配置与 SDK {#node-administration}
|
|
67
|
+
|
|
68
|
+
开发者在审批节点的 `administration` 声明可维护的模式、人员来源和任务按钮。未声明这些项的节点保留名称、说明及原人员来源维护;拓扑、分支、范围计算仍由代码控制。使用新声明的应用需要平台 `workflow.node-administration@1.0.0`,编译与激活均检查该能力。
|
|
69
|
+
|
|
70
|
+
模式为 `single/any/all/sequence` 的允许子集;来源限 `fixed_users/app_role/app_role_in_scope`,范围角色必须已有代码声明的 scope。按钮 code 保持同意、拒绝、退回、转交、委托、加签的稳定语义;同意和拒绝不能关闭。只有同意/拒绝支持意见规则,拒绝或代码已有必填意见不能放宽。字段显隐、填写与必填行为由应用页面和代码维护,不提供流程节点的字段管理覆盖。可编译声明见 `examples/workflow-administration/declaration.ts`。
|
|
71
|
+
|
|
72
|
+
应用自定义管理页可使用 `WorkflowNodeConfigurationEditor`(`openxiangda/react`),输入同一读面中的节点、principals 和 context.headRevision,放在平台 App/UI 作用域内。它复用下列当前用户 SDK:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
import { loadApplicationAdministrationContext, loadWorkflowNodeConfigurations,
|
|
76
|
+
saveWorkflowNodeConfiguration } from 'openxiangda/core';
|
|
77
|
+
|
|
78
|
+
const context = await loadApplicationAdministrationContext();
|
|
79
|
+
const configuration = await loadWorkflowNodeConfigurations('requests');
|
|
80
|
+
const node = configuration.nodes.find(item => item.nodeId === 'review')!;
|
|
81
|
+
const operationId = crypto.randomUUID();
|
|
82
|
+
await saveWorkflowNodeConfiguration('requests', node.nodeId, {
|
|
83
|
+
expectedHeadRevision: context.headRevision!, expectedRevision: node.configuration.revision,
|
|
84
|
+
operationId, reason: '更新复审方式', patch: { mode: 'all' },
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
只有已声明允许 all 的节点可保存此例。输入最多 32KiB,人员 200、按钮文字 40 字。用 `patch: null` 恢复默认,也产生审计修订。结果未知时保留相同 operationId 和完整请求,查询后重试相同操作;确认的修订/Head 冲突先重新读取,不能覆盖别人。共享编辑器按审批人、审批按钮、名称与说明分组,显示配置来源、修订与生效范围;切组保留草稿,校验失败定位到相应分组。在冲突时保留草稿,加载最新基准后再次显式保存。
|
|
89
|
+
|
|
90
|
+
新配置影响以后进入的节点,当前待办保留进入时模式、人员、按钮和必填意见;实时人员资格仍复核。含新增配置或快照的环境不能直接回退到忽略策略的旧服务器。
|
|
@@ -51,11 +51,11 @@ export async function readOffer(
|
|
|
51
51
|
|
|
52
52
|
### 只读预算繁忙恢复
|
|
53
53
|
|
|
54
|
-
`read`、`mine`、`result`、`allocation` 共用有界恢复:单次调用默认含 HTTP 和等待的总预算 120 秒,最多 12
|
|
54
|
+
`read`、`mine`、`result`、`allocation` 共用有界恢复:单次调用默认含 HTTP 和等待的总预算 120 秒,最多 12 次总请求。应用可以通过 `budgetMs` 显式延长;超过 120 秒时最多 120 次总请求,预算上限为 30 分钟,超出上限按 30 分钟处理。只重试 HTTP 429 的 `CONCURRENCY_API_BUSY`、`CONCURRENCY_RESULT_BUSY`、`CONCURRENCY_RATE_LIMITED`、`CONCURRENCY_SOURCE_BUSY`;兼容旧平台的 HTTP 503 仅限前两个已知预算错误。明确 `retryable: false`、未知 429、权限拒绝、Redis/数据库/授权依赖失败和网络失败直接返回,不用繁忙重试掩盖。
|
|
55
55
|
|
|
56
|
-
第一次失败后的基础等待为 2 秒,之后指数增加到最多 30 秒;取其与有效服务端提示的较大值,再加 0% 至 25% 随机抖动。提示优先使用合法 `Retry-After`(秒或 HTTP 日期),缺失时使用 `data.retryAfterMs
|
|
56
|
+
第一次失败后的基础等待为 2 秒,之后指数增加到最多 30 秒;取其与有效服务端提示的较大值,再加 0% 至 25% 随机抖动。提示优先使用合法 `Retry-After`(秒或 HTTP 日期),缺失时使用 `data.retryAfterMs`。若等待达到剩余预算,不提前查询,直接返回最后一次繁忙错误;请求次数用完也保留最后繁忙响应。正在进行的请求超过总预算则中止并返回 `CONCURRENCY_READ_RECOVERY_EXHAUSTED`,不以之前的繁忙响应掩盖悬挂请求。
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
可以传入更短的剩余预算,或为高流量详情入口显式选择较长的等待窗口:
|
|
59
59
|
|
|
60
60
|
```ts
|
|
61
61
|
// budgetMs 含本次请求和所有预算繁忙退避;服务端事实仍为最终依据。
|
|
@@ -63,8 +63,13 @@ const receipt = await client.result({ operationId }, signal, {
|
|
|
63
63
|
budgetMs: Math.max(0, originalDeadline - Date.now()),
|
|
64
64
|
});
|
|
65
65
|
const offer = await client.read<Offer>('offer', { id: offerId }, signal, { budgetMs: 30_000 });
|
|
66
|
+
const detail = await client.read<Offer>('offer', { id: offerId }, signal, {
|
|
67
|
+
budgetMs: 30 * 60 * 1000,
|
|
68
|
+
});
|
|
66
69
|
```
|
|
67
70
|
|
|
71
|
+
预算在本次调用启动时固定,繁忙重试不重新计时。页面应保留同一资源、身份和视角的整体截止时间,并在重新查询时传入剩余量;刷新不能无限续期。长期读取等待只表示尚未取得页面信息,不能显示为已报名或已进入业务队列。持久申请控制器继续保留每次读取最多 120 秒和原有受理、观察期限,显式延长详情读取不会更改已提交申请的首次期限。
|
|
72
|
+
|
|
68
73
|
每次调用在第一次请求前冻结完整参数、环境、主体及权限视角;后续修改表单不会改变重试内容。身份或视角变化时停止旧调用并返回 `CONCURRENCY_IDENTITY_CHANGED`。`AbortSignal` 可以中止请求和等待;组件卸载应中止旧读取。`enqueue`、`accept`、`cancel` 等写方法不使用这层自动重试,持久申请的原键受理恢复由下述控制器单独管理。普通 Data API 也不自动获得此策略。
|
|
69
74
|
|
|
70
75
|
`freshness: 'stale'` 表示返回的是允许使用的旧内容,并不证明后台刷新已经成功。保留内容并提示“当前展示最近一次可用信息”;按新鲜期和有界退避刷新,超过 `staleUntil` 后不能继续无限展示。手动刷新仍调用同一命名读取,不绕回普通 CRUD。
|
|
@@ -4,6 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
页面开发参见[并发能力的前端接入](managed-concurrency-frontend.md):按热点详情、一键申请、填完再提交、短确认入口、预占确认和原结果恢复选择交互方式,并核对当前 API 与尚未提供的封装边界。
|
|
6
6
|
|
|
7
|
+
## 开抢瞬间的完整请求链
|
|
8
|
+
|
|
9
|
+
容量验收覆盖同一批用户的整条请求链:进入 HTML 和静态资源、运行时身份初始化、活动内容与本人状态、持久排队提交、后台执行、按原请求键恢复结果,以及页面的自然查询。为这些入口共同规划连接数、HTTP 在途数、数据库连接、回源和 worker 预算;只测 enqueue 或缓存命中,不能证明整条链能承受同一秒进入的人数。共享活动内容和本人状态分别使用合适的读取范围与失效依赖,排队阶段按服务端建议间隔和抖动查询,避免自然刷新再次形成尖峰。
|
|
10
|
+
|
|
11
|
+
运行时 current 对明确繁忙响应最多恢复 300 秒,安全只读传输故障最多三次总尝试。它只帮助用户完成入口初始化,尚未持久受理业务申请;只有 enqueue 返回持久回执后才展示已受理。退出、真实身份变化、权限或版本拒绝仍应停止旧客户端。同身份检查保留页面和原申请,刷新或重新进入继续查原请求键,不自动创建第二次提交。
|
|
12
|
+
|
|
13
|
+
资源不足时,通过独立 intake 预算保护新受理,再让持久命令在业务 deadline 内等待受控执行;等待、重试与恢复不延长原截止。资源充足时,根据已测的 CPU、数据库连接、锁竞争和完成率提高工作预算,分别调整受理、回源、查询与执行,不能只增加队列长度或 worker 数。业务需要三十分钟内完成时,同时核对命令自身的 acceptedAt/deadlineAt,以及从开抢时刻到最终结果的总耗时,入口等待不能被排除在体验指标之外。
|
|
14
|
+
|
|
15
|
+
记录同一秒发起人数、进入成功率、持久受理率、明确拒绝、暂时无法确认、最终结果耗时分布、最老非终态与资源峰值。合成独立测试主体用于验证目标服务器的应用请求链;真实 SSO 认证、客户端网络和浏览器渲染容量需要另行验证,不能由合成压测推断。
|
|
16
|
+
|
|
7
17
|
## 声明与权限
|
|
8
18
|
|
|
9
19
|
完整且由双编译器测试验证的示例位于源码 `examples/managed-concurrency/declaration.ts`。调用 `defineOpenXiangdaApp(concurrencyExample())` 即可编译。把示例中的 `data.concurrency` 合入应用配置,并按实际业务配置模型和参与权限。
|
|
@@ -104,6 +104,8 @@ events: {
|
|
|
104
104
|
|
|
105
105
|
待办中心通过 Workflow 查询 `pending`、`handled`、`created`、`cc` 四种视图;消息中心默认向 Notification Hub 查询 `view=all`,沿用应用声明的渲染扩展。各入口按服务端 `detailNavigation` 打开详情,页面不自行拼接人员范围。
|
|
106
106
|
|
|
107
|
+
标准任务和实例详情的“返回”由应用 Router 使用同一份 route manifest 中对应设备的流程中心路径;没有中心条目时返回已声明门户。普通用户无需管理后台权限。应用独立消费 `WorkflowTaskPage` 或 `WorkflowInstancePage` 时,可以传入本应用已声明的 `returnPath`,例如 `<WorkflowInstancePage variant="mobile" returnPath="/m/work-center" />`。抽屉的 `onDismiss` 仍负责关闭当前抽屉;返回导航不授予目标页面权限。
|
|
108
|
+
|
|
107
109
|
抄送由动态 Surface 提供 `cc` 操作,使用 `user_select` 多选组件收集 1 至 20 位人员。任务 Surface 可以正式包含实例抄送命令;前端按 `operation.execute.href` 和该 Surface 的 token 提交,不另造任务命令或 token。公共事件为 `openxiangda.workflow.instance.cc_added.v2`。
|
|
108
110
|
|
|
109
111
|
## 钉钉卡片已读查询
|
|
@@ -378,3 +380,25 @@ Surface 上执行。
|
|
|
378
380
|
## 验证
|
|
379
381
|
|
|
380
382
|
至少验证:完整标准详情投影、父子表边界、流程附件读取、桌面/移动独立渲染、全部标准操作、多人模式、重复/并发命令、stale revision、重启 replay、乱序事件、重复回调、消息终态全量更新、详情跳转、错用户/错租户/过期动作、渠道超时/unknown、死信重放和 1.x 零触碰。
|
|
383
|
+
|
|
384
|
+
## 流程说明与变量来源 {#workflow-readability}
|
|
385
|
+
|
|
386
|
+
`definition.readability` 是可选说明,随不可变定义及其摘要发布。变量来源从实际 `inputSchema` 和 `subject.factProjection` 推导;不另行声明一个可编辑的条件图。例如,条件路径 `amountCents` 对应业务字段 `amountCents`,单选条件通常读取 `reason.value`:
|
|
387
|
+
|
|
388
|
+
```ts
|
|
389
|
+
readability: {
|
|
390
|
+
variables: {
|
|
391
|
+
amountCents: { label: '申请金额', unit: '分', description: '提交记录中的非负整数金额' },
|
|
392
|
+
'reason.value': { label: '休学原因值' },
|
|
393
|
+
},
|
|
394
|
+
logic: [{
|
|
395
|
+
code: 'submission-validation', title: '核验申请',
|
|
396
|
+
description: '提交时校验已声明字段;金额由表单直接提供',
|
|
397
|
+
phase: 'submission', inputPaths: ['amountCents'],
|
|
398
|
+
}],
|
|
399
|
+
}
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
说明的执行位置只能是 submission、某节点的 node_input 或 completion。它是对已有逻辑的注释,不会自动执行计算或产生新流程节点。没有实际计算步骤时,不应写成“系统已计算总金额”。条件的变量必须存在于输入 Schema;对旧未标注定义,读取投影会明确给出未知来源诊断。
|
|
403
|
+
|
|
404
|
+
可选 `source: { path, symbol?, digest }` 只返回源码位置和 SHA256,不返回源码内容。path 指向工作区 apps/packages/platform 下的代码文件,digest 为 `sha256:<原始文件字节摘要>`。工作区加载时核对文件存在、无符号链接、大小和摘要;源码变化后以 WORKFLOW_LOGIC_DESCRIPTION_STALE 阻止封装,开发者应核实说明并更新引用。32 个文件、单文件 2MiB、总量 8MiB 为上限。元数据不能验证任意 TypeScript 的业务含义,业务说明及验收仍由开发者维护。
|