diff --git a/mateclaw-server/src/main/java/vip/mate/trigger/ingest/TriggerPatternMatcher.java b/mateclaw-server/src/main/java/vip/mate/trigger/ingest/TriggerPatternMatcher.java index ea1caea4..59fc102a 100644 --- a/mateclaw-server/src/main/java/vip/mate/trigger/ingest/TriggerPatternMatcher.java +++ b/mateclaw-server/src/main/java/vip/mate/trigger/ingest/TriggerPatternMatcher.java @@ -97,6 +97,20 @@ public class TriggerPatternMatcher { if (wantSender != null && !wantSender.equals(envelope.senderId())) { return false; } + // contentContains is the keyword filter the templates relied on + // — without it a "feishu + 发票" trigger would fire on every + // feishu message. Matches case-insensitively against + // envelope.data.content, the same field content_match uses. + // Keeping the field on channel_message also folds the redundant + // content_match pattern type into the more general channel one; + // content_match remains supported for backwards compatibility + // via {@link #matchesContent}. + String wantContains = textOrNull(pattern, "contentContains"); + if (wantContains != null) { + Object content = envelope.data() == null ? null : envelope.data().get("content"); + if (!(content instanceof String body)) return false; + if (!body.toLowerCase().contains(wantContains.toLowerCase())) return false; + } return true; } diff --git a/mateclaw-server/src/main/java/vip/mate/workflow/draftgen/WorkflowDraftGenerator.java b/mateclaw-server/src/main/java/vip/mate/workflow/draftgen/WorkflowDraftGenerator.java index 11824c27..65d0f4ed 100644 --- a/mateclaw-server/src/main/java/vip/mate/workflow/draftgen/WorkflowDraftGenerator.java +++ b/mateclaw-server/src/main/java/vip/mate/workflow/draftgen/WorkflowDraftGenerator.java @@ -83,7 +83,7 @@ public class WorkflowDraftGenerator { conditional — mode.expression 必填(Pebble 子集,如 {{ outputs.x.approved == true }});agentId/agentName + promptTemplate 必填。 await_approval — approvalKind + approverChannels[] + approvalMessage 必填;可选 timeoutSecs;不要 agentId / agentName / promptTemplate。 dispatch_channel — channels[] + targets{} + content 必填;不要 agentId / agentName / promptTemplate。 - write_memory — employeeId + file + mergeStrategy(append/prepend/replace_section/upsert_kv/overwrite) + content 必填;不要 agentId / agentName / promptTemplate。 + write_memory — employeeId + file + mergeStrategy(append/replace_section/upsert_kv/overwrite) + content 必填;不要 agentId / agentName / promptTemplate。 # 不支持 @@ -214,13 +214,33 @@ public class WorkflowDraftGenerator { } // --- 6. trigger drafts ----------------------------------------- + // patternType allowlist mirrors what TriggerService accepts at + // create time. The generator prompt forbids agent_lifecycle and + // content_match; we filter defensively here too because models + // occasionally hallucinate trigger types under low confidence, + // and we don't want a future UI / tool that calls /draft/generate + // and trusts the response to silently re-introduce dropped types. + java.util.Set allowedPatternTypes = java.util.Set.of( + "cron", "channel_message", "workflow_completion", "webhook"); List> triggerDrafts = new ArrayList<>(); if (root.has("triggerDrafts") && root.get("triggerDrafts").isArray()) { - triggerDrafts = objectMapper.convertValue(root.get("triggerDrafts"), + List> candidates = objectMapper.convertValue(root.get("triggerDrafts"), new TypeReference>>() {}); - for (Map td : triggerDrafts) { + int dropped = 0; + for (Map td : candidates) { + String pt = td.get("patternType") instanceof String s ? s : null; + if (pt == null || !allowedPatternTypes.contains(pt)) { + dropped++; + continue; + } // Belt-and-suspenders: never trust the LLM to honor enabled=false. td.put("enabled", false); + triggerDrafts.add(td); + } + if (dropped > 0) { + warnings = appendWarning(warnings, + "dropped " + dropped + " unsupported triggerDraft entr" + (dropped == 1 ? "y" : "ies") + + " (allowed: " + String.join(", ", allowedPatternTypes) + ")"); } } diff --git a/mateclaw-server/src/main/java/vip/mate/workflow/draftgen/WorkflowDraftTemplateLibrary.java b/mateclaw-server/src/main/java/vip/mate/workflow/draftgen/WorkflowDraftTemplateLibrary.java index bd598533..9aab8721 100644 --- a/mateclaw-server/src/main/java/vip/mate/workflow/draftgen/WorkflowDraftTemplateLibrary.java +++ b/mateclaw-server/src/main/java/vip/mate/workflow/draftgen/WorkflowDraftTemplateLibrary.java @@ -160,7 +160,7 @@ public class WorkflowDraftTemplateLibrary { [{"name":"daily-memory-cron","patternType":"cron","enabled":false, "patternJson":{"cron":"0 0 22 * * ?","timezone":"Asia/Shanghai"}, "targetType":"workflow", - "payloadTemplate":"{\\"topic\\":\\"工作\\",\\"date\\":\\"{{ trigger.firedAt }}\\"}"}]""" + "payloadTemplate":"{\\"topic\\":\\"工作\\",\\"date\\":\\"{{ event.firedAt }}\\"}"}]""" ); } diff --git a/mateclaw-ui/src/components/workflow/GenerateWorkflowDialog.vue b/mateclaw-ui/src/components/workflow/GenerateWorkflowDialog.vue index 3d301ecd..700cc620 100644 --- a/mateclaw-ui/src/components/workflow/GenerateWorkflowDialog.vue +++ b/mateclaw-ui/src/components/workflow/GenerateWorkflowDialog.vue @@ -8,6 +8,22 @@