@roll-agent/smart-reply-agent 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,46 +22,57 @@
22
22
  {
23
23
  "id": "pos-001",
24
24
  "name": "服务员",
25
+ "sourceJobName": "示例品牌-南山店-服务员-兼职",
26
+ "jobCategory": "普通服务员",
25
27
  "brandId": "10001",
26
28
  "brandName": "示例品牌",
27
- "timeSlots": ["08:00-14:00", "14:00-22:00"],
29
+ "description": "负责门店日常服务工作",
30
+ "laborForm": "兼职",
31
+ "employmentForm": "长期用工",
32
+ "trainingRequired": "不需要",
33
+ "probationRequired": "不需要",
34
+ "timeSlots": ["08:00~14:00", "14:00~22:00"],
28
35
  "salary": {
29
36
  "base": 22,
37
+ "unit": "元/时",
30
38
  "range": "20-25",
31
39
  "memo": "时薪制,多劳多得"
32
40
  },
33
- "workHours": "6-8小时/天",
41
+ "workHours": "6",
34
42
  "benefits": {
35
- "items": ["包工作餐", "交通补贴"]
36
- },
37
- "requirements": ["18-45岁", "健康证"],
38
- "urgent": false,
39
- "scheduleType": "flexible",
40
- "attendancePolicy": {
41
- "punctualityRequired": true,
42
- "lateToleranceMinutes": 10,
43
- "attendanceTracking": "strict",
44
- "makeupShiftsAllowed": true
43
+ "insurance": "独立日购买",
44
+ "accommodation": "无住宿福利",
45
+ "catering": "包吃",
46
+ "moreWelfares": null,
47
+ "memo": null,
48
+ "promotion": null
45
49
  },
46
50
  "availableSlots": [
47
51
  {
48
- "slot": "08:00-14:00",
52
+ "slot": "08:00~14:00",
49
53
  "maxCapacity": 5,
50
54
  "currentBooked": 3,
51
55
  "isAvailable": true,
52
56
  "priority": "high"
53
57
  }
54
58
  ],
55
- "schedulingFlexibility": {
56
- "canSwapShifts": true,
57
- "advanceNoticeHours": 24,
58
- "partTimeAllowed": true,
59
- "weekendRequired": false,
60
- "holidayRequired": false
59
+ "minHoursPerWeek": 18,
60
+ "maxHoursPerWeek": 42,
61
+ "perMonthMinWorkTime": 80,
62
+ "attendanceRequirement": {
63
+ "minimumDays": 3,
64
+ "requiredDays": [1, 2, 3, 4, 5],
65
+ "description": "每周至少3天"
61
66
  },
62
67
  "hiringRequirements": {
63
68
  "minAge": 18,
64
- "maxAge": 45
69
+ "maxAge": 45,
70
+ "genderRequirement": null,
71
+ "education": "不限",
72
+ "healthCertificate": "食品健康证",
73
+ "languages": "普通话",
74
+ "certificatesRaw": "健康证",
75
+ "recruitmentRemark": null
65
76
  }
66
77
  }
67
78
  ]
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{defineAgent as e}from"@roll-agent/sdk";import{defineTool as t}from"@roll-agent/sdk";import{z as n}from"zod";import{z as r}from"zod";import{z as a}from"zod";var o=a.object({lat:a.number(),lng:a.number()}),i=r.object({name:r.string().optional(),position:r.string().optional(),expectedPosition:r.string().optional(),communicationPosition:r.string().optional(),age:r.string().optional(),gender:r.string().optional(),experience:r.string().optional(),education:r.string().optional(),expectedSalary:r.string().optional(),expectedLocation:r.string().optional(),jobAddress:r.string().optional(),height:r.string().optional(),weight:r.string().optional(),healthCertificate:r.boolean().optional(),activeTime:r.string().optional(),info:r.array(r.string()).optional(),fullText:r.string().optional()}),s=r.object({base:r.number(),range:r.string().optional(),bonus:r.string().optional(),memo:r.string(),scenarioSummary:r.string().optional(),settlementCycle:r.string().optional()}),l=r.object({items:r.array(r.string()),promotion:r.string().optional()}),u=r.object({requiredDays:r.array(r.number().min(1).max(7)).optional(),minimumDays:r.number().min(0).optional(),description:r.string()}),c=r.enum(["fixed","flexible","rotating","on_call"]),d=r.object({punctualityRequired:r.boolean(),lateToleranceMinutes:r.number().min(0),attendanceTracking:r.enum(["strict","flexible","none"]),makeupShiftsAllowed:r.boolean()}),m=r.object({slot:r.string(),maxCapacity:r.number().min(0),currentBooked:r.number().min(0),isAvailable:r.boolean(),priority:r.enum(["high","medium","low"])}),p=r.object({canSwapShifts:r.boolean(),advanceNoticeHours:r.number().min(0),partTimeAllowed:r.boolean(),weekendRequired:r.boolean(),holidayRequired:r.boolean()}),g=r.object({minAge:r.number().nullable().optional(),maxAge:r.number().nullable().optional(),genderRequirement:r.string().nullable().optional(),education:r.string().nullable().optional(),healthCertificate:r.string().nullable().optional()}),f=r.object({id:r.string(),name:r.string(),brandId:r.string().optional(),brandName:r.string().optional(),projectId:r.string().optional(),projectName:r.string().optional(),timeSlots:r.array(r.string()),salary:s,workHours:r.string(),benefits:l,requirements:r.array(r.string()),urgent:r.boolean(),scheduleType:c,attendancePolicy:d,availableSlots:r.array(m),schedulingFlexibility:p,minHoursPerWeek:r.number().min(0).optional(),maxHoursPerWeek:r.number().min(0).optional(),attendanceRequirement:u.optional(),hiringRequirements:g.optional(),description:r.string().optional()}),y=r.object({id:r.string(),brandId:r.string(),name:r.string(),city:r.string().optional(),location:r.string(),district:r.string(),subarea:r.string(),coordinates:o,positions:r.array(f)}),b=r.object({defaultBrandId:r.string().optional(),syncedAt:r.string().optional(),source:r.string().optional()}),h=r.object({id:r.string(),name:r.string(),aliases:r.array(r.string()).optional(),stores:r.array(y)}),S=r.object({meta:b,brands:r.array(h)});import{existsSync as N,readFileSync as I,writeFileSync as T}from"node:fs";import{dirname as A,join as _}from"node:path";import{z as E}from"zod";var R=E.enum(["trust_building","private_channel","qualify_candidate","job_consultation","interview_scheduling","onboard_followup"]),O=E.enum(["public","private"]),L=E.enum(["minimal","focused"]),v=E.enum(["salary","schedule","location","policy","requirements","availability"]),w={trust_building:{description:"初次接触,建立信任并了解求职意向",transitionSignal:"候选人表达明确兴趣或开始询问具体岗位信息",applicableChannels:["public","private"]},private_channel:{description:"引导用户从公域平台(如BOSS直聘/鱼泡)转入微信私聊",transitionSignal:"候选人有继续深入了解的意愿,适合引导到私域",applicableChannels:["public"]},qualify_candidate:{description:"轻量确认候选人的关键匹配信息,避免审查式盘问",transitionSignal:"候选人表达求职意向后,需要核实基本资格",applicableChannels:["public","private"]},job_consultation:{description:"回答岗位相关问题(薪资、排班、地点等)并提升兴趣",transitionSignal:"候选人主动询问岗位细节",applicableChannels:["public","private"]},interview_scheduling:{description:"推动面试预约,确认时间和到店安排",transitionSignal:"候选人核心问题已解答,准备推进面试",applicableChannels:["public","private"]},onboard_followup:{description:"促进到岗并保持回访",transitionSignal:"候选人确认上岗安排",applicableChannels:["public","private"]}},k=E.enum(["stores","location","salary","schedule","policy","availability","requirements","interview","wechat","none"]),M=E.enum(["insurance_promise_risk","age_sensitive","confrontation_emotion","urgency_high","qualification_mismatch"]),D={stores:["location"],location:["location"],salary:["salary"],schedule:["schedule"],policy:["policy"],availability:["availability"],requirements:["requirements"],interview:[],wechat:[],none:[]},x=E.object({mentionedBrand:E.string().nullable(),city:E.string().nullable(),mentionedLocations:E.array(E.object({location:E.string(),confidence:E.number().min(0).max(1)})).nullable(),mentionedDistricts:E.array(E.object({district:E.string(),confidence:E.number().min(0).max(1)})).max(10).nullable(),specificAge:E.number().nullable(),hasUrgency:E.boolean().nullable(),preferredSchedule:E.string().nullable()}),C=E.object({stage:R,subGoals:E.array(E.string()).max(2),needs:E.array(k).max(8),primaryNeed:k,riskFlags:E.array(M).max(6),confidence:E.number().min(0).max(1),extractedInfo:x,reasoningText:E.string()}),U=E.object({description:E.string().optional(),primaryGoal:E.string(),successCriteria:E.array(E.string()),ctaStrategy:E.preprocess(e=>Array.isArray(e)?e.join("\n"):e,E.string()),disallowedActions:E.array(E.string()).optional()}),$=E.object({tone:E.string(),warmth:E.string(),humor:E.string(),length:E.enum(["short","medium","long"]),questionStyle:E.string(),empathyStrategy:E.string(),addressStyle:E.string(),professionalIdentity:E.string(),companyBackground:E.string()}),j=E.object({name:E.string(),industryBackground:E.string(),jargon:E.array(E.string()),styleKeywords:E.array(E.string()),tabooPhrases:E.array(E.string()),guidance:E.array(E.string())}),W=E.object({id:E.string(),rule:E.string(),severity:E.enum(["high","medium","low"])}),F=E.object({rules:E.array(W)}),P=E.object({mode:E.enum(["strict","balanced","open"]),verifiableClaimTypes:E.array(E.string()),fallbackBehavior:E.enum(["generic_answer","ask_followup","handoff"]),forbiddenWhenMissingFacts:E.array(E.string())}),B={maxQuestionsByMode:{minimal:1,focused:2},blockedAuditPhrases:["是否满足","是否符合","基本入职要求","先确认资格","年龄是否符合"],blockFirstTurnSpecificFacts:!0},G=E.object({maxQuestionsByMode:E.object({minimal:E.number().int().min(0),focused:E.number().int().min(0)}),blockedAuditPhrases:E.array(E.string()),blockFirstTurnSpecificFacts:E.boolean()}),q=E.object({enabled:E.boolean().default(!0),revealRange:E.boolean().default(!1),failStrategy:E.string().default("礼貌说明不匹配,避免承诺"),unknownStrategy:E.string().default("先核实年龄或资格条件"),passStrategy:E.string().default("确认匹配后推进下一步"),allowRedirect:E.boolean().default(!0),redirectPriority:E.enum(["low","medium","high"]).default("medium")}),H=E.object({age:q.default({enabled:!0,revealRange:!1,failStrategy:"礼貌说明不匹配,避免承诺",unknownStrategy:"先核实年龄或资格条件",passStrategy:"确认匹配后推进下一步",allowRedirect:!0,redirectPriority:"medium"})}).default({age:{enabled:!0,revealRange:!1,failStrategy:"礼貌说明不匹配,避免承诺",unknownStrategy:"先核实年龄或资格条件",passStrategy:"确认匹配后推进下一步",allowRedirect:!0,redirectPriority:"medium"}}),K=E.object({trust_building:U,private_channel:U.optional(),qualify_candidate:U,job_consultation:U,interview_scheduling:U,onboard_followup:U}).transform(e=>({...e,private_channel:e.private_channel??e.trust_building})),V=E.object({stageGoals:K,persona:$,industryVoices:E.record(E.string(),j),defaultIndustryVoiceId:E.string(),hardConstraints:F,factGate:P,qualificationPolicy:H,outputGuards:G.default(B)}),Y={stageGoals:{trust_building:{description:"初次接触,建立信任并了解求职意向",primaryGoal:"建立信任并了解求职意向",successCriteria:["候选人愿意继续沟通"],ctaStrategy:"用轻量提问引导需求细化",disallowedActions:["过早承诺具体待遇"]},private_channel:{description:"引导用户从公域平台(如BOSS直聘/鱼泡)转入微信私聊",primaryGoal:"推动进入私域沟通",successCriteria:["候选人愿意交换联系方式"],ctaStrategy:"说明后续沟通效率与资料同步价值",disallowedActions:["强迫式要微信"]},qualify_candidate:{description:"轻量确认候选人的关键匹配信息,避免审查式盘问",primaryGoal:"确认一个关键匹配信息并保持继续沟通意愿",successCriteria:["明确一个关键匹配信息","候选人愿意继续沟通"],ctaStrategy:"先回应关切,再顺带确认一个最关键条件",disallowedActions:["连续盘问多个资格条件","直接否定候选人"]},job_consultation:{description:"回答岗位相关问题(薪资、排班、地点等)并提升兴趣",primaryGoal:"回答岗位问题并提升兴趣",successCriteria:["候选人对岗位保持兴趣"],ctaStrategy:"先答核心问题,再给下一步建议",disallowedActions:["编造数字或政策"]},interview_scheduling:{description:"推动面试预约,确认时间和到店安排",primaryGoal:"推动面试预约",successCriteria:["候选人给出可面试时间"],ctaStrategy:"给出明确时间选项并确认",disallowedActions:["不确认候选人可到店性"]},onboard_followup:{description:"促进到岗并保持回访",primaryGoal:"促进到岗并保持回访",successCriteria:["候选人确认上岗安排"],ctaStrategy:"明确下一步动作与提醒",disallowedActions:["承诺不确定资源"]}},persona:{tone:"口语化",warmth:"高",humor:"低",length:"short",questionStyle:"单轮一个关键问题",empathyStrategy:"先认可关切再给建议",addressStyle:"使用你",professionalIdentity:"资深招聘专员",companyBackground:"连锁餐饮招聘"},industryVoices:{default:{name:"餐饮连锁招聘",industryBackground:"门店密集、排班灵活、强调稳定出勤",jargon:["排班","到岗","门店","班次"],styleKeywords:["直接","清晰","可信"],tabooPhrases:["包过","绝对","随便都行"],guidance:["先解决顾虑,再推动下一步"]}},defaultIndustryVoiceId:"default",hardConstraints:{rules:[{id:"no-fabrication",rule:"不得编造门店、薪资、排班、福利等事实信息",severity:"high"},{id:"no-insurance-promise",rule:"兼职场景不得承诺五险一金",severity:"high"},{id:"age-sensitive",rule:"年龄敏感问题使用合规话术,不暴露内部筛选线",severity:"high"}]},factGate:{mode:"strict",verifiableClaimTypes:["salary","location","schedule","policy","availability"],fallbackBehavior:"generic_answer",forbiddenWhenMissingFacts:["具体数字","具体门店承诺","明确福利承诺"]},qualificationPolicy:{age:{enabled:!0,revealRange:!1,failStrategy:"礼貌说明不匹配,避免承诺",unknownStrategy:"先核实年龄或资格条件",passStrategy:"确认匹配后推进下一步",allowRedirect:!0,redirectPriority:"medium"}},outputGuards:B};function z(e){let t=e;for(;;){if(N(_(t,"package.json")))return t;const n=A(t);if(n===t)throw new Error(`Could not locate package root from ${e}`);t=n}}var J=_(z(import.meta.dirname),"data"),Q=_(J,"brand-config.json"),Z=_(J,"reply-policy.json"),X=3e5,ee=null,te=null;function ne(e){return Date.now()-e<X}function re(){if(ee&&ne(ee.loadedAt))return ee.data;const e=I(Q,"utf-8"),t=S.parse(JSON.parse(e));return ee={data:t,loadedAt:Date.now()},t}function ae(e){T(Q,JSON.stringify(e,null,2),"utf-8"),ee={data:e,loadedAt:Date.now()}}function oe(){if(te&&ne(te.loadedAt))return te.data;try{const e=I(Z,"utf-8"),t=V.parse(JSON.parse(e));return te={data:t,loadedAt:Date.now()},t}catch{return Y}}import{createAnthropic as ie}from"@ai-sdk/anthropic";import{createAlibaba as se}from"@ai-sdk/alibaba";import{createProviderRegistry as le}from"ai";import{createOpenAICompatible as ue}from"@ai-sdk/openai-compatible";import{createDeepSeek as ce}from"@ai-sdk/deepseek";import{createGoogleGenerativeAI as de}from"@ai-sdk/google";import{createOpenAI as me}from"@ai-sdk/openai";var pe=!1;function ge(e){pe=e}function fe(...e){pe||console.error(...e)}var ye=process.env.SMART_REPLY_PROXY_BASE_URL,be="https://apic1.ohmycdn.com/v1",he=ye||be,Se={anthropic:process.env.ANTHROPIC_BASE_URL||he,openai:process.env.OPENAI_BASE_URL||he,ohmygpt:process.env.OHMYGPT_BASE_URL||he,moonshotai:process.env.MOONSHOT_BASE_URL||"https://api.moonshot.cn/v1",deepseek:process.env.DEEPSEEK_BASE_URL||"https://api.deepseek.com",qwen:process.env.QWEN_BASE_URL||"https://dashscope.aliyuncs.com/compatible-mode/v1",google:process.env.GOOGLE_BASE_URL||"https://generativelanguage.googleapis.com/v1beta"},Ne={anthropic:{name:"Anthropic",baseURL:Se.anthropic,description:"Anthropic Claude"},openai:{name:"OpenAI",baseURL:Se.openai,description:"OpenAI GPT"},ohmygpt:{name:"OhMyGPT",baseURL:Se.ohmygpt,description:"OhMyGPT"},moonshotai:{name:"MoonshotAI",baseURL:Se.moonshotai,description:"MoonshotAI"},deepseek:{name:"DeepSeek",baseURL:Se.deepseek,description:"DeepSeek"},qwen:{name:"Qwen",baseURL:Se.qwen,description:"Qwen"},google:{name:"Google",baseURL:Se.google,description:"Google Gemini"}},Ie={chatModel:"anthropic/claude-haiku-4-5",classifyModel:process.env.SMART_REPLY_CLASSIFY_MODEL||"openai/gpt-5-mini",replyModel:process.env.SMART_REPLY_REPLY_MODEL||"openai/gpt-5.4"};function Te(){return process.env.ANTHROPIC_API_KEY||process.env.OPENAI_API_KEY||""}function Ae(e){const t=me({apiKey:e.apiKey||"",...void 0!==e.baseURL?{baseURL:e.baseURL}:{}});return new Proxy(t,{get(e,n){if("languageModel"===n)return e=>t.chat(e);if("chat"===n||"completion"===n)return t[n];if("embeddingModel"===n||"imageModel"===n){return t[n]||void 0}return t[n]}})}function _e(e){const t=Te();return le({anthropic:ie({apiKey:t,baseURL:e.anthropic?.baseURL||Se.anthropic}),openai:Ae({apiKey:t,baseURL:e.openai?.baseURL||Se.openai}),ohmygpt:ue({name:"ohmygpt",baseURL:e.ohmygpt?.baseURL||Se.ohmygpt,apiKey:t}),moonshotai:ue({name:"moonshotai",baseURL:e.moonshotai?.baseURL||Se.moonshotai,apiKey:process.env.MOONSHOT_API_KEY||""}),deepseek:ce({baseURL:e.deepseek?.baseURL||Se.deepseek,apiKey:process.env.DEEPSEEK_API_KEY||""}),google:de({apiKey:process.env.GEMINI_API_KEY||"",baseURL:e.google?.baseURL||Se.google}),qwen:se({apiKey:process.env.DASHSCOPE_API_KEY||process.env.ALIBABA_API_KEY||"",baseURL:e.qwen?.baseURL||Se.qwen})},{separator:"/"})}var Ee=null,Re=null;function Oe(e){const t=JSON.stringify(e);return Ee&&Re===t||(Ee=_e(e),Re=t,fe("[DYNAMIC REGISTRY] 创建新的动态registry,配置哈希:",t.substring(0,16)+"...")),Ee}function Le(e){return e.brands.flatMap(e=>e.stores)}function ve(e){return e.brands.map(e=>e.name)}function we(e,t){if(t)return e.brands.find(e=>e.name===t)}function ke(e){if(e.meta.defaultBrandId){const t=e.brands.find(t=>t.id===e.meta.defaultBrandId);if(t)return t}return e.brands[0]}function Me(e){return ke(e)?.name??""}function De(e,t){const n=t?we(e,t)?.stores??[]:Le(e);return n.find(e=>"string"==typeof e.city&&e.city.trim().length>0)?.city}import{z as xe}from"zod";import{setTimeout as Ce,clearTimeout as Ue}from"node:timers";import{performance as $e}from"node:perf_hooks";import{asSchema as je,generateText as We,jsonSchema as Fe,NoObjectGeneratedError as Pe,Output as Be}from"ai";import"zod";var Ge={CONFIG:"CONFIG",AUTH:"AUTH",NETWORK:"NETWORK",LLM:"LLM",VALIDATION:"VALIDATION",BUSINESS:"BUSINESS",SYSTEM:"SYSTEM"},qe={LLM_UNAUTHORIZED:"LLM_UNAUTHORIZED",LLM_MODEL_NOT_FOUND:"LLM_MODEL_NOT_FOUND",LLM_RATE_LIMITED:"LLM_RATE_LIMITED",LLM_TIMEOUT:"LLM_TIMEOUT",LLM_GENERATION_FAILED:"LLM_GENERATION_FAILED",LLM_RESPONSE_PARSE_ERROR:"LLM_RESPONSE_PARSE_ERROR",CONFIG_NOT_FOUND:"CONFIG_NOT_FOUND",CONFIG_INVALID:"CONFIG_INVALID",CONFIG_MISSING_FIELD:"CONFIG_MISSING_FIELD",CONFIG_LOAD_FAILED:"CONFIG_LOAD_FAILED",NETWORK_TIMEOUT:"NETWORK_TIMEOUT",NETWORK_CONNECTION_FAILED:"NETWORK_CONNECTION_FAILED",NETWORK_HTTP_ERROR:"NETWORK_HTTP_ERROR",NETWORK_DNS_FAILED:"NETWORK_DNS_FAILED",AUTH_UNAUTHORIZED:"AUTH_UNAUTHORIZED",AUTH_FORBIDDEN:"AUTH_FORBIDDEN",AUTH_TOKEN_EXPIRED:"AUTH_TOKEN_EXPIRED",AUTH_TOKEN_INVALID:"AUTH_TOKEN_INVALID",VALIDATION_INVALID_INPUT:"VALIDATION_INVALID_INPUT",VALIDATION_MISSING_REQUIRED:"VALIDATION_MISSING_REQUIRED",VALIDATION_FORMAT_ERROR:"VALIDATION_FORMAT_ERROR",VALIDATION_SCHEMA_ERROR:"VALIDATION_SCHEMA_ERROR",BUSINESS_RULE_VIOLATION:"BUSINESS_RULE_VIOLATION",BUSINESS_RESOURCE_NOT_FOUND:"BUSINESS_RESOURCE_NOT_FOUND",BUSINESS_RESOURCE_EXISTS:"BUSINESS_RESOURCE_EXISTS",BUSINESS_OPERATION_NOT_ALLOWED:"BUSINESS_OPERATION_NOT_ALLOWED",SYSTEM_INTERNAL:"SYSTEM_INTERNAL",SYSTEM_DEPENDENCY_FAILED:"SYSTEM_DEPENDENCY_FAILED",SYSTEM_RESOURCE_UNAVAILABLE:"SYSTEM_RESOURCE_UNAVAILABLE",SYSTEM_UNKNOWN:"SYSTEM_UNKNOWN"},He={[qe.LLM_UNAUTHORIZED]:Ge.LLM,[qe.LLM_MODEL_NOT_FOUND]:Ge.LLM,[qe.LLM_RATE_LIMITED]:Ge.LLM,[qe.LLM_TIMEOUT]:Ge.LLM,[qe.LLM_GENERATION_FAILED]:Ge.LLM,[qe.LLM_RESPONSE_PARSE_ERROR]:Ge.LLM,[qe.CONFIG_NOT_FOUND]:Ge.CONFIG,[qe.CONFIG_INVALID]:Ge.CONFIG,[qe.CONFIG_MISSING_FIELD]:Ge.CONFIG,[qe.CONFIG_LOAD_FAILED]:Ge.CONFIG,[qe.NETWORK_TIMEOUT]:Ge.NETWORK,[qe.NETWORK_CONNECTION_FAILED]:Ge.NETWORK,[qe.NETWORK_HTTP_ERROR]:Ge.NETWORK,[qe.NETWORK_DNS_FAILED]:Ge.NETWORK,[qe.AUTH_UNAUTHORIZED]:Ge.AUTH,[qe.AUTH_FORBIDDEN]:Ge.AUTH,[qe.AUTH_TOKEN_EXPIRED]:Ge.AUTH,[qe.AUTH_TOKEN_INVALID]:Ge.AUTH,[qe.VALIDATION_INVALID_INPUT]:Ge.VALIDATION,[qe.VALIDATION_MISSING_REQUIRED]:Ge.VALIDATION,[qe.VALIDATION_FORMAT_ERROR]:Ge.VALIDATION,[qe.VALIDATION_SCHEMA_ERROR]:Ge.VALIDATION,[qe.BUSINESS_RULE_VIOLATION]:Ge.BUSINESS,[qe.BUSINESS_RESOURCE_NOT_FOUND]:Ge.BUSINESS,[qe.BUSINESS_RESOURCE_EXISTS]:Ge.BUSINESS,[qe.BUSINESS_OPERATION_NOT_ALLOWED]:Ge.BUSINESS,[qe.SYSTEM_INTERNAL]:Ge.SYSTEM,[qe.SYSTEM_DEPENDENCY_FAILED]:Ge.SYSTEM,[qe.SYSTEM_RESOURCE_UNAVAILABLE]:Ge.SYSTEM,[qe.SYSTEM_UNKNOWN]:Ge.SYSTEM},Ke={[qe.LLM_UNAUTHORIZED]:"AI 服务认证失败,请检查配置",[qe.LLM_MODEL_NOT_FOUND]:"所选模型暂时不可用,请尝试其他模型",[qe.LLM_RATE_LIMITED]:"请求过于频繁,请稍后重试",[qe.LLM_TIMEOUT]:"AI 响应超时,请稍后重试",[qe.LLM_GENERATION_FAILED]:"内容生成失败,请稍后重试",[qe.LLM_RESPONSE_PARSE_ERROR]:"AI 响应格式异常,请重试",[qe.CONFIG_NOT_FOUND]:"配置数据未找到,请先进行初始化",[qe.CONFIG_INVALID]:"配置格式无效,请检查配置",[qe.CONFIG_MISSING_FIELD]:"配置缺少必需字段",[qe.CONFIG_LOAD_FAILED]:"配置加载失败,请重试",[qe.NETWORK_TIMEOUT]:"网络请求超时,请检查网络连接",[qe.NETWORK_CONNECTION_FAILED]:"网络连接失败,请检查网络",[qe.NETWORK_HTTP_ERROR]:"服务器返回错误,请稍后重试",[qe.NETWORK_DNS_FAILED]:"域名解析失败,请检查网络",[qe.AUTH_UNAUTHORIZED]:"请先登录",[qe.AUTH_FORBIDDEN]:"您没有权限执行此操作",[qe.AUTH_TOKEN_EXPIRED]:"登录已过期,请重新登录",[qe.AUTH_TOKEN_INVALID]:"认证信息无效,请重新登录",[qe.VALIDATION_INVALID_INPUT]:"输入参数无效",[qe.VALIDATION_MISSING_REQUIRED]:"缺少必需参数",[qe.VALIDATION_FORMAT_ERROR]:"数据格式错误",[qe.VALIDATION_SCHEMA_ERROR]:"数据验证失败",[qe.BUSINESS_RULE_VIOLATION]:"操作违反业务规则",[qe.BUSINESS_RESOURCE_NOT_FOUND]:"请求的资源不存在",[qe.BUSINESS_RESOURCE_EXISTS]:"资源已存在",[qe.BUSINESS_OPERATION_NOT_ALLOWED]:"当前操作不被允许",[qe.SYSTEM_INTERNAL]:"系统内部错误,请稍后重试",[qe.SYSTEM_DEPENDENCY_FAILED]:"依赖服务异常,请稍后重试",[qe.SYSTEM_RESOURCE_UNAVAILABLE]:"系统资源不可用,请稍后重试",[qe.SYSTEM_UNKNOWN]:"发生未知错误,请稍后重试"};function Ve(e){return He[e]}function Ye(e){return Ke[e]}var ze=class _AppError extends Error{code;category;userMessage;details;cause;timestamp;constructor(e){super(e.message),this.name="AppError",this.code=e.code,this.category=Ve(e.code),this.userMessage=e.userMessage||Ye(e.code),this.details=e.details,this.cause=e.cause,this.timestamp=(new Date).toISOString(),Error.captureStackTrace&&Error.captureStackTrace(this,_AppError)}toJSON(){const e={code:this.code,category:this.category,message:this.message,userMessage:this.userMessage,timestamp:this.timestamp};return void 0!==this.details&&(e.details=this.details),this.cause&&(this.cause instanceof _AppError?e.cause=this.cause.toJSON():e.cause={message:this.cause.message,stack:this.cause.stack}),e}getErrorChain(){const e=[this];let t=this.cause;for(;t;)e.push(t),t=t instanceof _AppError?t.cause:void 0;return e}getRootCause(){const e=this.getErrorChain();return e[e.length-1]}hasErrorCode(e){return this.getErrorChain().some(t=>t instanceof _AppError&&t.code===e)}hasErrorCategory(e){return this.getErrorChain().some(t=>t instanceof _AppError&&t.category===e)}toLogString(){const e=[`[${this.code}]`,this.message];return this.details&&e.push(`Details: ${JSON.stringify(this.details)}`),this.cause&&e.push(`Caused by: ${this.cause.message}`),e.join(" | ")}};function Je(e){return e instanceof ze}function Qe(e,t,n){const r=n?.model?` (model: ${n.model})`:"",a=n?.provider?` [${n.provider}]`:"",o={[qe.LLM_UNAUTHORIZED]:`LLM API authentication failed${a}${r}`,[qe.LLM_MODEL_NOT_FOUND]:`Model not found or unavailable${r}${a}`,[qe.LLM_RATE_LIMITED]:`LLM API rate limited${a}`,[qe.LLM_TIMEOUT]:`LLM API request timeout${a}${r}`,[qe.LLM_GENERATION_FAILED]:`LLM generation failed${a}${r}`,[qe.LLM_RESPONSE_PARSE_ERROR]:`Failed to parse LLM response${a}`};return new ze({code:e,message:o[e]||`LLM error: ${t.message}`,cause:t,details:n})}function Ze(e,t,n){const r=n?.url?` (${n.url})`:"",a=n?.statusCode?` [${n.statusCode}]`:"",o={[qe.NETWORK_TIMEOUT]:`Network request timeout${r}`,[qe.NETWORK_CONNECTION_FAILED]:`Failed to connect${r}`,[qe.NETWORK_HTTP_ERROR]:`HTTP error${a}${r}`,[qe.NETWORK_DNS_FAILED]:`DNS resolution failed${r}`};return new ze({code:e,message:o[e]||`Network error: ${t.message}`,cause:t,details:n})}function Xe(e,t,n){const r=n.isMarkdownFormat?" (detected markdown format)":"",a=n.schemaName?` for schema "${n.schemaName}"`:"";return new ze({code:e,message:`Failed to parse structured output${a}${r}`,cause:t,details:{rawText:n.rawText,isMarkdownFormat:n.isMarkdownFormat,parseErrorMessage:n.parseErrorMessage,model:n.model,provider:n.provider,schemaName:n.schemaName,usage:n.usage}})}import{NoObjectGeneratedError as et}from"ai";function tt(e){if(!e||"object"!=typeof e)return null;const t=e;if(!("AI_APICallError"===t.name||"APICallError"===t.name||"string"==typeof t.url&&"number"==typeof t.statusCode))return null;const n="number"==typeof t.statusCode?t.statusCode:void 0,r="string"==typeof t.responseBody?t.responseBody:void 0,a="string"==typeof t.url?t.url:void 0,o=t.message;let i,s;if(a&&(a.includes("openai.com")?i="openai":a.includes("anthropic.com")?i="anthropic":a.includes("dashscope.aliyuncs.com")?i="qwen":a.includes("openrouter.ai")?i="openrouter":a.includes("deepseek.com")?i="deepseek":a.includes("moonshot.cn")?i="moonshotai":a.includes("googleapis.com")&&(i="google")),r){const e=r.match(/model[`'":\s]+([^`'"}\s,]+)/i);e&&(s=e[1])}return{isAuthError:401===n||403===n,isModelNotFound:r?.includes("model")&&r?.includes("not exist")||r?.includes("not authorized to access this model")||!1,isRateLimited:429===n,isTimeout:408===n||504===n||o?.toLowerCase().includes("timeout")||!1,statusCode:n,provider:i,model:s,originalMessage:o,responseBody:r}}function nt(e){return[/^```/m,/^#{1,6}\s/m,/^\s*[-*+]\s/m,/^\s*\d+\.\s/m,/\[.+\]\(.+\)/,/^\s*>/m].some(t=>t.test(e))}function rt(e){try{if(void 0===et||"function"!=typeof et.isInstance)return null;if(!et.isInstance(e))return null}catch{return null}const t=e.text,n=!!t&&nt(t),r=e.response?{id:e.response.id,timestamp:e.response.timestamp,modelId:e.response.modelId}:void 0,a=e.usage??void 0,o={isNoObjectGeneratedError:!0,isMarkdownFormat:n};return void 0!==t&&(o.rawText=t),e.cause instanceof Error&&(o.cause=e.cause),void 0!==r&&(o.response=r),void 0!==a&&(o.usage=a),o}function at(e,t=qe.SYSTEM_UNKNOWN,n){if(Je(e))return n&&n!==e.userMessage?new ze({code:e.code,message:e.message,userMessage:n,cause:e.cause,details:e.details}):e;const r=ot(e),a=tt(e);if(a){const e={model:a.model,provider:a.provider,statusCode:a.statusCode,responseBody:a.responseBody};return a.isModelNotFound?Qe(qe.LLM_MODEL_NOT_FOUND,r,e):a.isAuthError?Qe(qe.LLM_UNAUTHORIZED,r,e):a.isRateLimited?Qe(qe.LLM_RATE_LIMITED,r,e):a.isTimeout?Qe(qe.LLM_TIMEOUT,r,e):Qe(qe.LLM_GENERATION_FAILED,r,e)}const o=rt(e);if(o)return Xe(qe.LLM_RESPONSE_PARSE_ERROR,r,{rawText:o.rawText,isMarkdownFormat:o.isMarkdownFormat,parseErrorMessage:o.cause?.message,usage:o.usage});const i=r.message.toLowerCase();return i.includes("timeout")||i.includes("econnrefused")||i.includes("network")||i.includes("fetch failed")?i.includes("timeout")?Ze(qe.NETWORK_TIMEOUT,r):Ze(qe.NETWORK_CONNECTION_FAILED,r):new ze({code:t,message:r.message,cause:r})}function ot(e){if(e instanceof Error)return e;if("string"==typeof e)return new Error(e);if("object"==typeof e&&null!==e){const t=e.message||e.error||JSON.stringify(e);return new Error(String(t))}return new Error(String(e))}function it(e,t){console.error(`[${t.code}] ${e}:`,t.toLogString()),t.cause&&console.error("Original error:",t.cause)}function st(e){return"object"==typeof e&&null!==e}function lt(e,t){t&&st(e.details)&&(e.details.schemaName=t)}function ut(e){const t=e.type;return"string"==typeof t?[t]:Array.isArray(t)?t.filter(e=>"string"==typeof e):[]}function ct(e,t){let n=null;for(const r of e){const e=t.get(r);if(void 0!==e&&e.size>0){n??=new Set;for(const t of e)n.add(t)}}return n}function dt(e,t){if(Array.isArray(e))return e.map(e=>dt(e,t));if(null===e||"object"!=typeof e)return e;const n=e,r=ct(ut(n),t),a={};for(const[e,o]of Object.entries(n))null!==r&&r.has(e)||(a[e]=dt(o,t));return a}function mt(e){const t=e.unsupportedKeywordsByType;if(void 0===t)return new Map;const n=new Map;for(const[e,r]of Object.entries(t)){if(0===r.length)continue;const t=n.get(e);if(void 0!==t)for(const e of r)t.add(e);else n.set(e,new Set(r))}const r=n.get("number");if(void 0!==r&&r.size>0){const e=n.get("integer");if(void 0!==e)for(const t of r)e.add(t);else n.set("integer",new Set(r))}return n}function pt(e,t={}){const n=mt(t);if(0===n.size)return e;const r=je(e);return Fe(async()=>dt(await r.jsonSchema,n),{validate:e=>({success:!0,value:e})})}async function gt(e){const{model:t,schema:n,outputSchema:r,schemaName:a,system:o,prompt:i,transformOutput:s,onError:l}=e;try{const e=await We({model:t,...void 0!==o?{system:o}:{},prompt:i,output:Be.object({schema:r??n,...void 0!==a?{name:a}:{}})});if(void 0===r&&void 0===s)return{success:!0,data:e.output,usage:e.usage};const u=void 0!==s?await s(e.output):e.output,c=await n.safeParseAsync(u);if(!c.success){const t=at(c.error,qe.LLM_RESPONSE_PARSE_ERROR);return lt(t,a),it(`Structured output validation (${a||"unknown"})`,t),l&&l(t,e.text),{success:!1,error:t,rawText:e.text}}return{success:!0,data:c.data,usage:e.usage}}catch(e){const t=at(e,qe.LLM_RESPONSE_PARSE_ERROR);let n;return Pe.isInstance(e)&&(n=e.text),lt(t,a),it(`Structured output generation (${a||"unknown"})`,t),l&&l(t,n),{success:!1,error:t,rawText:n}}}var ft=3e4,yt=2e3;async function bt(e){const{model:t,system:n,prompt:r,timeoutMs:a=ft,maxOutputTokens:o=yt,context:i="generateText",onError:s}=e,l=$e.now();try{const e=new AbortController,s=Ce(()=>e.abort(),a),u=await We({model:t,...void 0!==n?{system:n}:{},prompt:r,maxOutputTokens:o,abortSignal:e.signal});Ue(s);const c=Math.round($e.now()-l),d=u.usage,m=void 0!==d?.inputTokens&&void 0!==d?.outputTokens?d.inputTokens+d.outputTokens:void 0,p={inputTokens:d?.inputTokens,outputTokens:d?.outputTokens,totalTokens:m};return fe(`[${i}] 生成成功 | 耗时: ${c}ms | Tokens: ${m??"N/A"} (input: ${p.inputTokens??"?"}, output: ${p.outputTokens??"?"})`),{success:!0,text:u.text,usage:p,latencyMs:c}}catch(e){const t=Math.round($e.now()-l),n=e instanceof Error&&("AbortError"===e.name||e.message.includes("aborted")),r=at(e,n?qe.LLM_TIMEOUT:qe.LLM_GENERATION_FAILED);return st(r.details)&&(r.details.context=i,r.details.latencyMs=t),it(`${i} (${t}ms)`,r),s&&s(r),{success:!1,error:r}}}import{z as ht}from"zod";var St=ht.object({name:ht.string(),baseURL:ht.string(),description:ht.string()}),Nt=ht.record(ht.string(),St),It=ht.object({chatModel:ht.string().optional(),classifyModel:ht.string().optional(),replyModel:ht.string().optional(),providerConfigs:Nt.optional()}),Tt=ht.object({city:ht.string().optional(),defaultBrand:ht.string(),availableBrands:ht.array(ht.string()),storeCount:ht.number()}),At=ht.object({modelConfig:It,candidateMessage:ht.string(),conversationHistory:ht.array(ht.string()).default([]),brandData:Tt.optional(),channelType:O.optional()});function _t(e){const t=O.safeParse(e);return t.success?t.data:"public"}function Et(e="public"){const t=_t(e),n=R.options.filter(e=>w[e].applicableChannels.includes(t));return n.length>0?n:[...R.options]}function Rt(e){return xe.object({stage:xe.enum(e),subGoals:C.shape.subGoals,needs:C.shape.needs,primaryNeed:C.shape.primaryNeed,riskFlags:C.shape.riskFlags,confidence:C.shape.confidence,extractedInfo:C.shape.extractedInfo,reasoningText:C.shape.reasoningText})}var Ot={subGoals:2,needs:8,riskFlags:6,mentionedDistricts:10};function Lt(e){return e.startsWith("anthropic/")}function vt(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function wt(e){if(!vt(e))return e;const t={...e};if(Array.isArray(t.subGoals)&&(t.subGoals=t.subGoals.slice(0,Ot.subGoals)),Array.isArray(t.needs)&&(t.needs=t.needs.slice(0,Ot.needs)),Array.isArray(t.riskFlags)&&(t.riskFlags=t.riskFlags.slice(0,Ot.riskFlags)),vt(t.extractedInfo)){const e={...t.extractedInfo};Array.isArray(e.mentionedDistricts)&&(e.mentionedDistricts=e.mentionedDistricts.slice(0,Ot.mentionedDistricts)),t.extractedInfo=e}return t}var kt=[{need:"salary",patterns:[/薪资|工资|时薪|底薪|提成|奖金|补贴|多少钱|收入/i]},{need:"schedule",patterns:[/排班|班次|几点|上班|下班|工时|周末|节假日|做几天/i]},{need:"policy",patterns:[/五险一金|社保|保险|合同|考勤|迟到|补班|试用期/i]},{need:"availability",patterns:[/还有名额|空位|可用时段|什么时候能上|明天能面/i]},{need:"location",patterns:[/在哪|位置|地址|附近|地铁|门店|哪个区|多远/i]},{need:"stores",patterns:[/门店|哪家店|哪些店|有店吗/i]},{need:"requirements",patterns:[/要求|条件|年龄|经验|学历|健康证|身高|体重/i]},{need:"interview",patterns:[/面试|到店|约时间|约面/i]},{need:"wechat",patterns:[/微信|vx|私聊|联系方式|加你/i]}],Mt=["salary","schedule","location","stores","policy","requirements","availability","interview","wechat","none"];function Dt(e){const t=new Set;for(const n of kt)n.patterns.some(t=>t.test(e))&&t.add(n.need);return 0===t.size?t.add("none"):t.delete("none"),t}function xt(e,t){return Dt(`${t.slice(-4).join(" ")} ${e}`)}function Ct(e){return Dt(e)}function Ut(e,t,n,r=1){const a=new Set(t);a.size>1&&a.has("none")&&a.delete("none");const o=Ct(n);o.delete("none");const i=[];"none"!==e&&a.has(e)&&i.push(e);for(const t of Mt){if(i.length>=r)break;"none"!==t&&t!==e&&(o.has(t)&&a.has(t)&&i.push(t))}return i.length>0?i:"none"===e?["none"]:a.has(e)?[e]:["none"]}function $t(e,t,n){const r=new Set(t);if(r.size>1&&r.has("none")&&r.delete("none"),e&&r.has(e))return e;const a=Ct(n);a.delete("none");for(const e of Mt)if(a.has(e)&&r.has(e))return e;for(const e of Mt)if(r.has(e))return e;return"none"}function jt(e,t,n){const r=new Set([...e.needs,...Array.from(t)]);return r.size>1&&r.has("none")&&r.delete("none"),{...e,subGoals:e.subGoals.slice(0,2),needs:Array.from(r),primaryNeed:$t(e.primaryNeed,r,n),confidence:Number.isFinite(e.confidence)?Math.max(0,Math.min(1,e.confidence)):.5}}function Wt(e,t,n,r="public",a,o){const i=["你是招聘对话回合规划器,不直接回复候选人。","你只输出结构化规划结果,用于后续回复生成。","规划目标:确定阶段目标(stage)、子目标(subGoals)、事实需求(needs)、主回答轴(primaryNeed)、风险标记(riskFlags)。"].join("\n"),s=_t(r);return{system:i,prompt:["[阶段枚举与定义]",...Et(s).map(e=>{const t=w[e];return`- ${e}: ${a?.stageGoals[e]?.description||t.description} (转入条件: ${t.transitionSignal})`}),"","[needs枚举]","private"===s?"- stores, location, salary, schedule, policy, availability, requirements, interview, none":"- stores, location, salary, schedule, policy, availability, requirements, interview, wechat, none","","[riskFlags枚举]","- insurance_promise_risk, age_sensitive, confrontation_emotion, urgency_high, qualification_mismatch","","[规则]","- 优先判断本轮主阶段(stage);subGoals 最多 2 项,只保留最关键的。","- 候选人追问事实时,必须打开对应 needs。","- primaryNeed 必须从 needs 中选择一个最主的 need;如果没有明确事实轴则填 none。","- 不确定时 confidence 降低,不要臆断。","- 根据转入条件判断阶段转化,不要停留在不匹配的阶段。",...o&&o.length>0?[`- 候选人资料中已有:${o.join("、")}。不要生成追问这些字段的 subGoal。`]:[],"","[品牌数据]",JSON.stringify(n||{}),"","[历史对话]",t.slice(-8).join("\n")||"无","","[候选人消息]",e].join("\n")}}async function Ft(e,t){const{providerConfigs:n=Ne,modelConfig:r,conversationHistory:a=[],brandData:o,channelType:i,replyPolicy:s,knownCandidateFields:l}=t,u=Oe(n),c=r?.classifyModel||Ie.classifyModel,d=_t(i),m=Rt(Et(d)),p=Lt(c),g=Wt(e,a,o,d,s,l),f=await gt({model:u.languageModel(c),schema:m,...p?{outputSchema:pt(m,{unsupportedKeywordsByType:{array:["maxItems","minItems"],number:["maximum","minimum","exclusiveMaximum","exclusiveMinimum"]}}),transformOutput:wt}:{},schemaName:"TurnPlanningOutput",system:g.system,prompt:g.prompt}),y=xt(e,a),b=$t(void 0,y,e);return f.success?jt(f.data,y,e):{stage:"trust_building",subGoals:["保持对话并澄清需求"],needs:Array.from(y),primaryNeed:b,riskFlags:[],confidence:.35,extractedInfo:{mentionedBrand:null,city:o?.city||null,mentionedLocations:null,mentionedDistricts:null,specificAge:null,hasUrgency:null,preferredSchedule:null},reasoningText:"规划模型失败,使用规则降级策略"}}import{z as Pt}from"zod";var Bt=Pt.object({id:Pt.number(),name:Pt.string(),aliases:Pt.array(Pt.string()),projectIdList:Pt.array(Pt.number())}),Gt=Pt.object({code:Pt.number(),message:Pt.string().optional(),data:Pt.object({result:Pt.array(Bt),total:Pt.number()})}),qt=3e5,Ht=null;function Kt(){return null!==Ht&&Date.now()-Ht.timestamp<qt}var Vt=3e4;function Yt(){const e=process.env.DULIDAY_BRAND_LIST_URL;return"string"==typeof e&&e.trim().length>0?e:void 0}async function zt(e){const t=e||process.env.DULIDAY_TOKEN,n=Yt();if(!t)throw new ze({code:qe.CONFIG_MISSING_FIELD,message:"DULIDAY_TOKEN 未配置,无法获取品牌别名数据",userMessage:"品牌别名数据加载失败:缺少 Duliday Token 配置"});if(!n)throw new ze({code:qe.CONFIG_MISSING_FIELD,message:"DULIDAY_BRAND_LIST_URL 未配置,无法获取品牌别名数据",userMessage:"品牌别名数据加载失败:缺少 Duliday 品牌接口配置"});const r=new AbortController,a=setTimeout(()=>r.abort(),Vt);try{const e=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json","Duliday-Token":t},body:JSON.stringify({pageNum:1,pageSize:1e3}),signal:r.signal});if(!e.ok)throw new ze({code:qe.NETWORK_HTTP_ERROR,message:`Duliday 品牌列表 API 返回 HTTP ${e.status}: ${e.statusText}`,userMessage:`品牌别名数据加载失败:服务端返回 ${e.status}`});const a=await e.json(),o=Gt.safeParse(a);if(!o.success)throw new ze({code:qe.VALIDATION_SCHEMA_ERROR,message:`Duliday 品牌列表响应格式校验失败: ${o.error.message}`,userMessage:"品牌别名数据加载失败:响应格式异常"});return o.data.data.result}catch(e){if(e instanceof ze)throw e;if(e instanceof Error&&"AbortError"===e.name)throw new ze({code:qe.NETWORK_TIMEOUT,message:`Duliday 品牌列表 API 请求超时 (${Vt}ms)`,userMessage:"品牌别名数据加载超时,请稍后重试",cause:e});throw new ze({code:qe.SYSTEM_DEPENDENCY_FAILED,message:`获取品牌别名数据失败: ${e instanceof Error?e.message:String(e)}`,userMessage:"品牌别名数据加载失败,请检查网络连接",...e instanceof Error?{cause:e}:{}})}finally{clearTimeout(a)}}function Jt(e,t,n){const r={},a=new Map,o=e=>e.trim(),i=(e,t)=>{const n=o(e).toLowerCase().replace(/[\s._-]+/g,"");if(!n)return;const r=a.get(n);(!r||t.length>r.length)&&a.set(n,t)},s=[...e].sort((e,t)=>t.name.length-e.name.length);for(const e of s){const t=o(e.name);if(!t)continue;const a=Array.from(new Set([t,...e.aliases.map(o).filter(Boolean)].filter(e=>e!==t)));a.unshift(t),r[t]=a;for(const e of a)i(e,t);if(n&&e.projectIdList.length>0)for(const o of e.projectIdList){const e=n[String(o)];if(!e||e===t)continue;if(!e.includes(t))continue;const s=e.replace(t,"");if(!s)continue;const l=[e];for(const e of a)e!==t&&l.push(`${s}${e}`);if(r[e]){const t=new Set(r[e]);for(const n of l)t.has(n)||r[e].push(n)}else r[e]=l;for(const t of l)i(t,e)}}for(const e of t)r[e]||(r[e]=[e],i(e,e));return{dictionary:r,aliasMap:a}}async function Qt(e){if(Kt())return;const t=await zt(e),n=new Set,{dictionary:r,aliasMap:a}=Jt(t,n);Ht={aliasMap:a,dictionary:r,timestamp:Date.now()}}async function Zt(e){return await Qt(e),Ht.aliasMap}function Xt(e){const{base:t,range:n,memo:r}=e;let a="";return t<10&&r?a=`${t}元(${r.replace(/\n/g," ").trim()})`:(a=`${t}元/时`,n&&n!==`${t}-${t}`&&(a+=`,范围${n}元`),r&&r.length<50&&(a+=`(${r.replace(/\n/g," ").trim()})`)),e.scenarioSummary&&(a+=`(${e.scenarioSummary})`),a}function en(e,t,n){if(!e)return null;const r=e=>e.toLowerCase().replace(/[\s._-]+/g,"");if(n){const a=n.get(r(e))||n.get(e.toLowerCase());if(a&&t.includes(a))return a}const a=e.toLowerCase(),o=r(e),i=t.find(e=>e.toLowerCase()===a);if(i)return i;const s=t.find(e=>r(e)===o);if(s)return s;const l=t.filter(e=>{const t=e.toLowerCase();if(t.includes(a)||a.includes(t))return!0;const n=r(e);return n.includes(o)||o.includes(n)});if(l.length>0)return l.sort((e,t)=>t.length-e.length)[0]??null;if(a.includes("山姆")||a.includes("sam")){const e=t.find(e=>{const t=e.toLowerCase();return t.includes("山姆")||t.includes("sam")});if(e)return e}return null}function tn(e){const{uiSelectedBrand:t,configDefaultBrand:n,conversationBrand:r,availableBrands:a,strategy:o="smart",aliasMap:i}=e,s=(e,t)=>{if(e)return en(e,a,i)??void 0};switch(o){case"user-selected":{const e=s(t);if(e)return{resolvedBrand:e,matchType:e===t?"exact":"fuzzy",source:"ui",reason:"用户选择策略",originalInput:t};const r=s(n);return r?{resolvedBrand:r,matchType:r===n?"exact":"fuzzy",source:"config",reason:"配置默认",originalInput:n}:{resolvedBrand:a[0]??"",matchType:"fallback",source:"default",reason:"系统默认"}}case"conversation-extracted":{const e=s(r);if(e)return{resolvedBrand:e,matchType:e===r?"exact":"fuzzy",source:"conversation",reason:"对话提取",originalInput:r};const o=s(t);if(o)return{resolvedBrand:o,matchType:o===t?"exact":"fuzzy",source:"ui",reason:"UI选择",originalInput:t};const i=s(n);return i?{resolvedBrand:i,matchType:i===n?"exact":"fuzzy",source:"config",reason:"配置默认",originalInput:n}:{resolvedBrand:a[0]??"",matchType:"fallback",source:"default",reason:"系统默认"}}default:{const e=s(r),o=s(t);if(e)return{resolvedBrand:e,matchType:e===r?"exact":"fuzzy",source:"conversation",reason:"智能策略: 对话提取",originalInput:r};if(o)return{resolvedBrand:o,matchType:o===t?"exact":"fuzzy",source:"ui",reason:"智能策略: UI选择",originalInput:t};const i=s(n);return i?{resolvedBrand:i,matchType:i===n?"exact":"fuzzy",source:"config",reason:"智能策略: 配置默认",originalInput:n}:{resolvedBrand:a[0]??"",matchType:"fallback",source:"default",reason:"智能策略: 系统默认"}}}}function nn(e,t){const{mentionedLocations:n,mentionedDistricts:r}=t;return e.map(e=>{let t=0,a=0,o=0,i=0;if(n&&n.length>0){const r=n.find(t=>e.name.includes(t.location)||e.location.includes(t.location)||e.subarea.includes(t.location));r&&(t=40*r.confidence)}if(r&&r.length>0){const t=r.find(t=>e.district.includes(t.district)||e.subarea.includes(t.district));t&&(a=30*t.confidence)}const s=new Set(e.positions.map(e=>e.name));o=Math.min(5*s.size,20);const l=e.positions.filter(e=>e.availableSlots?.some(e=>e.isAvailable));return i=Math.min(2*l.length,10),{store:e,score:t+a+o+i,breakdown:{locationMatch:t,districtMatch:a,positionDiversity:o,availability:i}}}).sort((e,t)=>t.score-e.score).map(e=>({store:e.store,distance:void 0}))}function rn(e){if(!e)return"灵活排班";return{fixed:"固定排班",flexible:"灵活排班",rotating:"轮班制",on_call:"随叫随到"}[e]||"灵活排班"}function an(e){return D[e].length>0}function on(e,t){return e.has(t)}function sn(e,t,n){return"minimal"===t||(1===e||"trust_building"===n||"private_channel"===n)}async function ln(e,t,n,r,a,o,i,s,l=1,u="minimal",c=[t.primaryNeed]){const d=t.extractedInfo,m=t.primaryNeed,p=c.length>0?Array.from(new Set(c.filter(e=>"none"!==e))):"none"===m?[]:[m],g=new Set(p.flatMap(e=>D[e])),f=sn(l,u,t.stage),y=!f&&an(m);let b,h;try{b=await Zt()}catch(e){const t="object"==typeof e&&null!==e&&"userMessage"in e&&"string"==typeof e.userMessage?e.userMessage:e instanceof Error?e.message:String(e);h=t,fe(`[buildContextInfoByNeeds] 品牌别名服务不可用,回退 fuzzy 解析: ${t}`)}const S=tn({uiSelectedBrand:n,configDefaultBrand:Me(e),conversationBrand:r||void 0,availableBrands:ve(e),strategy:a||"smart",aliasMap:b}),N=S.resolvedBrand;fe(`[品牌解析] 工具传参: ${r??"(未指定)"} → 结果: ${N} (${S.matchType}, ${S.source})`);const I=we(e,N),T=I?.stores??[];let A=T;if(A.length>0){const e=d.mentionedLocations||[];if(e.length>0){const t=e[0]?.location?.trim();if(t){const e=A.filter(e=>e.name.includes(t)||e.location.includes(t)||e.district.includes(t)||e.subarea.includes(t));e.length>0&&(A=e)}}const t=d.mentionedDistricts||[];if(t.length>0){const e=A.filter(e=>t.some(t=>e.district.includes(t.district)||e.subarea.includes(t.district)));e.length>0&&(A=e)}if(A.length===T.length&&o?.jobAddress&&on(g,"location")){const e=A.filter(e=>e.name.includes(o.jobAddress||"")||e.location.includes(o.jobAddress||"")||e.district.includes(o.jobAddress||"")||e.subarea.includes(o.jobAddress||""));e.length>0&&(A=e)}}let _=[];A.length>0&&(_=nn(A,d));const E=y?Math.min(1,_.length):0,R=y?"focused":"minimal";let O=`阶段目标:${t.stage}\n默认推荐品牌:${N}\n`;if(h&&(O+=`系统状态:品牌别名服务暂不可用,已回退为规则匹配(${h})。\n`),i){const e=i.stageGoals[t.stage],n=s||i.defaultIndustryVoiceId,r=i.industryVoices[n];O+=`策略目标:${e.primaryGoal}\n`,O+=`推进方式:${e.ctaStrategy}\n`,O+=`主回答轴:${m}\n`,r&&(O+=`行业指纹:${r.name} | 风格:${r.styleKeywords.join("、")}\n`),O+=`红线:${i.hardConstraints.rules.map(e=>e.rule).join(";")}\n`}return y?0===E?O+="暂无可用的门店事实信息,请使用泛化回答,避免任何具体承诺。\n":(O+="匹配到的门店信息:\n",_.slice(0,E).forEach(({store:e})=>{const t=on(g,"location"),n=Array.from(g).some(e=>"location"!==e);O+=t?`• ${e.name}(${e.district}${e.subarea}):${e.location}\n`:`• ${e.name}\n`,n&&e.positions.slice(0,3).forEach(e=>{if(O+=` 职位:${e.name}\n`,on(g,"salary")&&(O+=` 薪资:${Xt(e.salary)}\n`),on(g,"schedule")&&(O+=` 排班:${rn(e.scheduleType)}\n`,O+=` 时间:${e.timeSlots.slice(0,3).join("、")}\n`,(e.minHoursPerWeek||e.maxHoursPerWeek)&&(O+=` 每周工时:${e.minHoursPerWeek||0}-${e.maxHoursPerWeek||"不限"}小时\n`)),on(g,"policy")&&(O+=` 考勤:最多迟到${e.attendancePolicy.lateToleranceMinutes}分钟\n`,e.attendanceRequirement?.description&&(O+=` 出勤要求:${e.attendanceRequirement.description}\n`)),on(g,"availability")){const t=e.availableSlots?.filter(e=>e.isAvailable).slice(0,3)||[];t.length>0&&(O+=` 可用时段:${t.map(e=>e.slot).join("、")}\n`)}if(on(g,"requirements"))if(e.hiringRequirements){const t=e.hiringRequirements,n=[];null==t.minAge&&null==t.maxAge||n.push(`年龄${t.minAge??"不限"}-${t.maxAge??"不限"}岁`),t.genderRequirement&&"0"!==t.genderRequirement&&n.push(`性别:${t.genderRequirement}`),t.education&&"1"!==t.education&&n.push(`学历:${t.education}`),n.length>0&&(O+=` 要求:${n.join("、")}\n`)}else e.requirements?.length&&(O+=` 要求:${e.requirements.filter(e=>"无"!==e).join("、")}\n`)})})):O+=f?"当前处于首轮或浅层沟通,优先泛化回答,不主动展开具体门店、数字或筛选条件。\n":"本轮以推进沟通为主,无需展开岗位细节,请保持回答聚焦且克制。\n",{contextInfo:O,resolvedBrand:N,debugInfo:{relevantStores:_.length>0?_:A.map(e=>({store:e,distance:void 0})),storeCount:E,detailLevel:R,primaryNeed:m,turnPlan:t,aliasLookupError:h}}}var un=["too_many_questions","audit_tone","premature_numeric_disclosure","off_axis_fact_disclosure","reply_overpacked"],cn=/[^。!?!?]*[??]/g,dn={salary:{mention:[/\d+(?:\.\d+)?\s*元(?:\/时|\/小时)?/i,/时薪|薪资|工资|底薪|收入/i],concrete:[/\d+(?:\.\d+)?\s*元(?:\/时|\/小时)?/i]},schedule:{mention:[/\d{1,2}:\d{2}\s*[~-]\s*\d{1,2}:\d{2}/,/班次|轮班|白班|晚班|工时|排班/i],concrete:[/\d{1,2}:\d{2}\s*[~-]\s*\d{1,2}:\d{2}/,/轮班|白班|晚班|早班|中班|夜班/i]},location:{mention:[/地址|地铁|附近|位于|门店|在.+(?:路|街|广场|商场|大厦)/i],concrete:[/地址|位于|地铁\S*站|在.+(?:路|街|广场|商场|大厦)/i]},policy:{mention:[/考勤|试用期|社保|五险一金|迟到|补班/i],concrete:[/考勤|试用期|社保|五险一金|迟到|补班/i]},requirements:{mention:[/年龄|学历|经验|健康证|要求/i],concrete:[/年龄|学历|经验|健康证/i]},availability:{mention:[/名额|空位|可用时段|可安排/i],concrete:[/名额|空位|可用时段/i]}};function mn(e){return e?.outputGuards??B}function pn(e){const t=e.match(cn)??[],n=new Set(t.map(e=>e.replace(/[??]/g,"").trim()).filter(Boolean)),r=e.split(/[。!?!?]/).map(e=>e.trim()).filter(Boolean).filter(e=>/[吗呢么]$/.test(e)&&!n.has(e)).length;return t.length+r}function gn(e){return e.split(/[。!?!?]/).map(e=>e.trim()).filter(Boolean).length}function fn(e){return/(?:^|\s)(?:\d+\.\s|- |•)/m.test(e)}function yn(e,t="mention"){return Object.entries(dn).filter(([,n])=>n[t].some(t=>t.test(e))).map(([e])=>e)}function bn(e,t){return t.some(t=>t&&e.includes(t))}function hn(e){return/\d+(?:\.\d+)?\s*元(?:\/时|\/小时)?/i.test(e)||/\d{1,2}:\d{2}\s*[~-]\s*\d{1,2}:\d{2}/.test(e)||/年龄\s*\d{1,2}\s*[-~到]\s*\d{1,2}\s*岁/i.test(e)||/\d{1,2}\s*[-~到]\s*\d{1,2}\s*岁/i.test(e)||/地址在|门店在|位于|在.+(?:路|街|广场|商场|大厦|地铁)/i.test(e)}function Sn(e,t,n){let r=0;return gn(e)>=4&&(r+=1),fn(e)&&(r+=1),t>=3&&(r+=1),n.length>=2&&(r+=1),r>=2}function Nn(e){return yn(e,"concrete")}function In(e){const t=[];return/薪资:/.test(e)&&t.push("salary"),/排班:|时间:|每周工时:/.test(e)&&t.push("schedule"),/匹配到的门店信息:[\s\S]*• .*:/.test(e)&&t.push("location"),/考勤:|出勤要求:/.test(e)&&t.push("policy"),/要求:/.test(e)&&t.push("requirements"),/可用时段:/.test(e)&&t.push("availability"),t}function Tn(e,t){const n=new Set(e.flatMap(e=>D[e]));return 0===n.size?t.length>0:t.some(e=>!n.has(e))}function An(e){const{text:t,turnIndex:n,mode:r,policy:a}=e,o=mn(a),i=pn(t),s=o.maxQuestionsByMode[r],l=Nn(t),u=e.allowedNeeds?.length?e.allowedNeeds:[e.primaryNeed],c=[];return i>s&&c.push("too_many_questions"),bn(t,o.blockedAuditPhrases)&&c.push("audit_tone"),o.blockFirstTurnSpecificFacts&&1===n&&hn(t)&&c.push("premature_numeric_disclosure"),Tn(u,l)&&c.push("off_axis_fact_disclosure"),Sn(t,i,l)&&c.push("reply_overpacked"),{violations:c,questionCount:i,factFamilies:l}}import _n from"ora";function En(){let e=null;return{update(t){e?e.text=t:e=_n({text:t,stream:process.stderr}).start()},succeed(t){e?(e.succeed(t),e=null):console.error(`✓ ${t}`)},fail(t){e?(e.fail(t),e=null):console.error(`✗ ${t}`)}}}import{z as Rn}from"zod";var On=6e4,Ln=200,vn=2e4,wn=null,kn=null;function Mn(){const e=process.env.DULIDAY_JOB_LIST_URL;return"string"==typeof e&&e.trim().length>0?e:void 0}function Dn(){const e=process.env.DULIDAY_TOKEN;return"string"==typeof e&&e.trim().length>0?e:void 0}function xn(e){return(e??"").trim()}function Cn(e){const t=xn(e);if(!t)return[];const n=new Set([t]);return t.endsWith("市")?n.add(t.slice(0,-1)):n.add(`${t}市`),Array.from(n).filter(Boolean)}function Un(e,t){const n=xn(e);if(!n)return[];const r=new Set([n]),a=Cn(t);for(const e of a)if(n.startsWith(e)){const t=n.slice(e.length).trim();t&&r.add(t)}return Array.from(r).filter(Boolean)}var $n=Rn.object({data:Rn.object({result:Rn.array(Rn.unknown()).optional(),list:Rn.array(Rn.unknown()).optional(),total:Rn.number().optional()}).nullable().optional(),result:Rn.array(Rn.unknown()).optional()});function jn(e){const t=$n.safeParse(e);if(!t.success)return{items:[],total:0};const n=t.data,r=n.data?.result??n.data?.list??(Array.isArray(n.result)?n.result:[]),a=n.data?.total??(Array.isArray(r)?r.length:0);return{items:Array.isArray(r)?r:[],total:"number"==typeof a?a:0}}var Wn={includeBasicInfo:!0,includeJobSalary:!0,includeWelfare:!0,includeHiringRequirement:!0,includeWorkTime:!0},Fn={includeBasicInfo:!0,includeHiringRequirement:!0};async function Pn(e,t,n,r,a){const o="test"!==process.env.NODE_ENV,i=Un(a?.brandAlias,a?.cityName),s=Cn(a?.cityName),l=a?.include??Fn,u=JSON.stringify({token:e,brandCandidates:i,cityCandidates:s,pageNum:n,includeOpts:l}),c=Date.now();if(o&&wn&&wn.cacheKey===u&&c-wn.fetchedAt<On)return wn.payload;if(o&&kn?.cacheKey===u)return kn.promise;const d=(async()=>{const a=new AbortController,o=setTimeout(()=>a.abort(),vn),c={};i.length>0&&(c.brandAliasList=i),s.length>0&&(c.cityNameList=s);const d={pageNum:n,pageSize:r,queryParam:c,options:l};try{const n=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json","Duliday-Token":e},body:JSON.stringify(d),signal:a.signal});if(!n.ok)throw new Error(`Duliday job list fetch failed: ${n.status}`);const r=await n.json();return wn={cacheKey:u,payload:r,fetchedAt:Date.now()},r}finally{clearTimeout(o),kn=null}})();return o&&(kn={cacheKey:u,promise:d}),d}async function Bn(e,t,n){const r=[];let a=1,o=0;for(;;){const i=jn(await Pn(e,t,a,Ln,n));if(1===a&&(o=i.total),r.push(...i.items),i.items.length<Ln||r.length>=o)break;a+=1}return{items:r,total:o}}var Gn=["pass","fail","unknown"],qn={enabled:!1,revealRange:!1,failStrategy:"礼貌说明不匹配,避免承诺",unknownStrategy:"先核实年龄或资格条件",passStrategy:"确认匹配后推进下一步",allowRedirect:!1,redirectPriority:"low"},Hn=200;function Kn(e){return(e??"").trim().toLowerCase()}function Vn(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)}function Yn(e){if("string"==typeof e)return e;if(Array.isArray(e)){const t=e.find(e=>"string"==typeof e);return"string"==typeof t?t:""}return""}function zn(e,t){for(const n of t)if(n in e){const t=Yn(e[n]);if(t)return t}return""}function Jn(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"==typeof e&&""!==e.trim()){const t=Number(e);return Number.isFinite(t)?t:null}return null}function Qn(e,t){const n=t??qn,r="pass"===e?n.passStrategy:"fail"===e?n.failStrategy:n.unknownStrategy;return{...n,status:e,strategy:r}}async function Zn({age:e,brandAlias:t,cityName:n,regionName:r,strategy:a}){const o=Dn(),i=Mn(),s={minAgeObserved:null,maxAgeObserved:null,matchedCount:0,total:0};if(!o)return{status:"unknown",summary:s,appliedStrategy:Qn("unknown",a)};if(!i)return{status:"unknown",summary:s,appliedStrategy:Qn("unknown",a)};try{const l=await Pn(o,i,1,Hn,{brandAlias:t??null,cityName:n??null}),{items:u,total:c}=jn(l);s.total=c;const d=c>u.length&&u.length>=Hn,m=Un(t,n).map(e=>Kn(e)).filter(Boolean),p=Cn(n).map(e=>Kn(e)).filter(Boolean),g=Kn(r);let f=!1,y=!1;for(const t of u){if(!Vn(t))continue;const n=t,r=Vn(n.basicInfo)?n.basicInfo:null,a=r&&Vn(r.storeInfo)?r.storeInfo:null,o=Kn(zn(n,["brandAlias","brandName","brand","organizationName"])||(r?zn(r,["brandAlias","brandName","brand"]):"")),i=Kn(zn(n,["cityName","storeCityName","jobCityName"])||(a?zn(a,["storeCityName","cityName"]):"")),l=Kn(zn(n,["regionName","storeRegionName","districtName"])||(a?zn(a,["storeRegionName","regionName","districtName"]):"")),u=Kn(zn(n,["storeAddress","jobAddress","address","storeExactAddress"])||(a?zn(a,["storeAddress","storeExactAddress","address"]):""));if(m.length>0&&!m.some(e=>o.includes(e)||e.includes(o)))continue;if(p.length>0&&!p.some(e=>i.includes(e)))continue;if(g&&!l.includes(g)&&!u.includes(g))continue;s.matchedCount+=1;const c=Vn(n.hiringRequirement)?n.hiringRequirement:void 0,d=Vn(c?.basicPersonalRequirements)?c.basicPersonalRequirements:void 0,b=Jn(d?.minAge??n.minAge),h=Jn(d?.maxAge??n.maxAge);if(null!==b&&(f=!0,s.minAgeObserved=null===s.minAgeObserved?b:Math.min(s.minAgeObserved,b)),null!==h&&(f=!0,s.maxAgeObserved=null===s.maxAgeObserved?h:Math.max(s.maxAgeObserved,h)),"number"==typeof e){null!==b&&e<b||null!==h&&e>h||(y=!0)}}if("number"!=typeof e||0===s.matchedCount||!f)return{status:"unknown",summary:s,appliedStrategy:Qn("unknown",a)};if(d)return{status:"unknown",summary:s,appliedStrategy:Qn("unknown",a)};const b=y?"pass":"fail";return{status:b,summary:s,appliedStrategy:Qn(b,a)}}catch{return{status:"unknown",summary:s,appliedStrategy:Qn("unknown",a)}}}function Xn(e){if(!e)return;const t=e.match(/(\d+)/);return t?t[1]:e}function er(e,t){if("number"==typeof t?.age)return t.age;const n=Xn(t?.age);if(n){const e=Number(n);if(Number.isFinite(e))return e}return"number"==typeof e.extractedInfo.specificAge?e.extractedInfo.specificAge:void 0}function tr(e,t){const n=e.extractedInfo.mentionedDistricts?.[0]?.district;if(n)return n;const r=e.extractedInfo.mentionedLocations?.[0]?.location;return r||(t?.jobAddress?t.jobAddress:void 0)}var nr=[{key:"age",label:"年龄"},{key:"gender",label:"性别"},{key:"education",label:"学历"},{key:"experience",label:"工作经验"},{key:"expectedSalary",label:"期望薪资"},{key:"expectedLocation",label:"期望位置"},{key:"jobAddress",label:"工作地址"},{key:"healthCertificate",label:"健康证"}];function rr(e){if(!e)return{factsText:"",knownFieldNames:[]};const t=[];for(const{key:n,label:r}of nr){const a=e[n];"string"==typeof a&&a.trim()?t.push({label:r,value:a.trim()}):"boolean"==typeof a&&t.push({label:r,value:a?"是":"否"})}return 0===t.length?{factsText:"",knownFieldNames:[]}:{factsText:t.map(e=>`${e.label}:${e.value}`).join("\n"),knownFieldNames:t.map(e=>e.label)}}function ar(e){if(null===e.minAgeObserved&&null===e.maxAgeObserved)return null;return`${e.minAgeObserved??"?"}-${e.maxAgeObserved??"?"}`}function or(e,t,n){const r=t?.qualificationPolicy?.age;if(!e||!r||!r.enabled)return[];if("unknown"===e.status&&!n.riskFlags.includes("age_sensitive"))return[];const a=["[QualificationPolicy:Age]"],o=ar(e.summary);return a.push(`- gateStatus: ${e.status}`),a.push(`- expressionStrategy: ${e.appliedStrategy.strategy}`),a.push("- redirect: "+(r.allowRedirect?`allowed priority=${r.redirectPriority}`:"not allowed")),a.push("- revealRange: "+(r.revealRange?"allowed":"not allowed")),r.revealRange&&o&&a.push(`- rangeObserved: ${o}`),"pass"===e.status?a.push(`- writingConstraint: ${e.appliedStrategy.strategy};匹配通过后推进下一步,避免强调年龄筛选`):"fail"===e.status?(a.push(`- writingConstraint: ${e.appliedStrategy.strategy};礼貌说明不匹配,避免承诺或争辩`),r.allowRedirect&&a.push("- writingConstraint: 可提示其他岗位或门店选项")):a.push("- writingConstraint: 如确需涉及年龄或资格,用合规、轻量的方式核实,不要审查式逐条盘问"),a}function ir(e){return"minimal"===e?["4. 当前为浅层沟通,优先泛化回答,不主动抛具体数字、时间、地址或筛选条件。","5. 若候选人追问具体事实,承接需求并引导进一步沟通,不编造细节。"]:["4. 围绕 primaryNeed 回答,上下文中有的事实可以正常引用,不要刻意回避。","5. 不主动展开其他事实轴;若候选人同时问两个点,只在上下文支持时简要带上次要问题。"]}function sr(e,t,n,r,a,o,i,s,l,u,c,d){if(!e)return{system:"你是招聘助手。遵循事实,不夸大承诺,回复简洁自然。",prompt:`候选人消息:${a}\n\n上下文:\n${r}\n\n请直接回复候选人。`};const m=e.stageGoals[t.stage],p=e.industryVoices[u||e.defaultIndustryVoiceId],g=e.outputGuards.maxQuestionsByMode[s];return{system:["你是政策驱动的招聘助手。",`当前阶段:${t.stage}`,`当前轮次:${i}`,`当前披露模式:${s}`,`主回答轴:${t.primaryNeed}`,`阶段目标:${m.primaryGoal}`,`阶段成功标准:${m.successCriteria.join(";")}`,`推进策略:${m.ctaStrategy}`,m.disallowedActions?.length?`阶段禁止:${m.disallowedActions.join(";")}`:"",`人格设定:语气=${e.persona.tone},亲和度=${e.persona.warmth},长度=${e.persona.length},称呼=${e.persona.addressStyle},提问风格=${e.persona.questionStyle}`,`共情策略:${e.persona.empathyStrategy}`,p?`行业指纹:${p.name};背景=${p.industryBackground};行业词=${p.jargon.join("、")};避免=${p.tabooPhrases.join("、")}`:"",`红线规则:${e.hardConstraints.rules.map(e=>e.rule).join(";")}`,`FactGate模式:${e.factGate.mode};缺事实回退=${e.factGate.fallbackBehavior}`,`禁止审查措辞:${e.outputGuards.blockedAuditPhrases.join("、")}`,...l.knownFieldNames.length>0?[`候选人资料已确认:${l.knownFieldNames.join("、")}。这些信息不得重复追问;如需引用,自然带过即可,不要像念资料一样复述。`]:[],...or(d,e,t),c?`如涉及换微信,优先引导平台交换,必要时可提供默认微信号:${c}`:"如涉及换微信,优先引导平台交换,不编造联系方式。","必须口语化、简洁,不输出解释。"].filter(Boolean).join("\n"),prompt:["[回合规划]",`stage=${t.stage}`,`subGoals=${t.subGoals.join("、")||"无"}`,`contextNeeds=${n.join("、")||"none"}`,`primaryNeed=${t.primaryNeed}`,`riskFlags=${t.riskFlags.join("、")||"无"}`,`confidence=${t.confidence.toFixed(2)}`,"","[对话历史]",o.slice(-6).join("\n")||"无","","[业务上下文]",r,"",...l.factsText?["[候选人已知信息]",l.factsText,""]:[],"[候选人消息]",a,"","[输出要求]","1. 直接给候选人的单条回复,不得输出多段解释或元信息。",`2. 最多追问 ${g} 个关键问题。`,"3. 禁止使用“是否满足”“是否符合”“基本入职要求”等审查措辞。",...ir(s)].join("\n")}}function lr(e,t,n){const r=Nn(e);if(0===r.length)return!1;const a=new Set(In(t)),o=new Set(n.flatMap(e=>D[e]));return r.some(e=>!o.has(e)||!a.has(e))}function ur(e){return"private_channel"===e||"interview_scheduling"===e}function cr(e,t){return Number.isInteger(t)&&void 0!==t&&t>=1?t:0===e.length?1:2}function dr(e,t){return 1===e||"trust_building"===t||"private_channel"===t?"minimal":"focused"}function mr(e,t){const n=["- 只修正命中的违规点,没有命中的部分不要过度改写。"];return e.includes("too_many_questions")&&n.push(`- 删除多余追问,只保留最关键的 ${t} 个问题。`),e.includes("audit_tone")&&n.push("- 保留原意,但把审查式措辞改成自然口语,不要像筛选候选人。"),e.includes("premature_numeric_disclosure")&&n.push("- 把具体数字、时间和地址细节改成泛化表达,例如“细节我帮你确认”或“以门店安排为准”。"),e.includes("off_axis_fact_disclosure")&&n.push("- 删除不属于主回答轴的具体事实;如果要提到次要问题,只能做不带细节的承接。"),e.includes("reply_overpacked")&&n.push("- 压缩成最多两句,不要列表、不要枚举、不要一口气展开太多信息。"),n}async function pr(e,t,n){const r=["请重写下面这条招聘回复。","要求:","- 不新增任何具体数字、地址、福利承诺。","- 仅保留泛化表达,强调可进一步沟通确认细节。","- 口语化、单行、简洁。","","[原回复]",e,"","[可用上下文]",n].join("\n"),a=await bt({model:t,prompt:r,context:"SmartReplyFactGateRewrite",timeoutMs:2e4,maxOutputTokens:500});return a.success?{text:a.text,usage:a.usage,latencyMs:a.latencyMs}:{text:e}}async function gr(e,t,n,r){const{turnIndex:a,effectiveDisclosureMode:o,primaryNeed:i,allowedNeeds:s,violations:l,policy:u}=r,c=u?.outputGuards.maxQuestionsByMode[o]??1,d=u?.outputGuards.blockedAuditPhrases.join("、")??"",m=mr(l,c),p=(s??[]).filter(e=>e!==i&&"none"!==e),g=["请重写下面这条招聘回复。","要求:",`- 当前轮次=${a},披露模式=${o},主回答轴=${i}。`,p.length>0?`- 允许顺带覆盖的次要轴:${p.join("、")}。`:"",`- 当前违规点:${l.join("、")}。`,...m,"- 只保留单条口语化回复,不输出解释。",`- 问题数最多 ${c} 个。`,"- 围绕主回答轴回答,不主动展开其他事实轴。","- 首轮时不要主动报具体数字、时间、地址或筛选条件。",d?`- 禁止使用这些措辞:${d}。`:"","","[原回复]",e,"","[可用上下文]",n].filter(Boolean).join("\n"),f=await bt({model:t,prompt:g,context:"SmartReplyReplyGateRewrite",timeoutMs:2e4,maxOutputTokens:500});return f.success?{text:f.text,usage:f.usage,latencyMs:f.latencyMs}:{text:e}}async function fr(e){const t=En();ge(!0);try{return await yr(e,t)}catch(e){throw t.fail("回复生成失败"),e}finally{ge(!1)}}async function yr(e,t){const{modelConfig:n,preferredBrand:r,toolBrand:a,brandPriorityStrategy:o,conversationHistory:i=[],candidateMessage:s,configData:l,replyPolicy:u,candidateInfo:c,defaultWechatId:d,industryVoiceId:m,channelType:p,turnIndex:g}=e,f=n?.providerConfigs||Ne,y=De(l),b={...y?{city:y}:{},defaultBrand:Me(l),availableBrands:ve(l),storeCount:Le(l).length},h=rr(c);t.update("分析对话意图...");const S=await Ft(s,{modelConfig:n||{},conversationHistory:i,brandData:b,providerConfigs:f,...void 0!==p?{channelType:p}:{},...void 0!==u?{replyPolicy:u}:{},...h.knownFieldNames.length>0?{knownCandidateFields:h.knownFieldNames}:{}}),N=cr(i,g),I=dr(N,S.stage),T="focused"===I?Ut(S.primaryNeed,S.needs,s,2):[S.primaryNeed],A=a||S.extractedInfo.mentionedBrand||void 0;t.update("构建业务上下文...");const{contextInfo:_,debugInfo:E,resolvedBrand:R}=await ln(l,S,r,A,o,c,u,m,N,I,T);t.update("校验候选人资格...");const O=er(S,c),L=tr(S,c),v=S.extractedInfo.city??De(l,R),w=await Zn({...void 0!==O?{age:O}:{},brandAlias:R,..."string"==typeof v?{cityName:v}:{},...void 0!==L?{regionName:L}:{},...void 0!==u?.qualificationPolicy?.age?{strategy:u.qualificationPolicy.age}:{}}),k=Oe(f),M=n?.replyModel||Ie.replyModel,D=k.languageModel(M),x=sr(u,S,T,_,s,i,N,I,h,m,d,w);t.update("生成回复...");const C=await bt({model:D,system:x.system,prompt:x.prompt,context:"SmartReply",timeoutMs:3e4,maxOutputTokens:2e3});if(!C.success)return t.fail("回复生成失败"),it("SmartReply 生成失败",C.error),{turnPlan:S,suggestedReply:"",confidence:0,shouldExchangeWechat:ur(S.stage),factGateRewritten:!1,replyGateRewritten:!1,gateViolations:[],contextInfo:_,debugInfo:{...E,resolvedBrand:R,turnIndex:N,effectiveDisclosureMode:I,primaryNeed:S.primaryNeed,replyGateRewritten:!1,gateViolations:[],gateStatus:w.status,appliedStrategy:w.appliedStrategy,ageRangeSummary:w.summary},usage:void 0,error:C.error};let U=C.text,$=C.usage,j=C.latencyMs,W=!1,F=!1,P=[];if(t.update("检查回复质量..."),"strict"===u?.factGate.mode){if(lr(U,_,T)){W=!0;const e=await pr(U,D,_);U=e.text,e.usage&&($=e.usage),void 0!==e.latencyMs&&(j=(j??0)+e.latencyMs)}}if(P=An({text:U,turnIndex:N,mode:I,primaryNeed:S.primaryNeed,allowedNeeds:T,policy:u}).violations,P.length>0){t.update("优化回复..."),F=!0;const e=await gr(U,D,_,{turnIndex:N,effectiveDisclosureMode:I,primaryNeed:S.primaryNeed,allowedNeeds:T,violations:P,policy:u});U=e.text,e.usage&&($=e.usage),void 0!==e.latencyMs&&(j=(j??0)+e.latencyMs),P=An({text:U,turnIndex:N,mode:I,primaryNeed:S.primaryNeed,allowedNeeds:T,policy:u}).violations}const B=j??0,G=$?.totalTokens??0;return t.succeed(`回复已生成 | ${S.stage} | ${B}ms | ${G} tokens${F?" | 已优化":""}`),{turnPlan:S,suggestedReply:U,confidence:Math.max(0,Math.min(1,S.confidence)),shouldExchangeWechat:ur(S.stage),factGateRewritten:W,replyGateRewritten:F,gateViolations:P,contextInfo:`${_}\n当前品牌:${R}`,debugInfo:{...E,resolvedBrand:R,turnIndex:N,effectiveDisclosureMode:I,primaryNeed:S.primaryNeed,replyGateRewritten:F,gateViolations:P,gateStatus:w.status,appliedStrategy:w.appliedStrategy,ageRangeSummary:w.summary},usage:$,latencyMs:j}}var br=n.enum(un),hr=n.enum(Gn),Sr=t({name:"generate_reply",description:"根据候选人消息、对话历史和品牌数据生成智能招聘回复。内部流程:回合规划 → primaryNeed 驱动上下文构建 → 年龄资格校验 → 策略化回复生成 → FactGate/ReplyGate 校验。",input:n.object({candidateMessage:n.string().describe("候选人发送的消息"),conversationHistory:n.array(n.string()).optional().describe("对话历史(最近几轮)"),candidateInfo:i.optional().describe("候选人基本信息"),preferredBrand:n.string().optional().describe("偏好品牌"),channelType:O.optional().describe("渠道类型: public(BOSS直聘) 或 private(微信)"),defaultWechatId:n.string().optional().describe("默认微信号"),industryVoiceId:n.string().optional().describe("行业语调ID"),turnIndex:n.number().int().min(1).optional().describe("当前会话回复轮次"),modelConfig:It.optional().describe("模型配置覆盖")}),output:n.object({suggestedReply:n.string(),confidence:n.number(),stage:R,latencyMs:n.number().optional(),shouldExchangeWechat:n.boolean().optional(),error:n.string().optional(),diagnostics:n.object({subGoals:n.array(n.string()),needs:n.array(k),primaryNeed:k,riskFlags:n.array(M),reasoningText:n.string(),extractedInfo:n.object({mentionedBrand:n.string().nullable(),city:n.string().nullable(),specificAge:n.number().nullable(),hasUrgency:n.boolean().nullable(),preferredSchedule:n.string().nullable()}),ageGate:n.object({enabled:n.boolean(),status:hr,strategy:n.string()}),resolvedBrand:n.string(),storeCount:n.number(),detailLevel:L,turnIndex:n.number(),effectiveDisclosureMode:L,replyGateRewritten:n.boolean(),gateViolations:n.array(br),factGateRewritten:n.boolean()}).optional()}),execute:async(e,t)=>{let n;t.logger.info(`Processing message: ${e.candidateMessage.slice(0,50)}...`);try{n=re()}catch{return{suggestedReply:"",confidence:0,stage:"trust_building",error:"品牌数据未配置,请先调用 sync_brand_data 写入数据"}}const r=oe(),a=await fr({candidateMessage:e.candidateMessage,conversationHistory:e.conversationHistory,candidateInfo:e.candidateInfo,preferredBrand:e.preferredBrand,channelType:e.channelType,defaultWechatId:e.defaultWechatId,industryVoiceId:e.industryVoiceId,turnIndex:e.turnIndex,modelConfig:e.modelConfig,configData:n,replyPolicy:r});t.logger.info(`Reply generated. Stage: ${a.turnPlan.stage}, Confidence: ${a.confidence}`);const o=a.debugInfo;return{suggestedReply:a.suggestedReply,confidence:a.confidence,stage:a.turnPlan.stage,latencyMs:a.latencyMs,shouldExchangeWechat:a.shouldExchangeWechat,error:a.error?.userMessage,diagnostics:o?{subGoals:a.turnPlan.subGoals,needs:a.turnPlan.needs,primaryNeed:a.turnPlan.primaryNeed,riskFlags:a.turnPlan.riskFlags,reasoningText:a.turnPlan.reasoningText,extractedInfo:{mentionedBrand:a.turnPlan.extractedInfo.mentionedBrand??null,city:a.turnPlan.extractedInfo.city??null,specificAge:a.turnPlan.extractedInfo.specificAge??null,hasUrgency:a.turnPlan.extractedInfo.hasUrgency??null,preferredSchedule:a.turnPlan.extractedInfo.preferredSchedule??null},ageGate:{enabled:o.appliedStrategy.enabled,status:o.gateStatus,strategy:o.appliedStrategy.strategy},resolvedBrand:o.resolvedBrand,storeCount:o.storeCount,detailLevel:o.detailLevel,turnIndex:o.turnIndex,effectiveDisclosureMode:o.effectiveDisclosureMode,replyGateRewritten:a.replyGateRewritten,gateViolations:a.gateViolations,factGateRewritten:a.factGateRewritten}:void 0}}});import{defineTool as Nr}from"@roll-agent/sdk";import{z as Ir}from"zod";import{z as Tr}from"zod";var Ar=Tr.object({content:Tr.string(),image:Tr.string().nullable().optional()}).passthrough(),_r=Tr.object({storeId:Tr.number().optional(),storeName:Tr.string(),storeCityName:Tr.string().optional(),storeRegionName:Tr.string().optional(),storeAddress:Tr.string().optional(),longitude:Tr.number().optional(),latitude:Tr.number().optional()}).passthrough(),Er=Tr.object({jobId:Tr.number(),jobName:Tr.string(),jobContent:Tr.string().nullable().optional(),brandId:Tr.number().optional(),brandName:Tr.string().optional(),projectId:Tr.number().optional(),projectName:Tr.string().optional(),storeInfo:_r.optional()}).passthrough(),Rr=Tr.object({salaryType:Tr.string().nullable().optional(),salaryPeriod:Tr.string().nullable().optional(),hasStairSalary:Tr.string().nullable().optional(),basicSalary:Tr.object({basicSalary:Tr.number().nullable().optional(),basicSalaryUnit:Tr.string().nullable().optional()}).passthrough().nullable().optional(),stairSalaries:Tr.array(Tr.object({fullWorkTime:Tr.number().nullable().optional(),fullWorkTimeUnit:Tr.string().nullable().optional(),salary:Tr.number().nullable().optional(),salaryUnit:Tr.string().nullable().optional()}).passthrough()).nullable().optional(),comprehensiveSalary:Tr.object({minComprehensiveSalary:Tr.number().nullable().optional(),maxComprehensiveSalary:Tr.number().nullable().optional(),comprehensiveSalaryUnit:Tr.string().nullable().optional()}).passthrough().nullable().optional(),holidaySalary:Tr.object({holidaySalaryType:Tr.string().nullable().optional(),holidaySalaryMultiple:Tr.number().nullable().optional(),holidayFixedSalary:Tr.number().nullable().optional(),holidayFixedSalaryUnit:Tr.string().nullable().optional()}).passthrough().nullable().optional()}).passthrough(),Or=Tr.object({salary:Tr.number().optional(),salaryUnitStr:Tr.string().optional(),salaryScenarioList:Tr.array(Rr).nullable().optional()}).passthrough(),Lr=Tr.object({haveInsurance:Tr.string(),accommodation:Tr.string(),catering:Tr.string().optional(),otherWelfare:Tr.array(Tr.string()).nullable().optional(),accommodationAllowance:Tr.number().nullable().optional(),accommodationAllowanceUnit:Tr.string().nullable().optional(),cateringSalary:Tr.number().nullable().optional(),cateringSalaryUnit:Tr.string().nullable().optional(),trafficAllowanceSalary:Tr.number().nullable().optional(),trafficAllowanceSalaryUnit:Tr.string().nullable().optional(),memo:Tr.string().nullable().optional(),promotionWelfare:Tr.string().nullable().optional(),moreWelfares:Tr.array(Ar).nullable().optional()}).passthrough(),vr=Tr.object({minAge:Tr.number().nullable().optional(),maxAge:Tr.number().nullable().optional(),genderRequirement:Tr.string().nullable().optional()}).passthrough(),wr=Tr.object({education:Tr.string().nullable().optional(),healthCertificate:Tr.string().nullable().optional()}).passthrough(),kr=Tr.object({cooperationMode:Tr.number().optional(),requirementNum:Tr.number().optional(),thresholdNum:Tr.number().optional(),signUpNum:Tr.number().nullable().optional(),basicPersonalRequirements:vr.nullable().optional(),certificate:wr.nullable().optional()}).passthrough(),Mr=Tr.object({employmentForm:Tr.string(),minWorkMonths:Tr.number().nullable().optional(),maxWorkTakingTime:Tr.number().nullable().optional(),restTimeDesc:Tr.string().nullable().optional(),workTimeRemark:Tr.string().nullable().optional(),employmentDescription:Tr.string().nullable().optional(),weekWorkTime:Tr.object({weekWorkTimeRequirement:Tr.string().nullable().optional(),perWeekWorkDays:Tr.number().nullable().optional(),perWeekRestDays:Tr.number().nullable().optional(),perWeekNeedWorkDays:Tr.union([Tr.string(),Tr.number()]).nullable().optional(),workSingleDouble:Tr.string().nullable().optional(),customnWorkTimeList:Tr.array(Tr.object({customMinWorkDays:Tr.number().nullable().optional(),customMaxWorkDays:Tr.number().nullable().optional(),customWorkWeekdays:Tr.array(Tr.union([Tr.string(),Tr.number()])).nullable().optional()}).passthrough()).nullable().optional()}).passthrough().nullable().optional(),monthWorkTime:Tr.object({perMonthMinWorkTime:Tr.number().nullable().optional(),perMonthMinWorkTimeUnit:Tr.union([Tr.string(),Tr.number()]).nullable().optional(),monthWorkTimeRequirement:Tr.string().nullable().optional(),perMonthMaxRestTime:Tr.number().nullable().optional(),perMonthMaxRestTimeUnit:Tr.number().nullable().optional()}).passthrough().nullable().optional(),dayWorkTime:Tr.object({perDayMinWorkHours:Tr.union([Tr.string(),Tr.number()]).nullable().optional(),dayWorkTimeRequirement:Tr.string().nullable().optional()}).passthrough().nullable().optional(),dailyShiftSchedule:Tr.object({arrangementType:Tr.string().nullable().optional(),fixedScheduleList:Tr.array(Tr.object({fixedShiftStartTime:Tr.union([Tr.string(),Tr.number()]).optional(),fixedShiftEndTime:Tr.union([Tr.string(),Tr.number()]).optional(),startTime:Tr.number().optional(),endTime:Tr.number().optional()}).passthrough()).nullable().optional(),combinedArrangement:Tr.array(Tr.object({CombinedArrangementWeekdays:Tr.union([Tr.string(),Tr.array(Tr.number())]).optional(),CombinedArrangementStartTime:Tr.number().optional(),CombinedArrangementEndTime:Tr.number().optional(),startTime:Tr.number().optional(),endTime:Tr.number().optional(),weekdays:Tr.array(Tr.number()).optional()}).passthrough()).nullable().optional(),fixedTime:Tr.object({goToWorkStartTime:Tr.union([Tr.string(),Tr.number()]).nullable().optional(),goToWorkEndTime:Tr.union([Tr.string(),Tr.number()]).nullable().optional(),goOffWorkStartTime:Tr.union([Tr.string(),Tr.number()]).nullable().optional(),goOffWorkEndTime:Tr.union([Tr.string(),Tr.number()]).nullable().optional()}).passthrough().nullable().optional()}).passthrough().nullable().optional(),temporaryEmployment:Tr.object({temporaryEmploymentStartTime:Tr.string().nullable().optional(),temporaryEmploymentEndTime:Tr.string().nullable().optional()}).passthrough().nullable().optional()}).passthrough(),Dr=Tr.object({basicInfo:Er,jobSalary:Or,welfare:Lr,hiringRequirement:kr,workTime:Mr}).passthrough();function xr(e){const t=Dr.safeParse(e);if(!t.success)return null;const n=t.data,r=n.basicInfo,a=r.storeInfo,o=n.jobSalary,i=n.hiringRequirement,s=o.salary??o.salaryScenarioList?.find(e=>"正式"===e.salaryType)?.basicSalary?.basicSalary??o.salaryScenarioList?.[0]?.basicSalary?.basicSalary??0,l=o.salaryUnitStr??o.salaryScenarioList?.find(e=>"正式"===e.salaryType)?.basicSalary?.basicSalaryUnit??o.salaryScenarioList?.[0]?.basicSalary?.basicSalaryUnit??"元/小时";let u=a?.storeId;if(null==u){const e=`${a?.storeName??""}|${a?.storeAddress??""}`;u=Array.from(e).reduce((e,t)=>31*e+t.charCodeAt(0)>>>0,7)}return{jobId:r.jobId,jobName:r.jobName,jobContent:r.jobContent??null,brandId:void 0!==r.brandId?String(r.brandId):void 0!==r.projectId?String(r.projectId):void 0,brandName:r.brandName,projectId:r.projectId,projectName:r.projectName,storeId:u,storeName:a?.storeName??"未知门店",storeCityName:a?.storeCityName??"",storeRegionName:a?.storeRegionName,storeAddress:a?.storeAddress??"",longitude:a?.longitude,latitude:a?.latitude,salary:s,salaryUnitStr:l,salaryScenarioList:o.salaryScenarioList??null,welfare:n.welfare,cooperationMode:i.cooperationMode??0,requirementNum:i.requirementNum??0,thresholdNum:i.thresholdNum??0,signUpNum:i.signUpNum??null,basicPersonalRequirements:i.basicPersonalRequirements?{minAge:i.basicPersonalRequirements.minAge??null,maxAge:i.basicPersonalRequirements.maxAge??null,genderRequirement:i.basicPersonalRequirements.genderRequirement??null}:null,certificate:i.certificate?{education:i.certificate.education??null,healthCertificate:i.certificate.healthCertificate??null}:null,workTime:n.workTime}}function Cr(e,t,n){const r=new Map;let a;for(let o=0;o<e.length;o++){const i=xr(e[o]);if(!i)continue;const s=i.brandName??t??"未知品牌",l=i.brandId??`name:${s}`;void 0!==a||void 0!==t&&s!==t||(a=l);let u=r.get(l);u||(u={id:l,name:s,stores:[]},r.set(l,u));const c=`store_${i.storeId}`;let d=u.stores.find(e=>e.id===c);d||(d=Ur(i,l,n),u.stores.push(d));const m=$r(i);d.positions.push(m)}return{meta:{...a??r.values().next().value?.id?{defaultBrandId:a??r.values().next().value?.id}:{},syncedAt:(new Date).toISOString(),source:"duliday"},brands:Array.from(r.values())}}function Ur(e,t,n){return{id:`store_${e.storeId}`,brandId:t,name:e.storeName,city:e.storeCityName||n,location:e.storeAddress,district:ta(e.storeAddress,e.storeRegionName),subarea:na(e.storeName),coordinates:"number"==typeof e.latitude&&"number"==typeof e.longitude?{lat:e.latitude,lng:e.longitude}:{lat:0,lng:0},positions:[]}}function $r(e){const t=jr(e.workTime);let n=[];return t.combinedArrangementTimes?.length?n=ea(t.combinedArrangementTimes):t.fixedArrangementTimes?.length&&(n=ea(t.fixedArrangementTimes.map(e=>({...e,weekdays:[]})))),{id:`pos_${e.jobId}`,name:ra(e.jobName),brandId:e.brandId,brandName:e.brandName,projectId:void 0!==e.projectId?String(e.projectId):void 0,projectName:e.projectName,timeSlots:n,salary:{...Wr(e.salary,e.welfare),scenarioSummary:Fr(e.salaryScenarioList),settlementCycle:Pr(e.salaryScenarioList)},workHours:String(t.perDayMinWorkHours??8),benefits:Br(e.welfare),requirements:Gr(e),urgent:e.requirementNum>3,scheduleType:2===e.cooperationMode?"flexible":"fixed",attendancePolicy:Kr(e.cooperationMode),availableSlots:Vr(e,t),schedulingFlexibility:Yr(e,t),minHoursPerWeek:Jr(t),maxHoursPerWeek:Qr(t),attendanceRequirement:Zr(t),hiringRequirements:Hr(e),description:e.jobContent||void 0}}function jr(e){const t=e.weekWorkTime,n=e.dayWorkTime,r=e.dailyShiftSchedule,a=Number(e.employmentForm)||({"长期用工":1,"临时用工":2,"短期用工":2}[String(e.employmentForm)]??1),o=Number(r?.arrangementType)||({"固定排班制":1,"组合排班制":3}[String(r?.arrangementType)]??0),i=null!=n?.perDayMinWorkHours?Number(n.perDayMinWorkHours):null,s=null!==i&&Number.isFinite(i)?i:null,l=t?.customnWorkTimeList?.map(e=>({weekdays:Array.isArray(e.customWorkWeekdays)?e.customWorkWeekdays.map(e=>Number(e)).filter(e=>Number.isFinite(e)):[],minWorkDays:e.customMinWorkDays??null,maxWorkDays:e.customMaxWorkDays??null}))??null,u=r?.fixedScheduleList?.map(e=>({startTime:e.startTime??Xr(e.fixedShiftStartTime),endTime:e.endTime??Xr(e.fixedShiftEndTime)}))??null,c=r?.combinedArrangement?.map(e=>{const t=(e.weekdays??("string"==typeof e.CombinedArrangementWeekdays?[Number(e.CombinedArrangementWeekdays)]:Array.isArray(e.CombinedArrangementWeekdays)?e.CombinedArrangementWeekdays:[])).map(e=>"number"==typeof e?e:Number(e)).filter(e=>Number.isFinite(e));return{startTime:e.startTime??e.CombinedArrangementStartTime??0,endTime:e.endTime??e.CombinedArrangementEndTime??0,weekdays:t}})??null;return{employmentForm:a,perDayMinWorkHours:s,perWeekWorkDays:t?.perWeekWorkDays??null,perWeekNeedWorkDays:null!=t?.perWeekNeedWorkDays?Number(t.perWeekNeedWorkDays):null,perWeekRestDays:t?.perWeekRestDays??null,arrangementType:o,maxWorkTakingTime:e.maxWorkTakingTime??0,workTimeRemark:e.workTimeRemark??null,fixedArrangementTimes:u,combinedArrangementTimes:c,customWorkTimes:l}}function Wr(e,t){const n=t.memo||"",r=n.match(/(\d+元?-\d+元?)/),a=r?r[1]:void 0,o=n.match(/(奖金[\d~\-~元]+)/);return{base:e,range:a,bonus:o?o[1]:void 0,memo:n}}function Fr(e){if(!e||0===e.length)return;const t=[];for(const n of e){if("培训期"===n.salaryType)continue;if(n.stairSalaries?.length){const e=n.stairSalaries.filter(e=>null!=e.salary).map(e=>{const t=e.salaryUnit??"元/时";return`满${e.fullWorkTime??"?"}${e.fullWorkTimeUnit??"小时"}后${e.salary}${t}`}).join(",");e&&t.push(e)}const e=n.comprehensiveSalary;null!=e?.minComprehensiveSalary&&null!=e?.maxComprehensiveSalary&&t.push(`综合${e.minComprehensiveSalary}-${e.maxComprehensiveSalary}${e.comprehensiveSalaryUnit??"元/月"}`);const r=n.holidaySalary;r&&(r.holidaySalaryMultiple?t.push(`节假日${r.holidaySalaryMultiple}倍`):null!=r.holidayFixedSalary&&t.push(`节假日${r.holidayFixedSalary}${r.holidayFixedSalaryUnit??"元/时"}`))}return t.length>0?t.join(";"):void 0}function Pr(e){if(!e||0===e.length)return;const t=e.find(e=>"正式"===e.salaryType)??e[0];return{"日结算":"日结","周结算":"周结","月结算":"月结","完结算":"完结","半月结算":"半月结"}[t?.salaryPeriod??""]??void 0}function Br(e){const t=[];if(e.haveInsurance&&"无"!==e.haveInsurance&&"0"!==e.haveInsurance&&t.push("五险一金"),e.accommodation&&"无"!==e.accommodation&&"0"!==e.accommodation&&t.push("住宿"),e.catering&&"无"!==e.catering&&"0"!==e.catering&&t.push("餐饮"),e.moreWelfares&&Array.isArray(e.moreWelfares))for(const n of e.moreWelfares){const e=n.content,r=["保险","年假","补贴","福利","股票","学历提升"];for(const n of r)if(e.includes(n)&&!t.some(e=>e.includes(n))){const r=e.match(new RegExp(`\\d*[天个月年]*${n}[^,。]*`));t.push(r?r[0]:n)}}if(e.memo){const n=["年假","补贴","商保","股票","学历提升"];for(const r of n)e.memo.includes(r)&&!t.some(e=>e.includes(r))&&t.push(r)}return 0===t.length&&t.push("按国家规定"),{items:t,promotion:e.promotionWelfare||void 0}}function Gr(e){const t=[],n=e.basicPersonalRequirements,r=e.certificate;if(null!=n?.minAge||null!=n?.maxAge){const e=n?.minAge??"不限",r=n?.maxAge??"不限";t.push(`年龄${e}-${r}岁`)}if(n?.genderRequirement&&"0"!==n.genderRequirement){if(!/男性.*女性|女性.*男性|不限/.test(n.genderRequirement)){const e={"男性":"限男性","女性":"限女性"};t.push(e[n.genderRequirement]??`性别要求:${n.genderRequirement}`)}}if(r?.education&&"不限"!==r.education){const e={"本科":"本科及以上","专科":"专科及以上","高中":"高中及以上","初中":"初中及以上"};t.push(e[r.education]??`学历${r.education}`)}if(r?.healthCertificate){const e={"食品健康证":"需食品健康证","零售健康证":"需零售健康证"};t.push(e[r.healthCertificate]??"需健康证")}return 0===t.length?qr(e.jobName):t}function qr(e){const t=["工作认真负责","团队合作精神"];return e.includes("服务员")?[...t,"有服务行业经验优先","沟通能力强"]:e.includes("经理")?[...t,"有管理经验","责任心强"]:[...t,"有相关工作经验者优先"]}function Hr(e){const t=e.basicPersonalRequirements,n=e.certificate;if(t||n)return{minAge:t?.minAge??null,maxAge:t?.maxAge??null,genderRequirement:t?.genderRequirement??null,education:n?.education??null,healthCertificate:n?.healthCertificate??null}}function Kr(e){const t=3===e;return{punctualityRequired:t,lateToleranceMinutes:t?5:15,attendanceTracking:t?"strict":"flexible",makeupShiftsAllowed:!t}}function Vr(e,t){const n=[];let r=[];t.combinedArrangementTimes?.length?r=ea(t.combinedArrangementTimes):t.fixedArrangementTimes?.length&&(r=ea(t.fixedArrangementTimes.map(e=>({...e,weekdays:[]}))));for(const t of r)n.push({slot:t,maxCapacity:e.requirementNum,currentBooked:e.signUpNum||0,isAvailable:(e.signUpNum||0)<e.requirementNum,priority:e.requirementNum>3?"high":"medium"});return n}function Yr(e,t){const n=2===e.cooperationMode;return{canSwapShifts:3===t.arrangementType||n,advanceNoticeHours:t.maxWorkTakingTime/60,partTimeAllowed:n,weekendRequired:zr(t),holidayRequired:!1}}function zr(e){return!!e.combinedArrangementTimes&&e.combinedArrangementTimes.some(e=>e.weekdays.includes(0)||e.weekdays.includes(6))}function Jr(e){const t=e.perDayMinWorkHours??8;let n=null;if(null!=e.perWeekWorkDays&&(n=e.perWeekWorkDays),null===n&&e.customWorkTimes?.length){const t=e.customWorkTimes.map(e=>e.minWorkDays).filter(e=>null!=e);t.length>0&&(n=Math.min(...t))}return null===n&&null!=e.perWeekNeedWorkDays&&(n=e.perWeekNeedWorkDays),null===n&&(n=5),t*n}function Qr(e){return 7*(e.perDayMinWorkHours??8)}function Zr(e){let t=[];if(e.combinedArrangementTimes?.length){const n=new Set;for(const t of e.combinedArrangementTimes)for(const e of t.weekdays)null!=e&&Number.isFinite(e)&&n.add(e);t=Array.from(n).sort()}else if(e.customWorkTimes?.length){const n=new Set;for(const t of e.customWorkTimes)for(const e of t.weekdays)null!=e&&Number.isFinite(e)&&n.add(e);t=Array.from(n).sort()}let n=null;if(null!=e.perWeekWorkDays&&(n=e.perWeekWorkDays),null===n&&e.customWorkTimes?.length){const t=e.customWorkTimes.map(e=>e.minWorkDays).filter(e=>null!=e);t.length>0&&(n=Math.min(...t))}return null===n&&null!=e.perWeekNeedWorkDays&&(n=e.perWeekNeedWorkDays),null===n&&(n=5),{minimumDays:n,requiredDays:aa(t),description:e.workTimeRemark||""}}function Xr(e){if("number"==typeof e)return e;if("string"!=typeof e||!e)return 0;const t=e.match(/^(\d{1,2}):(\d{2})$/);return t?3600*Number(t[1])+60*Number(t[2]):Number(e)||0}function ea(e){return e.map(e=>{const t=Math.floor(e.startTime/3600),n=Math.floor(e.startTime%3600/60),r=Math.floor(e.endTime/3600),a=Math.floor(e.endTime%3600/60);return`${t.toString().padStart(2,"0")}:${n.toString().padStart(2,"0")}~${r.toString().padStart(2,"0")}:${a.toString().padStart(2,"0")}`})}function ta(e,t){if(t)return t;return e.split("-")[1]||"未知区域"}function na(e){const t=e.match(/(.+?)(附近|周边|旁边|店)/);return t?.[1]??e}function ra(e){const t=e.split("-");return t[t.length-2]||"服务员"}function aa(e){return e.filter(e=>Number.isFinite(e)).map(e=>0===e?7:e)}var oa=Nr({name:"sync_brand_data",description:"从 Duliday API 拉取并同步品牌配置数据(门店、岗位、薪资等)到本地。可选传入品牌别名和城市名称作为过滤条件。",input:Ir.object({brandAlias:Ir.string().optional().describe("品牌别名(可选,配合 cityName 使用可按品牌过滤)"),cityName:Ir.string().describe('城市名称(必填,Duliday API 要求至少提供城市作为筛选条件,如 "上海市")')}),output:Ir.object({success:Ir.boolean(),brandsCount:Ir.number(),storesCount:Ir.number(),positionsCount:Ir.number(),updatedAt:Ir.string(),error:Ir.string().optional()}),execute:async(e,t)=>{const n=Dn(),r=Mn();if(!n||!r)return{success:!1,brandsCount:0,storesCount:0,positionsCount:0,updatedAt:(new Date).toISOString(),error:`缺少环境变量: ${[!n&&"DULIDAY_TOKEN",!r&&"DULIDAY_JOB_LIST_URL"].filter(Boolean).join(", ")}`};if(!e.cityName)return{success:!1,brandsCount:0,storesCount:0,positionsCount:0,updatedAt:(new Date).toISOString(),error:'cityName 为必填项,Duliday API 要求至少提供城市作为筛选条件(如 "上海市")'};try{t.logger.info("Fetching all job list pages from Duliday API...");const{items:a}=await Bn(n,r,{brandAlias:e.brandAlias??null,cityName:e.cityName??null,include:Wn});let o=sa(a);!o&&e.brandAlias&&(o=await la(e.brandAlias,n)),!o&&e.brandAlias&&(o=e.brandAlias),t.logger.info(`Resolved default brand: ${o??"自动推断"}, converting ${a.length} positions...`);const i=Cr(a,o,e.cityName);ae(i),t.logger.info(`Brand config saved: ${i.brands.length} brands, ${i.brands.reduce((e,t)=>e+t.stores.length,0)} stores`);const s=i.brands.reduce((e,t)=>e+t.stores.length,0),l=i.brands.reduce((e,t)=>e+t.stores.reduce((e,t)=>e+t.positions.length,0),0);return{success:!0,brandsCount:i.brands.length,storesCount:s,positionsCount:l,updatedAt:(new Date).toISOString()}}catch(e){return{success:!1,brandsCount:0,storesCount:0,positionsCount:0,updatedAt:(new Date).toISOString(),error:e instanceof Error?e.message:String(e)}}}});function ia(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)}function sa(e){for(const t of e){if(!ia(t))continue;const e=ia(t.basicInfo)?t.basicInfo:null;if(e&&"string"==typeof e.brandName&&e.brandName)return e.brandName}}async function la(e,t){try{const n=await Zt(t),r=e.trim().toLowerCase().replace(/[\s._-]+/g,"");return n.get(r)}catch{return}}var ua=e({name:"smart-reply-agent",tools:[Sr,oa]});ua.listen().catch(e=>{console.error("Fatal error:",e),process.exit(1)});
1
+ import{defineAgent as e}from"@roll-agent/sdk";import{defineTool as n}from"@roll-agent/sdk";import{z as t}from"zod";import{z as r}from"zod";import{z as a}from"zod";var o=a.object({lat:a.number(),lng:a.number()}),i=r.object({name:r.string().optional(),position:r.string().optional(),expectedPosition:r.string().optional(),communicationPosition:r.string().optional(),age:r.string().optional(),gender:r.string().optional(),experience:r.string().optional(),education:r.string().optional(),expectedSalary:r.string().optional(),expectedLocation:r.string().optional(),jobAddress:r.string().optional(),height:r.string().optional(),weight:r.string().optional(),healthCertificate:r.boolean().optional(),activeTime:r.string().optional(),info:r.array(r.string()).optional(),fullText:r.string().optional()}),s=r.object({base:r.number().nullable(),unit:r.string().nullable(),range:r.string().optional(),bonus:r.string().optional(),memo:r.string().nullable(),scenarioSummary:r.string().optional(),settlementCycle:r.string().optional()}),l=r.object({insurance:r.string().nullable(),accommodation:r.string().nullable(),catering:r.string().nullable(),moreWelfares:r.array(r.string()).nullable(),memo:r.string().nullable(),promotion:r.string().nullable()}),u=r.object({requiredDays:r.array(r.number().min(1).max(7)).optional(),minimumDays:r.number().min(0).nullable(),description:r.string().nullable()}),c=r.object({slot:r.string(),maxCapacity:r.number().min(0),currentBooked:r.number().min(0),isAvailable:r.boolean(),priority:r.enum(["high","medium","low"])}),d=r.object({minAge:r.number().nullable().optional(),maxAge:r.number().nullable().optional(),genderRequirement:r.string().nullable().optional(),education:r.string().nullable().optional(),healthCertificate:r.string().nullable().optional(),languages:r.string().nullable().optional(),certificatesRaw:r.string().nullable().optional(),recruitmentRemark:r.string().nullable().optional(),socialIdentity:r.string().nullable().optional()}),m=r.object({id:r.string(),name:r.string(),sourceJobName:r.string(),jobCategory:r.string().nullable(),brandId:r.string().optional(),brandName:r.string().optional(),projectId:r.string().optional(),projectName:r.string().optional(),description:r.string().nullable(),laborForm:r.string().nullable(),employmentForm:r.string().nullable(),trainingRequired:r.string().nullable(),probationRequired:r.string().nullable(),salary:s,timeSlots:r.array(r.string()),workHours:r.string().nullable(),minHoursPerWeek:r.number().min(0).nullable(),maxHoursPerWeek:r.number().min(0).nullable(),perMonthMinWorkTime:r.number().nullable(),perMonthMinWorkTimeUnit:r.union([r.string(),r.number()]).nullable(),attendanceRequirement:u.optional(),availableSlots:r.array(c),benefits:l,hiringRequirements:d.optional()}),p=r.object({id:r.string(),brandId:r.string(),name:r.string(),city:r.string().optional(),location:r.string(),district:r.string().nullable(),subarea:r.string().nullable(),coordinates:o,positions:r.array(m)}),g=r.object({defaultBrandId:r.string().optional(),syncedAt:r.string().optional(),source:r.string().optional()}),f=r.object({id:r.string(),name:r.string(),aliases:r.array(r.string()).optional(),stores:r.array(p)}),y=r.object({meta:g,brands:r.array(f)});import{existsSync as b,readFileSync as h,writeFileSync as N}from"node:fs";import{dirname as S,join as T}from"node:path";import{z as I}from"zod";var A=I.enum(["trust_building","private_channel","qualify_candidate","job_consultation","interview_scheduling","onboard_followup"]),_=I.enum(["public","private"]),E=I.enum(["minimal","focused"]),R=I.enum(["salary","schedule","location","policy","requirements","availability"]),O={trust_building:{description:"初次接触,建立信任并了解求职意向",transitionSignal:"候选人表达明确兴趣或开始询问具体岗位信息",applicableChannels:["public","private"]},private_channel:{description:"引导用户从公域平台(如BOSS直聘/鱼泡)转入微信私聊",transitionSignal:"候选人有继续深入了解的意愿,适合引导到私域",applicableChannels:["public"]},qualify_candidate:{description:"轻量确认候选人的关键匹配信息,避免审查式盘问",transitionSignal:"候选人表达求职意向后,需要核实基本资格",applicableChannels:["public","private"]},job_consultation:{description:"回答岗位相关问题(薪资、排班、地点等)并提升兴趣",transitionSignal:"候选人主动询问岗位细节",applicableChannels:["public","private"]},interview_scheduling:{description:"推动面试预约,确认时间和到店安排",transitionSignal:"候选人核心问题已解答,准备推进面试",applicableChannels:["public","private"]},onboard_followup:{description:"促进到岗并保持回访",transitionSignal:"候选人确认上岗安排",applicableChannels:["public","private"]}},L=I.enum(["stores","location","salary","schedule","policy","availability","requirements","interview","wechat","none"]),k=I.enum(["insurance_promise_risk","age_sensitive","confrontation_emotion","urgency_high","qualification_mismatch"]),M={stores:["location"],location:["location"],salary:["salary"],schedule:["schedule"],policy:["policy"],availability:["availability"],requirements:["requirements"],interview:[],wechat:[],none:[]},v=I.object({mentionedBrand:I.string().nullable(),city:I.string().nullable(),mentionedLocations:I.array(I.object({location:I.string(),confidence:I.number().min(0).max(1)})).nullable(),mentionedDistricts:I.array(I.object({district:I.string(),confidence:I.number().min(0).max(1)})).max(10).nullable(),specificAge:I.number().nullable(),hasUrgency:I.boolean().nullable(),preferredSchedule:I.string().nullable()}),w=I.object({stage:A,subGoals:I.array(I.string()).max(2),needs:I.array(L).max(8),primaryNeed:L,riskFlags:I.array(k).max(6),confidence:I.number().min(0).max(1),extractedInfo:v,reasoningText:I.string()}),D=I.object({description:I.string().optional(),primaryGoal:I.string(),successCriteria:I.array(I.string()),ctaStrategy:I.preprocess(e=>Array.isArray(e)?e.join("\n"):e,I.string()),disallowedActions:I.array(I.string()).optional()}),C=I.object({tone:I.string(),warmth:I.string(),humor:I.string(),length:I.enum(["short","medium","long"]),questionStyle:I.string(),empathyStrategy:I.string(),addressStyle:I.string(),professionalIdentity:I.string(),companyBackground:I.string()}),U=I.object({name:I.string(),industryBackground:I.string(),jargon:I.array(I.string()),styleKeywords:I.array(I.string()),tabooPhrases:I.array(I.string()),guidance:I.array(I.string())}),x=I.object({id:I.string(),rule:I.string(),severity:I.enum(["high","medium","low"])}),$=I.object({rules:I.array(x)}),j=I.object({mode:I.enum(["strict","balanced","open"]),verifiableClaimTypes:I.array(I.string()),fallbackBehavior:I.enum(["generic_answer","ask_followup","handoff"]),forbiddenWhenMissingFacts:I.array(I.string())}),W={maxQuestionsByMode:{minimal:1,focused:2},blockedAuditPhrases:["是否满足","是否符合","基本入职要求","先确认资格","年龄是否符合"],blockFirstTurnSpecificFacts:!0},F=I.object({maxQuestionsByMode:I.object({minimal:I.number().int().min(0),focused:I.number().int().min(0)}),blockedAuditPhrases:I.array(I.string()),blockFirstTurnSpecificFacts:I.boolean()}),P=I.object({enabled:I.boolean().default(!0),revealRange:I.boolean().default(!1),failStrategy:I.string().default("礼貌说明不匹配,避免承诺"),unknownStrategy:I.string().default("先核实年龄或资格条件"),passStrategy:I.string().default("确认匹配后推进下一步"),allowRedirect:I.boolean().default(!0),redirectPriority:I.enum(["low","medium","high"]).default("medium")}),B=I.object({age:P.default({enabled:!0,revealRange:!1,failStrategy:"礼貌说明不匹配,避免承诺",unknownStrategy:"先核实年龄或资格条件",passStrategy:"确认匹配后推进下一步",allowRedirect:!0,redirectPriority:"medium"})}).default({age:{enabled:!0,revealRange:!1,failStrategy:"礼貌说明不匹配,避免承诺",unknownStrategy:"先核实年龄或资格条件",passStrategy:"确认匹配后推进下一步",allowRedirect:!0,redirectPriority:"medium"}}),G=I.object({trust_building:D,private_channel:D.optional(),qualify_candidate:D,job_consultation:D,interview_scheduling:D,onboard_followup:D}).transform(e=>({...e,private_channel:e.private_channel??e.trust_building})),q=I.object({stageGoals:G,persona:C,industryVoices:I.record(I.string(),U),defaultIndustryVoiceId:I.string(),hardConstraints:$,factGate:j,qualificationPolicy:B,outputGuards:F.default(W)}),H={stageGoals:{trust_building:{description:"初次接触,建立信任并了解求职意向",primaryGoal:"建立信任并了解求职意向",successCriteria:["候选人愿意继续沟通"],ctaStrategy:"用轻量提问引导需求细化",disallowedActions:["过早承诺具体待遇"]},private_channel:{description:"引导用户从公域平台(如BOSS直聘/鱼泡)转入微信私聊",primaryGoal:"推动进入私域沟通",successCriteria:["候选人愿意交换联系方式"],ctaStrategy:"说明后续沟通效率与资料同步价值",disallowedActions:["强迫式要微信"]},qualify_candidate:{description:"轻量确认候选人的关键匹配信息,避免审查式盘问",primaryGoal:"确认一个关键匹配信息并保持继续沟通意愿",successCriteria:["明确一个关键匹配信息","候选人愿意继续沟通"],ctaStrategy:"先回应关切,再顺带确认一个最关键条件",disallowedActions:["连续盘问多个资格条件","直接否定候选人"]},job_consultation:{description:"回答岗位相关问题(薪资、排班、地点等)并提升兴趣",primaryGoal:"回答岗位问题并提升兴趣",successCriteria:["候选人对岗位保持兴趣"],ctaStrategy:"先答核心问题,再给下一步建议",disallowedActions:["编造数字或政策"]},interview_scheduling:{description:"推动面试预约,确认时间和到店安排",primaryGoal:"推动面试预约",successCriteria:["候选人给出可面试时间"],ctaStrategy:"给出明确时间选项并确认",disallowedActions:["不确认候选人可到店性"]},onboard_followup:{description:"促进到岗并保持回访",primaryGoal:"促进到岗并保持回访",successCriteria:["候选人确认上岗安排"],ctaStrategy:"明确下一步动作与提醒",disallowedActions:["承诺不确定资源"]}},persona:{tone:"口语化",warmth:"高",humor:"低",length:"short",questionStyle:"单轮一个关键问题",empathyStrategy:"先认可关切再给建议",addressStyle:"使用你",professionalIdentity:"资深招聘专员",companyBackground:"连锁餐饮招聘"},industryVoices:{default:{name:"餐饮连锁招聘",industryBackground:"门店密集、排班灵活、强调稳定出勤",jargon:["排班","到岗","门店","班次"],styleKeywords:["直接","清晰","可信"],tabooPhrases:["包过","绝对","随便都行"],guidance:["先解决顾虑,再推动下一步"]}},defaultIndustryVoiceId:"default",hardConstraints:{rules:[{id:"no-fabrication",rule:"不得编造门店、薪资、排班、福利等事实信息",severity:"high"},{id:"no-insurance-promise",rule:"兼职场景不得承诺五险一金",severity:"high"},{id:"age-sensitive",rule:"年龄敏感问题使用合规话术,不暴露内部筛选线",severity:"high"}]},factGate:{mode:"strict",verifiableClaimTypes:["salary","location","schedule","policy","availability"],fallbackBehavior:"generic_answer",forbiddenWhenMissingFacts:["具体数字","具体门店承诺","明确福利承诺"]},qualificationPolicy:{age:{enabled:!0,revealRange:!1,failStrategy:"礼貌说明不匹配,避免承诺",unknownStrategy:"先核实年龄或资格条件",passStrategy:"确认匹配后推进下一步",allowRedirect:!0,redirectPriority:"medium"}},outputGuards:W};function K(e){let n=e;for(;;){if(b(T(n,"package.json")))return n;const t=S(n);if(t===n)throw new Error(`Could not locate package root from ${e}`);n=t}}var V=T(K(import.meta.dirname),"data"),Y=T(V,"brand-config.json"),z=T(V,"reply-policy.json"),J=3e5,Q=null,Z=null;function X(e){return Date.now()-e<J}function ee(){if(Q&&X(Q.loadedAt))return Q.data;const e=h(Y,"utf-8"),n=y.parse(JSON.parse(e));return Q={data:n,loadedAt:Date.now()},n}function ne(e){N(Y,JSON.stringify(e,null,2),"utf-8"),Q={data:e,loadedAt:Date.now()}}function te(){if(Z&&X(Z.loadedAt))return Z.data;try{const e=h(z,"utf-8"),n=q.parse(JSON.parse(e));return Z={data:n,loadedAt:Date.now()},n}catch{return H}}import{createAnthropic as re}from"@ai-sdk/anthropic";import{createAlibaba as ae}from"@ai-sdk/alibaba";import{createProviderRegistry as oe}from"ai";import{createOpenAICompatible as ie}from"@ai-sdk/openai-compatible";import{createDeepSeek as se}from"@ai-sdk/deepseek";import{createGoogleGenerativeAI as le}from"@ai-sdk/google";import{createOpenAI as ue}from"@ai-sdk/openai";var ce=!1;function de(e){ce=e}function me(...e){ce||console.error(...e)}var pe=process.env.SMART_REPLY_PROXY_BASE_URL,ge="https://apic1.ohmycdn.com/v1",fe=pe||ge,ye={anthropic:process.env.ANTHROPIC_BASE_URL||fe,openai:process.env.OPENAI_BASE_URL||fe,ohmygpt:process.env.OHMYGPT_BASE_URL||fe,moonshotai:process.env.MOONSHOT_BASE_URL||"https://api.moonshot.cn/v1",deepseek:process.env.DEEPSEEK_BASE_URL||"https://api.deepseek.com",qwen:process.env.QWEN_BASE_URL||"https://dashscope.aliyuncs.com/compatible-mode/v1",google:process.env.GOOGLE_BASE_URL||"https://generativelanguage.googleapis.com/v1beta"},be={anthropic:{name:"Anthropic",baseURL:ye.anthropic,description:"Anthropic Claude"},openai:{name:"OpenAI",baseURL:ye.openai,description:"OpenAI GPT"},ohmygpt:{name:"OhMyGPT",baseURL:ye.ohmygpt,description:"OhMyGPT"},moonshotai:{name:"MoonshotAI",baseURL:ye.moonshotai,description:"MoonshotAI"},deepseek:{name:"DeepSeek",baseURL:ye.deepseek,description:"DeepSeek"},qwen:{name:"Qwen",baseURL:ye.qwen,description:"Qwen"},google:{name:"Google",baseURL:ye.google,description:"Google Gemini"}},he={chatModel:"anthropic/claude-haiku-4-5",classifyModel:process.env.SMART_REPLY_CLASSIFY_MODEL||"openai/gpt-5-mini",replyModel:process.env.SMART_REPLY_REPLY_MODEL||"openai/gpt-5.4"};function Ne(){return process.env.ANTHROPIC_API_KEY||process.env.OPENAI_API_KEY||""}function Se(e){const n=ue({apiKey:e.apiKey||"",...void 0!==e.baseURL?{baseURL:e.baseURL}:{}});return new Proxy(n,{get(e,t){if("languageModel"===t)return e=>n.chat(e);if("chat"===t||"completion"===t)return n[t];if("embeddingModel"===t||"imageModel"===t){return n[t]||void 0}return n[t]}})}function Te(e){const n=Ne();return oe({anthropic:re({apiKey:n,baseURL:e.anthropic?.baseURL||ye.anthropic}),openai:Se({apiKey:n,baseURL:e.openai?.baseURL||ye.openai}),ohmygpt:ie({name:"ohmygpt",baseURL:e.ohmygpt?.baseURL||ye.ohmygpt,apiKey:n}),moonshotai:ie({name:"moonshotai",baseURL:e.moonshotai?.baseURL||ye.moonshotai,apiKey:process.env.MOONSHOT_API_KEY||""}),deepseek:se({baseURL:e.deepseek?.baseURL||ye.deepseek,apiKey:process.env.DEEPSEEK_API_KEY||""}),google:le({apiKey:process.env.GEMINI_API_KEY||"",baseURL:e.google?.baseURL||ye.google}),qwen:ae({apiKey:process.env.DASHSCOPE_API_KEY||process.env.ALIBABA_API_KEY||"",baseURL:e.qwen?.baseURL||ye.qwen})},{separator:"/"})}var Ie=null,Ae=null;function _e(e){const n=JSON.stringify(e);return Ie&&Ae===n||(Ie=Te(e),Ae=n,me("[DYNAMIC REGISTRY] 创建新的动态registry,配置哈希:",n.substring(0,16)+"...")),Ie}function Ee(e){return e.brands.flatMap(e=>e.stores)}function Re(e){return e.brands.map(e=>e.name)}function Oe(e,n){if(n)return e.brands.find(e=>e.name===n)}function Le(e){if(e.meta.defaultBrandId){const n=e.brands.find(n=>n.id===e.meta.defaultBrandId);if(n)return n}return e.brands[0]}function ke(e){return Le(e)?.name??""}function Me(e,n){const t=n?Oe(e,n)?.stores??[]:Ee(e);return t.find(e=>"string"==typeof e.city&&e.city.trim().length>0)?.city}import{z as ve}from"zod";import{setTimeout as we,clearTimeout as De}from"node:timers";import{performance as Ce}from"node:perf_hooks";import{asSchema as Ue,generateText as xe,jsonSchema as $e,NoObjectGeneratedError as je,Output as We}from"ai";import"zod";var Fe={CONFIG:"CONFIG",AUTH:"AUTH",NETWORK:"NETWORK",LLM:"LLM",VALIDATION:"VALIDATION",BUSINESS:"BUSINESS",SYSTEM:"SYSTEM"},Pe={LLM_UNAUTHORIZED:"LLM_UNAUTHORIZED",LLM_MODEL_NOT_FOUND:"LLM_MODEL_NOT_FOUND",LLM_RATE_LIMITED:"LLM_RATE_LIMITED",LLM_TIMEOUT:"LLM_TIMEOUT",LLM_GENERATION_FAILED:"LLM_GENERATION_FAILED",LLM_RESPONSE_PARSE_ERROR:"LLM_RESPONSE_PARSE_ERROR",CONFIG_NOT_FOUND:"CONFIG_NOT_FOUND",CONFIG_INVALID:"CONFIG_INVALID",CONFIG_MISSING_FIELD:"CONFIG_MISSING_FIELD",CONFIG_LOAD_FAILED:"CONFIG_LOAD_FAILED",NETWORK_TIMEOUT:"NETWORK_TIMEOUT",NETWORK_CONNECTION_FAILED:"NETWORK_CONNECTION_FAILED",NETWORK_HTTP_ERROR:"NETWORK_HTTP_ERROR",NETWORK_DNS_FAILED:"NETWORK_DNS_FAILED",AUTH_UNAUTHORIZED:"AUTH_UNAUTHORIZED",AUTH_FORBIDDEN:"AUTH_FORBIDDEN",AUTH_TOKEN_EXPIRED:"AUTH_TOKEN_EXPIRED",AUTH_TOKEN_INVALID:"AUTH_TOKEN_INVALID",VALIDATION_INVALID_INPUT:"VALIDATION_INVALID_INPUT",VALIDATION_MISSING_REQUIRED:"VALIDATION_MISSING_REQUIRED",VALIDATION_FORMAT_ERROR:"VALIDATION_FORMAT_ERROR",VALIDATION_SCHEMA_ERROR:"VALIDATION_SCHEMA_ERROR",BUSINESS_RULE_VIOLATION:"BUSINESS_RULE_VIOLATION",BUSINESS_RESOURCE_NOT_FOUND:"BUSINESS_RESOURCE_NOT_FOUND",BUSINESS_RESOURCE_EXISTS:"BUSINESS_RESOURCE_EXISTS",BUSINESS_OPERATION_NOT_ALLOWED:"BUSINESS_OPERATION_NOT_ALLOWED",SYSTEM_INTERNAL:"SYSTEM_INTERNAL",SYSTEM_DEPENDENCY_FAILED:"SYSTEM_DEPENDENCY_FAILED",SYSTEM_RESOURCE_UNAVAILABLE:"SYSTEM_RESOURCE_UNAVAILABLE",SYSTEM_UNKNOWN:"SYSTEM_UNKNOWN"},Be={[Pe.LLM_UNAUTHORIZED]:Fe.LLM,[Pe.LLM_MODEL_NOT_FOUND]:Fe.LLM,[Pe.LLM_RATE_LIMITED]:Fe.LLM,[Pe.LLM_TIMEOUT]:Fe.LLM,[Pe.LLM_GENERATION_FAILED]:Fe.LLM,[Pe.LLM_RESPONSE_PARSE_ERROR]:Fe.LLM,[Pe.CONFIG_NOT_FOUND]:Fe.CONFIG,[Pe.CONFIG_INVALID]:Fe.CONFIG,[Pe.CONFIG_MISSING_FIELD]:Fe.CONFIG,[Pe.CONFIG_LOAD_FAILED]:Fe.CONFIG,[Pe.NETWORK_TIMEOUT]:Fe.NETWORK,[Pe.NETWORK_CONNECTION_FAILED]:Fe.NETWORK,[Pe.NETWORK_HTTP_ERROR]:Fe.NETWORK,[Pe.NETWORK_DNS_FAILED]:Fe.NETWORK,[Pe.AUTH_UNAUTHORIZED]:Fe.AUTH,[Pe.AUTH_FORBIDDEN]:Fe.AUTH,[Pe.AUTH_TOKEN_EXPIRED]:Fe.AUTH,[Pe.AUTH_TOKEN_INVALID]:Fe.AUTH,[Pe.VALIDATION_INVALID_INPUT]:Fe.VALIDATION,[Pe.VALIDATION_MISSING_REQUIRED]:Fe.VALIDATION,[Pe.VALIDATION_FORMAT_ERROR]:Fe.VALIDATION,[Pe.VALIDATION_SCHEMA_ERROR]:Fe.VALIDATION,[Pe.BUSINESS_RULE_VIOLATION]:Fe.BUSINESS,[Pe.BUSINESS_RESOURCE_NOT_FOUND]:Fe.BUSINESS,[Pe.BUSINESS_RESOURCE_EXISTS]:Fe.BUSINESS,[Pe.BUSINESS_OPERATION_NOT_ALLOWED]:Fe.BUSINESS,[Pe.SYSTEM_INTERNAL]:Fe.SYSTEM,[Pe.SYSTEM_DEPENDENCY_FAILED]:Fe.SYSTEM,[Pe.SYSTEM_RESOURCE_UNAVAILABLE]:Fe.SYSTEM,[Pe.SYSTEM_UNKNOWN]:Fe.SYSTEM},Ge={[Pe.LLM_UNAUTHORIZED]:"AI 服务认证失败,请检查配置",[Pe.LLM_MODEL_NOT_FOUND]:"所选模型暂时不可用,请尝试其他模型",[Pe.LLM_RATE_LIMITED]:"请求过于频繁,请稍后重试",[Pe.LLM_TIMEOUT]:"AI 响应超时,请稍后重试",[Pe.LLM_GENERATION_FAILED]:"内容生成失败,请稍后重试",[Pe.LLM_RESPONSE_PARSE_ERROR]:"AI 响应格式异常,请重试",[Pe.CONFIG_NOT_FOUND]:"配置数据未找到,请先进行初始化",[Pe.CONFIG_INVALID]:"配置格式无效,请检查配置",[Pe.CONFIG_MISSING_FIELD]:"配置缺少必需字段",[Pe.CONFIG_LOAD_FAILED]:"配置加载失败,请重试",[Pe.NETWORK_TIMEOUT]:"网络请求超时,请检查网络连接",[Pe.NETWORK_CONNECTION_FAILED]:"网络连接失败,请检查网络",[Pe.NETWORK_HTTP_ERROR]:"服务器返回错误,请稍后重试",[Pe.NETWORK_DNS_FAILED]:"域名解析失败,请检查网络",[Pe.AUTH_UNAUTHORIZED]:"请先登录",[Pe.AUTH_FORBIDDEN]:"您没有权限执行此操作",[Pe.AUTH_TOKEN_EXPIRED]:"登录已过期,请重新登录",[Pe.AUTH_TOKEN_INVALID]:"认证信息无效,请重新登录",[Pe.VALIDATION_INVALID_INPUT]:"输入参数无效",[Pe.VALIDATION_MISSING_REQUIRED]:"缺少必需参数",[Pe.VALIDATION_FORMAT_ERROR]:"数据格式错误",[Pe.VALIDATION_SCHEMA_ERROR]:"数据验证失败",[Pe.BUSINESS_RULE_VIOLATION]:"操作违反业务规则",[Pe.BUSINESS_RESOURCE_NOT_FOUND]:"请求的资源不存在",[Pe.BUSINESS_RESOURCE_EXISTS]:"资源已存在",[Pe.BUSINESS_OPERATION_NOT_ALLOWED]:"当前操作不被允许",[Pe.SYSTEM_INTERNAL]:"系统内部错误,请稍后重试",[Pe.SYSTEM_DEPENDENCY_FAILED]:"依赖服务异常,请稍后重试",[Pe.SYSTEM_RESOURCE_UNAVAILABLE]:"系统资源不可用,请稍后重试",[Pe.SYSTEM_UNKNOWN]:"发生未知错误,请稍后重试"};function qe(e){return Be[e]}function He(e){return Ge[e]}var Ke=class _AppError extends Error{code;category;userMessage;details;cause;timestamp;constructor(e){super(e.message),this.name="AppError",this.code=e.code,this.category=qe(e.code),this.userMessage=e.userMessage||He(e.code),this.details=e.details,this.cause=e.cause,this.timestamp=(new Date).toISOString(),Error.captureStackTrace&&Error.captureStackTrace(this,_AppError)}toJSON(){const e={code:this.code,category:this.category,message:this.message,userMessage:this.userMessage,timestamp:this.timestamp};return void 0!==this.details&&(e.details=this.details),this.cause&&(this.cause instanceof _AppError?e.cause=this.cause.toJSON():e.cause={message:this.cause.message,stack:this.cause.stack}),e}getErrorChain(){const e=[this];let n=this.cause;for(;n;)e.push(n),n=n instanceof _AppError?n.cause:void 0;return e}getRootCause(){const e=this.getErrorChain();return e[e.length-1]}hasErrorCode(e){return this.getErrorChain().some(n=>n instanceof _AppError&&n.code===e)}hasErrorCategory(e){return this.getErrorChain().some(n=>n instanceof _AppError&&n.category===e)}toLogString(){const e=[`[${this.code}]`,this.message];return this.details&&e.push(`Details: ${JSON.stringify(this.details)}`),this.cause&&e.push(`Caused by: ${this.cause.message}`),e.join(" | ")}};function Ve(e){return e instanceof Ke}function Ye(e,n,t){const r=t?.model?` (model: ${t.model})`:"",a=t?.provider?` [${t.provider}]`:"",o={[Pe.LLM_UNAUTHORIZED]:`LLM API authentication failed${a}${r}`,[Pe.LLM_MODEL_NOT_FOUND]:`Model not found or unavailable${r}${a}`,[Pe.LLM_RATE_LIMITED]:`LLM API rate limited${a}`,[Pe.LLM_TIMEOUT]:`LLM API request timeout${a}${r}`,[Pe.LLM_GENERATION_FAILED]:`LLM generation failed${a}${r}`,[Pe.LLM_RESPONSE_PARSE_ERROR]:`Failed to parse LLM response${a}`};return new Ke({code:e,message:o[e]||`LLM error: ${n.message}`,cause:n,details:t})}function ze(e,n,t){const r=t?.url?` (${t.url})`:"",a=t?.statusCode?` [${t.statusCode}]`:"",o={[Pe.NETWORK_TIMEOUT]:`Network request timeout${r}`,[Pe.NETWORK_CONNECTION_FAILED]:`Failed to connect${r}`,[Pe.NETWORK_HTTP_ERROR]:`HTTP error${a}${r}`,[Pe.NETWORK_DNS_FAILED]:`DNS resolution failed${r}`};return new Ke({code:e,message:o[e]||`Network error: ${n.message}`,cause:n,details:t})}function Je(e,n,t){const r=t.isMarkdownFormat?" (detected markdown format)":"",a=t.schemaName?` for schema "${t.schemaName}"`:"";return new Ke({code:e,message:`Failed to parse structured output${a}${r}`,cause:n,details:{rawText:t.rawText,isMarkdownFormat:t.isMarkdownFormat,parseErrorMessage:t.parseErrorMessage,model:t.model,provider:t.provider,schemaName:t.schemaName,usage:t.usage}})}import{NoObjectGeneratedError as Qe}from"ai";function Ze(e){if(!e||"object"!=typeof e)return null;const n=e;if(!("AI_APICallError"===n.name||"APICallError"===n.name||"string"==typeof n.url&&"number"==typeof n.statusCode))return null;const t="number"==typeof n.statusCode?n.statusCode:void 0,r="string"==typeof n.responseBody?n.responseBody:void 0,a="string"==typeof n.url?n.url:void 0,o=n.message;let i,s;if(a&&(a.includes("openai.com")?i="openai":a.includes("anthropic.com")?i="anthropic":a.includes("dashscope.aliyuncs.com")?i="qwen":a.includes("openrouter.ai")?i="openrouter":a.includes("deepseek.com")?i="deepseek":a.includes("moonshot.cn")?i="moonshotai":a.includes("googleapis.com")&&(i="google")),r){const e=r.match(/model[`'":\s]+([^`'"}\s,]+)/i);e&&(s=e[1])}return{isAuthError:401===t||403===t,isModelNotFound:r?.includes("model")&&r?.includes("not exist")||r?.includes("not authorized to access this model")||!1,isRateLimited:429===t,isTimeout:408===t||504===t||o?.toLowerCase().includes("timeout")||!1,statusCode:t,provider:i,model:s,originalMessage:o,responseBody:r}}function Xe(e){return[/^```/m,/^#{1,6}\s/m,/^\s*[-*+]\s/m,/^\s*\d+\.\s/m,/\[.+\]\(.+\)/,/^\s*>/m].some(n=>n.test(e))}function en(e){try{if(void 0===Qe||"function"!=typeof Qe.isInstance)return null;if(!Qe.isInstance(e))return null}catch{return null}const n=e.text,t=!!n&&Xe(n),r=e.response?{id:e.response.id,timestamp:e.response.timestamp,modelId:e.response.modelId}:void 0,a=e.usage??void 0,o={isNoObjectGeneratedError:!0,isMarkdownFormat:t};return void 0!==n&&(o.rawText=n),e.cause instanceof Error&&(o.cause=e.cause),void 0!==r&&(o.response=r),void 0!==a&&(o.usage=a),o}function nn(e,n=Pe.SYSTEM_UNKNOWN,t){if(Ve(e))return t&&t!==e.userMessage?new Ke({code:e.code,message:e.message,userMessage:t,cause:e.cause,details:e.details}):e;const r=tn(e),a=Ze(e);if(a){const e={model:a.model,provider:a.provider,statusCode:a.statusCode,responseBody:a.responseBody};return a.isModelNotFound?Ye(Pe.LLM_MODEL_NOT_FOUND,r,e):a.isAuthError?Ye(Pe.LLM_UNAUTHORIZED,r,e):a.isRateLimited?Ye(Pe.LLM_RATE_LIMITED,r,e):a.isTimeout?Ye(Pe.LLM_TIMEOUT,r,e):Ye(Pe.LLM_GENERATION_FAILED,r,e)}const o=en(e);if(o)return Je(Pe.LLM_RESPONSE_PARSE_ERROR,r,{rawText:o.rawText,isMarkdownFormat:o.isMarkdownFormat,parseErrorMessage:o.cause?.message,usage:o.usage});const i=r.message.toLowerCase();return i.includes("timeout")||i.includes("econnrefused")||i.includes("network")||i.includes("fetch failed")?i.includes("timeout")?ze(Pe.NETWORK_TIMEOUT,r):ze(Pe.NETWORK_CONNECTION_FAILED,r):new Ke({code:n,message:r.message,cause:r})}function tn(e){if(e instanceof Error)return e;if("string"==typeof e)return new Error(e);if("object"==typeof e&&null!==e){const n=e.message||e.error||JSON.stringify(e);return new Error(String(n))}return new Error(String(e))}function rn(e,n){console.error(`[${n.code}] ${e}:`,n.toLogString()),n.cause&&console.error("Original error:",n.cause)}function an(e){return"object"==typeof e&&null!==e}function on(e,n){n&&an(e.details)&&(e.details.schemaName=n)}function sn(e){const n=e.type;return"string"==typeof n?[n]:Array.isArray(n)?n.filter(e=>"string"==typeof e):[]}function ln(e,n){let t=null;for(const r of e){const e=n.get(r);if(void 0!==e&&e.size>0){t??=new Set;for(const n of e)t.add(n)}}return t}function un(e,n){if(Array.isArray(e))return e.map(e=>un(e,n));if(null===e||"object"!=typeof e)return e;const t=e,r=ln(sn(t),n),a={};for(const[e,o]of Object.entries(t))null!==r&&r.has(e)||(a[e]=un(o,n));return a}function cn(e){const n=e.unsupportedKeywordsByType;if(void 0===n)return new Map;const t=new Map;for(const[e,r]of Object.entries(n)){if(0===r.length)continue;const n=t.get(e);if(void 0!==n)for(const e of r)n.add(e);else t.set(e,new Set(r))}const r=t.get("number");if(void 0!==r&&r.size>0){const e=t.get("integer");if(void 0!==e)for(const n of r)e.add(n);else t.set("integer",new Set(r))}return t}function dn(e,n={}){const t=cn(n);if(0===t.size)return e;const r=Ue(e);return $e(async()=>un(await r.jsonSchema,t),{validate:e=>({success:!0,value:e})})}async function mn(e){const{model:n,schema:t,outputSchema:r,schemaName:a,system:o,prompt:i,transformOutput:s,onError:l}=e;try{const e=await xe({model:n,...void 0!==o?{system:o}:{},prompt:i,output:We.object({schema:r??t,...void 0!==a?{name:a}:{}})});if(void 0===r&&void 0===s)return{success:!0,data:e.output,usage:e.usage};const u=void 0!==s?await s(e.output):e.output,c=await t.safeParseAsync(u);if(!c.success){const n=nn(c.error,Pe.LLM_RESPONSE_PARSE_ERROR);return on(n,a),rn(`Structured output validation (${a||"unknown"})`,n),l&&l(n,e.text),{success:!1,error:n,rawText:e.text}}return{success:!0,data:c.data,usage:e.usage}}catch(e){const n=nn(e,Pe.LLM_RESPONSE_PARSE_ERROR);let t;return je.isInstance(e)&&(t=e.text),on(n,a),rn(`Structured output generation (${a||"unknown"})`,n),l&&l(n,t),{success:!1,error:n,rawText:t}}}var pn=3e4,gn=2e3;async function fn(e){const{model:n,system:t,prompt:r,timeoutMs:a=pn,maxOutputTokens:o=gn,context:i="generateText",onError:s}=e,l=Ce.now();try{const e=new AbortController,s=we(()=>e.abort(),a),u=await xe({model:n,...void 0!==t?{system:t}:{},prompt:r,maxOutputTokens:o,abortSignal:e.signal});De(s);const c=Math.round(Ce.now()-l),d=u.usage,m=void 0!==d?.inputTokens&&void 0!==d?.outputTokens?d.inputTokens+d.outputTokens:void 0,p={inputTokens:d?.inputTokens,outputTokens:d?.outputTokens,totalTokens:m};return me(`[${i}] 生成成功 | 耗时: ${c}ms | Tokens: ${m??"N/A"} (input: ${p.inputTokens??"?"}, output: ${p.outputTokens??"?"})`),{success:!0,text:u.text,usage:p,latencyMs:c}}catch(e){const n=Math.round(Ce.now()-l),t=e instanceof Error&&("AbortError"===e.name||e.message.includes("aborted")),r=nn(e,t?Pe.LLM_TIMEOUT:Pe.LLM_GENERATION_FAILED);return an(r.details)&&(r.details.context=i,r.details.latencyMs=n),rn(`${i} (${n}ms)`,r),s&&s(r),{success:!1,error:r}}}import{z as yn}from"zod";var bn=yn.object({name:yn.string(),baseURL:yn.string(),description:yn.string()}),hn=yn.record(yn.string(),bn),Nn=yn.object({chatModel:yn.string().optional(),classifyModel:yn.string().optional(),replyModel:yn.string().optional(),providerConfigs:hn.optional()}),Sn=yn.object({city:yn.string().optional(),defaultBrand:yn.string(),availableBrands:yn.array(yn.string()),storeCount:yn.number()}),Tn=yn.object({modelConfig:Nn,candidateMessage:yn.string(),conversationHistory:yn.array(yn.string()).default([]),brandData:Sn.optional(),channelType:_.optional()});function In(e){const n=_.safeParse(e);return n.success?n.data:"public"}function An(e="public"){const n=In(e),t=A.options.filter(e=>O[e].applicableChannels.includes(n));return t.length>0?t:[...A.options]}function _n(e){return ve.object({stage:ve.enum(e),subGoals:w.shape.subGoals,needs:w.shape.needs,primaryNeed:w.shape.primaryNeed,riskFlags:w.shape.riskFlags,confidence:w.shape.confidence,extractedInfo:w.shape.extractedInfo,reasoningText:w.shape.reasoningText})}var En={subGoals:2,needs:8,riskFlags:6,mentionedDistricts:10};function Rn(e){return e.startsWith("anthropic/")}function On(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function Ln(e){if(!On(e))return e;const n={...e};if(Array.isArray(n.subGoals)&&(n.subGoals=n.subGoals.slice(0,En.subGoals)),Array.isArray(n.needs)&&(n.needs=n.needs.slice(0,En.needs)),Array.isArray(n.riskFlags)&&(n.riskFlags=n.riskFlags.slice(0,En.riskFlags)),On(n.extractedInfo)){const e={...n.extractedInfo};Array.isArray(e.mentionedDistricts)&&(e.mentionedDistricts=e.mentionedDistricts.slice(0,En.mentionedDistricts)),n.extractedInfo=e}return n}var kn=[{need:"salary",patterns:[/薪资|工资|时薪|底薪|提成|奖金|补贴|多少钱|收入/i]},{need:"schedule",patterns:[/排班|班次|几点|上班|下班|工时|周末|节假日|做几天/i]},{need:"policy",patterns:[/五险一金|社保|保险|合同|考勤|迟到|补班|试用期/i]},{need:"availability",patterns:[/还有名额|空位|可用时段|什么时候能上|明天能面/i]},{need:"location",patterns:[/在哪|位置|地址|附近|地铁|门店|哪个区|多远/i]},{need:"stores",patterns:[/门店|哪家店|哪些店|有店吗/i]},{need:"requirements",patterns:[/要求|条件|年龄|经验|学历|健康证|身高|体重/i]},{need:"interview",patterns:[/面试|到店|约时间|约面/i]},{need:"wechat",patterns:[/微信|vx|私聊|联系方式|加你/i]}],Mn=["salary","schedule","location","stores","policy","requirements","availability","interview","wechat","none"];function vn(e){const n=new Set;for(const t of kn)t.patterns.some(n=>n.test(e))&&n.add(t.need);return 0===n.size?n.add("none"):n.delete("none"),n}function wn(e,n){return vn(`${n.slice(-4).join(" ")} ${e}`)}function Dn(e){return vn(e)}function Cn(e,n,t,r=1){const a=new Set(n);a.size>1&&a.has("none")&&a.delete("none");const o=Dn(t);o.delete("none");const i=[];"none"!==e&&a.has(e)&&i.push(e);for(const n of Mn){if(i.length>=r)break;"none"!==n&&n!==e&&(o.has(n)&&a.has(n)&&i.push(n))}return i.length>0?i:"none"===e?["none"]:a.has(e)?[e]:["none"]}function Un(e,n,t){const r=new Set(n);if(r.size>1&&r.has("none")&&r.delete("none"),e&&r.has(e))return e;const a=Dn(t);a.delete("none");for(const e of Mn)if(a.has(e)&&r.has(e))return e;for(const e of Mn)if(r.has(e))return e;return"none"}function xn(e,n,t){const r=new Set([...e.needs,...Array.from(n)]);return r.size>1&&r.has("none")&&r.delete("none"),{...e,subGoals:e.subGoals.slice(0,2),needs:Array.from(r),primaryNeed:Un(e.primaryNeed,r,t),confidence:Number.isFinite(e.confidence)?Math.max(0,Math.min(1,e.confidence)):.5}}function $n(e,n,t,r="public",a,o){const i=["你是招聘对话回合规划器,不直接回复候选人。","你只输出结构化规划结果,用于后续回复生成。","规划目标:确定阶段目标(stage)、子目标(subGoals)、事实需求(needs)、主回答轴(primaryNeed)、风险标记(riskFlags)。"].join("\n"),s=In(r);return{system:i,prompt:["[阶段枚举与定义]",...An(s).map(e=>{const n=O[e];return`- ${e}: ${a?.stageGoals[e]?.description||n.description} (转入条件: ${n.transitionSignal})`}),"","[needs枚举]","private"===s?"- stores, location, salary, schedule, policy, availability, requirements, interview, none":"- stores, location, salary, schedule, policy, availability, requirements, interview, wechat, none","","[riskFlags枚举]","- insurance_promise_risk, age_sensitive, confrontation_emotion, urgency_high, qualification_mismatch","","[规则]","- 优先判断本轮主阶段(stage);subGoals 最多 2 项,只保留最关键的。","- 候选人追问事实时,必须打开对应 needs。","- primaryNeed 必须从 needs 中选择一个最主的 need;如果没有明确事实轴则填 none。","- 不确定时 confidence 降低,不要臆断。","- 根据转入条件判断阶段转化,不要停留在不匹配的阶段。",...o&&o.length>0?[`- 候选人资料中已有:${o.join("、")}。不要生成追问这些字段的 subGoal。`]:[],"","[品牌数据]",JSON.stringify(t||{}),"","[历史对话]",n.slice(-8).join("\n")||"无","","[候选人消息]",e].join("\n")}}async function jn(e,n){const{providerConfigs:t=be,modelConfig:r,conversationHistory:a=[],brandData:o,channelType:i,replyPolicy:s,knownCandidateFields:l}=n,u=_e(t),c=r?.classifyModel||he.classifyModel,d=In(i),m=_n(An(d)),p=Rn(c),g=$n(e,a,o,d,s,l),f=await mn({model:u.languageModel(c),schema:m,...p?{outputSchema:dn(m,{unsupportedKeywordsByType:{array:["maxItems","minItems"],number:["maximum","minimum","exclusiveMaximum","exclusiveMinimum"]}}),transformOutput:Ln}:{},schemaName:"TurnPlanningOutput",system:g.system,prompt:g.prompt}),y=wn(e,a),b=Un(void 0,y,e);return f.success?xn(f.data,y,e):{stage:"trust_building",subGoals:["保持对话并澄清需求"],needs:Array.from(y),primaryNeed:b,riskFlags:[],confidence:.35,extractedInfo:{mentionedBrand:null,city:o?.city||null,mentionedLocations:null,mentionedDistricts:null,specificAge:null,hasUrgency:null,preferredSchedule:null},reasoningText:"规划模型失败,使用规则降级策略"}}import{z as Wn}from"zod";var Fn=Wn.object({id:Wn.number(),name:Wn.string(),aliases:Wn.array(Wn.string()),projectIdList:Wn.array(Wn.number())}),Pn=Wn.object({code:Wn.number(),message:Wn.string().optional(),data:Wn.object({result:Wn.array(Fn),total:Wn.number()})}),Bn=3e5,Gn=null;function qn(){return null!==Gn&&Date.now()-Gn.timestamp<Bn}var Hn=3e4;function Kn(){const e=process.env.DULIDAY_BRAND_LIST_URL;return"string"==typeof e&&e.trim().length>0?e:void 0}async function Vn(e){const n=e||process.env.DULIDAY_TOKEN,t=Kn();if(!n)throw new Ke({code:Pe.CONFIG_MISSING_FIELD,message:"DULIDAY_TOKEN 未配置,无法获取品牌别名数据",userMessage:"品牌别名数据加载失败:缺少 Duliday Token 配置"});if(!t)throw new Ke({code:Pe.CONFIG_MISSING_FIELD,message:"DULIDAY_BRAND_LIST_URL 未配置,无法获取品牌别名数据",userMessage:"品牌别名数据加载失败:缺少 Duliday 品牌接口配置"});const r=new AbortController,a=setTimeout(()=>r.abort(),Hn);try{const e=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json","Duliday-Token":n},body:JSON.stringify({pageNum:1,pageSize:1e3}),signal:r.signal});if(!e.ok)throw new Ke({code:Pe.NETWORK_HTTP_ERROR,message:`Duliday 品牌列表 API 返回 HTTP ${e.status}: ${e.statusText}`,userMessage:`品牌别名数据加载失败:服务端返回 ${e.status}`});const a=await e.json(),o=Pn.safeParse(a);if(!o.success)throw new Ke({code:Pe.VALIDATION_SCHEMA_ERROR,message:`Duliday 品牌列表响应格式校验失败: ${o.error.message}`,userMessage:"品牌别名数据加载失败:响应格式异常"});return o.data.data.result}catch(e){if(e instanceof Ke)throw e;if(e instanceof Error&&"AbortError"===e.name)throw new Ke({code:Pe.NETWORK_TIMEOUT,message:`Duliday 品牌列表 API 请求超时 (${Hn}ms)`,userMessage:"品牌别名数据加载超时,请稍后重试",cause:e});throw new Ke({code:Pe.SYSTEM_DEPENDENCY_FAILED,message:`获取品牌别名数据失败: ${e instanceof Error?e.message:String(e)}`,userMessage:"品牌别名数据加载失败,请检查网络连接",...e instanceof Error?{cause:e}:{}})}finally{clearTimeout(a)}}function Yn(e,n,t){const r={},a=new Map,o=e=>e.trim(),i=(e,n)=>{const t=o(e).toLowerCase().replace(/[\s._-]+/g,"");if(!t)return;const r=a.get(t);(!r||n.length>r.length)&&a.set(t,n)},s=[...e].sort((e,n)=>n.name.length-e.name.length);for(const e of s){const n=o(e.name);if(!n)continue;const a=Array.from(new Set([n,...e.aliases.map(o).filter(Boolean)].filter(e=>e!==n)));a.unshift(n),r[n]=a;for(const e of a)i(e,n);if(t&&e.projectIdList.length>0)for(const o of e.projectIdList){const e=t[String(o)];if(!e||e===n)continue;if(!e.includes(n))continue;const s=e.replace(n,"");if(!s)continue;const l=[e];for(const e of a)e!==n&&l.push(`${s}${e}`);if(r[e]){const n=new Set(r[e]);for(const t of l)n.has(t)||r[e].push(t)}else r[e]=l;for(const n of l)i(n,e)}}for(const e of n)r[e]||(r[e]=[e],i(e,e));return{dictionary:r,aliasMap:a}}async function zn(e){if(qn())return;const n=await Vn(e),t=new Set,{dictionary:r,aliasMap:a}=Yn(n,t);Gn={aliasMap:a,dictionary:r,timestamp:Date.now()}}async function Jn(e){return await zn(e),Gn.aliasMap}function Qn(e){const{base:n,unit:t,range:r,memo:a}=e,o=a?.replace(/\n/g," ").trim()??"";if(null==n)return e.scenarioSummary&&o?`${o}(${e.scenarioSummary})`:e.scenarioSummary?e.scenarioSummary:o;let i="";return n<10&&a?i=`${n}${t??""}(${o})`:(i=`${n}${t??""}`,r&&r!==`${n}-${n}`&&r!==`${n}元-${n}元`&&(i+=`,范围${r}`),o&&o.length<50&&(i+=`(${o})`)),e.scenarioSummary&&(i+=`(${e.scenarioSummary})`),i}function Zn(e,n,t){if(!e)return null;const r=e=>e.toLowerCase().replace(/[\s._-]+/g,"");if(t){const a=t.get(r(e))||t.get(e.toLowerCase());if(a&&n.includes(a))return a}const a=e.toLowerCase(),o=r(e),i=n.find(e=>e.toLowerCase()===a);if(i)return i;const s=n.find(e=>r(e)===o);if(s)return s;const l=n.filter(e=>{const n=e.toLowerCase();if(n.includes(a)||a.includes(n))return!0;const t=r(e);return t.includes(o)||o.includes(t)});if(l.length>0)return l.sort((e,n)=>n.length-e.length)[0]??null;if(a.includes("山姆")||a.includes("sam")){const e=n.find(e=>{const n=e.toLowerCase();return n.includes("山姆")||n.includes("sam")});if(e)return e}return null}function Xn(e){const{uiSelectedBrand:n,configDefaultBrand:t,conversationBrand:r,availableBrands:a,strategy:o="smart",aliasMap:i}=e,s=(e,n)=>{if(e)return Zn(e,a,i)??void 0};switch(o){case"user-selected":{const e=s(n);if(e)return{resolvedBrand:e,matchType:e===n?"exact":"fuzzy",source:"ui",reason:"用户选择策略",originalInput:n};const r=s(t);return r?{resolvedBrand:r,matchType:r===t?"exact":"fuzzy",source:"config",reason:"配置默认",originalInput:t}:{resolvedBrand:a[0]??"",matchType:"fallback",source:"default",reason:"系统默认"}}case"conversation-extracted":{const e=s(r);if(e)return{resolvedBrand:e,matchType:e===r?"exact":"fuzzy",source:"conversation",reason:"对话提取",originalInput:r};const o=s(n);if(o)return{resolvedBrand:o,matchType:o===n?"exact":"fuzzy",source:"ui",reason:"UI选择",originalInput:n};const i=s(t);return i?{resolvedBrand:i,matchType:i===t?"exact":"fuzzy",source:"config",reason:"配置默认",originalInput:t}:{resolvedBrand:a[0]??"",matchType:"fallback",source:"default",reason:"系统默认"}}default:{const e=s(r),o=s(n);if(e)return{resolvedBrand:e,matchType:e===r?"exact":"fuzzy",source:"conversation",reason:"智能策略: 对话提取",originalInput:r};if(o)return{resolvedBrand:o,matchType:o===n?"exact":"fuzzy",source:"ui",reason:"智能策略: UI选择",originalInput:n};const i=s(t);return i?{resolvedBrand:i,matchType:i===t?"exact":"fuzzy",source:"config",reason:"智能策略: 配置默认",originalInput:t}:{resolvedBrand:a[0]??"",matchType:"fallback",source:"default",reason:"智能策略: 系统默认"}}}}function et(e,n){const{mentionedLocations:t,mentionedDistricts:r}=n;return e.map(e=>{let n=0,a=0,o=0,i=0;if(t&&t.length>0){const r=t.find(n=>e.name.includes(n.location)||e.location.includes(n.location)||(e.subarea??"").includes(n.location));r&&(n=40*r.confidence)}if(r&&r.length>0){const n=r.find(n=>(e.district??"").includes(n.district)||(e.subarea??"").includes(n.district));n&&(a=30*n.confidence)}const s=new Set(e.positions.map(e=>e.name));o=Math.min(5*s.size,20);const l=e.positions.filter(e=>e.availableSlots?.some(e=>e.isAvailable));return i=Math.min(2*l.length,10),{store:e,score:n+a+o+i,breakdown:{locationMatch:n,districtMatch:a,positionDiversity:o,availability:i}}}).sort((e,n)=>n.score-e.score).map(e=>({store:e.store,distance:void 0}))}function nt(e){return M[e].length>0}function tt(e,n){return e.has(n)}function rt(e,n,t){return"minimal"===n||(1===e||"trust_building"===t||"private_channel"===t)}async function at(e,n,t,r,a,o,i,s,l=1,u="minimal",c=[n.primaryNeed]){const d=n.extractedInfo,m=n.primaryNeed,p=c.length>0?Array.from(new Set(c.filter(e=>"none"!==e))):"none"===m?[]:[m],g=new Set(p.flatMap(e=>M[e])),f=rt(l,u,n.stage),y=!f&&nt(m);let b,h;try{b=await Jn()}catch(e){const n="object"==typeof e&&null!==e&&"userMessage"in e&&"string"==typeof e.userMessage?e.userMessage:e instanceof Error?e.message:String(e);h=n,me(`[buildContextInfoByNeeds] 品牌别名服务不可用,回退 fuzzy 解析: ${n}`)}const N=Xn({uiSelectedBrand:t,configDefaultBrand:ke(e),conversationBrand:r||void 0,availableBrands:Re(e),strategy:a||"smart",aliasMap:b}),S=N.resolvedBrand;me(`[品牌解析] 工具传参: ${r??"(未指定)"} → 结果: ${S} (${N.matchType}, ${N.source})`);const T=Oe(e,S),I=T?.stores??[];let A=I;if(A.length>0){const e=d.mentionedLocations||[];if(e.length>0){const n=e[0]?.location?.trim();if(n){const e=A.filter(e=>e.name.includes(n)||e.location.includes(n)||(e.district??"").includes(n)||(e.subarea??"").includes(n));e.length>0&&(A=e)}}const n=d.mentionedDistricts||[];if(n.length>0){const e=A.filter(e=>n.some(n=>(e.district??"").includes(n.district)||(e.subarea??"").includes(n.district)));e.length>0&&(A=e)}if(A.length===I.length&&o?.jobAddress&&tt(g,"location")){const e=A.filter(e=>e.name.includes(o.jobAddress||"")||e.location.includes(o.jobAddress||"")||(e.district??"").includes(o.jobAddress||"")||(e.subarea??"").includes(o.jobAddress||""));e.length>0&&(A=e)}}let _=[];A.length>0&&(_=et(A,d));const E=y?Math.min(1,_.length):0,R=y?"focused":"minimal";let O=`阶段目标:${n.stage}\n默认推荐品牌:${S}\n`;if(h&&(O+=`系统状态:品牌别名服务暂不可用,已回退为规则匹配(${h})。\n`),i){const e=i.stageGoals[n.stage],t=s||i.defaultIndustryVoiceId,r=i.industryVoices[t];O+=`策略目标:${e.primaryGoal}\n`,O+=`推进方式:${e.ctaStrategy}\n`,O+=`主回答轴:${m}\n`,r&&(O+=`行业指纹:${r.name} | 风格:${r.styleKeywords.join("、")}\n`),O+=`红线:${i.hardConstraints.rules.map(e=>e.rule).join(";")}\n`}return y?0===E?O+="暂无可用的门店事实信息,请使用泛化回答,避免任何具体承诺。\n":(O+="匹配到的门店信息:\n",_.slice(0,E).forEach(({store:e})=>{const n=tt(g,"location"),t=Array.from(g).some(e=>"location"!==e),r=[e.district,e.subarea].filter(e=>Boolean(e)).join("");O+=n?r?`• ${e.name}(${r}):${e.location}\n`:`• ${e.name}:${e.location}\n`:`• ${e.name}\n`,t&&e.positions.slice(0,3).forEach(e=>{if(O+=` 职位:${e.name}\n`,tt(g,"salary")){const n=Qn(e.salary);n&&(O+=` 薪资:${n}\n`)}if(tt(g,"schedule")){if(e.laborForm){const n=[e.laborForm];e.employmentForm&&"长期用工"!==e.employmentForm&&n.push(e.employmentForm),O+=` 用工形式:${n.join(",")}\n`}if(e.timeSlots.length>0&&(O+=` 时间:${e.timeSlots.slice(0,3).join("、")}\n`),(e.minHoursPerWeek||e.maxHoursPerWeek)&&(O+=` 每周工时:${e.minHoursPerWeek||0}-${e.maxHoursPerWeek||"不限"}小时\n`),null!=e.perMonthMinWorkTime){const n=null!=e.perMonthMinWorkTimeUnit?String(e.perMonthMinWorkTimeUnit):"";O+=` 月最低工时:${e.perMonthMinWorkTime}${n}\n`}}if(tt(g,"policy")&&(e.attendanceRequirement?.description&&(O+=` 出勤要求:${e.attendanceRequirement.description}\n`),e.trainingRequired&&"不需要"!==e.trainingRequired&&(O+=` 培训要求:${e.trainingRequired}\n`),e.probationRequired&&"不需要"!==e.probationRequired&&(O+=` 试岗要求:${e.probationRequired}\n`)),tt(g,"availability")){const n=e.availableSlots?.filter(e=>e.isAvailable).slice(0,3)||[];n.length>0&&(O+=` 可用时段:${n.map(e=>e.slot).join("、")}\n`)}if(tt(g,"requirements")&&e.hiringRequirements){const n=e.hiringRequirements,t=[];null==n.minAge&&null==n.maxAge||t.push(`年龄${n.minAge??"不限"}-${n.maxAge??"不限"}岁`),n.genderRequirement&&"0"!==n.genderRequirement&&t.push(`性别:${n.genderRequirement}`),n.education&&"不限"!==n.education&&t.push(`学历:${n.education}`),n.healthCertificate&&t.push(n.healthCertificate),n.languages&&t.push(`语言:${n.languages}`),n.socialIdentity&&"不限"!==n.socialIdentity&&t.push(`社会身份:${n.socialIdentity}`),t.length>0&&(O+=` 要求:${t.join("、")}\n`),n.recruitmentRemark&&(O+=` 招聘备注:${n.recruitmentRemark.slice(0,200)}\n`)}})})):O+=f?"当前处于首轮或浅层沟通,优先泛化回答,不主动展开具体门店、数字或筛选条件。\n":"本轮以推进沟通为主,无需展开岗位细节,请保持回答聚焦且克制。\n",{contextInfo:O,resolvedBrand:S,debugInfo:{relevantStores:_.length>0?_:A.map(e=>({store:e,distance:void 0})),storeCount:E,detailLevel:R,primaryNeed:m,turnPlan:n,aliasLookupError:h}}}var ot=["too_many_questions","audit_tone","premature_numeric_disclosure","off_axis_fact_disclosure","reply_overpacked"],it=/[^。!?!?]*[??]/g,st={salary:{mention:[/\d+(?:\.\d+)?\s*元(?:\/时|\/小时)?/i,/时薪|薪资|工资|底薪|收入/i],concrete:[/\d+(?:\.\d+)?\s*元(?:\/时|\/小时)?/i]},schedule:{mention:[/\d{1,2}:\d{2}\s*[~-]\s*\d{1,2}:\d{2}/,/班次|轮班|白班|晚班|工时|排班/i],concrete:[/\d{1,2}:\d{2}\s*[~-]\s*\d{1,2}:\d{2}/,/轮班|白班|晚班|早班|中班|夜班/i]},location:{mention:[/地址|地铁|附近|位于|门店|在.+(?:路|街|广场|商场|大厦)/i],concrete:[/地址|位于|地铁\S*站|在.+(?:路|街|广场|商场|大厦)/i]},policy:{mention:[/考勤|试用期|社保|五险一金|迟到|补班/i],concrete:[/考勤|试用期|社保|五险一金|迟到|补班/i]},requirements:{mention:[/年龄|学历|经验|健康证|要求/i],concrete:[/年龄|学历|经验|健康证/i]},availability:{mention:[/名额|空位|可用时段|可安排/i],concrete:[/名额|空位|可用时段/i]}};function lt(e){return e?.outputGuards??W}function ut(e){const n=e.match(it)??[],t=new Set(n.map(e=>e.replace(/[??]/g,"").trim()).filter(Boolean)),r=e.split(/[。!?!?]/).map(e=>e.trim()).filter(Boolean).filter(e=>/[吗呢么]$/.test(e)&&!t.has(e)).length;return n.length+r}function ct(e){return e.split(/[。!?!?]/).map(e=>e.trim()).filter(Boolean).length}function dt(e){return/(?:^|\s)(?:\d+\.\s|- |•)/m.test(e)}function mt(e,n="mention"){return Object.entries(st).filter(([,t])=>t[n].some(n=>n.test(e))).map(([e])=>e)}function pt(e,n){return n.some(n=>n&&e.includes(n))}function gt(e){return/\d+(?:\.\d+)?\s*元(?:\/时|\/小时)?/i.test(e)||/\d{1,2}:\d{2}\s*[~-]\s*\d{1,2}:\d{2}/.test(e)||/年龄\s*\d{1,2}\s*[-~到]\s*\d{1,2}\s*岁/i.test(e)||/\d{1,2}\s*[-~到]\s*\d{1,2}\s*岁/i.test(e)||/地址在|门店在|位于|在.+(?:路|街|广场|商场|大厦|地铁)/i.test(e)}function ft(e,n,t){let r=0;return ct(e)>=4&&(r+=1),dt(e)&&(r+=1),n>=3&&(r+=1),t.length>=2&&(r+=1),r>=2}function yt(e){return mt(e,"concrete")}function bt(e){const n=[];return/薪资:/.test(e)&&n.push("salary"),/排班:|时间:|每周工时:/.test(e)&&n.push("schedule"),/匹配到的门店信息:[\s\S]*• .*:/.test(e)&&n.push("location"),/考勤:|出勤要求:/.test(e)&&n.push("policy"),/要求:/.test(e)&&n.push("requirements"),/可用时段:/.test(e)&&n.push("availability"),n}function ht(e,n){const t=new Set(e.flatMap(e=>M[e]));return 0===t.size?n.length>0:n.some(e=>!t.has(e))}function Nt(e){const{text:n,turnIndex:t,mode:r,policy:a}=e,o=lt(a),i=ut(n),s=o.maxQuestionsByMode[r],l=yt(n),u=e.allowedNeeds?.length?e.allowedNeeds:[e.primaryNeed],c=[];return i>s&&c.push("too_many_questions"),pt(n,o.blockedAuditPhrases)&&c.push("audit_tone"),o.blockFirstTurnSpecificFacts&&1===t&&gt(n)&&c.push("premature_numeric_disclosure"),ht(u,l)&&c.push("off_axis_fact_disclosure"),ft(n,i,l)&&c.push("reply_overpacked"),{violations:c,questionCount:i,factFamilies:l}}import St from"ora";function Tt(){let e=null;return{update(n){e?e.text=n:e=St({text:n,stream:process.stderr}).start()},succeed(n){e?(e.succeed(n),e=null):console.error(`✓ ${n}`)},fail(n){e?(e.fail(n),e=null):console.error(`✗ ${n}`)}}}import{z as It}from"zod";var At=6e4,_t=200,Et=2e4,Rt=null,Ot=null;function Lt(){const e=process.env.DULIDAY_JOB_LIST_URL;return"string"==typeof e&&e.trim().length>0?e:void 0}function kt(){const e=process.env.DULIDAY_TOKEN;return"string"==typeof e&&e.trim().length>0?e:void 0}function Mt(e){return(e??"").trim()}function vt(e){const n=Mt(e);if(!n)return[];const t=new Set([n]);return n.endsWith("市")?t.add(n.slice(0,-1)):t.add(`${n}市`),Array.from(t).filter(Boolean)}function wt(e,n){const t=Mt(e);if(!t)return[];const r=new Set([t]),a=vt(n);for(const e of a)if(t.startsWith(e)){const n=t.slice(e.length).trim();n&&r.add(n)}return Array.from(r).filter(Boolean)}var Dt=It.object({data:It.object({result:It.array(It.unknown()).optional(),list:It.array(It.unknown()).optional(),total:It.number().optional()}).nullable().optional(),result:It.array(It.unknown()).optional()});function Ct(e){const n=Dt.safeParse(e);if(!n.success)return{items:[],total:0};const t=n.data,r=t.data?.result??t.data?.list??(Array.isArray(t.result)?t.result:[]),a=t.data?.total??(Array.isArray(r)?r.length:0);return{items:Array.isArray(r)?r:[],total:"number"==typeof a?a:0}}var Ut={includeBasicInfo:!0,includeJobSalary:!0,includeWelfare:!0,includeHiringRequirement:!0,includeWorkTime:!0},xt={includeBasicInfo:!0,includeHiringRequirement:!0};async function $t(e,n,t,r,a){const o="test"!==process.env.NODE_ENV,i=wt(a?.brandAlias,a?.cityName),s=vt(a?.cityName),l=a?.include??xt,u=JSON.stringify({token:e,brandCandidates:i,cityCandidates:s,pageNum:t,includeOpts:l}),c=Date.now();if(o&&Rt&&Rt.cacheKey===u&&c-Rt.fetchedAt<At)return Rt.payload;if(o&&Ot?.cacheKey===u)return Ot.promise;const d=(async()=>{const a=new AbortController,o=setTimeout(()=>a.abort(),Et),c={};i.length>0&&(c.brandAliasList=i),s.length>0&&(c.cityNameList=s);const d={pageNum:t,pageSize:r,queryParam:c,options:l};try{const t=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json","Duliday-Token":e},body:JSON.stringify(d),signal:a.signal});if(!t.ok)throw new Error(`Duliday job list fetch failed: ${t.status}`);const r=await t.json();return Rt={cacheKey:u,payload:r,fetchedAt:Date.now()},r}finally{clearTimeout(o),Ot=null}})();return o&&(Ot={cacheKey:u,promise:d}),d}async function jt(e,n,t){const r=[];let a=1,o=0;for(;;){const i=Ct(await $t(e,n,a,_t,t));if(1===a&&(o=i.total),r.push(...i.items),i.items.length<_t||r.length>=o)break;a+=1}return{items:r,total:o}}var Wt=["pass","fail","unknown"],Ft={enabled:!1,revealRange:!1,failStrategy:"礼貌说明不匹配,避免承诺",unknownStrategy:"先核实年龄或资格条件",passStrategy:"确认匹配后推进下一步",allowRedirect:!1,redirectPriority:"low"},Pt=200;function Bt(e){return(e??"").trim().toLowerCase()}function Gt(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)}function qt(e){if("string"==typeof e)return e;if(Array.isArray(e)){const n=e.find(e=>"string"==typeof e);return"string"==typeof n?n:""}return""}function Ht(e,n){for(const t of n)if(t in e){const n=qt(e[t]);if(n)return n}return""}function Kt(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"==typeof e&&""!==e.trim()){const n=Number(e);return Number.isFinite(n)?n:null}return null}function Vt(e,n){const t=n??Ft,r="pass"===e?t.passStrategy:"fail"===e?t.failStrategy:t.unknownStrategy;return{...t,status:e,strategy:r}}async function Yt({age:e,brandAlias:n,cityName:t,regionName:r,strategy:a}){const o=kt(),i=Lt(),s={minAgeObserved:null,maxAgeObserved:null,matchedCount:0,total:0};if(!o)return{status:"unknown",summary:s,appliedStrategy:Vt("unknown",a)};if(!i)return{status:"unknown",summary:s,appliedStrategy:Vt("unknown",a)};try{const l=await $t(o,i,1,Pt,{brandAlias:n??null,cityName:t??null}),{items:u,total:c}=Ct(l);s.total=c;const d=c>u.length&&u.length>=Pt,m=wt(n,t).map(e=>Bt(e)).filter(Boolean),p=vt(t).map(e=>Bt(e)).filter(Boolean),g=Bt(r);let f=!1,y=!1;for(const n of u){if(!Gt(n))continue;const t=n,r=Gt(t.basicInfo)?t.basicInfo:null,a=r&&Gt(r.storeInfo)?r.storeInfo:null,o=Bt(Ht(t,["brandAlias","brandName","brand","organizationName"])||(r?Ht(r,["brandAlias","brandName","brand"]):"")),i=Bt(Ht(t,["cityName","storeCityName","jobCityName"])||(a?Ht(a,["storeCityName","cityName"]):"")),l=Bt(Ht(t,["regionName","storeRegionName","districtName"])||(a?Ht(a,["storeRegionName","regionName","districtName"]):"")),u=Bt(Ht(t,["storeAddress","jobAddress","address","storeExactAddress"])||(a?Ht(a,["storeAddress","storeExactAddress","address"]):""));if(m.length>0&&!m.some(e=>o.includes(e)||e.includes(o)))continue;if(p.length>0&&!p.some(e=>i.includes(e)))continue;if(g&&!l.includes(g)&&!u.includes(g))continue;s.matchedCount+=1;const c=Gt(t.hiringRequirement)?t.hiringRequirement:void 0,d=Gt(c?.basicPersonalRequirements)?c.basicPersonalRequirements:void 0,b=Kt(d?.minAge??t.minAge),h=Kt(d?.maxAge??t.maxAge);if(null!==b&&(f=!0,s.minAgeObserved=null===s.minAgeObserved?b:Math.min(s.minAgeObserved,b)),null!==h&&(f=!0,s.maxAgeObserved=null===s.maxAgeObserved?h:Math.max(s.maxAgeObserved,h)),"number"==typeof e){null!==b&&e<b||null!==h&&e>h||(y=!0)}}if("number"!=typeof e||0===s.matchedCount||!f)return{status:"unknown",summary:s,appliedStrategy:Vt("unknown",a)};if(d)return{status:"unknown",summary:s,appliedStrategy:Vt("unknown",a)};const b=y?"pass":"fail";return{status:b,summary:s,appliedStrategy:Vt(b,a)}}catch{return{status:"unknown",summary:s,appliedStrategy:Vt("unknown",a)}}}function zt(e){if(!e)return;const n=e.match(/(\d+)/);return n?n[1]:e}function Jt(e,n){if("number"==typeof n?.age)return n.age;const t=zt(n?.age);if(t){const e=Number(t);if(Number.isFinite(e))return e}return"number"==typeof e.extractedInfo.specificAge?e.extractedInfo.specificAge:void 0}function Qt(e,n){const t=e.extractedInfo.mentionedDistricts?.[0]?.district;if(t)return t;const r=e.extractedInfo.mentionedLocations?.[0]?.location;return r||(n?.jobAddress?n.jobAddress:void 0)}var Zt=[{key:"age",label:"年龄"},{key:"gender",label:"性别"},{key:"education",label:"学历"},{key:"experience",label:"工作经验"},{key:"expectedSalary",label:"期望薪资"},{key:"expectedLocation",label:"期望位置"},{key:"jobAddress",label:"工作地址"},{key:"healthCertificate",label:"健康证"}];function Xt(e){if(!e)return{factsText:"",knownFieldNames:[]};const n=[];for(const{key:t,label:r}of Zt){const a=e[t];"string"==typeof a&&a.trim()?n.push({label:r,value:a.trim()}):"boolean"==typeof a&&n.push({label:r,value:a?"是":"否"})}return 0===n.length?{factsText:"",knownFieldNames:[]}:{factsText:n.map(e=>`${e.label}:${e.value}`).join("\n"),knownFieldNames:n.map(e=>e.label)}}function er(e){if(null===e.minAgeObserved&&null===e.maxAgeObserved)return null;return`${e.minAgeObserved??"?"}-${e.maxAgeObserved??"?"}`}function nr(e,n,t){const r=n?.qualificationPolicy?.age;if(!e||!r||!r.enabled)return[];if("unknown"===e.status&&!t.riskFlags.includes("age_sensitive"))return[];const a=["[QualificationPolicy:Age]"],o=er(e.summary);return a.push(`- gateStatus: ${e.status}`),a.push(`- expressionStrategy: ${e.appliedStrategy.strategy}`),a.push("- redirect: "+(r.allowRedirect?`allowed priority=${r.redirectPriority}`:"not allowed")),a.push("- revealRange: "+(r.revealRange?"allowed":"not allowed")),r.revealRange&&o&&a.push(`- rangeObserved: ${o}`),"pass"===e.status?a.push(`- writingConstraint: ${e.appliedStrategy.strategy};匹配通过后推进下一步,避免强调年龄筛选`):"fail"===e.status?(a.push(`- writingConstraint: ${e.appliedStrategy.strategy};礼貌说明不匹配,避免承诺或争辩`),r.allowRedirect&&a.push("- writingConstraint: 可提示其他岗位或门店选项")):a.push("- writingConstraint: 如确需涉及年龄或资格,用合规、轻量的方式核实,不要审查式逐条盘问"),a}function tr(e){return"minimal"===e?["4. 当前为浅层沟通,优先泛化回答,不主动抛具体数字、时间、地址或筛选条件。","5. 若候选人追问具体事实,承接需求并引导进一步沟通,不编造细节。"]:["4. 围绕 primaryNeed 回答,上下文中有的事实可以正常引用,不要刻意回避。","5. 不主动展开其他事实轴;若候选人同时问两个点,只在上下文支持时简要带上次要问题。"]}function rr(e,n,t,r,a,o,i,s,l,u,c,d){if(!e)return{system:"你是招聘助手。遵循事实,不夸大承诺,回复简洁自然。",prompt:`候选人消息:${a}\n\n上下文:\n${r}\n\n请直接回复候选人。`};const m=e.stageGoals[n.stage],p=e.industryVoices[u||e.defaultIndustryVoiceId],g=e.outputGuards.maxQuestionsByMode[s];return{system:["你是政策驱动的招聘助手。",`当前阶段:${n.stage}`,`当前轮次:${i}`,`当前披露模式:${s}`,`主回答轴:${n.primaryNeed}`,`阶段目标:${m.primaryGoal}`,`阶段成功标准:${m.successCriteria.join(";")}`,`推进策略:${m.ctaStrategy}`,m.disallowedActions?.length?`阶段禁止:${m.disallowedActions.join(";")}`:"",`人格设定:语气=${e.persona.tone},亲和度=${e.persona.warmth},长度=${e.persona.length},称呼=${e.persona.addressStyle},提问风格=${e.persona.questionStyle}`,`共情策略:${e.persona.empathyStrategy}`,p?`行业指纹:${p.name};背景=${p.industryBackground};行业词=${p.jargon.join("、")};避免=${p.tabooPhrases.join("、")}`:"",`红线规则:${e.hardConstraints.rules.map(e=>e.rule).join(";")}`,`FactGate模式:${e.factGate.mode};缺事实回退=${e.factGate.fallbackBehavior}`,`禁止审查措辞:${e.outputGuards.blockedAuditPhrases.join("、")}`,...l.knownFieldNames.length>0?[`候选人资料已确认:${l.knownFieldNames.join("、")}。这些信息不得重复追问;如需引用,自然带过即可,不要像念资料一样复述。`]:[],...nr(d,e,n),c?`如涉及换微信,优先引导平台交换,必要时可提供默认微信号:${c}`:"如涉及换微信,优先引导平台交换,不编造联系方式。","必须口语化、简洁,不输出解释。"].filter(Boolean).join("\n"),prompt:["[回合规划]",`stage=${n.stage}`,`subGoals=${n.subGoals.join("、")||"无"}`,`contextNeeds=${t.join("、")||"none"}`,`primaryNeed=${n.primaryNeed}`,`riskFlags=${n.riskFlags.join("、")||"无"}`,`confidence=${n.confidence.toFixed(2)}`,"","[对话历史]",o.slice(-6).join("\n")||"无","","[业务上下文]",r,"",...l.factsText?["[候选人已知信息]",l.factsText,""]:[],"[候选人消息]",a,"","[输出要求]","1. 直接给候选人的单条回复,不得输出多段解释或元信息。",`2. 最多追问 ${g} 个关键问题。`,"3. 禁止使用“是否满足”“是否符合”“基本入职要求”等审查措辞。",...tr(s)].join("\n")}}function ar(e,n,t){const r=yt(e);if(0===r.length)return!1;const a=new Set(bt(n)),o=new Set(t.flatMap(e=>M[e]));return r.some(e=>!o.has(e)||!a.has(e))}function or(e){return"private_channel"===e||"interview_scheduling"===e}function ir(e,n){return Number.isInteger(n)&&void 0!==n&&n>=1?n:0===e.length?1:2}function sr(e,n){return 1===e||"trust_building"===n||"private_channel"===n?"minimal":"focused"}function lr(e,n){const t=["- 只修正命中的违规点,没有命中的部分不要过度改写。"];return e.includes("too_many_questions")&&t.push(`- 删除多余追问,只保留最关键的 ${n} 个问题。`),e.includes("audit_tone")&&t.push("- 保留原意,但把审查式措辞改成自然口语,不要像筛选候选人。"),e.includes("premature_numeric_disclosure")&&t.push("- 把具体数字、时间和地址细节改成泛化表达,例如“细节我帮你确认”或“以门店安排为准”。"),e.includes("off_axis_fact_disclosure")&&t.push("- 删除不属于主回答轴的具体事实;如果要提到次要问题,只能做不带细节的承接。"),e.includes("reply_overpacked")&&t.push("- 压缩成最多两句,不要列表、不要枚举、不要一口气展开太多信息。"),t}async function ur(e,n,t){const r=["请重写下面这条招聘回复。","要求:","- 不新增任何具体数字、地址、福利承诺。","- 仅保留泛化表达,强调可进一步沟通确认细节。","- 口语化、单行、简洁。","","[原回复]",e,"","[可用上下文]",t].join("\n"),a=await fn({model:n,prompt:r,context:"SmartReplyFactGateRewrite",timeoutMs:2e4,maxOutputTokens:500});return a.success?{text:a.text,usage:a.usage,latencyMs:a.latencyMs}:{text:e}}async function cr(e,n,t,r){const{turnIndex:a,effectiveDisclosureMode:o,primaryNeed:i,allowedNeeds:s,violations:l,policy:u}=r,c=u?.outputGuards.maxQuestionsByMode[o]??1,d=u?.outputGuards.blockedAuditPhrases.join("、")??"",m=lr(l,c),p=(s??[]).filter(e=>e!==i&&"none"!==e),g=["请重写下面这条招聘回复。","要求:",`- 当前轮次=${a},披露模式=${o},主回答轴=${i}。`,p.length>0?`- 允许顺带覆盖的次要轴:${p.join("、")}。`:"",`- 当前违规点:${l.join("、")}。`,...m,"- 只保留单条口语化回复,不输出解释。",`- 问题数最多 ${c} 个。`,"- 围绕主回答轴回答,不主动展开其他事实轴。","- 首轮时不要主动报具体数字、时间、地址或筛选条件。",d?`- 禁止使用这些措辞:${d}。`:"","","[原回复]",e,"","[可用上下文]",t].filter(Boolean).join("\n"),f=await fn({model:n,prompt:g,context:"SmartReplyReplyGateRewrite",timeoutMs:2e4,maxOutputTokens:500});return f.success?{text:f.text,usage:f.usage,latencyMs:f.latencyMs}:{text:e}}async function dr(e){const n=Tt();de(!0);try{return await mr(e,n)}catch(e){throw n.fail("回复生成失败"),e}finally{de(!1)}}async function mr(e,n){const{modelConfig:t,preferredBrand:r,toolBrand:a,brandPriorityStrategy:o,conversationHistory:i=[],candidateMessage:s,configData:l,replyPolicy:u,candidateInfo:c,defaultWechatId:d,industryVoiceId:m,channelType:p,turnIndex:g}=e,f=t?.providerConfigs||be,y=Me(l),b={...y?{city:y}:{},defaultBrand:ke(l),availableBrands:Re(l),storeCount:Ee(l).length},h=Xt(c);n.update("分析对话意图...");const N=await jn(s,{modelConfig:t||{},conversationHistory:i,brandData:b,providerConfigs:f,...void 0!==p?{channelType:p}:{},...void 0!==u?{replyPolicy:u}:{},...h.knownFieldNames.length>0?{knownCandidateFields:h.knownFieldNames}:{}}),S=ir(i,g),T=sr(S,N.stage),I="focused"===T?Cn(N.primaryNeed,N.needs,s,2):[N.primaryNeed],A=a||N.extractedInfo.mentionedBrand||void 0;n.update("构建业务上下文...");const{contextInfo:_,debugInfo:E,resolvedBrand:R}=await at(l,N,r,A,o,c,u,m,S,T,I);n.update("校验候选人资格...");const O=Jt(N,c),L=Qt(N,c),k=N.extractedInfo.city??Me(l,R),M=await Yt({...void 0!==O?{age:O}:{},brandAlias:R,..."string"==typeof k?{cityName:k}:{},...void 0!==L?{regionName:L}:{},...void 0!==u?.qualificationPolicy?.age?{strategy:u.qualificationPolicy.age}:{}}),v=_e(f),w=t?.replyModel||he.replyModel,D=v.languageModel(w),C=rr(u,N,I,_,s,i,S,T,h,m,d,M);n.update("生成回复...");const U=await fn({model:D,system:C.system,prompt:C.prompt,context:"SmartReply",timeoutMs:3e4,maxOutputTokens:2e3});if(!U.success)return n.fail("回复生成失败"),rn("SmartReply 生成失败",U.error),{turnPlan:N,suggestedReply:"",confidence:0,shouldExchangeWechat:or(N.stage),factGateRewritten:!1,replyGateRewritten:!1,gateViolations:[],contextInfo:_,debugInfo:{...E,resolvedBrand:R,turnIndex:S,effectiveDisclosureMode:T,primaryNeed:N.primaryNeed,replyGateRewritten:!1,gateViolations:[],gateStatus:M.status,appliedStrategy:M.appliedStrategy,ageRangeSummary:M.summary},usage:void 0,error:U.error};let x=U.text,$=U.usage,j=U.latencyMs,W=!1,F=!1,P=[];if(n.update("检查回复质量..."),"strict"===u?.factGate.mode){if(ar(x,_,I)){W=!0;const e=await ur(x,D,_);x=e.text,e.usage&&($=e.usage),void 0!==e.latencyMs&&(j=(j??0)+e.latencyMs)}}if(P=Nt({text:x,turnIndex:S,mode:T,primaryNeed:N.primaryNeed,allowedNeeds:I,policy:u}).violations,P.length>0){n.update("优化回复..."),F=!0;const e=await cr(x,D,_,{turnIndex:S,effectiveDisclosureMode:T,primaryNeed:N.primaryNeed,allowedNeeds:I,violations:P,policy:u});x=e.text,e.usage&&($=e.usage),void 0!==e.latencyMs&&(j=(j??0)+e.latencyMs),P=Nt({text:x,turnIndex:S,mode:T,primaryNeed:N.primaryNeed,allowedNeeds:I,policy:u}).violations}const B=j??0,G=$?.totalTokens??0;return n.succeed(`回复已生成 | ${N.stage} | ${B}ms | ${G} tokens${F?" | 已优化":""}`),{turnPlan:N,suggestedReply:x,confidence:Math.max(0,Math.min(1,N.confidence)),shouldExchangeWechat:or(N.stage),factGateRewritten:W,replyGateRewritten:F,gateViolations:P,contextInfo:`${_}\n当前品牌:${R}`,debugInfo:{...E,resolvedBrand:R,turnIndex:S,effectiveDisclosureMode:T,primaryNeed:N.primaryNeed,replyGateRewritten:F,gateViolations:P,gateStatus:M.status,appliedStrategy:M.appliedStrategy,ageRangeSummary:M.summary},usage:$,latencyMs:j}}var pr=t.enum(ot),gr=t.enum(Wt),fr=n({name:"generate_reply",description:"根据候选人消息、对话历史和品牌数据生成智能招聘回复。内部流程:回合规划 → primaryNeed 驱动上下文构建 → 年龄资格校验 → 策略化回复生成 → FactGate/ReplyGate 校验。",input:t.object({candidateMessage:t.string().describe("候选人发送的消息"),conversationHistory:t.array(t.string()).optional().describe("对话历史(最近几轮)"),candidateInfo:i.optional().describe("候选人基本信息"),preferredBrand:t.string().optional().describe("偏好品牌"),channelType:_.optional().describe("渠道类型: public(BOSS直聘) 或 private(微信)"),defaultWechatId:t.string().optional().describe("默认微信号"),industryVoiceId:t.string().optional().describe("行业语调ID"),turnIndex:t.number().int().min(1).optional().describe("当前会话回复轮次"),modelConfig:Nn.optional().describe("模型配置覆盖")}),output:t.object({suggestedReply:t.string(),confidence:t.number(),stage:A,latencyMs:t.number().optional(),shouldExchangeWechat:t.boolean().optional(),error:t.string().optional(),diagnostics:t.object({subGoals:t.array(t.string()),needs:t.array(L),primaryNeed:L,riskFlags:t.array(k),reasoningText:t.string(),extractedInfo:t.object({mentionedBrand:t.string().nullable(),city:t.string().nullable(),specificAge:t.number().nullable(),hasUrgency:t.boolean().nullable(),preferredSchedule:t.string().nullable()}),ageGate:t.object({enabled:t.boolean(),status:gr,strategy:t.string()}),resolvedBrand:t.string(),storeCount:t.number(),detailLevel:E,turnIndex:t.number(),effectiveDisclosureMode:E,replyGateRewritten:t.boolean(),gateViolations:t.array(pr),factGateRewritten:t.boolean()}).optional()}),execute:async(e,n)=>{let t;n.logger.info(`Processing message: ${e.candidateMessage.slice(0,50)}...`);try{t=ee()}catch{return{suggestedReply:"",confidence:0,stage:"trust_building",error:"品牌数据未配置,请先调用 sync_brand_data 写入数据"}}const r=te(),a=await dr({candidateMessage:e.candidateMessage,conversationHistory:e.conversationHistory,candidateInfo:e.candidateInfo,preferredBrand:e.preferredBrand,channelType:e.channelType,defaultWechatId:e.defaultWechatId,industryVoiceId:e.industryVoiceId,turnIndex:e.turnIndex,modelConfig:e.modelConfig,configData:t,replyPolicy:r});n.logger.info(`Reply generated. Stage: ${a.turnPlan.stage}, Confidence: ${a.confidence}`);const o=a.debugInfo;return{suggestedReply:a.suggestedReply,confidence:a.confidence,stage:a.turnPlan.stage,latencyMs:a.latencyMs,shouldExchangeWechat:a.shouldExchangeWechat,error:a.error?.userMessage,diagnostics:o?{subGoals:a.turnPlan.subGoals,needs:a.turnPlan.needs,primaryNeed:a.turnPlan.primaryNeed,riskFlags:a.turnPlan.riskFlags,reasoningText:a.turnPlan.reasoningText,extractedInfo:{mentionedBrand:a.turnPlan.extractedInfo.mentionedBrand??null,city:a.turnPlan.extractedInfo.city??null,specificAge:a.turnPlan.extractedInfo.specificAge??null,hasUrgency:a.turnPlan.extractedInfo.hasUrgency??null,preferredSchedule:a.turnPlan.extractedInfo.preferredSchedule??null},ageGate:{enabled:o.appliedStrategy.enabled,status:o.gateStatus,strategy:o.appliedStrategy.strategy},resolvedBrand:o.resolvedBrand,storeCount:o.storeCount,detailLevel:o.detailLevel,turnIndex:o.turnIndex,effectiveDisclosureMode:o.effectiveDisclosureMode,replyGateRewritten:a.replyGateRewritten,gateViolations:a.gateViolations,factGateRewritten:a.factGateRewritten}:void 0}}});import{defineTool as yr}from"@roll-agent/sdk";import{z as br}from"zod";import{z as hr}from"zod";var Nr=hr.object({content:hr.string(),image:hr.string().nullable().optional()}).passthrough(),Sr=hr.object({storeId:hr.number().optional(),storeName:hr.string(),storeCityName:hr.string().optional(),storeRegionName:hr.string().optional(),storeAddress:hr.string().optional(),longitude:hr.number().optional(),latitude:hr.number().optional()}).passthrough(),Tr=hr.object({jobId:hr.number(),jobName:hr.string(),jobNickName:hr.string().nullable().optional(),jobCategoryName:hr.string().nullable().optional(),jobContent:hr.string().nullable().optional(),laborForm:hr.string().nullable().optional(),needTraining:hr.string().nullable().optional(),needProbationWork:hr.string().nullable().optional(),brandId:hr.number().optional(),brandName:hr.string().optional(),projectId:hr.number().optional(),projectName:hr.string().optional(),storeInfo:Sr.optional()}).passthrough(),Ir=hr.object({salaryType:hr.string().nullable().optional(),salaryPeriod:hr.string().nullable().optional(),hasStairSalary:hr.string().nullable().optional(),basicSalary:hr.object({basicSalary:hr.number().nullable().optional(),basicSalaryUnit:hr.string().nullable().optional()}).passthrough().nullable().optional(),stairSalaries:hr.array(hr.object({fullWorkTime:hr.number().nullable().optional(),fullWorkTimeUnit:hr.string().nullable().optional(),salary:hr.number().nullable().optional(),salaryUnit:hr.string().nullable().optional()}).passthrough()).nullable().optional(),comprehensiveSalary:hr.object({minComprehensiveSalary:hr.number().nullable().optional(),maxComprehensiveSalary:hr.number().nullable().optional(),comprehensiveSalaryUnit:hr.string().nullable().optional()}).passthrough().nullable().optional(),holidaySalary:hr.object({holidaySalaryType:hr.string().nullable().optional(),holidaySalaryMultiple:hr.number().nullable().optional(),holidayFixedSalary:hr.number().nullable().optional(),holidayFixedSalaryUnit:hr.string().nullable().optional()}).passthrough().nullable().optional()}).passthrough(),Ar=hr.object({salary:hr.number().optional(),salaryUnitStr:hr.string().optional(),salaryScenarioList:hr.array(Ir).nullable().optional()}).passthrough(),_r=hr.object({haveInsurance:hr.string(),accommodation:hr.string(),catering:hr.string().optional(),otherWelfare:hr.array(hr.string()).nullable().optional(),accommodationAllowance:hr.number().nullable().optional(),accommodationAllowanceUnit:hr.string().nullable().optional(),cateringSalary:hr.number().nullable().optional(),cateringSalaryUnit:hr.string().nullable().optional(),trafficAllowanceSalary:hr.number().nullable().optional(),trafficAllowanceSalaryUnit:hr.string().nullable().optional(),memo:hr.string().nullable().optional(),promotionWelfare:hr.string().nullable().optional(),moreWelfares:hr.array(Nr).nullable().optional()}).passthrough(),Er=hr.object({minAge:hr.number().nullable().optional(),maxAge:hr.number().nullable().optional(),genderRequirement:hr.string().nullable().optional()}).passthrough(),Rr=hr.object({education:hr.string().nullable().optional(),healthCertificate:hr.string().nullable().optional(),certificates:hr.string().nullable().optional()}).passthrough(),Or=hr.object({languages:hr.string().nullable().optional(),languageRemark:hr.string().nullable().optional()}).passthrough(),Lr=hr.object({cooperationMode:hr.number().optional(),requirementNum:hr.number().optional(),thresholdNum:hr.number().optional(),signUpNum:hr.number().nullable().optional(),basicPersonalRequirements:Er.nullable().optional(),certificate:Rr.nullable().optional(),language:Or.nullable().optional(),figure:hr.string().nullable().optional(),remark:hr.string().nullable().optional()}).passthrough(),kr=hr.object({employmentForm:hr.string(),minWorkMonths:hr.number().nullable().optional(),maxWorkTakingTime:hr.number().nullable().optional(),restTimeDesc:hr.string().nullable().optional(),workTimeRemark:hr.string().nullable().optional(),employmentDescription:hr.string().nullable().optional(),weekWorkTime:hr.object({weekWorkTimeRequirement:hr.string().nullable().optional(),perWeekWorkDays:hr.number().nullable().optional(),perWeekRestDays:hr.number().nullable().optional(),perWeekNeedWorkDays:hr.union([hr.string(),hr.number()]).nullable().optional(),workSingleDouble:hr.string().nullable().optional(),customnWorkTimeList:hr.array(hr.object({customMinWorkDays:hr.number().nullable().optional(),customMaxWorkDays:hr.number().nullable().optional(),customWorkWeekdays:hr.array(hr.union([hr.string(),hr.number()])).nullable().optional()}).passthrough()).nullable().optional()}).passthrough().nullable().optional(),monthWorkTime:hr.object({perMonthMinWorkTime:hr.number().nullable().optional(),perMonthMinWorkTimeUnit:hr.union([hr.string(),hr.number()]).nullable().optional(),monthWorkTimeRequirement:hr.string().nullable().optional(),perMonthMaxRestTime:hr.number().nullable().optional(),perMonthMaxRestTimeUnit:hr.number().nullable().optional()}).passthrough().nullable().optional(),dayWorkTime:hr.object({perDayMinWorkHours:hr.union([hr.string(),hr.number()]).nullable().optional(),dayWorkTimeRequirement:hr.string().nullable().optional()}).passthrough().nullable().optional(),dailyShiftSchedule:hr.object({arrangementType:hr.string().nullable().optional(),fixedScheduleList:hr.array(hr.object({fixedShiftStartTime:hr.union([hr.string(),hr.number()]).optional(),fixedShiftEndTime:hr.union([hr.string(),hr.number()]).optional(),startTime:hr.number().optional(),endTime:hr.number().optional()}).passthrough()).nullable().optional(),combinedArrangement:hr.array(hr.object({CombinedArrangementWeekdays:hr.union([hr.string(),hr.array(hr.number())]).optional(),CombinedArrangementStartTime:hr.number().optional(),CombinedArrangementEndTime:hr.number().optional(),combinedArrangementStartTime:hr.union([hr.string(),hr.number()]).optional(),combinedArrangementEndTime:hr.union([hr.string(),hr.number()]).optional(),startTime:hr.number().optional(),endTime:hr.number().optional(),weekdays:hr.array(hr.number()).optional()}).passthrough()).nullable().optional(),fixedTime:hr.object({goToWorkStartTime:hr.union([hr.string(),hr.number()]).nullable().optional(),goToWorkEndTime:hr.union([hr.string(),hr.number()]).nullable().optional(),goOffWorkStartTime:hr.union([hr.string(),hr.number()]).nullable().optional(),goOffWorkEndTime:hr.union([hr.string(),hr.number()]).nullable().optional()}).passthrough().nullable().optional()}).passthrough().nullable().optional(),temporaryEmployment:hr.object({temporaryEmploymentStartTime:hr.string().nullable().optional(),temporaryEmploymentEndTime:hr.string().nullable().optional()}).passthrough().nullable().optional()}).passthrough(),Mr=hr.object({basicInfo:Tr,jobSalary:Ar,welfare:_r,hiringRequirement:Lr,workTime:kr}).passthrough();function vr(e){const n=Mr.safeParse(e);if(!n.success)return null;const t=n.data,r=t.basicInfo,a=r.storeInfo,o=t.jobSalary,i=t.hiringRequirement,s=o.salary??o.salaryScenarioList?.find(e=>"正式"===e.salaryType)?.basicSalary?.basicSalary??o.salaryScenarioList?.[0]?.basicSalary?.basicSalary??null,l=o.salaryUnitStr??o.salaryScenarioList?.find(e=>"正式"===e.salaryType)?.basicSalary?.basicSalaryUnit??o.salaryScenarioList?.[0]?.basicSalary?.basicSalaryUnit??null;let u=a?.storeId;if(null==u){const e=`${a?.storeName??""}|${a?.storeAddress??""}`;u=Array.from(e).reduce((e,n)=>31*e+n.charCodeAt(0)>>>0,7)}return{jobId:r.jobId,jobName:r.jobName,jobNickName:r.jobNickName??null,jobCategoryName:r.jobCategoryName??null,jobContent:r.jobContent??null,laborForm:r.laborForm??null,employmentForm:t.workTime.employmentForm,trainingRequired:r.needTraining??null,probationRequired:r.needProbationWork??null,brandId:void 0!==r.brandId?String(r.brandId):void 0!==r.projectId?String(r.projectId):void 0,brandName:r.brandName,projectId:r.projectId,projectName:r.projectName,storeId:u,storeName:a?.storeName??"未知门店",storeCityName:a?.storeCityName??"",storeRegionName:a?.storeRegionName,storeAddress:a?.storeAddress??"",longitude:a?.longitude,latitude:a?.latitude,salary:s,salaryUnitStr:l,salaryScenarioList:o.salaryScenarioList??null,welfare:t.welfare,requirementNum:i.requirementNum??0,signUpNum:i.signUpNum??null,basicPersonalRequirements:i.basicPersonalRequirements?{minAge:i.basicPersonalRequirements.minAge??null,maxAge:i.basicPersonalRequirements.maxAge??null,genderRequirement:i.basicPersonalRequirements.genderRequirement??null}:null,certificate:i.certificate?{education:i.certificate.education??null,healthCertificate:i.certificate.healthCertificate??null}:null,languages:i.language?.languages??null,certificatesRaw:i.certificate?.certificates??null,recruitmentRemark:i.remark??null,socialIdentity:i.figure??null,workTime:t.workTime,perMonthMinWorkTime:t.workTime.monthWorkTime?.perMonthMinWorkTime??null,perMonthMinWorkTimeUnit:t.workTime.monthWorkTime?.perMonthMinWorkTimeUnit??null}}function wr(e,n,t){const r=new Map;let a;for(let o=0;o<e.length;o++){const i=vr(e[o]);if(!i)continue;const s=i.brandName??n??"未知品牌",l=i.brandId??`name:${s}`;void 0!==a||void 0!==n&&s!==n||(a=l);let u=r.get(l);u||(u={id:l,name:s,stores:[]},r.set(l,u));const c=`store_${i.storeId}`;let d=u.stores.find(e=>e.id===c);d||(d=Dr(i,l,t),u.stores.push(d));const m=Cr(i);d.positions.push(m)}return{meta:{...a??r.values().next().value?.id?{defaultBrandId:a??r.values().next().value?.id}:{},syncedAt:(new Date).toISOString(),source:"duliday"},brands:Array.from(r.values())}}function Dr(e,n,t){return{id:`store_${e.storeId}`,brandId:n,name:e.storeName,city:e.storeCityName||t,location:e.storeAddress,district:Vr(e.storeAddress,e.storeRegionName),subarea:Yr(e.storeName),coordinates:"number"==typeof e.latitude&&"number"==typeof e.longitude?{lat:e.latitude,lng:e.longitude}:{lat:0,lng:0},positions:[]}}function Cr(e){const n=Ur(e.workTime);let t=[];return n.combinedArrangementTimes?.length?t=Kr(n.combinedArrangementTimes):n.fixedArrangementTimes?.length&&(t=Kr(n.fixedArrangementTimes.map(e=>({...e,weekdays:[]})))),{id:`pos_${e.jobId}`,name:e.jobNickName??zr(e.jobName),sourceJobName:e.jobName,jobCategory:e.jobCategoryName,brandId:e.brandId,brandName:e.brandName,projectId:void 0!==e.projectId?String(e.projectId):void 0,projectName:e.projectName,description:e.jobContent||null,laborForm:e.laborForm,employmentForm:e.employmentForm,trainingRequired:e.trainingRequired,probationRequired:e.probationRequired,salary:{...xr(e.salary,e.salaryUnitStr,e.welfare),scenarioSummary:$r(e.salaryScenarioList),settlementCycle:jr(e.salaryScenarioList)},timeSlots:t,workHours:null!=n.perDayMinWorkHours?String(n.perDayMinWorkHours):null,minHoursPerWeek:Br(n),maxHoursPerWeek:Gr(n),perMonthMinWorkTime:e.perMonthMinWorkTime,perMonthMinWorkTimeUnit:e.perMonthMinWorkTimeUnit,attendanceRequirement:qr(n),availableSlots:Pr(e,n),benefits:Wr(e.welfare),hiringRequirements:Fr(e)}}function Ur(e){const n=e.weekWorkTime,t=e.dayWorkTime,r=e.dailyShiftSchedule,a=Number(r?.arrangementType)||({"固定排班制":1,"组合排班制":3}[String(r?.arrangementType)]??0),o=null!=t?.perDayMinWorkHours?Number(t.perDayMinWorkHours):null,i=null!==o&&Number.isFinite(o)?o:null,s=n?.customnWorkTimeList?.map(e=>({weekdays:Array.isArray(e.customWorkWeekdays)?e.customWorkWeekdays.map(e=>Number(e)).filter(e=>Number.isFinite(e)):[],minWorkDays:e.customMinWorkDays??null,maxWorkDays:e.customMaxWorkDays??null}))??null,l=r?.fixedScheduleList?.map(e=>({startTime:e.startTime??Hr(e.fixedShiftStartTime),endTime:e.endTime??Hr(e.fixedShiftEndTime)}))??null,u=r?.combinedArrangement?.map(e=>{const n=null!=e.combinedArrangementStartTime?Hr(e.combinedArrangementStartTime):void 0,t=null!=e.combinedArrangementEndTime?Hr(e.combinedArrangementEndTime):void 0,r=(e.weekdays??("string"==typeof e.CombinedArrangementWeekdays?[Number(e.CombinedArrangementWeekdays)]:Array.isArray(e.CombinedArrangementWeekdays)?e.CombinedArrangementWeekdays:[])).map(e=>"number"==typeof e?e:Number(e)).filter(e=>Number.isFinite(e));return{startTime:e.startTime??e.CombinedArrangementStartTime??n??0,endTime:e.endTime??e.CombinedArrangementEndTime??t??0,weekdays:r}})??null;return{perDayMinWorkHours:i,perWeekWorkDays:n?.perWeekWorkDays??null,perWeekNeedWorkDays:null!=n?.perWeekNeedWorkDays?Number(n.perWeekNeedWorkDays):null,perWeekRestDays:n?.perWeekRestDays??null,arrangementType:a,maxWorkTakingTime:e.maxWorkTakingTime??0,workTimeRemark:e.workTimeRemark??null,fixedArrangementTimes:l,combinedArrangementTimes:u,customWorkTimes:s}}function xr(e,n,t){const r=t.memo??null,a=r?.match(/(\d+元?-\d+元?)/),o=a?a[1]:void 0,i=r?.match(/(奖金[\d~\-~元]+)/);return{base:e,unit:n,range:o,bonus:i?i[1]:void 0,memo:r}}function $r(e){if(!e||0===e.length)return;const n=[];for(const t of e){if("培训期"===t.salaryType)continue;if(t.stairSalaries?.length){const e=t.stairSalaries.filter(e=>null!=e.salary).map(e=>{const n=e.salaryUnit??"元/时";return`满${e.fullWorkTime??"?"}${e.fullWorkTimeUnit??"小时"}后${e.salary}${n}`}).join(",");e&&n.push(e)}const e=t.comprehensiveSalary;null!=e?.minComprehensiveSalary&&null!=e?.maxComprehensiveSalary&&n.push(`综合${e.minComprehensiveSalary}-${e.maxComprehensiveSalary}${e.comprehensiveSalaryUnit??"元/月"}`);const r=t.holidaySalary;r&&(r.holidaySalaryMultiple?n.push(`节假日${r.holidaySalaryMultiple}倍`):null!=r.holidayFixedSalary&&n.push(`节假日${r.holidayFixedSalary}${r.holidayFixedSalaryUnit??"元/时"}`))}return n.length>0?n.join(";"):void 0}function jr(e){if(!e||0===e.length)return;const n=e.find(e=>"正式"===e.salaryType)??e[0];return{"日结算":"日结","周结算":"周结","月结算":"月结","完结算":"完结","半月结算":"半月结"}[n?.salaryPeriod??""]??void 0}function Wr(e){const n=e.moreWelfares&&Array.isArray(e.moreWelfares)&&e.moreWelfares.length>0?e.moreWelfares.map(e=>e.content):null;return{insurance:e.haveInsurance||null,accommodation:e.accommodation||null,catering:e.catering??null,moreWelfares:n,memo:e.memo??null,promotion:e.promotionWelfare??null}}function Fr(e){const n=e.basicPersonalRequirements,t=e.certificate;if(n||t||e.languages||e.certificatesRaw||e.recruitmentRemark||e.socialIdentity)return{minAge:n?.minAge??null,maxAge:n?.maxAge??null,genderRequirement:n?.genderRequirement??null,education:t?.education??null,healthCertificate:t?.healthCertificate??null,languages:e.languages,certificatesRaw:e.certificatesRaw,recruitmentRemark:e.recruitmentRemark,socialIdentity:e.socialIdentity}}function Pr(e,n){const t=[];let r=[];n.combinedArrangementTimes?.length?r=Kr(n.combinedArrangementTimes):n.fixedArrangementTimes?.length&&(r=Kr(n.fixedArrangementTimes.map(e=>({...e,weekdays:[]}))));for(const n of r)t.push({slot:n,maxCapacity:e.requirementNum,currentBooked:e.signUpNum||0,isAvailable:(e.signUpNum||0)<e.requirementNum,priority:e.requirementNum>3?"high":"medium"});return t}function Br(e){const n=e.perDayMinWorkHours;if(null==n)return null;let t=null;if(null!=e.perWeekWorkDays&&(t=e.perWeekWorkDays),null===t&&e.customWorkTimes?.length){const n=e.customWorkTimes.map(e=>e.minWorkDays).filter(e=>null!=e);n.length>0&&(t=Math.min(...n))}return null===t&&null!=e.perWeekNeedWorkDays&&(t=e.perWeekNeedWorkDays),null===t?null:n*t}function Gr(e){const n=e.perDayMinWorkHours;if(null==n||null==e.perWeekWorkDays)return null;return n*e.perWeekWorkDays}function qr(e){let n=[];if(e.combinedArrangementTimes?.length){const t=new Set;for(const n of e.combinedArrangementTimes)for(const e of n.weekdays)null!=e&&Number.isFinite(e)&&t.add(e);n=Array.from(t).sort()}else if(e.customWorkTimes?.length){const t=new Set;for(const n of e.customWorkTimes)for(const e of n.weekdays)null!=e&&Number.isFinite(e)&&t.add(e);n=Array.from(t).sort()}let t=null;if(null!=e.perWeekWorkDays&&(t=e.perWeekWorkDays),null===t&&e.customWorkTimes?.length){const n=e.customWorkTimes.map(e=>e.minWorkDays).filter(e=>null!=e);n.length>0&&(t=Math.min(...n))}return null===t&&null!=e.perWeekNeedWorkDays&&(t=e.perWeekNeedWorkDays),{minimumDays:t,requiredDays:Jr(n),description:e.workTimeRemark??null}}function Hr(e){if("number"==typeof e)return e;if("string"!=typeof e||!e)return 0;const n=e.match(/^(\d{1,2}):(\d{2})$/);return n?3600*Number(n[1])+60*Number(n[2]):Number(e)||0}function Kr(e){return e.map(e=>{const n=Math.floor(e.startTime/3600),t=Math.floor(e.startTime%3600/60),r=Math.floor(e.endTime/3600),a=Math.floor(e.endTime%3600/60);return`${n.toString().padStart(2,"0")}:${t.toString().padStart(2,"0")}~${r.toString().padStart(2,"0")}:${a.toString().padStart(2,"0")}`})}function Vr(e,n){if(n)return n;return e.split("-")[1]||null}function Yr(e){const n=e.match(/(.+?)(附近|周边|旁边|店)/);return n?.[1]??null}function zr(e){const n=e.split("-");return n[n.length-2]||e}function Jr(e){return e.filter(e=>Number.isFinite(e)).map(e=>0===e?7:e)}var Qr=yr({name:"sync_brand_data",description:"从 Duliday API 拉取并同步品牌配置数据(门店、岗位、薪资等)到本地。可选传入品牌别名和城市名称作为过滤条件。",input:br.object({brandAlias:br.string().optional().describe("品牌别名(可选,配合 cityName 使用可按品牌过滤)"),cityName:br.string().describe('城市名称(必填,Duliday API 要求至少提供城市作为筛选条件,如 "上海市")')}),output:br.object({success:br.boolean(),brandsCount:br.number(),storesCount:br.number(),positionsCount:br.number(),updatedAt:br.string(),error:br.string().optional()}),execute:async(e,n)=>{const t=kt(),r=Lt();if(!t||!r)return{success:!1,brandsCount:0,storesCount:0,positionsCount:0,updatedAt:(new Date).toISOString(),error:`缺少环境变量: ${[!t&&"DULIDAY_TOKEN",!r&&"DULIDAY_JOB_LIST_URL"].filter(Boolean).join(", ")}`};if(!e.cityName)return{success:!1,brandsCount:0,storesCount:0,positionsCount:0,updatedAt:(new Date).toISOString(),error:'cityName 为必填项,Duliday API 要求至少提供城市作为筛选条件(如 "上海市")'};try{n.logger.info("Fetching all job list pages from Duliday API...");const{items:a}=await jt(t,r,{brandAlias:e.brandAlias??null,cityName:e.cityName??null,include:Ut});let o=Xr(a);!o&&e.brandAlias&&(o=await ea(e.brandAlias,t)),!o&&e.brandAlias&&(o=e.brandAlias),n.logger.info(`Resolved default brand: ${o??"自动推断"}, converting ${a.length} positions...`);const i=wr(a,o,e.cityName);ne(i),n.logger.info(`Brand config saved: ${i.brands.length} brands, ${i.brands.reduce((e,n)=>e+n.stores.length,0)} stores`);const s=i.brands.reduce((e,n)=>e+n.stores.length,0),l=i.brands.reduce((e,n)=>e+n.stores.reduce((e,n)=>e+n.positions.length,0),0);return{success:!0,brandsCount:i.brands.length,storesCount:s,positionsCount:l,updatedAt:(new Date).toISOString()}}catch(e){return{success:!1,brandsCount:0,storesCount:0,positionsCount:0,updatedAt:(new Date).toISOString(),error:e instanceof Error?e.message:String(e)}}}});function Zr(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)}function Xr(e){for(const n of e){if(!Zr(n))continue;const e=Zr(n.basicInfo)?n.basicInfo:null;if(e&&"string"==typeof e.brandName&&e.brandName)return e.brandName}}async function ea(e,n){try{const t=await Jn(n),r=e.trim().toLowerCase().replace(/[\s._-]+/g,"");return t.get(r)}catch{return}}var na=e({name:"smart-reply-agent",tools:[fr,Qr]});na.listen().catch(e=>{console.error("Fatal error:",e),process.exit(1)});