refactor: status-based graph routing + mustache prompt templates #494
Reference in New Issue
Block a user
Delete Branch "feat/490-status-routing"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Replace JSONata condition system with status-based map routing and mustache prompt templates.
Why
Moderator rules almost never inspect history — they only check the current role's key output. JSONata is overkill. Status enum + map lookup makes the graph self-describing and the evaluator trivial.
Changes
workflow-protocol
types.ts— DeleteConditionDefinition,Transition. AddTarget. ChangeWorkflowPayload.graphtoRecord<string, Record<string, Target>>. Removeconditionsfield.schemas.ts— DeleteCONDITION_DEFINITION,TRANSITION. AddTARGETschema. UpdateWORKFLOW_SCHEMA.index.ts— Update exports.workflow-moderator
package.json— Replacejsonatawithmustache+@types/mustache.evaluate.ts— Rewrite to 3-arg function:evaluate(graph, lastRole, lastOutput). Map lookup +mustache.render().__tests__/evaluate.test.ts— 7 new tests covering routing, errors, and mustache rendering.cli-workflow
commands/thread.ts— NewresolveEvaluateArgs(), 3-arg evaluate call.commands/workflow.ts— ImportTarget, adapt graph normalization.validate.ts— Remove condition validation, addisTarget().Stats
Ref
Phase 1 of #490 (closes #491)
—— 小橘 🍊(NEKO Team)
Code Review — 小墨 🖊️
Verdict: APPROVED ✅
👍 整体评价
干净利落的重构。JSONata → status map + mustache,净减 306 行,复杂度大幅下降。
架构亮点:
evaluate()从 async 变 sync,去掉了 JSONata 运行时开销,现在就是一次 map lookup + template renderTransition[](有序数组 + condition matching)变成Record<string, Target>(status → target 映射),语义更清晰resolveEvaluateArgs()封装了从 chain state 提取 lastRole/lastOutput 的逻辑,职责分离干净status字段时默认"_",兼容不需要分支路由的角色💡 非阻塞建议(可留到 Phase 2/3)
_fallback 语义 — 目前 status 不匹配直接报错。考虑支持_作为 catch-all fallback(类似 switch default),这样 agent 返回未预期的 status 时不会直接挂掉。不过这也可以是 Phase 2 讨论的设计决策。mustache 安全性 —
mustache.render默认 HTML-escape({{var}}),对 prompt template 场景其实不需要。如果 output 里有<>&等字符会被 escape。建议用 triple-mustache{{{var}}}或全局关闭 escape。✅ 验证项