lobehub / lobe-chat

🤯 Lobe Chat - an open-source, modern-design AI chat framework. Supports Multi AI Providers( OpenAI / Claude 3 / Gemini / Ollama / Azure / DeepSeek), Knowledge Base (file upload / knowledge management / RAG ), Multi-Modals (Vision/TTS) and plugin system. One-click FREE deployment of your private ChatGPT/ Claude application.
https://chat-preview.lobehub.com
Other
44.39k stars 9.95k forks source link

[Request] 支持设置多个插件 index, agent index #1559

Open LeoQuote opened 8 months ago

LeoQuote commented 8 months ago

🥰 需求描述

私有化部署后, 有时候有自己设置自己的插件中心和 agent 中心的需求, 但是如果简单的替换, 会丧失之前拥有的社区优势, 而镜像社区的中心到私有的插件中心, 虽然可以实现, 但是不算特别优雅.

所以此时如果 AGENTS_INDEX_URLPLUGINS_INDEX_URL 中可以配置多个, 那么就可以解决这个问题

🧐 解决方案

以 agent 市场为例

https://github.com/lobehub/lobe-chat/blob/0988466b99b13cff19d9957f7876c5db130e9b15/src/app/api/market/route.ts#L10

此处get 到 config, 并用,分割开, 实例化两个 AgentMarket 对象, 并分别 fetch , 应该可以达到需求.

📝 补充信息

No response

lobehubbot commented 8 months ago

👀 @LeoQuote

Thank you for raising an issue. We will investigate into the matter and get back to you as soon as possible. Please make sure you have given us as much context as possible.\ 非常感谢您提交 issue。我们会尽快调查此事,并尽快回复您。 请确保您已经提供了尽可能多的背景信息。

lobehubbot commented 8 months ago

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


🥰 Description of requirements

After privatized deployment, there is sometimes a need to set up your own plug-in center and agent center. However, if you simply replace it, you will lose the community advantages you had before. Mirroring the community center to a private plug-in center can be achieved, but Not particularly elegant.

So at this time, if multiple AGENTS_INDEX_URL and PLUGINS_INDEX_URL can be configured, then this problem can be solved

🧐 Solution

Take the agent market as an example

https://github.com/lobehub/lobe-chat/blob/0988466b99b13cff19d9957f7876c5db130e9b15/src/app/api/market/route.ts#L10

Here, get config, separate it with ,, instantiate two AgentMarket objects, and fetch them respectively, which should meet the requirements.

📝 Supplementary information

No response

arvinxx commented 8 months ago

好想法,考不考虑写个 RFC 然后来个PR ?

lobehubbot commented 8 months ago

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


Great idea, would you consider writing an RFC and then issuing a PR?

LeoQuote commented 8 months ago

@arvinxx 嗯,可以等我,我大概下周或者下下周尝试实现,看起来只是需要多实例化一个对象

lobehubbot commented 8 months ago

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


@arvinxx Well, you can wait for me. I will try to implement it probably next week or the next week. It seems that I just need to instantiate one more object.

LeoQuote commented 8 months ago

仔细看了下代码, 这边实现的方式不会太优雅或者简单, 如果说两个 index url 分成N个接口, 前端分别请求, 改动还挺大的, 从前端的 service 到后端的 API 全部都要更改, 以 agent 市场为例, 包括以下部分:

  1. agent index discovery url, 用来告诉前端我们这边有几个市场
  2. agent index url, 需要有 index, /api/market?locale=zh-CN&index=0
  3. agent json url, 需要 index /api/market/gen-z?locale=zh-CN&index=0
  4. 调取 index 部分的代码, 需要先发现有几个市场, 然后再挨个调取市场
  5. 市场的 index 下载后, 需要在前端做好标记, 如 gen-z 是 社区市场的, url 形如 /market?agent=gen-z&index=0

如果说不更改接口的 url 和返回体, 那就是后端来拼合两个 index url, 而请求具体的 agent json 时, 是逐个 fallback, 首先拼合这个方案就不太优雅, 再有就是 fallback 方案可能会有一些不必要的请求, 甚至还有一些隐私方面的潜在问题.

所以综合考虑下来, 工程量还是比我想得大的, 看看有什么建议, 有什么更好的方案?

lobehubbot commented 8 months ago

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


After carefully looking at the code, the implementation method here is not too elegant or simple. If the two index URLs are divided into N interfaces, and the front end requests them separately, the changes are quite big, from the front-end service to the back-end API. Changes, taking the agent market as an example, include the following parts:

  1. agent index discovery url, used to tell the front-end how many markets we have here
  2. agent index url, requires index, /api/market?locale=zh-CN&index=0
  3. agent json url, requires index /api/market/gen-z?locale=zh-CN&index=0
  4. To retrieve the code in the index part, you need to first find out how many markets there are, and then retrieve the markets one by one.
  5. After the market index is downloaded, it needs to be marked on the front end. For example, gen-z is for the community market, and the url is in the form of /market?agent=gen-z&index=0

If the url and return body of the interface are not changed, then the backend has to combine the two index urls, and when requesting the specific agent json, it will fallback one by one. First of all, it is not very elegant to combine this solution, and then the fallback solution may There are some unnecessary requests and even some potential privacy issues.

So after comprehensive consideration, the project volume is still larger than I thought. I would like to see if you have any suggestions. Is there any better solution?

arvinxx commented 8 months ago
  1. 可能不需要一个专门的接口来检查有多少个市场,直接拉列表我觉得就可以,在index列表里直接合并所有市场的助手
  2. 我建议的改造思路是在返回 list 列表的时候,给所有 item 加一个市场 id,这样请求单个助手时就可以先找到市场,然后再请求市场中的助手
  3. 可以考虑在市场索引层面加一个构造请求单个助手的正则,因为现在我们的开源版是从无数据库角度出发的全量静态文件,而其他部署场景下可能会有数据库,因此不同市场的请求单个助手的方式说不定会有区别,构造url的逻辑可能也不同。
lobehubbot commented 8 months ago

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


  1. You may not need a special interface to check how many markets there are. I think it is enough to directly pull up the list, and directly merge all market assistants in the index list.
  2. The transformation idea I suggest is to add a market id to all items when returning the list, so that when requesting a single assistant, you can first find the market, and then request the assistant in the market.
  3. You can consider adding a regular structure to request a single assistant at the market index level, because now we have all static files from the perspective of no database, and other deployment scenarios may have databases, so different markets have different ways of requesting a single assistant. Maybe there will be a difference, and the logic of constructing the URL may also be different.