route:生成完整配置,沉淀常用判断
route 函数组生成普通 WorkflowRoute 配置;手写对象与生成配置遵守同一个合同。
所有 to* 的第一个参数都是目标节点。route(target, id?) 是 route.to 的别名,只有它与 to 的第二个参数直接是可选路由 ID。条件生成器在 options 中提供 id、conditionId、description;通常可省略。
| 生成器 | 判断与结果 |
|---|---|
| to(target, id?) | 不带 when,直接跳转 |
| toIf(target, options?) | 同名状态字段求真 Boolean(state[target]) |
| toIfDefined(target, field, options?) | 字段不为 undefined;null、false、0 也算已定义 |
| toIfError(target, options?) | 默认检测 error 是否已定义,可用 errorKey 指定其他字段 |
| toIfNotEmpty(target, key, options?) | 已知数组的 length 大于 0,不是任意值通用的空值检测 |
| toIfEqual(target, path, value, options?) | path 读取的值与固定 value 严格相等 |
| toIfEqualWith(target, leftPath, rightPath, options?) | 两个状态 path 读取的值严格相等 |
| deliver(field, options?) | 结束并读取必需字段;undefined 会拒绝 |
| deliverIfReady(field, options?) | 字段已定义才结束,否则继续匹配下一条 |
| deliverWhenComplete(field, options?) | StepOutcome.type 为 complete 才结束并取其 value |
Equal 两种生成器支持 profile.items.0.id 一类点路径;当前 toIfDefined、toIfNotEmpty 的参数是字段 key,不能擅自推断它们也支持路径。严格相等不会深比较对象;两个缺失路径都得到 undefined 时会相等,业务不接受时应先配前置检查。
现有 to* 一般按目标生成 to-target;toIfEqual 对可稳定表达的 path、值、目标组合生成 ID,toIfEqualWith 依据左右路径与目标生成;symbol 路径或非标量相等值不能得到同样的稳定默认 ID。deliver 系列习惯使用 complete。这些是各专用函数的习惯,不是 Workflow 强加的统一命名约束。
生成器常用 conditionId: {nid}.{rid}。普通手写对象同样支持这两个占位符;Workflow 只展开节点值和本地最终路由 ID,并为重复路由 ID 加 ~2 等后缀,不猜测未提供的 ID 或专用函数规则。
由简到繁的同业务示例
最小跳转与结束
入门 · Node.js
ts
import { route } from '@jangts/agent-core/engine';
const jump = route('reply');
const sameJump = route.to('reply');
const finish = route.deliver('answer');
console.log(jump, sameJump, finish);js
import { route } from '@jangts/agent-core/engine';
const jump = route('reply');
const sameJump = route.to('reply');
const finish = route.deliver('answer');
console.log(jump, sameJump, finish);同一业务的常用分支
配置 · Node.js
ts
import { route } from '@jangts/agent-core/engine';
const reviewRoutes = [
route.toIfError('failure'),
route.toIf('recovered'),
route.toIfNotEmpty('candidate', 'candidates'),
route.toIfDefined('reply', 'answer'),
route.toIfEqual('status', 'intent.id', 'status'),
route.toIfEqualWith('reuse', 'cache.0.id', 'request.id'),
route.to('fallback'),
];
const completionRoutes = [route.deliverIfReady('answer'), route.to('retry')];
const outcomeRoutes = [route.deliverWhenComplete('outcome'), route.to('retry')];
console.log(reviewRoutes, completionRoutes, outcomeRoutes);js
import { route } from '@jangts/agent-core/engine';
const reviewRoutes = [
route.toIfError('failure'),
route.toIf('recovered'),
route.toIfNotEmpty('candidate', 'candidates'),
route.toIfDefined('reply', 'answer'),
route.toIfEqual('status', 'intent.id', 'status'),
route.toIfEqualWith('reuse', 'cache.0.id', 'request.id'),
route.to('fallback'),
];
const completionRoutes = [route.deliverIfReady('answer'), route.to('retry')];
const outcomeRoutes = [route.deliverWhenComplete('outcome'), route.to('retry')];
console.log(reviewRoutes, completionRoutes, outcomeRoutes);按业务需要覆盖身份,手写对象也支持占位符
扩展 · Node.js
conditionId 不承担授权。它帮助日志解释命中了哪次判断。
ts
import { defineWorkflow, route } from '@jangts/agent-core/engine';
type State = { answer?: string; reviewError?: string };
const workflow = defineWorkflow<State, string>({ id: 'review', nodes: [
{ id: 'check', description: '检查既有结果', startsRound: true, routes: [
route.toIfError('failure', { errorKey: 'reviewError', id: 'review-error' }),
{ id: 'ready', conditionId: '{nid}.{rid}', when: state => state.answer !== undefined,
complete: state => state.answer! },
route.to('failure'),
] },
{ id: 'failure', description: '给出当前缺失信息',
run: () => ({ answer: '当前没有可交付结果' }), routes: [route.deliver('answer')] },
] });
console.log(workflow.describe());js
import { defineWorkflow, route } from '@jangts/agent-core/engine';
const workflow = defineWorkflow({ id: 'review', nodes: [
{ id: 'check', description: '检查既有结果', startsRound: true, routes: [
route.toIfError('failure', { errorKey: 'reviewError', id: 'review-error' }),
{ id: 'ready', conditionId: '{nid}.{rid}', when: state => state.answer !== undefined,
complete: state => state.answer },
route.to('failure'),
] },
{ id: 'failure', description: '给出当前缺失信息',
run: () => ({ answer: '当前没有可交付结果' }), routes: [route.deliver('answer')] },
] });
console.log(workflow.describe());