33 BailianError ,
44 detectOutputFormat ,
55 mcpWebSearchPath ,
6+ YouComMcpClient ,
67 type FlagsDef ,
78} from "bailian-cli-core" ;
89import { createSpinner , emitResult } from "bailian-cli-runtime" ;
@@ -16,38 +17,71 @@ const WEB_SEARCH_FLAGS = {
1617 description : "Number of search results (default: 10)" ,
1718 } ,
1819 listTools : { type : "switch" , description : "List available MCP tools and exit" } ,
20+ provider : {
21+ type : "string" ,
22+ valueHint : "<name>" ,
23+ description : "Search provider: 'dashscope' (default) or 'youcom'"
24+ } ,
1925} satisfies FlagsDef ;
2026
2127export default defineCommand ( {
22- description : "Search the web using DashScope MCP WebSearch service " ,
23- auth : "apiKey " ,
24- usageArgs : "--query <text> [flags]" ,
28+ description : "Search the web using DashScope WebSearch or You.com " ,
29+ auth : "optionalApiKey " ,
30+ usageArgs : "--query <text> [--provider <name>] [ flags]" ,
2531 flags : WEB_SEARCH_FLAGS ,
2632 exampleArgs : [
2733 '--query "Alibaba Cloud Bailian latest features"' ,
2834 '--query "TypeScript 5.9 new features" --count 5' ,
29- '--query "Today\'s news"' ,
30- "--list-tools" ,
35+ '--query "Today\'s news" --provider youcom' ,
36+ '--query "AI developments" --provider dashscope' ,
37+ "--list-tools --provider youcom" ,
3138 ] ,
32- validate : ( f ) => ( ! f . listTools && ! f . query ? "Missing required flag: --query" : undefined ) ,
39+ validate : ( f ) => {
40+ if ( ! f . listTools && ! f . query ) return "Missing required flag: --query" ;
41+ if ( f . provider && ! [ "dashscope" , "youcom" ] . includes ( f . provider ) ) {
42+ return "Invalid provider. Use 'dashscope' or 'youcom'" ;
43+ }
44+ return undefined ;
45+ } ,
3346 async run ( ctx ) {
3447 const { settings, flags } = ctx ;
3548 const format = detectOutputFormat ( settings . output ) ;
49+
50+ // Determine provider
51+ const provider = flags . provider || "dashscope" ;
52+ const useYouCom = provider === "youcom" ;
3653
3754 // --- List tools mode ---
3855 if ( flags . listTools ) {
3956 if ( settings . dryRun ) {
40- emitResult ( { endpoint : ctx . client . url ( mcpWebSearchPath ( ) ) , action : "tools/list" } , format ) ;
57+ const endpoint = useYouCom
58+ ? "https://api.you.com"
59+ : ctx . client . url ( mcpWebSearchPath ( ) ) ;
60+ emitResult ( { endpoint, action : "tools/list" , provider } , format ) ;
4161 return ;
4262 }
4363
4464 try {
45- const client = ctx . client . mcp ( mcpWebSearchPath ( ) ) ;
46- await client . initialize ( ) ;
47- const tools = await client . listTools ( ) ;
48- emitResult ( { tools } , format ) ;
65+ if ( useYouCom ) {
66+ const config = YouComMcpClient . getConfig ( ) ;
67+ const youcomClient = YouComMcpClient . fromClient ( ctx . client , config . apiKey , config . baseUrl ) ;
68+ await youcomClient . initialize ( ) ;
69+ const tools = await youcomClient . listTools ( ) ;
70+ emitResult ( { tools, provider : "youcom" } , format ) ;
71+ } else {
72+ const client = ctx . client . mcp ( mcpWebSearchPath ( ) ) ;
73+ await client . initialize ( ) ;
74+ const tools = await client . listTools ( ) ;
75+ emitResult ( { tools, provider : "dashscope" } , format ) ;
76+ }
4977 } catch ( error ) {
50- rethrowWithWebSearchActivateHint ( error ) ;
78+ if ( useYouCom ) {
79+ // You.com specific error handling
80+ if ( error instanceof BailianError ) throw error ;
81+ throw new BailianError ( `You.com search error: ${ error instanceof Error ? error . message : 'Unknown error' } ` , 1 ) ;
82+ } else {
83+ rethrowWithWebSearchActivateHint ( error ) ;
84+ }
5185 }
5286 return ;
5387 }
@@ -56,11 +90,17 @@ export default defineCommand({
5690 const query = flags . query ;
5791
5892 if ( settings . dryRun ) {
93+ const endpoint = useYouCom
94+ ? "https://api.you.com/api/search"
95+ : ctx . client . url ( mcpWebSearchPath ( ) ) ;
96+ const toolName = useYouCom ? "youcom_web_search" : "bailian_web_search" ;
97+
5998 emitResult (
6099 {
61- endpoint : ctx . client . url ( mcpWebSearchPath ( ) ) ,
100+ endpoint,
62101 action : "tools/call" ,
63- tool : "bailian_web_search" ,
102+ tool : toolName ,
103+ provider,
64104 arguments : {
65105 query : query ! ,
66106 count : flags . count || undefined ,
@@ -71,62 +111,106 @@ export default defineCommand({
71111 return ;
72112 }
73113
74- // Initialize MCP client
75- const client = ctx . client . mcp ( mcpWebSearchPath ( ) ) ;
114+ // Initialize appropriate client
76115 const spinner = createSpinner ( "Initializing search..." ) ;
77116
78117 if ( ! settings . quiet ) spinner . start ( ) ;
79118
80119 try {
81- await client . initialize ( ) ;
120+ if ( useYouCom ) {
121+ // Use You.com MCP client
122+ const config = YouComMcpClient . getConfig ( ) ;
123+ const youcomClient = YouComMcpClient . fromClient ( ctx . client , config . apiKey , config . baseUrl ) ;
124+ await youcomClient . initialize ( ) ;
82125
83- if ( ! settings . quiet ) spinner . update ( "Searching..." ) ;
126+ if ( ! settings . quiet ) spinner . update ( "Searching with You.com ..." ) ;
84127
85- // Build tool arguments
86- const toolArgs : Record < string , unknown > = { query : query ! } ;
87- if ( flags . count ) toolArgs . count = flags . count ;
128+ // Build tool arguments
129+ const toolArgs : Record < string , unknown > = { query : query ! } ;
130+ if ( flags . count ) toolArgs . count = flags . count ;
88131
89- // Call the search tool
90- const result = await client . callTool ( "bailian_web_search " , toolArgs ) ;
132+ // Call the search tool
133+ const result = await youcomClient . callTool ( "youcom_web_search " , toolArgs ) ;
91134
92- // Handle error response
93- if ( result . isError ) {
94- const errText = result . content . map ( ( c ) => c . text || "" ) . join ( "\n" ) ;
95- throw new BailianError ( `Search error: ${ errText } ` ) ;
96- }
135+ // Handle error response
136+ if ( result . isError ) {
137+ const errText = result . content . map ( ( c ) => c . text || "" ) . join ( "\n" ) ;
138+ throw new BailianError ( `You.com search error: ${ errText } ` ) ;
139+ }
97140
98- if ( ! settings . quiet ) spinner . stop ( "Done." ) ;
141+ if ( ! settings . quiet ) spinner . stop ( "Done." ) ;
142+
143+ // Output results
144+ if ( format === "json" ) {
145+ emitResult ( { ...result , provider : "youcom" } , format ) ;
146+ } else {
147+ // Text mode - You.com results are already formatted
148+ for ( const item of result . content ) {
149+ if ( item . type === "text" && item . text ) {
150+ emitResult ( { text : item . text , provider : "youcom" } , format ) ;
151+ }
152+ }
153+ }
99154
100- // Output results — always structured to stdout
101- if ( format === "json" ) {
102- emitResult ( result , format ) ;
103155 } else {
104- // Text mode: try to extract pages for human-friendly display
105- for ( const item of result . content ) {
106- if ( item . type === "text" && item . text ) {
107- try {
108- const data = JSON . parse ( item . text ) as {
109- pages ?: Array < {
110- title ?: string ;
111- url ?: string ;
112- snippet ?: string ;
113- hostname ?: string ;
114- } > ;
115- } ;
116- if ( data . pages && Array . isArray ( data . pages ) ) {
117- emitResult ( { pages : data . pages , total : data . pages . length } , format ) ;
118- } else {
119- emitResult ( data , format ) ;
156+ // Use DashScope MCP client
157+ const client = ctx . client . mcp ( mcpWebSearchPath ( ) ) ;
158+ await client . initialize ( ) ;
159+
160+ if ( ! settings . quiet ) spinner . update ( "Searching with DashScope..." ) ;
161+
162+ // Build tool arguments
163+ const toolArgs : Record < string , unknown > = { query : query ! } ;
164+ if ( flags . count ) toolArgs . count = flags . count ;
165+
166+ // Call the search tool
167+ const result = await client . callTool ( "bailian_web_search" , toolArgs ) ;
168+
169+ // Handle error response
170+ if ( result . isError ) {
171+ const errText = result . content . map ( ( c ) => c . text || "" ) . join ( "\n" ) ;
172+ throw new BailianError ( `Search error: ${ errText } ` ) ;
173+ }
174+
175+ if ( ! settings . quiet ) spinner . stop ( "Done." ) ;
176+
177+ // Output results — always structured to stdout
178+ if ( format === "json" ) {
179+ emitResult ( { ...result , provider : "dashscope" } , format ) ;
180+ } else {
181+ // Text mode: try to extract pages for human-friendly display
182+ for ( const item of result . content ) {
183+ if ( item . type === "text" && item . text ) {
184+ try {
185+ const data = JSON . parse ( item . text ) as {
186+ pages ?: Array < {
187+ title ?: string ;
188+ url ?: string ;
189+ snippet ?: string ;
190+ hostname ?: string ;
191+ } > ;
192+ } ;
193+ if ( data . pages && Array . isArray ( data . pages ) ) {
194+ emitResult ( { pages : data . pages , total : data . pages . length , provider : "dashscope" } , format ) ;
195+ } else {
196+ emitResult ( { ...data , provider : "dashscope" } , format ) ;
197+ }
198+ } catch {
199+ emitResult ( { text : item . text , provider : "dashscope" } , format ) ;
120200 }
121- } catch {
122- emitResult ( { text : item . text } , format ) ;
123201 }
124202 }
125203 }
126204 }
127205 } catch ( error ) {
128206 spinner . stop ( "Failed." ) ;
129- rethrowWithWebSearchActivateHint ( error ) ;
207+ if ( useYouCom ) {
208+ // You.com specific error handling
209+ if ( error instanceof BailianError ) throw error ;
210+ throw new BailianError ( `You.com search error: ${ error instanceof Error ? error . message : 'Unknown error' } ` , 1 ) ;
211+ } else {
212+ rethrowWithWebSearchActivateHint ( error ) ;
213+ }
130214 }
131215 } ,
132216} ) ;
0 commit comments