research-agent-ui 0.1.127 → 0.1.129
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/handlers/topic-searches.d.ts +2 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api.cjs +19 -3
- package/dist/api.mjs +133 -49
- package/package.json +7 -7
package/dist/api/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export * from "./types";
|
|
5
5
|
export * from "./handlers/article-followups";
|
|
6
|
+
export * from "./handlers/page-tips";
|
|
7
|
+
export * from "./handlers/topic-searches";
|
|
6
8
|
export * from "./handlers/article-qa";
|
|
7
9
|
export * from "./handlers/chats";
|
|
8
10
|
export * from "./handlers/chat-title";
|
package/dist/api.cjs
CHANGED
|
@@ -7,7 +7,23 @@ ${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{title:r=``,content:i,maxTopics: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 suggests related searches for a reader based on a page they currently have open.
|
|
19
|
+
Generate ${a} short search queries (each a few words, phrased the way someone would type it into a search box) that dig deeper into topics related to the page.
|
|
20
|
+
Return ONLY the search queries, one per line, without numbering or bullet points.`,u=`Page title: ${r}
|
|
21
|
+
|
|
22
|
+
Page content:
|
|
23
|
+
${i.slice(0,15e3)}
|
|
24
|
+
|
|
25
|
+
Generate ${a} short related search queries for this page.`,{text:d}=await(0,t.generateText)({model:c,messages:[{role:`system`,content:l},{role:`user`,content:u}]}),f=d.split(`
|
|
26
|
+
`).map(e=>e.trim()).filter(e=>e.length>0).map(e=>e.replace(/^[\d\-\*\.\)]+\s*/,``).trim()).filter(e=>e.length>2).slice(0,a);return Response.json({topics:f,success:!0})}catch(e){return console.error(`Error generating topic searches:`,e),Response.json({error:`An error occurred while generating topic searches`,details:e instanceof Error?e.message:String(e)},{status:500})}}}function g(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
27
|
`)}`:``,u=`Article content:
|
|
12
28
|
${r.slice(0,15e3)}
|
|
13
29
|
|
|
@@ -17,6 +33,6 @@ User question: ${i}
|
|
|
17
33
|
|
|
18
34
|
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
35
|
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:
|
|
36
|
+
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 _(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 v(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 y(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 b(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 x(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 S=[`assistant`,`user`,`source`,`suggestion`];function C(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 w(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}):S.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:`,C(e)),Response.json({message:`Failed to save message`},{status:500})}}}}function T(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 E(){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 D(){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 O(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 k(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 A(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 j={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 M(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 N(){return{GET:async e=>{try{let t=new URL(e.url).searchParams,n=t.get(`mode`)||`normal`,r=j[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 P=[`google`,`duckduckgo`,`wikipedia`],F=3,I=3,L=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})),R=null;function z(){return R||=new s.default(L,{keys:[{name:`name`,weight:.6},{name:`domain`,weight:.4}],threshold:.1,ignoreLocation:!0,includeScore:!0,minMatchCharLength:3}),R}function B(e,t,n){return{domain:e,name:t,favicon:`https://www.google.com/s2/favicons?domain=${encodeURIComponent(e)}&sz=64`,rank:n}}function V(e){let t=(0,c.parse)(e);return t.domain&&t.isIcann?t.hostname:null}function H(e){let t=e.split(/\s+/).filter(Boolean),n=t[t.length-1]||``;if(n.length<3)return[];let r=z().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})=>B(e.domain,e.name,e.rank)),i=V(n);return i&&!r.some(e=>e.domain===i)&&r.unshift(B(i,``,2**53-1)),r.slice(0,I)}async function U(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(F,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 W(){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):P;try{let e=await U(o,n,r),t=H(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 G(){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 K(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 q(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
37
|
|
|
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
|
|
38
|
+
${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 J(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 Y(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 X(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=Y(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 Z(){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 Q=864e5,$=null;function ee(e){return{GET:async t=>{try{let t=Date.now();if($&&t-$.timestamp<Q)return Response.json({...$.result,cached:!0,cacheAge:t-$.timestamp});let n=await e.validateOpenRouterModels();return $={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 $={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=K,exports.createArticleFollowupsHandler=p,exports.createArticleQAHandler=g,exports.createAutocompleteHandler=W,exports.createChatByIdHandler=v,exports.createChatTitleHandler=x,exports.createChatsHandler=_,exports.createChatsSearchHandler=y,exports.createChatsShareHandler=b,exports.createDiscoverHandler=N,exports.createMCPServerByIdHandler=k,exports.createMCPServerToggleHandler=A,exports.createMCPServersHandler=O,exports.createMessagesHandler=w,exports.createPageTipsHandler=m,exports.createProviderByIdHandler=E,exports.createProviderModelsHandler=D,exports.createProvidersHandler=T,exports.createRewriteHandler=q,exports.createSearchHandler=M,exports.createSuggestionsHandler=G,exports.createTestModelsHandler=Z,exports.createTopicSearchesHandler=h,exports.createTranscriptHandler=X,exports.createValidateOpenRouterHandler=ee,exports.createVoiceHandler=J,exports.describeError=C;
|
package/dist/api.mjs
CHANGED
|
@@ -52,8 +52,92 @@ 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/topic-searches.ts
|
|
98
|
+
function S(n) {
|
|
99
|
+
return async (n) => {
|
|
100
|
+
try {
|
|
101
|
+
let { title: r = "", content: i, maxTopics: a = 4, chatModel: o } = await n.json();
|
|
102
|
+
if (!i) return Response.json({ error: "Content is required" }, { status: 400 });
|
|
103
|
+
let s = new t(), c;
|
|
104
|
+
try {
|
|
105
|
+
c = await s.loadChatModel(o?.providerId, o?.key);
|
|
106
|
+
} catch (e) {
|
|
107
|
+
return Response.json({ error: e instanceof Error ? e.message : "Failed to load language model" }, { status: 500 });
|
|
108
|
+
}
|
|
109
|
+
let l = `You are a helpful AI that suggests related searches for a reader based on a page they currently have open.
|
|
110
|
+
Generate ${a} short search queries (each a few words, phrased the way someone would type it into a search box) that dig deeper into topics related to the page.
|
|
111
|
+
Return ONLY the search queries, one per line, without numbering or bullet points.`, u = `Page title: ${r}
|
|
112
|
+
|
|
113
|
+
Page content:
|
|
114
|
+
${i.slice(0, 15e3)}
|
|
115
|
+
|
|
116
|
+
Generate ${a} short related search queries for this page.`, { text: d } = await e({
|
|
117
|
+
model: c,
|
|
118
|
+
messages: [{
|
|
119
|
+
role: "system",
|
|
120
|
+
content: l
|
|
121
|
+
}, {
|
|
122
|
+
role: "user",
|
|
123
|
+
content: u
|
|
124
|
+
}]
|
|
125
|
+
}), f = d.split("\n").map((e) => e.trim()).filter((e) => e.length > 0).map((e) => e.replace(/^[\d\-\*\.\)]+\s*/, "").trim()).filter((e) => e.length > 2).slice(0, a);
|
|
126
|
+
return Response.json({
|
|
127
|
+
topics: f,
|
|
128
|
+
success: !0
|
|
129
|
+
});
|
|
130
|
+
} catch (e) {
|
|
131
|
+
return console.error("Error generating topic searches:", e), Response.json({
|
|
132
|
+
error: "An error occurred while generating topic searches",
|
|
133
|
+
details: e instanceof Error ? e.message : String(e)
|
|
134
|
+
}, { status: 500 });
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
//#endregion
|
|
139
|
+
//#region src/api/handlers/article-qa.ts
|
|
140
|
+
function C(n) {
|
|
57
141
|
return async (n) => {
|
|
58
142
|
try {
|
|
59
143
|
let { article: r, question: i, chatHistory: a = [], chatModel: o } = await n.json();
|
|
@@ -95,7 +179,7 @@ Please provide a helpful answer based on the article content above.`, { text: d
|
|
|
95
179
|
}
|
|
96
180
|
//#endregion
|
|
97
181
|
//#region src/api/handlers/chats.ts
|
|
98
|
-
function
|
|
182
|
+
function w(e) {
|
|
99
183
|
let { chats: t, messages: o } = e.schema;
|
|
100
184
|
return {
|
|
101
185
|
GET: async (a) => {
|
|
@@ -132,7 +216,7 @@ function S(e) {
|
|
|
132
216
|
}
|
|
133
217
|
};
|
|
134
218
|
}
|
|
135
|
-
function
|
|
219
|
+
function T(e) {
|
|
136
220
|
let { chats: t, messages: r } = e.schema;
|
|
137
221
|
return {
|
|
138
222
|
GET: async (n, { params: a }) => {
|
|
@@ -165,7 +249,7 @@ function ee(e) {
|
|
|
165
249
|
}
|
|
166
250
|
};
|
|
167
251
|
}
|
|
168
|
-
function
|
|
252
|
+
function ee(e) {
|
|
169
253
|
let { chats: t, messages: r } = e.schema;
|
|
170
254
|
return { GET: async (a) => {
|
|
171
255
|
try {
|
|
@@ -198,7 +282,7 @@ function C(e) {
|
|
|
198
282
|
}
|
|
199
283
|
} };
|
|
200
284
|
}
|
|
201
|
-
function
|
|
285
|
+
function E(e) {
|
|
202
286
|
let { chats: t } = e.schema;
|
|
203
287
|
return { POST: async (n) => {
|
|
204
288
|
try {
|
|
@@ -238,7 +322,7 @@ function w(e) {
|
|
|
238
322
|
}
|
|
239
323
|
//#endregion
|
|
240
324
|
//#region src/api/handlers/chat-title.ts
|
|
241
|
-
function
|
|
325
|
+
function D(e) {
|
|
242
326
|
let { chats: n } = e.schema;
|
|
243
327
|
return { POST: async (r) => {
|
|
244
328
|
try {
|
|
@@ -264,22 +348,22 @@ function te(e) {
|
|
|
264
348
|
}
|
|
265
349
|
//#endregion
|
|
266
350
|
//#region src/api/handlers/messages.ts
|
|
267
|
-
var
|
|
351
|
+
var O = [
|
|
268
352
|
"assistant",
|
|
269
353
|
"user",
|
|
270
354
|
"source",
|
|
271
355
|
"suggestion"
|
|
272
356
|
];
|
|
273
|
-
function
|
|
357
|
+
function k(e) {
|
|
274
358
|
let t = [], n = e;
|
|
275
359
|
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
360
|
return t.join(" <- caused by: ");
|
|
277
361
|
}
|
|
278
|
-
function
|
|
362
|
+
function A(e) {
|
|
279
363
|
return { POST: async (t) => {
|
|
280
364
|
try {
|
|
281
365
|
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 }) :
|
|
366
|
+
return !i || !a || !o ? Response.json({ message: "Missing required fields" }, { status: 400 }) : O.includes(o) ? (await n.insert(e.messagesSchema).values({
|
|
283
367
|
chatId: i,
|
|
284
368
|
userId: r,
|
|
285
369
|
messageId: a,
|
|
@@ -290,13 +374,13 @@ function D(e) {
|
|
|
290
374
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
291
375
|
}), Response.json({ message: "Message saved successfully" }, { status: 200 })) : Response.json({ message: `Invalid role: ${o}` }, { status: 400 });
|
|
292
376
|
} catch (e) {
|
|
293
|
-
return console.error("Error saving message:",
|
|
377
|
+
return console.error("Error saving message:", k(e)), Response.json({ message: "Failed to save message" }, { status: 500 });
|
|
294
378
|
}
|
|
295
379
|
} };
|
|
296
380
|
}
|
|
297
381
|
//#endregion
|
|
298
382
|
//#region src/api/handlers/providers.ts
|
|
299
|
-
function
|
|
383
|
+
function j(e) {
|
|
300
384
|
return {
|
|
301
385
|
GET: async (n) => {
|
|
302
386
|
try {
|
|
@@ -326,7 +410,7 @@ function O(e) {
|
|
|
326
410
|
}
|
|
327
411
|
};
|
|
328
412
|
}
|
|
329
|
-
function
|
|
413
|
+
function M() {
|
|
330
414
|
return {
|
|
331
415
|
DELETE: async (e, { params: n }) => {
|
|
332
416
|
try {
|
|
@@ -348,7 +432,7 @@ function k() {
|
|
|
348
432
|
}
|
|
349
433
|
};
|
|
350
434
|
}
|
|
351
|
-
function
|
|
435
|
+
function N() {
|
|
352
436
|
return {
|
|
353
437
|
POST: async (e, { params: n }) => {
|
|
354
438
|
try {
|
|
@@ -370,7 +454,7 @@ function A() {
|
|
|
370
454
|
}
|
|
371
455
|
//#endregion
|
|
372
456
|
//#region src/api/handlers/mcpservers.ts
|
|
373
|
-
function
|
|
457
|
+
function P(e) {
|
|
374
458
|
return {
|
|
375
459
|
GET: async (t) => {
|
|
376
460
|
try {
|
|
@@ -392,7 +476,7 @@ function j(e) {
|
|
|
392
476
|
}
|
|
393
477
|
};
|
|
394
478
|
}
|
|
395
|
-
function
|
|
479
|
+
function F(e) {
|
|
396
480
|
return {
|
|
397
481
|
DELETE: async (t, { params: n }) => {
|
|
398
482
|
try {
|
|
@@ -414,7 +498,7 @@ function M(e) {
|
|
|
414
498
|
}
|
|
415
499
|
};
|
|
416
500
|
}
|
|
417
|
-
function
|
|
501
|
+
function I(e) {
|
|
418
502
|
return { POST: async (t, { params: n }) => {
|
|
419
503
|
try {
|
|
420
504
|
let { enabled: r } = await t.json(), { id: i } = await n;
|
|
@@ -428,7 +512,7 @@ function N(e) {
|
|
|
428
512
|
}
|
|
429
513
|
//#endregion
|
|
430
514
|
//#region src/api/handlers/search.ts
|
|
431
|
-
var
|
|
515
|
+
var L = {
|
|
432
516
|
tech: {
|
|
433
517
|
query: [
|
|
434
518
|
"technology news",
|
|
@@ -494,7 +578,7 @@ var P = {
|
|
|
494
578
|
]
|
|
495
579
|
}
|
|
496
580
|
};
|
|
497
|
-
function
|
|
581
|
+
function R(e = {}) {
|
|
498
582
|
let t = e.searxngDomain ?? "https://search.qwksearch.com";
|
|
499
583
|
return { GET: async (e) => {
|
|
500
584
|
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 +625,10 @@ function F(e = {}) {
|
|
|
541
625
|
}
|
|
542
626
|
} };
|
|
543
627
|
}
|
|
544
|
-
function
|
|
628
|
+
function z() {
|
|
545
629
|
return { GET: async (e) => {
|
|
546
630
|
try {
|
|
547
|
-
let t = new URL(e.url).searchParams, n = t.get("mode") || "normal", r =
|
|
631
|
+
let t = new URL(e.url).searchParams, n = t.get("mode") || "normal", r = L[t.get("topic") || "tech"], i = [];
|
|
548
632
|
if (n === "normal") {
|
|
549
633
|
let e = /* @__PURE__ */ new Set();
|
|
550
634
|
i = (await Promise.all(r.links.flatMap((e) => r.query.map(async (t) => (await d(`site:${e} ${t}`, {
|
|
@@ -568,17 +652,17 @@ function I() {
|
|
|
568
652
|
}
|
|
569
653
|
//#endregion
|
|
570
654
|
//#region src/api/handlers/autocomplete.ts
|
|
571
|
-
var
|
|
655
|
+
var B = [
|
|
572
656
|
"google",
|
|
573
657
|
"duckduckgo",
|
|
574
658
|
"wikipedia"
|
|
575
|
-
],
|
|
659
|
+
], V = 3, te = 3, H = Object.entries(g).map(([e, t]) => ({
|
|
576
660
|
domain: e,
|
|
577
661
|
name: typeof t?.[0] == "string" ? t[0] : "",
|
|
578
662
|
rank: typeof t?.[1] == "number" ? t[1] : 2 ** 53 - 1
|
|
579
|
-
})),
|
|
580
|
-
function
|
|
581
|
-
return
|
|
663
|
+
})), U = null;
|
|
664
|
+
function W() {
|
|
665
|
+
return U ||= new m(H, {
|
|
582
666
|
keys: [{
|
|
583
667
|
name: "name",
|
|
584
668
|
weight: .6
|
|
@@ -590,9 +674,9 @@ function H() {
|
|
|
590
674
|
ignoreLocation: !0,
|
|
591
675
|
includeScore: !0,
|
|
592
676
|
minMatchCharLength: 3
|
|
593
|
-
}),
|
|
677
|
+
}), U;
|
|
594
678
|
}
|
|
595
|
-
function
|
|
679
|
+
function G(e, t, n) {
|
|
596
680
|
return {
|
|
597
681
|
domain: e,
|
|
598
682
|
name: t,
|
|
@@ -600,20 +684,20 @@ function U(e, t, n) {
|
|
|
600
684
|
rank: n
|
|
601
685
|
};
|
|
602
686
|
}
|
|
603
|
-
function
|
|
687
|
+
function K(e) {
|
|
604
688
|
let t = h(e);
|
|
605
689
|
return t.domain && t.isIcann ? t.hostname : null;
|
|
606
690
|
}
|
|
607
|
-
function
|
|
691
|
+
function q(e) {
|
|
608
692
|
let t = e.split(/\s+/).filter(Boolean), n = t[t.length - 1] || "";
|
|
609
693
|
if (n.length < 3) return [];
|
|
610
|
-
let r =
|
|
611
|
-
return i && !r.some((e) => e.domain === i) && r.unshift(
|
|
694
|
+
let r = W().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 }) => G(e.domain, e.name, e.rank)), i = K(n);
|
|
695
|
+
return i && !r.some((e) => e.domain === i) && r.unshift(G(i, "", 2 ** 53 - 1)), r.slice(0, te);
|
|
612
696
|
}
|
|
613
|
-
async function
|
|
697
|
+
async function J(e, t, n) {
|
|
614
698
|
let r = await p(e, t, n);
|
|
615
699
|
if (r.length > 0) return r;
|
|
616
|
-
let i = t.split(/\s+/).filter(Boolean), a = Math.min(
|
|
700
|
+
let i = t.split(/\s+/).filter(Boolean), a = Math.min(V, i.length - 1);
|
|
617
701
|
for (let r = a; r >= 1; r--) {
|
|
618
702
|
let a = i.slice(-r).join(" "), o = i.slice(0, -r).join(" "), s = await p(e, a, n);
|
|
619
703
|
if (s.length > 0) {
|
|
@@ -627,16 +711,16 @@ async function K(e, t, n) {
|
|
|
627
711
|
}
|
|
628
712
|
return [];
|
|
629
713
|
}
|
|
630
|
-
function
|
|
714
|
+
function Y() {
|
|
631
715
|
return { GET: async (e) => {
|
|
632
716
|
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
717
|
if (!n) return Response.json({
|
|
634
718
|
suggestions: [],
|
|
635
719
|
domains: []
|
|
636
720
|
});
|
|
637
|
-
let o = i ? i.split(",").map((e) => e.trim()).filter(Boolean) :
|
|
721
|
+
let o = i ? i.split(",").map((e) => e.trim()).filter(Boolean) : B;
|
|
638
722
|
try {
|
|
639
|
-
let e = await
|
|
723
|
+
let e = await J(o, n, r), t = q(n);
|
|
640
724
|
return Response.json({
|
|
641
725
|
suggestions: e.slice(0, a),
|
|
642
726
|
domains: t
|
|
@@ -651,7 +735,7 @@ function q() {
|
|
|
651
735
|
}
|
|
652
736
|
//#endregion
|
|
653
737
|
//#region src/api/handlers/suggestions.ts
|
|
654
|
-
function
|
|
738
|
+
function X() {
|
|
655
739
|
return { POST: async (e) => {
|
|
656
740
|
let n = await e.json(), r = n.chatHistory.filter((e) => e.role === "user" || e.role === "assistant").map((e) => ({
|
|
657
741
|
role: e.role,
|
|
@@ -665,7 +749,7 @@ function J() {
|
|
|
665
749
|
}
|
|
666
750
|
//#endregion
|
|
667
751
|
//#region src/api/handlers/agents.ts
|
|
668
|
-
function
|
|
752
|
+
function Z(e) {
|
|
669
753
|
return { POST: async (t) => {
|
|
670
754
|
let n;
|
|
671
755
|
try {
|
|
@@ -680,7 +764,7 @@ function Y(e) {
|
|
|
680
764
|
}
|
|
681
765
|
//#endregion
|
|
682
766
|
//#region src/api/handlers/rewrite.ts
|
|
683
|
-
function
|
|
767
|
+
function Q(e) {
|
|
684
768
|
return { POST: async (t) => {
|
|
685
769
|
try {
|
|
686
770
|
let { text: n, prompt: r } = await t.json();
|
|
@@ -702,7 +786,7 @@ ${n}`, s = (await e.generateText({
|
|
|
702
786
|
}
|
|
703
787
|
//#endregion
|
|
704
788
|
//#region src/api/handlers/voice.ts
|
|
705
|
-
function
|
|
789
|
+
function ne(e) {
|
|
706
790
|
return { POST: async (t) => {
|
|
707
791
|
let n, r, i;
|
|
708
792
|
try {
|
|
@@ -737,15 +821,15 @@ function Z(e) {
|
|
|
737
821
|
}
|
|
738
822
|
//#endregion
|
|
739
823
|
//#region src/api/handlers/transcript.ts
|
|
740
|
-
function
|
|
824
|
+
function re(e) {
|
|
741
825
|
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
826
|
}
|
|
743
|
-
function
|
|
827
|
+
function ie(e) {
|
|
744
828
|
return { POST: async (t) => {
|
|
745
829
|
try {
|
|
746
830
|
let n = await t.formData(), r = n.get("file");
|
|
747
831
|
if (!r || !(r instanceof File)) return Response.json({ error: "file is required" }, { status: 400 });
|
|
748
|
-
let i =
|
|
832
|
+
let i = re(n.get("model")), a;
|
|
749
833
|
try {
|
|
750
834
|
a = e.getCloudflareContext().env?.AI;
|
|
751
835
|
} catch {}
|
|
@@ -762,7 +846,7 @@ function ne(e) {
|
|
|
762
846
|
}
|
|
763
847
|
//#endregion
|
|
764
848
|
//#region src/api/handlers/test-models.ts
|
|
765
|
-
function
|
|
849
|
+
function ae() {
|
|
766
850
|
return { POST: async (e) => {
|
|
767
851
|
try {
|
|
768
852
|
let { providerType: t, apiKey: n, onlyFree: r = !0 } = await e.json();
|
|
@@ -783,13 +867,13 @@ function re() {
|
|
|
783
867
|
}
|
|
784
868
|
//#endregion
|
|
785
869
|
//#region src/api/handlers/validate-openrouter.ts
|
|
786
|
-
var
|
|
787
|
-
function
|
|
870
|
+
var oe = 864e5, $ = null;
|
|
871
|
+
function se(e) {
|
|
788
872
|
return {
|
|
789
873
|
GET: async (t) => {
|
|
790
874
|
try {
|
|
791
875
|
let t = Date.now();
|
|
792
|
-
if ($ && t - $.timestamp <
|
|
876
|
+
if ($ && t - $.timestamp < oe) return Response.json({
|
|
793
877
|
...$.result,
|
|
794
878
|
cached: !0,
|
|
795
879
|
cacheAge: t - $.timestamp
|
|
@@ -823,4 +907,4 @@ function ae(e) {
|
|
|
823
907
|
};
|
|
824
908
|
}
|
|
825
909
|
//#endregion
|
|
826
|
-
export {
|
|
910
|
+
export { Z as createAgentsHandler, b as createArticleFollowupsHandler, C as createArticleQAHandler, Y as createAutocompleteHandler, T as createChatByIdHandler, D as createChatTitleHandler, w as createChatsHandler, ee as createChatsSearchHandler, E as createChatsShareHandler, z as createDiscoverHandler, F as createMCPServerByIdHandler, I as createMCPServerToggleHandler, P as createMCPServersHandler, A as createMessagesHandler, x as createPageTipsHandler, M as createProviderByIdHandler, N as createProviderModelsHandler, j as createProvidersHandler, Q as createRewriteHandler, R as createSearchHandler, X as createSuggestionsHandler, ae as createTestModelsHandler, S as createTopicSearchesHandler, ie as createTranscriptHandler, se as createValidateOpenRouterHandler, ne as createVoiceHandler, k 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.129",
|
|
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.258",
|
|
84
84
|
"class-variance-authority": "^0.7.1",
|
|
85
85
|
"clsx": "^2.1.1",
|
|
86
|
-
"domain-rank": "^0.1.
|
|
86
|
+
"domain-rank": "^0.1.247",
|
|
87
87
|
"dompurify": "^3.4.9",
|
|
88
88
|
"drizzle-orm": "^0.45.2",
|
|
89
|
-
"extract-webpage": "^1.2.
|
|
89
|
+
"extract-webpage": "^1.2.257",
|
|
90
90
|
"framer-motion": "^12.40.0",
|
|
91
91
|
"fuse.js": "^7.1.0",
|
|
92
92
|
"grab-url": "^1.6.22",
|
|
@@ -96,13 +96,13 @@
|
|
|
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.204",
|
|
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.
|
|
105
|
-
"search-web-api": "^1.0.
|
|
104
|
+
"use-weather-forecast": "^0.1.74",
|
|
105
|
+
"search-web-api": "^1.0.111",
|
|
106
106
|
"sonner": "^2.0.7",
|
|
107
107
|
"streamdown": "^2.5.0",
|
|
108
108
|
"tailwind-merge": "^3.6.0",
|