Skip to content

Commit

Permalink
Plugin runtime (#2050)
Browse files Browse the repository at this point in the history
* feat: plugin run (#1950)

* feat: plugin run

* fix

* ui

* fix

* change user input type

* fix

* fix

* temp

* split out plugin chat

* perf: chatbox

* perf: chatbox

* fix: plugin runtime (#2032)

* fix: plugin runtime

* fix

* fix build

* fix build

* perf: chat send prompt

* perf: chat log ux

* perf: chatbox context and share page plugin runtime

* perf: plugin run time config

* fix: ts

* feat: doc

* perf: isPc check

* perf: variable input render

* feat: app search

* fix: response box height

* fix: phone ui

* perf: lock

* perf: plugin route

* fix: chat (#2049)

---------

Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>
  • Loading branch information
c121914yu and newfish-cmyk authored Jul 15, 2024
1 parent 090c880 commit b5c98a4
Show file tree
Hide file tree
Showing 126 changed files with 5,053 additions and 4,358 deletions.
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
public-hoist-pattern[]=*tiktoken*
public-hoist-pattern[]=*@zilliz/milvus2-sdk-node*
registry=https://registry.npmjs.org/
202 changes: 196 additions & 6 deletions docSite/content/zh-cn/docs/development/openapi/chat.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@ toc: true
weight: 852
---

## 发起对话

{{% alert icon="🤖 " context="success" %}}
该接口的 API Key 需使用`应用特定的 key`,否则会报错。

有些包调用时,`BaseUrl`需要添加`v1`路径,有些不需要,如果出现404情况,可补充`v1`重试。
{{% /alert %}}

## 发起对话(简易应用和工作流)

**对话接口兼容`GPT`的接口!如果你的项目使用的是标准的`GPT`官方接口,可以直接通过修改`BaseUrl``Authorization`来访问 FastGpt 应用**
对话接口兼容`GPT`的接口!如果你的项目使用的是标准的`GPT`官方接口,可以直接通过修改`BaseUrl``Authorization`来访问 FastGpt 应用,不过需要注意下面几个规则:

## 请求
{{% alert icon="🤖 " context="success" %}}
* 传入的`model``temperature`等参数字段均无效,这些字段由编排决定。
* 不会返回实际消耗`Token`值,如果需要,可以设置`detail=true`,并手动计算 `responseData` 里的`tokens`值。
{{% /alert %}}

### 请求

{{< tabs tabTotal="2" >}}
{{< tab tabName="请求示例" >}}
Expand Down Expand Up @@ -67,7 +71,7 @@ curl --location --request POST 'https://api.fastgpt.in/api/v1/chat/completions'
{{< /tab >}}
{{< /tabs >}}

## 响应
### 响应

{{< tabs tabTotal="5" >}}
{{< tab tabName="detail=false,stream=false 响应" >}}
Expand Down Expand Up @@ -245,7 +249,7 @@ data: [{"moduleName":"知识库搜索","moduleType":"datasetSearchNode","running
{{< /markdownify >}}
{{< /tab >}}

{{< tab tabName="detail=true,stream=true 时,event值" >}}
{{< tab tabName="event值" >}}
{{< markdownify >}}

event取值:
Expand All @@ -265,6 +269,192 @@ event取值:
{{< /tabs >}}



## 请求插件

插件的接口与对话接口一致,仅请求参数略有区别,有以下规定:

* 调用插件类型的应用时,接口默认为`detail`模式。
* 无需传入 `chatId`,因为插件只能运行一轮。
* 无需传入`messages`
* 通过传递`variables`来代表插件的输入。
* 通过获取`pluginData`来获取插件输出。

### 请求示例

```bash
curl --location --request POST 'http://localhost:3000/api/v1/chat/completions' \
--header 'Authorization: Bearer test-xxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"stream": false,
"chatId": "test",
"variables": {
"query":"你好" # 我的插件输入有一个参数,变量名叫 query
}
}'
```

### 响应示例

{{< tabs tabTotal="3" >}}

{{< tab tabName="detail=true,stream=false 响应" >}}
{{< markdownify >}}

* 插件的输出可以通过查找`responseData`中, `moduleType=pluginOutput`的元素,其`pluginOutput`是插件的输出。
* 流输出,仍可以通过`choices`进行获取。

```json
{
"responseData": [
{
"nodeId": "fdDgXQ6SYn8v",
"moduleName": "AI 对话",
"moduleType": "chatNode",
"totalPoints": 0.685,
"model": "FastAI-3.5",
"tokens": 685,
"query": "你好",
"maxToken": 2000,
"historyPreview": [
{
"obj": "Human",
"value": "你好"
},
{
"obj": "AI",
"value": "你好!有什么可以帮助你的吗?欢迎向我提问。"
}
],
"contextTotalLen": 14,
"runningTime": 1.73
},
{
"nodeId": "pluginOutput",
"moduleName": "自定义插件输出",
"moduleType": "pluginOutput",
"totalPoints": 0,
"pluginOutput": {
"result": "你好!有什么可以帮助你的吗?欢迎向我提问。"
},
"runningTime": 0
}
],
"newVariables": {
"query": "你好"
},
"id": "safsafsa",
"model": "",
"usage": {
"prompt_tokens": 1,
"completion_tokens": 1,
"total_tokens": 1
},
"choices": [
{
"message": {
"role": "assistant",
"content": "你好!有什么可以帮助你的吗?欢迎向我提问。"
},
"finish_reason": "stop",
"index": 0
}
]
}
```

{{< /markdownify >}}
{{< /tab >}}


{{< tab tabName="detail=true,stream=true 响应" >}}
{{< markdownify >}}

* 插件的输出可以通过获取`event=flowResponses`中的字符串,并将其反序列化后得到一个数组。同样的,查找 `moduleType=pluginOutput`的元素,其`pluginOutput`是插件的输出。
* 流输出,仍和对话接口一样获取。

```bash
event: flowNodeStatus
data: {"status":"running","name":"AI 对话"}

event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}

event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}

event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}

event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}

event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}

event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}

event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}

event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":"可以"},"index":0,"finish_reason":null}]}

event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}

event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}

event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}

event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}

event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}

event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}

event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}

event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{},"index":0,"finish_reason":"stop"}]}

event: answer
data: [DONE]

event: flowResponses
data: [{"nodeId":"fdDgXQ6SYn8v","moduleName":"AI 对话","moduleType":"chatNode","totalPoints":0.033,"model":"FastAI-3.5","tokens":33,"query":"你好","maxToken":2000,"historyPreview":[{"obj":"Human","value":"你好"},{"obj":"AI","value":"你好!有什么可以帮助你的吗?"}],"contextTotalLen":2,"runningTime":1.42},{"nodeId":"pluginOutput","moduleName":"自定义插件输出","moduleType":"pluginOutput","totalPoints":0,"pluginOutput":{"result":"你好!有什么可以帮助你的吗?"},"runningTime":0}]
```

{{< /markdownify >}}
{{< /tab >}}

{{< tab tabName="输出获取" >}}
{{< markdownify >}}

event取值:

- answer: 返回给客户端的文本(最终会算作回答)
- fastAnswer: 指定回复返回给客户端的文本(最终会算作回答)
- toolCall: 执行工具
- toolParams: 工具参数
- toolResponse: 工具返回
- flowNodeStatus: 运行到的节点状态
- flowResponses: 节点完整响应
- updateVariables: 更新变量
- error: 报错

{{< /markdownify >}}
{{< /tab >}}
{{< /tabs >}}

## 使用案例

- [接入 NextWeb/ChatGPT web 等应用](/docs/use-cases/openapi)
Expand Down
27 changes: 27 additions & 0 deletions docSite/content/zh-cn/docs/development/upgrading/487.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
title: 'V4.8.7(进行中)'
description: 'FastGPT V4.8.7 更新说明'
icon: 'upgrade'
draft: false
toc: true
weight: 817
---

## 升级指南

### 1. 做好数据库备份

### 2. 修改镜像

- fastgpt 镜像 tag 修改成 v4.8.7-alpha
- 商业版镜像 tag 修改成 v4.8.7-alpha

-------

## V4.8.7 更新说明

1. 新增 - 插件支持独立运行,发布和日志查看
2. 新增 - 应用搜索
3. 优化 - 对话框代码
4. 优化 - 升级 Dockerfile node 和 pnpm 版本
5. 修复 - 简易模式无法变更全局变量
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ weight: 404
},
{
"nodeId": "u6IAOEssxoZT",
"name": "工具调用(实验)",
"name": "工具调用",
"intro": "通过AI模型自动选择一个或多个功能块进行调用,也可以对插件进行调用。",
"avatar": "/imgs/workflow/tool.svg",
"flowNodeType": "tools",
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"./docSite/**/**/*.md": "npm run format-doc"
},
"engines": {
"node": ">=18.0.0",
"pnpm": ">=8.6.0"
"node": ">=18.16.0",
"pnpm": ">=9.0.0"
}
}
10 changes: 10 additions & 0 deletions packages/global/core/app/plugin/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { StoreNodeItemType } from '../../workflow/type/node';
import { FlowNodeInputItemType } from '../../workflow/type/io';
import { FlowNodeTypeEnum } from '../../workflow/node/constant';

export const getPluginInputsFromStoreNodes = (nodes: StoreNodeItemType[]) => {
return nodes.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput)?.inputs || [];
};
export const getPluginRunContent = (e: { pluginInputs: FlowNodeInputItemType[] }) => {
return JSON.stringify(e);
};
1 change: 1 addition & 0 deletions packages/global/core/app/type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export type AppSchema = {
name: string;
avatar: string;
intro: string;

updateTime: Date;

modules: StoreNodeItemType[];
Expand Down
9 changes: 5 additions & 4 deletions packages/global/core/chat/adapt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,17 @@ export const chats2GPTMessages = ({
text: item.text?.content || ''
};
}
if (item.type === 'file' && item.file?.type === ChatFileTypeEnum.image) {
if (
item.type === ChatItemValueTypeEnum.file &&
item.file?.type === ChatFileTypeEnum.image
) {
return {
type: 'image_url',
image_url: {
url: item.file?.url || ''
}
};
}
return;
})
.filter(Boolean) as ChatCompletionContentPart[];

Expand Down Expand Up @@ -166,7 +168,7 @@ export const GPTMessages2Chats = (
} else if (item.type === 'image_url') {
value.push({
//@ts-ignore
type: 'file',
type: ChatItemValueTypeEnum.file,
file: {
type: ChatFileTypeEnum.image,
name: '',
Expand All @@ -175,7 +177,6 @@ export const GPTMessages2Chats = (
});
}
});
// @ts-ignore
}
} else if (
obj === ChatRoleEnum.AI &&
Expand Down
3 changes: 2 additions & 1 deletion packages/global/core/chat/type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { DispatchNodeResponseKeyEnum } from '../workflow/runtime/constants';
import { AppChatConfigType, AppSchema, VariableItemType } from '../app/type';
import type { AppSchema as AppType } from '@fastgpt/global/core/app/type.d';
import { DatasetSearchModeEnum } from '../dataset/constants';
import { ChatBoxInputType } from '../../../../projects/app/src/components/ChatBox/type';
import { DispatchNodeResponseType } from '../workflow/runtime/type.d';
import { ChatBoxInputType } from '../../../../projects/app/src/components/core/chat/ChatContainer/ChatBox/type';

export type ChatSchema = {
_id: string;
Expand Down Expand Up @@ -115,6 +115,7 @@ export type ChatSiteItemType = (UserChatItemType | SystemChatItemType | AIChatIt
status: `${ChatStatusEnum}`;
moduleName?: string;
ttsBuffer?: Uint8Array;
responseData?: ChatHistoryItemResType[];
} & ChatBoxInputType;

/* --------- team chat --------- */
Expand Down
Loading

0 comments on commit b5c98a4

Please sign in to comment.