milvus-io / milvus-sdk-node

The Official Mivus node.js sdk(client)
https://milvus.io
Apache License 2.0
113 stars 35 forks source link

Error: ENOENT: no such file or directory, open '/var/task/.next/proto/proto/schema.proto' #326

Open AOvardovVSG opened 2 weeks ago

AOvardovVSG commented 2 weeks ago

Describe the bug: I'm trying to use Milvus with Langchain in a Next.js app. I finished my project and tested it locally, and it works perfectly without any issues. However, when it came time to deploy my project to Vercel, I ran into an issue with the production version.

When I try to use Milvus vector store for similarity searching, I receive this error: ENOENT: no such file or directory, open '/var/task/.next/proto/proto/schema.proto'.

I have tried a couple of things to fix it but without success:

First, I tried to add this code into my next.config.js

experimental: {
    serverComponentsExternalPackages: ['@zilliz/milvus2-sdk-node'],
}

Second, I tried to copy proto files into the .next folder:

const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
  webpack: (config, { isServer }) => {
    if (isServer) {
      const dirname = path.resolve(path.dirname(''));

      // Copy the proto files to the server build directory
      config.plugins.push(
        new CopyWebpackPlugin({
          patterns: [
            {
              from: path.join(dirname, 'node_modules/@zilliz/milvus2-sdk-node/dist'),
              to: path.join(dirname, '.next'),
            },
          ],
        })
      );
    }
    // Important: return the modified config
    return config;
  },
};

Despite these efforts, I haven't been able to resolve the issue.

This is the way of how I'm using Milvus

import { Milvus } from "@langchain/community/vectorstores/milvus";

export const getVectorStore = async () => {
  const embeddings = getEmbeddings();

  return Milvus.fromExistingCollection(embeddings, {
    collectionName: process.env.MILVUS_COLLECTION_NAME,
    url: process.env.MILVUS_DB_URL,
    clientConfig: { address: '', token: process.env.MILVUS_API_KEY }
  });
}

const vectorStore = await getVectorStore();
const res = await vectorStore.similaritySearch('question')

Steps to reproduce:

  1. Deploy app to vercel

Milvus-node-sdk version: @zilliz/milvus2-sdk-node: 2.4.2 next 14.1.4

Milvus version:

zhanshuyou commented 2 weeks ago

@AOvardovVSG You can try this example https://github.com/zhanshuyou/milvus-next-example Deploy to vercel successfully image If there are still problems, please provide an example repository.

AOvardovVSG commented 2 weeks ago

Hi @zhanshuyou,

Thank you for your example. I tried your example and it actually worked. While it is helpful, my situation is slightly different. I am working on a client-side component called Form that includes a basic form element with an input field for a question and a submit button. When the form is submitted, it sends a POST request containing the question's value to an endpoint in my Next.js application (located in the api folder).

This endpoint is responsible for searching documents in a vector store within an existing Milvus collection. Unfortunately, due to company policy, I am unable to share the repository.

Here is the code for my Next.js endpoint: It is located in "api/documents/route.ts" path.

import { NextResponse } from "next/server";
import { HuggingFaceInferenceEmbeddings } from "@langchain/community/embeddings/hf";
import { Milvus } from "@langchain/community/vectorstores/milvus";

export async function POST(req: Request) {
  try {
    const embeddings = new HuggingFaceInferenceEmbeddings({ apiKey: process.env.HUGGINGFACEHUB_API_KEY });

    const vectorStore = await Milvus.fromExistingCollection(embeddings, {
      collectionName: process.env.MILVUS_COLLECTION_NAME,
      url: process.env.MILVUS_DB_URL,
      clientConfig: { address: '', token: process.env.MILVUS_API_KEY }
    });

    const res = await vectorStore.similaritySearch('Why the sky is blue?');

    return NextResponse.json({ res: res }, { status: 200 });
  } catch (error: Error | any) {
    return NextResponse.json({ error: error.message }, { status: error.status ?? 500 });
  }
}

And actually I received this error only inside next.js endpoint. Everything works fine in a server-side component, but I have to do that in the endpoint because we use the result from the search for other purposes and it has to be in the endpoint.

That's the issue that I receive ENOENT: no such file or directory, open '/var/task/node_modules/@zilliz/milvus2-sdk-node/dist/proto/proto/common.proto'

Please take in notes that I copied your next.config.js and also included the proto files in the public folder as from your example.

Thanks in advance! I hope that you will find a way to reproduce and fix that.

zhanshuyou commented 2 weeks ago

@AOvardovVSG I have already moved it to the /api folder, and it still works properly.

https://github.com/zhanshuyou/milvus-next-example/blob/main/app/api/langchain/route.ts https://github.com/zhanshuyou/milvus-next-example/blob/main/app/components/LangchainExample.tsx

AOvardovVSG commented 2 weeks ago

Hi @zhanshuyou ,

Thank you again for your solution! I have identified the root cause of the issue. When I make a GET request, everything works fine. However, when I make a POST request, I encounter an error.

It seems the issue might be related to how Next.js handles and structures files when creating a POST function.

You can reproduce the error by changing your method to POST.

zhanshuyou commented 2 weeks ago

Hi @zhanshuyou ,

Thank you again for your solution! I have identified the root cause of the issue. When I make a GET request, everything works fine. However, when I make a POST request, I encounter an error.

It seems the issue might be related to how Next.js handles and structures files when creating a POST function.

You can reproduce the error by changing your method to POST.

I have already reproduced it. It looks like a Vercel issue 🤔

AOvardovVSG commented 2 weeks ago

What is your next.js version?

14.1.4

shanghaikid commented 1 week ago

What is your next.js version?

14.1.4

Hi, can you try this config?

https://github.com/zilliztech/zilliz-cloud-typescript-example/blob/master/semantic-search-example/next.config.js

We may update the sdk to avoid this setup , but right now, you should include this, thanks.

kknono commented 5 days ago

Additionally, modifying it in Nuxt 3 can work very well:

hooks: {

'nitro:build:public-assets': (_nitro: any) => {

  const sourceDir = path.resolve(__dirname, 'node_modules/@zilliz/milvus2-sdk-node/dist/proto')
  const destDir = path.resolve(__dirname, '.output/server/node_modules/@zilliz/milvus2-sdk-node/dist/proto')

  const copyDir = (src: string, dest: string): void => {
    if (!fs.existsSync(dest)) {
      fs.mkdirSync(dest, { recursive: true })
    }
    fs.readdirSync(src).forEach((file) => {
      const srcFile = path.resolve(src, file)
      const destFile = path.resolve(dest, file)
      if (fs.lstatSync(srcFile).isDirectory()) {
        copyDir(srcFile, destFile)
      }
      else {
        fs.copyFileSync(srcFile, destFile)
      }
    })
  }

  copyDir(sourceDir, destDir)
  console.log('Proto files copied successfully!')
},

},