research-agent-ui 0.1.252 → 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.
- package/dist/api/handlers/rewrite.d.ts +12 -1
- package/dist/api/types.d.ts +15 -0
- package/dist/api.cjs +2 -2
- package/dist/api.mjs +89 -56
- package/package.json +11 -11
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview Handler that rewrites user-supplied text for clarity/grammar/style
|
|
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): {
|
package/dist/api/types.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
351
|
+
var E = [
|
|
352
352
|
"assistant",
|
|
353
353
|
"user",
|
|
354
354
|
"source",
|
|
355
355
|
"suggestion"
|
|
356
356
|
];
|
|
357
|
-
function
|
|
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
|
|
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 }) :
|
|
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:",
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
656
|
+
var R = [
|
|
657
657
|
"google",
|
|
658
658
|
"duckduckgo",
|
|
659
659
|
"wikipedia"
|
|
660
|
-
],
|
|
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
|
-
})),
|
|
665
|
-
function
|
|
666
|
-
return
|
|
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
|
-
}),
|
|
678
|
+
}), V;
|
|
679
679
|
}
|
|
680
|
-
function
|
|
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
|
|
688
|
+
function W(e) {
|
|
689
689
|
let t = h(e);
|
|
690
690
|
return t.domain && t.isIcann ? t.hostname : null;
|
|
691
691
|
}
|
|
692
|
-
function
|
|
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 =
|
|
696
|
-
return i && !r.some((e) => e.domain === i) && r.unshift(
|
|
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
|
|
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(
|
|
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
|
|
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) :
|
|
722
|
+
let o = i ? i.split(",").map((e) => e.trim()).filter(Boolean) : R;
|
|
723
723
|
try {
|
|
724
|
-
let e = await
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
775
|
-
|
|
776
|
-
|
|
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
|
|
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
|
|
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(
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
894
|
-
function
|
|
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 <
|
|
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 {
|
|
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.
|
|
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.
|
|
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.
|
|
96
|
+
"domain-rank": "^0.1.375",
|
|
97
97
|
"dompurify": "^3.4.15",
|
|
98
98
|
"drizzle-orm": "^0.45.2",
|
|
99
|
-
"extract-webpage": "^1.2.
|
|
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.
|
|
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.
|
|
114
|
-
"shadcn-app-dock": "^0.1.
|
|
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.
|
|
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.
|
|
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.
|
|
143
|
-
"react-reason-editor-sidebar": "^0.1.
|
|
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",
|