mirror of
https://github.com/idootop/mi-gpt.git
synced 2025-04-07 22:49:21 +00:00
misc: add stream answer for AI response
This commit is contained in:
parent
631876d2ac
commit
db9adb652d
|
@ -4,10 +4,11 @@ import {
|
|||
SpeakerCommand,
|
||||
SpeakerConfig,
|
||||
QueryMessage,
|
||||
SpeakerAnswer,
|
||||
} from "./speaker";
|
||||
|
||||
export type AISpeakerConfig = SpeakerConfig & {
|
||||
askAI?: (msg: QueryMessage) => Promise<string>;
|
||||
askAI?: (msg: QueryMessage) => Promise<SpeakerAnswer>;
|
||||
/**
|
||||
* 切换音色前缀
|
||||
*
|
||||
|
@ -200,7 +201,7 @@ export class AISpeaker extends Speaker {
|
|||
];
|
||||
|
||||
async askAIForAnswer(msg: QueryMessage) {
|
||||
let data: any = {};
|
||||
let data: { answer?: SpeakerAnswer } = {};
|
||||
const { hasNewMsg } = this.checkIfHasNewMsg(msg);
|
||||
for (const action of this._askAIForAnswerSteps) {
|
||||
const res = await action(msg, data);
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
} from "mi-service-lite";
|
||||
import { sleep } from "../../utils/base";
|
||||
import { Http } from "../http";
|
||||
import { ResponseStream } from "./stream";
|
||||
import { StreamResponse } from "./stream";
|
||||
|
||||
export type TTSProvider = "xiaoai" | "doubao";
|
||||
|
||||
|
@ -59,7 +59,7 @@ export class BaseSpeaker {
|
|||
async response(options: {
|
||||
tts?: TTSProvider;
|
||||
text?: string;
|
||||
stream?: ResponseStream;
|
||||
stream?: StreamResponse;
|
||||
audio?: string;
|
||||
speaker?: string;
|
||||
keepAlive?: boolean;
|
||||
|
@ -79,7 +79,7 @@ export class BaseSpeaker {
|
|||
|
||||
if (ttsNotXiaoai && !stream) {
|
||||
// 长文本 TTS 转化成 stream 分段模式
|
||||
stream = ResponseStream.createResponseStream(text!);
|
||||
stream = StreamResponse.createStreamResponse(text!);
|
||||
}
|
||||
|
||||
let res;
|
||||
|
@ -139,7 +139,7 @@ export class BaseSpeaker {
|
|||
private async _response(options: {
|
||||
tts?: TTSProvider;
|
||||
text?: string;
|
||||
stream?: ResponseStream;
|
||||
stream?: StreamResponse;
|
||||
audio?: string;
|
||||
speaker?: string;
|
||||
keepAlive?: boolean;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { firstOf, lastOf, sleep } from "../../utils/base";
|
||||
import { BaseSpeaker, BaseSpeakerConfig } from "./base";
|
||||
import { StreamResponse } from "./stream";
|
||||
|
||||
export interface QueryMessage {
|
||||
text: string;
|
||||
|
@ -10,12 +11,18 @@ export interface QueryMessage {
|
|||
timestamp: number;
|
||||
}
|
||||
|
||||
export interface SpeakerAnswer {
|
||||
text?: string;
|
||||
url?: string;
|
||||
steam?: StreamResponse;
|
||||
}
|
||||
|
||||
export interface SpeakerCommand {
|
||||
match: (msg: QueryMessage) => boolean;
|
||||
/**
|
||||
* 命中后执行的操作,返回值非空时会自动回复给用户
|
||||
*/
|
||||
run: (msg: QueryMessage) => Promise<string | undefined | void>;
|
||||
run: (msg: QueryMessage) => Promise<SpeakerAnswer | undefined | void>;
|
||||
}
|
||||
|
||||
export type SpeakerConfig = BaseSpeakerConfig & {
|
||||
|
@ -105,7 +112,7 @@ export class Speaker extends BaseSpeaker {
|
|||
if (answer) {
|
||||
if (noNewMsg()) {
|
||||
await this.response({
|
||||
text: answer,
|
||||
...answer,
|
||||
keepAlive: this.keepAlive,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
type ResponseStatus = "idle" | "responding" | "finished" | "canceled";
|
||||
|
||||
interface ResponseStreamOptions {
|
||||
interface StreamResponseOptions {
|
||||
/**
|
||||
* 单次响应句子的最大长度
|
||||
*/
|
||||
|
@ -23,12 +23,12 @@ interface ResponseStreamOptions {
|
|||
batchSubmitTimeout?: number;
|
||||
}
|
||||
|
||||
export class ResponseStream {
|
||||
export class StreamResponse {
|
||||
// 将已有的大篇文字回复 chuck 成 stream 回复
|
||||
static createResponseStream(text: string, options?: ResponseStreamOptions) {
|
||||
static createStreamResponse(text: string, options?: StreamResponseOptions) {
|
||||
const { maxSentenceLength = 100 } = options ?? {};
|
||||
if (text.length > maxSentenceLength) {
|
||||
const stream = new ResponseStream(options);
|
||||
const stream = new StreamResponse(options);
|
||||
stream.addResponse(text);
|
||||
stream.finish();
|
||||
return stream;
|
||||
|
@ -38,7 +38,7 @@ export class ResponseStream {
|
|||
maxSentenceLength: number;
|
||||
firstSubmitTimeout: number;
|
||||
batchSubmitTimeout: number;
|
||||
constructor(options?: ResponseStreamOptions) {
|
||||
constructor(options?: StreamResponseOptions) {
|
||||
const {
|
||||
maxSentenceLength = 100,
|
||||
firstSubmitTimeout = 200,
|
||||
|
@ -173,7 +173,7 @@ export class ResponseStream {
|
|||
}
|
||||
}
|
||||
|
||||
const stream = new ResponseStream();
|
||||
const stream = new StreamResponse();
|
||||
|
||||
// ai onNewText
|
||||
// {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { AISpeaker } from "../src/services/speaker/ai";
|
||||
import { ResponseStream } from "../src/services/speaker/stream";
|
||||
import { StreamResponse } from "../src/services/speaker/stream";
|
||||
import { sleep } from "../src/utils/base";
|
||||
|
||||
export async function testSpeaker() {
|
||||
|
@ -13,16 +13,16 @@ export async function testSpeaker() {
|
|||
const speaker = new AISpeaker(config);
|
||||
await speaker.initMiServices();
|
||||
// await testSpeakerResponse(speaker);
|
||||
await testSpeakerStreamResponse(speaker);
|
||||
// await testSpeakerStreamResponse(speaker);
|
||||
// await testSpeakerGetMessages(speaker);
|
||||
// await testSwitchSpeaker(speaker);
|
||||
// await testSpeakerUnWakeUp(speaker);
|
||||
// await testAISpeaker(speaker);
|
||||
await testAISpeaker(speaker);
|
||||
}
|
||||
|
||||
async function testAISpeaker(speaker: AISpeaker) {
|
||||
speaker.askAI = async (msg) => {
|
||||
return "你说:" + msg.text;
|
||||
return { text: "你说:" + msg.text };
|
||||
};
|
||||
await speaker.run();
|
||||
console.log("finished");
|
||||
|
@ -60,7 +60,7 @@ async function testSpeakerResponse(speaker: AISpeaker) {
|
|||
}
|
||||
|
||||
async function testSpeakerStreamResponse(speaker: AISpeaker) {
|
||||
const stream = new ResponseStream();
|
||||
const stream = new StreamResponse();
|
||||
const add = async (text: string) => {
|
||||
stream.addResponse(text);
|
||||
await sleep(100);
|
||||
|
|
Loading…
Reference in New Issue
Block a user