research-agent-ui 0.1.25 → 0.1.27
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/messages.d.ts +7 -0
- package/dist/api.cjs +2 -2
- package/dist/api.mjs +54 -43
- package/package.json +4 -4
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import type { MessagesDeps } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Flattens an error's `cause` chain into one string. Drizzle wraps driver
|
|
4
|
+
* errors (e.g. D1's "no such column" / constraint failures) in a generic
|
|
5
|
+
* "Failed query" error and puts the real one in `cause`, which structured
|
|
6
|
+
* log sinks drop unless serialized explicitly.
|
|
7
|
+
*/
|
|
8
|
+
export declare function describeError(err: unknown): string;
|
|
2
9
|
export declare function createMessagesHandler(deps: MessagesDeps): {
|
|
3
10
|
POST: (req: Request) => Promise<Response>;
|
|
4
11
|
};
|
package/dist/api.cjs
CHANGED
|
@@ -17,6 +17,6 @@ User question: ${a}
|
|
|
17
17
|
|
|
18
18
|
Please provide a helpful answer based on the article content above.`,_=await m.stream([{role:`system`,content:`You are a helpful AI assistant that answers questions about articles.
|
|
19
19
|
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:g}]),v=``;for await(let e of _)v+=e.content;return Response.json({content:v,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 f(e){let{chats:t,messages:r}=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,n.count)(r.id)}).from(t).leftJoin(r,(0,n.and)((0,n.eq)(r.chatId,t.id),(0,n.eq)(r.role,`user`))).where((0,n.eq)(t.userId,a)).groupBy(t.id,t.title,t.createdAt,t.focusMode,t.userId,t.files).orderBy(n.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,n.eq)(t.userId,a),columns:{id:!0}});if(o.length>0){let e=o.map(e=>e.id);await i.delete(r).where((0,n.inArray)(r.chatId,e)),await i.delete(t).where((0,n.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 p(e){let{chats:t,messages:r}=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,n.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,n.eq)(r.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,n.and)((0,n.eq)(t.id,o),(0,n.eq)(t.userId,s))})?(await i.delete(t).where((0,n.eq)(t.id,o)).execute(),await i.delete(r).where((0,n.eq)(r.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 m(e){let{chats:t,messages:r}=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,n.and)((0,n.eq)(t.userId,o),(0,n.like)(t.title,l))).orderBy(n.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(r).innerJoin(t,(0,n.eq)(r.chatId,t.id)).where((0,n.and)((0,n.eq)(t.userId,o),(0,n.or)((0,n.like)(r.content,l)))).orderBy(n.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:r.chatId,count:n.sql`count(*)`}).from(r).where((0,n.and)(n.sql`${r.chatId} IN (${n.sql.join(m.map(e=>n.sql`${e}`),n.sql`, `)})`,(0,n.eq)(r.role,`user`))).groupBy(r.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 h(e){let{chats:t}=e.schema;return{POST:async r=>{try{let i=e.getDB(),{chatId:a}=await r.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,n.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,n.eq)(t.id,a)).execute();let c=`${new URL(r.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 g(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}):(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}))}catch(e){return console.error(`Error saving message:`,e),Response.json({message:`Failed to save message`},{status:500})}}}}function _(e){return{GET:async n=>{try{let r=new t.default,i=new URL(n.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:n,config:r}=await e.json();if(!n||!r)return Response.json({message:`Missing required fields.`},{status:400});let i=await new t.default().addProvider(n,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 v(){return{DELETE:async(e,{params:n})=>{try{let{id:e}=await n;return e?(await new t.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:n})=>{try{let{config:r}=await e.json(),{id:i}=await n;if(!i||!r)return Response.json({message:`Missing required fields.`},{status:400});let a=await new t.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 y(){return{POST:async(e,{params:n})=>{try{let{id:r}=await n,i=await e.json();return!i.key||!i.name?Response.json({message:`Key and name must be provided`},{status:400}):(await new t.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:n})=>{try{let{id:r}=await n,i=await e.json();return i.key?(await new t.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 b(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 x(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 S(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 C={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 w(e={}){let t=e.searxngDomain??`https://search.qwksearch.com`;return{GET:async e=>{let n=new URL(e.url).searchParams,i=n.get(`q`),a=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(!i)return Response.json({error:`Query parameter is required`},{status:400});let d=Date.now();try{let e=await(0,r.searchWeb)(i,{category:a,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,r.searchWeb)(i,{category:a,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 T(){return{GET:async e=>{try{let t=new URL(e.url).searchParams,n=t.get(`mode`)||`normal`,i=C[t.get(`topic`)||`tech`],a=[];if(n===`normal`){let e=new Set;a=(await Promise.all(i.links.flatMap(e=>i.query.map(async t=>(await(0,r.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)?!1:(e.add(n),!0)}).sort(()=>Math.random()-.5)}else a=(await(0,r.searchSearxng)(`site:${i.links[Math.floor(Math.random()*i.links.length)]} ${i.query[Math.floor(Math.random()*i.query.length)]}`,{engines:[`bing news`],pageno:1,language:`en`})).results;return Response.json({blogs:a},{status:200})}catch(e){return console.error(`An error occurred in discover route: ${e}`),Response.json({message:`An error has occurred`},{status:500})}}}}var E=[`google`,`duckduckgo`,`wikipedia`],D=3,O=3,k=Object.entries(o.default).map(([e,t])=>({domain:e,name:typeof t?.[0]==`string`?t[0]:``,rank:typeof t?.[1]==`number`?t[1]:2**53-1})),A=null;function j(){return A||=new a.default(k,{keys:[{name:`name`,weight:.6},{name:`domain`,weight:.4}],threshold:.1,ignoreLocation:!0,includeScore:!0,minMatchCharLength:3}),A}function M(e){let t=e.split(/\s+/).filter(Boolean),n=t[t.length-1]||``;return n.length<3?[]:j().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).slice(0,O).map(({item:e})=>({domain:e.domain,name:e.name,favicon:`https://www.google.com/s2/favicons?domain=${encodeURIComponent(e.domain)}&sz=64`}))}async function N(e,t,n){let r=await(0,i.searchAutocompleteMulti)(e,t,n);if(r.length>0)return r;let a=t.split(/\s+/).filter(Boolean),o=Math.min(D,a.length-1);for(let r=o;r>=1;r--){let o=a.slice(-r).join(` `),s=a.slice(0,-r).join(` `),c=await(0,i.searchAutocompleteMulti)(e,o,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 P(){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):E;try{let e=await N(o,n,r),t=M(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 F(){return{POST:async e=>{let n=await e.json(),r=n.chatHistory.filter(e=>e.role===`user`||e.role===`assistant`).map(e=>({role:e.role,content:String(e.content??``)})),i=await new t.default().loadChatModel(n.chatModel.providerId,n.chatModel.key),a=(await(0,s.default)({chat_history:r,maxQuestions:n.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 I(e){return{POST:async t=>{let r;try{r=await t.json()}catch{return Response.json({error:`Invalid JSON input`},{status:500})}r.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,n.eq)(e.userSchema.id,a)})),o&&(r.apiKey=o.settings?.providerApiKeys?.find(e=>e.provider==r.provider)?.key),r.apiKey||=r.provider==`groq`&&e.getEnv(`GROQ_API_KEY`),r.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 L(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:
|
|
20
|
+
If the answer is not in the article, say so.`},{role:`user`,content:g}]),v=``;for await(let e of _)v+=e.content;return Response.json({content:v,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 f(e){let{chats:t,messages:r}=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,n.count)(r.id)}).from(t).leftJoin(r,(0,n.and)((0,n.eq)(r.chatId,t.id),(0,n.eq)(r.role,`user`))).where((0,n.eq)(t.userId,a)).groupBy(t.id,t.title,t.createdAt,t.focusMode,t.userId,t.files).orderBy(n.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,n.eq)(t.userId,a),columns:{id:!0}});if(o.length>0){let e=o.map(e=>e.id);await i.delete(r).where((0,n.inArray)(r.chatId,e)),await i.delete(t).where((0,n.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 p(e){let{chats:t,messages:r}=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,n.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,n.eq)(r.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,n.and)((0,n.eq)(t.id,o),(0,n.eq)(t.userId,s))})?(await i.delete(t).where((0,n.eq)(t.id,o)).execute(),await i.delete(r).where((0,n.eq)(r.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 m(e){let{chats:t,messages:r}=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,n.and)((0,n.eq)(t.userId,o),(0,n.like)(t.title,l))).orderBy(n.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(r).innerJoin(t,(0,n.eq)(r.chatId,t.id)).where((0,n.and)((0,n.eq)(t.userId,o),(0,n.or)((0,n.like)(r.content,l)))).orderBy(n.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:r.chatId,count:n.sql`count(*)`}).from(r).where((0,n.and)(n.sql`${r.chatId} IN (${n.sql.join(m.map(e=>n.sql`${e}`),n.sql`, `)})`,(0,n.eq)(r.role,`user`))).groupBy(r.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 h(e){let{chats:t}=e.schema;return{POST:async r=>{try{let i=e.getDB(),{chatId:a}=await r.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,n.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,n.eq)(t.id,a)).execute();let c=`${new URL(r.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}))}}}}var g=[`assistant`,`user`,`source`,`suggestion`];function _(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 v(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}):g.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:`,_(e)),Response.json({message:`Failed to save message`},{status:500})}}}}function y(e){return{GET:async n=>{try{let r=new t.default,i=new URL(n.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:n,config:r}=await e.json();if(!n||!r)return Response.json({message:`Missing required fields.`},{status:400});let i=await new t.default().addProvider(n,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 b(){return{DELETE:async(e,{params:n})=>{try{let{id:e}=await n;return e?(await new t.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:n})=>{try{let{config:r}=await e.json(),{id:i}=await n;if(!i||!r)return Response.json({message:`Missing required fields.`},{status:400});let a=await new t.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 x(){return{POST:async(e,{params:n})=>{try{let{id:r}=await n,i=await e.json();return!i.key||!i.name?Response.json({message:`Key and name must be provided`},{status:400}):(await new t.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:n})=>{try{let{id:r}=await n,i=await e.json();return i.key?(await new t.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 S(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 C(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 w(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 T={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 E(e={}){let t=e.searxngDomain??`https://search.qwksearch.com`;return{GET:async e=>{let n=new URL(e.url).searchParams,i=n.get(`q`),a=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(!i)return Response.json({error:`Query parameter is required`},{status:400});let d=Date.now();try{let e=await(0,r.searchWeb)(i,{category:a,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,r.searchWeb)(i,{category:a,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 D(){return{GET:async e=>{try{let t=new URL(e.url).searchParams,n=t.get(`mode`)||`normal`,i=T[t.get(`topic`)||`tech`],a=[];if(n===`normal`){let e=new Set;a=(await Promise.all(i.links.flatMap(e=>i.query.map(async t=>(await(0,r.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)?!1:(e.add(n),!0)}).sort(()=>Math.random()-.5)}else a=(await(0,r.searchSearxng)(`site:${i.links[Math.floor(Math.random()*i.links.length)]} ${i.query[Math.floor(Math.random()*i.query.length)]}`,{engines:[`bing news`],pageno:1,language:`en`})).results;return Response.json({blogs:a},{status:200})}catch(e){return console.error(`An error occurred in discover route: ${e}`),Response.json({message:`An error has occurred`},{status:500})}}}}var O=[`google`,`duckduckgo`,`wikipedia`],k=3,A=3,j=Object.entries(o.default).map(([e,t])=>({domain:e,name:typeof t?.[0]==`string`?t[0]:``,rank:typeof t?.[1]==`number`?t[1]:2**53-1})),M=null;function N(){return M||=new a.default(j,{keys:[{name:`name`,weight:.6},{name:`domain`,weight:.4}],threshold:.1,ignoreLocation:!0,includeScore:!0,minMatchCharLength:3}),M}function P(e){let t=e.split(/\s+/).filter(Boolean),n=t[t.length-1]||``;return n.length<3?[]:N().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).slice(0,A).map(({item:e})=>({domain:e.domain,name:e.name,favicon:`https://www.google.com/s2/favicons?domain=${encodeURIComponent(e.domain)}&sz=64`}))}async function F(e,t,n){let r=await(0,i.searchAutocompleteMulti)(e,t,n);if(r.length>0)return r;let a=t.split(/\s+/).filter(Boolean),o=Math.min(k,a.length-1);for(let r=o;r>=1;r--){let o=a.slice(-r).join(` `),s=a.slice(0,-r).join(` `),c=await(0,i.searchAutocompleteMulti)(e,o,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 I(){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):O;try{let e=await F(o,n,r),t=P(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 L(){return{POST:async e=>{let n=await e.json(),r=n.chatHistory.filter(e=>e.role===`user`||e.role===`assistant`).map(e=>({role:e.role,content:String(e.content??``)})),i=await new t.default().loadChatModel(n.chatModel.providerId,n.chatModel.key),a=(await(0,s.default)({chat_history:r,maxQuestions:n.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 R(e){return{POST:async t=>{let r;try{r=await t.json()}catch{return Response.json({error:`Invalid JSON input`},{status:500})}r.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,n.eq)(e.userSchema.id,a)})),o&&(r.apiKey=o.settings?.providerApiKeys?.find(e=>e.provider==r.provider)?.key),r.apiKey||=r.provider==`groq`&&e.getEnv(`GROQ_API_KEY`),r.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 z(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
21
|
|
|
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
|
|
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 B(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 V(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 H(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=V(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 U(){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=l.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,c.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 W=1440*60*1e3,G=null;function K(e){return{GET:async t=>{try{let t=Date.now();if(G&&t-G.timestamp<W)return Response.json({...G.result,cached:!0,cacheAge:t-G.timestamp});let n=await e.validateOpenRouterModels();return G={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 G={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=R,exports.createArticleFollowupsHandler=u,exports.createArticleQAHandler=d,exports.createAutocompleteHandler=I,exports.createChatByIdHandler=p,exports.createChatsHandler=f,exports.createChatsSearchHandler=m,exports.createChatsShareHandler=h,exports.createDiscoverHandler=D,exports.createMCPServerByIdHandler=C,exports.createMCPServerToggleHandler=w,exports.createMCPServersHandler=S,exports.createMessagesHandler=v,exports.createProviderByIdHandler=b,exports.createProviderModelsHandler=x,exports.createProvidersHandler=y,exports.createRewriteHandler=z,exports.createSearchHandler=E,exports.createSuggestionsHandler=L,exports.createTestModelsHandler=U,exports.createTranscriptHandler=H,exports.createValidateOpenRouterHandler=K,exports.createVoiceHandler=B,exports.describeError=_;
|
package/dist/api.mjs
CHANGED
|
@@ -227,11 +227,22 @@ function x(e) {
|
|
|
227
227
|
}
|
|
228
228
|
//#endregion
|
|
229
229
|
//#region src/api/handlers/messages.ts
|
|
230
|
-
|
|
230
|
+
var S = [
|
|
231
|
+
"assistant",
|
|
232
|
+
"user",
|
|
233
|
+
"source",
|
|
234
|
+
"suggestion"
|
|
235
|
+
];
|
|
236
|
+
function C(e) {
|
|
237
|
+
let t = [], n = e;
|
|
238
|
+
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;
|
|
239
|
+
return t.join(" <- caused by: ");
|
|
240
|
+
}
|
|
241
|
+
function w(e) {
|
|
231
242
|
return { POST: async (t) => {
|
|
232
243
|
try {
|
|
233
244
|
let n = e.getDB(), r = await e.requireUserId(), { chatId: i, messageId: a, role: o, suggestions: s, content: c, sources: l } = await t.json();
|
|
234
|
-
return !i || !a || !o ? Response.json({ message: "Missing required fields" }, { status: 400 }) : (await n.insert(e.messagesSchema).values({
|
|
245
|
+
return !i || !a || !o ? Response.json({ message: "Missing required fields" }, { status: 400 }) : S.includes(o) ? (await n.insert(e.messagesSchema).values({
|
|
235
246
|
chatId: i,
|
|
236
247
|
userId: r,
|
|
237
248
|
messageId: a,
|
|
@@ -240,15 +251,15 @@ function S(e) {
|
|
|
240
251
|
suggestions: s || [],
|
|
241
252
|
sources: l || [],
|
|
242
253
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
243
|
-
}), Response.json({ message: "Message saved successfully" }, { status: 200 }));
|
|
254
|
+
}), Response.json({ message: "Message saved successfully" }, { status: 200 })) : Response.json({ message: `Invalid role: ${o}` }, { status: 400 });
|
|
244
255
|
} catch (e) {
|
|
245
|
-
return console.error("Error saving message:", e), Response.json({ message: "Failed to save message" }, { status: 500 });
|
|
256
|
+
return console.error("Error saving message:", C(e)), Response.json({ message: "Failed to save message" }, { status: 500 });
|
|
246
257
|
}
|
|
247
258
|
} };
|
|
248
259
|
}
|
|
249
260
|
//#endregion
|
|
250
261
|
//#region src/api/handlers/providers.ts
|
|
251
|
-
function
|
|
262
|
+
function T(t) {
|
|
252
263
|
return {
|
|
253
264
|
GET: async (n) => {
|
|
254
265
|
try {
|
|
@@ -278,7 +289,7 @@ function C(t) {
|
|
|
278
289
|
}
|
|
279
290
|
};
|
|
280
291
|
}
|
|
281
|
-
function
|
|
292
|
+
function E() {
|
|
282
293
|
return {
|
|
283
294
|
DELETE: async (t, { params: n }) => {
|
|
284
295
|
try {
|
|
@@ -300,7 +311,7 @@ function w() {
|
|
|
300
311
|
}
|
|
301
312
|
};
|
|
302
313
|
}
|
|
303
|
-
function
|
|
314
|
+
function D() {
|
|
304
315
|
return {
|
|
305
316
|
POST: async (t, { params: n }) => {
|
|
306
317
|
try {
|
|
@@ -322,7 +333,7 @@ function T() {
|
|
|
322
333
|
}
|
|
323
334
|
//#endregion
|
|
324
335
|
//#region src/api/handlers/mcpservers.ts
|
|
325
|
-
function
|
|
336
|
+
function O(e) {
|
|
326
337
|
return {
|
|
327
338
|
GET: async (t) => {
|
|
328
339
|
try {
|
|
@@ -344,7 +355,7 @@ function E(e) {
|
|
|
344
355
|
}
|
|
345
356
|
};
|
|
346
357
|
}
|
|
347
|
-
function
|
|
358
|
+
function k(e) {
|
|
348
359
|
return {
|
|
349
360
|
DELETE: async (t, { params: n }) => {
|
|
350
361
|
try {
|
|
@@ -366,7 +377,7 @@ function D(e) {
|
|
|
366
377
|
}
|
|
367
378
|
};
|
|
368
379
|
}
|
|
369
|
-
function
|
|
380
|
+
function A(e) {
|
|
370
381
|
return { POST: async (t, { params: n }) => {
|
|
371
382
|
try {
|
|
372
383
|
let { enabled: r } = await t.json(), { id: i } = await n;
|
|
@@ -380,7 +391,7 @@ function O(e) {
|
|
|
380
391
|
}
|
|
381
392
|
//#endregion
|
|
382
393
|
//#region src/api/handlers/search.ts
|
|
383
|
-
var
|
|
394
|
+
var j = {
|
|
384
395
|
tech: {
|
|
385
396
|
query: [
|
|
386
397
|
"technology news",
|
|
@@ -446,7 +457,7 @@ var k = {
|
|
|
446
457
|
]
|
|
447
458
|
}
|
|
448
459
|
};
|
|
449
|
-
function
|
|
460
|
+
function M(e = {}) {
|
|
450
461
|
let t = e.searxngDomain ?? "https://search.qwksearch.com";
|
|
451
462
|
return { GET: async (e) => {
|
|
452
463
|
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, u = n.get("publicInstances") === "true";
|
|
@@ -493,10 +504,10 @@ function A(e = {}) {
|
|
|
493
504
|
}
|
|
494
505
|
} };
|
|
495
506
|
}
|
|
496
|
-
function
|
|
507
|
+
function N() {
|
|
497
508
|
return { GET: async (e) => {
|
|
498
509
|
try {
|
|
499
|
-
let t = new URL(e.url).searchParams, n = t.get("mode") || "normal", r =
|
|
510
|
+
let t = new URL(e.url).searchParams, n = t.get("mode") || "normal", r = j[t.get("topic") || "tech"], i = [];
|
|
500
511
|
if (n === "normal") {
|
|
501
512
|
let e = /* @__PURE__ */ new Set();
|
|
502
513
|
i = (await Promise.all(r.links.flatMap((e) => r.query.map(async (t) => (await c(`site:${e} ${t}`, {
|
|
@@ -520,17 +531,17 @@ function j() {
|
|
|
520
531
|
}
|
|
521
532
|
//#endregion
|
|
522
533
|
//#region src/api/handlers/autocomplete.ts
|
|
523
|
-
var
|
|
534
|
+
var P = [
|
|
524
535
|
"google",
|
|
525
536
|
"duckduckgo",
|
|
526
537
|
"wikipedia"
|
|
527
|
-
],
|
|
538
|
+
], F = 3, I = 3, L = Object.entries(f).map(([e, t]) => ({
|
|
528
539
|
domain: e,
|
|
529
540
|
name: typeof t?.[0] == "string" ? t[0] : "",
|
|
530
541
|
rank: typeof t?.[1] == "number" ? t[1] : 2 ** 53 - 1
|
|
531
|
-
})),
|
|
532
|
-
function
|
|
533
|
-
return
|
|
542
|
+
})), R = null;
|
|
543
|
+
function z() {
|
|
544
|
+
return R ||= new d(L, {
|
|
534
545
|
keys: [{
|
|
535
546
|
name: "name",
|
|
536
547
|
weight: .6
|
|
@@ -542,20 +553,20 @@ function L() {
|
|
|
542
553
|
ignoreLocation: !0,
|
|
543
554
|
includeScore: !0,
|
|
544
555
|
minMatchCharLength: 3
|
|
545
|
-
}),
|
|
556
|
+
}), R;
|
|
546
557
|
}
|
|
547
|
-
function
|
|
558
|
+
function B(e) {
|
|
548
559
|
let t = e.split(/\s+/).filter(Boolean), n = t[t.length - 1] || "";
|
|
549
|
-
return n.length < 3 ? [] :
|
|
560
|
+
return n.length < 3 ? [] : 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).slice(0, I).map(({ item: e }) => ({
|
|
550
561
|
domain: e.domain,
|
|
551
562
|
name: e.name,
|
|
552
563
|
favicon: `https://www.google.com/s2/favicons?domain=${encodeURIComponent(e.domain)}&sz=64`
|
|
553
564
|
}));
|
|
554
565
|
}
|
|
555
|
-
async function
|
|
566
|
+
async function V(e, t, n) {
|
|
556
567
|
let r = await u(e, t, n);
|
|
557
568
|
if (r.length > 0) return r;
|
|
558
|
-
let i = t.split(/\s+/).filter(Boolean), a = Math.min(
|
|
569
|
+
let i = t.split(/\s+/).filter(Boolean), a = Math.min(F, i.length - 1);
|
|
559
570
|
for (let r = a; r >= 1; r--) {
|
|
560
571
|
let a = i.slice(-r).join(" "), o = i.slice(0, -r).join(" "), s = await u(e, a, n);
|
|
561
572
|
if (s.length > 0) {
|
|
@@ -569,16 +580,16 @@ async function z(e, t, n) {
|
|
|
569
580
|
}
|
|
570
581
|
return [];
|
|
571
582
|
}
|
|
572
|
-
function
|
|
583
|
+
function H() {
|
|
573
584
|
return { GET: async (e) => {
|
|
574
585
|
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);
|
|
575
586
|
if (!n) return Response.json({
|
|
576
587
|
suggestions: [],
|
|
577
588
|
domains: []
|
|
578
589
|
});
|
|
579
|
-
let o = i ? i.split(",").map((e) => e.trim()).filter(Boolean) :
|
|
590
|
+
let o = i ? i.split(",").map((e) => e.trim()).filter(Boolean) : P;
|
|
580
591
|
try {
|
|
581
|
-
let e = await
|
|
592
|
+
let e = await V(o, n, r), t = B(n);
|
|
582
593
|
return Response.json({
|
|
583
594
|
suggestions: e.slice(0, a),
|
|
584
595
|
domains: t
|
|
@@ -593,7 +604,7 @@ function B() {
|
|
|
593
604
|
}
|
|
594
605
|
//#endregion
|
|
595
606
|
//#region src/api/handlers/suggestions.ts
|
|
596
|
-
function
|
|
607
|
+
function U() {
|
|
597
608
|
return { POST: async (t) => {
|
|
598
609
|
let n = await t.json(), r = n.chatHistory.filter((e) => e.role === "user" || e.role === "assistant").map((e) => ({
|
|
599
610
|
role: e.role,
|
|
@@ -607,7 +618,7 @@ function V() {
|
|
|
607
618
|
}
|
|
608
619
|
//#endregion
|
|
609
620
|
//#region src/api/handlers/agents.ts
|
|
610
|
-
function
|
|
621
|
+
function W(e) {
|
|
611
622
|
return { POST: async (t) => {
|
|
612
623
|
let n;
|
|
613
624
|
try {
|
|
@@ -622,7 +633,7 @@ function H(e) {
|
|
|
622
633
|
}
|
|
623
634
|
//#endregion
|
|
624
635
|
//#region src/api/handlers/rewrite.ts
|
|
625
|
-
function
|
|
636
|
+
function G(e) {
|
|
626
637
|
return { POST: async (t) => {
|
|
627
638
|
try {
|
|
628
639
|
let { text: n, prompt: r } = await t.json();
|
|
@@ -644,7 +655,7 @@ ${n}`, s = (await e.generateText({
|
|
|
644
655
|
}
|
|
645
656
|
//#endregion
|
|
646
657
|
//#region src/api/handlers/voice.ts
|
|
647
|
-
function
|
|
658
|
+
function K(e) {
|
|
648
659
|
return { POST: async (t) => {
|
|
649
660
|
let n, r, i;
|
|
650
661
|
try {
|
|
@@ -679,15 +690,15 @@ function W(e) {
|
|
|
679
690
|
}
|
|
680
691
|
//#endregion
|
|
681
692
|
//#region src/api/handlers/transcript.ts
|
|
682
|
-
function
|
|
693
|
+
function q(e) {
|
|
683
694
|
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";
|
|
684
695
|
}
|
|
685
|
-
function
|
|
696
|
+
function J(e) {
|
|
686
697
|
return { POST: async (t) => {
|
|
687
698
|
try {
|
|
688
699
|
let n = await t.formData(), r = n.get("file");
|
|
689
700
|
if (!r || !(r instanceof File)) return Response.json({ error: "file is required" }, { status: 400 });
|
|
690
|
-
let i =
|
|
701
|
+
let i = q(n.get("model")), a;
|
|
691
702
|
try {
|
|
692
703
|
a = e.getCloudflareContext().env?.AI;
|
|
693
704
|
} catch {}
|
|
@@ -704,7 +715,7 @@ function K(e) {
|
|
|
704
715
|
}
|
|
705
716
|
//#endregion
|
|
706
717
|
//#region src/api/handlers/test-models.ts
|
|
707
|
-
function
|
|
718
|
+
function Y() {
|
|
708
719
|
return { POST: async (e) => {
|
|
709
720
|
try {
|
|
710
721
|
let { providerType: t, apiKey: n, onlyFree: r = !0 } = await e.json();
|
|
@@ -725,19 +736,19 @@ function q() {
|
|
|
725
736
|
}
|
|
726
737
|
//#endregion
|
|
727
738
|
//#region src/api/handlers/validate-openrouter.ts
|
|
728
|
-
var
|
|
729
|
-
function
|
|
739
|
+
var X = 1440 * 60 * 1e3, Z = null;
|
|
740
|
+
function Q(e) {
|
|
730
741
|
return {
|
|
731
742
|
GET: async (t) => {
|
|
732
743
|
try {
|
|
733
744
|
let t = Date.now();
|
|
734
|
-
if (
|
|
735
|
-
...
|
|
745
|
+
if (Z && t - Z.timestamp < X) return Response.json({
|
|
746
|
+
...Z.result,
|
|
736
747
|
cached: !0,
|
|
737
|
-
cacheAge: t -
|
|
748
|
+
cacheAge: t - Z.timestamp
|
|
738
749
|
});
|
|
739
750
|
let n = await e.validateOpenRouterModels();
|
|
740
|
-
return
|
|
751
|
+
return Z = {
|
|
741
752
|
result: n,
|
|
742
753
|
timestamp: t
|
|
743
754
|
}, Response.json({
|
|
@@ -751,7 +762,7 @@ function X(e) {
|
|
|
751
762
|
POST: async (t) => {
|
|
752
763
|
try {
|
|
753
764
|
let { concurrency: n = 3, timeout: r = 15e3 } = await t.json().catch(() => ({})), i = await e.validateOpenRouterModels(n, r);
|
|
754
|
-
return
|
|
765
|
+
return Z = {
|
|
755
766
|
result: i,
|
|
756
767
|
timestamp: Date.now()
|
|
757
768
|
}, Response.json({
|
|
@@ -765,4 +776,4 @@ function X(e) {
|
|
|
765
776
|
};
|
|
766
777
|
}
|
|
767
778
|
//#endregion
|
|
768
|
-
export {
|
|
779
|
+
export { W as createAgentsHandler, g as createArticleFollowupsHandler, _ as createArticleQAHandler, H as createAutocompleteHandler, y as createChatByIdHandler, v as createChatsHandler, b as createChatsSearchHandler, x as createChatsShareHandler, N as createDiscoverHandler, k as createMCPServerByIdHandler, A as createMCPServerToggleHandler, O as createMCPServersHandler, w as createMessagesHandler, E as createProviderByIdHandler, D as createProviderModelsHandler, T as createProvidersHandler, G as createRewriteHandler, M as createSearchHandler, U as createSuggestionsHandler, Y as createTestModelsHandler, J as createTranscriptHandler, Q as createValidateOpenRouterHandler, K as createVoiceHandler, C 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.27",
|
|
5
5
|
"author": "vtempest",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -60,14 +60,14 @@
|
|
|
60
60
|
"@radix-ui/react-slot": "^1.2.5",
|
|
61
61
|
"@radix-ui/react-tooltip": "^1.2.9",
|
|
62
62
|
"@ricky0123/vad-web": "^0.0.30",
|
|
63
|
-
"chat-agent-toolkit": "^1.2.
|
|
64
|
-
"domain-rank": "^0.1.
|
|
63
|
+
"chat-agent-toolkit": "^1.2.46",
|
|
64
|
+
"domain-rank": "^0.1.35",
|
|
65
65
|
"drizzle-orm": "^0.45.2",
|
|
66
66
|
"fuse.js": "^7.1.0",
|
|
67
67
|
"class-variance-authority": "^0.7.1",
|
|
68
68
|
"clsx": "^2.1.1",
|
|
69
69
|
"dompurify": "^3.4.9",
|
|
70
|
-
"extract-webpage": "^1.2.
|
|
70
|
+
"extract-webpage": "^1.2.47",
|
|
71
71
|
"framer-motion": "^12.40.0",
|
|
72
72
|
"grab-url": "^1.6.22",
|
|
73
73
|
"qwksearch-api-client": "^0.9.1",
|