11import { LinkupIcon } from '@/components/icons'
22import { AuthMode , type BlockConfig , type BlockMeta , IntegrationType } from '@/blocks/types'
3- import type { LinkupSearchToolResponse } from '@/tools/linkup/types'
3+ import type { LinkupResponse } from '@/tools/linkup/types'
44
5- export const LinkupBlock : BlockConfig < LinkupSearchToolResponse > = {
5+ /**
6+ * Blocks saved before the operation dropdown existed have no stored
7+ * `operation`, so search fields are gated on "not fetch" rather than on
8+ * `linkup_search` to keep those blocks rendering and serializing as before.
9+ */
10+ const SEARCH_CONDITION = { field : 'operation' , value : 'linkup_fetch' , not : true }
11+ const FETCH_CONDITION = { field : 'operation' , value : 'linkup_fetch' }
12+
13+ export const LinkupBlock : BlockConfig < LinkupResponse > = {
614 type : 'linkup' ,
715 name : 'Linkup' ,
816 description : 'Search the web with Linkup' ,
917 authMode : AuthMode . ApiKey ,
10- longDescription : 'Integrate Linkup into the workflow. Can search the web.' ,
18+ longDescription :
19+ 'Integrate Linkup into the workflow. Can search the web and fetch the contents of a webpage as markdown.' ,
1120 docsLink : 'https://docs.sim.ai/integrations/linkup' ,
1221 category : 'tools' ,
1322 integrationType : IntegrationType . Search ,
@@ -16,20 +25,42 @@ export const LinkupBlock: BlockConfig<LinkupSearchToolResponse> = {
1625 canvasPresentation : {
1726 defaultTitle : 'Linkup' ,
1827 sentences : {
28+ /** Painted for blocks saved before the operation dropdown existed. */
1929 default : [
20- { text : 'Search the web for' , field : 'q' , core : true } ,
30+ 'Search the web' ,
31+ { text : 'for' , field : 'q' } ,
2132 { text : ', within' , field : 'includeDomains' } ,
2233 { text : ', since' , field : 'fromDate' } ,
2334 ] ,
35+ byOperation : {
36+ linkup_search : [
37+ { text : 'Search the web for' , field : 'q' , core : true } ,
38+ { text : ', within' , field : 'includeDomains' } ,
39+ { text : ', since' , field : 'fromDate' } ,
40+ ] ,
41+ linkup_fetch : [ { text : 'Fetch' , field : 'url' , after : 'as markdown' , core : true } ] ,
42+ } ,
2443 } ,
2544 } ,
2645
2746 subBlocks : [
47+ {
48+ id : 'operation' ,
49+ title : 'Operation' ,
50+ type : 'dropdown' ,
51+ options : [
52+ { label : 'Search' , id : 'linkup_search' } ,
53+ { label : 'Fetch' , id : 'linkup_fetch' } ,
54+ ] ,
55+ value : ( ) => 'linkup_search' ,
56+ } ,
57+ // Search operation inputs
2858 {
2959 id : 'q' ,
3060 title : 'Search Query' ,
3161 type : 'long-input' ,
3262 placeholder : 'Enter your search query' ,
63+ condition : SEARCH_CONDITION ,
3364 required : true ,
3465 } ,
3566 {
@@ -41,6 +72,7 @@ export const LinkupBlock: BlockConfig<LinkupSearchToolResponse> = {
4172 { label : 'Search' , id : 'searchResults' } ,
4273 ] ,
4374 value : ( ) => 'sourcedAnswer' ,
75+ condition : SEARCH_CONDITION ,
4476 } ,
4577 {
4678 id : 'depth' ,
@@ -51,30 +83,35 @@ export const LinkupBlock: BlockConfig<LinkupSearchToolResponse> = {
5183 { label : 'Deep' , id : 'deep' } ,
5284 ] ,
5385 value : ( ) => 'standard' ,
86+ condition : SEARCH_CONDITION ,
5487 } ,
5588 {
5689 id : 'includeImages' ,
5790 title : 'Include Images' ,
5891 type : 'switch' ,
92+ condition : SEARCH_CONDITION ,
5993 mode : 'advanced' ,
6094 } ,
6195 {
6296 id : 'includeInlineCitations' ,
6397 title : 'Include Inline Citations' ,
6498 type : 'switch' ,
99+ condition : SEARCH_CONDITION ,
65100 mode : 'advanced' ,
66101 } ,
67102 {
68103 id : 'includeSources' ,
69104 title : 'Include Sources' ,
70105 type : 'switch' ,
106+ condition : SEARCH_CONDITION ,
71107 mode : 'advanced' ,
72108 } ,
73109 {
74110 id : 'fromDate' ,
75111 title : 'From Date' ,
76112 type : 'short-input' ,
77113 placeholder : 'YYYY-MM-DD' ,
114+ condition : SEARCH_CONDITION ,
78115 mode : 'advanced' ,
79116 wandConfig : {
80117 enabled : true ,
@@ -95,6 +132,7 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
95132 title : 'To Date' ,
96133 type : 'short-input' ,
97134 placeholder : 'YYYY-MM-DD' ,
135+ condition : SEARCH_CONDITION ,
98136 mode : 'advanced' ,
99137 wandConfig : {
100138 enabled : true ,
@@ -115,13 +153,44 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
115153 title : 'Include Domains' ,
116154 type : 'long-input' ,
117155 placeholder : 'example.com, another.com (comma-separated)' ,
156+ condition : SEARCH_CONDITION ,
118157 mode : 'advanced' ,
119158 } ,
120159 {
121160 id : 'excludeDomains' ,
122161 title : 'Exclude Domains' ,
123162 type : 'long-input' ,
124163 placeholder : 'example.com, another.com (comma-separated)' ,
164+ condition : SEARCH_CONDITION ,
165+ mode : 'advanced' ,
166+ } ,
167+ // Fetch operation inputs
168+ {
169+ id : 'url' ,
170+ title : 'URL' ,
171+ type : 'short-input' ,
172+ placeholder : 'https://example.com' ,
173+ condition : FETCH_CONDITION ,
174+ required : true ,
175+ } ,
176+ {
177+ id : 'renderJs' ,
178+ title : 'Render JavaScript' ,
179+ type : 'switch' ,
180+ condition : FETCH_CONDITION ,
181+ } ,
182+ {
183+ id : 'includeRawHtml' ,
184+ title : 'Include Raw HTML' ,
185+ type : 'switch' ,
186+ condition : FETCH_CONDITION ,
187+ mode : 'advanced' ,
188+ } ,
189+ {
190+ id : 'extractImages' ,
191+ title : 'Extract Images' ,
192+ type : 'switch' ,
193+ condition : FETCH_CONDITION ,
125194 mode : 'advanced' ,
126195 } ,
127196 {
@@ -136,12 +205,24 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
136205 ] ,
137206
138207 tools : {
139- access : [ 'linkup_search' ] ,
208+ access : [ 'linkup_search' , 'linkup_fetch' ] ,
209+ config : {
210+ tool : ( params ) => {
211+ switch ( params . operation ) {
212+ case 'linkup_fetch' :
213+ return 'linkup_fetch'
214+ default :
215+ return 'linkup_search'
216+ }
217+ } ,
218+ } ,
140219 } ,
141220
142221 inputs : {
143- q : { type : 'string' , description : 'Search query ' } ,
222+ operation : { type : 'string' , description : 'Operation to perform ' } ,
144223 apiKey : { type : 'string' , description : 'Linkup API key' } ,
224+ // Search operation
225+ q : { type : 'string' , description : 'Search query' } ,
145226 depth : { type : 'string' , description : 'Search depth level' } ,
146227 outputType : { type : 'string' , description : 'Output format type' } ,
147228 includeImages : { type : 'boolean' , description : 'Include images in results' } ,
@@ -157,11 +238,22 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
157238 type : 'string' ,
158239 description : 'Domains to exclude from search (comma-separated)' ,
159240 } ,
241+ // Fetch operation
242+ url : { type : 'string' , description : 'URL of the webpage to fetch' } ,
243+ renderJs : { type : 'boolean' , description : 'Render JavaScript before extracting content' } ,
244+ includeRawHtml : { type : 'boolean' , description : 'Include the raw HTML in the response' } ,
245+ extractImages : { type : 'boolean' , description : 'Extract images from the webpage' } ,
160246 } ,
161247
162248 outputs : {
249+ // Search output
163250 answer : { type : 'string' , description : 'Generated answer' } ,
164251 sources : { type : 'json' , description : 'Source references' } ,
252+ // Fetch output
253+ markdown : { type : 'string' , description : 'Webpage content as markdown' } ,
254+ rawHtml : { type : 'string' , description : 'Raw HTML of the webpage, when requested' } ,
255+ images : { type : 'json' , description : '[{alt, url}] — images extracted from the webpage' } ,
256+ favicon : { type : 'string' , description : 'URL of the website favicon' } ,
165257 } ,
166258}
167259
@@ -258,5 +350,11 @@ export const LinkupBlockMeta = {
258350 content :
259351 '# Monitor Topic Mentions\n\nTrack fresh mentions of a topic or competitor.\n\n## Steps\n1. Set the search query to the brand, competitor, or topic to monitor.\n2. Use the Search output type and set the from date to the start of the window you want to cover.\n3. Optionally restrict to news or specific domains.\n4. Filter the results to genuinely new or relevant mentions and summarize each.\n\n## Output\nA list of new mentions with source URL, date, and a one-line summary of each.' ,
260352 } ,
353+ {
354+ name : 'fetch-page-markdown' ,
355+ description : 'Use Linkup Fetch to turn a webpage into clean markdown for downstream steps.' ,
356+ content :
357+ '# Fetch Page Markdown\n\nRead the contents of a specific webpage with Linkup.\n\n## Steps\n1. Use the Fetch operation with the full URL of the page.\n2. Enable Render JavaScript for single-page apps or pages that load their content client-side.\n3. Enable Extract Images when the page images matter, and Include Raw HTML only when a later step needs the original markup.\n4. Pass the markdown to a summarizer, extractor, or knowledge base.\n\n## Output\nThe page content as markdown, plus any extracted images and the raw HTML when requested.' ,
358+ } ,
261359 ] ,
262360} as const satisfies BlockMeta
0 commit comments