@retrivora-ai/rag-engine 1.0.3 → 1.0.5

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 (40) hide show
  1. package/dist/DocumentChunker-Dh9TvmGG.d.mts +45 -0
  2. package/dist/DocumentChunker-Dh9TvmGG.d.ts +45 -0
  3. package/dist/{RagConfig-DRJO4hGU.d.mts → RagConfig-BEmz4hVP.d.mts} +58 -1
  4. package/dist/{RagConfig-DRJO4hGU.d.ts → RagConfig-BEmz4hVP.d.ts} +58 -1
  5. package/dist/{chunk-3JR3SAWX.mjs → chunk-MWL4AGQI.mjs} +216 -108
  6. package/dist/handlers/index.d.mts +2 -2
  7. package/dist/handlers/index.d.ts +2 -2
  8. package/dist/handlers/index.js +218 -110
  9. package/dist/handlers/index.mjs +11 -3
  10. package/dist/index-CSfaCeux.d.ts +206 -0
  11. package/dist/index-DFSy0CG6.d.mts +206 -0
  12. package/dist/index.d.mts +3 -4
  13. package/dist/index.d.ts +3 -4
  14. package/dist/index.js +103 -89
  15. package/dist/index.mjs +91 -95
  16. package/dist/server.d.mts +45 -97
  17. package/dist/server.d.ts +45 -97
  18. package/dist/server.js +298 -225
  19. package/dist/server.mjs +78 -167
  20. package/package.json +12 -10
  21. package/src/components/ChatWindow.tsx +2 -2
  22. package/src/components/ConfigProvider.tsx +2 -2
  23. package/src/components/MessageBubble.tsx +2 -2
  24. package/src/components/SourceCard.tsx +1 -1
  25. package/src/components/ThemeToggle.tsx +1 -1
  26. package/src/config/ConfigBuilder.ts +86 -211
  27. package/src/config/uiConstants.ts +23 -0
  28. package/src/core/ConfigResolver.ts +57 -29
  29. package/src/core/LangChainAgent.ts +73 -40
  30. package/src/core/Pipeline.ts +63 -7
  31. package/src/core/ProviderRegistry.ts +2 -2
  32. package/src/core/QueryProcessor.ts +9 -8
  33. package/src/handlers/index.ts +138 -49
  34. package/src/hooks/useRagChat.ts +71 -32
  35. package/src/rag/EntityExtractor.ts +40 -13
  36. package/src/server.ts +12 -2
  37. package/dist/DocumentChunker-C-sCZPhi.d.mts +0 -102
  38. package/dist/DocumentChunker-C-sCZPhi.d.ts +0 -102
  39. package/dist/index-B2mutkgp.d.ts +0 -116
  40. package/dist/index-Bjy0es5a.d.mts +0 -116
@@ -1508,7 +1508,11 @@ __export(handlers_exports, {
1508
1508
  createHealthHandler: () => createHealthHandler,
1509
1509
  createIngestHandler: () => createIngestHandler,
1510
1510
  createStreamHandler: () => createStreamHandler,
1511
- createUploadHandler: () => createUploadHandler
1511
+ createUploadHandler: () => createUploadHandler,
1512
+ sseErrorFrame: () => sseErrorFrame,
1513
+ sseFrame: () => sseFrame,
1514
+ sseMetaFrame: () => sseMetaFrame,
1515
+ sseTextFrame: () => sseTextFrame
1512
1516
  });
1513
1517
  module.exports = __toCommonJS(handlers_exports);
1514
1518
  var import_server = require("next/server");
@@ -1691,13 +1695,20 @@ function getRagConfig(env = process.env) {
1691
1695
  }
1692
1696
 
1693
1697
  // src/core/ConfigResolver.ts
1698
+ var _cachedEnvConfig = null;
1699
+ function getCachedEnvConfig() {
1700
+ if (!_cachedEnvConfig) {
1701
+ _cachedEnvConfig = getRagConfig();
1702
+ }
1703
+ return _cachedEnvConfig;
1704
+ }
1694
1705
  var ConfigResolver = class {
1695
1706
  /**
1696
- * Resolves the final configuration by merging host-provided config with defaults.
1707
+ * Resolves the final configuration by merging host-provided config with environment defaults.
1697
1708
  * @param hostConfig - Partial configuration passed from the host application.
1698
1709
  */
1699
1710
  static resolve(hostConfig) {
1700
- const envConfig = getRagConfig();
1711
+ const envConfig = getCachedEnvConfig();
1701
1712
  if (!hostConfig) {
1702
1713
  return envConfig;
1703
1714
  }
@@ -2871,25 +2882,42 @@ Text to extract from:
2871
2882
  const response = await this.llm.chat([
2872
2883
  { role: "system", content: "You are a precise knowledge graph extraction engine. You always output valid JSON and nothing else." },
2873
2884
  { role: "user", content: prompt }
2874
- ], "", { maxTokens: 2048, temperature: 0.1 });
2885
+ ], "", { maxTokens: 4096, temperature: 0.1 });
2875
2886
  try {
2876
2887
  const jsonMatch = response.match(/\{[\s\S]*\}/);
2877
2888
  const cleanJson = jsonMatch ? jsonMatch[0] : response.trim();
2878
2889
  return JSON.parse(cleanJson);
2879
2890
  } catch (e) {
2880
- console.warn(`[EntityExtractor] Failed to parse LLM response. Length: ${response.length} chars.`);
2881
- if (response.trim().endsWith("}") === false && response.includes('"nodes"')) {
2882
- try {
2883
- const partialResponse = response.trim() + (response.includes("[") ? "]}" : "}");
2884
- const jsonMatch = partialResponse.match(/\{[\s\S]*\}/);
2885
- if (jsonMatch) return JSON.parse(jsonMatch[0]);
2886
- } catch (e2) {
2887
- }
2891
+ try {
2892
+ const repaired = this.repairTruncatedJson(response);
2893
+ if (repaired) return JSON.parse(repaired);
2894
+ } catch (e2) {
2888
2895
  }
2889
- console.warn("[EntityExtractor] Full failing response:", response.substring(0, 200) + "...");
2896
+ console.warn(`[EntityExtractor] Failed to parse LLM response. Length: ${response.length} chars.`);
2897
+ console.warn("[EntityExtractor] Snippet:", response.substring(0, 100) + "...");
2890
2898
  return { nodes: [], edges: [] };
2891
2899
  }
2892
2900
  }
2901
+ /**
2902
+ * Attempts to fix JSON that was cut off mid-generation.
2903
+ * Strategy: Find the last valid element in an array and close the structure.
2904
+ */
2905
+ repairTruncatedJson(json) {
2906
+ let text = json.trim();
2907
+ const startIdx = text.indexOf("{");
2908
+ if (startIdx === -1) return null;
2909
+ text = text.substring(startIdx);
2910
+ const lastCompleteObjectIdx = text.lastIndexOf("}");
2911
+ if (lastCompleteObjectIdx === -1) return null;
2912
+ let repaired = text.substring(0, lastCompleteObjectIdx + 1);
2913
+ const openBrackets = (repaired.match(/\{/g) || []).length;
2914
+ const closedBrackets = (repaired.match(/\}/g) || []).length;
2915
+ const openSquares = (repaired.match(/\[/g) || []).length;
2916
+ const closedSquares = (repaired.match(/\]/g) || []).length;
2917
+ for (let i = 0; i < openSquares - closedSquares; i++) repaired += "]";
2918
+ for (let i = 0; i < openBrackets - closedBrackets; i++) repaired += "}";
2919
+ return repaired;
2920
+ }
2893
2921
  };
2894
2922
 
2895
2923
  // src/rag/Reranker.ts
@@ -2954,14 +2982,16 @@ var LangChainAgent = class {
2954
2982
  this.config = config;
2955
2983
  }
2956
2984
  /**
2957
- * Initializes the agent with the RAG pipeline as a primary tool.
2958
- * Dynamically imports LangChain dependencies to avoid build errors if missing.
2985
+ * Initializes the LangChain ReAct agent with the RAG pipeline as a tool.
2986
+ * Dynamically imports langchain so the package doesn't crash if it isn't installed.
2959
2987
  */
2960
2988
  async initialize(chatModel) {
2961
2989
  try {
2962
- const { DynamicTool } = await import(`${"@langchain/core/tools"}`);
2963
- const { ChatPromptTemplate, MessagesPlaceholder } = await import(`${"@langchain/core/prompts"}`);
2964
- const { AgentExecutor, createOpenAIFunctionsAgent } = await import(`${"langchain/agents"}`);
2990
+ const [{ DynamicTool }, { HumanMessage }, { createAgent }] = await Promise.all([
2991
+ import("@langchain/core/tools"),
2992
+ import("@langchain/core/messages"),
2993
+ import("langchain")
2994
+ ]);
2965
2995
  const searchTool = new DynamicTool({
2966
2996
  name: "document_search",
2967
2997
  description: "Use this tool to search through the knowledge base and document repository. Input should be a specific search query.",
@@ -2970,42 +3000,53 @@ var LangChainAgent = class {
2970
3000
  return `Search Results:
2971
3001
  ${response.reply}
2972
3002
 
2973
- Sources Used: ${JSON.stringify(response.sources.map((s) => s.id))}`;
3003
+ Sources Used: ${JSON.stringify(
3004
+ response.sources.map((s) => s.id)
3005
+ )}`;
2974
3006
  }
2975
3007
  });
2976
- const tools = [searchTool];
2977
- const prompt = ChatPromptTemplate.fromMessages([
2978
- ["system", this.config.llm.systemPrompt || "You are a helpful AI assistant with access to a document search tool."],
2979
- new MessagesPlaceholder("chat_history"),
2980
- ["human", "{input}"],
2981
- new MessagesPlaceholder("agent_scratchpad")
2982
- ]);
2983
- const agent = await createOpenAIFunctionsAgent({
2984
- llm: chatModel,
2985
- tools,
2986
- prompt
2987
- });
2988
- this.executor = new AgentExecutor({
2989
- agent,
2990
- tools
3008
+ this.agent = createAgent({
3009
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3010
+ model: chatModel,
3011
+ tools: [searchTool],
3012
+ systemPrompt: this.config.llm.systemPrompt || "You are a helpful AI assistant with access to a document search tool."
2991
3013
  });
3014
+ void HumanMessage;
2992
3015
  } catch (error) {
2993
- console.error("[LangChainAgent] Failed to initialize. Ensure 'langchain' and '@langchain/core' are installed.");
2994
- throw error;
3016
+ const isMissing = error instanceof Error && error.message.includes("Cannot find module");
3017
+ const hint = isMissing ? " Make sure 'langchain' and '@langchain/core' are installed:\n npm install langchain @langchain/core" : "";
3018
+ throw new Error(
3019
+ `[LangChainAgent] Failed to initialize.${hint}
3020
+ ${error instanceof Error ? error.message : String(error)}`
3021
+ );
2995
3022
  }
2996
3023
  }
2997
3024
  /**
2998
3025
  * Run the agentic flow.
3026
+ *
3027
+ * LangChain v1.x: invoke takes `{ messages: [...] }` instead of `{ input, chat_history }`.
3028
+ * The agent returns `{ messages: [...] }` — the last message is the final answer.
2999
3029
  */
3000
3030
  async run(input, chatHistory = []) {
3001
- if (!this.executor) {
3031
+ var _a, _b, _c;
3032
+ if (!this.agent) {
3002
3033
  throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
3003
3034
  }
3004
- const response = await this.executor.invoke({
3005
- input,
3006
- chat_history: chatHistory
3035
+ const { HumanMessage, AIMessage } = await import("@langchain/core/messages");
3036
+ const historyMessages = chatHistory.map(
3037
+ (m) => m.role === "user" ? new HumanMessage(m.content) : new AIMessage(m.content)
3038
+ );
3039
+ const response = await this.agent.invoke({
3040
+ messages: [...historyMessages, new HumanMessage(input)]
3007
3041
  });
3008
- return response.output;
3042
+ const lastMessage = (_a = response == null ? void 0 : response.messages) == null ? void 0 : _a.at(-1);
3043
+ if (lastMessage && typeof lastMessage.content === "string") {
3044
+ return lastMessage.content;
3045
+ }
3046
+ if (Array.isArray(lastMessage == null ? void 0 : lastMessage.content)) {
3047
+ return lastMessage.content.filter((c) => c.type === "text").map((c) => c.text).join("");
3048
+ }
3049
+ return String((_c = (_b = response == null ? void 0 : response.output) != null ? _b : response) != null ? _c : "");
3009
3050
  }
3010
3051
  };
3011
3052
 
@@ -3408,6 +3449,10 @@ var QueryProcessor = class {
3408
3449
  }
3409
3450
  /**
3410
3451
  * Constructs a QueryFilter object from extracted hints.
3452
+ *
3453
+ * Note: proper nouns are extracted inside `extractQueryFieldHints` and surfaced
3454
+ * as field-less hints; `buildQueryFilter` adds them to `keywords` without
3455
+ * re-running the proper noun regex to avoid duplication.
3411
3456
  */
3412
3457
  static buildQueryFilter(question, hints) {
3413
3458
  const filter = { metadata: {}, keywords: [], queryText: question };
@@ -3415,13 +3460,11 @@ var QueryProcessor = class {
3415
3460
  if (hint.field) {
3416
3461
  filter.metadata[hint.field] = hint.value;
3417
3462
  } else {
3418
- filter.keywords.push(hint.value);
3463
+ if (!filter.keywords.includes(hint.value)) {
3464
+ filter.keywords.push(hint.value);
3465
+ }
3419
3466
  }
3420
3467
  }
3421
- for (const match of question.matchAll(/\b[A-Z][a-z]+(?:\s+[A-Z][a-z]+){0,3}\b/g)) {
3422
- const term = this.normalizeHintValue(match[0]);
3423
- if (term && !filter.keywords.includes(term)) filter.keywords.push(term);
3424
- }
3425
3468
  if (Object.keys(filter.metadata || {}).length === 0) delete filter.metadata;
3426
3469
  if (filter.keywords && filter.keywords.length === 0) delete filter.keywords;
3427
3470
  return filter;
@@ -3429,10 +3472,40 @@ var QueryProcessor = class {
3429
3472
  };
3430
3473
 
3431
3474
  // src/core/Pipeline.ts
3475
+ var LRUEmbeddingCache = class {
3476
+ constructor(maxSize = 500) {
3477
+ this.cache = /* @__PURE__ */ new Map();
3478
+ this.maxSize = maxSize;
3479
+ }
3480
+ get(key) {
3481
+ const value = this.cache.get(key);
3482
+ if (value !== void 0) {
3483
+ this.cache.delete(key);
3484
+ this.cache.set(key, value);
3485
+ }
3486
+ return value;
3487
+ }
3488
+ set(key, value) {
3489
+ if (this.cache.has(key)) {
3490
+ this.cache.delete(key);
3491
+ } else if (this.cache.size >= this.maxSize) {
3492
+ const oldestKey = this.cache.keys().next().value;
3493
+ if (oldestKey !== void 0) this.cache.delete(oldestKey);
3494
+ }
3495
+ this.cache.set(key, value);
3496
+ }
3497
+ clear() {
3498
+ this.cache.clear();
3499
+ }
3500
+ get size() {
3501
+ return this.cache.size;
3502
+ }
3503
+ };
3432
3504
  var Pipeline = class {
3433
3505
  constructor(config) {
3434
3506
  this.config = config;
3435
- this.embeddingCache = /* @__PURE__ */ new Map();
3507
+ /** LRU-bounded cache: avoids re-embedding identical queries within the same process. */
3508
+ this.embeddingCache = new LRUEmbeddingCache(500);
3436
3509
  this.initialised = false;
3437
3510
  var _a, _b, _c, _d, _e;
3438
3511
  this.chunker = new DocumentChunker(
@@ -3520,6 +3593,7 @@ var Pipeline = class {
3520
3593
  }
3521
3594
  /**
3522
3595
  * Step 2: Generate embeddings for chunks with retry logic.
3596
+ * Uses batchEmbed when available for efficiency; falls back to sequential embedding.
3523
3597
  */
3524
3598
  async processEmbeddings(chunks) {
3525
3599
  const embedBatchOptions = {
@@ -3533,7 +3607,9 @@ var Pipeline = class {
3533
3607
  embedBatchOptions
3534
3608
  );
3535
3609
  if (vectors.length !== chunks.length) {
3536
- throw new Error(`Embedding mismatch: got ${vectors.length} vectors for ${chunks.length} chunks`);
3610
+ throw new Error(
3611
+ `[Pipeline] Embedding mismatch: got ${vectors.length} vectors for ${chunks.length} chunks. Check embedding provider logs for individual chunk failures.`
3612
+ );
3537
3613
  }
3538
3614
  return vectors;
3539
3615
  }
@@ -3687,6 +3763,7 @@ ${context}`;
3687
3763
  }
3688
3764
  /**
3689
3765
  * Universal retrieval method combining all enabled providers.
3766
+ * Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
3690
3767
  */
3691
3768
  async retrieve(query, options) {
3692
3769
  var _a, _b, _c;
@@ -3719,10 +3796,13 @@ ${history.map((m) => `${m.role}: ${m.content}`).join("\n")}
3719
3796
  New Question: ${question}
3720
3797
 
3721
3798
  Optimized Search Query:`;
3722
- const rewrite = await this.llmProvider.chat([
3723
- { role: "system", content: "You are an assistant that optimizes search queries for RAG systems." },
3724
- { role: "user", content: prompt }
3725
- ], "");
3799
+ const rewrite = await this.llmProvider.chat(
3800
+ [
3801
+ { role: "system", content: "You are an assistant that optimizes search queries for RAG systems." },
3802
+ { role: "user", content: prompt }
3803
+ ],
3804
+ ""
3805
+ );
3726
3806
  return rewrite.trim() || question;
3727
3807
  }
3728
3808
  };
@@ -3941,8 +4021,35 @@ var DocumentParser = class {
3941
4021
  };
3942
4022
 
3943
4023
  // src/handlers/index.ts
3944
- function createChatHandler(config) {
3945
- const plugin = new VectorPlugin(config);
4024
+ function sseFrame(payload) {
4025
+ return `data: ${JSON.stringify(payload)}
4026
+
4027
+ `;
4028
+ }
4029
+ function sseTextFrame(text) {
4030
+ return `data: ${JSON.stringify({ type: "text", text })}
4031
+
4032
+ `;
4033
+ }
4034
+ function sseMetaFrame(meta) {
4035
+ return `data: ${JSON.stringify(__spreadValues({ type: "metadata" }, meta != null ? meta : {}))}
4036
+
4037
+ `;
4038
+ }
4039
+ function sseErrorFrame(message) {
4040
+ return `data: ${JSON.stringify({ type: "error", error: message })}
4041
+
4042
+ `;
4043
+ }
4044
+ var SSE_HEADERS = {
4045
+ "Content-Type": "text/event-stream; charset=utf-8",
4046
+ "Cache-Control": "no-cache, no-transform",
4047
+ Connection: "keep-alive",
4048
+ "X-Accel-Buffering": "no"
4049
+ // Disable Nginx buffering for streaming
4050
+ };
4051
+ function createChatHandler(configOrPlugin) {
4052
+ const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
3946
4053
  return async function POST(req) {
3947
4054
  try {
3948
4055
  const body = await req.json();
@@ -3958,67 +4065,64 @@ function createChatHandler(config) {
3958
4065
  }
3959
4066
  };
3960
4067
  }
3961
- function createStreamHandler(config) {
3962
- const plugin = new VectorPlugin(config);
4068
+ function createStreamHandler(configOrPlugin) {
4069
+ const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
3963
4070
  return async function POST(req) {
4071
+ let body;
3964
4072
  try {
3965
- const body = await req.json();
3966
- const { message, history = [], namespace } = body;
3967
- const encoder = new TextEncoder();
3968
- const stream = new ReadableStream({
3969
- async start(controller) {
4073
+ body = await req.json();
4074
+ } catch (e) {
4075
+ return new Response(JSON.stringify({ error: "Invalid JSON body" }), {
4076
+ status: 400,
4077
+ headers: { "Content-Type": "application/json" }
4078
+ });
4079
+ }
4080
+ const { message, history = [], namespace } = body;
4081
+ if (!(message == null ? void 0 : message.trim())) {
4082
+ return new Response(JSON.stringify({ error: "message is required" }), {
4083
+ status: 400,
4084
+ headers: { "Content-Type": "application/json" }
4085
+ });
4086
+ }
4087
+ const encoder = new TextEncoder();
4088
+ const stream = new ReadableStream({
4089
+ async start(controller) {
4090
+ const enqueue = (text) => controller.enqueue(encoder.encode(text));
4091
+ try {
4092
+ const pipelineStream = plugin.chatStream(message, history, namespace);
3970
4093
  try {
3971
- const pipelineStream = plugin.chatStream(message, history, namespace);
3972
- try {
3973
- for (var iter = __forAwait(pipelineStream), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
3974
- const chunk = temp.value;
3975
- if (typeof chunk === "string") {
3976
- controller.enqueue(encoder.encode(chunk));
3977
- } else {
3978
- controller.enqueue(encoder.encode(`
3979
-
3980
- __METADATA__${JSON.stringify(chunk)}`));
3981
- }
4094
+ for (var iter = __forAwait(pipelineStream), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
4095
+ const chunk = temp.value;
4096
+ if (typeof chunk === "string") {
4097
+ enqueue(sseTextFrame(chunk));
4098
+ } else {
4099
+ enqueue(sseMetaFrame(chunk));
3982
4100
  }
3983
- } catch (temp) {
3984
- error = [temp];
4101
+ }
4102
+ } catch (temp) {
4103
+ error = [temp];
4104
+ } finally {
4105
+ try {
4106
+ more && (temp = iter.return) && await temp.call(iter);
3985
4107
  } finally {
3986
- try {
3987
- more && (temp = iter.return) && await temp.call(iter);
3988
- } finally {
3989
- if (error)
3990
- throw error[0];
3991
- }
4108
+ if (error)
4109
+ throw error[0];
3992
4110
  }
3993
- controller.close();
3994
- } catch (streamError) {
3995
- console.error("[createStreamHandler] Stream processing error:", streamError);
3996
- const errorMessage = streamError instanceof Error ? streamError.message : String(streamError);
3997
- controller.enqueue(encoder.encode(`
3998
-
3999
- __ERROR__${JSON.stringify({ error: errorMessage })}`));
4000
- controller.close();
4001
4111
  }
4112
+ } catch (streamError) {
4113
+ const errorMessage = streamError instanceof Error ? streamError.message : String(streamError);
4114
+ console.error("[createStreamHandler] Stream error:", streamError);
4115
+ enqueue(sseErrorFrame(errorMessage));
4116
+ } finally {
4117
+ controller.close();
4002
4118
  }
4003
- });
4004
- return new Response(stream, {
4005
- headers: {
4006
- "Content-Type": "text/event-stream",
4007
- "Cache-Control": "no-cache",
4008
- "Connection": "keep-alive"
4009
- }
4010
- });
4011
- } catch (err) {
4012
- const message = err instanceof Error ? err.message : "Internal server error";
4013
- return new Response(JSON.stringify({ error: message }), {
4014
- status: 500,
4015
- headers: { "Content-Type": "application/json" }
4016
- });
4017
- }
4119
+ }
4120
+ });
4121
+ return new Response(stream, { headers: SSE_HEADERS });
4018
4122
  };
4019
4123
  }
4020
- function createIngestHandler(config) {
4021
- const plugin = new VectorPlugin(config);
4124
+ function createIngestHandler(configOrPlugin) {
4125
+ const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
4022
4126
  return async function POST(req) {
4023
4127
  try {
4024
4128
  const body = await req.json();
@@ -4034,8 +4138,8 @@ function createIngestHandler(config) {
4034
4138
  }
4035
4139
  };
4036
4140
  }
4037
- function createHealthHandler(config) {
4038
- const plugin = new VectorPlugin(config);
4141
+ function createHealthHandler(configOrPlugin) {
4142
+ const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
4039
4143
  return async function GET() {
4040
4144
  try {
4041
4145
  const health = await plugin.checkHealth();
@@ -4051,8 +4155,8 @@ function createHealthHandler(config) {
4051
4155
  }
4052
4156
  };
4053
4157
  }
4054
- function createUploadHandler(config) {
4055
- const plugin = new VectorPlugin(config);
4158
+ function createUploadHandler(configOrPlugin) {
4159
+ const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
4056
4160
  return async function POST(req) {
4057
4161
  try {
4058
4162
  const formData = await req.formData();
@@ -4090,5 +4194,9 @@ function createUploadHandler(config) {
4090
4194
  createHealthHandler,
4091
4195
  createIngestHandler,
4092
4196
  createStreamHandler,
4093
- createUploadHandler
4197
+ createUploadHandler,
4198
+ sseErrorFrame,
4199
+ sseFrame,
4200
+ sseMetaFrame,
4201
+ sseTextFrame
4094
4202
  });
@@ -3,8 +3,12 @@ import {
3
3
  createHealthHandler,
4
4
  createIngestHandler,
5
5
  createStreamHandler,
6
- createUploadHandler
7
- } from "../chunk-3JR3SAWX.mjs";
6
+ createUploadHandler,
7
+ sseErrorFrame,
8
+ sseFrame,
9
+ sseMetaFrame,
10
+ sseTextFrame
11
+ } from "../chunk-MWL4AGQI.mjs";
8
12
  import "../chunk-YLTMFW4M.mjs";
9
13
  import "../chunk-X4TOT24V.mjs";
10
14
  export {
@@ -12,5 +16,9 @@ export {
12
16
  createHealthHandler,
13
17
  createIngestHandler,
14
18
  createStreamHandler,
15
- createUploadHandler
19
+ createUploadHandler,
20
+ sseErrorFrame,
21
+ sseFrame,
22
+ sseMetaFrame,
23
+ sseTextFrame
16
24
  };