research-agent-ui 0.1.126 → 0.1.128
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.
- package/dist/api/handlers/page-tips.d.ts +2 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api.cjs +11 -3
- package/dist/api.mjs +91 -49
- package/package.json +6 -6
package/dist/api/index.d.ts
CHANGED
package/dist/api.cjs
CHANGED
|
@@ -7,7 +7,15 @@ ${r.slice(0,15e3)}
|
|
|
7
7
|
${l}
|
|
8
8
|
|
|
9
9
|
Generate ${a} follow-up questions that would help readers dive deeper into this article.`,{text:f}=await(0,t.generateText)({model:c,messages:[{role:`system`,content:u},{role:`user`,content:d}]}),p=f.split(`
|
|
10
|
-
`).map(e=>e.trim()).filter(e=>e.length>0).map(e=>e.replace(/^[\d\-\*\.\)]+\s*/,``).trim()).filter(e=>e.length>10).slice(0,a);return Response.json({extract:p,success:!0})}catch(e){return console.error(`Error generating follow-up questions:`,e),Response.json({error:`An error occurred while generating follow-up questions`,details:e instanceof Error?e.message:String(e)},{status:500})}}}function m(e){return async e=>{try{let{
|
|
10
|
+
`).map(e=>e.trim()).filter(e=>e.length>0).map(e=>e.replace(/^[\d\-\*\.\)]+\s*/,``).trim()).filter(e=>e.length>10).slice(0,a);return Response.json({extract:p,success:!0})}catch(e){return console.error(`Error generating follow-up questions:`,e),Response.json({error:`An error occurred while generating follow-up questions`,details:e instanceof Error?e.message:String(e)},{status:500})}}}function m(e){return async e=>{try{let{title:r=``,content:i,maxTips:a=4,chatModel:o}=await e.json();if(!i)return Response.json({error:`Content is required`},{status:400});let s=new n.default,c;try{c=await s.loadChatModel(o?.providerId,o?.key)}catch(e){return Response.json({error:e instanceof Error?e.message:`Failed to load language model`},{status:500})}let l=`You are a helpful AI that surfaces short, useful tips about a page the reader currently has open.
|
|
11
|
+
Generate ${a} concise tips (each a single sentence) highlighting the most useful takeaways or things worth noticing on the page.
|
|
12
|
+
Return ONLY the tips, one per line, without numbering or bullet points.`,u=`Page title: ${r}
|
|
13
|
+
|
|
14
|
+
Page content:
|
|
15
|
+
${i.slice(0,15e3)}
|
|
16
|
+
|
|
17
|
+
Generate ${a} short tips about this page.`,{text:d}=await(0,t.generateText)({model:c,messages:[{role:`system`,content:l},{role:`user`,content:u}]}),f=d.split(`
|
|
18
|
+
`).map(e=>e.trim()).filter(e=>e.length>0).map(e=>e.replace(/^[\d\-\*\.\)]+\s*/,``).trim()).filter(e=>e.length>10).slice(0,a);return Response.json({tips:f,success:!0})}catch(e){return console.error(`Error generating page tips:`,e),Response.json({error:`An error occurred while generating page tips`,details:e instanceof Error?e.message:String(e)},{status:500})}}}function h(e){return async e=>{try{let{article:r,question:i,chatHistory:a=[],chatModel:o}=await e.json();if(!r||!i)return Response.json({error:`Article and question are required`},{status:400});let s=new n.default,c;try{c=await s.loadChatModel(o?.providerId,o?.key)}catch(e){return Response.json({error:e instanceof Error?e.message:`Failed to load language model`},{status:500})}let l=a.length>0?`\n\nPrevious conversation:\n${a.map(e=>`${e.role===`user`?`User`:`Assistant`}: ${e.content}`).join(`
|
|
11
19
|
`)}`:``,u=`Article content:
|
|
12
20
|
${r.slice(0,15e3)}
|
|
13
21
|
|
|
@@ -17,6 +25,6 @@ User question: ${i}
|
|
|
17
25
|
|
|
18
26
|
Please provide a helpful answer based on the article content above.`,{text:d}=await(0,t.generateText)({model:c,messages:[{role:`system`,content:`You are a helpful AI assistant that answers questions about articles.
|
|
19
27
|
Provide clear, concise, and accurate answers based on the article content provided.
|
|
20
|
-
If the answer is not in the article, say so.`},{role:`user`,content:u}]});return Response.json({content:d,success:!0})}catch(e){return console.error(`Error in article Q&A:`,e),Response.json({error:`An error occurred while generating the answer`,details:e instanceof Error?e.message:String(e)},{status:500})}}}function h(e){let{chats:t,messages:n}=e.schema;return{GET:async i=>{try{let i=e.getDB(),a=await e.requireUserId(),o=await i.select({id:t.id,title:t.title,createdAt:t.createdAt,focusMode:t.focusMode,userId:t.userId,files:t.files,messageCount:(0,r.count)(n.id),lastMessageAt:(0,r.max)(n.createdAt)}).from(t).leftJoin(n,(0,r.and)((0,r.eq)(n.chatId,t.id),(0,r.eq)(n.role,`user`))).where((0,r.eq)(t.userId,a)).groupBy(t.id,t.title,t.createdAt,t.focusMode,t.userId,t.files).orderBy(r.sql`${t.createdAt} DESC`);return Response.json({chats:o},{status:200})}catch(e){return e instanceof Error&&e.message===`Unauthorized`?Response.json({message:`Authentication required`},{status:401}):(console.error(`Error in getting chats: `,e),Response.json({message:`An error has occurred.`},{status:500}))}},DELETE:async i=>{try{let i=e.getDB(),a=await e.requireUserId(),o=await i.query.chats.findMany({where:(0,r.eq)(t.userId,a),columns:{id:!0}});if(o.length>0){let e=o.map(e=>e.id);await i.delete(n).where((0,r.inArray)(n.chatId,e)),await i.delete(t).where((0,r.eq)(t.userId,a))}return Response.json({message:`All chats deleted`},{status:200})}catch(e){return e instanceof Error&&e.message===`Unauthorized`?Response.json({message:`Authentication required`},{status:401}):(console.error(`Error in deleting all chats: `,e),Response.json({message:`An error has occurred.`},{status:500}))}}}}function g(e){let{chats:t,messages:n}=e.schema;return{GET:async(i,{params:a})=>{try{let i=e.getDB(),{id:o}=await a,s;try{s=await e.requireUserId()}catch{s=void 0}let c=await i.query.chats.findFirst({where:(0,r.eq)(t.id,o)});if(!c)return Response.json({message:`Chat not found`},{status:404});if(!(c.userId===s||c.isPublic))return Response.json({message:`Unauthorized - this chat is private`},{status:403});let l=await i.query.messages.findMany({where:(0,r.eq)(n.chatId,o)});return Response.json({chat:c,messages:l},{status:200})}catch(e){return console.error(`Error in getting chat by id: `,e),Response.json({message:`An error has occurred.`},{status:500})}},DELETE:async(i,{params:a})=>{try{let i=e.getDB(),{id:o}=await a,s=await e.requireUserId();return await i.query.chats.findFirst({where:(0,r.and)((0,r.eq)(t.id,o),(0,r.eq)(t.userId,s))})?(await i.delete(t).where((0,r.eq)(t.id,o)).execute(),await i.delete(n).where((0,r.eq)(n.chatId,o)).execute(),Response.json({message:`Chat deleted successfully`},{status:200})):Response.json({message:`Chat not found`},{status:404})}catch(e){return e instanceof Error&&e.message===`Unauthorized`?Response.json({message:`Authentication required`},{status:401}):(console.error(`Error in deleting chat by id: `,e),Response.json({message:`An error has occurred.`},{status:500}))}}}}function _(e){let{chats:t,messages:n}=e.schema;return{GET:async i=>{try{let a=e.getDB(),o=await e.requireUserId(),{searchParams:s}=new URL(i.url),c=s.get(`q`);if(!c||c.trim().length===0)return Response.json({chats:[]},{status:200});let l=`%${c.trim()}%`,u=await a.select({id:t.id,title:t.title,createdAt:t.createdAt,focusMode:t.focusMode,userId:t.userId,files:t.files}).from(t).where((0,r.and)((0,r.eq)(t.userId,o),(0,r.like)(t.title,l))).orderBy(r.sql`${t.createdAt} DESC`),d=await a.selectDistinct({id:t.id,title:t.title,createdAt:t.createdAt,focusMode:t.focusMode,userId:t.userId,files:t.files}).from(n).innerJoin(t,(0,r.eq)(n.chatId,t.id)).where((0,r.and)((0,r.eq)(t.userId,o),(0,r.or)((0,r.like)(n.content,l)))).orderBy(r.sql`${t.createdAt} DESC`),f=[...u,...d],p=Array.from(new Map(f.map(e=>[e.id,e])).values()),m=p.map(e=>e.id),h=m.length?await a.select({chatId:n.chatId,count:r.sql`count(*)`}).from(n).where((0,r.and)(r.sql`${n.chatId} IN (${r.sql.join(m.map(e=>r.sql`${e}`),r.sql`, `)})`,(0,r.eq)(n.role,`user`))).groupBy(n.chatId):[],g=new Map(h.map(e=>[e.chatId,Number(e.count)])),_=p.map(e=>({...e,messageCount:g.get(e.id)||0}));return Response.json({chats:_},{status:200})}catch(e){return e instanceof Error&&e.message===`Unauthorized`?Response.json({message:`Authentication required`},{status:401}):(console.error(`Error searching chats:`,e),Response.json({message:`An error has occurred.`},{status:500}))}}}}function v(e){let{chats:t}=e.schema;return{POST:async n=>{try{let i=e.getDB(),{chatId:a}=await n.json();if(!a)return Response.json({success:!1,error:`Chat ID is required`},{status:400});let o=await e.requireUserId(),s=await i.query.chats.findFirst({where:(0,r.eq)(t.id,a)});if(!s)return Response.json({success:!1,error:`Chat not found`},{status:404});if(s.userId!==o)return Response.json({success:!1,error:`Unauthorized`},{status:403});await i.update(t).set({isPublic:1}).where((0,r.eq)(t.id,a)).execute();let c=`${new URL(n.url).origin}/c/${a}`;return Response.json({success:!0,data:{chatId:a,shareUrl:c}})}catch(e){return e instanceof Error&&e.message===`Unauthorized`?Response.json({success:!1,error:`Authentication required`},{status:401}):(console.error(`Error in making chat public: `,e),Response.json({success:!1,error:`An error has occurred.`},{status:500}))}}}}function y(e){let{chats:t}=e.schema;return{POST:async a=>{try{let o=await a.json(),s=o.chatHistory.filter(e=>e.role===`user`||e.role===`assistant`).map(e=>({role:e.role,content:String(e.content??``)}));if(s.length===0)return Response.json({message:`No conversation content`},{status:400});let c=await new n.default().loadChatModel(o.chatModel.providerId,o.chatModel.key),l=await(0,i.default)({chat_history:s},c);if(!l)return Response.json({message:`Failed to generate title`},{status:500});let u=e.getUserId?await e.getUserId():null;if(u&&o.chatId)try{let n=e.getDB(),i=await n.query.chats.findFirst({where:(0,r.eq)(t.id,o.chatId)});i&&i.userId===u&&await n.update(t).set({title:l}).where((0,r.eq)(t.id,o.chatId)).execute()}catch(e){console.error(`Failed to persist chat title:`,e)}return Response.json({title:l},{status:200})}catch(e){return console.error(`Error generating chat title:`,e),Response.json({message:`Failed to generate title`},{status:500})}}}}var b=[`assistant`,`user`,`source`,`suggestion`];function x(e){let t=[],n=e;for(let e=0;n!=null&&e<5;e++)t.push(n instanceof Error?n.message:String(n)),n=n instanceof Error?n.cause:void 0;return t.join(` <- caused by: `)}function S(e){return{POST:async t=>{try{let n=e.getDB(),r=await e.requireUserId(),{chatId:i,messageId:a,role:o,suggestions:s,content:c,sources:l}=await t.json();return!i||!a||!o?Response.json({message:`Missing required fields`},{status:400}):b.includes(o)?(await n.insert(e.messagesSchema).values({chatId:i,userId:r,messageId:a,role:o,content:c||``,suggestions:s||[],sources:l||[],createdAt:new Date().toISOString()}),Response.json({message:`Message saved successfully`},{status:200})):Response.json({message:`Invalid role: ${o}`},{status:400})}catch(e){return console.error(`Error saving message:`,x(e)),Response.json({message:`Failed to save message`},{status:500})}}}}function C(e){return{GET:async t=>{try{let r=new n.default,i=new URL(t.url).searchParams.get(`guest`),a=i===`true`;i===null&&(a=!await e.getSession());let o=(await r.getActiveProviders(a)).filter(e=>!e.chatModels.some(e=>e.key===`error`));return o.length===0?Response.json({providers:[],error:a?`No guest-safe AI providers available. Please sign in for more options.`:`No AI providers configured. Please add OPENROUTER_API_KEY to your environment variables or configure your own API keys in Settings.`},{status:200}):Response.json({providers:o,isGuest:a},{status:200})}catch(e){return console.error(`An error occurred while fetching providers`,e),Response.json({message:`An error has occurred.`},{status:500})}},POST:async e=>{try{let{type:t,config:r}=await e.json();if(!t||!r)return Response.json({message:`Missing required fields.`},{status:400});let i=await new n.default().addProvider(t,r);return Response.json({provider:i},{status:200})}catch(e){return console.error(`An error occurred while creating provider`,e),Response.json({message:`An error has occurred.`},{status:500})}}}}function w(){return{DELETE:async(e,{params:t})=>{try{let{id:e}=await t;return e?(await new n.default().removeProvider(e),Response.json({message:`Provider deleted successfully.`},{status:200})):Response.json({message:`Provider ID is required.`},{status:400})}catch(e){return console.error(`An error occurred while deleting provider`,e.message),Response.json({message:`An error has occurred.`},{status:500})}},PATCH:async(e,{params:t})=>{try{let{config:r}=await e.json(),{id:i}=await t;if(!i||!r)return Response.json({message:`Missing required fields.`},{status:400});let a=await new n.default().updateProvider(i,r);return Response.json({provider:a},{status:200})}catch(e){return console.error(`An error occurred while updating provider`,e.message),Response.json({message:`An error has occurred.`},{status:500})}}}}function T(){return{POST:async(e,{params:t})=>{try{let{id:r}=await t,i=await e.json();return!i.key||!i.name?Response.json({message:`Key and name must be provided`},{status:400}):(await new n.default().addProviderModel(r,i.type,i),Response.json({message:`Model added successfully`},{status:200}))}catch(e){return console.error(`An error occurred while adding provider model`,e),Response.json({message:`An error has occurred.`},{status:500})}},DELETE:async(e,{params:t})=>{try{let{id:r}=await t,i=await e.json();return i.key?(await new n.default().removeProviderModel(r,i.type,i.key),Response.json({message:`Model added successfully`},{status:200})):Response.json({message:`Key and name must be provided`},{status:400})}catch(e){return console.error(`An error occurred while deleting provider model`,e),Response.json({message:`An error has occurred.`},{status:500})}}}}function E(e){return{GET:async t=>{try{let t=e.getConfiguredMCPServers();return Response.json({servers:t},{status:200})}catch(e){return console.error(`An error occurred while fetching MCP servers`,e),Response.json({message:`An error has occurred.`},{status:500})}},POST:async t=>{try{let{type:n,name:r,config:i}=await t.json();if(!n||!r||!i)return Response.json({message:`Missing required fields.`},{status:400});let a=e.configManager.addMCPServer(n,r,i);return Response.json({server:a},{status:200})}catch(e){return console.error(`An error occurred while creating MCP server`,e),Response.json({message:`An error has occurred.`},{status:500})}}}}function D(e){return{DELETE:async(t,{params:n})=>{try{let{id:t}=await n;return t?(e.configManager.removeMCPServer(t),Response.json({message:`MCP server deleted successfully.`},{status:200})):Response.json({message:`MCP Server ID is required.`},{status:400})}catch(e){return console.error(`An error occurred while deleting MCP server`,e.message),Response.json({message:`An error has occurred.`},{status:500})}},PATCH:async(t,{params:n})=>{try{let{name:r,config:i}=await t.json(),{id:a}=await n;if(!a||!r||!i)return Response.json({message:`Missing required fields.`},{status:400});let o=await e.configManager.updateMCPServer(a,r,i);return Response.json({server:o},{status:200})}catch(e){return console.error(`An error occurred while updating MCP server`,e.message),Response.json({message:`An error has occurred.`},{status:500})}}}}function O(e){return{POST:async(t,{params:n})=>{try{let{enabled:r}=await t.json(),{id:i}=await n;if(!i||typeof r!=`boolean`)return Response.json({message:`Missing required fields.`},{status:400});let a=e.configManager.toggleMCPServer(i,r);return Response.json({server:a},{status:200})}catch(e){return console.error(`An error occurred while toggling MCP server`,e.message),Response.json({message:`An error has occurred.`},{status:500})}}}}var k={tech:{query:[`technology news`,`latest tech`,`AI`,`science and innovation`],links:[`techcrunch.com`,`wired.com`,`theverge.com`]},finance:{query:[`finance news`,`economy`,`stock market`,`investing`],links:[`bloomberg.com`,`cnbc.com`,`marketwatch.com`]},art:{query:[`art news`,`culture`,`modern art`,`cultural events`],links:[`artnews.com`,`hyperallergic.com`,`theartnewspaper.com`]},sports:{query:[`sports news`,`latest sports`,`cricket football tennis`],links:[`espn.com`,`bbc.com/sport`,`skysports.com`]},entertainment:{query:[`entertainment news`,`movies`,`TV shows`,`celebrities`],links:[`hollywoodreporter.com`,`variety.com`,`deadline.com`]}};function A(e={}){let t=e.searxngDomain??`https://search.qwksearch.com`;return{GET:async e=>{let n=new URL(e.url).searchParams,r=n.get(`q`),i=n.get(`cat`)||`general`,o=parseInt(n.get(`page`)||`1`,10),s=n.get(`lang`)||`en-US`,c=n.get(`safesearch`)===`true`,l=n.get(`recency`)||void 0,u=n.get(`publicInstances`)===`true`;if(!r)return Response.json({error:`Query parameter is required`},{status:400});let d=Date.now();try{let e=await(0,a.searchWeb)(r,{category:i,recency:l,safesearch:c,maxRetries:6,privateSearxng:!u&&t,proxy:``,lang:s,page:o});e&&(Array.isArray(e)?e.length>0:e.results&&e.results.length>0)||(e=await(0,a.searchWeb)(r,{category:i,recency:l,safesearch:c,maxRetries:6,privateSearxng:!1,proxy:``,lang:s,page:o}));let n=Date.now()-d;return e?Array.isArray(e)?Response.json({results:e,elapsedTime:n}):Response.json({...e,elapsedTime:n}):Response.json({results:[],suggestions:[],elapsedTime:n})}catch(e){return console.error(`Search error:`,e),Response.json({error:`Search failed`,results:[]},{status:500})}}}}function j(){return{GET:async e=>{try{let t=new URL(e.url).searchParams,n=t.get(`mode`)||`normal`,r=k[t.get(`topic`)||`tech`],i=[];if(n===`normal`){let e=new Set;i=(await Promise.all(r.links.flatMap(e=>r.query.map(async t=>(await(0,a.searchSearxng)(`site:${e} ${t}`,{engines:[`bing news`],pageno:1,language:`en`})).results)))).flat().filter(t=>{let n=t.url?.toLowerCase().trim();return!e.has(n)&&(e.add(n),!0)}).sort(()=>Math.random()-.5)}else i=(await(0,a.searchSearxng)(`site:${r.links[Math.floor(Math.random()*r.links.length)]} ${r.query[Math.floor(Math.random()*r.query.length)]}`,{engines:[`bing news`],pageno:1,language:`en`})).results;return Response.json({blogs:i},{status:200})}catch(e){return console.error(`An error occurred in discover route: ${e}`),Response.json({message:`An error has occurred`},{status:500})}}}}var M=[`google`,`duckduckgo`,`wikipedia`],N=3,P=3,F=Object.entries(l.default).map(([e,t])=>({domain:e,name:typeof t?.[0]==`string`?t[0]:``,rank:typeof t?.[1]==`number`?t[1]:2**53-1})),I=null;function L(){return I||=new s.default(F,{keys:[{name:`name`,weight:.6},{name:`domain`,weight:.4}],threshold:.1,ignoreLocation:!0,includeScore:!0,minMatchCharLength:3}),I}function R(e,t,n){return{domain:e,name:t,favicon:`https://www.google.com/s2/favicons?domain=${encodeURIComponent(e)}&sz=64`,rank:n}}function z(e){let t=(0,c.parse)(e);return t.domain&&t.isIcann?t.hostname:null}function B(e){let t=e.split(/\s+/).filter(Boolean),n=t[t.length-1]||``;if(n.length<3)return[];let r=L().search(n,{limit:12}).sort((e,t)=>Math.round((e.score??1)*10)-Math.round((t.score??1)*10)||e.item.rank-t.item.rank).map(({item:e})=>R(e.domain,e.name,e.rank)),i=z(n);return i&&!r.some(e=>e.domain===i)&&r.unshift(R(i,``,2**53-1)),r.slice(0,P)}async function V(e,t,n){let r=await(0,o.searchAutocompleteMulti)(e,t,n);if(r.length>0)return r;let i=t.split(/\s+/).filter(Boolean),a=Math.min(N,i.length-1);for(let r=a;r>=1;r--){let a=i.slice(-r).join(` `),s=i.slice(0,-r).join(` `),c=await(0,o.searchAutocompleteMulti)(e,a,n);if(c.length>0){let e=new Set;for(let n of c){let r=s?`${s} ${n}`:n;r.toLowerCase()!==t.toLowerCase()&&e.add(r)}if(e.size>0)return Array.from(e)}}return[]}function H(){return{GET:async e=>{let{searchParams:t}=new URL(e.url),n=t.get(`q`)?.trim(),r=t.get(`locale`)||`en-US`,i=t.get(`backends`),a=parseInt(t.get(`limit`)||`8`,10);if(!n)return Response.json({suggestions:[],domains:[]});let o=i?i.split(`,`).map(e=>e.trim()).filter(Boolean):M;try{let e=await V(o,n,r),t=B(n);return Response.json({suggestions:e.slice(0,a),domains:t})}catch(e){return console.error(`Autocomplete error:`,e),Response.json({suggestions:[],domains:[]},{status:500})}}}}function U(){return{POST:async e=>{let t=await e.json(),r=t.chatHistory.filter(e=>e.role===`user`||e.role===`assistant`).map(e=>({role:e.role,content:String(e.content??``)})),i=await new n.default().loadChatModel(t.chatModel.providerId,t.chatModel.key),a=(await(0,u.default)({chat_history:r,maxQuestions:t.maxQuestions},i)).flatMap(e=>(e.match(/\?/g)||[]).length>1?e.split(/\?/).map(e=>e.trim()).filter(e=>e.length>0).map(e=>e+`?`):[e]);return Response.json({suggestions:a},{status:200})}}}function W(e){return{POST:async t=>{let n;try{n=await t.json()}catch{return Response.json({error:`Invalid JSON input`},{status:500})}n.ip=t.headers?.get?.(`x-forwarded-for`)||t.headers?.get?.(`x-real-ip`)||`unknown`;let i=e.getDB(),a=await e.getUserId(),o=null;return a&&(o=await i.query.user.findFirst({where:(0,r.eq)(e.userSchema.id,a)})),o&&(n.apiKey=o.settings?.providerApiKeys?.find(e=>e.provider==n.provider)?.key),n.apiKey||(n.apiKey=n.provider==`groq`&&e.getEnv(`GROQ_API_KEY`)),n.apiKey?Response.json({error:`Language generation endpoint is deprecated. Please use /api/agent/chat instead.`},{status:501}):Response.json({error:`API key is required`},{status:500})}}}function G(e){return{POST:async t=>{try{let{text:n,prompt:r}=await t.json();if(!n||typeof n!=`string`)return Response.json({error:`Text is required and must be a string`},{status:400});let i=e.getEnv(`GROQ_API_KEY`);if(!i)return console.error(`GROQ_API_KEY is not configured`),Response.json({error:`AI service is not configured. Please contact the administrator.`},{status:500});let a=e.createGroq({apiKey:i})(`llama-3.3-70b-versatile`),o=r||`Rewrite the following text to improve clarity, grammar, and style while maintaining the original meaning and tone. Only return the rewritten text without any explanation or additional commentary:
|
|
28
|
+
If the answer is not in the article, say so.`},{role:`user`,content:u}]});return Response.json({content:d,success:!0})}catch(e){return console.error(`Error in article Q&A:`,e),Response.json({error:`An error occurred while generating the answer`,details:e instanceof Error?e.message:String(e)},{status:500})}}}function g(e){let{chats:t,messages:n}=e.schema;return{GET:async i=>{try{let i=e.getDB(),a=await e.requireUserId(),o=await i.select({id:t.id,title:t.title,createdAt:t.createdAt,focusMode:t.focusMode,userId:t.userId,files:t.files,messageCount:(0,r.count)(n.id),lastMessageAt:(0,r.max)(n.createdAt)}).from(t).leftJoin(n,(0,r.and)((0,r.eq)(n.chatId,t.id),(0,r.eq)(n.role,`user`))).where((0,r.eq)(t.userId,a)).groupBy(t.id,t.title,t.createdAt,t.focusMode,t.userId,t.files).orderBy(r.sql`${t.createdAt} DESC`);return Response.json({chats:o},{status:200})}catch(e){return e instanceof Error&&e.message===`Unauthorized`?Response.json({message:`Authentication required`},{status:401}):(console.error(`Error in getting chats: `,e),Response.json({message:`An error has occurred.`},{status:500}))}},DELETE:async i=>{try{let i=e.getDB(),a=await e.requireUserId(),o=await i.query.chats.findMany({where:(0,r.eq)(t.userId,a),columns:{id:!0}});if(o.length>0){let e=o.map(e=>e.id);await i.delete(n).where((0,r.inArray)(n.chatId,e)),await i.delete(t).where((0,r.eq)(t.userId,a))}return Response.json({message:`All chats deleted`},{status:200})}catch(e){return e instanceof Error&&e.message===`Unauthorized`?Response.json({message:`Authentication required`},{status:401}):(console.error(`Error in deleting all chats: `,e),Response.json({message:`An error has occurred.`},{status:500}))}}}}function _(e){let{chats:t,messages:n}=e.schema;return{GET:async(i,{params:a})=>{try{let i=e.getDB(),{id:o}=await a,s;try{s=await e.requireUserId()}catch{s=void 0}let c=await i.query.chats.findFirst({where:(0,r.eq)(t.id,o)});if(!c)return Response.json({message:`Chat not found`},{status:404});if(!(c.userId===s||c.isPublic))return Response.json({message:`Unauthorized - this chat is private`},{status:403});let l=await i.query.messages.findMany({where:(0,r.eq)(n.chatId,o)});return Response.json({chat:c,messages:l},{status:200})}catch(e){return console.error(`Error in getting chat by id: `,e),Response.json({message:`An error has occurred.`},{status:500})}},DELETE:async(i,{params:a})=>{try{let i=e.getDB(),{id:o}=await a,s=await e.requireUserId();return await i.query.chats.findFirst({where:(0,r.and)((0,r.eq)(t.id,o),(0,r.eq)(t.userId,s))})?(await i.delete(t).where((0,r.eq)(t.id,o)).execute(),await i.delete(n).where((0,r.eq)(n.chatId,o)).execute(),Response.json({message:`Chat deleted successfully`},{status:200})):Response.json({message:`Chat not found`},{status:404})}catch(e){return e instanceof Error&&e.message===`Unauthorized`?Response.json({message:`Authentication required`},{status:401}):(console.error(`Error in deleting chat by id: `,e),Response.json({message:`An error has occurred.`},{status:500}))}}}}function v(e){let{chats:t,messages:n}=e.schema;return{GET:async i=>{try{let a=e.getDB(),o=await e.requireUserId(),{searchParams:s}=new URL(i.url),c=s.get(`q`);if(!c||c.trim().length===0)return Response.json({chats:[]},{status:200});let l=`%${c.trim()}%`,u=await a.select({id:t.id,title:t.title,createdAt:t.createdAt,focusMode:t.focusMode,userId:t.userId,files:t.files}).from(t).where((0,r.and)((0,r.eq)(t.userId,o),(0,r.like)(t.title,l))).orderBy(r.sql`${t.createdAt} DESC`),d=await a.selectDistinct({id:t.id,title:t.title,createdAt:t.createdAt,focusMode:t.focusMode,userId:t.userId,files:t.files}).from(n).innerJoin(t,(0,r.eq)(n.chatId,t.id)).where((0,r.and)((0,r.eq)(t.userId,o),(0,r.or)((0,r.like)(n.content,l)))).orderBy(r.sql`${t.createdAt} DESC`),f=[...u,...d],p=Array.from(new Map(f.map(e=>[e.id,e])).values()),m=p.map(e=>e.id),h=m.length?await a.select({chatId:n.chatId,count:r.sql`count(*)`}).from(n).where((0,r.and)(r.sql`${n.chatId} IN (${r.sql.join(m.map(e=>r.sql`${e}`),r.sql`, `)})`,(0,r.eq)(n.role,`user`))).groupBy(n.chatId):[],g=new Map(h.map(e=>[e.chatId,Number(e.count)])),_=p.map(e=>({...e,messageCount:g.get(e.id)||0}));return Response.json({chats:_},{status:200})}catch(e){return e instanceof Error&&e.message===`Unauthorized`?Response.json({message:`Authentication required`},{status:401}):(console.error(`Error searching chats:`,e),Response.json({message:`An error has occurred.`},{status:500}))}}}}function y(e){let{chats:t}=e.schema;return{POST:async n=>{try{let i=e.getDB(),{chatId:a}=await n.json();if(!a)return Response.json({success:!1,error:`Chat ID is required`},{status:400});let o=await e.requireUserId(),s=await i.query.chats.findFirst({where:(0,r.eq)(t.id,a)});if(!s)return Response.json({success:!1,error:`Chat not found`},{status:404});if(s.userId!==o)return Response.json({success:!1,error:`Unauthorized`},{status:403});await i.update(t).set({isPublic:1}).where((0,r.eq)(t.id,a)).execute();let c=`${new URL(n.url).origin}/c/${a}`;return Response.json({success:!0,data:{chatId:a,shareUrl:c}})}catch(e){return e instanceof Error&&e.message===`Unauthorized`?Response.json({success:!1,error:`Authentication required`},{status:401}):(console.error(`Error in making chat public: `,e),Response.json({success:!1,error:`An error has occurred.`},{status:500}))}}}}function b(e){let{chats:t}=e.schema;return{POST:async a=>{try{let o=await a.json(),s=o.chatHistory.filter(e=>e.role===`user`||e.role===`assistant`).map(e=>({role:e.role,content:String(e.content??``)}));if(s.length===0)return Response.json({message:`No conversation content`},{status:400});let c=await new n.default().loadChatModel(o.chatModel.providerId,o.chatModel.key),l=await(0,i.default)({chat_history:s},c);if(!l)return Response.json({message:`Failed to generate title`},{status:500});let u=e.getUserId?await e.getUserId():null;if(u&&o.chatId)try{let n=e.getDB(),i=await n.query.chats.findFirst({where:(0,r.eq)(t.id,o.chatId)});i&&i.userId===u&&await n.update(t).set({title:l}).where((0,r.eq)(t.id,o.chatId)).execute()}catch(e){console.error(`Failed to persist chat title:`,e)}return Response.json({title:l},{status:200})}catch(e){return console.error(`Error generating chat title:`,e),Response.json({message:`Failed to generate title`},{status:500})}}}}var x=[`assistant`,`user`,`source`,`suggestion`];function S(e){let t=[],n=e;for(let e=0;n!=null&&e<5;e++)t.push(n instanceof Error?n.message:String(n)),n=n instanceof Error?n.cause:void 0;return t.join(` <- caused by: `)}function C(e){return{POST:async t=>{try{let n=e.getDB(),r=await e.requireUserId(),{chatId:i,messageId:a,role:o,suggestions:s,content:c,sources:l}=await t.json();return!i||!a||!o?Response.json({message:`Missing required fields`},{status:400}):x.includes(o)?(await n.insert(e.messagesSchema).values({chatId:i,userId:r,messageId:a,role:o,content:c||``,suggestions:s||[],sources:l||[],createdAt:new Date().toISOString()}),Response.json({message:`Message saved successfully`},{status:200})):Response.json({message:`Invalid role: ${o}`},{status:400})}catch(e){return console.error(`Error saving message:`,S(e)),Response.json({message:`Failed to save message`},{status:500})}}}}function w(e){return{GET:async t=>{try{let r=new n.default,i=new URL(t.url).searchParams.get(`guest`),a=i===`true`;i===null&&(a=!await e.getSession());let o=(await r.getActiveProviders(a)).filter(e=>!e.chatModels.some(e=>e.key===`error`));return o.length===0?Response.json({providers:[],error:a?`No guest-safe AI providers available. Please sign in for more options.`:`No AI providers configured. Please add OPENROUTER_API_KEY to your environment variables or configure your own API keys in Settings.`},{status:200}):Response.json({providers:o,isGuest:a},{status:200})}catch(e){return console.error(`An error occurred while fetching providers`,e),Response.json({message:`An error has occurred.`},{status:500})}},POST:async e=>{try{let{type:t,config:r}=await e.json();if(!t||!r)return Response.json({message:`Missing required fields.`},{status:400});let i=await new n.default().addProvider(t,r);return Response.json({provider:i},{status:200})}catch(e){return console.error(`An error occurred while creating provider`,e),Response.json({message:`An error has occurred.`},{status:500})}}}}function T(){return{DELETE:async(e,{params:t})=>{try{let{id:e}=await t;return e?(await new n.default().removeProvider(e),Response.json({message:`Provider deleted successfully.`},{status:200})):Response.json({message:`Provider ID is required.`},{status:400})}catch(e){return console.error(`An error occurred while deleting provider`,e.message),Response.json({message:`An error has occurred.`},{status:500})}},PATCH:async(e,{params:t})=>{try{let{config:r}=await e.json(),{id:i}=await t;if(!i||!r)return Response.json({message:`Missing required fields.`},{status:400});let a=await new n.default().updateProvider(i,r);return Response.json({provider:a},{status:200})}catch(e){return console.error(`An error occurred while updating provider`,e.message),Response.json({message:`An error has occurred.`},{status:500})}}}}function E(){return{POST:async(e,{params:t})=>{try{let{id:r}=await t,i=await e.json();return!i.key||!i.name?Response.json({message:`Key and name must be provided`},{status:400}):(await new n.default().addProviderModel(r,i.type,i),Response.json({message:`Model added successfully`},{status:200}))}catch(e){return console.error(`An error occurred while adding provider model`,e),Response.json({message:`An error has occurred.`},{status:500})}},DELETE:async(e,{params:t})=>{try{let{id:r}=await t,i=await e.json();return i.key?(await new n.default().removeProviderModel(r,i.type,i.key),Response.json({message:`Model added successfully`},{status:200})):Response.json({message:`Key and name must be provided`},{status:400})}catch(e){return console.error(`An error occurred while deleting provider model`,e),Response.json({message:`An error has occurred.`},{status:500})}}}}function D(e){return{GET:async t=>{try{let t=e.getConfiguredMCPServers();return Response.json({servers:t},{status:200})}catch(e){return console.error(`An error occurred while fetching MCP servers`,e),Response.json({message:`An error has occurred.`},{status:500})}},POST:async t=>{try{let{type:n,name:r,config:i}=await t.json();if(!n||!r||!i)return Response.json({message:`Missing required fields.`},{status:400});let a=e.configManager.addMCPServer(n,r,i);return Response.json({server:a},{status:200})}catch(e){return console.error(`An error occurred while creating MCP server`,e),Response.json({message:`An error has occurred.`},{status:500})}}}}function O(e){return{DELETE:async(t,{params:n})=>{try{let{id:t}=await n;return t?(e.configManager.removeMCPServer(t),Response.json({message:`MCP server deleted successfully.`},{status:200})):Response.json({message:`MCP Server ID is required.`},{status:400})}catch(e){return console.error(`An error occurred while deleting MCP server`,e.message),Response.json({message:`An error has occurred.`},{status:500})}},PATCH:async(t,{params:n})=>{try{let{name:r,config:i}=await t.json(),{id:a}=await n;if(!a||!r||!i)return Response.json({message:`Missing required fields.`},{status:400});let o=await e.configManager.updateMCPServer(a,r,i);return Response.json({server:o},{status:200})}catch(e){return console.error(`An error occurred while updating MCP server`,e.message),Response.json({message:`An error has occurred.`},{status:500})}}}}function k(e){return{POST:async(t,{params:n})=>{try{let{enabled:r}=await t.json(),{id:i}=await n;if(!i||typeof r!=`boolean`)return Response.json({message:`Missing required fields.`},{status:400});let a=e.configManager.toggleMCPServer(i,r);return Response.json({server:a},{status:200})}catch(e){return console.error(`An error occurred while toggling MCP server`,e.message),Response.json({message:`An error has occurred.`},{status:500})}}}}var A={tech:{query:[`technology news`,`latest tech`,`AI`,`science and innovation`],links:[`techcrunch.com`,`wired.com`,`theverge.com`]},finance:{query:[`finance news`,`economy`,`stock market`,`investing`],links:[`bloomberg.com`,`cnbc.com`,`marketwatch.com`]},art:{query:[`art news`,`culture`,`modern art`,`cultural events`],links:[`artnews.com`,`hyperallergic.com`,`theartnewspaper.com`]},sports:{query:[`sports news`,`latest sports`,`cricket football tennis`],links:[`espn.com`,`bbc.com/sport`,`skysports.com`]},entertainment:{query:[`entertainment news`,`movies`,`TV shows`,`celebrities`],links:[`hollywoodreporter.com`,`variety.com`,`deadline.com`]}};function j(e={}){let t=e.searxngDomain??`https://search.qwksearch.com`;return{GET:async e=>{let n=new URL(e.url).searchParams,r=n.get(`q`),i=n.get(`cat`)||`general`,o=parseInt(n.get(`page`)||`1`,10),s=n.get(`lang`)||`en-US`,c=n.get(`safesearch`)===`true`,l=n.get(`recency`)||void 0,u=n.get(`publicInstances`)===`true`;if(!r)return Response.json({error:`Query parameter is required`},{status:400});let d=Date.now();try{let e=await(0,a.searchWeb)(r,{category:i,recency:l,safesearch:c,maxRetries:6,privateSearxng:!u&&t,proxy:``,lang:s,page:o});e&&(Array.isArray(e)?e.length>0:e.results&&e.results.length>0)||(e=await(0,a.searchWeb)(r,{category:i,recency:l,safesearch:c,maxRetries:6,privateSearxng:!1,proxy:``,lang:s,page:o}));let n=Date.now()-d;return e?Array.isArray(e)?Response.json({results:e,elapsedTime:n}):Response.json({...e,elapsedTime:n}):Response.json({results:[],suggestions:[],elapsedTime:n})}catch(e){return console.error(`Search error:`,e),Response.json({error:`Search failed`,results:[]},{status:500})}}}}function M(){return{GET:async e=>{try{let t=new URL(e.url).searchParams,n=t.get(`mode`)||`normal`,r=A[t.get(`topic`)||`tech`],i=[];if(n===`normal`){let e=new Set;i=(await Promise.all(r.links.flatMap(e=>r.query.map(async t=>(await(0,a.searchSearxng)(`site:${e} ${t}`,{engines:[`bing news`],pageno:1,language:`en`})).results)))).flat().filter(t=>{let n=t.url?.toLowerCase().trim();return!e.has(n)&&(e.add(n),!0)}).sort(()=>Math.random()-.5)}else i=(await(0,a.searchSearxng)(`site:${r.links[Math.floor(Math.random()*r.links.length)]} ${r.query[Math.floor(Math.random()*r.query.length)]}`,{engines:[`bing news`],pageno:1,language:`en`})).results;return Response.json({blogs:i},{status:200})}catch(e){return console.error(`An error occurred in discover route: ${e}`),Response.json({message:`An error has occurred`},{status:500})}}}}var N=[`google`,`duckduckgo`,`wikipedia`],P=3,F=3,I=Object.entries(l.default).map(([e,t])=>({domain:e,name:typeof t?.[0]==`string`?t[0]:``,rank:typeof t?.[1]==`number`?t[1]:2**53-1})),L=null;function R(){return L||=new s.default(I,{keys:[{name:`name`,weight:.6},{name:`domain`,weight:.4}],threshold:.1,ignoreLocation:!0,includeScore:!0,minMatchCharLength:3}),L}function z(e,t,n){return{domain:e,name:t,favicon:`https://www.google.com/s2/favicons?domain=${encodeURIComponent(e)}&sz=64`,rank:n}}function B(e){let t=(0,c.parse)(e);return t.domain&&t.isIcann?t.hostname:null}function V(e){let t=e.split(/\s+/).filter(Boolean),n=t[t.length-1]||``;if(n.length<3)return[];let r=R().search(n,{limit:12}).sort((e,t)=>Math.round((e.score??1)*10)-Math.round((t.score??1)*10)||e.item.rank-t.item.rank).map(({item:e})=>z(e.domain,e.name,e.rank)),i=B(n);return i&&!r.some(e=>e.domain===i)&&r.unshift(z(i,``,2**53-1)),r.slice(0,F)}async function H(e,t,n){let r=await(0,o.searchAutocompleteMulti)(e,t,n);if(r.length>0)return r;let i=t.split(/\s+/).filter(Boolean),a=Math.min(P,i.length-1);for(let r=a;r>=1;r--){let a=i.slice(-r).join(` `),s=i.slice(0,-r).join(` `),c=await(0,o.searchAutocompleteMulti)(e,a,n);if(c.length>0){let e=new Set;for(let n of c){let r=s?`${s} ${n}`:n;r.toLowerCase()!==t.toLowerCase()&&e.add(r)}if(e.size>0)return Array.from(e)}}return[]}function U(){return{GET:async e=>{let{searchParams:t}=new URL(e.url),n=t.get(`q`)?.trim(),r=t.get(`locale`)||`en-US`,i=t.get(`backends`),a=parseInt(t.get(`limit`)||`8`,10);if(!n)return Response.json({suggestions:[],domains:[]});let o=i?i.split(`,`).map(e=>e.trim()).filter(Boolean):N;try{let e=await H(o,n,r),t=V(n);return Response.json({suggestions:e.slice(0,a),domains:t})}catch(e){return console.error(`Autocomplete error:`,e),Response.json({suggestions:[],domains:[]},{status:500})}}}}function W(){return{POST:async e=>{let t=await e.json(),r=t.chatHistory.filter(e=>e.role===`user`||e.role===`assistant`).map(e=>({role:e.role,content:String(e.content??``)})),i=await new n.default().loadChatModel(t.chatModel.providerId,t.chatModel.key),a=(await(0,u.default)({chat_history:r,maxQuestions:t.maxQuestions},i)).flatMap(e=>(e.match(/\?/g)||[]).length>1?e.split(/\?/).map(e=>e.trim()).filter(e=>e.length>0).map(e=>e+`?`):[e]);return Response.json({suggestions:a},{status:200})}}}function G(e){return{POST:async t=>{let n;try{n=await t.json()}catch{return Response.json({error:`Invalid JSON input`},{status:500})}n.ip=t.headers?.get?.(`x-forwarded-for`)||t.headers?.get?.(`x-real-ip`)||`unknown`;let i=e.getDB(),a=await e.getUserId(),o=null;return a&&(o=await i.query.user.findFirst({where:(0,r.eq)(e.userSchema.id,a)})),o&&(n.apiKey=o.settings?.providerApiKeys?.find(e=>e.provider==n.provider)?.key),n.apiKey||(n.apiKey=n.provider==`groq`&&e.getEnv(`GROQ_API_KEY`)),n.apiKey?Response.json({error:`Language generation endpoint is deprecated. Please use /api/agent/chat instead.`},{status:501}):Response.json({error:`API key is required`},{status:500})}}}function K(e){return{POST:async t=>{try{let{text:n,prompt:r}=await t.json();if(!n||typeof n!=`string`)return Response.json({error:`Text is required and must be a string`},{status:400});let i=e.getEnv(`GROQ_API_KEY`);if(!i)return console.error(`GROQ_API_KEY is not configured`),Response.json({error:`AI service is not configured. Please contact the administrator.`},{status:500});let a=e.createGroq({apiKey:i})(`llama-3.3-70b-versatile`),o=r||`Rewrite the following text to improve clarity, grammar, and style while maintaining the original meaning and tone. Only return the rewritten text without any explanation or additional commentary:
|
|
21
29
|
|
|
22
|
-
${n}`,s=(await e.generateText({model:a,prompt:o,temperature:.7})).text.trim();return Response.json({rewrittenText:s})}catch(e){return console.error(`AI rewrite error:`,e),Response.json({error:`Failed to process AI request. Please try again.`},{status:500})}}}}function
|
|
30
|
+
${n}`,s=(await e.generateText({model:a,prompt:o,temperature:.7})).text.trim();return Response.json({rewrittenText:s})}catch(e){return console.error(`AI rewrite error:`,e),Response.json({error:`Failed to process AI request. Please try again.`},{status:500})}}}}function q(e){return{POST:async t=>{let n,r,i;try{let e=await t.json();n=e.text,r=e.voice||e.speaker||`af_heart`,i=e.provider||`kokoro`}catch{return Response.json({error:`Invalid request body`},{status:400})}if(!n||typeof n!=`string`||n.trim().length===0)return Response.json({error:`text is required`},{status:400});let a=await e.getUserId()??t.headers?.get?.(`x-forwarded-for`)?.split(`,`)[0]?.trim()??t.headers?.get?.(`x-real-ip`)??`unknown`,{allowed:o}=e.checkTTSRateLimit(a);if(!o)return Response.json({error:`Daily TTS limit reached (10/day)`,rateLimited:!0},{status:429});try{let t=await e.generateSpeech({text:n.slice(0,5e3),provider:i,voice:r});return new Response(t.audio,{headers:{"Content-Type":t.contentType,"Cache-Control":`public, max-age=86400`,"Content-Disposition":`inline; filename="speech.${t.contentType.includes(`wav`)?`wav`:`mp3`}"`}})}catch(e){console.error(`[TTS] Error:`,e);let t=e instanceof Error?e.message:`TTS generation failed`;return t.includes(`Cloudflare AI binding`)?Response.json({error:`Deepgram provider requires Cloudflare AI binding. Use 'kokoro' provider instead.`},{status:503}):Response.json({error:t},{status:500})}}}}function J(e){return e===`small`||e===`fast`?`@cf/openai/whisper-tiny-en`:e===`medium`||e===`turbo`?`@cf/openai/whisper-large-v3-turbo`:e===`large`?`@cf/openai/whisper-large-v3`:`@cf/openai/whisper-large-v3-turbo`}function Y(e){return{POST:async t=>{try{let n=await t.formData(),r=n.get(`file`);if(!r||!(r instanceof File))return Response.json({error:`file is required`},{status:400});let i=J(n.get(`model`)),a;try{a=e.getCloudflareContext().env?.AI}catch{}if(!a)return Response.json({error:`Cloudflare AI binding not available`},{status:503});let o=await r.arrayBuffer(),{text:s}=await a.run(i,{audio:[...new Uint8Array(o)]});return Response.json({text:s,model:i})}catch(e){return console.error(`Transcript error:`,e),Response.json({error:`Failed to transcribe audio`},{status:500})}}}}function X(){return{POST:async e=>{try{let{providerType:t,apiKey:n,onlyFree:r=!0}=await e.json();if(!t)return Response.json({error:`Provider type is required`},{status:400});if(!n)return Response.json({error:`API key is required`},{status:400});let i=f.LANGUAGE_MODELS.find(e=>e.provider.toLowerCase()===t.toLowerCase());if(!i)return Response.json({error:`Provider ${t} not found`},{status:404});let a=await(0,d.testProviderModels)(t,n,i.models,{onlyFree:r,concurrency:3,timeout:15e3});return Response.json(a)}catch(e){return console.error(`[test-models] Error:`,e),Response.json({error:e.message||`Failed to test models`},{status:500})}}}}var Z=864e5,Q=null;function $(e){return{GET:async t=>{try{let t=Date.now();if(Q&&t-Q.timestamp<Z)return Response.json({...Q.result,cached:!0,cacheAge:t-Q.timestamp});let n=await e.validateOpenRouterModels();return Q={result:n,timestamp:t},Response.json({...n,cached:!1})}catch(e){return console.error(`[validate-openrouter] GET error:`,e),Response.json({error:e.message||`Validation failed`},{status:500})}},POST:async t=>{try{let{concurrency:n=3,timeout:r=15e3}=await t.json().catch(()=>({})),i=await e.validateOpenRouterModels(n,r);return Q={result:i,timestamp:Date.now()},Response.json({...i,cached:!1})}catch(e){return console.error(`[validate-openrouter] POST error:`,e),Response.json({error:e.message||`Validation failed`},{status:500})}}}}exports.createAgentsHandler=G,exports.createArticleFollowupsHandler=p,exports.createArticleQAHandler=h,exports.createAutocompleteHandler=U,exports.createChatByIdHandler=_,exports.createChatTitleHandler=b,exports.createChatsHandler=g,exports.createChatsSearchHandler=v,exports.createChatsShareHandler=y,exports.createDiscoverHandler=M,exports.createMCPServerByIdHandler=O,exports.createMCPServerToggleHandler=k,exports.createMCPServersHandler=D,exports.createMessagesHandler=C,exports.createPageTipsHandler=m,exports.createProviderByIdHandler=T,exports.createProviderModelsHandler=E,exports.createProvidersHandler=w,exports.createRewriteHandler=K,exports.createSearchHandler=j,exports.createSuggestionsHandler=W,exports.createTestModelsHandler=X,exports.createTranscriptHandler=Y,exports.createValidateOpenRouterHandler=$,exports.createVoiceHandler=q,exports.describeError=S;
|
package/dist/api.mjs
CHANGED
|
@@ -52,8 +52,50 @@ Generate ${a} follow-up questions that would help readers dive deeper into this
|
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
//#endregion
|
|
55
|
-
//#region src/api/handlers/
|
|
55
|
+
//#region src/api/handlers/page-tips.ts
|
|
56
56
|
function x(n) {
|
|
57
|
+
return async (n) => {
|
|
58
|
+
try {
|
|
59
|
+
let { title: r = "", content: i, maxTips: a = 4, chatModel: o } = await n.json();
|
|
60
|
+
if (!i) return Response.json({ error: "Content is required" }, { status: 400 });
|
|
61
|
+
let s = new t(), c;
|
|
62
|
+
try {
|
|
63
|
+
c = await s.loadChatModel(o?.providerId, o?.key);
|
|
64
|
+
} catch (e) {
|
|
65
|
+
return Response.json({ error: e instanceof Error ? e.message : "Failed to load language model" }, { status: 500 });
|
|
66
|
+
}
|
|
67
|
+
let l = `You are a helpful AI that surfaces short, useful tips about a page the reader currently has open.
|
|
68
|
+
Generate ${a} concise tips (each a single sentence) highlighting the most useful takeaways or things worth noticing on the page.
|
|
69
|
+
Return ONLY the tips, one per line, without numbering or bullet points.`, u = `Page title: ${r}
|
|
70
|
+
|
|
71
|
+
Page content:
|
|
72
|
+
${i.slice(0, 15e3)}
|
|
73
|
+
|
|
74
|
+
Generate ${a} short tips about this page.`, { text: d } = await e({
|
|
75
|
+
model: c,
|
|
76
|
+
messages: [{
|
|
77
|
+
role: "system",
|
|
78
|
+
content: l
|
|
79
|
+
}, {
|
|
80
|
+
role: "user",
|
|
81
|
+
content: u
|
|
82
|
+
}]
|
|
83
|
+
}), f = d.split("\n").map((e) => e.trim()).filter((e) => e.length > 0).map((e) => e.replace(/^[\d\-\*\.\)]+\s*/, "").trim()).filter((e) => e.length > 10).slice(0, a);
|
|
84
|
+
return Response.json({
|
|
85
|
+
tips: f,
|
|
86
|
+
success: !0
|
|
87
|
+
});
|
|
88
|
+
} catch (e) {
|
|
89
|
+
return console.error("Error generating page tips:", e), Response.json({
|
|
90
|
+
error: "An error occurred while generating page tips",
|
|
91
|
+
details: e instanceof Error ? e.message : String(e)
|
|
92
|
+
}, { status: 500 });
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
//#region src/api/handlers/article-qa.ts
|
|
98
|
+
function S(n) {
|
|
57
99
|
return async (n) => {
|
|
58
100
|
try {
|
|
59
101
|
let { article: r, question: i, chatHistory: a = [], chatModel: o } = await n.json();
|
|
@@ -95,7 +137,7 @@ Please provide a helpful answer based on the article content above.`, { text: d
|
|
|
95
137
|
}
|
|
96
138
|
//#endregion
|
|
97
139
|
//#region src/api/handlers/chats.ts
|
|
98
|
-
function
|
|
140
|
+
function C(e) {
|
|
99
141
|
let { chats: t, messages: o } = e.schema;
|
|
100
142
|
return {
|
|
101
143
|
GET: async (a) => {
|
|
@@ -132,7 +174,7 @@ function S(e) {
|
|
|
132
174
|
}
|
|
133
175
|
};
|
|
134
176
|
}
|
|
135
|
-
function
|
|
177
|
+
function w(e) {
|
|
136
178
|
let { chats: t, messages: r } = e.schema;
|
|
137
179
|
return {
|
|
138
180
|
GET: async (n, { params: a }) => {
|
|
@@ -165,7 +207,7 @@ function ee(e) {
|
|
|
165
207
|
}
|
|
166
208
|
};
|
|
167
209
|
}
|
|
168
|
-
function
|
|
210
|
+
function T(e) {
|
|
169
211
|
let { chats: t, messages: r } = e.schema;
|
|
170
212
|
return { GET: async (a) => {
|
|
171
213
|
try {
|
|
@@ -198,7 +240,7 @@ function C(e) {
|
|
|
198
240
|
}
|
|
199
241
|
} };
|
|
200
242
|
}
|
|
201
|
-
function
|
|
243
|
+
function ee(e) {
|
|
202
244
|
let { chats: t } = e.schema;
|
|
203
245
|
return { POST: async (n) => {
|
|
204
246
|
try {
|
|
@@ -238,7 +280,7 @@ function w(e) {
|
|
|
238
280
|
}
|
|
239
281
|
//#endregion
|
|
240
282
|
//#region src/api/handlers/chat-title.ts
|
|
241
|
-
function
|
|
283
|
+
function E(e) {
|
|
242
284
|
let { chats: n } = e.schema;
|
|
243
285
|
return { POST: async (r) => {
|
|
244
286
|
try {
|
|
@@ -264,22 +306,22 @@ function te(e) {
|
|
|
264
306
|
}
|
|
265
307
|
//#endregion
|
|
266
308
|
//#region src/api/handlers/messages.ts
|
|
267
|
-
var
|
|
309
|
+
var D = [
|
|
268
310
|
"assistant",
|
|
269
311
|
"user",
|
|
270
312
|
"source",
|
|
271
313
|
"suggestion"
|
|
272
314
|
];
|
|
273
|
-
function
|
|
315
|
+
function O(e) {
|
|
274
316
|
let t = [], n = e;
|
|
275
317
|
for (let e = 0; n != null && e < 5; e++) t.push(n instanceof Error ? n.message : String(n)), n = n instanceof Error ? n.cause : void 0;
|
|
276
318
|
return t.join(" <- caused by: ");
|
|
277
319
|
}
|
|
278
|
-
function
|
|
320
|
+
function k(e) {
|
|
279
321
|
return { POST: async (t) => {
|
|
280
322
|
try {
|
|
281
323
|
let n = e.getDB(), r = await e.requireUserId(), { chatId: i, messageId: a, role: o, suggestions: s, content: c, sources: l } = await t.json();
|
|
282
|
-
return !i || !a || !o ? Response.json({ message: "Missing required fields" }, { status: 400 }) :
|
|
324
|
+
return !i || !a || !o ? Response.json({ message: "Missing required fields" }, { status: 400 }) : D.includes(o) ? (await n.insert(e.messagesSchema).values({
|
|
283
325
|
chatId: i,
|
|
284
326
|
userId: r,
|
|
285
327
|
messageId: a,
|
|
@@ -290,13 +332,13 @@ function D(e) {
|
|
|
290
332
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
291
333
|
}), Response.json({ message: "Message saved successfully" }, { status: 200 })) : Response.json({ message: `Invalid role: ${o}` }, { status: 400 });
|
|
292
334
|
} catch (e) {
|
|
293
|
-
return console.error("Error saving message:",
|
|
335
|
+
return console.error("Error saving message:", O(e)), Response.json({ message: "Failed to save message" }, { status: 500 });
|
|
294
336
|
}
|
|
295
337
|
} };
|
|
296
338
|
}
|
|
297
339
|
//#endregion
|
|
298
340
|
//#region src/api/handlers/providers.ts
|
|
299
|
-
function
|
|
341
|
+
function A(e) {
|
|
300
342
|
return {
|
|
301
343
|
GET: async (n) => {
|
|
302
344
|
try {
|
|
@@ -326,7 +368,7 @@ function O(e) {
|
|
|
326
368
|
}
|
|
327
369
|
};
|
|
328
370
|
}
|
|
329
|
-
function
|
|
371
|
+
function j() {
|
|
330
372
|
return {
|
|
331
373
|
DELETE: async (e, { params: n }) => {
|
|
332
374
|
try {
|
|
@@ -348,7 +390,7 @@ function k() {
|
|
|
348
390
|
}
|
|
349
391
|
};
|
|
350
392
|
}
|
|
351
|
-
function
|
|
393
|
+
function M() {
|
|
352
394
|
return {
|
|
353
395
|
POST: async (e, { params: n }) => {
|
|
354
396
|
try {
|
|
@@ -370,7 +412,7 @@ function A() {
|
|
|
370
412
|
}
|
|
371
413
|
//#endregion
|
|
372
414
|
//#region src/api/handlers/mcpservers.ts
|
|
373
|
-
function
|
|
415
|
+
function N(e) {
|
|
374
416
|
return {
|
|
375
417
|
GET: async (t) => {
|
|
376
418
|
try {
|
|
@@ -392,7 +434,7 @@ function j(e) {
|
|
|
392
434
|
}
|
|
393
435
|
};
|
|
394
436
|
}
|
|
395
|
-
function
|
|
437
|
+
function P(e) {
|
|
396
438
|
return {
|
|
397
439
|
DELETE: async (t, { params: n }) => {
|
|
398
440
|
try {
|
|
@@ -414,7 +456,7 @@ function M(e) {
|
|
|
414
456
|
}
|
|
415
457
|
};
|
|
416
458
|
}
|
|
417
|
-
function
|
|
459
|
+
function F(e) {
|
|
418
460
|
return { POST: async (t, { params: n }) => {
|
|
419
461
|
try {
|
|
420
462
|
let { enabled: r } = await t.json(), { id: i } = await n;
|
|
@@ -428,7 +470,7 @@ function N(e) {
|
|
|
428
470
|
}
|
|
429
471
|
//#endregion
|
|
430
472
|
//#region src/api/handlers/search.ts
|
|
431
|
-
var
|
|
473
|
+
var I = {
|
|
432
474
|
tech: {
|
|
433
475
|
query: [
|
|
434
476
|
"technology news",
|
|
@@ -494,7 +536,7 @@ var P = {
|
|
|
494
536
|
]
|
|
495
537
|
}
|
|
496
538
|
};
|
|
497
|
-
function
|
|
539
|
+
function L(e = {}) {
|
|
498
540
|
let t = e.searxngDomain ?? "https://search.qwksearch.com";
|
|
499
541
|
return { GET: async (e) => {
|
|
500
542
|
let n = new URL(e.url).searchParams, r = n.get("q"), i = n.get("cat") || "general", a = parseInt(n.get("page") || "1", 10), o = n.get("lang") || "en-US", s = n.get("safesearch") === "true", c = n.get("recency") || void 0, l = n.get("publicInstances") === "true";
|
|
@@ -541,10 +583,10 @@ function F(e = {}) {
|
|
|
541
583
|
}
|
|
542
584
|
} };
|
|
543
585
|
}
|
|
544
|
-
function
|
|
586
|
+
function R() {
|
|
545
587
|
return { GET: async (e) => {
|
|
546
588
|
try {
|
|
547
|
-
let t = new URL(e.url).searchParams, n = t.get("mode") || "normal", r =
|
|
589
|
+
let t = new URL(e.url).searchParams, n = t.get("mode") || "normal", r = I[t.get("topic") || "tech"], i = [];
|
|
548
590
|
if (n === "normal") {
|
|
549
591
|
let e = /* @__PURE__ */ new Set();
|
|
550
592
|
i = (await Promise.all(r.links.flatMap((e) => r.query.map(async (t) => (await d(`site:${e} ${t}`, {
|
|
@@ -568,17 +610,17 @@ function I() {
|
|
|
568
610
|
}
|
|
569
611
|
//#endregion
|
|
570
612
|
//#region src/api/handlers/autocomplete.ts
|
|
571
|
-
var
|
|
613
|
+
var z = [
|
|
572
614
|
"google",
|
|
573
615
|
"duckduckgo",
|
|
574
616
|
"wikipedia"
|
|
575
|
-
],
|
|
617
|
+
], B = 3, V = 3, te = Object.entries(g).map(([e, t]) => ({
|
|
576
618
|
domain: e,
|
|
577
619
|
name: typeof t?.[0] == "string" ? t[0] : "",
|
|
578
620
|
rank: typeof t?.[1] == "number" ? t[1] : 2 ** 53 - 1
|
|
579
|
-
})),
|
|
580
|
-
function
|
|
581
|
-
return
|
|
621
|
+
})), H = null;
|
|
622
|
+
function U() {
|
|
623
|
+
return H ||= new m(te, {
|
|
582
624
|
keys: [{
|
|
583
625
|
name: "name",
|
|
584
626
|
weight: .6
|
|
@@ -590,9 +632,9 @@ function H() {
|
|
|
590
632
|
ignoreLocation: !0,
|
|
591
633
|
includeScore: !0,
|
|
592
634
|
minMatchCharLength: 3
|
|
593
|
-
}),
|
|
635
|
+
}), H;
|
|
594
636
|
}
|
|
595
|
-
function
|
|
637
|
+
function W(e, t, n) {
|
|
596
638
|
return {
|
|
597
639
|
domain: e,
|
|
598
640
|
name: t,
|
|
@@ -600,20 +642,20 @@ function U(e, t, n) {
|
|
|
600
642
|
rank: n
|
|
601
643
|
};
|
|
602
644
|
}
|
|
603
|
-
function
|
|
645
|
+
function G(e) {
|
|
604
646
|
let t = h(e);
|
|
605
647
|
return t.domain && t.isIcann ? t.hostname : null;
|
|
606
648
|
}
|
|
607
|
-
function
|
|
649
|
+
function K(e) {
|
|
608
650
|
let t = e.split(/\s+/).filter(Boolean), n = t[t.length - 1] || "";
|
|
609
651
|
if (n.length < 3) return [];
|
|
610
|
-
let r =
|
|
611
|
-
return i && !r.some((e) => e.domain === i) && r.unshift(
|
|
652
|
+
let r = U().search(n, { limit: 12 }).sort((e, t) => Math.round((e.score ?? 1) * 10) - Math.round((t.score ?? 1) * 10) || e.item.rank - t.item.rank).map(({ item: e }) => W(e.domain, e.name, e.rank)), i = G(n);
|
|
653
|
+
return i && !r.some((e) => e.domain === i) && r.unshift(W(i, "", 2 ** 53 - 1)), r.slice(0, V);
|
|
612
654
|
}
|
|
613
|
-
async function
|
|
655
|
+
async function q(e, t, n) {
|
|
614
656
|
let r = await p(e, t, n);
|
|
615
657
|
if (r.length > 0) return r;
|
|
616
|
-
let i = t.split(/\s+/).filter(Boolean), a = Math.min(
|
|
658
|
+
let i = t.split(/\s+/).filter(Boolean), a = Math.min(B, i.length - 1);
|
|
617
659
|
for (let r = a; r >= 1; r--) {
|
|
618
660
|
let a = i.slice(-r).join(" "), o = i.slice(0, -r).join(" "), s = await p(e, a, n);
|
|
619
661
|
if (s.length > 0) {
|
|
@@ -627,16 +669,16 @@ async function K(e, t, n) {
|
|
|
627
669
|
}
|
|
628
670
|
return [];
|
|
629
671
|
}
|
|
630
|
-
function
|
|
672
|
+
function J() {
|
|
631
673
|
return { GET: async (e) => {
|
|
632
674
|
let { searchParams: t } = new URL(e.url), n = t.get("q")?.trim(), r = t.get("locale") || "en-US", i = t.get("backends"), a = parseInt(t.get("limit") || "8", 10);
|
|
633
675
|
if (!n) return Response.json({
|
|
634
676
|
suggestions: [],
|
|
635
677
|
domains: []
|
|
636
678
|
});
|
|
637
|
-
let o = i ? i.split(",").map((e) => e.trim()).filter(Boolean) :
|
|
679
|
+
let o = i ? i.split(",").map((e) => e.trim()).filter(Boolean) : z;
|
|
638
680
|
try {
|
|
639
|
-
let e = await
|
|
681
|
+
let e = await q(o, n, r), t = K(n);
|
|
640
682
|
return Response.json({
|
|
641
683
|
suggestions: e.slice(0, a),
|
|
642
684
|
domains: t
|
|
@@ -651,7 +693,7 @@ function q() {
|
|
|
651
693
|
}
|
|
652
694
|
//#endregion
|
|
653
695
|
//#region src/api/handlers/suggestions.ts
|
|
654
|
-
function
|
|
696
|
+
function Y() {
|
|
655
697
|
return { POST: async (e) => {
|
|
656
698
|
let n = await e.json(), r = n.chatHistory.filter((e) => e.role === "user" || e.role === "assistant").map((e) => ({
|
|
657
699
|
role: e.role,
|
|
@@ -665,7 +707,7 @@ function J() {
|
|
|
665
707
|
}
|
|
666
708
|
//#endregion
|
|
667
709
|
//#region src/api/handlers/agents.ts
|
|
668
|
-
function
|
|
710
|
+
function X(e) {
|
|
669
711
|
return { POST: async (t) => {
|
|
670
712
|
let n;
|
|
671
713
|
try {
|
|
@@ -680,7 +722,7 @@ function Y(e) {
|
|
|
680
722
|
}
|
|
681
723
|
//#endregion
|
|
682
724
|
//#region src/api/handlers/rewrite.ts
|
|
683
|
-
function
|
|
725
|
+
function Z(e) {
|
|
684
726
|
return { POST: async (t) => {
|
|
685
727
|
try {
|
|
686
728
|
let { text: n, prompt: r } = await t.json();
|
|
@@ -702,7 +744,7 @@ ${n}`, s = (await e.generateText({
|
|
|
702
744
|
}
|
|
703
745
|
//#endregion
|
|
704
746
|
//#region src/api/handlers/voice.ts
|
|
705
|
-
function
|
|
747
|
+
function Q(e) {
|
|
706
748
|
return { POST: async (t) => {
|
|
707
749
|
let n, r, i;
|
|
708
750
|
try {
|
|
@@ -737,15 +779,15 @@ function Z(e) {
|
|
|
737
779
|
}
|
|
738
780
|
//#endregion
|
|
739
781
|
//#region src/api/handlers/transcript.ts
|
|
740
|
-
function
|
|
782
|
+
function ne(e) {
|
|
741
783
|
return e === "small" || e === "fast" ? "@cf/openai/whisper-tiny-en" : e === "medium" || e === "turbo" ? "@cf/openai/whisper-large-v3-turbo" : e === "large" ? "@cf/openai/whisper-large-v3" : "@cf/openai/whisper-large-v3-turbo";
|
|
742
784
|
}
|
|
743
|
-
function
|
|
785
|
+
function re(e) {
|
|
744
786
|
return { POST: async (t) => {
|
|
745
787
|
try {
|
|
746
788
|
let n = await t.formData(), r = n.get("file");
|
|
747
789
|
if (!r || !(r instanceof File)) return Response.json({ error: "file is required" }, { status: 400 });
|
|
748
|
-
let i =
|
|
790
|
+
let i = ne(n.get("model")), a;
|
|
749
791
|
try {
|
|
750
792
|
a = e.getCloudflareContext().env?.AI;
|
|
751
793
|
} catch {}
|
|
@@ -762,7 +804,7 @@ function ne(e) {
|
|
|
762
804
|
}
|
|
763
805
|
//#endregion
|
|
764
806
|
//#region src/api/handlers/test-models.ts
|
|
765
|
-
function
|
|
807
|
+
function ie() {
|
|
766
808
|
return { POST: async (e) => {
|
|
767
809
|
try {
|
|
768
810
|
let { providerType: t, apiKey: n, onlyFree: r = !0 } = await e.json();
|
|
@@ -783,13 +825,13 @@ function re() {
|
|
|
783
825
|
}
|
|
784
826
|
//#endregion
|
|
785
827
|
//#region src/api/handlers/validate-openrouter.ts
|
|
786
|
-
var
|
|
787
|
-
function
|
|
828
|
+
var ae = 864e5, $ = null;
|
|
829
|
+
function oe(e) {
|
|
788
830
|
return {
|
|
789
831
|
GET: async (t) => {
|
|
790
832
|
try {
|
|
791
833
|
let t = Date.now();
|
|
792
|
-
if ($ && t - $.timestamp <
|
|
834
|
+
if ($ && t - $.timestamp < ae) return Response.json({
|
|
793
835
|
...$.result,
|
|
794
836
|
cached: !0,
|
|
795
837
|
cacheAge: t - $.timestamp
|
|
@@ -823,4 +865,4 @@ function ae(e) {
|
|
|
823
865
|
};
|
|
824
866
|
}
|
|
825
867
|
//#endregion
|
|
826
|
-
export {
|
|
868
|
+
export { X as createAgentsHandler, b as createArticleFollowupsHandler, S as createArticleQAHandler, J as createAutocompleteHandler, w as createChatByIdHandler, E as createChatTitleHandler, C as createChatsHandler, T as createChatsSearchHandler, ee as createChatsShareHandler, R as createDiscoverHandler, P as createMCPServerByIdHandler, F as createMCPServerToggleHandler, N as createMCPServersHandler, k as createMessagesHandler, x as createPageTipsHandler, j as createProviderByIdHandler, M as createProviderModelsHandler, A as createProvidersHandler, Z as createRewriteHandler, L as createSearchHandler, Y as createSuggestionsHandler, ie as createTestModelsHandler, re as createTranscriptHandler, oe as createValidateOpenRouterHandler, Q as createVoiceHandler, O as describeError };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "research-agent-ui",
|
|
3
3
|
"description": "Chat research agent UI: conversation window, article reader, search config, file uploads, and chat history",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.128",
|
|
5
5
|
"author": "vtempest",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -80,13 +80,13 @@
|
|
|
80
80
|
"@radix-ui/react-tooltip": "^1.2.9",
|
|
81
81
|
"@ricky0123/vad-web": "^0.0.30",
|
|
82
82
|
"ai": "^5.0.0",
|
|
83
|
-
"chat-agent-toolkit": "^1.2.
|
|
83
|
+
"chat-agent-toolkit": "^1.2.257",
|
|
84
84
|
"class-variance-authority": "^0.7.1",
|
|
85
85
|
"clsx": "^2.1.1",
|
|
86
|
-
"domain-rank": "^0.1.
|
|
86
|
+
"domain-rank": "^0.1.246",
|
|
87
87
|
"dompurify": "^3.4.9",
|
|
88
88
|
"drizzle-orm": "^0.45.2",
|
|
89
|
-
"extract-webpage": "^1.2.
|
|
89
|
+
"extract-webpage": "^1.2.256",
|
|
90
90
|
"framer-motion": "^12.40.0",
|
|
91
91
|
"fuse.js": "^7.1.0",
|
|
92
92
|
"grab-url": "^1.6.22",
|
|
@@ -96,12 +96,12 @@
|
|
|
96
96
|
"markdown-to-jsx": "^9.8.2",
|
|
97
97
|
"motion": "^12.40.0",
|
|
98
98
|
"quantum-sphere-loading-icon": "^1.0.3",
|
|
99
|
-
"qwksearch-api-client": "^0.9.
|
|
99
|
+
"qwksearch-api-client": "^0.9.203",
|
|
100
100
|
"react-icons": "^5.6.0",
|
|
101
101
|
"react-native-app-buttons": "^0.1.4",
|
|
102
102
|
"react-textarea-autosize": "^8.5.9",
|
|
103
103
|
"trending-news-api": "^0.1.0",
|
|
104
|
-
"use-weather-forecast": "^0.1.
|
|
104
|
+
"use-weather-forecast": "^0.1.73",
|
|
105
105
|
"search-web-api": "^1.0.108",
|
|
106
106
|
"sonner": "^2.0.7",
|
|
107
107
|
"streamdown": "^2.5.0",
|