Compare commits

...

10 Commits

Author SHA1 Message Date
Archer
cf7145ab54 System plugin (#2091)
* System template (#2082)

* feat: system plugin (#2024)

* add plugin cost & change plugin avatar (#2030)

* add plugin cost & change plugin avatar

* add author

* feat: duckduckgo plugin

* duckduck search

* perf: templates select system plugin

* perf: system plugin avatar

* feat: duckduck plugins

* doc

* perf: plugin classify

* perf: icon avatar component

* perf: system template avatar

---------

Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>

* feat: system plugin search

* perf: plugin packages important

* perf: source avatar

* nextconfig

* perf: i18n

* perf: default model

* perf: system plugin author

---------

Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>
2024-07-19 14:15:01 +08:00
Carson Yang
1eedb9caba Update workflow to change baseurl for cn site (#2081)
* Docs: fix gitinfo

Signed-off-by: Carson Yang <yangchuansheng33@gmail.com>

* Update workflow to change baseurl for cn site

Signed-off-by: Carson Yang <yangchuansheng33@gmail.com>

---------

Signed-off-by: Carson Yang <yangchuansheng33@gmail.com>
2024-07-18 12:15:03 +08:00
heheer
6390d64417 fix: delete plugin output node check filter (#2080) 2024-07-18 10:44:13 +08:00
Archer
3d80eb288b lock (#2079) 2024-07-18 10:13:47 +08:00
Archer
5cb196535f 4.8.7 fix (#2076) 2024-07-17 19:06:37 +08:00
jingyang
982325d066 fix i18next.d.ts (#2064)
* fix i18next.d.ts

* feat: packages web i18n

* delete file
2024-07-17 15:27:51 +08:00
Archer
36f8755d09 lock (#2063)
* lock

* perf: init data

* perf: vision model url

* fix: chat index
2024-07-17 00:16:57 +08:00
jingyang
fc96bb99cc feat: optimize i18n implementation for better localization (#2062)
* feat: optimize i18n implementation for better localization

* delete i18n-ally-custom-framework.yml

* update common key
2024-07-16 17:56:27 +08:00
papapatrick
1e4ffc2481 docs: 完善本地开发教程 (#2061) 2024-07-16 17:38:11 +08:00
Archer
ee7496467b 4.8.7 test (#2058)
* fix: query extension id;App page change type invalid

* prettier
2024-07-16 16:55:12 +08:00
377 changed files with 5194 additions and 3232 deletions

View File

@@ -16,6 +16,9 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Change baseURL
run: sed -i 's|^baseURL =.*|baseURL = "https://doc.fastgpt.cn"|g' ./docSite/hugo.toml
- name: Get current date and time
id: datetime
run: echo "datetime=$(date +'%Y%m%d%H%M%S')" >> "$GITHUB_OUTPUT"

View File

@@ -1,46 +0,0 @@
# .vscode/i18n-ally-custom-framework.yml
# An array of strings which contain Language Ids defined by VS Code
# You can check available language ids here: https://code.visualstudio.com/docs/languages/identifiers
languageIds:
- javascript
- typescript
- javascriptreact
- typescriptreact
# An array of RegExes to find the key usage. **The key should be captured in the first match group**.
# You should unescape RegEx strings in order to fit in the YAML file
# To help with this, you can use https://www.freeformatter.com/json-escape.html
usageMatchRegex:
# The following example shows how to detect `t("your.i18n.keys")`
# the `{key}` will be placed by a proper keypath matching regex,
# you can ignore it and use your own matching rules as well
- "[^\\w\\d]t\\(['\"`]({key})['\"`]"
- "[^\\w\\d]commonT\\(['\"`]({key})['\"`]"
# 支持 appT("your.i18n.keys")
- "[^\\w\\d]appT\\(['\"`]({key})['\"`]"
# 支持 datasetT("your.i18n.keys")
- "[^\\w\\d]datasetT\\(['\"`]({key})['\"`]"
- "[^\\w\\d]fileT\\(['\"`]({key})['\"`]"
- "[^\\w\\d]publishT\\(['\"`]({key})['\"`]"
- "[^\\w\\d]workflowT\\(['\"`]({key})['\"`]"
- "[^\\w\\d]userT\\(['\"`]({key})['\"`]"
- "[^\\w\\d]chatT\\(['\"`]({key})['\"`]"
# A RegEx to set a custom scope range. This scope will be used as a prefix when detecting keys
# and works like how the i18next framework identifies the namespace scope from the
# useTranslation() hook.
# You should unescape RegEx strings in order to fit in the YAML file
# To help with this, you can use https://www.freeformatter.com/json-escape.html
scopeRangeRegex: "useTranslation\\(\\s*\\[?\\s*['\"`](.*?)['\"`]"
# An array of strings containing refactor templates.
# The "$1" will be replaced by the keypath specified.
# Optional: uncomment the following two lines to use
# refactorTemplates:
# - i18n.get("$1")
# If set to true, only enables this custom framework (will disable all built-in frameworks)
monopoly: true

View File

@@ -7,11 +7,18 @@
"i18n-ally.localesPaths": [
"packages/web/i18n",
],
"i18n-ally.enabledParsers": ["json", "yaml", "js", "ts"],
"i18n-ally.enabledParsers": [
"json",
"yaml",
"js",
"ts"
],
"i18n-ally.keystyle": "nested",
"i18n-ally.sortKeys": true,
"i18n-ally.keepFulfilled": false,
"i18n-ally.sourceLanguage": "zh", // 根据此语言文件翻译其他语言文件的变量和内容
"i18n-ally.displayLanguage": "zh", // 显示语言
"i18n-ally.namespace": true,
"i18n-ally.pathMatcher": "{locale}/{namespaces}.json",
"i18n-ally.extract.targetPickingStrategy": "most-similar-by-key"
}

View File

@@ -11,7 +11,6 @@ weight: 707
![](/imgs/sealos-fastgpt.webp)
{{% alert icon="🤖" context="success" %}}
- MongoDB用于存储除了向量外的各类数据
@@ -105,13 +104,11 @@ brew install orbstack
{{< /tab >}}
{{< /tabs >}}
## 开始部署
### 1. 下载 docker-compose.yml
非 Linux 环境或无法访问外网环境,可手动创建一个目录,并下载配置文件和对应版本的`docker-compose.yml`
非 Linux 环境或无法访问外网环境,可手动创建一个目录,并下载配置文件和对应版本的`docker-compose.yml`在这个文件夹中依据下载的配置文件运行docker若作为本地开发使用推荐`docker-compose-pgvector`版本,并且自行拉取并运行`sandbox``fastgpt`并在docker配置文件中注释掉`sandbox``fastgpt`的部分
- [config.json](https://github.com/labring/FastGPT/blob/main/projects/app/data/config.json)
- [docker-compose.yml](https://github.com/labring/FastGPT/blob/main/files/docker) (注意,不同向量库版本的文件不一样)
@@ -271,7 +268,6 @@ rs.status()
默认是写了OneAPi的连接地址和密钥可以通过修改`docker-compose.yml`fastgpt容器的环境变量实现。
`OPENAI_BASE_URL`API 接口的地址,需要加/v1
`CHAT_API_KEY`API 接口的凭证)。
@@ -315,8 +311,7 @@ docker-compose up -d
1. `docker exec -it fastgpt sh` 进入 FastGPT 容器。
2. 直接输入`env`命令查看所有环境变量。
### 为什么无法连接`本地模型`镜像。
### 为什么无法连接`本地模型`镜像
`docker-compose.yml`中使用了桥接的模式建立了`fastgpt`网络如想通过0.0.0.0或镜像名访问其它镜像,需将其它镜像也加入到网络中。
@@ -368,8 +363,8 @@ mongo连接失败查看mongo的运行状态**对应日志**。
由于服务初始化错误,系统重启导致。
* 90%是由于配置文件写不对,导致 JSON 解析报错
* 剩下的基本是因为向量数据库连不上
- 90%是由于配置文件写不对,导致 JSON 解析报错
- 剩下的基本是因为向量数据库连不上
### 如何修改密码

View File

@@ -7,8 +7,7 @@ toc: true
weight: 705
---
本文档介绍了如何设置开发环境以构建和测试 [FastGPT](https://fastgpt.in)。
本文档介绍了如何设置开发环境以构建和测试 [FastGPT](https://fastgpt.in)
## 前置依赖项
@@ -16,13 +15,14 @@ weight: 705
- [Git](http://git-scm.com/)
- [Docker](https://www.docker.com/)(构建镜像)
- [Node.js v18.17 / v20.x](http://nodejs.org)
- [Node.js v18.17 / v20.x](http://nodejs.org)版本尽量一样可以使用nvm管理node版本
- [pnpm](https://pnpm.io/) 版本 8.6.0 (目前官方的开发环境)
- make命令: 根据不同平台,百度安装 (官方是GNU Make 4.3)
## 开始本地开发
{{% alert context="success" %}}
1. 用户默认的时区为 `Asia/Shanghai`,非 linux 环境时候,获取系统时间会异常,本地开发时候,可以将用户的时区调整成 UTC+0
2. 建议先服务器装好**数据库**,再进行本地开发。
{{% /alert %}}
@@ -47,9 +47,10 @@ git clone git@github.com:<github_username>/FastGPT.git
### 3. 安装数据库
第一次开发,需要先部署数据库,建议本地开发可以随便找一台 2C2G 的轻量小数据库实践。数据库部署教程:[Docker 快速部署](/docs/development/docker/)。部署完了,可以本地访问其数据库。
第一次开发,需要先部署数据库,建议本地开发可以随便找一台 2C2G 的轻量小数据库实践或者新建文件夹并配置相关文件用以运行docker。数据库部署教程:[Docker 快速部署](/docs/development/docker/)。部署完了,可以本地访问其数据库。
{{% alert context="warning" %}}
Mongo 数据库需要注意,需要注意在连接地址中增加 `directConnection=true` 参数,才能连接上副本集的数据库。
{{% /alert %}}
### 4. 初始配置
@@ -57,7 +58,7 @@ Mongo 数据库需要注意,需要注意在连接地址中增加 `directConnec
**1. 环境变量**
复制`.env.template`文件,在同级目录下生成一个`.env.local` 文件,修改`.env.local` 里内容才是有效的变量。变量说明见 .env.template
复制`.env.template`文件,在同级目录下生成一个`.env.local` 文件,修改`.env.local` 里内容才是有效的变量。变量说明见 .env.template,主要需要修改`API_KEY`和数据库的地址与端口以及数据库账号的用户名和密码具体配置需要和docker配置文件相同其中用户名和密码如需修改需要修改docker配置文件、数据库和`.env.local`文件,不能只改一处。
**2. config 配置文件**
@@ -73,7 +74,7 @@ Mongo 数据库需要注意,需要注意在连接地址中增加 `directConnec
### 5. 运行
可参考项目根目录下的 `dev.md`
可参考项目根目录下的 `dev.md`,第一次编译运行可能会有点慢,需要点耐心哦
```bash
# 给自动化脚本代码执行权限(非 linux 系统, 可以手动执行里面的 postinstall.sh 文件内容)
@@ -114,7 +115,6 @@ make build name=app image=registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8
如果遇到问题,比如合并冲突或不知道如何打开拉取请求,请查看 GitHub 的[拉取请求教程](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests),了解如何解决合并冲突和其他问题。一旦您的 PR 被合并,您将自豪地被列为[贡献者表](https://github.com/labring/FastGPT/graphs/contributors)中的一员。
## QA
### 本地数据库无法连接
@@ -130,6 +130,7 @@ make build name=app image=registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8
FastGPT 在`pnpm i`后会执行`postinstall`脚本,用于自动生成`ChakraUI``Type`。如果没有权限,可以先执行`chmod -R +x ./scripts/`,再执行`pnpm i`
仍不可行的话,可以手动执行`./scripts/postinstall.sh`里的内容。
*如果是Windows下的话可以使用git bash给`postinstall`脚本添加执行权限并执行sh脚本*
### TypeError: Cannot read properties of null (reading 'useMemo' )
@@ -141,6 +142,9 @@ FastGPT 在`pnpm i`后会执行`postinstall`脚本,用于自动生成`ChakraUI
4. `cd projects/app`
5. `pnpm dev`
### Error response from daemon: error while creating mount source path 'XXX': mkdir XXX: file exists
这个错误可能是之前停止容器时有文件残留导致的首先需要确认相关镜像都全部关闭然后手动删除相关文件或者重启docker即可
## 加入社区
@@ -155,6 +159,7 @@ FastGPT 在`pnpm i`后会执行`postinstall`脚本,用于自动生成`ChakraUI
FastGPT 使用了 nextjs 的 page route 作为框架。为了区分好前后端代码,在目录分配上会分成 global, service, web 3个自目录分别对应着 `前后端共用``后端专用``前端专用`的代码。
### monorepo
FastGPT 采用 pnpm workspace 方式构建 monorepo 项目,主要分为两个部分:
- projects/app - FastGPT 主项目
@@ -173,6 +178,7 @@ support - 支撑功能(用户体系,计费,鉴权等)
common - 基础功能(日志管理,文件读写等)
{{% details title="代码结构说明" closed="true" %}}
```
.
├── .github // github 相关配置
@@ -200,4 +206,5 @@ common - 基础功能(日志管理,文件读写等)
├── README_ja.md
├── dev.md
```
{{% /details %}}

View File

@@ -77,7 +77,7 @@ docker-compose up -d
商业版用户需要执行一个初始化,格式化团队信息。
发起 1 个 HTTP 请求 ({{rootkey}} 替换成环境变量里的 `rootkey`{{host}} 替换成自己域名)
发起 1 个 HTTP 请求 ({{rootkey}} 替换成环境变量里的 `rootkey`{{host}} 替换成商业版域名)
```bash
curl --location --request POST 'https://{{host}}/api/init/v468' \

View File

@@ -1,5 +1,5 @@
---
title: 'V4.8.7(进行中)'
title: 'V4.8.7'
description: 'FastGPT V4.8.7 更新说明'
icon: 'upgrade'
draft: false
@@ -13,8 +13,8 @@ weight: 817
### 2. 修改镜像
- fastgpt 镜像 tag 修改成 v4.8.7-alpha
- 商业版镜像 tag 修改成 v4.8.7-alpha
- fastgpt 镜像 tag 修改成 v4.8.7
- 商业版镜像 tag 修改成 v4.8.7
-------
@@ -24,4 +24,6 @@ weight: 817
2. 新增 - 应用搜索
3. 优化 - 对话框代码
4. 优化 - 升级 Dockerfile node 和 pnpm 版本
5. 修复 - 简易模式无法变更全局变量
5. 优化 - local 域名部署,也可以正常使用 vision 模式
6. 修复 - 简易模式无法变更全局变量
7. 修复 - gpt4o 无法同时使用工具和图片

View File

@@ -0,0 +1,25 @@
---
title: 'V4.8.8(进行中)'
description: 'FastGPT V4.8.8 更新说明'
icon: 'upgrade'
draft: false
toc: true
weight: 816
---
## 升级指南
### 1. 做好数据库备份
### 2. 修改镜像
- fastgpt 镜像 tag 修改成 v4.8.8-alpha
- 商业版镜像 tag 修改成 v4.8.8-alpha
-------
## V4.8. 8 更新说明
1. 新增 - 重构系统插件的结构。允许向开源社区 PR 系统插件,具体可见: [如何向 FastGPT 社区提交系统插件](https://fael3z0zfze.feishu.cn/wiki/ERZnw9R26iRRG0kXZRec6WL9nwh)。欢迎
2. 新增 - DuckDuckGo 系统插件。
3. 优化 - 节点图标。

View File

@@ -5,6 +5,7 @@ enableEmoji = true
enableGitInfo = false # N.B. .GitInfo does not currently function with git submodule content directories
defaultContentLanguage = 'zh-cn'
defaultContentLanguageInSubdir = false
[languages]
[languages.zh-cn]
title = "FastGPT"

View File

@@ -15,7 +15,7 @@
{{ end }}
<!-- change -->
{{ $repoURL = $repoURL | append "docSite/content" .Site.LanguagePrefix $filePath }}
{{ $repoURL = $repoURL | append "docSite/content" .Site.Language.Lang $filePath }}
{{ $repoURL = delimit $repoURL "/" }}
{{ $editPageURL := replaceRE "(https?://)|(/)+" "$1$2" $repoURL }}

View File

@@ -121,8 +121,8 @@ services:
restart: always
fastgpt:
container_name: fastgpt
image: ghcr.io/labring/fastgpt:v4.8.6 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.6 # 阿里云
image: ghcr.io/labring/fastgpt:v4.8.7 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.7 # 阿里云
ports:
- 3000:3000
networks:

View File

@@ -79,8 +79,8 @@ services:
restart: always
fastgpt:
container_name: fastgpt
image: ghcr.io/labring/fastgpt:v4.8.6 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.6 # 阿里云
image: ghcr.io/labring/fastgpt:v4.8.7 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.7 # 阿里云
ports:
- 3000:3000
networks:

View File

@@ -60,8 +60,8 @@ services:
restart: always
fastgpt:
container_name: fastgpt
image: ghcr.io/labring/fastgpt:v4.8.6 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.6 # 阿里云
image: ghcr.io/labring/fastgpt:v4.8.7 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.7 # 阿里云
ports:
- 3000:3000
networks:

View File

@@ -14,11 +14,11 @@
"devDependencies": {
"@chakra-ui/cli": "^2.4.1",
"husky": "^8.0.3",
"i18next": "23.10.0",
"lint-staged": "^13.3.0",
"next-i18next": "15.2.0",
"i18next": "23.11.5",
"next-i18next": "15.3.0",
"react-i18next": "14.1.2",
"prettier": "3.2.4",
"react-i18next": "13.5.0",
"zhlint": "^0.7.4"
},
"lint-staged": {
@@ -29,4 +29,4 @@
"node": ">=18.16.0",
"pnpm": ">=9.0.0"
}
}
}

View File

@@ -32,9 +32,12 @@ export type FastGPTFeConfigsType = {
show_promotion?: boolean;
show_team_chat?: boolean;
concatMd?: string;
docUrl?: string;
chatbotUrl?: string;
openAPIDocUrl?: string;
systemPluginCourseUrl?: string;
systemTitle?: string;
systemDescription?: string;
googleClientVerKey?: string;
@@ -70,9 +73,3 @@ export type SystemEnvType = {
oneapiUrl?: string;
chatApiKey?: string;
};
// declare global {
// var feConfigs: FastGPTFeConfigsType;
// var systemEnv: SystemEnvType;
// var systemInitd: boolean;
// }

View File

@@ -2,8 +2,8 @@ import type { LLMModelItemType, VectorModelItemType } from './model.d';
export const defaultQAModels: LLMModelItemType[] = [
{
model: 'gpt-3.5-turbo',
name: 'gpt-3.5-turbo',
model: 'gpt-4o-mini',
name: 'gpt-4o-mini',
maxContext: 16000,
maxResponse: 16000,
quoteMaxToken: 13000,

View File

@@ -8,7 +8,7 @@ import { DatasetSearchModeEnum } from '../dataset/constants';
export const getDefaultAppForm = (): AppSimpleEditFormType => ({
aiSettings: {
model: 'gpt-3.5-turbo',
model: 'gpt-4o-mini',
systemPrompt: '',
temperature: 0,
isResponseAnswerText: true,

View File

@@ -56,7 +56,4 @@ export enum ChatStatusEnum {
finish = 'finish'
}
export const IMG_BLOCK_KEY = 'img-block';
export const FILE_BLOCK_KEY = 'file-block';
export const MARKDOWN_QUOTE_SIGN = 'QUOTE SIGN';

View File

@@ -32,7 +32,7 @@ export type PluginItemSchema = {
export type PluginTemplateType = PluginRuntimeType & {
author?: string;
id: string;
source: `${PluginSourceEnum}`;
source: PluginSourceEnum;
templateType: FlowNodeTemplateType['templateType'];
intro: string;
version: string;

View File

@@ -4,6 +4,9 @@ export enum FlowNodeTemplateTypeEnum {
function = 'function',
tools = 'tools',
search = 'search',
multimodal = 'multimodal',
other = 'other',
teamApp = 'teamApp'
}

View File

@@ -67,11 +67,12 @@ export type RuntimeNodeItemType = {
};
export type PluginRuntimeType = {
id: string;
teamId?: string;
name: string;
avatar: string;
showStatus?: boolean;
isTool?: boolean;
currentCost?: number;
nodes: StoreNodeItemType[];
edges: StoreEdgeItemType[];
};

View File

@@ -26,7 +26,7 @@ export const AiChatModule: FlowNodeTemplateType = {
flowNodeType: FlowNodeTypeEnum.chatNode,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/AI.png',
avatar: 'core/workflow/template/aiChat',
name: 'AI 对话',
intro: 'AI 大模型对话',
showStatus: true,

View File

@@ -13,7 +13,7 @@ export const AssignedAnswerModule: FlowNodeTemplateType = {
flowNodeType: FlowNodeTypeEnum.answerNode,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/reply.png',
avatar: 'core/workflow/template/reply',
name: '指定回复',
intro:
'该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。',

View File

@@ -25,7 +25,7 @@ export const ClassifyQuestionModule: FlowNodeTemplateType = {
flowNodeType: FlowNodeTypeEnum.classifyQuestion,
sourceHandle: getHandleConfig(false, false, false, false),
targetHandle: getHandleConfig(true, false, true, true),
avatar: '/imgs/workflow/cq.png',
avatar: 'core/workflow/template/questionClassify',
name: '问题分类',
intro: `根据用户的历史记录和当前问题判断该次提问的类型。可以添加多组问题类型,下面是一个模板例子:\n类型1: 打招呼\n类型2: 关于商品“使用”问题\n类型3: 关于商品“购买”问题\n类型4: 其他问题`,
showStatus: true,

View File

@@ -20,7 +20,7 @@ export const ContextExtractModule: FlowNodeTemplateType = {
flowNodeType: FlowNodeTypeEnum.contentExtract,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/extract.png',
avatar: 'core/workflow/template/extractJson',
name: '文本内容提取',
intro: '可从文本中提取指定的数据例如sql语句、搜索关键词、代码等',
showStatus: true,

View File

@@ -13,7 +13,7 @@ export const CustomFeedbackNode: FlowNodeTemplateType = {
flowNodeType: FlowNodeTypeEnum.customFeedback,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/customFeedback.svg',
avatar: 'core/workflow/template/customFeedback',
name: '自定义反馈',
intro: '该模块被触发时,会给当前的对话记录增加一条反馈。可用于自动记录对话效果等。',
version: '486',

View File

@@ -37,7 +37,7 @@ export const DatasetConcatModule: FlowNodeTemplateType = {
templateType: FlowNodeTemplateTypeEnum.other,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/concat.svg',
avatar: 'core/workflow/template/datasetConcat',
name: '知识库搜索引用合并',
intro: '可以将多个知识库搜索结果进行合并输出。使用 RRF 的合并方式进行最终排序输出。',
showStatus: false,

View File

@@ -23,7 +23,7 @@ export const DatasetSearchModule: FlowNodeTemplateType = {
flowNodeType: FlowNodeTypeEnum.datasetSearchNode,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/db.png',
avatar: 'core/workflow/template/datasetSearch',
name: '知识库搜索',
intro: Dataset_SEARCH_DESC,
showStatus: true,

View File

@@ -20,7 +20,7 @@ export const HttpNode468: FlowNodeTemplateType = {
flowNodeType: FlowNodeTypeEnum.httpRequest468,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/http.png',
avatar: 'core/workflow/template/httpRequest',
name: 'HTTP 请求',
intro: '可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)',
showStatus: true,

View File

@@ -18,7 +18,7 @@ export const IfElseNode: FlowNodeTemplateType = {
flowNodeType: FlowNodeTypeEnum.ifElseNode,
sourceHandle: getHandleConfig(false, false, false, false),
targetHandle: getHandleConfig(true, false, true, true),
avatar: '/imgs/workflow/ifElse.svg',
avatar: 'core/workflow/template/ifelse',
name: '判断器',
intro: '根据一定的条件,执行不同的分支。',
showStatus: true,

View File

@@ -26,7 +26,7 @@ export const LafModule: FlowNodeTemplateType = {
flowNodeType: FlowNodeTypeEnum.lafModule,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/laf.png',
avatar: 'core/workflow/template/lafDispatch',
name: 'Laf 函数调用(测试)',
intro: '可以调用Laf账号下的云函数。',
showStatus: true,

View File

@@ -11,7 +11,7 @@ export const PluginInputModule: FlowNodeTemplateType = {
targetHandle: getHandleConfig(false, false, false, false),
unique: true,
forbidDelete: true,
avatar: '/imgs/workflow/input.png',
avatar: 'core/workflow/template/workflowStart',
name: '插件输入',
intro: '可以配置插件需要哪些输入,利用这些输入来运行插件',
showStatus: false,

View File

@@ -11,7 +11,7 @@ export const PluginOutputModule: FlowNodeTemplateType = {
targetHandle: getHandleConfig(false, false, false, true),
unique: true,
forbidDelete: true,
avatar: '/imgs/workflow/output.png',
avatar: 'core/workflow/template/pluginOutput',
name: '自定义插件输出',
intro: '自定义配置外部输出,使用插件时,仅暴露自定义配置的输出',
showStatus: false,

View File

@@ -19,12 +19,12 @@ import { LLMModelTypeEnum } from '../../../ai/constants';
import { getHandleConfig } from '../utils';
export const AiQueryExtension: FlowNodeTemplateType = {
id: FlowNodeTypeEnum.chatNode,
id: FlowNodeTypeEnum.queryExtension,
templateType: FlowNodeTemplateTypeEnum.other,
flowNodeType: FlowNodeTypeEnum.queryExtension,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/cfr.svg',
avatar: 'core/workflow/template/queryExtension',
name: '问题优化',
intro:
'使用问题优化功能,可以提高知识库连续对话时搜索的精度。使用该功能后,会先利用 AI 根据上下文构建一个或多个新的检索词,这些检索词更利于进行知识库搜索。该模块已内置在知识库搜索模块中,如果您仅进行一次知识库搜索,可直接使用知识库内置的补全功能。',

View File

@@ -19,7 +19,7 @@ export const RunAppModule: FlowNodeTemplateType = {
flowNodeType: FlowNodeTypeEnum.runApp,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/app.png',
avatar: 'core/workflow/template/runApp',
name: '应用调用',
intro: '可以选择一个其他应用进行调用',
showStatus: true,

View File

@@ -21,7 +21,7 @@ export const CodeNode: FlowNodeTemplateType = {
flowNodeType: FlowNodeTypeEnum.code,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/code.svg',
avatar: 'core/workflow/template/codeRun',
name: '代码运行',
intro: '执行一段简单的脚本代码,通常用于进行复杂的数据处理。',
showStatus: true,

View File

@@ -9,7 +9,7 @@ export const StopToolNode: FlowNodeTemplateType = {
flowNodeType: FlowNodeTypeEnum.stopTool,
sourceHandle: getHandleConfig(false, false, false, false),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/toolStop.svg',
avatar: 'core/workflow/template/stopTool',
name: '工具调用终止',
intro:
'该模块需配置工具调用使用。当该模块被执行时本次工具调用将会强制结束并且不再调用AI针对工具调用结果回答问题。',

View File

@@ -9,7 +9,7 @@ export const SystemConfigNode: FlowNodeTemplateType = {
flowNodeType: FlowNodeTypeEnum.systemConfig,
sourceHandle: getHandleConfig(false, false, false, false),
targetHandle: getHandleConfig(false, false, false, false),
avatar: '/imgs/workflow/userGuide.png',
avatar: 'core/workflow/template/systemConfig',
name: '系统配置',
intro: '可以配置应用的系统参数。',
unique: true,

View File

@@ -19,7 +19,7 @@ export const TextEditorNode: FlowNodeTemplateType = {
flowNodeType: FlowNodeTypeEnum.textEditor,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/textEditor.svg',
avatar: 'core/workflow/template/textConcat',
name: '文本拼接',
intro: '可对固定或传入的文本进行加工后输出,非字符串类型数据最终会转成字符串类型。',
version: '486',

View File

@@ -26,7 +26,7 @@ export const ToolModule: FlowNodeTemplateType = {
templateType: FlowNodeTemplateTypeEnum.ai,
sourceHandle: getHandleConfig(true, true, false, true),
targetHandle: getHandleConfig(true, true, false, true),
avatar: '/imgs/workflow/tool.svg',
avatar: 'core/workflow/template/toolCall',
name: '工具调用',
intro: '通过AI模型自动选择一个或多个功能块进行调用也可以对插件进行调用。',
showStatus: true,

View File

@@ -13,7 +13,7 @@ export const VariableUpdateNode: FlowNodeTemplateType = {
flowNodeType: FlowNodeTypeEnum.variableUpdate,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/variable.png',
avatar: 'core/workflow/template/variableUpdate',
name: '变量更新',
intro: '可以更新指定节点的输出值或更新全局变量',
showStatus: false,

View File

@@ -14,7 +14,7 @@ export const WorkflowStart: FlowNodeTemplateType = {
flowNodeType: FlowNodeTypeEnum.workflowStart,
sourceHandle: getHandleConfig(false, true, false, false),
targetHandle: getHandleConfig(false, false, false, false),
avatar: '/imgs/workflow/userChatInput.svg',
avatar: 'core/workflow/template/workflowStart',
name: '流程开始',
intro: '',
forbidDelete: true,

View File

@@ -42,17 +42,29 @@ export type WorkflowTemplateType = {
workflow: WorkflowTemplateBasicType;
};
// template market
export type TemplateMarketItemType = WorkflowTemplateType & {
tags?: { id: string; label: string }[];
};
// system plugin
export type SystemPluginTemplateItemType = WorkflowTemplateType & {
templateType: FlowNodeTemplateTypeEnum;
isTool?: boolean;
// commercial plugin config
originCost: number; // n points/one time
currentCost: number;
isActive?: boolean;
inputConfig?: {
// Render config input form. Find the corresponding node and replace the variable directly
key: string;
label: string;
description: string;
value?: any;
}[];
workflow: WorkflowTemplateBasicType;
};

View File

@@ -70,7 +70,7 @@ export type FlowNodeTemplateType = FlowNodeCommonType & {
export type NodeTemplateListItemType = {
id: string; // 系统节点-系统节点的 id 系统插件-插件的 id团队应用的 id
flowNodeType: FlowNodeTypeEnum; // render node card
parentId?: string;
parentId?: ParentIdType;
isFolder?: boolean;
templateType: FlowNodeTemplateTypeEnum;
avatar?: string;
@@ -79,6 +79,7 @@ export type NodeTemplateListItemType = {
isTool?: boolean;
author?: string;
unique?: boolean; // 唯一的
currentCost?: number; // 当前积分消耗
};
export type NodeTemplateListType = {

View File

@@ -10,13 +10,13 @@
"js-yaml": "^4.1.0",
"jschardet": "3.1.1",
"nanoid": "^4.0.1",
"next": "14.2.3",
"next": "14.2.5",
"openai": "4.28.0",
"openapi-types": "^12.1.3",
"timezones-list": "^3.0.2"
},
"devDependencies": {
"@types/js-yaml": "^4.0.9",
"@types/node": "^20.14.2"
"@types/node": "20.14.0"
}
}

View File

@@ -2,11 +2,14 @@
"name": "@fastgpt/plugins",
"version": "1.0.0",
"dependencies": {
"duck-duck-scrape": "^2.2.5",
"lodash": "^4.17.21",
"expr-eval": "^2.0.2"
},
"devDependencies": {
"@fastgpt/global": "workspace:*",
"@fastgpt/service": "workspace:*",
"@types/node": "^20.14.2"
"@types/lodash": "^4.14.191",
"@types/node": "20.14.0"
}
}

View File

@@ -1,57 +1,126 @@
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
import { FlowNodeTemplateTypeEnum } from '@fastgpt/global/core/workflow/constants';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { SystemPluginResponseType } from './type';
import { NodeTemplateListItemType } from '@fastgpt/global/core/workflow/type/node';
import { isProduction } from '../service/common/system/constants';
import { FastGPTProUrl, isProduction } from '../service/common/system/constants';
import { GET, POST } from '@fastgpt/service/common/api/plusRequest';
import { SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type';
import { cloneDeep } from 'lodash';
let list = ['getTime', 'fetchUrl', 'mathExprVal'];
let list = [
'getTime',
'fetchUrl',
'mathExprVal',
'duckduckgo',
'duckduckgo/search',
'duckduckgo/searchImg',
'duckduckgo/searchNews',
'duckduckgo/searchVideo'
];
/* Get plugins */
export const getCommunityPlugins = () => {
if (isProduction && global.communitySystemPlugins) return global.communitySystemPlugins;
return list.map<SystemPluginTemplateItemType>((name) => {
const config = require(`./src/${name}/template.json`);
global.communitySystemPlugins = list.map((name) => ({
...require(`./src/${name}/template.json`),
id: `${PluginSourceEnum.community}-${name}`
}));
const isFolder = list.find((item) => item.startsWith(`${name}/`));
return global.communitySystemPlugins;
const parentIdList = name.split('/').slice(0, -1);
const parentId =
parentIdList.length > 0 ? `${PluginSourceEnum.community}-${parentIdList.join('/')}` : null;
return {
...config,
id: `${PluginSourceEnum.community}-${name}`,
isFolder,
parentId,
isActive: true
};
});
};
const getCommercialPlugins = () => {
return GET<SystemPluginTemplateItemType[]>('/core/app/plugin/getSystemPlugins');
};
export const getSystemPluginTemplates = async (refresh = false) => {
if (isProduction && global.systemPlugins && !refresh) return cloneDeep(global.systemPlugins);
export const getCommunityPluginsTemplateList = () => {
return getCommunityPlugins().map<NodeTemplateListItemType>((plugin) => ({
id: plugin.id,
templateType: plugin.templateType ?? FlowNodeTemplateTypeEnum.other,
flowNodeType: FlowNodeTypeEnum.pluginModule,
avatar: plugin.avatar,
name: plugin.name,
intro: plugin.intro,
isTool: plugin.isTool
}));
try {
if (!global.systemPlugins) {
global.systemPlugins = [];
}
global.systemPlugins = FastGPTProUrl ? await getCommercialPlugins() : getCommunityPlugins();
return cloneDeep(global.systemPlugins);
} catch (error) {
//@ts-ignore
global.systemPlugins = undefined;
return Promise.reject(error);
}
};
export const getCommunityCb = async () => {
if (isProduction && global.communitySystemPluginCb) return global.communitySystemPluginCb;
// Do not modify the following code
const loadModule = async (name: string) => {
const module = await import(`./src/${name}/index`);
return module.default;
};
const result = await Promise.all(
list.map(async (name) => ({
name,
cb: await loadModule(name)
}))
const result = (
await Promise.all(
list.map(async (name) => {
try {
return {
name,
cb: await loadModule(name)
};
} catch (error) {}
})
)
).filter(Boolean) as {
name: string;
cb: any;
}[];
return result.reduce<Record<string, (e: any) => SystemPluginResponseType>>(
(acc, { name, cb }) => {
acc[name] = cb;
return acc;
},
{}
);
global.communitySystemPluginCb = result.reduce<
Record<string, (e: any) => SystemPluginResponseType>
>((acc, { name, cb }) => {
acc[name] = cb;
return acc;
}, {});
return global.communitySystemPluginCb;
};
const getCommercialCb = async () => {
const plugins = await getSystemPluginTemplates();
const result = plugins.map((plugin) => {
const name = plugin.id.split('-')[1];
return {
name,
cb: (e: any) =>
POST<Record<string, any>>('/core/app/plugin/run', {
pluginName: name,
data: e
})
};
});
return result.reduce<Record<string, (e: any) => SystemPluginResponseType>>(
(acc, { name, cb }) => {
acc[name] = cb;
return acc;
},
{}
);
};
export const getSystemPluginCb = async () => {
if (isProduction && global.systemPluginCb) return global.systemPluginCb;
try {
global.systemPluginCb = {};
global.systemPluginCb = FastGPTProUrl ? await getCommercialCb() : await getCommunityCb();
return global.systemPluginCb;
} catch (error) {
//@ts-ignore
global.systemPluginCb = undefined;
return Promise.reject(error);
}
};

View File

@@ -0,0 +1,47 @@
import { search, SafeSearchType } from 'duck-duck-scrape';
import { delay } from '@fastgpt/global/common/system/utils';
import { addLog } from '@fastgpt/service/common/system/log';
type Props = {
query: string;
};
// Response type same as HTTP outputs
type Response = Promise<{
result: string;
}>;
const main = async (props: Props, retry = 3): Response => {
const { query } = props;
try {
const searchResults = await search(query, {
safeSearch: SafeSearchType.STRICT,
time: 'y'
});
const result = searchResults.results
.map((item) => ({
title: item.title,
link: item.url,
snippet: item.description
}))
.slice(0, 10);
return {
result: JSON.stringify(result)
};
} catch (error) {
if (retry <= 0) {
return {
result: 'Failed to fetch data'
};
}
addLog.warn('DuckDuckGo error', { error });
await delay(Math.random() * 2000);
return main(props, retry - 1);
}
};
export default main;

View File

@@ -0,0 +1,260 @@
{
"author": "",
"version": "486",
"name": "DuckDuckGo 网络搜索",
"avatar": "core/workflow/template/duckduckgo",
"intro": "使用 DuckDuckGo 进行网络搜索",
"showStatus": true,
"weight": 10,
"isTool": true,
"templateType": "search",
"workflow": {
"nodes": [
{
"nodeId": "pluginInput",
"name": "自定义插件输入",
"intro": "可以配置插件需要哪些输入,利用这些输入来运行插件",
"avatar": "/imgs/workflow/input.png",
"flowNodeType": "pluginInput",
"showStatus": false,
"position": {
"x": 393.68844551739926,
"y": -58.80666875994541
},
"version": "481",
"inputs": [
{
"renderTypeList": ["reference"],
"selectedTypeIndex": 0,
"valueType": "string",
"canEdit": true,
"key": "query",
"label": "query",
"description": "检索词",
"required": true,
"toolDescription": "检索词"
}
],
"outputs": [
{
"id": "query",
"valueType": "string",
"key": "query",
"label": "query",
"type": "hidden"
}
]
},
{
"nodeId": "pluginOutput",
"name": "自定义插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "/imgs/workflow/output.png",
"flowNodeType": "pluginOutput",
"showStatus": false,
"position": {
"x": 1795.6509902691012,
"y": -47.04550785550961
},
"version": "481",
"inputs": [
{
"renderTypeList": ["reference"],
"valueType": "string",
"canEdit": true,
"key": "result",
"label": "result",
"description": " 检索结果",
"value": ["hjnVuJAOwyXV", "lEyy5QqyIBrK"]
}
],
"outputs": []
},
{
"nodeId": "hjnVuJAOwyXV",
"name": "HTTP 请求",
"intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)",
"avatar": "/imgs/workflow/http.png",
"flowNodeType": "httpRequest468",
"showStatus": true,
"position": {
"x": 1054.6774638324207,
"y": -403.06127656499825
},
"version": "481",
"inputs": [
{
"key": "system_addInputParam",
"renderTypeList": ["addInputParam"],
"valueType": "dynamic",
"label": "",
"required": false,
"description": "core.module.input.description.HTTP Dynamic Input",
"customInputConfig": {
"selectValueTypeList": [
"string",
"number",
"boolean",
"object",
"arrayString",
"arrayNumber",
"arrayBoolean",
"arrayObject",
"any",
"chatHistory",
"datasetQuote",
"dynamic",
"selectApp",
"selectDataset"
],
"showDescription": false,
"showDefaultValue": true
}
},
{
"key": "system_httpMethod",
"renderTypeList": ["custom"],
"valueType": "string",
"label": "",
"value": "POST",
"required": true
},
{
"key": "system_httpReqUrl",
"renderTypeList": ["hidden"],
"valueType": "string",
"label": "",
"description": "core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory",
"required": false,
"value": "duckduckgo/search"
},
{
"key": "system_httpHeader",
"renderTypeList": ["custom"],
"valueType": "any",
"value": [],
"label": "",
"description": "core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header",
"required": false
},
{
"key": "system_httpParams",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false
},
{
"key": "system_httpJsonBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": "{\n \"query\": \"{{query}}\"\n}",
"label": "",
"required": false
},
{
"renderTypeList": ["reference"],
"valueType": "string",
"canEdit": true,
"key": "query",
"label": "query",
"customInputConfig": {
"selectValueTypeList": [
"string",
"number",
"boolean",
"object",
"arrayString",
"arrayNumber",
"arrayBoolean",
"arrayObject",
"any",
"chatHistory",
"datasetQuote",
"dynamic",
"selectApp",
"selectDataset"
],
"showDescription": false,
"showDefaultValue": true
},
"required": true,
"value": ["pluginInput", "query"]
}
],
"outputs": [
{
"id": "system_addOutputParam",
"key": "system_addOutputParam",
"type": "dynamic",
"valueType": "dynamic",
"label": "",
"customFieldConfig": {
"selectValueTypeList": [
"string",
"number",
"boolean",
"object",
"arrayString",
"arrayNumber",
"arrayBoolean",
"arrayObject",
"any",
"chatHistory",
"datasetQuote",
"dynamic",
"selectApp",
"selectDataset"
],
"showDescription": false,
"showDefaultValue": false
}
},
{
"id": "error",
"key": "error",
"label": "请求错误",
"description": "HTTP请求错误信息成功时返回空",
"valueType": "object",
"type": "static"
},
{
"id": "httpRawResponse",
"key": "httpRawResponse",
"label": "原始响应",
"required": true,
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "static"
},
{
"id": "lEyy5QqyIBrK",
"valueType": "string",
"type": "dynamic",
"key": "result",
"label": "result"
}
]
}
],
"edges": [
{
"source": "pluginInput",
"target": "hjnVuJAOwyXV",
"sourceHandle": "pluginInput-source-right",
"targetHandle": "hjnVuJAOwyXV-target-left"
},
{
"source": "hjnVuJAOwyXV",
"target": "pluginOutput",
"sourceHandle": "hjnVuJAOwyXV-source-right",
"targetHandle": "pluginOutput-target-left"
}
]
}
}

View File

@@ -0,0 +1,46 @@
import { searchImages, SafeSearchType } from 'duck-duck-scrape';
import { delay } from '@fastgpt/global/common/system/utils';
import { addLog } from '@fastgpt/service/common/system/log';
type Props = {
query: string;
};
// Response type same as HTTP outputs
type Response = Promise<{
result: string;
}>;
const main = async (props: Props, retry = 3): Response => {
const { query } = props;
try {
const searchResults = await searchImages(query, {
safeSearch: SafeSearchType.STRICT
});
const result = searchResults.results
.map((item) => ({
title: item.title,
image: item.image
}))
.slice(0, 10);
return {
result: JSON.stringify(result)
};
} catch (error) {
if (retry <= 0) {
return {
result: 'Failed to fetch data'
};
}
addLog.warn('DuckDuckGo error', { error });
await delay(Math.random() * 2000);
return main(props, retry - 1);
}
};
export default main;

View File

@@ -0,0 +1,260 @@
{
"author": "",
"version": "486",
"name": "DuckDuckGo 图片搜索",
"avatar": "core/workflow/template/duckduckgo",
"intro": "使用 DuckDuckGo 进行图片搜索",
"showStatus": true,
"weight": 10,
"isTool": true,
"templateType": "search",
"workflow": {
"nodes": [
{
"nodeId": "pluginInput",
"name": "自定义插件输入",
"intro": "可以配置插件需要哪些输入,利用这些输入来运行插件",
"avatar": "/imgs/workflow/input.png",
"flowNodeType": "pluginInput",
"showStatus": false,
"position": {
"x": 393.68844551739926,
"y": -58.80666875994541
},
"version": "481",
"inputs": [
{
"renderTypeList": ["reference"],
"selectedTypeIndex": 0,
"valueType": "string",
"canEdit": true,
"key": "query",
"label": "query",
"description": "检索词",
"required": true,
"toolDescription": "检索词"
}
],
"outputs": [
{
"id": "query",
"valueType": "string",
"key": "query",
"label": "query",
"type": "hidden"
}
]
},
{
"nodeId": "pluginOutput",
"name": "自定义插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "/imgs/workflow/output.png",
"flowNodeType": "pluginOutput",
"showStatus": false,
"position": {
"x": 1795.6509902691012,
"y": -47.04550785550961
},
"version": "481",
"inputs": [
{
"renderTypeList": ["reference"],
"valueType": "string",
"canEdit": true,
"key": "result",
"label": "result",
"description": " 检索结果",
"value": ["hjnVuJAOwyXV", "lEyy5QqyIBrK"]
}
],
"outputs": []
},
{
"nodeId": "hjnVuJAOwyXV",
"name": "HTTP 请求",
"intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)",
"avatar": "/imgs/workflow/http.png",
"flowNodeType": "httpRequest468",
"showStatus": true,
"position": {
"x": 1054.6774638324207,
"y": -403.06127656499825
},
"version": "481",
"inputs": [
{
"key": "system_addInputParam",
"renderTypeList": ["addInputParam"],
"valueType": "dynamic",
"label": "",
"required": false,
"description": "core.module.input.description.HTTP Dynamic Input",
"customInputConfig": {
"selectValueTypeList": [
"string",
"number",
"boolean",
"object",
"arrayString",
"arrayNumber",
"arrayBoolean",
"arrayObject",
"any",
"chatHistory",
"datasetQuote",
"dynamic",
"selectApp",
"selectDataset"
],
"showDescription": false,
"showDefaultValue": true
}
},
{
"key": "system_httpMethod",
"renderTypeList": ["custom"],
"valueType": "string",
"label": "",
"value": "POST",
"required": true
},
{
"key": "system_httpReqUrl",
"renderTypeList": ["hidden"],
"valueType": "string",
"label": "",
"description": "core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory",
"required": false,
"value": "duckduckgo/searchImg"
},
{
"key": "system_httpHeader",
"renderTypeList": ["custom"],
"valueType": "any",
"value": [],
"label": "",
"description": "core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header",
"required": false
},
{
"key": "system_httpParams",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false
},
{
"key": "system_httpJsonBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": "{\n \"query\": \"{{query}}\"\n}",
"label": "",
"required": false
},
{
"renderTypeList": ["reference"],
"valueType": "string",
"canEdit": true,
"key": "query",
"label": "query",
"customInputConfig": {
"selectValueTypeList": [
"string",
"number",
"boolean",
"object",
"arrayString",
"arrayNumber",
"arrayBoolean",
"arrayObject",
"any",
"chatHistory",
"datasetQuote",
"dynamic",
"selectApp",
"selectDataset"
],
"showDescription": false,
"showDefaultValue": true
},
"required": true,
"value": ["pluginInput", "query"]
}
],
"outputs": [
{
"id": "system_addOutputParam",
"key": "system_addOutputParam",
"type": "dynamic",
"valueType": "dynamic",
"label": "",
"customFieldConfig": {
"selectValueTypeList": [
"string",
"number",
"boolean",
"object",
"arrayString",
"arrayNumber",
"arrayBoolean",
"arrayObject",
"any",
"chatHistory",
"datasetQuote",
"dynamic",
"selectApp",
"selectDataset"
],
"showDescription": false,
"showDefaultValue": false
}
},
{
"id": "error",
"key": "error",
"label": "请求错误",
"description": "HTTP请求错误信息成功时返回空",
"valueType": "object",
"type": "static"
},
{
"id": "httpRawResponse",
"key": "httpRawResponse",
"label": "原始响应",
"required": true,
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "static"
},
{
"id": "lEyy5QqyIBrK",
"valueType": "string",
"type": "dynamic",
"key": "result",
"label": "result"
}
]
}
],
"edges": [
{
"source": "pluginInput",
"target": "hjnVuJAOwyXV",
"sourceHandle": "pluginInput-source-right",
"targetHandle": "hjnVuJAOwyXV-target-left"
},
{
"source": "hjnVuJAOwyXV",
"target": "pluginOutput",
"sourceHandle": "hjnVuJAOwyXV-source-right",
"targetHandle": "pluginOutput-target-left"
}
]
}
}

View File

@@ -0,0 +1,47 @@
import { searchNews, SafeSearchType } from 'duck-duck-scrape';
import { delay } from '@fastgpt/global/common/system/utils';
import { addLog } from '@fastgpt/service/common/system/log';
type Props = {
query: string;
};
// Response type same as HTTP outputs
type Response = Promise<{
result: string;
}>;
const main = async (props: Props, retry = 3): Response => {
const { query } = props;
try {
const searchResults = await searchNews(query, {
safeSearch: SafeSearchType.STRICT
});
const result = searchResults.results
.map((item) => ({
title: item.title,
excerpt: item.excerpt,
url: item.url
}))
.slice(0, 10);
return {
result: JSON.stringify(result)
};
} catch (error) {
if (retry <= 0) {
return {
result: 'Failed to fetch data'
};
}
addLog.warn('DuckDuckGo error', { error });
await delay(Math.random() * 2000);
return main(props, retry - 1);
}
};
export default main;

View File

@@ -0,0 +1,260 @@
{
"author": "",
"version": "486",
"name": "DuckDuckGo 新闻检索",
"avatar": "core/workflow/template/duckduckgo",
"intro": "使用 DuckDuckGo 进行新闻检索",
"showStatus": true,
"weight": 10,
"isTool": true,
"templateType": "search",
"workflow": {
"nodes": [
{
"nodeId": "pluginInput",
"name": "自定义插件输入",
"intro": "可以配置插件需要哪些输入,利用这些输入来运行插件",
"avatar": "/imgs/workflow/input.png",
"flowNodeType": "pluginInput",
"showStatus": false,
"position": {
"x": 393.68844551739926,
"y": -58.80666875994541
},
"version": "481",
"inputs": [
{
"renderTypeList": ["reference"],
"selectedTypeIndex": 0,
"valueType": "string",
"canEdit": true,
"key": "query",
"label": "query",
"description": "检索词",
"required": true,
"toolDescription": "检索词"
}
],
"outputs": [
{
"id": "query",
"valueType": "string",
"key": "query",
"label": "query",
"type": "hidden"
}
]
},
{
"nodeId": "pluginOutput",
"name": "自定义插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "/imgs/workflow/output.png",
"flowNodeType": "pluginOutput",
"showStatus": false,
"position": {
"x": 1795.6509902691012,
"y": -47.04550785550961
},
"version": "481",
"inputs": [
{
"renderTypeList": ["reference"],
"valueType": "string",
"canEdit": true,
"key": "result",
"label": "result",
"description": " 检索结果",
"value": ["hjnVuJAOwyXV", "lEyy5QqyIBrK"]
}
],
"outputs": []
},
{
"nodeId": "hjnVuJAOwyXV",
"name": "HTTP 请求",
"intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)",
"avatar": "/imgs/workflow/http.png",
"flowNodeType": "httpRequest468",
"showStatus": true,
"position": {
"x": 1054.6774638324207,
"y": -403.06127656499825
},
"version": "481",
"inputs": [
{
"key": "system_addInputParam",
"renderTypeList": ["addInputParam"],
"valueType": "dynamic",
"label": "",
"required": false,
"description": "core.module.input.description.HTTP Dynamic Input",
"customInputConfig": {
"selectValueTypeList": [
"string",
"number",
"boolean",
"object",
"arrayString",
"arrayNumber",
"arrayBoolean",
"arrayObject",
"any",
"chatHistory",
"datasetQuote",
"dynamic",
"selectApp",
"selectDataset"
],
"showDescription": false,
"showDefaultValue": true
}
},
{
"key": "system_httpMethod",
"renderTypeList": ["custom"],
"valueType": "string",
"label": "",
"value": "POST",
"required": true
},
{
"key": "system_httpReqUrl",
"renderTypeList": ["hidden"],
"valueType": "string",
"label": "",
"description": "core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory",
"required": false,
"value": "duckduckgo/searchNews"
},
{
"key": "system_httpHeader",
"renderTypeList": ["custom"],
"valueType": "any",
"value": [],
"label": "",
"description": "core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header",
"required": false
},
{
"key": "system_httpParams",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false
},
{
"key": "system_httpJsonBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": "{\n \"query\": \"{{query}}\"\n}",
"label": "",
"required": false
},
{
"renderTypeList": ["reference"],
"valueType": "string",
"canEdit": true,
"key": "query",
"label": "query",
"customInputConfig": {
"selectValueTypeList": [
"string",
"number",
"boolean",
"object",
"arrayString",
"arrayNumber",
"arrayBoolean",
"arrayObject",
"any",
"chatHistory",
"datasetQuote",
"dynamic",
"selectApp",
"selectDataset"
],
"showDescription": false,
"showDefaultValue": true
},
"required": true,
"value": ["pluginInput", "query"]
}
],
"outputs": [
{
"id": "system_addOutputParam",
"key": "system_addOutputParam",
"type": "dynamic",
"valueType": "dynamic",
"label": "",
"customFieldConfig": {
"selectValueTypeList": [
"string",
"number",
"boolean",
"object",
"arrayString",
"arrayNumber",
"arrayBoolean",
"arrayObject",
"any",
"chatHistory",
"datasetQuote",
"dynamic",
"selectApp",
"selectDataset"
],
"showDescription": false,
"showDefaultValue": false
}
},
{
"id": "error",
"key": "error",
"label": "请求错误",
"description": "HTTP请求错误信息成功时返回空",
"valueType": "object",
"type": "static"
},
{
"id": "httpRawResponse",
"key": "httpRawResponse",
"label": "原始响应",
"required": true,
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "static"
},
{
"id": "lEyy5QqyIBrK",
"valueType": "string",
"type": "dynamic",
"key": "result",
"label": "result"
}
]
}
],
"edges": [
{
"source": "pluginInput",
"target": "hjnVuJAOwyXV",
"sourceHandle": "pluginInput-source-right",
"targetHandle": "hjnVuJAOwyXV-target-left"
},
{
"source": "hjnVuJAOwyXV",
"target": "pluginOutput",
"sourceHandle": "hjnVuJAOwyXV-source-right",
"targetHandle": "pluginOutput-target-left"
}
]
}
}

View File

@@ -0,0 +1,47 @@
import { searchVideos, SafeSearchType } from 'duck-duck-scrape';
import { delay } from '@fastgpt/global/common/system/utils';
import { addLog } from '@fastgpt/service/common/system/log';
type Props = {
query: string;
};
// Response type same as HTTP outputs
type Response = Promise<{
result: string;
}>;
const main = async (props: Props, retry = 3): Response => {
const { query } = props;
try {
const searchResults = await searchVideos(query, {
safeSearch: SafeSearchType.STRICT
});
const result = searchResults.results
.map((item) => ({
title: item.title,
description: item.description,
url: item.url
}))
.slice(0, 10);
return {
result: JSON.stringify(result)
};
} catch (error) {
if (retry <= 0) {
return {
result: 'Failed to fetch data'
};
}
addLog.warn('DuckDuckGo error', { error });
await delay(Math.random() * 2000);
return main(props, retry - 1);
}
};
export default main;

View File

@@ -0,0 +1,260 @@
{
"author": "",
"version": "486",
"name": "DuckDuckGo 视频搜索",
"avatar": "core/workflow/template/duckduckgo",
"intro": "使用 DuckDuckGo 进行视频搜索",
"showStatus": true,
"weight": 10,
"isTool": true,
"templateType": "search",
"workflow": {
"nodes": [
{
"nodeId": "pluginInput",
"name": "自定义插件输入",
"intro": "可以配置插件需要哪些输入,利用这些输入来运行插件",
"avatar": "/imgs/workflow/input.png",
"flowNodeType": "pluginInput",
"showStatus": false,
"position": {
"x": 393.68844551739926,
"y": -58.80666875994541
},
"version": "481",
"inputs": [
{
"renderTypeList": ["reference"],
"selectedTypeIndex": 0,
"valueType": "string",
"canEdit": true,
"key": "query",
"label": "query",
"description": "检索词",
"required": true,
"toolDescription": "检索词"
}
],
"outputs": [
{
"id": "query",
"valueType": "string",
"key": "query",
"label": "query",
"type": "hidden"
}
]
},
{
"nodeId": "pluginOutput",
"name": "自定义插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "/imgs/workflow/output.png",
"flowNodeType": "pluginOutput",
"showStatus": false,
"position": {
"x": 1795.6509902691012,
"y": -47.04550785550961
},
"version": "481",
"inputs": [
{
"renderTypeList": ["reference"],
"valueType": "string",
"canEdit": true,
"key": "result",
"label": "result",
"description": " 检索结果",
"value": ["hjnVuJAOwyXV", "lEyy5QqyIBrK"]
}
],
"outputs": []
},
{
"nodeId": "hjnVuJAOwyXV",
"name": "HTTP 请求",
"intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)",
"avatar": "/imgs/workflow/http.png",
"flowNodeType": "httpRequest468",
"showStatus": true,
"position": {
"x": 1054.6774638324207,
"y": -403.06127656499825
},
"version": "481",
"inputs": [
{
"key": "system_addInputParam",
"renderTypeList": ["addInputParam"],
"valueType": "dynamic",
"label": "",
"required": false,
"description": "core.module.input.description.HTTP Dynamic Input",
"customInputConfig": {
"selectValueTypeList": [
"string",
"number",
"boolean",
"object",
"arrayString",
"arrayNumber",
"arrayBoolean",
"arrayObject",
"any",
"chatHistory",
"datasetQuote",
"dynamic",
"selectApp",
"selectDataset"
],
"showDescription": false,
"showDefaultValue": true
}
},
{
"key": "system_httpMethod",
"renderTypeList": ["custom"],
"valueType": "string",
"label": "",
"value": "POST",
"required": true
},
{
"key": "system_httpReqUrl",
"renderTypeList": ["hidden"],
"valueType": "string",
"label": "",
"description": "core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory",
"required": false,
"value": "duckduckgo/searchVideo"
},
{
"key": "system_httpHeader",
"renderTypeList": ["custom"],
"valueType": "any",
"value": [],
"label": "",
"description": "core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header",
"required": false
},
{
"key": "system_httpParams",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false
},
{
"key": "system_httpJsonBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": "{\n \"query\": \"{{query}}\"\n}",
"label": "",
"required": false
},
{
"renderTypeList": ["reference"],
"valueType": "string",
"canEdit": true,
"key": "query",
"label": "query",
"customInputConfig": {
"selectValueTypeList": [
"string",
"number",
"boolean",
"object",
"arrayString",
"arrayNumber",
"arrayBoolean",
"arrayObject",
"any",
"chatHistory",
"datasetQuote",
"dynamic",
"selectApp",
"selectDataset"
],
"showDescription": false,
"showDefaultValue": true
},
"required": true,
"value": ["pluginInput", "query"]
}
],
"outputs": [
{
"id": "system_addOutputParam",
"key": "system_addOutputParam",
"type": "dynamic",
"valueType": "dynamic",
"label": "",
"customFieldConfig": {
"selectValueTypeList": [
"string",
"number",
"boolean",
"object",
"arrayString",
"arrayNumber",
"arrayBoolean",
"arrayObject",
"any",
"chatHistory",
"datasetQuote",
"dynamic",
"selectApp",
"selectDataset"
],
"showDescription": false,
"showDefaultValue": false
}
},
{
"id": "error",
"key": "error",
"label": "请求错误",
"description": "HTTP请求错误信息成功时返回空",
"valueType": "object",
"type": "static"
},
{
"id": "httpRawResponse",
"key": "httpRawResponse",
"label": "原始响应",
"required": true,
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "static"
},
{
"id": "lEyy5QqyIBrK",
"valueType": "string",
"type": "dynamic",
"key": "result",
"label": "result"
}
]
}
],
"edges": [
{
"source": "pluginInput",
"target": "hjnVuJAOwyXV",
"sourceHandle": "pluginInput-source-right",
"targetHandle": "hjnVuJAOwyXV-target-left"
},
{
"source": "hjnVuJAOwyXV",
"target": "pluginOutput",
"sourceHandle": "hjnVuJAOwyXV-source-right",
"targetHandle": "pluginOutput-target-left"
}
]
}
}

View File

@@ -0,0 +1,17 @@
{
"author": "",
"version": "486",
"name": "DuckDuckGo服务",
"avatar": "core/workflow/template/duckduckgo",
"intro": "DuckDuckGo 服务,包含网络搜索、图片搜索、新闻搜索等。",
"showStatus": false,
"weight": 10,
"isTool": true,
"templateType": "tools",
"workflow": {
"nodes": [],
"edges": []
}
}

View File

@@ -1,8 +1,8 @@
{
"author": "FastGPT",
"author": "",
"version": "486",
"name": "网页内容抓取",
"avatar": "/imgs/workflow/fetchUrl.svg",
"avatar": "core/workflow/template/fetchUrl",
"intro": "可获取一个网页链接内容,并以 Markdown 格式输出,仅支持获取静态网站。",
"showStatus": true,
"weight": 10,

View File

@@ -1,9 +1,9 @@
{
"author": "FastGPT Team",
"author": "",
"version": "481",
"templateType": "tools",
"name": "获取当前时间",
"avatar": "/imgs/workflow/getCurrentTime.svg",
"avatar": "core/workflow/template/getTime",
"intro": "获取用户当前时区的时间。",
"showStatus": false,
"isTool": true,

View File

@@ -1,8 +1,8 @@
{
"author": "FastGPT",
"author": "",
"version": "486",
"name": "数学公式执行",
"avatar": "/imgs/workflow/mathExprEval.svg",
"avatar": "core/workflow/template/mathCall",
"intro": "用于执行数学表达式的工具,通过 js 的 expr-eval 库运行表达式并返回结果。",
"showStatus": false,
"weight": 10,

View File

@@ -1,7 +1,9 @@
import { PluginTemplateType } from '@fastgpt/global/core/plugin/type.d';
import { SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type';
export type SystemPluginResponseType = Promise<Record<string, any>>;
declare global {
var communitySystemPlugins: SystemPluginTemplateItemType[];
var communitySystemPluginCb: Record<string, (e: any) => SystemPluginResponseType>;
var systemPlugins: SystemPluginTemplateItemType[];
var systemPluginCb: Record<string, (e: any) => SystemPluginResponseType>;
}

View File

@@ -63,6 +63,7 @@ const instance = axios.create({
'Cache-Control': 'no-cache'
}
});
export const serverRequestBaseUrl = `http://${SERVICE_LOCAL_HOST}`;
/* 请求拦截 */
instance.interceptors.request.use(requestStart, (err) => Promise.reject(err));
@@ -79,7 +80,7 @@ export function request(url: string, data: any, config: ConfigType, method: Meth
return instance
.request({
baseURL: `http://${SERVICE_LOCAL_HOST}`,
baseURL: serverRequestBaseUrl,
url,
method,
data: ['POST', 'PUT'].includes(method) ? data : null,

View File

@@ -47,7 +47,7 @@ const addCommonMiddleware = (schema: mongoose.Schema) => {
if (duration > 1000) {
addLog.warn(`Slow operation ${duration}ms`, warnLogData);
} else if (duration > 300) {
} else if (duration > 3000) {
addLog.error(`Slow operation ${duration}ms`, warnLogData);
}
}
@@ -64,10 +64,13 @@ export const getMongoModel = <T>(name: string, schema: mongoose.Schema) => {
addCommonMiddleware(schema);
const model = connectionMongo.model<T>(name, schema);
try {
model.syncIndexes();
} catch (error) {
addLog.error('Create index error', error);
if (process.env.SYNC_INDEX !== '0') {
try {
model.syncIndexes({ background: true });
} catch (error) {
addLog.error('Create index error', error);
}
}
return model;

View File

@@ -7,19 +7,12 @@ const maxConnecting = Math.max(30, Number(process.env.DB_MAX_LINK || 20));
/**
* connect MongoDB and init data
*/
export async function connectMongo({
beforeHook,
afterHook
}: {
beforeHook?: () => any;
afterHook?: () => Promise<any>;
}): Promise<Mongoose> {
export async function connectMongo(): Promise<Mongoose> {
/* Connecting, connected will return */
if (connectionMongo.connection.readyState !== 0) {
return connectionMongo;
}
beforeHook && beforeHook();
console.log('mongo start connect');
try {
connectionMongo.set('strictQuery', true);
@@ -55,11 +48,5 @@ export async function connectMongo({
addLog.error('mongo connect error', error);
}
try {
afterHook && (await afterHook());
} catch (error) {
addLog.error('mongo connect after hook error', error);
}
return connectionMongo;
}

View File

@@ -9,7 +9,7 @@ import { getNanoid } from '@fastgpt/global/common/string/tools';
import { cloneDeep } from 'lodash';
import { MongoApp } from '../schema';
import { SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type';
import { getCommunityPlugins } from '@fastgpt/plugins/register';
import { getSystemPluginTemplates } from '../../../../plugins/register';
/*
plugin id rule:
@@ -28,7 +28,7 @@ export async function splitCombinePluginId(id: string) {
};
}
const [source, pluginId] = id.split('-') as [`${PluginSourceEnum}`, string];
const [source, pluginId] = id.split('-') as [PluginSourceEnum, string];
if (!source || !pluginId) return Promise.reject('pluginId not found');
return { source, pluginId: id };
@@ -39,14 +39,6 @@ const getPluginTemplateById = async (
): Promise<SystemPluginTemplateItemType & { teamId?: string }> => {
const { source, pluginId } = await splitCombinePluginId(id);
if (source === PluginSourceEnum.community) {
const item = [...global.communityPlugins, ...getCommunityPlugins()].find(
(plugin) => plugin.id === pluginId
);
if (!item) return Promise.reject('plugin not found');
return cloneDeep(item);
}
if (source === PluginSourceEnum.personal) {
const item = await MongoApp.findById(id).lean();
if (!item) return Promise.reject('plugin not found');
@@ -68,8 +60,14 @@ const getPluginTemplateById = async (
originCost: 0,
currentCost: 0
};
} else {
const item = [...global.communityPlugins, ...(await getSystemPluginTemplates())].find(
(plugin) => plugin.id === pluginId
);
if (!item) return Promise.reject('plugin not found');
return cloneDeep(item);
}
return Promise.reject('plugin not found');
};
/* format plugin modules to plugin preview module */
@@ -98,10 +96,12 @@ export async function getPluginRuntimeById(id: string): Promise<PluginRuntimeTyp
const plugin = await getPluginTemplateById(id);
return {
id: plugin.id,
teamId: plugin.teamId,
name: plugin.name,
avatar: plugin.avatar,
showStatus: plugin.showStatus,
currentCost: plugin.currentCost,
nodes: plugin.workflow.nodes,
edges: plugin.workflow.edges
};

View File

@@ -0,0 +1,35 @@
import { connectionMongo, getMongoModel } from '../../../common/mongo/index';
const { Schema } = connectionMongo;
import type { SystemPluginConfigSchemaType } from './type';
export const collectionName = 'app_system_plugins';
const SystemPluginSchema = new Schema({
pluginId: {
type: String,
required: true
},
isActive: {
type: Boolean,
required: true
},
inputConfig: {
type: Array,
default: []
},
originCost: {
type: Number,
default: 0
},
currentCost: {
type: Number,
default: 0
}
});
SystemPluginSchema.index({ pluginId: 1 });
export const MongoSystemPluginSchema = getMongoModel<SystemPluginConfigSchemaType>(
collectionName,
SystemPluginSchema
);

View File

@@ -0,0 +1,10 @@
import { SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type';
export type SystemPluginConfigSchemaType = {
pluginId: string;
originCost: number; // n points/one time
currentCost: number;
isActive: boolean;
inputConfig: SystemPluginTemplateItemType['inputConfig'];
};

View File

@@ -0,0 +1,21 @@
import { PluginRuntimeType } from '@fastgpt/global/core/workflow/runtime/type';
import { ChatNodeUsageType } from '@fastgpt/global/support/wallet/bill/type';
import { splitCombinePluginId } from './controller';
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
/*
1. Commercial plugin: n points per times
2. Other plugin: sum of children points
*/
export const computedPluginUsage = async (
plugin: PluginRuntimeType,
childrenUsage: ChatNodeUsageType[]
) => {
const { source } = await splitCombinePluginId(plugin.id);
if (source === PluginSourceEnum.commercial) {
return plugin.currentCost ?? 0;
}
return childrenUsage.reduce((sum, item) => sum + (item.totalPoints || 0), 0);
};

View File

@@ -89,7 +89,7 @@ try {
get chat logs;
close custom feedback;
*/
ChatItemSchema.index({ appId: 1, chatId: 1, dataId: 1 }, { background: true, unique: true });
ChatItemSchema.index({ appId: 1, chatId: 1, dataId: 1 }, { background: true });
// admin charts
ChatItemSchema.index({ time: -1, obj: 1 }, { background: true });
// timer, clear history

View File

@@ -85,7 +85,7 @@ try {
// get user history
ChatSchema.index({ tmbId: 1, appId: 1, top: -1, updateTime: -1 }, { background: true });
// delete by appid; clear history; init chat; update chat; auth chat; get chat;
ChatSchema.index({ appId: 1, chatId: 1 }, { background: true, unique: true });
ChatSchema.index({ appId: 1, chatId: 1 }, { background: true });
// get chat logs;
ChatSchema.index({ teamId: 1, appId: 1, updateTime: -1 }, { background: true });

View File

@@ -1,4 +1,3 @@
import { IMG_BLOCK_KEY } from '@fastgpt/global/core/chat/constants';
import { countGptMessagesTokens } from '../../common/string/tiktoken/index';
import type {
ChatCompletionContentPart,
@@ -7,6 +6,8 @@ import type {
import axios from 'axios';
import { ChatCompletionRequestMessageRoleEnum } from '@fastgpt/global/core/ai/constants';
import { guessBase64ImageType } from '../../common/file/utils';
import { serverRequestBaseUrl } from '../../common/api/serverRequest';
import { cloneDeep } from 'lodash';
/* slice chat context by tokens */
const filterEmptyMessages = (messages: ChatCompletionMessageParam[]) => {
@@ -120,137 +121,64 @@ export const formatGPTMessagesInRequestBefore = (messages: ChatCompletionMessage
.filter(Boolean) as ChatCompletionMessageParam[];
};
/**
string to vision model. Follow the markdown code block rule for interception:
@rule:
```img-block
{src:""}
{src:""}
```
```file-block
{name:"",src:""},
{name:"",src:""}
```
@example:
Whats in this image?
```img-block
{src:"https://1.png"}
```
@return
[
{ type: 'text', text: 'Whats in this image?' },
{
type: 'image_url',
image_url: {
url: 'https://1.png'
}
}
]
*/
export async function formatStr2ChatContent(str: string) {
const content: ChatCompletionContentPart[] = [];
let lastIndex = 0;
const regex = new RegExp(`\`\`\`(${IMG_BLOCK_KEY})\\n([\\s\\S]*?)\`\`\``, 'g');
const imgKey: 'image_url' = 'image_url';
let match;
while ((match = regex.exec(str)) !== null) {
// add previous text
if (match.index > lastIndex) {
const text = str.substring(lastIndex, match.index).trim();
if (text) {
content.push({ type: 'text', text });
}
}
const blockType = match[1].trim();
if (blockType === IMG_BLOCK_KEY) {
const blockContentLines = match[2].trim().split('\n');
const jsonLines = blockContentLines.map((item) => {
try {
return JSON.parse(item) as { src: string };
} catch (error) {
return { src: '' };
}
});
for (const item of jsonLines) {
if (!item.src) throw new Error("image block's content error");
}
content.push(
...jsonLines.map((item) => ({
type: imgKey,
image_url: {
url: item.src
}
}))
);
}
lastIndex = regex.lastIndex;
}
// add remaining text
if (lastIndex < str.length) {
const remainingText = str.substring(lastIndex).trim();
if (remainingText) {
content.push({ type: 'text', text: remainingText });
}
}
// Continuous text type content, if type=text, merge them
for (let i = 0; i < content.length - 1; i++) {
const currentContent = content[i];
const nextContent = content[i + 1];
if (currentContent.type === 'text' && nextContent.type === 'text') {
currentContent.text += nextContent.text;
content.splice(i + 1, 1);
i--;
}
}
if (content.length === 1 && content[0].type === 'text') {
return content[0].text;
}
if (!content) return null;
// load img to base64
for await (const item of content) {
if (item.type === imgKey && item[imgKey]?.url) {
const response = await axios.get(item[imgKey].url, {
responseType: 'arraybuffer'
});
const base64 = Buffer.from(response.data).toString('base64');
item[imgKey].url = `data:${response.headers['content-type']};base64,${base64}`;
}
}
return content ? content : null;
}
/* Load user chat content.
Img: to base 64
*/
export const loadChatImgToBase64 = async (content: string | ChatCompletionContentPart[]) => {
if (typeof content === 'string') {
return content;
}
return Promise.all(
content.map(async (item) => {
if (item.type === 'text') return item;
// load image
const response = await axios.get(item.image_url.url, {
responseType: 'arraybuffer'
});
const base64 = Buffer.from(response.data).toString('base64');
let imageType = response.headers['content-type'];
if (imageType === undefined) {
imageType = guessBase64ImageType(base64);
if (!item.image_url.url) return item;
/*
1. From db: Get it from db
2. From web: Not update
*/
if (item.image_url.url.startsWith('/')) {
const response = await axios.get(item.image_url.url, {
baseURL: serverRequestBaseUrl,
responseType: 'arraybuffer'
});
const base64 = Buffer.from(response.data).toString('base64');
let imageType = response.headers['content-type'];
if (imageType === undefined) {
imageType = guessBase64ImageType(base64);
}
return {
...item,
image_url: {
...item.image_url,
url: `data:${imageType};base64,${base64}`
}
};
}
item.image_url.url = `data:${imageType};base64,${base64}`;
return item;
})
);
};
export const loadRequestMessages = async (messages: ChatCompletionMessageParam[]) => {
if (messages.length === 0) {
return Promise.reject('core.chat.error.Messages empty');
}
const loadMessages = await Promise.all(
messages.map(async (item) => {
if (item.role === ChatCompletionRequestMessageRoleEnum.User) {
return {
...item,
content: await loadChatImgToBase64(item.content)
};
} else {
return item;
}
})
);
return loadMessages;
};

View File

@@ -67,7 +67,7 @@ const DatasetSchema = new Schema({
agentModel: {
type: String,
required: true,
default: 'gpt-3.5-turbo'
default: 'gpt-4o-mini'
},
intro: {
type: String,

View File

@@ -1,6 +1,6 @@
import { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
import { getAIApi } from '../../../../ai/config';
import { filterGPTMessageByMaxTokens } from '../../../../chat/utils';
import { filterGPTMessageByMaxTokens, loadRequestMessages } from '../../../../chat/utils';
import {
ChatCompletion,
StreamChatType,
@@ -88,6 +88,7 @@ export const runToolWithFunctionCall = async (
}
return item;
});
const requestMessages = await loadRequestMessages(formativeMessages);
/* Run llm */
const ai = getAIApi({
@@ -99,7 +100,7 @@ export const runToolWithFunctionCall = async (
model: toolModel.model,
temperature: 0,
stream,
messages: formativeMessages,
messages: requestMessages,
functions,
function_call: 'auto'
},

View File

@@ -12,6 +12,7 @@ import { ChatItemType } from '@fastgpt/global/core/chat/type';
import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
import {
GPTMessages2Chats,
chatValue2RuntimePrompt,
chats2GPTMessages,
getSystemPrompt,
runtimePrompt2ChatsValue
@@ -29,10 +30,11 @@ type Response = DispatchNodeResultType<{
export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<Response> => {
const {
node: { nodeId, name, outputs },
node: { nodeId, name },
runtimeNodes,
runtimeEdges,
histories,
query,
params: { model, systemPrompt, userChatInput, history = 6 }
} = props;
@@ -65,7 +67,7 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
obj: ChatRoleEnum.Human,
value: runtimePrompt2ChatsValue({
text: userChatInput,
files: []
files: chatValue2RuntimePrompt(query).files
})
}
];

View File

@@ -1,6 +1,6 @@
import { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
import { getAIApi } from '../../../../ai/config';
import { filterGPTMessageByMaxTokens } from '../../../../chat/utils';
import { filterGPTMessageByMaxTokens, loadRequestMessages } from '../../../../chat/utils';
import {
ChatCompletion,
StreamChatType,
@@ -87,6 +87,8 @@ export const runToolWithPromptCall = async (
messages,
maxTokens: toolModel.maxContext - 500 // filter token. not response maxToken
});
const requestMessages = await loadRequestMessages(filterMessages);
// console.log(JSON.stringify(filterMessages, null, 2));
/* Run llm */
const ai = getAIApi({
@@ -98,7 +100,7 @@ export const runToolWithPromptCall = async (
model: toolModel.model,
temperature: 0,
stream,
messages: filterMessages
messages: requestMessages
},
{
headers: {

View File

@@ -1,6 +1,6 @@
import { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
import { getAIApi } from '../../../../ai/config';
import { filterGPTMessageByMaxTokens } from '../../../../chat/utils';
import { filterGPTMessageByMaxTokens, loadRequestMessages } from '../../../../chat/utils';
import {
ChatCompletion,
ChatCompletionMessageToolCall,
@@ -99,6 +99,8 @@ export const runToolWithToolChoice = async (
}
return item;
});
const requestMessages = await loadRequestMessages(formativeMessages);
// console.log(
// JSON.stringify(
// {
@@ -106,7 +108,7 @@ export const runToolWithToolChoice = async (
// model: toolModel.model,
// temperature: 0,
// stream,
// messages: formativeMessages,
// messages: requestMessages,
// tools,
// tool_choice: 'auto'
// },
@@ -124,7 +126,7 @@ export const runToolWithToolChoice = async (
model: toolModel.model,
temperature: 0,
stream,
messages: formativeMessages,
messages: requestMessages,
tools,
tool_choice: 'auto'
},

View File

@@ -2,7 +2,7 @@ import type { NextApiResponse } from 'next';
import {
filterGPTMessageByMaxTokens,
formatGPTMessagesInRequestBefore,
loadChatImgToBase64
loadRequestMessages
} from '../../../chat/utils';
import type { ChatItemType, UserChatItemValueItemType } from '@fastgpt/global/core/chat/type.d';
import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
@@ -151,22 +151,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
...formatGPTMessagesInRequestBefore(filterMessages)
] as ChatCompletionMessageParam[];
if (concatMessages.length === 0) {
return Promise.reject('core.chat.error.Messages empty');
}
const loadMessages = await Promise.all(
concatMessages.map(async (item) => {
if (item.role === ChatCompletionRequestMessageRoleEnum.User) {
return {
...item,
content: await loadChatImgToBase64(item.content)
};
} else {
return item;
}
})
);
const requestMessages = await loadRequestMessages(concatMessages);
const requestBody = {
...modelConstantsData?.defaultConfig,
@@ -174,72 +159,88 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
temperature,
max_tokens,
stream,
messages: loadMessages
messages: requestMessages
};
const response = await ai.chat.completions.create(requestBody, {
headers: {
Accept: 'application/json, text/plain, */*'
}
});
try {
const response = await ai.chat.completions.create(requestBody, {
headers: {
Accept: 'application/json, text/plain, */*'
}
});
const { answerText } = await (async () => {
if (res && stream) {
// sse response
const { answer } = await streamResponse({
res,
detail,
stream: response,
requestBody
});
const { answerText } = await (async () => {
if (res && stream) {
// sse response
const { answer } = await streamResponse({
res,
detail,
stream: response
});
return {
answerText: answer
};
} else {
const unStreamResponse = response as ChatCompletion;
const answer = unStreamResponse.choices?.[0]?.message?.content || '';
if (!answer) {
throw new Error('LLM model response empty');
}
return {
answerText: answer
};
}
})();
return {
answerText: answer
};
} else {
const unStreamResponse = response as ChatCompletion;
const answer = unStreamResponse.choices?.[0]?.message?.content || '';
const completeMessages = filterMessages.concat({
role: ChatCompletionRequestMessageRoleEnum.Assistant,
content: answerText
});
const chatCompleteMessages = GPTMessages2Chats(completeMessages);
return {
answerText: answer
};
}
})();
const tokens = await countMessagesTokens(chatCompleteMessages);
const { totalPoints, modelName } = formatModelChars2Points({
model,
tokens,
modelType: ModelTypeEnum.llm
});
const completeMessages = filterMessages.concat({
role: ChatCompletionRequestMessageRoleEnum.Assistant,
content: answerText
});
const chatCompleteMessages = GPTMessages2Chats(completeMessages);
return {
answerText,
[DispatchNodeResponseKeyEnum.nodeResponse]: {
totalPoints: user.openaiAccount?.key ? 0 : totalPoints,
model: modelName,
const tokens = await countMessagesTokens(chatCompleteMessages);
const { totalPoints, modelName } = formatModelChars2Points({
model,
tokens,
query: `${userChatInput}`,
maxToken: max_tokens,
historyPreview: getHistoryPreview(chatCompleteMessages),
contextTotalLen: completeMessages.length
},
[DispatchNodeResponseKeyEnum.nodeDispatchUsages]: [
{
moduleName: name,
modelType: ModelTypeEnum.llm
});
return {
answerText,
[DispatchNodeResponseKeyEnum.nodeResponse]: {
totalPoints: user.openaiAccount?.key ? 0 : totalPoints,
model: modelName,
tokens
}
],
[DispatchNodeResponseKeyEnum.toolResponses]: answerText,
history: chatCompleteMessages
};
tokens,
query: `${userChatInput}`,
maxToken: max_tokens,
historyPreview: getHistoryPreview(chatCompleteMessages),
contextTotalLen: completeMessages.length
},
[DispatchNodeResponseKeyEnum.nodeDispatchUsages]: [
{
moduleName: name,
totalPoints: user.openaiAccount?.key ? 0 : totalPoints,
model: modelName,
tokens
}
],
[DispatchNodeResponseKeyEnum.toolResponses]: answerText,
history: chatCompleteMessages
};
} catch (error) {
addLog.warn(`LLM response error`, {
baseUrl: user.openaiAccount?.baseUrl,
requestBody
});
if (user.openaiAccount?.baseUrl) {
return Promise.reject(`您的 OpenAI key 出错了: ${JSON.stringify(requestBody)}`);
}
return Promise.reject(error);
}
};
async function filterQuote({
@@ -349,13 +350,11 @@ async function getMaxTokens({
async function streamResponse({
res,
detail,
stream,
requestBody
stream
}: {
res: NextApiResponse;
detail: boolean;
stream: StreamChatType;
requestBody: Record<string, any>;
}) {
const write = responseWriteController({
res,
@@ -379,10 +378,5 @@ async function streamResponse({
});
}
if (!answer) {
addLog.info(`LLM model response empty`, requestBody);
return Promise.reject('core.chat.Chat API is error or undefined');
}
return { answer };
}

View File

@@ -2,7 +2,7 @@ import type { ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/
import { dispatchWorkFlow } from '../index';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
import { getPluginRuntimeById, splitCombinePluginId } from '../../../app/plugin/controller';
import { getPluginRuntimeById } from '../../../app/plugin/controller';
import {
getDefaultEntryNodeIds,
initWorkflowEdgeStatus,
@@ -10,9 +10,9 @@ import {
} from '@fastgpt/global/core/workflow/runtime/utils';
import { DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type';
import { updateToolInputValue } from '../agent/runTool/utils';
import { authAppByTmbId } from '../../../../support/permission/app/auth';
import { authPluginByTmbId } from '../../../../support/permission/app/auth';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
import { computedPluginUsage } from '../../../app/plugin/utils';
type RunPluginProps = ModuleDispatchProps<{
[key: string]: any;
@@ -33,14 +33,12 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
}
// auth plugin
const { source } = await splitCombinePluginId(pluginId);
if (source === PluginSourceEnum.personal) {
await authAppByTmbId({
appId: pluginId,
tmbId: workflowApp.tmbId,
per: ReadPermissionVal
});
}
await authPluginByTmbId({
appId: pluginId,
tmbId: workflowApp.tmbId,
per: ReadPermissionVal
});
const plugin = await getPluginRuntimeById(pluginId);
// concat dynamic inputs
@@ -78,12 +76,15 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
output.moduleLogo = plugin.avatar;
}
const isError = !!output?.pluginOutput?.error;
const usagePoints = isError ? 0 : await computedPluginUsage(plugin, flowUsages);
return {
assistantResponses,
// responseData, // debug
[DispatchNodeResponseKeyEnum.nodeResponse]: {
moduleLogo: plugin.avatar,
totalPoints: flowResponses.reduce((sum, item) => sum + (item.totalPoints || 0), 0),
totalPoints: usagePoints,
pluginOutput: output?.pluginOutput,
pluginDetail:
mode === 'test' && plugin.teamId === teamId
@@ -96,8 +97,7 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
[DispatchNodeResponseKeyEnum.nodeDispatchUsages]: [
{
moduleName: plugin.name,
totalPoints: flowUsages.reduce((sum, item) => sum + (item.totalPoints || 0), 0),
model: plugin.name,
totalPoints: usagePoints,
tokens: 0
}
],

View File

@@ -16,7 +16,7 @@ import { DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/ty
import { getErrText } from '@fastgpt/global/common/error/utils';
import { responseWrite } from '../../../../common/response';
import { textAdaptGptResponse } from '@fastgpt/global/core/workflow/runtime/utils';
import { getCommunityCb } from '@fastgpt/plugins/register';
import { getSystemPluginCb } from '../../../../../plugins/register';
type PropsArrType = {
key: string;
@@ -121,9 +121,9 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
try {
const { formatResponse, rawResponse } = await (async () => {
const communityPluginCb = await getCommunityCb();
if (communityPluginCb[httpReqUrl]) {
const pluginResult = await communityPluginCb[httpReqUrl](requestBody);
const systemPluginCb = await getSystemPluginCb();
if (systemPluginCb[httpReqUrl]) {
const pluginResult = await systemPluginCb[httpReqUrl](requestBody);
return {
formatResponse: pluginResult,
rawResponse: pluginResult

View File

@@ -3,7 +3,6 @@
"version": "1.0.0",
"dependencies": {
"@fastgpt/global": "workspace:*",
"@fastgpt/plugins": "workspace:*",
"@node-rs/jieba": "1.10.0",
"@xmldom/xmldom": "^0.8.10",
"@zilliz/milvus2-sdk-node": "2.4.2",
@@ -25,7 +24,7 @@
"mammoth": "^1.6.0",
"mongoose": "^7.0.2",
"multer": "1.4.5-lts.1",
"next": "14.2.3",
"next": "14.2.5",
"nextjs-cors": "^2.2.0",
"node-cron": "^3.0.3",
"node-xlsx": "^0.23.0",

View File

@@ -12,6 +12,27 @@ import { AuthResponseType } from '../type/auth.d';
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
import { AppFolderTypeList } from '@fastgpt/global/core/app/constants';
import { ParentIdType } from '@fastgpt/global/common/parentFolder/type';
import { splitCombinePluginId } from '../../../core/app/plugin/controller';
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
export const authPluginByTmbId = async ({
tmbId,
appId,
per
}: {
tmbId: string;
appId: string;
per: PermissionValueType;
}) => {
const { source } = await splitCombinePluginId(appId);
if (source === PluginSourceEnum.personal) {
await authAppByTmbId({
appId,
tmbId,
per
});
}
};
export const authAppByTmbId = async ({
tmbId,

View File

@@ -25,4 +25,7 @@ declare global {
worker: Worker;
callbackMap: Record<string, (e: number) => void>;
}[];
var systemLoadedGlobalVariables: boolean;
var systemLoadedGlobalConfig: boolean;
}

View File

@@ -2,9 +2,16 @@ import React from 'react';
import { Image } from '@chakra-ui/react';
import type { ImageProps } from '@chakra-ui/react';
import { LOGO_ICON } from '@fastgpt/global/common/system/constants';
import MyIcon from '../Icon';
import { iconPaths } from '../Icon/constants';
const Avatar = ({ w = '30px', src, ...props }: ImageProps) => {
return (
// @ts-ignore
const isIcon = !!iconPaths[src as any];
return isIcon ? (
<MyIcon name={src as any} w={w} borderRadius={props.borderRadius} />
) : (
<Image
fallbackSrc={LOGO_ICON}
fallbackStrategy={'onError'}

View File

@@ -103,7 +103,7 @@ const DateRangePicker = ({
mr={2}
onClick={() => setShowSelected(false)}
>
{t('common.Close')}
{t('common:common.Close')}
</Button>
<Button
size={'sm'}
@@ -112,7 +112,7 @@ const DateRangePicker = ({
setShowSelected(false);
}}
>
{t('common.Confirm')}
{t('common:common.Confirm')}
</Button>
</Flex>
}

View File

@@ -13,7 +13,7 @@ const EmptyTip = ({ text, ...props }: Props) => {
<Flex mt={5} flexDirection={'column'} alignItems={'center'} py={'10vh'} {...props}>
<MyIcon name="empty" w={'48px'} h={'48px'} color={'transparent'} />
<Box mt={2} color={'myGray.500'} fontSize={'sm'}>
{text || t('common.empty.Common Tip')}
{text || t('common:common.empty.Common Tip')}
</Box>
</Flex>
);

View File

@@ -163,6 +163,45 @@ export const iconPaths = {
'core/workflow/runSkip': () => import('./icons/core/workflow/runSkip.svg'),
'core/workflow/runSuccess': () => import('./icons/core/workflow/runSuccess.svg'),
'core/workflow/running': () => import('./icons/core/workflow/running.svg'),
'core/workflow/template/FileRead': () => import('./icons/core/workflow/template/FileRead.svg'),
'core/workflow/template/aiChat': () => import('./icons/core/workflow/template/aiChat.svg'),
'core/workflow/template/codeRun': () => import('./icons/core/workflow/template/codeRun.svg'),
'core/workflow/template/customFeedback': () =>
import('./icons/core/workflow/template/customFeedback.svg'),
'core/workflow/template/datasetConcat': () =>
import('./icons/core/workflow/template/datasetConcat.svg'),
'core/workflow/template/datasetSearch': () =>
import('./icons/core/workflow/template/datasetSearch.svg'),
'core/workflow/template/duckduckgo': () =>
import('./icons/core/workflow/template/duckduckgo.svg'),
'core/workflow/template/extractJson': () =>
import('./icons/core/workflow/template/extractJson.svg'),
'core/workflow/template/fetchUrl': () => import('./icons/core/workflow/template/fetchUrl.svg'),
'core/workflow/template/getTime': () => import('./icons/core/workflow/template/getTime.svg'),
'core/workflow/template/httpRequest': () =>
import('./icons/core/workflow/template/httpRequest.svg'),
'core/workflow/template/ifelse': () => import('./icons/core/workflow/template/ifelse.svg'),
'core/workflow/template/lafDispatch': () =>
import('./icons/core/workflow/template/lafDispatch.svg'),
'core/workflow/template/mathCall': () => import('./icons/core/workflow/template/mathCall.svg'),
'core/workflow/template/pluginOutput': () =>
import('./icons/core/workflow/template/pluginOutput.svg'),
'core/workflow/template/queryExtension': () =>
import('./icons/core/workflow/template/queryExtension.svg'),
'core/workflow/template/questionClassify': () =>
import('./icons/core/workflow/template/questionClassify.svg'),
'core/workflow/template/reply': () => import('./icons/core/workflow/template/reply.svg'),
'core/workflow/template/runApp': () => import('./icons/core/workflow/template/runApp.svg'),
'core/workflow/template/stopTool': () => import('./icons/core/workflow/template/stopTool.svg'),
'core/workflow/template/systemConfig': () =>
import('./icons/core/workflow/template/systemConfig.svg'),
'core/workflow/template/textConcat': () =>
import('./icons/core/workflow/template/textConcat.svg'),
'core/workflow/template/toolCall': () => import('./icons/core/workflow/template/toolCall.svg'),
'core/workflow/template/variableUpdate': () =>
import('./icons/core/workflow/template/variableUpdate.svg'),
'core/workflow/template/workflowStart': () =>
import('./icons/core/workflow/template/workflowStart.svg'),
'core/workflow/versionHistories': () => import('./icons/core/workflow/versionHistories.svg'),
date: () => import('./icons/date.svg'),
delete: () => import('./icons/delete.svg'),
@@ -206,6 +245,7 @@ export const iconPaths = {
'phoneTabbar/me': () => import('./icons/phoneTabbar/me.svg'),
'phoneTabbar/tool': () => import('./icons/phoneTabbar/tool.svg'),
'phoneTabbar/toolFill': () => import('./icons/phoneTabbar/toolFill.svg'),
'plugins/textEditor': () => import('./icons/plugins/textEditor.svg'),
'price/bg': () => import('./icons/price/bg.svg'),
'price/right': () => import('./icons/price/right.svg'),
save: () => import('./icons/save.svg'),

View File

@@ -0,0 +1,10 @@
<svg viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" fill="url(#paint0_linear_7245_16485)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.7763 8.12977C21.1563 8.34937 21.486 8.65892 22.1453 9.27804L25.0531 12.0087C25.7718 12.6836 26.1312 13.0211 26.387 13.4223C26.6045 13.7632 26.7661 14.1367 26.8658 14.5285C26.9831 14.9897 26.9831 15.4826 26.9831 16.4686V22.262C26.9831 24.4261 26.9831 25.5081 26.5553 26.3317C26.1947 27.0258 25.6288 27.5916 24.9348 27.9522C24.1112 28.38 23.0292 28.38 20.8651 28.38H15.1348C12.9708 28.38 11.8887 28.38 11.0651 27.9522C10.3711 27.5916 9.8052 27.0258 9.44467 26.3317C9.01685 25.5081 9.01685 24.4261 9.01685 22.262V13.7379C9.01685 11.5738 9.01685 10.4918 9.44467 9.66817C9.8052 8.97413 10.3711 8.40823 11.0651 8.0477C11.8887 7.61987 12.9708 7.61987 15.1348 7.61987H17.9572C18.8616 7.61987 19.3138 7.61987 19.7411 7.71991C20.1045 7.80496 20.4533 7.94307 20.7763 8.12977ZM20.3328 10.6525C19.7396 10.0837 19.443 9.79934 19.1884 9.78903C18.9862 9.78085 18.791 9.8641 18.657 10.0157C18.4882 10.2066 18.4882 10.6176 18.4882 11.4394V12.3778C18.4882 13.58 18.4882 14.1811 18.7222 14.6403C18.928 15.0442 19.2564 15.3726 19.6603 15.5784C20.1195 15.8124 20.7206 15.8124 21.9228 15.8124H23.0022C23.8674 15.8124 24.3 15.8124 24.4924 15.6378C24.6451 15.4992 24.7258 15.2984 24.7115 15.0927C24.6935 14.8335 24.3812 14.5342 23.7567 13.9354L20.3328 10.6525ZM13.0047 19.6762C13.0047 19.1239 13.4524 18.6762 14.0047 18.6762H21.9996C22.5519 18.6762 22.9996 19.1239 22.9996 19.6762C22.9996 20.2284 22.5519 20.6762 21.9996 20.6762H14.0047C13.4524 20.6762 13.0047 20.2284 13.0047 19.6762ZM12.993 23.4244C12.993 22.8721 13.4407 22.4244 13.993 22.4244H19.9946C20.5469 22.4244 20.9946 22.8721 20.9946 23.4244C20.9946 23.9767 20.5469 24.4244 19.9946 24.4244H13.993C13.4407 24.4244 12.993 23.9767 12.993 23.4244Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_7245_16485" x1="18" y1="0" x2="5.5" y2="33" gradientUnits="userSpaceOnUse">
<stop stop-color="#7B98FF"/>
<stop offset="1" stop-color="#7479FF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,10 @@
<svg viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" fill="url(#paint0_linear_7245_16463)"/>
<path d="M23.128 12.0501H24.25C26.3211 12.0501 28 13.7291 28 15.8001V20.8001C28 22.8711 26.3211 24.55 24.25 24.55H11.75C9.67895 24.55 8 22.8711 8 20.8001V15.8001C8 13.7291 9.67895 12.0501 11.75 12.0501H12.872L12.4153 9.31012C12.3131 8.69728 12.7272 8.11763 13.34 8.01548C13.9529 7.91333 14.5326 8.32738 14.6347 8.94022L15.1347 11.9402C15.1409 11.977 15.1451 12.0137 15.1476 12.0501H20.8524C20.8549 12.0136 20.8591 11.977 20.8653 11.9402L21.3653 8.94022C21.4675 8.32738 22.0471 7.91333 22.66 8.01548C23.2728 8.11763 23.6869 8.69728 23.5847 9.31012L23.128 12.0501ZM12.9 17.3001V18.3001C12.9 18.9214 13.4037 19.4251 14.025 19.4251C14.6463 19.4251 15.15 18.9214 15.15 18.3001V17.3001C15.15 16.6788 14.6463 16.1751 14.025 16.1751C13.4037 16.1751 12.9 16.6788 12.9 17.3001ZM20.85 17.3001V18.3001C20.85 18.9214 21.3537 19.4251 21.975 19.4251C22.5963 19.4251 23.1 18.9214 23.1 18.3001V17.3001C23.1 16.6788 22.5963 16.1751 21.975 16.1751C21.3537 16.1751 20.85 16.6788 20.85 17.3001ZM13 28C12.3787 28 11.875 27.4963 11.875 26.875C11.875 26.2537 12.3787 25.75 13 25.75H23C23.6213 25.75 24.125 26.2537 24.125 26.875C24.125 27.4963 23.6213 28 23 28H13Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_7245_16463" x1="18" y1="0" x2="5.5" y2="33" gradientUnits="userSpaceOnUse">
<stop stop-color="#7C98FF"/>
<stop offset="1" stop-color="#7479FF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,10 @@
<svg viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" fill="url(#paint0_linear_7245_16518)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 11.7083C8 10.0514 9.34315 8.70825 11 8.70825H25C26.6569 8.70825 28 10.0514 28 11.7083V11.7522H8V11.7083ZM8 13.3522H28V24.2919C28 25.9487 26.6569 27.2919 25 27.2919H11C9.34315 27.2919 8 25.9487 8 24.2919V13.3522ZM17.3879 24.8245C16.9503 24.7637 16.645 24.3596 16.7058 23.9221L17.7098 16.7034C17.7707 16.2659 18.1747 15.9605 18.6123 16.0213C19.0499 16.0822 19.3553 16.4863 19.2944 16.9238L18.2904 24.1424C18.2295 24.58 17.8255 24.8854 17.3879 24.8245ZM11.5976 19.864C11.2852 20.1764 11.2852 20.6829 11.5976 20.9953C11.6306 21.0283 11.6658 21.0579 11.7028 21.0839L14.2858 23.667C14.5982 23.9794 15.1047 23.9794 15.4171 23.667C15.7295 23.3546 15.7295 22.8481 15.4171 22.5357L13.3027 20.4214L15.3684 18.3557C15.6808 18.0433 15.6808 17.5368 15.3684 17.2244C15.056 16.9121 14.5495 16.9121 14.2372 17.2244L11.5976 19.864ZM24.4023 19.864C24.7147 20.1764 24.7147 20.6829 24.4023 20.9953C24.3693 21.0283 24.3341 21.0579 24.2971 21.0839L21.7141 23.667C21.4017 23.9794 20.8952 23.9794 20.5828 23.667C20.2704 23.3546 20.2704 22.8481 20.5828 22.5357L22.6972 20.4214L20.6315 18.3557C20.3191 18.0433 20.3191 17.5368 20.6315 17.2244C20.9439 16.9121 21.4504 16.9121 21.7627 17.2244L24.4023 19.864Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_7245_16518" x1="18" y1="0" x2="5.5" y2="33" gradientUnits="userSpaceOnUse">
<stop stop-color="#5CD8C9"/>
<stop offset="1" stop-color="#13C993"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,10 @@
<svg viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" fill="url(#paint0_linear_7245_16543)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.1152 12.8164C14.7413 14.4056 13.3142 15.5887 11.6108 15.5887C9.62262 15.5887 8.01084 13.9769 8.01084 11.9887C8.01084 10.0004 9.62262 8.38867 11.6108 8.38867C12.9548 8.38867 14.1267 9.12507 14.7451 10.2164H23.4586C25.9667 10.2164 27.9999 12.2496 27.9999 14.7576C27.9999 17.2657 25.9667 19.2989 23.4586 19.2989H21.963C21.4484 20.658 20.1346 21.6243 18.5952 21.6243C17.0557 21.6243 15.742 20.658 15.2273 19.2989L12.5414 19.2989C11.4693 19.2989 10.6001 20.168 10.6001 21.2402C10.6001 22.3123 11.4693 23.1814 12.5414 23.1814H22.3597V22.1525C22.3597 21.5366 23.0264 21.1517 23.5597 21.4597L27.5935 23.7886C28.1269 24.0965 28.1269 24.8663 27.5935 25.1742L23.5597 27.5032C23.0264 27.8111 22.3597 27.4262 22.3597 26.8104V25.7814L12.5414 25.7814C10.0333 25.7814 8.00012 23.7482 8.00012 21.2402C8.00012 18.7321 10.0333 16.6989 12.5414 16.6989L15.247 16.6989C15.7749 15.3666 17.075 14.4243 18.5952 14.4243C20.1154 14.4243 21.4155 15.3666 21.9434 16.6989H23.4586C24.5307 16.6989 25.3999 15.8298 25.3999 14.7576C25.3999 13.6855 24.5307 12.8164 23.4586 12.8164H15.1152ZM13.2108 11.9887C13.2108 12.8723 12.4945 13.5887 11.6108 13.5887C10.7272 13.5887 10.0108 12.8723 10.0108 11.9887C10.0108 11.105 10.7272 10.3887 11.6108 10.3887C12.4945 10.3887 13.2108 11.105 13.2108 11.9887ZM20.1419 17.9989C20.1419 17.7926 20.1167 17.5924 20.0694 17.4013C19.8264 16.8272 19.2578 16.4243 18.5952 16.4243C17.7115 16.4243 16.9952 17.1407 16.9952 18.0243C16.9952 18.908 17.7115 19.6243 18.5952 19.6243C19.227 19.6243 19.7733 19.2581 20.0334 18.7263C20.1039 18.4968 20.1419 18.2524 20.1419 17.9989Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_7245_16543" x1="18" y1="0" x2="5.5" y2="33" gradientUnits="userSpaceOnUse">
<stop stop-color="#A6DA72"/>
<stop offset="1" stop-color="#78C952"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,10 @@
<svg viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" fill="url(#paint0_linear_7245_16528)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.06162 10.0117C8.28842 10.0117 7.66162 10.6385 7.66162 11.4117C7.66162 12.1849 8.28842 12.8117 9.06162 12.8117H13.3351C13.5886 12.8117 13.8147 12.971 13.9 13.2096L15.3298 17.2054C15.4955 17.6687 16.1178 17.7465 16.3925 17.3383L17.5019 15.6896C17.6084 15.5314 17.6333 15.332 17.569 15.1525L16.5364 12.2663C16.0526 10.9141 14.7713 10.0117 13.3351 10.0117H9.06162ZM9.07444 25.9882C8.30124 25.9882 7.67444 25.3614 7.67444 24.5882C7.67444 23.815 8.30124 23.1882 9.07444 23.1882H13.7724C13.9674 23.1882 14.1503 23.0934 14.2627 22.934L18.3233 17.1769C18.6143 16.7642 19.0879 16.5567 19.5575 16.5865H22.5883V15.8215C22.5883 15.0517 23.4216 14.5705 24.0883 14.9554L27.8383 17.1205C28.505 17.5054 28.505 18.4676 27.8383 18.8525L24.0883 21.0176C23.4216 21.4025 22.5883 20.9214 22.5883 20.1516V19.3865H20.1912L16.5508 24.5478C15.9138 25.451 14.8776 25.9882 13.7724 25.9882H9.07444Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_7245_16528" x1="18" y1="0" x2="5.5" y2="33" gradientUnits="userSpaceOnUse">
<stop stop-color="#68C0FF"/>
<stop offset="1" stop-color="#52A2FF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,13 @@
<svg viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" fill="url(#paint0_linear_7245_16465)"/>
<path d="M27.1151 12.2072V11.7056L27.1145 11.6586C27.0605 9.33579 23.0005 8 18 8C12.9992 8 8.93848 9.31688 8.8849 11.6586V12.2072H8.8894C8.88641 12.2458 8.8849 12.2847 8.8849 12.324C8.8849 14.088 12.128 15.5179 18 15.5179C23.872 15.5179 27.1151 14.088 27.1151 12.324C27.1151 12.2848 27.1135 12.2458 27.1105 12.2072H27.1151Z" fill="white"/>
<path d="M8.8849 14.9628V18.5214C8.8847 18.5297 8.88477 18.5381 8.88483 18.5464L8.8849 18.5591C8.8849 20.321 12.128 21.7492 18 21.7492C18.4714 21.7492 18.9259 21.74 19.3631 21.7222C20.2048 20.0119 21.965 18.835 24 18.835C24.9917 18.835 25.9182 19.1145 26.7049 19.5991C26.9765 19.2731 27.1151 18.9232 27.1151 18.5591L27.1149 18.5415L27.1146 18.5214L27.1151 14.9628H27.0523C26.5758 16.5689 23.3992 17.8089 18 17.8089C12.6007 17.8089 9.42412 16.5689 8.94764 14.9628H8.8849Z" fill="white"/>
<path d="M18.8438 24.3042C18.9264 25.7274 19.5854 26.9961 20.5908 27.8801C19.7948 27.9584 18.9304 28 18 28C12.2513 28 9.0223 26.4099 8.88919 24.4229H8.8849V20.8458C8.8849 22.7619 12.128 24.3152 18 24.3152C18.2876 24.3152 18.5689 24.3115 18.8438 24.3042Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.0877 26.9562C25.5444 27.3044 24.8983 27.5064 24.2051 27.5064C22.2756 27.5064 20.7115 25.9423 20.7115 24.0129C20.7115 22.0834 22.2756 20.5193 24.2051 20.5193C26.1345 20.5193 27.6986 22.0834 27.6986 24.0129C27.6986 24.7061 27.4966 25.3522 27.1484 25.8955L28.2289 26.976C28.5218 27.2689 28.5218 27.7438 28.2289 28.0367C27.936 28.3296 27.4611 28.3296 27.1682 28.0367L26.0877 26.9562ZM26.1986 24.0129C26.1986 25.1138 25.306 26.0064 24.2051 26.0064C23.1041 26.0064 22.2115 25.1138 22.2115 24.0129C22.2115 22.9119 23.1041 22.0193 24.2051 22.0193C25.306 22.0193 26.1986 22.9119 26.1986 24.0129Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_7245_16465" x1="18" y1="0" x2="5.5" y2="33" gradientUnits="userSpaceOnUse">
<stop stop-color="#55B8FF"/>
<stop offset="1" stop-color="#149DFF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1 @@
<svg t="1721273358953" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4468" width="200" height="200"><path d="M514.56 509.44m-486.4 0a486.4 486.4 0 1 0 972.8 0 486.4 486.4 0 1 0-972.8 0Z" fill="#CC6633" p-id="4469"></path><path d="M512 512m-448 0a448 448 0 1 0 896 0 448 448 0 1 0-896 0Z" fill="#FFFFFF" p-id="4470"></path><path d="M934.912 516.096c0 199.68-138.24 367.616-324.096 412.672-11.264-21.504-22.016-42.496-31.232-59.904 31.744 28.16 70.144 38.912 91.648 25.6 27.648-16.896 37.376-78.848-5.632-135.168-13.312 0.512-30.72 2.56-50.176 8.192-27.648 8.192-48.128 20.992-61.44 30.72-11.776-17.92-28.16-48.64-36.352-89.6-6.656-33.28-5.12-61.952-2.56-81.408 14.848 10.24 113.664 43.52 162.816 42.496 49.152-1.024 129.536-30.72 120.832-54.784s-88.576 20.992-172.544 13.312c-61.952-5.632-72.704-33.28-58.88-53.76 17.408-25.6 48.64 4.608 100.352-10.752s124.416-43.008 151.04-58.368c61.952-34.816-26.112-49.152-46.592-39.424-19.968 9.216-88.064 26.624-120.32 34.304 17.92-62.976-25.088-172.544-73.216-220.672-15.872-15.872-39.424-25.6-66.56-30.72-10.24-14.336-27.136-28.16-51.2-40.448-46.08-24.064-98.304-32.768-149.504-24.064h-2.56c-6.144 1.024-9.728 3.584-14.848 4.096 6.144 0.512 29.184 11.264 44.032 17.408-7.168 3.072-16.896 4.608-24.576 7.68-3.072 0.512-5.632 1.024-8.704 2.56-7.168 3.072-12.8 15.36-12.288 21.504 34.816-3.584 86.528-1.024 124.416 10.24-26.624 3.584-51.2 10.752-69.12 19.968-0.512 0.512-1.024 0.512-2.048 1.024-2.048 1.024-4.608 1.536-6.144 2.56-56.832 29.696-81.92 99.84-67.072 183.808 13.312 75.776 69.12 336.384 95.232 460.288-164.352-56.32-282.624-214.016-282.624-399.36 0-235.008 190.464-424.96 424.96-424.96s424.96 190.464 424.96 424.96z" fill="#DE5833" p-id="4471"></path><path d="M389.12 446.976m-31.744 0a31.744 31.744 0 1 0 63.488 0 31.744 31.744 0 1 0-63.488 0Z" fill="#336699" p-id="4472"></path><path d="M599.552 401.408c-14.848-0.512-27.648 11.264-28.16 26.112s11.264 27.648 26.112 28.16h2.048c14.848 0 27.136-12.288 27.136-27.136s-12.288-27.136-27.136-27.136zM397.824 355.84s-23.552-10.752-46.592 3.584c-23.04 14.848-22.016 29.696-22.016 29.696s-12.288-27.136 20.48-40.448c32.256-13.824 48.64 7.168 48.128 7.168zM615.936 353.792s-16.896-9.728-30.208-9.728c-27.136 0.512-34.816 12.288-34.816 12.288s4.608-28.672 39.424-23.04c11.264 2.56 20.992 9.728 25.6 20.48z" fill="#336699" p-id="4473"></path><path d="M549.376 522.24c24.576-9.728 35.328-9.728 74.24-17.408 24.576-5.12 56.832-11.776 94.72-23.552 30.208-9.216 36.864-13.824 56.32-15.36 26.112-2.048 62.464 1.024 66.56 15.36 2.048 6.656-4.608 13.824-10.24 20.48-14.336 16.384-32.256 22.016-61.44 30.72-36.352 11.264-38.912 11.264-51.2 15.36-58.368 18.432-55.296 23.552-76.8 25.6-38.912 3.584-60.928-12.8-71.68 0-6.656 8.192-4.608 22.016 0 30.72 6.656 11.776 19.968 15.36 40.96 20.48 25.6 6.144 46.08 5.632 51.2 5.12 18.432-1.024 31.744-4.608 51.2-10.24 40.96-11.776 52.736-21.504 71.68-15.36 3.584 1.024 19.456 6.144 20.48 15.36 2.048 18.432-53.76 43.52-102.4 51.2-47.104 7.168-86.528-2.56-97.28-5.12-7.168-2.048-19.968-6.144-46.08-15.36-29.696-10.24-37.376-13.824-46.08-20.48-9.216-7.168-23.04-17.92-25.6-35.84-2.56-18.432 9.216-33.28 15.36-40.96 9.216-11.264 21.504-20.992 46.08-30.72z" fill="#FDD20A" p-id="4474"></path><path d="M523.776 798.72c4.096-3.584 9.216-7.168 15.36-10.24 11.776-6.144 22.528-9.216 30.72-10.24-1.536 3.584-3.584 6.656-5.12 10.24 14.336-7.168 29.696-13.824 46.08-20.48 25.088-10.24 49.152-18.432 71.68-25.6 7.68 12.288 22.016 36.864 25.6 71.68 3.584 35.328-5.12 63.488-10.24 76.8-6.144 3.584-32.768 17.408-66.56 10.24s-51.712-30.208-56.32-35.84c-1.536 5.12-3.584 10.24-5.12 15.36-5.632 1.024-14.848 2.048-25.6 0-11.776-2.048-20.48-7.168-25.6-10.24-24.064 11.776-47.616 24.064-71.68 35.84-3.584 4.608-9.728 6.656-15.36 5.12-7.68-2.048-10.24-9.728-10.24-10.24-5.632-16.896-11.264-37.888-15.36-61.44-4.096-25.088-5.12-47.616-5.12-66.56-2.048-6.144 0.512-12.8 5.12-15.36s9.728-0.512 10.24 0c18.944 2.56 44.544 7.68 71.68 20.48 13.824 6.656 26.112 13.824 35.84 20.48z" fill="#66CC33" p-id="4475"></path></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -0,0 +1,11 @@
<svg viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" fill="url(#paint0_linear_7245_16480)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.35535 15.7015C8.35535 18.0133 10.1708 19.901 12.4538 20.0167V20.0223H13.8556V18.5875C13.8556 17.4756 14.757 16.5742 15.8689 16.5742C16.9808 16.5742 17.8821 17.4756 17.8821 18.5875V20.0223H23.5043V20.0111C25.8068 19.9168 27.6446 18.0204 27.6446 15.6947C27.6446 13.3794 25.8233 11.4896 23.5353 11.3796C23.2332 10.6659 22.7962 10.0171 22.248 9.46891C21.6889 8.90978 21.0251 8.46626 20.2945 8.16366C19.564 7.86107 18.781 7.70532 17.9903 7.70532C17.1996 7.70532 16.4166 7.86107 15.6861 8.16366C14.9555 8.46626 14.2917 8.90979 13.7326 9.46891C13.1825 10.019 12.7443 10.6704 12.4421 11.387C10.1646 11.5085 8.35535 13.3938 8.35535 15.7015Z" fill="white"/>
<path d="M15.8746 17.9688C16.4269 17.9688 16.8746 18.4165 16.8746 18.9688V20.139C16.8746 20.6596 16.8754 20.9898 16.8958 21.2398C16.9153 21.4781 16.9475 21.5542 16.9618 21.5822C17.0385 21.7327 17.1609 21.8551 17.3114 21.9318C17.3395 21.9461 17.4155 21.9783 17.6538 21.9978C17.9038 22.0182 18.2341 22.019 18.7546 22.019H22.3193C22.5741 21.7527 22.9331 21.5869 23.3308 21.5869C24.104 21.5869 24.7308 22.2137 24.7308 22.9869C24.7308 23.7601 24.104 24.3869 23.3308 24.3869C22.9662 24.3869 22.6341 24.2475 22.3849 24.019H18.7169C18.2451 24.019 17.8322 24.0191 17.4909 23.9912C17.2865 23.9745 17.08 23.9462 16.8746 23.892C16.8747 24.4194 16.8766 24.7683 16.8985 25.0372C16.9207 25.3088 16.9584 25.4096 16.9836 25.459C17.0795 25.6472 17.2325 25.8001 17.4206 25.896C17.4701 25.9212 17.5708 25.9589 17.8424 25.9811C18.1258 26.0042 18.498 26.005 19.0746 26.005H20.1289C20.3856 25.6934 20.7746 25.4947 21.2099 25.4947C21.9831 25.4947 22.6099 26.1215 22.6099 26.8947C22.6099 27.6679 21.9831 28.2947 21.2099 28.2947C20.8889 28.2947 20.5932 28.1867 20.357 28.005H19.0361C18.5089 28.005 18.0541 28.005 17.6796 27.9744C17.2842 27.9421 16.891 27.8708 16.5126 27.678C15.9481 27.3904 15.4892 26.9315 15.2016 26.367C15.0088 25.9886 14.9375 25.5954 14.9052 25.2C14.8746 24.8255 14.8746 24.3707 14.8746 23.8436V20.2399C14.8746 20.219 14.8746 20.1979 14.8746 20.1767V18.9688C14.8746 18.4165 15.3223 17.9688 15.8746 17.9688Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_7245_16480" x1="18" y1="0" x2="5.5" y2="33" gradientUnits="userSpaceOnUse">
<stop stop-color="#61D2C4"/>
<stop offset="1" stop-color="#00C874"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1,10 @@
<svg viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" fill="url(#paint0_linear_7275_6584)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.3961 16.1278C9.26542 16.7311 9.1966 17.3575 9.1966 18C9.1966 18.6425 9.26542 19.2688 9.3961 19.8722H13.0856C13.0027 19.2617 12.9542 18.6443 12.9412 18.0229C12.9409 18.0076 12.9409 17.9924 12.9412 17.9771C12.9542 17.3557 13.0027 16.7383 13.0856 16.1278H9.3961ZM10.1913 13.9312H13.5404C13.9734 12.3864 14.6335 10.9116 15.5009 9.55638C13.1957 10.2376 11.2847 11.8371 10.1913 13.9312ZM18 9.81135C17.0506 11.06 16.3212 12.4534 15.8358 13.9312H20.1641C19.6788 12.4534 18.9493 11.06 18 9.81135ZM20.6943 16.1278H15.3056C15.2085 16.7444 15.152 17.3697 15.1379 18C15.152 18.6302 15.2085 19.2556 15.3056 19.8722H20.6943C20.7915 19.2556 20.8479 18.6302 20.8621 18C20.8479 17.3697 20.7915 16.7444 20.6943 16.1278ZM22.9143 19.8722C22.9973 19.2617 23.0458 18.6443 23.0587 18.0229C23.059 18.0076 23.059 17.9924 23.0587 17.9771C23.0458 17.3557 22.9973 16.7383 22.9143 16.1278H26.6039C26.7345 16.7311 26.8034 17.3575 26.8034 18C26.8034 18.6425 26.7345 19.2688 26.6039 19.8722H22.9143ZM20.1641 22.0688H15.8358C16.3212 23.5465 17.0506 24.94 18 26.1886C18.9493 24.94 19.6788 23.5465 20.1641 22.0688ZM15.5009 26.4436C14.6335 25.0884 13.9734 23.6136 13.5404 22.0688H10.1913C11.2847 24.1629 13.1957 25.7624 15.5009 26.4436ZM20.4991 26.4436C21.3665 25.0884 22.0266 23.6136 22.4596 22.0688H25.8087C24.7153 24.1629 22.8042 25.7624 20.4991 26.4436ZM25.8087 13.9312H22.4596C22.0266 12.3864 21.3665 10.9116 20.4991 9.55638C22.8042 10.2376 24.7153 11.8371 25.8087 13.9312ZM7 18C7 11.9249 11.9249 7 18 7C24.0751 7 29 11.9249 29 18C29 24.0751 24.0751 29 18 29C11.9249 29 7 24.0751 7 18Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_7275_6584" x1="18" y1="0" x2="5.5" y2="33" gradientUnits="userSpaceOnUse">
<stop stop-color="#68C0FF"/>
<stop offset="1" stop-color="#52A2FF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,12 @@
<svg viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" fill="url(#paint0_linear_7275_6485)"/>
<path d="M12.048 7.94883C12.4706 8.37148 12.4706 9.05673 12.048 9.47939L9.84755 11.6798C9.4249 12.1025 8.73964 12.1025 8.31699 11.6798C7.89434 11.2572 7.89434 10.5719 8.31699 10.1493L10.5174 7.94883C10.9401 7.52617 11.6253 7.52617 12.048 7.94883Z" fill="white"/>
<path d="M23.952 7.94884C24.3747 7.52618 25.0599 7.52618 25.4826 7.94884L27.683 10.1493C28.1056 10.5719 28.1056 11.2572 27.683 11.6798C27.2603 12.1025 26.5751 12.1025 26.1524 11.6798L23.952 9.4794C23.5294 9.05675 23.5294 8.37149 23.952 7.94884Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M18 27.2284C19.7368 27.2284 21.359 26.7375 22.7354 25.8868C22.746 25.8984 22.7568 25.9097 22.768 25.9209L24.9684 28.1213C25.3911 28.544 26.0764 28.544 26.499 28.1213C26.9217 27.6987 26.9217 27.0134 26.499 26.5907L24.4361 24.5279C26.0342 22.9004 27.0198 20.6696 27.0198 18.2086C27.0198 13.227 22.9815 9.18873 18 9.18873C13.0185 9.18873 8.98017 13.227 8.98017 18.2086C8.98017 20.6696 9.96581 22.9005 11.5639 24.5279L9.50099 26.5908C9.07834 27.0134 9.07834 27.6987 9.50099 28.1213C9.92365 28.544 10.6089 28.544 11.0316 28.1213L13.232 25.9209C13.2432 25.9097 13.254 25.8984 13.2646 25.8868C14.641 26.7375 16.2631 27.2284 18 27.2284ZM18 13.2945C18.5765 13.2945 19.0438 13.7618 19.0438 14.3383V17.5759L21.378 18.9235C21.8773 19.2118 22.0483 19.8502 21.7601 20.3494C21.4719 20.8486 20.8335 21.0197 20.3342 20.7315L17.5377 19.1169C17.5261 19.1102 17.5146 19.1033 17.5034 19.0962C17.1775 18.9196 16.9562 18.5746 16.9562 18.1779V14.3383C16.9562 13.7618 17.4235 13.2945 18 13.2945Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_7275_6485" x1="18" y1="0" x2="5.5" y2="33" gradientUnits="userSpaceOnUse">
<stop stop-color="#FCA18D"/>
<stop offset="1" stop-color="#E97359"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,10 @@
<svg viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" fill="url(#paint0_linear_7245_16503)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.5174 19.5124C6.5174 23.1879 9.35744 26.2002 12.9628 26.4743V26.4868H13.1653C13.2761 26.492 13.3876 26.4947 13.4997 26.4947C13.6118 26.4947 13.7233 26.492 13.8342 26.4868H22.9882C23.0924 26.492 23.1973 26.4947 23.3028 26.4947C26.7158 26.4947 29.4827 23.7279 29.4827 20.3148C29.4827 17.8113 27.994 15.6556 25.8537 14.6843C25.1036 11.7054 22.4688 9.50513 19.3336 9.50513C17.0173 9.50513 14.9741 10.7061 13.7623 12.5349C13.6752 12.5317 13.5876 12.53 13.4997 12.53C9.64349 12.53 6.5174 15.6561 6.5174 19.5124ZM9.86901 21.5155C9.9592 21.6057 10.087 21.6508 10.2523 21.6508C10.4252 21.6508 10.5548 21.6057 10.6413 21.5155C10.7277 21.4216 10.7709 21.2901 10.7709 21.1209V20.0105H12.4113V21.1209C12.4113 21.2901 12.4545 21.4216 12.5409 21.5155C12.6311 21.6057 12.7608 21.6508 12.9299 21.6508C13.0952 21.6508 13.2211 21.6057 13.3075 21.5155C13.3977 21.4216 13.4428 21.2901 13.4428 21.1209V18.1052C13.4428 17.9323 13.3977 17.8008 13.3075 17.7106C13.2211 17.6204 13.0952 17.5753 12.9299 17.5753C12.7608 17.5753 12.6311 17.6204 12.5409 17.7106C12.4545 17.8008 12.4113 17.9323 12.4113 18.1052V19.1593H10.7709V18.1052C10.7709 17.9323 10.7258 17.8008 10.6356 17.7106C10.5492 17.6204 10.4214 17.5753 10.2523 17.5753C10.087 17.5753 9.9592 17.6204 9.86901 17.7106C9.77882 17.8008 9.73373 17.9323 9.73373 18.1052V21.1209C9.73373 21.2901 9.77882 21.4216 9.86901 21.5155ZM15.6871 21.5155C15.7773 21.6057 15.905 21.6508 16.0704 21.6508C16.2432 21.6508 16.3729 21.6057 16.4593 21.5155C16.5458 21.4216 16.589 21.2919 16.589 21.1266V18.4716H17.474C17.613 18.4716 17.7182 18.4359 17.7896 18.3645C17.8648 18.2893 17.9024 18.1841 17.9024 18.0488C17.9024 17.9098 17.8648 17.8046 17.7896 17.7332C17.7182 17.6618 17.613 17.6261 17.474 17.6261H14.6668C14.5277 17.6261 14.4206 17.6618 14.3455 17.7332C14.2741 17.8046 14.2384 17.9098 14.2384 18.0488C14.2384 18.1841 14.2741 18.2893 14.3455 18.3645C14.4206 18.4359 14.5277 18.4716 14.6668 18.4716H15.5518V21.1266C15.5518 21.2919 15.5969 21.4216 15.6871 21.5155ZM20.2261 21.6508C20.0607 21.6508 19.9329 21.6057 19.8428 21.5155C19.7526 21.4216 19.7075 21.2919 19.7075 21.1266V18.4716H18.8225C18.6834 18.4716 18.5763 18.4359 18.5012 18.3645C18.4298 18.2893 18.3941 18.1841 18.3941 18.0488C18.3941 17.9098 18.4298 17.8046 18.5012 17.7332C18.5763 17.6618 18.6834 17.6261 18.8225 17.6261H21.6297C21.7687 17.6261 21.8739 17.6618 21.9453 17.7332C22.0205 17.8046 22.0581 17.9098 22.0581 18.0488C22.0581 18.1841 22.0205 18.2893 21.9453 18.3645C21.8739 18.4359 21.7687 18.4716 21.6297 18.4716H20.7447V21.1266C20.7447 21.2919 20.7014 21.4216 20.615 21.5155C20.5286 21.6057 20.3989 21.6508 20.2261 21.6508ZM22.9856 21.5155C23.0758 21.6057 23.2036 21.6508 23.369 21.6508C23.5418 21.6508 23.6715 21.6057 23.7579 21.5155C23.8443 21.4216 23.8876 21.2919 23.8876 21.1266V20.2303H24.7613C25.2122 20.2303 25.5598 20.1157 25.8041 19.8865C26.0521 19.6535 26.1761 19.334 26.1761 18.9282C26.1761 18.5223 26.0521 18.2048 25.8041 17.9755C25.5598 17.7426 25.2122 17.6261 24.7613 17.6261H23.3746C23.2092 17.6261 23.0796 17.6712 22.9856 17.7613C22.8955 17.8515 22.8504 17.9812 22.8504 18.1503V21.1266C22.8504 21.2919 22.8955 21.4216 22.9856 21.5155ZM24.5809 19.4355H23.8876V18.4209H24.5809C24.7763 18.4209 24.9266 18.4622 25.0318 18.5449C25.1371 18.6276 25.1897 18.7553 25.1897 18.9282C25.1897 19.0973 25.1371 19.2251 25.0318 19.3115C24.9266 19.3942 24.7763 19.4355 24.5809 19.4355Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_7245_16503" x1="18" y1="0" x2="5.5" y2="33" gradientUnits="userSpaceOnUse">
<stop stop-color="#7895FE"/>
<stop offset="1" stop-color="#7177FF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -0,0 +1,10 @@
<svg viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" fill="url(#paint0_linear_7245_16508)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.6891 10.1841C26.941 9.45667 26.3109 8.72937 25.555 8.87495L21.303 9.69389C20.5471 9.83948 20.2323 10.7488 20.7363 11.3306L21.1948 11.8599L16.254 16.0602H9.26425C8.49085 16.0602 7.86389 16.6872 7.86389 17.4606C7.86389 18.234 8.49085 18.8609 9.26425 18.8609H16.4514C16.5645 18.8609 16.6745 18.8475 16.7799 18.8222C17.1118 18.8304 17.448 18.7212 17.7209 18.4892L23.0287 13.9768L23.5715 14.6035C24.0756 15.1853 25.0204 15.0033 25.2723 14.2759L26.6891 10.1841ZM18.8174 18.9913C18.4653 19.2924 18.4241 19.8219 18.7252 20.1739L21.563 23.4918L20.9894 23.9939C20.4101 24.5009 20.5968 25.4449 21.3255 25.693L25.4245 27.0891C26.1532 27.3372 26.8773 26.7035 26.7278 25.9483L25.8874 21.7006C25.7379 20.9454 24.8271 20.6352 24.2478 21.1422L23.6707 21.6472L20.8535 18.3535C20.5524 18.0014 20.023 17.9601 19.6709 18.2612L18.8174 18.9913Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_7245_16508" x1="18" y1="0" x2="5.5" y2="33" gradientUnits="userSpaceOnUse">
<stop stop-color="#61D287"/>
<stop offset="1" stop-color="#43CA40"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,10 @@
<svg viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" fill="url(#paint0_linear_7245_16538)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.05 7.5C12.2511 7.5 7.55005 12.201 7.55005 18C7.55005 23.799 12.2511 28.5 18.05 28.5C23.849 28.5 28.55 23.799 28.55 18C28.55 12.201 23.849 7.5 18.05 7.5ZM10.4536 16.6776L11.2345 15.8967C12.5284 14.6028 14.6261 14.6028 15.92 15.8967L21.3864 21.3631C19.6613 23.0883 16.8642 23.0883 15.1391 21.3631L10.4536 16.6776ZM19.0437 17.4585L19.8246 16.6776C20.8765 15.6257 22.4598 15.429 23.7104 16.0875C24.2671 16.3806 24.8755 16.6306 25.4995 16.5504C25.4995 16.5504 25.0284 17.5308 24.6367 18.1034C23.8653 19.2312 22.1674 20.5822 22.1674 20.5822L19.0437 17.4585Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_7245_16538" x1="18" y1="0" x2="5.5" y2="33" gradientUnits="userSpaceOnUse">
<stop stop-color="#5DD9CA"/>
<stop offset="1" stop-color="#14CA93"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 982 B

View File

@@ -0,0 +1,10 @@
<svg viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" fill="url(#paint0_linear_7275_6588)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.303 9.4C15.303 8.6268 15.9298 8 16.703 8H19.297C20.0702 8 20.697 8.6268 20.697 9.4V11.578C20.697 12.3512 20.0702 12.978 19.297 12.978H16.703C15.9298 12.978 15.303 12.3512 15.303 11.578V9.4ZM15.303 24.422C15.303 23.6488 15.9298 23.022 16.703 23.022H19.297C20.0702 23.022 20.697 23.6488 20.697 24.422V26.6C20.697 27.3732 20.0702 28 19.297 28H16.703C15.9298 28 15.303 27.3732 15.303 26.6V24.422ZM9.7902 15.84C9.017 15.84 8.3902 16.4668 8.3902 17.24V18.76C8.3902 19.5332 9.017 20.16 9.7902 20.16H26.2098C26.983 20.16 27.6098 19.5332 27.6098 18.76V17.24C27.6098 16.4668 26.983 15.84 26.2098 15.84H9.7902Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_7275_6588" x1="18" y1="0" x2="5.5" y2="33" gradientUnits="userSpaceOnUse">
<stop stop-color="#91A9FE"/>
<stop offset="1" stop-color="#797EFF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,13 @@
<svg viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" fill="url(#paint0_linear_7399_1292)"/>
<path d="M18.5151 18.0001C18.5151 17.4478 18.9629 17.0001 19.5151 17.0001H27.8021C28.3543 17.0001 28.8021 17.4478 28.8021 18.0001C28.8021 18.5524 28.3543 19.0001 27.8021 19.0001H19.5151C18.9629 19.0001 18.5151 18.5524 18.5151 18.0001Z" fill="white"/>
<path d="M24.5558 14.606C24.9464 14.2155 25.5795 14.2155 25.97 14.606L28.5156 17.1516C28.9062 17.5421 28.9062 18.1753 28.5156 18.5658C28.1251 18.9564 27.4919 18.9564 27.1014 18.5658L24.5558 16.0202C24.1653 15.6297 24.1653 14.9966 24.5558 14.606Z" fill="white"/>
<path d="M24.5558 21.2528C24.1653 20.8623 24.1653 20.2291 24.5558 19.8386L27.1014 17.293C27.4919 16.9025 28.1251 16.9025 28.5156 17.293C28.9061 17.6835 28.9061 18.3167 28.5156 18.7072L25.97 21.2528C25.5795 21.6433 24.9463 21.6433 24.5558 21.2528Z" fill="white"/>
<path d="M12.2499 8C10.593 8 9.24988 9.34314 9.24988 11V25.0001C9.24988 26.6569 10.593 28.0001 12.2499 28.0001H19.397C21.0539 28.0001 22.397 26.6569 22.397 25.0001V21.8676L17.8665 21.2666C17.1885 21.1767 16.6775 20.611 16.6517 19.9327H16.6506V16.0674H16.6517C16.6775 15.3891 17.1885 14.8234 17.8665 14.7335L22.397 14.1325V11C22.397 9.34315 21.0539 8 19.397 8H12.2499Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_7399_1292" x1="18" y1="0" x2="5.5" y2="33" gradientUnits="userSpaceOnUse">
<stop stop-color="#8DD56B"/>
<stop offset="1" stop-color="#65C144"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Some files were not shown because too many files have changed in this diff Show More