@aituber-onair/core 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants/index.d.ts +0 -1
- package/dist/constants/index.js +0 -1
- package/dist/constants/index.js.map +1 -1
- package/dist/core/AITuberOnAirCore.d.ts +1 -1
- package/dist/core/AITuberOnAirCore.js +1 -1
- package/dist/core/AITuberOnAirCore.js.map +1 -1
- package/dist/index.d.ts +1 -3
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/dist/services/chat/providers/claude/ClaudeChatService.js +2 -7
- package/dist/services/chat/providers/claude/ClaudeChatService.js.map +1 -1
- package/dist/services/chat/providers/gemini/GeminiChatService.js +5 -10
- package/dist/services/chat/providers/gemini/GeminiChatService.js.map +1 -1
- package/dist/services/chat/providers/openai/OpenAIChatService.js +8 -27
- package/dist/services/chat/providers/openai/OpenAIChatService.js.map +1 -1
- package/dist/types/index.d.ts +1 -8
- package/dist/types/index.js +0 -6
- package/dist/types/index.js.map +1 -1
- package/dist/utils/chatServiceHttpClient.d.ts +46 -0
- package/dist/utils/chatServiceHttpClient.js +126 -0
- package/dist/utils/chatServiceHttpClient.js.map +1 -0
- package/dist/utils/emotionParser.d.ts +45 -0
- package/dist/utils/emotionParser.js +55 -0
- package/dist/utils/emotionParser.js.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/screenplay.js +5 -13
- package/dist/utils/screenplay.js.map +1 -1
- package/dist/utils/streamTextAccumulator.d.ts +24 -0
- package/dist/utils/streamTextAccumulator.js +43 -0
- package/dist/utils/streamTextAccumulator.js.map +1 -0
- package/package.json +4 -1
- package/dist/constants/voiceEngine.d.ts +0 -9
- package/dist/constants/voiceEngine.js +0 -12
- package/dist/constants/voiceEngine.js.map +0 -1
- package/dist/services/voice/VoiceEngineAdapter.d.ts +0 -46
- package/dist/services/voice/VoiceEngineAdapter.js +0 -205
- package/dist/services/voice/VoiceEngineAdapter.js.map +0 -1
- package/dist/services/voice/VoiceService.d.ts +0 -65
- package/dist/services/voice/VoiceService.js +0 -2
- package/dist/services/voice/VoiceService.js.map +0 -1
- package/dist/services/voice/engines/AivisSpeechEngine.d.ts +0 -16
- package/dist/services/voice/engines/AivisSpeechEngine.js +0 -80
- package/dist/services/voice/engines/AivisSpeechEngine.js.map +0 -1
- package/dist/services/voice/engines/MinimaxEngine.d.ts +0 -131
- package/dist/services/voice/engines/MinimaxEngine.js +0 -372
- package/dist/services/voice/engines/MinimaxEngine.js.map +0 -1
- package/dist/services/voice/engines/NijiVoiceEngine.d.ts +0 -11
- package/dist/services/voice/engines/NijiVoiceEngine.js +0 -105
- package/dist/services/voice/engines/NijiVoiceEngine.js.map +0 -1
- package/dist/services/voice/engines/NoneEngine.d.ts +0 -28
- package/dist/services/voice/engines/NoneEngine.js +0 -34
- package/dist/services/voice/engines/NoneEngine.js.map +0 -1
- package/dist/services/voice/engines/OpenAiEngine.d.ts +0 -9
- package/dist/services/voice/engines/OpenAiEngine.js +0 -35
- package/dist/services/voice/engines/OpenAiEngine.js.map +0 -1
- package/dist/services/voice/engines/VoiceEngine.d.ts +0 -25
- package/dist/services/voice/engines/VoiceEngine.js +0 -2
- package/dist/services/voice/engines/VoiceEngine.js.map +0 -1
- package/dist/services/voice/engines/VoiceEngineFactory.d.ts +0 -15
- package/dist/services/voice/engines/VoiceEngineFactory.js +0 -40
- package/dist/services/voice/engines/VoiceEngineFactory.js.map +0 -1
- package/dist/services/voice/engines/VoicePeakEngine.d.ts +0 -19
- package/dist/services/voice/engines/VoicePeakEngine.js +0 -58
- package/dist/services/voice/engines/VoicePeakEngine.js.map +0 -1
- package/dist/services/voice/engines/VoiceVoxEngine.d.ts +0 -19
- package/dist/services/voice/engines/VoiceVoxEngine.js +0 -77
- package/dist/services/voice/engines/VoiceVoxEngine.js.map +0 -1
- package/dist/services/voice/engines/index.d.ts +0 -8
- package/dist/services/voice/engines/index.js +0 -8
- package/dist/services/voice/engines/index.js.map +0 -1
- package/dist/services/voice/messages.d.ts +0 -3
- package/dist/services/voice/messages.js +0 -43
- package/dist/services/voice/messages.js.map +0 -1
- package/dist/types/nijiVoice.d.ts +0 -27
- package/dist/types/nijiVoice.js +0 -2
- package/dist/types/nijiVoice.js.map +0 -1
- package/dist/types/voice.d.ts +0 -35
- package/dist/types/voice.js +0 -19
- package/dist/types/voice.js.map +0 -1
- package/dist/types/voiceEngine.d.ts +0 -1
- package/dist/types/voiceEngine.js +0 -2
- package/dist/types/voiceEngine.js.map +0 -1
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP error response
|
|
3
|
+
*/
|
|
4
|
+
export class HttpError extends Error {
|
|
5
|
+
constructor(status, statusText, body) {
|
|
6
|
+
super(`HTTP ${status}: ${statusText}`);
|
|
7
|
+
this.status = status;
|
|
8
|
+
this.statusText = statusText;
|
|
9
|
+
this.body = body;
|
|
10
|
+
this.name = 'HttpError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Unified HTTP client for chat services
|
|
15
|
+
*/
|
|
16
|
+
export class ChatServiceHttpClient {
|
|
17
|
+
/**
|
|
18
|
+
* Make a POST request with common error handling
|
|
19
|
+
* @param url Request URL
|
|
20
|
+
* @param body Request body
|
|
21
|
+
* @param headers Request headers
|
|
22
|
+
* @param options Additional options
|
|
23
|
+
* @returns Response object
|
|
24
|
+
*/
|
|
25
|
+
static async post(url, body, headers = {}, options = {}) {
|
|
26
|
+
const { timeout = 30000, retries = 0, retryDelay = 1000 } = options;
|
|
27
|
+
// Default headers
|
|
28
|
+
const defaultHeaders = {
|
|
29
|
+
'Content-Type': 'application/json',
|
|
30
|
+
};
|
|
31
|
+
const finalHeaders = { ...defaultHeaders, ...headers };
|
|
32
|
+
let lastError = null;
|
|
33
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
34
|
+
try {
|
|
35
|
+
const controller = new AbortController();
|
|
36
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
37
|
+
const response = await fetch(url, {
|
|
38
|
+
method: 'POST',
|
|
39
|
+
headers: finalHeaders,
|
|
40
|
+
body: typeof body === 'string' ? body : JSON.stringify(body),
|
|
41
|
+
signal: controller.signal,
|
|
42
|
+
});
|
|
43
|
+
clearTimeout(timeoutId);
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
const errorBody = await response.text();
|
|
46
|
+
throw new HttpError(response.status, response.statusText, errorBody);
|
|
47
|
+
}
|
|
48
|
+
return response;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
lastError = error;
|
|
52
|
+
// Don't retry on client errors (4xx)
|
|
53
|
+
if (error instanceof HttpError &&
|
|
54
|
+
error.status >= 400 &&
|
|
55
|
+
error.status < 500) {
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
// Don't retry if aborted
|
|
59
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
60
|
+
throw new Error(`Request timeout after ${timeout}ms`);
|
|
61
|
+
}
|
|
62
|
+
// Wait before retrying
|
|
63
|
+
if (attempt < retries) {
|
|
64
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelay * (attempt + 1)));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
throw lastError || new Error('Request failed');
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Handle error response and throw appropriate error
|
|
72
|
+
* @param res Response object
|
|
73
|
+
* @returns Never (always throws)
|
|
74
|
+
*/
|
|
75
|
+
static async handleErrorResponse(res) {
|
|
76
|
+
const errorBody = await res.text();
|
|
77
|
+
throw new HttpError(res.status, res.statusText, errorBody);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Make a GET request (for fetching images, etc.)
|
|
81
|
+
* @param url Request URL
|
|
82
|
+
* @param headers Request headers
|
|
83
|
+
* @param options Additional options
|
|
84
|
+
* @returns Response object
|
|
85
|
+
*/
|
|
86
|
+
static async get(url, headers = {}, options = {}) {
|
|
87
|
+
const { timeout = 30000, retries = 0, retryDelay = 1000 } = options;
|
|
88
|
+
let lastError = null;
|
|
89
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
90
|
+
try {
|
|
91
|
+
const controller = new AbortController();
|
|
92
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
93
|
+
const response = await fetch(url, {
|
|
94
|
+
method: 'GET',
|
|
95
|
+
headers,
|
|
96
|
+
signal: controller.signal,
|
|
97
|
+
});
|
|
98
|
+
clearTimeout(timeoutId);
|
|
99
|
+
if (!response.ok) {
|
|
100
|
+
const errorBody = await response.text();
|
|
101
|
+
throw new HttpError(response.status, response.statusText, errorBody);
|
|
102
|
+
}
|
|
103
|
+
return response;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
lastError = error;
|
|
107
|
+
// Don't retry on client errors (4xx)
|
|
108
|
+
if (error instanceof HttpError &&
|
|
109
|
+
error.status >= 400 &&
|
|
110
|
+
error.status < 500) {
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
// Don't retry if aborted
|
|
114
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
115
|
+
throw new Error(`Request timeout after ${timeout}ms`);
|
|
116
|
+
}
|
|
117
|
+
// Wait before retrying
|
|
118
|
+
if (attempt < retries) {
|
|
119
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelay * (attempt + 1)));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
throw lastError || new Error('Request failed');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=chatServiceHttpClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chatServiceHttpClient.js","sourceRoot":"","sources":["../../src/utils/chatServiceHttpClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
declare const emotions: readonly ["happy", "sad", "angry", "surprised", "neutral"];
|
|
2
|
+
type EmotionType = (typeof emotions)[number];
|
|
3
|
+
/**
|
|
4
|
+
* Regular expressions for emotion tag parsing
|
|
5
|
+
*/
|
|
6
|
+
export declare const EMOTION_TAG_REGEX: RegExp;
|
|
7
|
+
export declare const EMOTION_TAG_CLEANUP_REGEX: RegExp;
|
|
8
|
+
/**
|
|
9
|
+
* Result of emotion extraction
|
|
10
|
+
*/
|
|
11
|
+
export interface EmotionExtractionResult {
|
|
12
|
+
emotion?: string;
|
|
13
|
+
cleanText: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Utility class for parsing and handling emotion tags in text
|
|
17
|
+
*/
|
|
18
|
+
export declare class EmotionParser {
|
|
19
|
+
/**
|
|
20
|
+
* Extract emotion from text and return clean text
|
|
21
|
+
* @param text Text that may contain emotion tags like [happy]
|
|
22
|
+
* @returns Object containing extracted emotion and clean text
|
|
23
|
+
*/
|
|
24
|
+
static extractEmotion(text: string): EmotionExtractionResult;
|
|
25
|
+
/**
|
|
26
|
+
* Check if an emotion is valid
|
|
27
|
+
* @param emotion Emotion string to validate
|
|
28
|
+
* @returns True if the emotion is valid
|
|
29
|
+
*/
|
|
30
|
+
static isValidEmotion(emotion: string): emotion is EmotionType;
|
|
31
|
+
/**
|
|
32
|
+
* Remove all emotion tags from text
|
|
33
|
+
* @param text Text containing emotion tags
|
|
34
|
+
* @returns Clean text without emotion tags
|
|
35
|
+
*/
|
|
36
|
+
static cleanEmotionTags(text: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Add emotion tag to text
|
|
39
|
+
* @param emotion Emotion to add
|
|
40
|
+
* @param text Text content
|
|
41
|
+
* @returns Text with emotion tag prepended
|
|
42
|
+
*/
|
|
43
|
+
static addEmotionTag(emotion: string, text: string): string;
|
|
44
|
+
}
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Define emotion types and list locally to avoid dependency on voice package
|
|
2
|
+
const emotions = ['happy', 'sad', 'angry', 'surprised', 'neutral'];
|
|
3
|
+
/**
|
|
4
|
+
* Regular expressions for emotion tag parsing
|
|
5
|
+
*/
|
|
6
|
+
export const EMOTION_TAG_REGEX = /\[([a-z]+)\]/i;
|
|
7
|
+
export const EMOTION_TAG_CLEANUP_REGEX = /\[[a-z]+\]\s*/gi;
|
|
8
|
+
/**
|
|
9
|
+
* Utility class for parsing and handling emotion tags in text
|
|
10
|
+
*/
|
|
11
|
+
export class EmotionParser {
|
|
12
|
+
/**
|
|
13
|
+
* Extract emotion from text and return clean text
|
|
14
|
+
* @param text Text that may contain emotion tags like [happy]
|
|
15
|
+
* @returns Object containing extracted emotion and clean text
|
|
16
|
+
*/
|
|
17
|
+
static extractEmotion(text) {
|
|
18
|
+
const match = text.match(EMOTION_TAG_REGEX);
|
|
19
|
+
if (match) {
|
|
20
|
+
const emotion = match[1].toLowerCase();
|
|
21
|
+
const cleanText = text.replace(EMOTION_TAG_CLEANUP_REGEX, '').trim();
|
|
22
|
+
return {
|
|
23
|
+
emotion,
|
|
24
|
+
cleanText,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return { cleanText: text };
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if an emotion is valid
|
|
31
|
+
* @param emotion Emotion string to validate
|
|
32
|
+
* @returns True if the emotion is valid
|
|
33
|
+
*/
|
|
34
|
+
static isValidEmotion(emotion) {
|
|
35
|
+
return emotions.includes(emotion);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Remove all emotion tags from text
|
|
39
|
+
* @param text Text containing emotion tags
|
|
40
|
+
* @returns Clean text without emotion tags
|
|
41
|
+
*/
|
|
42
|
+
static cleanEmotionTags(text) {
|
|
43
|
+
return text.replace(EMOTION_TAG_CLEANUP_REGEX, '').trim();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Add emotion tag to text
|
|
47
|
+
* @param emotion Emotion to add
|
|
48
|
+
* @param text Text content
|
|
49
|
+
* @returns Text with emotion tag prepended
|
|
50
|
+
*/
|
|
51
|
+
static addEmotionTag(emotion, text) {
|
|
52
|
+
return `[${emotion}] ${text}`;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=emotionParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emotionParser.js","sourceRoot":"","sources":["../../src/utils/emotionParser.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,CAAU,CAAC;AAG5E;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAe,CAAC;AACjD,MAAM,CAAC,MAAM,yBAAyB,GAAG,iBAAiB,CAAC;AAU3D;;GAEG;AACH,MAAM,OAAO,aAAa;IACxB;;;;OAIG;IACH,MAAM,CAAC,cAAc,CAAC,IAAY;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAE5C,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACvC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACrE,OAAO;gBACL,OAAO;gBACP,SAAS;aACV,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,cAAc,CAAC,OAAe;QACnC,OAAO,QAAQ,CAAC,QAAQ,CAAC,OAAc,CAAC,CAAC;IAC3C,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,gBAAgB,CAAC,IAAY;QAClC,OAAO,IAAI,CAAC,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5D,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,aAAa,CAAC,OAAe,EAAE,IAAY;QAChD,OAAO,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;IAChC,CAAC;CACF"}
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC"}
|
package/dist/utils/screenplay.js
CHANGED
|
@@ -1,26 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
* Extract emotion from text using regex
|
|
3
|
-
* Extract emotion from text written in the format [happy], [sad], etc.
|
|
4
|
-
*/
|
|
5
|
-
const EMOTION_REGEX = /\[([a-z]+)\]/i;
|
|
6
|
-
const EMOTION_CLEANUP_REGEX = /\[[a-z]+\]\s*/gi;
|
|
1
|
+
import { EmotionParser } from './emotionParser';
|
|
7
2
|
/**
|
|
8
3
|
* Convert text to screenplay (text with emotion)
|
|
9
4
|
* @param text Original text (may contain emotion expressions like [happy])
|
|
10
5
|
* @returns Screenplay object with emotion and text separated
|
|
11
6
|
*/
|
|
12
7
|
export function textToScreenplay(text) {
|
|
13
|
-
const
|
|
14
|
-
if (
|
|
15
|
-
const emotion = match[1].toLowerCase();
|
|
16
|
-
// Remove all emotion tags from the text and trim whitespace
|
|
17
|
-
const cleanText = text.replace(EMOTION_CLEANUP_REGEX, '').trim();
|
|
8
|
+
const { emotion, cleanText } = EmotionParser.extractEmotion(text);
|
|
9
|
+
if (emotion) {
|
|
18
10
|
return {
|
|
19
11
|
emotion,
|
|
20
12
|
text: cleanText,
|
|
21
13
|
};
|
|
22
14
|
}
|
|
23
|
-
return { text };
|
|
15
|
+
return { text: cleanText };
|
|
24
16
|
}
|
|
25
17
|
/**
|
|
26
18
|
* Convert multiple texts to screenplay array
|
|
@@ -37,7 +29,7 @@ export function textsToScreenplay(texts) {
|
|
|
37
29
|
*/
|
|
38
30
|
export function screenplayToText(screenplay) {
|
|
39
31
|
if (screenplay.emotion) {
|
|
40
|
-
return
|
|
32
|
+
return EmotionParser.addEmotionTag(screenplay.emotion, screenplay.text);
|
|
41
33
|
}
|
|
42
34
|
return screenplay.text;
|
|
43
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screenplay.js","sourceRoot":"","sources":["../../src/utils/screenplay.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"screenplay.js","sourceRoot":"","sources":["../../src/utils/screenplay.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAElE,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO;YACL,OAAO;YACP,IAAI,EAAE,SAAS;SAChB,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAC7B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAe;IAC/C,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAA0B;IACzD,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;QACvB,OAAO,aAAa,CAAC,aAAa,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,UAAU,CAAC,IAAI,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ToolChatBlock } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Utility class for accumulating text in streaming chat responses
|
|
4
|
+
*/
|
|
5
|
+
export declare class StreamTextAccumulator {
|
|
6
|
+
/**
|
|
7
|
+
* Append text to the blocks array, merging with the last block if it's a text block
|
|
8
|
+
* @param blocks Array of chat blocks
|
|
9
|
+
* @param text Text to append
|
|
10
|
+
*/
|
|
11
|
+
static append(blocks: ToolChatBlock[], text: string): void;
|
|
12
|
+
/**
|
|
13
|
+
* Get the full concatenated text from all text blocks
|
|
14
|
+
* @param blocks Array of chat blocks
|
|
15
|
+
* @returns Concatenated text from all text blocks
|
|
16
|
+
*/
|
|
17
|
+
static getFullText(blocks: ToolChatBlock[]): string;
|
|
18
|
+
/**
|
|
19
|
+
* Add a text block without merging
|
|
20
|
+
* @param blocks Array of chat blocks
|
|
21
|
+
* @param text Text to add as a new block
|
|
22
|
+
*/
|
|
23
|
+
static addTextBlock(blocks: ToolChatBlock[], text: string): void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility class for accumulating text in streaming chat responses
|
|
3
|
+
*/
|
|
4
|
+
export class StreamTextAccumulator {
|
|
5
|
+
/**
|
|
6
|
+
* Append text to the blocks array, merging with the last block if it's a text block
|
|
7
|
+
* @param blocks Array of chat blocks
|
|
8
|
+
* @param text Text to append
|
|
9
|
+
*/
|
|
10
|
+
static append(blocks, text) {
|
|
11
|
+
if (!text)
|
|
12
|
+
return;
|
|
13
|
+
const lastBlock = blocks[blocks.length - 1];
|
|
14
|
+
if (lastBlock && lastBlock.type === 'text') {
|
|
15
|
+
lastBlock.text += text;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
blocks.push({ type: 'text', text });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get the full concatenated text from all text blocks
|
|
23
|
+
* @param blocks Array of chat blocks
|
|
24
|
+
* @returns Concatenated text from all text blocks
|
|
25
|
+
*/
|
|
26
|
+
static getFullText(blocks) {
|
|
27
|
+
return blocks
|
|
28
|
+
.filter((block) => block.type === 'text')
|
|
29
|
+
.map((block) => block.text)
|
|
30
|
+
.join('');
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Add a text block without merging
|
|
34
|
+
* @param blocks Array of chat blocks
|
|
35
|
+
* @param text Text to add as a new block
|
|
36
|
+
*/
|
|
37
|
+
static addTextBlock(blocks, text) {
|
|
38
|
+
if (!text)
|
|
39
|
+
return;
|
|
40
|
+
blocks.push({ type: 'text', text });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=streamTextAccumulator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamTextAccumulator.js","sourceRoot":"","sources":["../../src/utils/streamTextAccumulator.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,OAAO,qBAAqB;IAChC;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,MAAuB,EAAE,IAAY;QACjD,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC5C,IAAI,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC3C,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAAC,MAAuB;QACxC,OAAO,MAAM;aACV,MAAM,CACL,CAAC,KAAK,EAA2C,EAAE,CACjD,KAAK,CAAC,IAAI,KAAK,MAAM,CACxB;aACA,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;aAC1B,IAAI,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,YAAY,CAAC,MAAuB,EAAE,IAAY;QACvD,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aituber-onair/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Core library for AITuber OnAir providing voice synthesis and chat processing",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -20,6 +20,9 @@
|
|
|
20
20
|
"keywords": ["aituber", "vtuber", "ai", "voice", "streaming"],
|
|
21
21
|
"author": "shinshin86 (https://github.com/shinshin86)",
|
|
22
22
|
"license": "MIT",
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@aituber-onair/voice": "^0.1.0"
|
|
25
|
+
},
|
|
23
26
|
"peerDependencies": {
|
|
24
27
|
"@pixiv/three-vrm": "^1.0.9"
|
|
25
28
|
},
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export declare const VOICE_VOX_API_URL = "http://localhost:50021";
|
|
2
|
-
export declare const VOICEPEAK_API_URL = "http://localhost:20202";
|
|
3
|
-
export declare const AIVIS_SPEECH_API_URL = "http://localhost:10101";
|
|
4
|
-
export declare const NIJI_VOICE_API_URL = "https://api.nijivoice.com/api/platform/v1";
|
|
5
|
-
export declare const OPENAI_TTS_API_URL = "https://api.openai.com/v1/audio/speech";
|
|
6
|
-
export declare const MINIMAX_GLOBAL_API_URL = "https://api.minimax.io/v1/t2a_v2";
|
|
7
|
-
export declare const MINIMAX_CHINA_API_URL = "https://api.minimaxi.com/v1/t2a_v2";
|
|
8
|
-
export declare const MINIMAX_GLOBAL_VOICE_LIST_URL = "https://api.minimax.io/v1/query/tts_speakers";
|
|
9
|
-
export declare const MINIMAX_CHINA_VOICE_LIST_URL = "https://api.minimaxi.com/v1/query/tts_speakers";
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export const VOICE_VOX_API_URL = 'http://localhost:50021';
|
|
2
|
-
export const VOICEPEAK_API_URL = 'http://localhost:20202';
|
|
3
|
-
export const AIVIS_SPEECH_API_URL = 'http://localhost:10101';
|
|
4
|
-
export const NIJI_VOICE_API_URL = 'https://api.nijivoice.com/api/platform/v1';
|
|
5
|
-
export const OPENAI_TTS_API_URL = 'https://api.openai.com/v1/audio/speech';
|
|
6
|
-
// MiniMax API endpoints
|
|
7
|
-
export const MINIMAX_GLOBAL_API_URL = 'https://api.minimax.io/v1/t2a_v2';
|
|
8
|
-
export const MINIMAX_CHINA_API_URL = 'https://api.minimaxi.com/v1/t2a_v2';
|
|
9
|
-
// MiniMax voice list endpoint
|
|
10
|
-
export const MINIMAX_GLOBAL_VOICE_LIST_URL = 'https://api.minimax.io/v1/query/tts_speakers';
|
|
11
|
-
export const MINIMAX_CHINA_VOICE_LIST_URL = 'https://api.minimaxi.com/v1/query/tts_speakers';
|
|
12
|
-
//# sourceMappingURL=voiceEngine.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"voiceEngine.js","sourceRoot":"","sources":["../../src/constants/voiceEngine.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,wBAAwB,CAAC;AAC1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,wBAAwB,CAAC;AAC1D,MAAM,CAAC,MAAM,oBAAoB,GAAG,wBAAwB,CAAC;AAC7D,MAAM,CAAC,MAAM,kBAAkB,GAAG,2CAA2C,CAAC;AAC9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,wCAAwC,CAAC;AAE3E,wBAAwB;AACxB,MAAM,CAAC,MAAM,sBAAsB,GAAG,kCAAkC,CAAC;AACzE,MAAM,CAAC,MAAM,qBAAqB,GAAG,oCAAoC,CAAC;AAE1E,8BAA8B;AAC9B,MAAM,CAAC,MAAM,6BAA6B,GACxC,8CAA8C,CAAC;AACjD,MAAM,CAAC,MAAM,4BAA4B,GACvC,gDAAgD,CAAC"}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { ChatScreenplay } from '../../types';
|
|
2
|
-
import { VoiceService, VoiceServiceOptions, AudioPlayOptions } from './VoiceService';
|
|
3
|
-
/**
|
|
4
|
-
* Adapter implementation for using existing voice engines
|
|
5
|
-
*/
|
|
6
|
-
export declare class VoiceEngineAdapter implements VoiceService {
|
|
7
|
-
private options;
|
|
8
|
-
private isPlayingAudio;
|
|
9
|
-
private audioElement;
|
|
10
|
-
/**
|
|
11
|
-
* Constructor
|
|
12
|
-
* @param options Voice service options
|
|
13
|
-
*/
|
|
14
|
-
constructor(options: VoiceServiceOptions);
|
|
15
|
-
/**
|
|
16
|
-
* Speak the screenplay as audio
|
|
17
|
-
* @param screenplay Screenplay (text and emotion)
|
|
18
|
-
* @param options Audio playback options
|
|
19
|
-
*/
|
|
20
|
-
speak(screenplay: ChatScreenplay, options?: AudioPlayOptions): Promise<void>;
|
|
21
|
-
/**
|
|
22
|
-
* Speak text as audio
|
|
23
|
-
* @param text Text (with emotion tags) to speak
|
|
24
|
-
* @param options Audio playback options
|
|
25
|
-
*/
|
|
26
|
-
speakText(text: string, options?: AudioPlayOptions): Promise<void>;
|
|
27
|
-
/**
|
|
28
|
-
* Get whether currently playing
|
|
29
|
-
*/
|
|
30
|
-
isPlaying(): boolean;
|
|
31
|
-
/**
|
|
32
|
-
* Stop playback
|
|
33
|
-
*/
|
|
34
|
-
stop(): void;
|
|
35
|
-
/**
|
|
36
|
-
* Update service settings
|
|
37
|
-
* @param options New settings options
|
|
38
|
-
*/
|
|
39
|
-
updateOptions(options: Partial<VoiceServiceOptions>): void;
|
|
40
|
-
/**
|
|
41
|
-
* Play audio buffer
|
|
42
|
-
* @param audioBuffer Audio data ArrayBuffer
|
|
43
|
-
* @param audioElementId ID of HTML element to play audio (use internal element if omitted)
|
|
44
|
-
*/
|
|
45
|
-
private playAudioBuffer;
|
|
46
|
-
}
|