diff --git a/mateclaw-ui/src/components/workflow/StepPropertyPanel.vue b/mateclaw-ui/src/components/workflow/StepPropertyPanel.vue
index 51e739a3..732b2e72 100644
--- a/mateclaw-ui/src/components/workflow/StepPropertyPanel.vue
+++ b/mateclaw-ui/src/components/workflow/StepPropertyPanel.vue
@@ -93,13 +93,13 @@
@@ -265,11 +265,15 @@ const { t } = useI18n()
const modeType = computed(() => (props.step?.mode?.type ?? 'sequential') as string)
const localizedModeLabel = computed(() => {
- const key = `workflows.canvas.modeLabels.${modeType.value}`
- const localized = t(key, '')
- return localized && localized !== key ? localized : modeType.value
+ return modeOptionLabel(modeType.value)
})
+function modeOptionLabel(type: string): string {
+ const key = `workflows.canvas.modeLabels.${type}`
+ const localized = t(key, '')
+ return localized && localized !== key ? localized : type
+}
+
const modeNeedsAgent = computed(() => {
// fan_out / collect / await_approval / dispatch_channel / write_memory
// don't take an agent — the runtime calls a service adapter instead.
diff --git a/mateclaw-ui/src/components/workflow/TriggerPatternForm.vue b/mateclaw-ui/src/components/workflow/TriggerPatternForm.vue
new file mode 100644
index 00000000..4be40a78
--- /dev/null
+++ b/mateclaw-ui/src/components/workflow/TriggerPatternForm.vue
@@ -0,0 +1,386 @@
+
+
+
+
+
+
+
diff --git a/mateclaw-ui/src/i18n/locales/en-US.ts b/mateclaw-ui/src/i18n/locales/en-US.ts
index c278437a..50c6d8b0 100644
--- a/mateclaw-ui/src/i18n/locales/en-US.ts
+++ b/mateclaw-ui/src/i18n/locales/en-US.ts
@@ -2081,6 +2081,37 @@ export default {
agent_lifecycle: 'Optional agentId and phase (spawned / terminated / crashed).',
workflow_completion: 'Optional sourceWorkflowId and stateFilter (completed / failed / any).',
},
+ pattern: {
+ cronExpression: 'Cron expression',
+ cronExpressionPlaceholder: '0 0 * * * *',
+ cronExpressionHint: '5 fields (min hour day month weekday) or 6 fields (with seconds). Each change bumps pattern_version.',
+ cronTimezone: 'Timezone',
+ cronTimezonePlaceholder: 'UTC',
+ channelType: 'Channel type',
+ channelTypeAny: 'Any channel',
+ senderEquals: 'Sender equals',
+ senderEqualsPlaceholder: 'Optional sender ID',
+ senderEqualsHint: 'Empty matches any sender; filled narrows to that one sender.',
+ substring: 'Substring',
+ substringPlaceholder: 'order',
+ substringHint: 'Case-insensitive. Empty strings refuse to fire (no broadcast trap).',
+ agentId: 'Agent ID',
+ agentIdPlaceholder: '0 means any',
+ agentIdHint: 'Empty or 0 matches any agent.',
+ phase: 'Lifecycle phase',
+ phaseAny: 'Any phase',
+ sourceWorkflowId: 'Source workflow',
+ sourceWorkflowAny: 'Any upstream',
+ stateFilter: 'Completion state',
+ stateFilterAny: 'Any state',
+ stateFilterHint: 'completed is an alias for succeeded; failed only matches failed terminal runs.',
+ webhookHeader: 'Webhook pass-through',
+ webhookBody: 'No filtering on the UI side — make sure the HTTP entry validates the webhook secret; every accepted request reaches the trigger.',
+ rawHeader: 'Raw pattern_json (advanced)',
+ errCronRequired: 'Cron expression cannot be empty',
+ errCronShape: 'Cron must be 5–7 fields',
+ errSubstringRequired: 'Substring cannot be empty or the trigger never fires',
+ },
unnamed: '(unnamed)',
rateUnit: '{count}/min',
enabled: 'enabled',
diff --git a/mateclaw-ui/src/i18n/locales/zh-CN.ts b/mateclaw-ui/src/i18n/locales/zh-CN.ts
index b51067ea..b26dc661 100644
--- a/mateclaw-ui/src/i18n/locales/zh-CN.ts
+++ b/mateclaw-ui/src/i18n/locales/zh-CN.ts
@@ -1943,10 +1943,10 @@ export default {
templates: {
label: '插入模板',
placeholder: '选择步骤模板',
- sequential: 'sequential(顺序步骤)',
- fan_out: 'fan_out(并行扇出)',
+ sequential: '顺序步骤',
+ fan_out: '并行扇出',
collect: 'collect(汇聚结果)',
- conditional: 'conditional(条件分支)',
+ conditional: '条件分支',
await_approval: 'await_approval(等待审批)',
dispatch_channel: 'dispatch_channel(消息分发)',
write_memory: 'write_memory(写入记忆)',
@@ -2093,6 +2093,37 @@ export default {
agent_lifecycle: '可选 agentId 和 phase(spawned / terminated / crashed)。',
workflow_completion: '可选 sourceWorkflowId 和 stateFilter(completed / failed / any)。',
},
+ pattern: {
+ cronExpression: 'Cron 表达式',
+ cronExpressionPlaceholder: '0 0 * * * *',
+ cronExpressionHint: '5 字段(分 时 日 月 周)或 6 字段(含秒)。修改后 pattern_version 自增。',
+ cronTimezone: '时区',
+ cronTimezonePlaceholder: 'Asia/Shanghai',
+ channelType: '渠道类型',
+ channelTypeAny: '任意渠道',
+ senderEquals: '发送者匹配',
+ senderEqualsPlaceholder: '可选,发送者 ID',
+ senderEqualsHint: '留空表示任意发送者;填写后只匹配该发送者的消息。',
+ substring: '子串匹配',
+ substringPlaceholder: '订单 / order',
+ substringHint: '不区分大小写。空字符串将拒绝触发(避免无意义广播)。',
+ agentId: '智能体 ID',
+ agentIdPlaceholder: '0 表示任意',
+ agentIdHint: '留空或填 0 表示任意智能体。',
+ phase: '生命周期阶段',
+ phaseAny: '任意阶段',
+ sourceWorkflowId: '上游工作流',
+ sourceWorkflowAny: '任意上游',
+ stateFilter: '完成状态',
+ stateFilterAny: '任意状态',
+ stateFilterHint: 'completed 等价于 succeeded;failed 仅匹配失败结束。',
+ webhookHeader: 'Webhook 透传匹配',
+ webhookBody: '此模式不在前端做过滤——请确保 HTTP 入口校验 webhook 密钥;通过校验的请求会全部进入触发器。',
+ rawHeader: '原始 pattern_json(高级)',
+ errCronRequired: 'Cron 表达式不能为空',
+ errCronShape: 'Cron 表达式格式不正确(5 ~ 7 字段)',
+ errSubstringRequired: '子串不能为空,否则触发器不会激活',
+ },
unnamed: '(未命名)',
rateUnit: '{count}/分钟',
enabled: '已启用',
diff --git a/mateclaw-ui/src/views/Triggers.vue b/mateclaw-ui/src/views/Triggers.vue
index def2276c..bdeadf9d 100644
--- a/mateclaw-ui/src/views/Triggers.vue
+++ b/mateclaw-ui/src/views/Triggers.vue
@@ -74,11 +74,15 @@
-
+
+ {{ t('triggers.fields.patternJson') }}
+
+