research-agent-ui 0.1.293 → 0.1.294

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.
Files changed (54) hide show
  1. package/README.md +42 -1
  2. package/dist/ArticleExtractPanel-25tRTnpl.cjs +2 -0
  3. package/dist/ArticleExtractPanel-D_y16YHG.js +389 -0
  4. package/dist/ChatConversationThread-BIJ8aNug.js +1428 -0
  5. package/dist/ChatConversationThread-BoNH0wvs.cjs +17 -0
  6. package/dist/DownloadsDialog-CCPj0hA8.cjs +1 -0
  7. package/dist/{DownloadsDialog-bTEDe2DI.js → DownloadsDialog-DvS23Dh-.js} +8 -9
  8. package/dist/api/handlers/autocomplete.d.ts +6 -9
  9. package/dist/api/handlers/openai-transcription.d.ts +53 -0
  10. package/dist/api/handlers/transcript.d.ts +33 -0
  11. package/dist/api/index.d.ts +1 -0
  12. package/dist/api.cjs +10 -10
  13. package/dist/api.mjs +161 -208
  14. package/dist/app/index.d.ts +1 -1
  15. package/dist/app/useChunkErrorReload.d.ts +13 -2
  16. package/dist/components/ArticleReader/ArticleReaderMount.d.ts +5 -0
  17. package/dist/components/ArticleReader/ExtractPanelContext.d.ts +17 -1
  18. package/dist/components/ChatConversation/MessageBubble/AssistantMessageActions.d.ts +2 -1
  19. package/dist/components/ChatConversation/background-art.d.ts +3 -1
  20. package/dist/components/ChatConversation/background-cache.d.ts +41 -0
  21. package/dist/components/Footer.d.ts +5 -4
  22. package/dist/components/Footer.stories.d.ts +3 -3
  23. package/dist/config.cjs +1 -1
  24. package/dist/config.d.ts +9 -0
  25. package/dist/config.mjs +4 -3
  26. package/dist/dialog-7GDz0sWx.cjs +1 -0
  27. package/dist/dialog-Cufn2u50.js +80 -0
  28. package/dist/hooks/voice/useKokoroTTS.d.ts +2 -0
  29. package/dist/hooks/voice/useTextToVoice.d.ts +2 -1
  30. package/dist/index.cjs +1 -1
  31. package/dist/index.d.ts +5 -1
  32. package/dist/index.mjs +4 -2
  33. package/dist/lib/file-sources.d.ts +8 -0
  34. package/dist/lib/google-drive-source.d.ts +100 -0
  35. package/dist/lib/kokoro.d.ts +14 -2
  36. package/dist/lib/qwksearch-connect.d.ts +79 -0
  37. package/dist/settings/index.d.ts +15 -0
  38. package/dist/src-GPr1ceY8.js +6165 -0
  39. package/dist/src-ebmQu_if.cjs +34 -0
  40. package/dist/tooltip-Bl3IdX-I.js +179 -0
  41. package/dist/tooltip-DmUO6ZUz.cjs +1 -0
  42. package/dist/types/fileSource.d.ts +9 -0
  43. package/dist/workspace/QwkSearchWorkspaceApp.d.ts +9 -2
  44. package/dist/workspace/ResearchWorkspaceView.d.ts +18 -4
  45. package/dist/workspace.cjs +1 -1
  46. package/dist/workspace.d.ts +1 -1
  47. package/dist/workspace.mjs +234 -91
  48. package/package.json +54 -51
  49. package/src/app/useChunkErrorReload.ts +92 -0
  50. package/src/settings/index.ts +23 -0
  51. package/src/settings/search.json +19 -1
  52. package/dist/DownloadsDialog-Ca6aRRcP.cjs +0 -1
  53. package/dist/src-HL9JjPc-.js +0 -8218
  54. package/dist/src-r4BsCIB4.cjs +0 -51
package/dist/api.mjs CHANGED
@@ -3,15 +3,12 @@ import t from "chat-agent-toolkit/models/registry";
3
3
  import { and as n, count as r, eq as i, inArray as a, like as o, max as s, or as c, sql as l } from "drizzle-orm";
4
4
  import u from "chat-agent-toolkit/tools/search/titleGeneratorAgent";
5
5
  import { searchSearxng as d, searchWeb as f } from "search-web-api/search/public-searxng";
6
- import { searchAutocompleteMulti as p } from "extract-webpage/suggest-next-words/autocomplete-search-engines";
7
- import m from "fuse.js";
8
- import { parse as h } from "tldts";
9
- import g from "domain-rank/data/domain-rank-merged.json";
10
- import _ from "chat-agent-toolkit/tools/search/suggestionGeneratorAgent";
11
- import { testProviderModels as v } from "chat-agent-toolkit/config/model-tester";
12
- import { LANGUAGE_MODELS as y } from "chat-agent-toolkit/config/language-models-database";
13
- //#region src/api/handlers/article-followups.ts
14
- function b(n) {
6
+ import { createAutocompleteHandler as p } from "search-autocomplete/server";
7
+ import m from "chat-agent-toolkit/tools/search/suggestionGeneratorAgent";
8
+ import { testProviderModels as h } from "chat-agent-toolkit/config/model-tester";
9
+ import { LANGUAGE_MODELS as g } from "chat-agent-toolkit/config/language-models-database";
10
+ // src/api/handlers/article-followups.ts
11
+ function _(n) {
15
12
  return async (n) => {
16
13
  try {
17
14
  let { article: r, chatHistory: i = [], maxQuestions: a = 5, chatModel: o } = await n.json();
@@ -31,13 +28,8 @@ ${l}
31
28
 
32
29
  Generate ${a} follow-up questions that would help readers dive deeper into this article.`, { text: f } = await e({
33
30
  model: c,
34
- messages: [{
35
- role: "system",
36
- content: u
37
- }, {
38
- role: "user",
39
- content: d
40
- }]
31
+ instructions: u,
32
+ prompt: d
41
33
  }), p = f.split("\n").map((e) => e.trim()).filter((e) => e.length > 0).map((e) => e.replace(/^[\d\-\*\.\)]+\s*/, "").trim()).filter((e) => e.length > 10).slice(0, a);
42
34
  return Response.json({
43
35
  extract: p,
@@ -51,9 +43,8 @@ Generate ${a} follow-up questions that would help readers dive deeper into this
51
43
  }
52
44
  };
53
45
  }
54
- //#endregion
55
- //#region src/api/handlers/page-tips.ts
56
- function x(n) {
46
+ // src/api/handlers/page-tips.ts
47
+ function v(n) {
57
48
  return async (n) => {
58
49
  try {
59
50
  let { title: r = "", content: i, maxTips: a = 4, chatModel: o } = await n.json();
@@ -73,13 +64,8 @@ ${i.slice(0, 15e3)}
73
64
 
74
65
  Generate ${a} short tips about this page.`, { text: d } = await e({
75
66
  model: c,
76
- messages: [{
77
- role: "system",
78
- content: l
79
- }, {
80
- role: "user",
81
- content: u
82
- }]
67
+ instructions: l,
68
+ prompt: u
83
69
  }), f = d.split("\n").map((e) => e.trim()).filter((e) => e.length > 0).map((e) => e.replace(/^[\d\-\*\.\)]+\s*/, "").trim()).filter((e) => e.length > 10).slice(0, a);
84
70
  return Response.json({
85
71
  tips: f,
@@ -93,9 +79,8 @@ Generate ${a} short tips about this page.`, { text: d } = await e({
93
79
  }
94
80
  };
95
81
  }
96
- //#endregion
97
- //#region src/api/handlers/topic-searches.ts
98
- function S(n) {
82
+ // src/api/handlers/topic-searches.ts
83
+ function y(n) {
99
84
  return async (n) => {
100
85
  try {
101
86
  let { title: r = "", content: i, maxTopics: a = 4, chatModel: o } = await n.json();
@@ -115,13 +100,8 @@ ${i.slice(0, 15e3)}
115
100
 
116
101
  Generate ${a} short related search queries for this page.`, { text: d } = await e({
117
102
  model: c,
118
- messages: [{
119
- role: "system",
120
- content: l
121
- }, {
122
- role: "user",
123
- content: u
124
- }]
103
+ instructions: l,
104
+ prompt: u
125
105
  }), f = d.split("\n").map((e) => e.trim()).filter((e) => e.length > 0).map((e) => e.replace(/^[\d\-\*\.\)]+\s*/, "").trim()).filter((e) => e.length > 2).slice(0, a);
126
106
  return Response.json({
127
107
  topics: f,
@@ -135,9 +115,8 @@ Generate ${a} short related search queries for this page.`, { text: d } = await
135
115
  }
136
116
  };
137
117
  }
138
- //#endregion
139
- //#region src/api/handlers/article-qa.ts
140
- function C(n) {
118
+ // src/api/handlers/article-qa.ts
119
+ function b(n) {
141
120
  return async (n) => {
142
121
  try {
143
122
  let { article: r, question: i, chatHistory: a = [], chatModel: o } = await n.json();
@@ -157,13 +136,8 @@ User question: ${i}
157
136
 
158
137
  Please provide a helpful answer based on the article content above.`, { text: d } = await e({
159
138
  model: c,
160
- messages: [{
161
- role: "system",
162
- content: "You are a helpful AI assistant that answers questions about articles.\nProvide clear, concise, and accurate answers based on the article content provided.\nIf the answer is not in the article, say so."
163
- }, {
164
- role: "user",
165
- content: u
166
- }]
139
+ instructions: "You are a helpful AI assistant that answers questions about articles.\nProvide clear, concise, and accurate answers based on the article content provided.\nIf the answer is not in the article, say so.",
140
+ prompt: u
167
141
  });
168
142
  return Response.json({
169
143
  content: d,
@@ -177,9 +151,8 @@ Please provide a helpful answer based on the article content above.`, { text: d
177
151
  }
178
152
  };
179
153
  }
180
- //#endregion
181
- //#region src/api/handlers/chats.ts
182
- function w(e) {
154
+ // src/api/handlers/chats.ts
155
+ function x(e) {
183
156
  let { chats: t, messages: o } = e.schema;
184
157
  return {
185
158
  GET: async (a) => {
@@ -249,7 +222,7 @@ function ee(e) {
249
222
  }
250
223
  };
251
224
  }
252
- function te(e) {
225
+ function S(e) {
253
226
  let { chats: t, messages: r } = e.schema;
254
227
  return { GET: async (a) => {
255
228
  try {
@@ -282,7 +255,7 @@ function te(e) {
282
255
  }
283
256
  } };
284
257
  }
285
- function ne(e) {
258
+ function C(e) {
286
259
  let { chats: t } = e.schema;
287
260
  return { POST: async (n) => {
288
261
  try {
@@ -320,9 +293,8 @@ function ne(e) {
320
293
  }
321
294
  } };
322
295
  }
323
- //#endregion
324
- //#region src/api/handlers/chat-title.ts
325
- function T(e) {
296
+ // src/api/handlers/chat-title.ts
297
+ function w(e) {
326
298
  let { chats: n } = e.schema;
327
299
  return { POST: async (r) => {
328
300
  try {
@@ -346,24 +318,23 @@ function T(e) {
346
318
  }
347
319
  } };
348
320
  }
349
- //#endregion
350
- //#region src/api/handlers/messages.ts
351
- var E = [
321
+ // src/api/handlers/messages.ts
322
+ var T = [
352
323
  "assistant",
353
324
  "user",
354
325
  "source",
355
326
  "suggestion"
356
327
  ];
357
- function D(e) {
328
+ function E(e) {
358
329
  let t = [], n = e;
359
330
  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
331
  return t.join(" <- caused by: ");
361
332
  }
362
- function O(e) {
333
+ function D(e) {
363
334
  return { POST: async (t) => {
364
335
  try {
365
336
  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 }) : E.includes(o) ? (await n.insert(e.messagesSchema).values({
337
+ return !i || !a || !o ? Response.json({ message: "Missing required fields" }, { status: 400 }) : T.includes(o) ? (await n.insert(e.messagesSchema).values({
367
338
  chatId: i,
368
339
  userId: r,
369
340
  messageId: a,
@@ -374,13 +345,12 @@ function O(e) {
374
345
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
375
346
  }), Response.json({ message: "Message saved successfully" }, { status: 200 })) : Response.json({ message: `Invalid role: ${o}` }, { status: 400 });
376
347
  } catch (e) {
377
- return console.error("Error saving message:", D(e)), Response.json({ message: "Failed to save message" }, { status: 500 });
348
+ return console.error("Error saving message:", E(e)), Response.json({ message: "Failed to save message" }, { status: 500 });
378
349
  }
379
350
  } };
380
351
  }
381
- //#endregion
382
- //#region src/api/handlers/providers.ts
383
- function k(e) {
352
+ // src/api/handlers/providers.ts
353
+ function O(e) {
384
354
  return {
385
355
  GET: async (n) => {
386
356
  try {
@@ -410,7 +380,7 @@ function k(e) {
410
380
  }
411
381
  };
412
382
  }
413
- function A() {
383
+ function k() {
414
384
  return {
415
385
  DELETE: async (e, { params: n }) => {
416
386
  try {
@@ -432,7 +402,7 @@ function A() {
432
402
  }
433
403
  };
434
404
  }
435
- function j() {
405
+ function A() {
436
406
  return {
437
407
  POST: async (e, { params: n }) => {
438
408
  try {
@@ -452,9 +422,8 @@ function j() {
452
422
  }
453
423
  };
454
424
  }
455
- //#endregion
456
- //#region src/api/handlers/mcpservers.ts
457
- function M(e) {
425
+ // src/api/handlers/mcpservers.ts
426
+ function j(e) {
458
427
  return {
459
428
  GET: async (t) => {
460
429
  try {
@@ -476,7 +445,7 @@ function M(e) {
476
445
  }
477
446
  };
478
447
  }
479
- function N(e) {
448
+ function M(e) {
480
449
  return {
481
450
  DELETE: async (t, { params: n }) => {
482
451
  try {
@@ -498,7 +467,7 @@ function N(e) {
498
467
  }
499
468
  };
500
469
  }
501
- function P(e) {
470
+ function N(e) {
502
471
  return { POST: async (t, { params: n }) => {
503
472
  try {
504
473
  let { enabled: r } = await t.json(), { id: i } = await n;
@@ -510,9 +479,8 @@ function P(e) {
510
479
  }
511
480
  } };
512
481
  }
513
- //#endregion
514
- //#region src/api/handlers/search.ts
515
- var F = {
482
+ // src/api/handlers/search.ts
483
+ var te = {
516
484
  tech: {
517
485
  query: [
518
486
  "technology news",
@@ -578,7 +546,7 @@ var F = {
578
546
  ]
579
547
  }
580
548
  };
581
- function I(e = {}) {
549
+ function P(e = {}) {
582
550
  let t = e.searxngDomain ?? "https://search.qwksearch.com";
583
551
  return { GET: async (e) => {
584
552
  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 +594,10 @@ function I(e = {}) {
626
594
  }
627
595
  } };
628
596
  }
629
- function L() {
597
+ function F() {
630
598
  return { GET: async (e) => {
631
599
  try {
632
- let t = new URL(e.url).searchParams, n = t.get("mode") || "normal", r = F[t.get("topic") || "tech"], i = [];
600
+ let t = new URL(e.url).searchParams, n = t.get("mode") || "normal", r = te[t.get("topic") || "tech"], i = [];
633
601
  if (n === "normal") {
634
602
  let e = /* @__PURE__ */ new Set();
635
603
  i = (await Promise.all(r.links.flatMap((e) => r.query.map(async (t) => (await d(`site:${e} ${t}`, {
@@ -651,97 +619,13 @@ function L() {
651
619
  }
652
620
  } };
653
621
  }
654
- //#endregion
655
- //#region src/api/handlers/autocomplete.ts
656
- var R = [
657
- "google",
658
- "duckduckgo",
659
- "wikipedia"
660
- ], z = 3, B = 3, re = Object.entries(g).map(([e, t]) => ({
661
- domain: e,
662
- name: typeof t?.[0] == "string" ? t[0] : "",
663
- rank: typeof t?.[1] == "number" ? t[1] : 2 ** 53 - 1
664
- })), V = null;
665
- function H() {
666
- return V ||= new m(re, {
667
- keys: [{
668
- name: "name",
669
- weight: .6
670
- }, {
671
- name: "domain",
672
- weight: .4
673
- }],
674
- threshold: .1,
675
- ignoreLocation: !0,
676
- includeScore: !0,
677
- minMatchCharLength: 3
678
- }), V;
679
- }
680
- function U(e, t, n) {
681
- return {
682
- domain: e,
683
- name: t,
684
- favicon: `https://www.google.com/s2/favicons?domain=${encodeURIComponent(e)}&sz=64`,
685
- rank: n
686
- };
687
- }
688
- function W(e) {
689
- let t = h(e);
690
- return t.domain && t.isIcann ? t.hostname : null;
691
- }
692
- function G(e) {
693
- let t = e.split(/\s+/).filter(Boolean), n = t[t.length - 1] || "";
694
- if (n.length < 3) return [];
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
- }
698
- async function K(e, t, n) {
699
- let r = await p(e, t, n);
700
- if (r.length > 0) return r;
701
- let i = t.split(/\s+/).filter(Boolean), a = Math.min(z, i.length - 1);
702
- for (let r = a; r >= 1; r--) {
703
- let a = i.slice(-r).join(" "), o = i.slice(0, -r).join(" "), s = await p(e, a, n);
704
- if (s.length > 0) {
705
- let e = /* @__PURE__ */ new Set();
706
- for (let n of s) {
707
- let r = o ? `${o} ${n}` : n;
708
- r.toLowerCase() !== t.toLowerCase() && e.add(r);
709
- }
710
- if (e.size > 0) return Array.from(e);
711
- }
712
- }
713
- return [];
714
- }
715
- function q() {
716
- return { GET: async (e) => {
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
- if (!n) return Response.json({
719
- suggestions: [],
720
- domains: []
721
- });
722
- let o = i ? i.split(",").map((e) => e.trim()).filter(Boolean) : R;
723
- try {
724
- let e = await K(o, n, r), t = G(n);
725
- return Response.json({
726
- suggestions: e.slice(0, a),
727
- domains: t
728
- });
729
- } catch (e) {
730
- return console.error("Autocomplete error:", e), Response.json({
731
- suggestions: [],
732
- domains: []
733
- }, { status: 500 });
734
- }
735
- } };
736
- }
737
- //#endregion
738
- //#region src/api/handlers/suggestions.ts
739
- function J() {
622
+ // src/api/handlers/suggestions.ts
623
+ function I() {
740
624
  return { POST: async (e) => {
741
625
  let n = await e.json(), r = n.chatHistory.filter((e) => e.role === "user" || e.role === "assistant").map((e) => ({
742
626
  role: e.role,
743
627
  content: String(e.content ?? "")
744
- })), i = await new t().loadChatModel(n.chatModel.providerId, n.chatModel.key), a = (await _({
628
+ })), i = await new t().loadChatModel(n.chatModel.providerId, n.chatModel.key), a = (await m({
745
629
  chat_history: r,
746
630
  maxQuestions: n.maxQuestions,
747
631
  promptTemplate: n.promptTemplate
@@ -749,9 +633,8 @@ function J() {
749
633
  return Response.json({ suggestions: a }, { status: 200 });
750
634
  } };
751
635
  }
752
- //#endregion
753
- //#region src/api/handlers/agents.ts
754
- function Y(e) {
636
+ // src/api/handlers/agents.ts
637
+ function L(e) {
755
638
  return { POST: async (t) => {
756
639
  let n;
757
640
  try {
@@ -764,38 +647,37 @@ function Y(e) {
764
647
  return a && (o = await r.query.user.findFirst({ where: i(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 });
765
648
  } };
766
649
  }
767
- //#endregion
768
- //#region src/api/handlers/rewrite.ts
769
- var X = "llama-3.3-70b-versatile";
770
- function Z(e) {
650
+ // src/api/handlers/rewrite.ts
651
+ var R = "llama-3.3-70b-versatile";
652
+ function z(e) {
771
653
  return e instanceof Error ? e.message : typeof e == "string" ? e : String(e);
772
654
  }
773
- async function ie(e, t) {
655
+ async function B(e, t) {
774
656
  let n = [];
775
657
  if (t && e.loadChatModel) try {
776
658
  return await e.loadChatModel(t);
777
659
  } catch (e) {
778
- n.push(Z(e));
660
+ n.push(z(e));
779
661
  }
780
662
  let r = e.getEnv("GROQ_API_KEY");
781
- if (r) return e.createGroq({ apiKey: r })(X);
663
+ if (r) return e.createGroq({ apiKey: r })(R);
782
664
  if (e.loadChatModel) try {
783
665
  return await e.loadChatModel();
784
666
  } catch (e) {
785
- n.push(Z(e));
667
+ n.push(z(e));
786
668
  }
787
669
  throw Error(n.length ? `AI service is not configured: ${n.join("; ")}` : "AI service is not configured. Please contact the administrator.");
788
670
  }
789
- function ae(e) {
671
+ function V(e) {
790
672
  return { POST: async (t) => {
791
673
  try {
792
674
  let { text: n, prompt: r, stream: i, chatModel: a } = await t.json();
793
675
  if (!n || typeof n != "string") return Response.json({ error: "Text is required and must be a string" }, { status: 400 });
794
676
  let o;
795
677
  try {
796
- o = await ie(e, a);
678
+ o = await B(e, a);
797
679
  } catch (e) {
798
- let t = Z(e);
680
+ let t = z(e);
799
681
  return console.error("AI rewrite has no usable model:", t), Response.json({ error: t }, { status: 500 });
800
682
  }
801
683
  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:
@@ -832,7 +714,7 @@ ${n}`;
832
714
  })).text.trim();
833
715
  return Response.json({ rewrittenText: c });
834
716
  } catch (e) {
835
- let t = Z(e);
717
+ let t = z(e);
836
718
  return console.error("AI rewrite error:", e), Response.json({
837
719
  error: `Failed to process AI request: ${t}`,
838
720
  details: t
@@ -840,9 +722,8 @@ ${n}`;
840
722
  }
841
723
  } };
842
724
  }
843
- //#endregion
844
- //#region src/api/handlers/voice.ts
845
- function oe(e) {
725
+ // src/api/handlers/voice.ts
726
+ function H(e) {
846
727
  return { POST: async (t) => {
847
728
  let n, r, i;
848
729
  try {
@@ -875,42 +756,116 @@ function oe(e) {
875
756
  }
876
757
  } };
877
758
  }
878
- //#endregion
879
- //#region src/api/handlers/transcript.ts
880
- function se(e) {
759
+ // src/api/handlers/transcript.ts
760
+ var U = [
761
+ "small",
762
+ "fast",
763
+ "medium",
764
+ "turbo",
765
+ "large"
766
+ ], W = "turbo";
767
+ function G(e) {
768
+ return typeof e == "string" && U.includes(e);
769
+ }
770
+ function K(e) {
881
771
  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";
882
772
  }
883
- function Q(e) {
773
+ async function q(e, t, n) {
774
+ let r = K(n), i;
775
+ try {
776
+ i = e.getCloudflareContext().env?.AI;
777
+ } catch {}
778
+ if (!i) return {
779
+ ok: !1,
780
+ reason: "ai_unavailable"
781
+ };
782
+ let a = await t.arrayBuffer(), { text: o } = await i.run(r, { audio: [...new Uint8Array(a)] });
783
+ return {
784
+ ok: !0,
785
+ text: o,
786
+ model: r
787
+ };
788
+ }
789
+ function J(e) {
884
790
  return { POST: async (t) => {
885
791
  try {
886
792
  let n = await t.formData(), r = n.get("file");
887
793
  if (!r || !(r instanceof File)) return Response.json({ error: "file is required" }, { status: 400 });
888
- let i = se(n.get("model")), a;
889
- try {
890
- a = e.getCloudflareContext().env?.AI;
891
- } catch {}
892
- if (!a) return Response.json({ error: "Cloudflare AI binding not available" }, { status: 503 });
893
- let o = await r.arrayBuffer(), { text: s } = await a.run(i, { audio: [...new Uint8Array(o)] });
894
- return Response.json({
895
- text: s,
896
- model: i
897
- });
794
+ let i = await q(e, r, n.get("model"));
795
+ return i.ok ? Response.json({
796
+ text: i.text,
797
+ model: i.model
798
+ }) : Response.json({ error: "Cloudflare AI binding not available" }, { status: 503 });
898
799
  } catch (e) {
899
800
  return console.error("Transcript error:", e), Response.json({ error: "Failed to transcribe audio" }, { status: 500 });
900
801
  }
901
802
  } };
902
803
  }
903
- //#endregion
904
- //#region src/api/handlers/test-models.ts
905
- function ce() {
804
+ // src/api/handlers/openai-transcription.ts
805
+ var Y = ["json"];
806
+ function X(e, t, n, r = null, i = null) {
807
+ return Response.json({ error: {
808
+ message: t,
809
+ type: n,
810
+ param: r,
811
+ code: i
812
+ } }, { status: e });
813
+ }
814
+ async function Z(e, t) {
815
+ let n = await e.authorize(t);
816
+ if (n.authorized) return null;
817
+ let { status: r, message: i } = n;
818
+ return X(r ?? 401, i, "authentication_error", null, "invalid_api_key");
819
+ }
820
+ function Q() {
821
+ return {
822
+ object: "list",
823
+ data: U.map((e) => ({
824
+ id: e,
825
+ object: "model",
826
+ created: 0,
827
+ owned_by: "qwksearch"
828
+ }))
829
+ };
830
+ }
831
+ function ne(e) {
832
+ return { GET: async (t) => await Z(e, t) || Response.json(Q()) };
833
+ }
834
+ function re(e) {
835
+ return { POST: async (t) => {
836
+ let n = await Z(e, t);
837
+ if (n) return n;
838
+ let r;
839
+ try {
840
+ r = await t.formData();
841
+ } catch {
842
+ return X(400, "Request body must be multipart/form-data with a `file` field.", "invalid_request_error", null, "invalid_body");
843
+ }
844
+ let i = r.get("file");
845
+ if (!i || !(i instanceof File)) return X(400, "`file` is required.", "invalid_request_error", "file", "missing_file");
846
+ if (i.size === 0) return X(400, "`file` is empty.", "invalid_request_error", "file", "empty_file");
847
+ let a = r.get("model"), o = a === null || a === "" ? W : a;
848
+ if (!G(o)) return X(400, `Unsupported model. Use one of: ${U.join(", ")}.`, "invalid_request_error", "model", "model_not_found");
849
+ let s = r.get("response_format");
850
+ if (s !== null && s !== "" && s !== "json") return X(400, `Unsupported response_format. Only ${Y.join(", ")} is supported.`, "invalid_request_error", "response_format", "unsupported_response_format");
851
+ try {
852
+ let t = await q(e, i, o);
853
+ return t.ok ? Response.json({ text: t.text }) : X(503, "Transcription is not available right now.", "server_error", null, "ai_unavailable");
854
+ } catch (e) {
855
+ return console.error("[v1/audio/transcriptions] Workers AI failed:", e instanceof Error ? e.name : typeof e), X(500, "Failed to transcribe audio.", "server_error", null, "transcription_failed");
856
+ }
857
+ } };
858
+ }
859
+ // src/api/handlers/test-models.ts
860
+ function ie() {
906
861
  return { POST: async (e) => {
907
862
  try {
908
863
  let { providerType: t, apiKey: n, onlyFree: r = !0 } = await e.json();
909
864
  if (!t) return Response.json({ error: "Provider type is required" }, { status: 400 });
910
865
  if (!n) return Response.json({ error: "API key is required" }, { status: 400 });
911
- let i = y.find((e) => e.provider.toLowerCase() === t.toLowerCase());
866
+ let i = g.find((e) => e.provider.toLowerCase() === t.toLowerCase());
912
867
  if (!i) return Response.json({ error: `Provider ${t} not found` }, { status: 404 });
913
- let a = await v(t, n, i.models, {
868
+ let a = await h(t, n, i.models, {
914
869
  onlyFree: r,
915
870
  concurrency: 3,
916
871
  timeout: 15e3
@@ -921,15 +876,14 @@ function ce() {
921
876
  }
922
877
  } };
923
878
  }
924
- //#endregion
925
- //#region src/api/handlers/validate-openrouter.ts
926
- var le = 864e5, $ = null;
927
- function ue(e) {
879
+ // src/api/handlers/validate-openrouter.ts
880
+ var ae = 864e5, $ = null;
881
+ function oe(e) {
928
882
  return {
929
883
  GET: async (t) => {
930
884
  try {
931
885
  let t = Date.now();
932
- if ($ && t - $.timestamp < le) return Response.json({
886
+ if ($ && t - $.timestamp < ae) return Response.json({
933
887
  ...$.result,
934
888
  cached: !0,
935
889
  cacheAge: t - $.timestamp
@@ -962,5 +916,4 @@ function ue(e) {
962
916
  }
963
917
  };
964
918
  }
965
- //#endregion
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 };
919
+ export { W as DEFAULT_TRANSCRIPTION_MODEL, Y as SUPPORTED_RESPONSE_FORMATS, U as TRANSCRIPTION_MODELS, L as createAgentsHandler, _ as createArticleFollowupsHandler, b as createArticleQAHandler, p as createAutocompleteHandler, ee as createChatByIdHandler, w as createChatTitleHandler, x as createChatsHandler, S as createChatsSearchHandler, C as createChatsShareHandler, F as createDiscoverHandler, M as createMCPServerByIdHandler, N as createMCPServerToggleHandler, j as createMCPServersHandler, D as createMessagesHandler, ne as createOpenAIModelsHandler, re as createOpenAITranscriptionHandler, v as createPageTipsHandler, k as createProviderByIdHandler, A as createProviderModelsHandler, O as createProvidersHandler, V as createRewriteHandler, P as createSearchHandler, I as createSuggestionsHandler, ie as createTestModelsHandler, y as createTopicSearchesHandler, J as createTranscriptHandler, oe as createValidateOpenRouterHandler, H as createVoiceHandler, E as describeError, K as getWhisperModel, G as isTranscriptionModel, Q as listTranscriptionModels, X as openAIError, q as transcribeAudio };
@@ -13,4 +13,4 @@ export { CategoryDock } from './CategoryDock';
13
13
  export { CookieConsent } from './CookieConsent';
14
14
  export { MainViewProvider, useMainView, type MainViewMode, } from './MainViewProvider';
15
15
  export { useChatTabs, type ChatTab } from './useChatTabs';
16
- export { useChunkErrorReload } from './useChunkErrorReload';
16
+ export { useChunkErrorReload, isChunkLoadError, reloadForChunkError, } from './useChunkErrorReload';
@@ -1,8 +1,19 @@
1
+ /** Whether `error` (an Error, a message, or a rejection reason) is a failed chunk fetch. */
2
+ export declare function isChunkLoadError(error: unknown): boolean;
3
+ /**
4
+ * Reloads the page if `error` is a failed chunk fetch and no such reload
5
+ * happened in the last {@link RELOAD_COOLDOWN_MS}. Returns whether it reloaded,
6
+ * so a caller can keep showing a loading state instead of an error.
7
+ */
8
+ export declare function reloadForChunkError(error: unknown): boolean;
1
9
  /**
2
10
  * Deployments replace `_next/static` chunks with newly-hashed filenames, so a
3
11
  * browser tab left open from before a deploy will 404 when it tries to fetch
4
12
  * an old chunk (e.g. on a client-side navigation). Reload once to pick up the
5
- * new build instead of leaving the user stuck on a broken page; the
6
- * sessionStorage flag stops a reload loop if the new build somehow fails too.
13
+ * new build instead of leaving the user stuck on a broken page.
14
+ *
15
+ * This only sees failures nothing else handled. A lazy component's failed
16
+ * chunk is caught by the nearest error boundary instead, so boundaries around
17
+ * lazy subtrees should call {@link reloadForChunkError} themselves.
7
18
  */
8
19
  export declare function useChunkErrorReload(): void;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Renders the reader once it has been opened, and keeps it mounted after.
3
+ * Renders nothing outside an `ExtractPanelProvider`.
4
+ */
5
+ export default function ArticleReaderMount(): import("react").JSX.Element;