/** * Prefer kd-grill on new Kingdee delivery turns. * Does not block coding; injects guidance only. */ export type GrillSoftHint = { shouldPreferGrill: boolean; reason: string; systemLines: string[]; }; const SKIP_TERMS = [ "只改 readme", "只改文档", "changelog", "写文档", "翻译文档", "更新说明", "直接写", "别问", "不要问", "别确认", "不用确认", "跳过澄清", "skip grill", "no grill", ] as const; const KINGDEE_DEV_TERMS = [ "插件", "plugin", "表单", "列表", "操作插件", "单据", "分录", "openapi", "webapi", "苍穹", "星瀚", "星空", "企业版", "bos", "abstractbill", "abstractform", "二开", "扩展", "下推", "审核", "保存", "字段", "表单插件", ] as const; const NEW_WORK_TERMS = [ "写", "做", "实现", "开发", "加一个", "搞一个", "帮我", "需要", "要一个", "新增", "做一个", "来个", "生成", "创建", ] as const; function hasAny(text: string, terms: readonly string[]): boolean { const lower = text.toLowerCase(); return terms.some(t => lower.includes(t.toLowerCase())); } export function buildGrillSoftHint(prompt: string): GrillSoftHint { const text = (prompt || "").trim(); if (!text) { return { shouldPreferGrill: false, reason: "empty", systemLines: [] }; } if (hasAny(text, SKIP_TERMS)) { return { shouldPreferGrill: false, reason: "user asked to skip clarify / direct write", systemLines: [], }; } const kingdee = hasAny(text, KINGDEE_DEV_TERMS); const newWork = hasAny(text, NEW_WORK_TERMS); const shortDelivery = kingdee && (text.length < 80 || /校验|联动|只读|批量|推单|对接|打开|加载|提示|拦/.test(text)); if (!kingdee || (!newWork && !shortDelivery)) { return { shouldPreferGrill: false, reason: "not new kingdee delivery", systemLines: [], }; } const lines = [ "", "## 本轮建议:优先 kd-grill 与通用契约", "", "- 优先 skill `kd-grill`:对齐产品线、生命周期位、目标单据、边界。", "- **通用契约** `api-surface-contract.md`(覆盖任意场景,非单题样例):", " 1) 生命周期位 → 表单/列表/操作/转换/OpenAPI;", " 2) 每个字段字符串 → 访问位:GetValue/SetValue/FieldKeys=Key,entity/entry/DataEntity 索引=PropertyName,SQL=FieldName;", " 3) API ⊆ 当前类型 assets 手册,禁止面外方法。", "- 红旗:`entity[\"F…\"]` / `entry[\"F…\"]` 通常是 Key 误作 PropertyName(任意字段,不限数量)。", "- 企业版:禁止口算去 F;数据包索引用 PropertyName(元数据)。", "- 旗舰/苍穹/星瀚:不套企业版三标识;entityId 禁止物理表名。", "- 字段取证(企业版与旗舰相同):Agent 引导只读 SQL 连业务库 + LLM 解析(metadata-db-query.md),**非 MCP**。", "- 无主机/库名/只读认证时:**先向用户索取连接信息**,禁止装成已验证。", "- 用户明确跳过查库:可写码,字段必须标 // source=assumption 待库验证。", "- 实现:产品 skill + assets;禁止臆造 SDK。", "", ]; return { shouldPreferGrill: true, reason: "new kingdee delivery — prefer kd-grill first", systemLines: lines, }; } export function withGrillPreferred(skills: string[], prefer: boolean): string[] { if (!prefer) return skills; const rest = skills.filter(s => s !== "kd-grill"); return ["kd-grill", ...rest]; }