chore: initial commit
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import type {NodeHandler} from '../../../types/bot/workflow/runtime.ts';
|
||||
import type {WorkflowNodeTemplate} from '../../../types/bot/workflow/metadata.ts';
|
||||
import {describe, failure_port, output, port} from '../metadata.ts';
|
||||
import {assert_json} from '../runtime/value.ts';
|
||||
|
||||
export const config_template: WorkflowNodeTemplate = {
|
||||
name: 'goto', version: '1.0.0',
|
||||
i18n: describe('重试跳转', '按当前节点的重试计数限制跳转次数,重试目标由 retry 出口连线指定。'),
|
||||
config: [
|
||||
{name: 'max_retries', type: 'number', required: true, default: 2, integer: true, min: 0, max: 10_000,
|
||||
i18n: describe('最大重试次数', '允许经过 retry 出口的次数;0 表示直接进入次数耗尽分支,默认允许重试 2 次。')},
|
||||
{name: 'delay_ms', type: 'number', required: true, default: 0, integer: true, min: 0, max: 2_147_483_647,
|
||||
i18n: describe('重试间隔', '每次重试跳转前等待的毫秒数,0 表示不增加等待时长。')},
|
||||
],
|
||||
output: output('json', '上一节点输出', '重试或次数耗尽时均透传上一节点的 output,缺失时为 null。'),
|
||||
ports: [port('retry', '重试', '未达到最大重试次数时增加计数、等待指定间隔,再以 success 状态跳转;必须连接重试目标。'),
|
||||
port('exhausted', '次数耗尽', '已达到最大重试次数时以 failure 状态执行,错误代码为 RETRY_EXHAUSTED。'), failure_port],
|
||||
};
|
||||
|
||||
export const execute: NodeHandler = async (node, state, signal, deps) => {
|
||||
if (node.type !== 'goto') throw new Error('Expected a goto node');
|
||||
signal.throwIfAborted();
|
||||
const count = Object.hasOwn(state.retry_counts, node.id) ? state.retry_counts[node.id] : 0;
|
||||
if (!Number.isSafeInteger(count) || count < 0 || !Number.isSafeInteger(node.config.max_retries)
|
||||
|| node.config.max_retries < 0 || !Number.isFinite(node.config.delay_ms) || node.config.delay_ms < 0) {
|
||||
throw Object.assign(new Error('Invalid retry configuration or count'), {code: 'INVALID_RETRY'});
|
||||
}
|
||||
if (count >= node.config.max_retries) {
|
||||
return {port: 'exhausted', result: {status: 'failure', output: state.last_result?.output ?? null,
|
||||
error: {code: 'RETRY_EXHAUSTED', message: 'Retry limit exhausted', node_id: node.id}}};
|
||||
}
|
||||
const retry_counts = {[node.id]: count + 1};
|
||||
assert_json(retry_counts);
|
||||
await deps.sleep('milliseconds', node.config.delay_ms, signal);
|
||||
signal.throwIfAborted();
|
||||
return {port: 'retry', result: {status: 'success', output: state.last_result?.output ?? null}, retry_counts};
|
||||
};
|
||||
Reference in New Issue
Block a user