diff --git a/mateclaw-ui/src/i18n/locales/en-US.ts b/mateclaw-ui/src/i18n/locales/en-US.ts index 30f8c4d6..d24edd6d 100644 --- a/mateclaw-ui/src/i18n/locales/en-US.ts +++ b/mateclaw-ui/src/i18n/locales/en-US.ts @@ -301,6 +301,8 @@ export default { security: 'Security', tokenUsage: 'Token Usage', cronJobs: 'Cron Jobs', + workflows: 'Workflows', + triggers: 'Triggers', settings: 'Settings', logout: 'Logout', memory: 'Memory', @@ -1904,6 +1906,129 @@ export default { goalRequired: 'Goal is required', }, }, + workflows: { + kicker: 'Workflows', + title: 'Workflow Editor', + desc: 'Author multi-step workflows. Save the draft as you go, compile to surface diagnostics, then publish a revision when it is ready to run.', + newWorkflow: '+ New Workflow', + defined: 'Defined ({count})', + refresh: 'Refresh', + unnamed: '(unnamed)', + draftBadge: 'draft', + publishedBadge: 'v{rev}', + listEmpty: 'No workflows yet — create one to get started.', + namePlaceholder: 'Workflow name', + descPlaceholder: 'Optional description', + actions: { + saveMeta: 'Save Meta', + saveDraft: 'Save Draft', + compile: 'Compile', + publish: 'Publish', + delete: 'Delete', + }, + bodyPlaceholder: '{"steps":[{"name":"step-a","agentName":"...","mode":{"type":"sequential"},"promptTemplate":"..."}]}', + compileErrorsTitle: '{count} compile error(s)', + templates: { + label: 'Insert template', + placeholder: 'Pick a step template', + sequential: 'sequential (linear step)', + fan_out: 'fan_out (parallel)', + collect: 'collect (join fan_out)', + conditional: 'conditional (gated)', + await_approval: 'await_approval (pause)', + dispatch_channel: 'dispatch_channel (broadcast)', + write_memory: 'write_memory (persist)', + }, + jsonInvalid: 'JSON parse failed: {msg}', + jsonOk: 'JSON syntax OK.', + selectHint: 'Select a workflow on the left, or click "New Workflow" to start a fresh draft.', + runs: { + header: 'Recent runs ({count})', + empty: 'No runs yet.', + detailTitle: 'Run #{id} — {state}', + runHash: 'run #{id}', + }, + prompts: { + newName: 'New workflow name:', + defaultName: 'untitled-workflow', + publishNote: 'Optional publish note:', + deleteConfirm: 'Delete workflow "{name}"? This is reversible via the audit log.', + }, + status: { + metaSaved: 'Metadata saved.', + draftSaved: 'Draft saved.', + compileOk: 'Compile OK.', + published: 'Published.', + deleted: 'Deleted.', + createFailed: 'Create failed: {msg}', + saveFailed: 'Save failed: {msg}', + saveDraftFailed: 'Save draft failed: {msg}', + deleteFailed: 'Delete failed: {msg}', + compileFailed: '{count} compile error(s) — see panel below.', + compileFallback: 'Compile / publish failed.', + }, + }, + triggers: { + kicker: 'Triggers', + title: 'Workflow Triggers', + desc: 'Connect cron schedules and channel events to your published workflows. pattern_version increments on every cron expression change so multi-node deployments coordinate correctly.', + newTrigger: '+ New Trigger', + columns: { + name: 'Name', + pattern: 'Pattern', + target: 'Target Workflow', + rate: 'Rate', + fires: 'Fires', + patternVersion: 'pattern_v', + lastFired: 'Last fired', + state: 'State', + actions: 'Actions', + }, + targetWorkflowSelect: 'Pick a published workflow', + targetWorkflowEmpty: 'No published workflows yet.', + patternHints: { + cron: 'Example: {"cron":"0 0 * * * *","timezone":"UTC"} — every cron change bumps pattern_version.', + channel_message: 'Optional channelType (e.g. feishu) and senderEquals narrow the match.', + webhook: 'Pass-through match. Ensure the HTTP entry validates the webhook secret.', + content_match: 'Requires substring (case-insensitive). Empty strings refuse to fire.', + agent_lifecycle: 'Optional agentId and phase (spawned / terminated / crashed).', + workflow_completion: 'Optional sourceWorkflowId and stateFilter (completed / failed / any).', + }, + unnamed: '(unnamed)', + rateUnit: '{count}/min', + enabled: 'enabled', + disabled: 'disabled', + empty: 'No triggers configured.', + actions: { + edit: 'Edit', + delete: 'Delete', + cancel: 'Cancel', + save: 'Save', + close: 'Close', + }, + formTitleNew: 'New Trigger', + formTitleEdit: 'Edit Trigger', + fields: { + name: 'Name', + namePlaceholder: 'hourly-cleanup', + patternType: 'Pattern type', + patternJson: 'Pattern JSON', + patternJsonPlaceholder: '{"cron":"0 0 * * * *","timezone":"UTC"}', + targetType: 'Target type', + targetId: 'Target id', + ratePerMin: 'Rate / min', + dedupWindowSecs: 'Dedup window (s)', + maxFires: 'Max fires (0 = unlimited)', + botSelfFilter: 'Bot-self filter (recommended)', + payloadTemplate: 'Payload template (Pebble)', + payloadTemplatePlaceholder: '{"who":"{{ event.who }}"}', + enabled: 'Enabled', + }, + deleteConfirm: 'Delete trigger "{name}"?', + saveFailed: 'Save failed: {msg}', + toggleFailed: 'Toggle failed: {msg}', + deleteFailed: 'Delete failed: {msg}', + }, login: { kicker: 'AI Operating System', subtitle: 'Your intelligent AI assistant', diff --git a/mateclaw-ui/src/i18n/locales/zh-CN.ts b/mateclaw-ui/src/i18n/locales/zh-CN.ts index 5350ecdb..d989ba8f 100644 --- a/mateclaw-ui/src/i18n/locales/zh-CN.ts +++ b/mateclaw-ui/src/i18n/locales/zh-CN.ts @@ -301,6 +301,8 @@ export default { security: '安全', tokenUsage: 'Token 统计', cronJobs: '定时任务', + workflows: '工作流', + triggers: '触发器', settings: '设置', logout: '退出登录', themeLight: '浅色', @@ -1916,6 +1918,129 @@ export default { goalRequired: '执行目标不能为空', }, }, + workflows: { + kicker: '工作流', + title: '工作流编辑器', + desc: '编排多步骤工作流:边写边存草稿,编译查看诊断,准备好后发布版本。', + newWorkflow: '+ 新建工作流', + defined: '已定义 ({count})', + refresh: '刷新', + unnamed: '(未命名)', + draftBadge: '草稿', + publishedBadge: 'v{rev}', + listEmpty: '还没有任何工作流,新建一个开始吧。', + namePlaceholder: '工作流名称', + descPlaceholder: '可选描述', + actions: { + saveMeta: '保存元数据', + saveDraft: '保存草稿', + compile: '编译', + publish: '发布', + delete: '删除', + }, + bodyPlaceholder: '{"steps":[{"name":"step-a","agentName":"...","mode":{"type":"sequential"},"promptTemplate":"..."}]}', + compileErrorsTitle: '{count} 条编译错误', + templates: { + label: '插入模板', + placeholder: '选择步骤模板', + sequential: 'sequential(顺序步骤)', + fan_out: 'fan_out(并行扇出)', + collect: 'collect(汇聚结果)', + conditional: 'conditional(条件分支)', + await_approval: 'await_approval(等待审批)', + dispatch_channel: 'dispatch_channel(消息分发)', + write_memory: 'write_memory(写入记忆)', + }, + jsonInvalid: 'JSON 解析失败:{msg}', + jsonOk: 'JSON 语法 OK。', + selectHint: '在左侧选择一个工作流,或点击「新建工作流」开始。', + runs: { + header: '近期运行 ({count})', + empty: '暂无运行记录。', + detailTitle: 'Run #{id} — {state}', + runHash: 'run #{id}', + }, + prompts: { + newName: '新工作流名称:', + defaultName: 'untitled-workflow', + publishNote: '可选发布备注:', + deleteConfirm: '删除工作流「{name}」?此操作可通过审计日志撤销。', + }, + status: { + metaSaved: '元数据已保存。', + draftSaved: '草稿已保存。', + compileOk: '编译通过。', + published: '已发布。', + deleted: '已删除。', + createFailed: '创建失败:{msg}', + saveFailed: '保存失败:{msg}', + saveDraftFailed: '草稿保存失败:{msg}', + deleteFailed: '删除失败:{msg}', + compileFailed: '{count} 条编译错误,详见下方面板。', + compileFallback: '编译/发布失败。', + }, + }, + triggers: { + kicker: '触发器', + title: '工作流触发器', + desc: '把 cron 调度和渠道事件接到已发布的工作流上。每次修改 cron 表达式都会让 pattern_version 自增,多节点部署据此协调。', + newTrigger: '+ 新建触发器', + columns: { + name: '名称', + pattern: '模式', + target: '目标工作流', + rate: '速率', + fires: '触发次数', + patternVersion: 'pattern_v', + lastFired: '上次触发', + state: '状态', + actions: '操作', + }, + targetWorkflowSelect: '选择已发布的工作流', + targetWorkflowEmpty: '尚无已发布的工作流。', + patternHints: { + cron: '示例:{"cron":"0 0 * * * *","timezone":"Asia/Shanghai"} —— 每次修改 cron 都会让 pattern_version 自增。', + channel_message: '可填 channelType(如 feishu)和 senderEquals 进一步过滤。', + webhook: '透传匹配,请确保 HTTP 入口已校验 webhook 密钥。', + content_match: '需要 substring(不区分大小写)。空字符串将拒绝触发。', + agent_lifecycle: '可选 agentId 和 phase(spawned / terminated / crashed)。', + workflow_completion: '可选 sourceWorkflowId 和 stateFilter(completed / failed / any)。', + }, + unnamed: '(未命名)', + rateUnit: '{count}/分钟', + enabled: '已启用', + disabled: '已停用', + empty: '暂无触发器配置。', + actions: { + edit: '编辑', + delete: '删除', + cancel: '取消', + save: '保存', + close: '关闭', + }, + formTitleNew: '新建触发器', + formTitleEdit: '编辑触发器', + fields: { + name: '名称', + namePlaceholder: 'hourly-cleanup', + patternType: '模式类型', + patternJson: '模式 JSON', + patternJsonPlaceholder: '{"cron":"0 0 * * * *","timezone":"UTC"}', + targetType: '目标类型', + targetId: '目标 ID', + ratePerMin: '每分钟速率', + dedupWindowSecs: '去重窗口(秒)', + maxFires: '最大触发数(0 = 不限)', + botSelfFilter: 'Bot 自循环过滤(推荐)', + payloadTemplate: '载荷模板(Pebble)', + payloadTemplatePlaceholder: '{"who":"{{ event.who }}"}', + enabled: '启用', + }, + deleteConfirm: '删除触发器「{name}」?', + saveFailed: '保存失败:{msg}', + toggleFailed: '切换失败:{msg}', + deleteFailed: '删除失败:{msg}', + }, login: { kicker: 'AI Operating System', subtitle: '你的智能 AI 助手', diff --git a/mateclaw-ui/src/views/Triggers.vue b/mateclaw-ui/src/views/Triggers.vue index ce7e3fa3..0c834c9c 100644 --- a/mateclaw-ui/src/views/Triggers.vue +++ b/mateclaw-ui/src/views/Triggers.vue @@ -4,52 +4,52 @@
- Connect cron schedules and channel events to your published workflows. - Pattern_version increments on every cron expression change so multi-node - deployments coordinate correctly. -
+{{ t('triggers.desc') }}
| Name | -Pattern | -Target Workflow | -Rate | -Fires | -State | -Actions | +{{ t('triggers.columns.name') }} | +{{ t('triggers.columns.pattern') }} | +{{ t('triggers.columns.target') }} | +{{ t('triggers.columns.rate') }} | +{{ t('triggers.columns.fires') }} | +{{ t('triggers.columns.patternVersion') }} | +{{ t('triggers.columns.lastFired') }} | +{{ t('triggers.columns.state') }} | +{{ t('triggers.columns.actions') }} |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| {{ t.name || '(unnamed)' }} | +|||||||||||||||
| {{ row.name || t('triggers.unnamed') }} |
- {{ t.patternType }}
- {{ t.patternJson }}
+ {{ row.patternType }}
+ {{ row.patternJson }}
|
- {{ t.targetType }}#{{ t.targetId }} | -{{ t.rateLimitPerMin }}/min | -{{ t.fireCount }} / {{ t.maxFires }} | +{{ formatTarget(row) }} | +{{ t('triggers.rateUnit', { count: row.rateLimitPerMin }) }} | +{{ row.fireCount }} / {{ row.maxFires }} | +{{ row.patternVersion }} | +{{ formatTime(row.lastFiredAt) }} | - - + + | |||||
| No triggers configured. | +{{ t('triggers.empty') }} | ||||||||||||||