research-agent-ui 0.1.251 → 0.1.253

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @fileoverview Handler that rewrites user-supplied text for clarity/grammar/style via Groq.
2
+ * @fileoverview Handler that rewrites user-supplied text for clarity/grammar/style.
3
3
  *
4
4
  * Answers in one of two shapes, chosen by the request:
5
5
  *
@@ -11,6 +11,17 @@
11
11
  * instead of jumping from a spinner to a finished answer.
12
12
  *
13
13
  * Both run the same prompt against the same model; only the transport differs.
14
+ *
15
+ * Two things here exist because of a live 500 on `/api/agent/rewrite`, which
16
+ * the logs could only describe as "500, 70ms":
17
+ *
18
+ * - The model is no longer *only* the deployment's Groq key. A host that
19
+ * configured some other provider — or a signed-in user who brought their
20
+ * own — now gets a rewrite instead of a 500 nobody could act on.
21
+ * - A failure says what failed. The catch-all used to answer "Please try
22
+ * again" whatever went wrong, and the streaming path committed to a 200
23
+ * before the model had produced a single token, so a rejected key or a
24
+ * retired model reached the editor as an empty panel.
14
25
  */
15
26
  import type { RewriteDeps } from "../types";
16
27
  export declare function createRewriteHandler(deps: RewriteDeps): {
@@ -81,6 +81,21 @@ export interface RewriteDeps extends EnvDeps {
81
81
  createGroq: (opts: {
82
82
  apiKey: string;
83
83
  }) => (modelId: string) => any;
84
+ /**
85
+ * Loads a model the way the article/page handlers do — from the host's own
86
+ * provider registry, using whichever key that deployment or the signed-in
87
+ * user configured. Optional, and tried either side of the Groq key: first
88
+ * when the caller names a `chatModel`, last when `GROQ_API_KEY` is unset.
89
+ *
90
+ * Without it a deployment that never set `GROQ_API_KEY` answers every
91
+ * rewrite with a 500, even while its chat routes hold a working model.
92
+ */
93
+ loadChatModel?: (chatModel?: RewriteChatModel) => Promise<unknown>;
94
+ }
95
+ /** The provider/model pair a caller may name, as the settings UI stores it. */
96
+ export interface RewriteChatModel {
97
+ providerId?: string;
98
+ key?: string;
84
99
  }
85
100
  export interface ValidateOpenRouterDeps {
86
101
  validateOpenRouterModels: (concurrency?: number, timeout?: number) => Promise<any>;
package/dist/api.cjs CHANGED
@@ -33,6 +33,6 @@ User question: ${i}
33
33
 
34
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.
35
35
  Provide clear, concise, and accurate answers based on the article content provided.
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=Number.isFinite(o)&&o>0?o:1,c=n.get(`lang`)||`en-US`,l=n.get(`safesearch`)===`true`,u=n.get(`recency`)||void 0,d=n.get(`publicInstances`)===`true`;if(!r)return Response.json({error:`Query parameter is required`},{status:400});let f=Date.now();try{let e=await(0,a.searchWeb)(r,{category:i,recency:u,safesearch:l,maxRetries:6,privateSearxng:!d&&t,proxy:``,lang:c,page:s});e&&(Array.isArray(e)?e.length>0:e.results&&e.results.length>0)||(e=await(0,a.searchWeb)(r,{category:i,recency:u,safesearch:l,maxRetries:6,privateSearxng:!1,proxy:``,lang:c,page:s}));let n=Date.now()-f;return e?Array.isArray(e)?Response.json({results:e,elapsedTime:n}):Response.json({...e,elapsedTime:n}):Response.json({results:[],suggestions:[],elapsedTime:n})}catch(e){let t=e instanceof Error?e.message:String(e);return console.error(`Search error for q="${r}" cat="${i}" page=${s}: ${t}`,e instanceof Error?e.stack:void 0),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,promptTemplate:t.promptTemplate},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,stream:i}=await t.json();if(!n||typeof n!=`string`)return Response.json({error:`Text is required and must be a string`},{status:400});let a=e.getEnv(`GROQ_API_KEY`);if(!a)return console.error(`GROQ_API_KEY is not configured`),Response.json({error:`AI service is not configured. Please contact the administrator.`},{status:500});let o=e.createGroq({apiKey:a})(`llama-3.3-70b-versatile`),s=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 ee(e){let{chats:t,messages:n}=e.schema;return{GET:async(i,{params:a})=>{try{let i=e.getDB(),{id:o}=await a,s;try{s=await e.requireUserId()}catch{s=void 0}let c=await i.query.chats.findFirst({where:(0,r.eq)(t.id,o)});if(!c)return Response.json({message:`Chat not found`},{status:404});if(!(c.userId===s||c.isPublic))return Response.json({message:`Unauthorized - this chat is private`},{status:403});let l=await i.query.messages.findMany({where:(0,r.eq)(n.chatId,o)});return Response.json({chat:c,messages:l},{status:200})}catch(e){return console.error(`Error in getting chat by id: `,e),Response.json({message:`An error has occurred.`},{status:500})}},DELETE:async(i,{params:a})=>{try{let i=e.getDB(),{id:o}=await a,s=await e.requireUserId();return await i.query.chats.findFirst({where:(0,r.and)((0,r.eq)(t.id,o),(0,r.eq)(t.userId,s))})?(await i.delete(t).where((0,r.eq)(t.id,o)).execute(),await i.delete(n).where((0,r.eq)(n.chatId,o)).execute(),Response.json({message:`Chat deleted successfully`},{status:200})):Response.json({message:`Chat not found`},{status:404})}catch(e){return e instanceof Error&&e.message===`Unauthorized`?Response.json({message:`Authentication required`},{status:401}):(console.error(`Error in deleting chat by id: `,e),Response.json({message:`An error has occurred.`},{status:500}))}}}}function v(e){let{chats:t,messages:n}=e.schema;return{GET:async i=>{try{let a=e.getDB(),o=await e.requireUserId(),{searchParams:s}=new URL(i.url),c=s.get(`q`);if(!c||c.trim().length===0)return Response.json({chats:[]},{status:200});let l=`%${c.trim()}%`,u=await a.select({id:t.id,title:t.title,createdAt:t.createdAt,focusMode:t.focusMode,userId:t.userId,files:t.files}).from(t).where((0,r.and)((0,r.eq)(t.userId,o),(0,r.like)(t.title,l))).orderBy(r.sql`${t.createdAt} DESC`),d=await a.selectDistinct({id:t.id,title:t.title,createdAt:t.createdAt,focusMode:t.focusMode,userId:t.userId,files:t.files}).from(n).innerJoin(t,(0,r.eq)(n.chatId,t.id)).where((0,r.and)((0,r.eq)(t.userId,o),(0,r.or)((0,r.like)(n.content,l)))).orderBy(r.sql`${t.createdAt} DESC`),f=[...u,...d],p=Array.from(new Map(f.map(e=>[e.id,e])).values()),m=p.map(e=>e.id),h=m.length?await a.select({chatId:n.chatId,count:r.sql`count(*)`}).from(n).where((0,r.and)(r.sql`${n.chatId} IN (${r.sql.join(m.map(e=>r.sql`${e}`),r.sql`, `)})`,(0,r.eq)(n.role,`user`))).groupBy(n.chatId):[],g=new Map(h.map(e=>[e.chatId,Number(e.count)])),_=p.map(e=>({...e,messageCount:g.get(e.id)||0}));return Response.json({chats:_},{status:200})}catch(e){return e instanceof Error&&e.message===`Unauthorized`?Response.json({message:`Authentication required`},{status:401}):(console.error(`Error searching chats:`,e),Response.json({message:`An error has occurred.`},{status:500}))}}}}function te(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=Number.isFinite(o)&&o>0?o:1,c=n.get(`lang`)||`en-US`,l=n.get(`safesearch`)===`true`,u=n.get(`recency`)||void 0,d=n.get(`publicInstances`)===`true`;if(!r)return Response.json({error:`Query parameter is required`},{status:400});let f=Date.now();try{let e=await(0,a.searchWeb)(r,{category:i,recency:u,safesearch:l,maxRetries:6,privateSearxng:!d&&t,proxy:``,lang:c,page:s});e&&(Array.isArray(e)?e.length>0:e.results&&e.results.length>0)||(e=await(0,a.searchWeb)(r,{category:i,recency:u,safesearch:l,maxRetries:6,privateSearxng:!1,proxy:``,lang:c,page:s}));let n=Date.now()-f;return e?Array.isArray(e)?Response.json({results:e,elapsedTime:n}):Response.json({...e,elapsedTime:n}):Response.json({results:[],suggestions:[],elapsedTime:n})}catch(e){let t=e instanceof Error?e.message:String(e);return console.error(`Search error for q="${r}" cat="${i}" page=${s}: ${t}`,e instanceof Error?e.stack:void 0),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,promptTemplate:t.promptTemplate},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})}}}var G=`llama-3.3-70b-versatile`;function K(e){return e instanceof Error?e.message:typeof e==`string`?e:String(e)}async function q(e,t){let n=[];if(t&&e.loadChatModel)try{return await e.loadChatModel(t)}catch(e){n.push(K(e))}let r=e.getEnv(`GROQ_API_KEY`);if(r)return e.createGroq({apiKey:r})(G);if(e.loadChatModel)try{return await e.loadChatModel()}catch(e){n.push(K(e))}throw Error(n.length?`AI service is not configured: ${n.join(`; `)}`:`AI service is not configured. Please contact the administrator.`)}function J(e){return{POST:async t=>{try{let{text:n,prompt:r,stream:i,chatModel:a}=await t.json();if(!n||typeof n!=`string`)return Response.json({error:`Text is required and must be a string`},{status:400});let o;try{o=await q(e,a)}catch(e){let t=K(e);return console.error(`AI rewrite has no usable model:`,t),Response.json({error:t},{status:500})}let s=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:
37
37
 
38
- ${n}`;if(i&&e.streamText){let{textStream:t}=e.streamText({model:o,prompt:s,temperature:.7}),n=new ReadableStream({async start(e){let n=new TextEncoder;try{for await(let r of t)e.enqueue(n.encode(r));e.close()}catch(t){console.error(`AI rewrite stream error:`,t),e.error(t)}}});return new Response(n,{headers:{"Content-Type":`text/plain; charset=utf-8`,"Cache-Control":`no-store`,"X-Accel-Buffering":`no`}})}let c=(await e.generateText({model:o,prompt:s,temperature:.7})).text.trim();return Response.json({rewrittenText:c})}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;
38
+ ${n}`;if(i&&e.streamText){let{textStream:t}=e.streamText({model:o,prompt:s,temperature:.7}),n=t[Symbol.asyncIterator](),r=await n.next(),i=new ReadableStream({async start(e){let t=new TextEncoder;try{for(r.done||e.enqueue(t.encode(r.value));;){let r=await n.next();if(r.done)break;e.enqueue(t.encode(r.value))}e.close()}catch(t){console.error(`AI rewrite stream error:`,t),e.error(t)}}});return new Response(i,{headers:{"Content-Type":`text/plain; charset=utf-8`,"Cache-Control":`no-store`,"X-Accel-Buffering":`no`}})}let c=(await e.generateText({model:o,prompt:s,temperature:.7})).text.trim();return Response.json({rewrittenText:c})}catch(e){let t=K(e);return console.error(`AI rewrite error:`,e),Response.json({error:`Failed to process AI request: ${t}`,details:t},{status:500})}}}}function Y(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 X(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 Z(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=X(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 Q(){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 ne=864e5,$=null;function re(e){return{GET:async t=>{try{let t=Date.now();if($&&t-$.timestamp<ne)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=W,exports.createArticleFollowupsHandler=p,exports.createArticleQAHandler=g,exports.createAutocompleteHandler=H,exports.createChatByIdHandler=ee,exports.createChatTitleHandler=y,exports.createChatsHandler=_,exports.createChatsSearchHandler=v,exports.createChatsShareHandler=te,exports.createDiscoverHandler=j,exports.createMCPServerByIdHandler=D,exports.createMCPServerToggleHandler=O,exports.createMCPServersHandler=E,exports.createMessagesHandler=S,exports.createPageTipsHandler=m,exports.createProviderByIdHandler=w,exports.createProviderModelsHandler=T,exports.createProvidersHandler=C,exports.createRewriteHandler=J,exports.createSearchHandler=A,exports.createSuggestionsHandler=U,exports.createTestModelsHandler=Q,exports.createTopicSearchesHandler=h,exports.createTranscriptHandler=Z,exports.createValidateOpenRouterHandler=re,exports.createVoiceHandler=Y,exports.describeError=x;
package/dist/api.mjs CHANGED
@@ -216,7 +216,7 @@ function w(e) {
216
216
  }
217
217
  };
218
218
  }
219
- function T(e) {
219
+ function ee(e) {
220
220
  let { chats: t, messages: r } = e.schema;
221
221
  return {
222
222
  GET: async (n, { params: a }) => {
@@ -249,7 +249,7 @@ function T(e) {
249
249
  }
250
250
  };
251
251
  }
252
- function ee(e) {
252
+ function te(e) {
253
253
  let { chats: t, messages: r } = e.schema;
254
254
  return { GET: async (a) => {
255
255
  try {
@@ -282,7 +282,7 @@ function ee(e) {
282
282
  }
283
283
  } };
284
284
  }
285
- function E(e) {
285
+ function ne(e) {
286
286
  let { chats: t } = e.schema;
287
287
  return { POST: async (n) => {
288
288
  try {
@@ -322,7 +322,7 @@ function E(e) {
322
322
  }
323
323
  //#endregion
324
324
  //#region src/api/handlers/chat-title.ts
325
- function D(e) {
325
+ function T(e) {
326
326
  let { chats: n } = e.schema;
327
327
  return { POST: async (r) => {
328
328
  try {
@@ -348,22 +348,22 @@ function D(e) {
348
348
  }
349
349
  //#endregion
350
350
  //#region src/api/handlers/messages.ts
351
- var O = [
351
+ var E = [
352
352
  "assistant",
353
353
  "user",
354
354
  "source",
355
355
  "suggestion"
356
356
  ];
357
- function k(e) {
357
+ function D(e) {
358
358
  let t = [], n = e;
359
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;
360
360
  return t.join(" <- caused by: ");
361
361
  }
362
- function A(e) {
362
+ function O(e) {
363
363
  return { POST: async (t) => {
364
364
  try {
365
365
  let n = e.getDB(), r = await e.requireUserId(), { chatId: i, messageId: a, role: o, suggestions: s, content: c, sources: l } = await t.json();
366
- return !i || !a || !o ? Response.json({ message: "Missing required fields" }, { status: 400 }) : O.includes(o) ? (await n.insert(e.messagesSchema).values({
366
+ return !i || !a || !o ? Response.json({ message: "Missing required fields" }, { status: 400 }) : E.includes(o) ? (await n.insert(e.messagesSchema).values({
367
367
  chatId: i,
368
368
  userId: r,
369
369
  messageId: a,
@@ -374,13 +374,13 @@ function A(e) {
374
374
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
375
375
  }), Response.json({ message: "Message saved successfully" }, { status: 200 })) : Response.json({ message: `Invalid role: ${o}` }, { status: 400 });
376
376
  } catch (e) {
377
- return console.error("Error saving message:", k(e)), Response.json({ message: "Failed to save message" }, { status: 500 });
377
+ return console.error("Error saving message:", D(e)), Response.json({ message: "Failed to save message" }, { status: 500 });
378
378
  }
379
379
  } };
380
380
  }
381
381
  //#endregion
382
382
  //#region src/api/handlers/providers.ts
383
- function j(e) {
383
+ function k(e) {
384
384
  return {
385
385
  GET: async (n) => {
386
386
  try {
@@ -410,7 +410,7 @@ function j(e) {
410
410
  }
411
411
  };
412
412
  }
413
- function M() {
413
+ function A() {
414
414
  return {
415
415
  DELETE: async (e, { params: n }) => {
416
416
  try {
@@ -432,7 +432,7 @@ function M() {
432
432
  }
433
433
  };
434
434
  }
435
- function N() {
435
+ function j() {
436
436
  return {
437
437
  POST: async (e, { params: n }) => {
438
438
  try {
@@ -454,7 +454,7 @@ function N() {
454
454
  }
455
455
  //#endregion
456
456
  //#region src/api/handlers/mcpservers.ts
457
- function P(e) {
457
+ function M(e) {
458
458
  return {
459
459
  GET: async (t) => {
460
460
  try {
@@ -476,7 +476,7 @@ function P(e) {
476
476
  }
477
477
  };
478
478
  }
479
- function F(e) {
479
+ function N(e) {
480
480
  return {
481
481
  DELETE: async (t, { params: n }) => {
482
482
  try {
@@ -498,7 +498,7 @@ function F(e) {
498
498
  }
499
499
  };
500
500
  }
501
- function I(e) {
501
+ function P(e) {
502
502
  return { POST: async (t, { params: n }) => {
503
503
  try {
504
504
  let { enabled: r } = await t.json(), { id: i } = await n;
@@ -512,7 +512,7 @@ function I(e) {
512
512
  }
513
513
  //#endregion
514
514
  //#region src/api/handlers/search.ts
515
- var L = {
515
+ var F = {
516
516
  tech: {
517
517
  query: [
518
518
  "technology news",
@@ -578,7 +578,7 @@ var L = {
578
578
  ]
579
579
  }
580
580
  };
581
- function R(e = {}) {
581
+ function I(e = {}) {
582
582
  let t = e.searxngDomain ?? "https://search.qwksearch.com";
583
583
  return { GET: async (e) => {
584
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 = Number.isFinite(a) && a > 0 ? a : 1, s = n.get("lang") || "en-US", c = n.get("safesearch") === "true", l = n.get("recency") || void 0, u = n.get("publicInstances") === "true";
@@ -626,10 +626,10 @@ function R(e = {}) {
626
626
  }
627
627
  } };
628
628
  }
629
- function z() {
629
+ function L() {
630
630
  return { GET: async (e) => {
631
631
  try {
632
- let t = new URL(e.url).searchParams, n = t.get("mode") || "normal", r = L[t.get("topic") || "tech"], i = [];
632
+ let t = new URL(e.url).searchParams, n = t.get("mode") || "normal", r = F[t.get("topic") || "tech"], i = [];
633
633
  if (n === "normal") {
634
634
  let e = /* @__PURE__ */ new Set();
635
635
  i = (await Promise.all(r.links.flatMap((e) => r.query.map(async (t) => (await d(`site:${e} ${t}`, {
@@ -653,17 +653,17 @@ function z() {
653
653
  }
654
654
  //#endregion
655
655
  //#region src/api/handlers/autocomplete.ts
656
- var B = [
656
+ var R = [
657
657
  "google",
658
658
  "duckduckgo",
659
659
  "wikipedia"
660
- ], V = 3, te = 3, H = Object.entries(g).map(([e, t]) => ({
660
+ ], z = 3, B = 3, re = Object.entries(g).map(([e, t]) => ({
661
661
  domain: e,
662
662
  name: typeof t?.[0] == "string" ? t[0] : "",
663
663
  rank: typeof t?.[1] == "number" ? t[1] : 2 ** 53 - 1
664
- })), U = null;
665
- function W() {
666
- return U ||= new m(H, {
664
+ })), V = null;
665
+ function H() {
666
+ return V ||= new m(re, {
667
667
  keys: [{
668
668
  name: "name",
669
669
  weight: .6
@@ -675,9 +675,9 @@ function W() {
675
675
  ignoreLocation: !0,
676
676
  includeScore: !0,
677
677
  minMatchCharLength: 3
678
- }), U;
678
+ }), V;
679
679
  }
680
- function G(e, t, n) {
680
+ function U(e, t, n) {
681
681
  return {
682
682
  domain: e,
683
683
  name: t,
@@ -685,20 +685,20 @@ function G(e, t, n) {
685
685
  rank: n
686
686
  };
687
687
  }
688
- function K(e) {
688
+ function W(e) {
689
689
  let t = h(e);
690
690
  return t.domain && t.isIcann ? t.hostname : null;
691
691
  }
692
- function q(e) {
692
+ function G(e) {
693
693
  let t = e.split(/\s+/).filter(Boolean), n = t[t.length - 1] || "";
694
694
  if (n.length < 3) return [];
695
- 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);
696
- return i && !r.some((e) => e.domain === i) && r.unshift(G(i, "", 2 ** 53 - 1)), r.slice(0, te);
695
+ let r = H().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 }) => U(e.domain, e.name, e.rank)), i = W(n);
696
+ return i && !r.some((e) => e.domain === i) && r.unshift(U(i, "", 2 ** 53 - 1)), r.slice(0, B);
697
697
  }
698
- async function J(e, t, n) {
698
+ async function K(e, t, n) {
699
699
  let r = await p(e, t, n);
700
700
  if (r.length > 0) return r;
701
- let i = t.split(/\s+/).filter(Boolean), a = Math.min(V, i.length - 1);
701
+ let i = t.split(/\s+/).filter(Boolean), a = Math.min(z, i.length - 1);
702
702
  for (let r = a; r >= 1; r--) {
703
703
  let a = i.slice(-r).join(" "), o = i.slice(0, -r).join(" "), s = await p(e, a, n);
704
704
  if (s.length > 0) {
@@ -712,16 +712,16 @@ async function J(e, t, n) {
712
712
  }
713
713
  return [];
714
714
  }
715
- function Y() {
715
+ function q() {
716
716
  return { GET: async (e) => {
717
717
  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);
718
718
  if (!n) return Response.json({
719
719
  suggestions: [],
720
720
  domains: []
721
721
  });
722
- let o = i ? i.split(",").map((e) => e.trim()).filter(Boolean) : B;
722
+ let o = i ? i.split(",").map((e) => e.trim()).filter(Boolean) : R;
723
723
  try {
724
- let e = await J(o, n, r), t = q(n);
724
+ let e = await K(o, n, r), t = G(n);
725
725
  return Response.json({
726
726
  suggestions: e.slice(0, a),
727
727
  domains: t
@@ -736,7 +736,7 @@ function Y() {
736
736
  }
737
737
  //#endregion
738
738
  //#region src/api/handlers/suggestions.ts
739
- function X() {
739
+ function J() {
740
740
  return { POST: async (e) => {
741
741
  let n = await e.json(), r = n.chatHistory.filter((e) => e.role === "user" || e.role === "assistant").map((e) => ({
742
742
  role: e.role,
@@ -751,7 +751,7 @@ function X() {
751
751
  }
752
752
  //#endregion
753
753
  //#region src/api/handlers/agents.ts
754
- function Z(e) {
754
+ function Y(e) {
755
755
  return { POST: async (t) => {
756
756
  let n;
757
757
  try {
@@ -766,14 +766,39 @@ function Z(e) {
766
766
  }
767
767
  //#endregion
768
768
  //#region src/api/handlers/rewrite.ts
769
- function Q(e) {
769
+ var X = "llama-3.3-70b-versatile";
770
+ function Z(e) {
771
+ return e instanceof Error ? e.message : typeof e == "string" ? e : String(e);
772
+ }
773
+ async function ie(e, t) {
774
+ let n = [];
775
+ if (t && e.loadChatModel) try {
776
+ return await e.loadChatModel(t);
777
+ } catch (e) {
778
+ n.push(Z(e));
779
+ }
780
+ let r = e.getEnv("GROQ_API_KEY");
781
+ if (r) return e.createGroq({ apiKey: r })(X);
782
+ if (e.loadChatModel) try {
783
+ return await e.loadChatModel();
784
+ } catch (e) {
785
+ n.push(Z(e));
786
+ }
787
+ throw Error(n.length ? `AI service is not configured: ${n.join("; ")}` : "AI service is not configured. Please contact the administrator.");
788
+ }
789
+ function ae(e) {
770
790
  return { POST: async (t) => {
771
791
  try {
772
- let { text: n, prompt: r, stream: i } = await t.json();
792
+ let { text: n, prompt: r, stream: i, chatModel: a } = await t.json();
773
793
  if (!n || typeof n != "string") return Response.json({ error: "Text is required and must be a string" }, { status: 400 });
774
- let a = e.getEnv("GROQ_API_KEY");
775
- if (!a) return console.error("GROQ_API_KEY is not configured"), Response.json({ error: "AI service is not configured. Please contact the administrator." }, { status: 500 });
776
- let o = e.createGroq({ apiKey: a })("llama-3.3-70b-versatile"), s = 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:
794
+ let o;
795
+ try {
796
+ o = await ie(e, a);
797
+ } catch (e) {
798
+ let t = Z(e);
799
+ return console.error("AI rewrite has no usable model:", t), Response.json({ error: t }, { status: 500 });
800
+ }
801
+ let s = 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:
777
802
 
778
803
  ${n}`;
779
804
  if (i && e.streamText) {
@@ -781,16 +806,20 @@ ${n}`;
781
806
  model: o,
782
807
  prompt: s,
783
808
  temperature: .7
784
- }), n = new ReadableStream({ async start(e) {
785
- let n = new TextEncoder();
809
+ }), n = t[Symbol.asyncIterator](), r = await n.next(), i = new ReadableStream({ async start(e) {
810
+ let t = new TextEncoder();
786
811
  try {
787
- for await (let r of t) e.enqueue(n.encode(r));
812
+ for (r.done || e.enqueue(t.encode(r.value));;) {
813
+ let r = await n.next();
814
+ if (r.done) break;
815
+ e.enqueue(t.encode(r.value));
816
+ }
788
817
  e.close();
789
818
  } catch (t) {
790
819
  console.error("AI rewrite stream error:", t), e.error(t);
791
820
  }
792
821
  } });
793
- return new Response(n, { headers: {
822
+ return new Response(i, { headers: {
794
823
  "Content-Type": "text/plain; charset=utf-8",
795
824
  "Cache-Control": "no-store",
796
825
  "X-Accel-Buffering": "no"
@@ -803,13 +832,17 @@ ${n}`;
803
832
  })).text.trim();
804
833
  return Response.json({ rewrittenText: c });
805
834
  } catch (e) {
806
- return console.error("AI rewrite error:", e), Response.json({ error: "Failed to process AI request. Please try again." }, { status: 500 });
835
+ let t = Z(e);
836
+ return console.error("AI rewrite error:", e), Response.json({
837
+ error: `Failed to process AI request: ${t}`,
838
+ details: t
839
+ }, { status: 500 });
807
840
  }
808
841
  } };
809
842
  }
810
843
  //#endregion
811
844
  //#region src/api/handlers/voice.ts
812
- function ne(e) {
845
+ function oe(e) {
813
846
  return { POST: async (t) => {
814
847
  let n, r, i;
815
848
  try {
@@ -844,15 +877,15 @@ function ne(e) {
844
877
  }
845
878
  //#endregion
846
879
  //#region src/api/handlers/transcript.ts
847
- function re(e) {
880
+ function se(e) {
848
881
  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";
849
882
  }
850
- function ie(e) {
883
+ function Q(e) {
851
884
  return { POST: async (t) => {
852
885
  try {
853
886
  let n = await t.formData(), r = n.get("file");
854
887
  if (!r || !(r instanceof File)) return Response.json({ error: "file is required" }, { status: 400 });
855
- let i = re(n.get("model")), a;
888
+ let i = se(n.get("model")), a;
856
889
  try {
857
890
  a = e.getCloudflareContext().env?.AI;
858
891
  } catch {}
@@ -869,7 +902,7 @@ function ie(e) {
869
902
  }
870
903
  //#endregion
871
904
  //#region src/api/handlers/test-models.ts
872
- function ae() {
905
+ function ce() {
873
906
  return { POST: async (e) => {
874
907
  try {
875
908
  let { providerType: t, apiKey: n, onlyFree: r = !0 } = await e.json();
@@ -890,13 +923,13 @@ function ae() {
890
923
  }
891
924
  //#endregion
892
925
  //#region src/api/handlers/validate-openrouter.ts
893
- var oe = 864e5, $ = null;
894
- function se(e) {
926
+ var le = 864e5, $ = null;
927
+ function ue(e) {
895
928
  return {
896
929
  GET: async (t) => {
897
930
  try {
898
931
  let t = Date.now();
899
- if ($ && t - $.timestamp < oe) return Response.json({
932
+ if ($ && t - $.timestamp < le) return Response.json({
900
933
  ...$.result,
901
934
  cached: !0,
902
935
  cacheAge: t - $.timestamp
@@ -930,4 +963,4 @@ function se(e) {
930
963
  };
931
964
  }
932
965
  //#endregion
933
- 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 };
966
+ export { Y as createAgentsHandler, b as createArticleFollowupsHandler, C as createArticleQAHandler, q as createAutocompleteHandler, ee as createChatByIdHandler, T as createChatTitleHandler, w as createChatsHandler, te as createChatsSearchHandler, ne as createChatsShareHandler, L as createDiscoverHandler, N as createMCPServerByIdHandler, P as createMCPServerToggleHandler, M as createMCPServersHandler, O as createMessagesHandler, x as createPageTipsHandler, A as createProviderByIdHandler, j as createProviderModelsHandler, k as createProvidersHandler, ae as createRewriteHandler, I as createSearchHandler, J as createSuggestionsHandler, ce as createTestModelsHandler, S as createTopicSearchesHandler, Q as createTranscriptHandler, ue as createValidateOpenRouterHandler, oe as createVoiceHandler, D as describeError };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "research-agent-ui",
3
3
  "description": "The QwkSearch app UI: conversation window, article reader, search config, file uploads, chat history, and the app shell — exported both with and without the REASON editor and its sidebar",
4
- "version": "0.1.251",
4
+ "version": "0.1.253",
5
5
  "author": "vtempest",
6
6
  "repository": {
7
7
  "type": "git",
@@ -90,13 +90,13 @@
90
90
  "@radix-ui/react-tooltip": "^1.2.16",
91
91
  "@ricky0123/vad-web": "^0.0.30",
92
92
  "ai": "^7.0.94",
93
- "chat-agent-toolkit": "^1.2.384",
93
+ "chat-agent-toolkit": "^1.2.386",
94
94
  "class-variance-authority": "^0.7.1",
95
95
  "clsx": "^2.1.1",
96
- "domain-rank": "^0.1.373",
96
+ "domain-rank": "^0.1.375",
97
97
  "dompurify": "^3.4.15",
98
98
  "drizzle-orm": "^0.45.2",
99
- "extract-webpage": "^1.2.378",
99
+ "extract-webpage": "^1.2.380",
100
100
  "framer-motion": "^13.2.0",
101
101
  "fuse.js": "^7.5.0",
102
102
  "grab-url": "^1.6.22",
@@ -106,21 +106,21 @@
106
106
  "markdown-to-jsx": "^9.10.2",
107
107
  "motion": "^13.2.0",
108
108
  "quantum-sphere-loading-icon": "^1.0.3",
109
- "qwksearch-api-client": "^1.0.56",
109
+ "qwksearch-api-client": "^1.0.58",
110
110
  "react-icons": "^5.7.0",
111
111
  "react-native-app-buttons": "^0.1.4",
112
112
  "react-textarea-autosize": "^8.5.9",
113
- "search-web-api": "^1.0.236",
114
- "shadcn-app-dock": "^0.1.234",
113
+ "search-web-api": "^1.0.238",
114
+ "shadcn-app-dock": "^0.1.236",
115
115
  "shadcn-theme-menu": "^1.1.47",
116
116
  "sonner": "^2.0.8",
117
117
  "streamdown": "^2.6.0",
118
118
  "tailwind-merge": "^3.6.0",
119
119
  "tldts": "^7.4.12",
120
- "trending-news-api": "^0.1.112",
120
+ "trending-news-api": "^0.1.114",
121
121
  "turndown": "^7.2.4",
122
122
  "use-voice-control": "^0.1.95",
123
- "use-weather-forecast": "^0.1.198"
123
+ "use-weather-forecast": "^0.1.200"
124
124
  },
125
125
  "devDependencies": {
126
126
  "@cloudflare/workers-types": "^5.20260908.1",
@@ -139,8 +139,8 @@
139
139
  "next": "^16.3.4",
140
140
  "react": "^19.2.8",
141
141
  "react-dom": "^19.2.8",
142
- "react-reason-editor": "^1.0.186",
143
- "react-reason-editor-sidebar": "^0.1.103",
142
+ "react-reason-editor": "^1.0.188",
143
+ "react-reason-editor-sidebar": "^0.1.105",
144
144
  "storybook": "^10.6.0",
145
145
  "tailwindcss": "^4.3.3",
146
146
  "typescript": "^7.0.2",