From 0104b14b0b9e9eae47935803910cc08d32cc92ab Mon Sep 17 00:00:00 2001 From: xiang <1984871009@qq.com> Date: Tue, 13 Jun 2023 20:54:45 +0800 Subject: [PATCH] feat: add site --- README.md | 8 ++-- README_zh.md | 4 +- model/chatdemo/index.ts | 97 +++++++++++++++++++++++++++++++++++++++++ model/index.ts | 3 ++ 4 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 model/chatdemo/index.ts diff --git a/README.md b/README.md index 09c8449..00d4111 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,9 @@ Have implemented models here: If you do not want your website to appear here, please raise an issue and I will remove it immediately. |model|support|status|active time| |--|--|--|--| -|[ai.mcbbs.gq](https://ai.mcbbs.gq)|gpt3.5|![Active](https://img.shields.io/badge/Active-brightgreen)|after 2023-06-03| -|[forefront.ai](https://chat.forefront.ai)|👍GPT-4/gpt3.5|![Active](https://img.shields.io/badge/Active-brightgreen)|after 2023-06-03| -|[you.com](https://you.com)|👍GPT-3.5|![Active](https://img.shields.io/badge/Active-brightgreen)|after 2023-05-12 +|[chatdemo]()|👍gpt3.5|![Active](https://img.shields.io/badge/Active-brightgreen)|after 2023-06-13| +|[forefront.ai](https://chat.forefront.ai)|👍GPT-4/gpt3.5|![Active](https://img.shields.io/badge/Active-brightgreen)|after 2023-06-13| +|[you.com](https://you.com)|👍GPT-3.5|![Active](https://img.shields.io/badge/Active-brightgreen)|after 2023-06-13 |[phind.com](https://www.phind.com/)|GPT-4 / Internet / good search|![Active](https://img.shields.io/badge/Active-grey)| |[bing.com/chat](https://bing.com/chat)|GPT-4/3.5|| |[poe.com](https://poe.com)| GPT-4/3.5|| @@ -104,7 +104,7 @@ docker-compose up --build -d - example `jsonstr`:`[{"role":"user","content":"hello\n"},{"role":"assistant","content":"Hi there! How can I assist you today?"},{"role":"user","content":"who are you"}]` - example `string`: `who are you` - `model`: default `gpt3.5-turbo`. model include:`gpt4` `gpt3.5-turbo` -- `site`: default `you`. target site, include `forefront` `you` `mcbbs` +- `site`: default `you`. target site, include `forefront` `you` `chatdemo` ### Response Params 🔙 diff --git a/README_zh.md b/README_zh.md index 11e5030..af69b8f 100644 --- a/README_zh.md +++ b/README_zh.md @@ -34,7 +34,7 @@ |model|support|status|active time| |--|--|--|--| -|[ai.mcbbs.gq](https://ai.mcbbs.gq)|gpt3.5|![Active](https://img.shields.io/badge/Active-brightgreen)|after 2023-06-03| +|[chatdemo]()|👍gpt3.5|![Active](https://img.shields.io/badge/Active-brightgreen)|after 2023-06-13| |[forefront.ai](https://chat.forefront.ai)|👍GPT-4/gpt3.5|![Active](https://img.shields.io/badge/Active-brightgreen)|after 2023-06-03| |[you.com](you.com)|👍GPT-3.5|![Active](https://img.shields.io/badge/Active-brightgreen)|after 2023-05-12 |[phind.com](https://www.phind.com/)|GPT-4 / Internet / good search|![Active](https://img.shields.io/badge/Active-grey)| @@ -102,7 +102,7 @@ docker-compose up --build -d - `jsonstr`:包含上下文的json字符串,例如:`[{"role":"user","content":"你好\n"},{"role":"assistant","content":"你好!有什么我可以帮助你的吗?"},{"role":"user","content":"你是谁"}]` - `string`: 单次对话 例如:`你是谁` - `model`: 默认 `gpt3.5-turbo`. 模型:`gpt4` `gpt3.5-turbo` -- `site`: 默认 `you`. 目标网站 `forefront` `you` `mcbbs` +- `site`: 默认 `you`. 目标网站 `forefront` `you` `chatdemo` ### 返回参数 🔙 diff --git a/model/chatdemo/index.ts b/model/chatdemo/index.ts new file mode 100644 index 0000000..6cf3ea1 --- /dev/null +++ b/model/chatdemo/index.ts @@ -0,0 +1,97 @@ +import {Chat, ChatOptions, ChatRequest, ChatResponse, ModelType} from "../base"; +import {AxiosInstance, AxiosRequestConfig, CreateAxiosDefaults} from "axios"; +import {CreateAxiosProxy} from "../../utils/proxyAgent"; +import es from "event-stream"; +import {ErrorData, Event, EventStream, MessageData, parseJSON} from "../../utils"; +import {randomUUID} from "crypto"; +import {v4} from "uuid"; +import moment from "moment"; + +interface RealReq { + question: string; + chat_id: string; + timestamp: number; +} + +export class ChatDemo extends Chat { + private client: AxiosInstance; + + constructor(options?: ChatOptions) { + super(options); + this.client = CreateAxiosProxy({ + baseURL: 'https://chat.chatgptdemo.net', + headers: { + 'Content-Type': 'application/json', + "accept": "text/event-stream", + "Cache-Control": "no-cache", + "Proxy-Connection": "keep-alive" + } + } as CreateAxiosDefaults); + } + + support(model: ModelType): number { + switch (model) { + case ModelType.GPT3p5Turbo: + return 2000; + default: + return 0; + } + } + + public async ask(req: ChatRequest): Promise { + const stream = new EventStream(); + const res = await this.askStream(req, stream); + const result: ChatResponse = { + content: '', + } + return new Promise(resolve => { + stream.read((event, data) => { + switch (event) { + case Event.done: + break; + case Event.message: + result.content += (data as MessageData).content + break; + case Event.error: + result.error = (data as ErrorData).error + break; + } + }, () => { + resolve(result); + }) + }) + + } + + public async askStream(req: ChatRequest, stream: EventStream) { + const data: RealReq = { + question: req.prompt, + chat_id: v4(), + timestamp: moment().valueOf(), + }; + try { + const res = await this.client.post('/chat_api_stream', data, { + responseType: 'stream', + } as AxiosRequestConfig); + res.data.pipe(es.split(/\r?\n\r?\n/)).pipe(es.map(async (chunk: any, cb: any) => { + const dataStr = chunk.replace('data: ', ''); + if (!dataStr) { + stream.end(); + return; + } + const data = parseJSON(dataStr, {} as any); + if (!data?.choices) { + stream.write(Event.error, {error: 'not found data.choices'}) + stream.end(); + return; + } + const [{delta: {content = ""}}] = data.choices; + stream.write(Event.message, {content}); + })) + } catch (e: any) { + console.error(e); + stream.write(Event.error, {error: e.message}) + stream.end(); + } + } +} diff --git a/model/index.ts b/model/index.ts index 03d7ec9..d49744c 100644 --- a/model/index.ts +++ b/model/index.ts @@ -2,12 +2,14 @@ import {Chat, ChatOptions} from "./base"; import {You} from "./you"; import {Forefrontnew} from "./forefront"; import {Mcbbs} from "./mcbbs"; +import {ChatDemo} from "./chatdemo"; export enum Site { // define new model here You = 'you', Forefront = 'forefront', Mcbbs = 'mcbbs', + ChatDemo = 'chatdemo', } export class ChatModelFactory { @@ -25,6 +27,7 @@ export class ChatModelFactory { this.modelMap.set(Site.You, new You(this.options)) this.modelMap.set(Site.Forefront, new Forefrontnew(this.options)) this.modelMap.set(Site.Mcbbs, new Mcbbs(this.options)) + this.modelMap.set(Site.ChatDemo, new ChatDemo(this.options)) } get(model: Site): Chat | undefined {