@@ -76,4 +76,95 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend(DashScope)",
7676 expect ( data . recommendations ?. [ 0 ] ?. model ) . toBeDefined ( ) ;
7777 expect ( data . recommendations ?. [ 0 ] ?. reason ) . toBeDefined ( ) ;
7878 } , 120_000 ) ;
79+
80+ // ---- 模型偏好:正例 ----
81+
82+ test ( "scoped 偏好 — 限定系列时 intent 含 modelPreference.mode=scoped" , async ( ) => {
83+ const { stdout, stderr, exitCode } = await runCli ( [
84+ "advisor" ,
85+ "recommend" ,
86+ "--dry-run" ,
87+ "--message" ,
88+ "deepseek系列中哪个模型最适合用来进行快速推理" ,
89+ "--non-interactive" ,
90+ "--output" ,
91+ "json" ,
92+ ] ) ;
93+ expect ( exitCode , stderr ) . toBe ( 0 ) ;
94+ const data = parseStdoutJson < {
95+ intent ?: { modelPreference ?: { mode ?: string ; targets ?: string [ ] } } ;
96+ } > ( stdout ) ;
97+ expect ( data . intent ?. modelPreference ?. mode ) . toBe ( "scoped" ) ;
98+ expect ( data . intent ?. modelPreference ?. targets ?. length ) . toBeGreaterThan ( 0 ) ;
99+ expect (
100+ data . intent ?. modelPreference ?. targets ?. some ( ( target ) =>
101+ target . toLowerCase ( ) . includes ( "deepseek" ) ,
102+ ) ,
103+ ) . toBe ( true ) ;
104+ } , 60_000 ) ;
105+
106+ test ( "comparison 偏好 — 对比模型时 intent 含 modelPreference.mode=comparison" , async ( ) => {
107+ const { stdout, stderr, exitCode } = await runCli ( [
108+ "advisor" ,
109+ "recommend" ,
110+ "--dry-run" ,
111+ "--message" ,
112+ "qwen-max和deepseek-v3哪个更适合做代码生成" ,
113+ "--non-interactive" ,
114+ "--output" ,
115+ "json" ,
116+ ] ) ;
117+ expect ( exitCode , stderr ) . toBe ( 0 ) ;
118+ const data = parseStdoutJson < {
119+ intent ?: { modelPreference ?: { mode ?: string ; targets ?: string [ ] } } ;
120+ } > ( stdout ) ;
121+ expect ( data . intent ?. modelPreference ?. mode ) . toBe ( "comparison" ) ;
122+ expect ( data . intent ?. modelPreference ?. targets ?. length ) . toBeGreaterThanOrEqual ( 2 ) ;
123+ } , 60_000 ) ;
124+
125+ test ( "excludes 偏好 — 排除模型时 intent 识别出 modelPreference" , async ( ) => {
126+ const { stdout, stderr, exitCode } = await runCli ( [
127+ "advisor" ,
128+ "recommend" ,
129+ "--dry-run" ,
130+ "--message" ,
131+ "不要qwen,推荐一个适合文本生成的模型" ,
132+ "--non-interactive" ,
133+ "--output" ,
134+ "json" ,
135+ ] ) ;
136+ expect ( exitCode , stderr ) . toBe ( 0 ) ;
137+ const data = parseStdoutJson < {
138+ intent ?: {
139+ modelPreference ?: { mode ?: string ; excludes ?: string [ ] ; targets ?: string [ ] } ;
140+ } ;
141+ } > ( stdout ) ;
142+ const pref = data . intent ?. modelPreference ;
143+ expect ( pref ) . toBeDefined ( ) ;
144+ const hasExcludes =
145+ ( pref ?. excludes ?. length ?? 0 ) > 0 ||
146+ ( pref ?. mode !== "unconstrained" && pref ?. mode !== undefined ) ;
147+ expect ( hasExcludes ) . toBe ( true ) ;
148+ } , 60_000 ) ;
149+
150+ // ---- 模型偏好:反例 ----
151+
152+ test ( "无偏好 — 普通需求查询时 intent 不含 modelPreference 或 mode=unconstrained" , async ( ) => {
153+ const { stdout, stderr, exitCode } = await runCli ( [
154+ "advisor" ,
155+ "recommend" ,
156+ "--dry-run" ,
157+ "--message" ,
158+ "我要做一个能理解图片的客服机器人" ,
159+ "--non-interactive" ,
160+ "--output" ,
161+ "json" ,
162+ ] ) ;
163+ expect ( exitCode , stderr ) . toBe ( 0 ) ;
164+ const data = parseStdoutJson < {
165+ intent ?: { modelPreference ?: { mode ?: string } } ;
166+ } > ( stdout ) ;
167+ const mode = data . intent ?. modelPreference ?. mode ;
168+ expect ( mode === undefined || mode === "unconstrained" ) . toBe ( true ) ;
169+ } , 60_000 ) ;
79170} ) ;
0 commit comments