@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.
Files changed (84) hide show
  1. package/dist/constants/index.d.ts +0 -1
  2. package/dist/constants/index.js +0 -1
  3. package/dist/constants/index.js.map +1 -1
  4. package/dist/core/AITuberOnAirCore.d.ts +1 -1
  5. package/dist/core/AITuberOnAirCore.js +1 -1
  6. package/dist/core/AITuberOnAirCore.js.map +1 -1
  7. package/dist/index.d.ts +1 -3
  8. package/dist/index.js +10 -2
  9. package/dist/index.js.map +1 -1
  10. package/dist/services/chat/providers/claude/ClaudeChatService.js +2 -7
  11. package/dist/services/chat/providers/claude/ClaudeChatService.js.map +1 -1
  12. package/dist/services/chat/providers/gemini/GeminiChatService.js +5 -10
  13. package/dist/services/chat/providers/gemini/GeminiChatService.js.map +1 -1
  14. package/dist/services/chat/providers/openai/OpenAIChatService.js +8 -27
  15. package/dist/services/chat/providers/openai/OpenAIChatService.js.map +1 -1
  16. package/dist/types/index.d.ts +1 -8
  17. package/dist/types/index.js +0 -6
  18. package/dist/types/index.js.map +1 -1
  19. package/dist/utils/chatServiceHttpClient.d.ts +46 -0
  20. package/dist/utils/chatServiceHttpClient.js +126 -0
  21. package/dist/utils/chatServiceHttpClient.js.map +1 -0
  22. package/dist/utils/emotionParser.d.ts +45 -0
  23. package/dist/utils/emotionParser.js +55 -0
  24. package/dist/utils/emotionParser.js.map +1 -0
  25. package/dist/utils/index.d.ts +3 -0
  26. package/dist/utils/index.js +3 -0
  27. package/dist/utils/index.js.map +1 -1
  28. package/dist/utils/screenplay.js +5 -13
  29. package/dist/utils/screenplay.js.map +1 -1
  30. package/dist/utils/streamTextAccumulator.d.ts +24 -0
  31. package/dist/utils/streamTextAccumulator.js +43 -0
  32. package/dist/utils/streamTextAccumulator.js.map +1 -0
  33. package/package.json +4 -1
  34. package/dist/constants/voiceEngine.d.ts +0 -9
  35. package/dist/constants/voiceEngine.js +0 -12
  36. package/dist/constants/voiceEngine.js.map +0 -1
  37. package/dist/services/voice/VoiceEngineAdapter.d.ts +0 -46
  38. package/dist/services/voice/VoiceEngineAdapter.js +0 -205
  39. package/dist/services/voice/VoiceEngineAdapter.js.map +0 -1
  40. package/dist/services/voice/VoiceService.d.ts +0 -65
  41. package/dist/services/voice/VoiceService.js +0 -2
  42. package/dist/services/voice/VoiceService.js.map +0 -1
  43. package/dist/services/voice/engines/AivisSpeechEngine.d.ts +0 -16
  44. package/dist/services/voice/engines/AivisSpeechEngine.js +0 -80
  45. package/dist/services/voice/engines/AivisSpeechEngine.js.map +0 -1
  46. package/dist/services/voice/engines/MinimaxEngine.d.ts +0 -131
  47. package/dist/services/voice/engines/MinimaxEngine.js +0 -372
  48. package/dist/services/voice/engines/MinimaxEngine.js.map +0 -1
  49. package/dist/services/voice/engines/NijiVoiceEngine.d.ts +0 -11
  50. package/dist/services/voice/engines/NijiVoiceEngine.js +0 -105
  51. package/dist/services/voice/engines/NijiVoiceEngine.js.map +0 -1
  52. package/dist/services/voice/engines/NoneEngine.d.ts +0 -28
  53. package/dist/services/voice/engines/NoneEngine.js +0 -34
  54. package/dist/services/voice/engines/NoneEngine.js.map +0 -1
  55. package/dist/services/voice/engines/OpenAiEngine.d.ts +0 -9
  56. package/dist/services/voice/engines/OpenAiEngine.js +0 -35
  57. package/dist/services/voice/engines/OpenAiEngine.js.map +0 -1
  58. package/dist/services/voice/engines/VoiceEngine.d.ts +0 -25
  59. package/dist/services/voice/engines/VoiceEngine.js +0 -2
  60. package/dist/services/voice/engines/VoiceEngine.js.map +0 -1
  61. package/dist/services/voice/engines/VoiceEngineFactory.d.ts +0 -15
  62. package/dist/services/voice/engines/VoiceEngineFactory.js +0 -40
  63. package/dist/services/voice/engines/VoiceEngineFactory.js.map +0 -1
  64. package/dist/services/voice/engines/VoicePeakEngine.d.ts +0 -19
  65. package/dist/services/voice/engines/VoicePeakEngine.js +0 -58
  66. package/dist/services/voice/engines/VoicePeakEngine.js.map +0 -1
  67. package/dist/services/voice/engines/VoiceVoxEngine.d.ts +0 -19
  68. package/dist/services/voice/engines/VoiceVoxEngine.js +0 -77
  69. package/dist/services/voice/engines/VoiceVoxEngine.js.map +0 -1
  70. package/dist/services/voice/engines/index.d.ts +0 -8
  71. package/dist/services/voice/engines/index.js +0 -8
  72. package/dist/services/voice/engines/index.js.map +0 -1
  73. package/dist/services/voice/messages.d.ts +0 -3
  74. package/dist/services/voice/messages.js +0 -43
  75. package/dist/services/voice/messages.js.map +0 -1
  76. package/dist/types/nijiVoice.d.ts +0 -27
  77. package/dist/types/nijiVoice.js +0 -2
  78. package/dist/types/nijiVoice.js.map +0 -1
  79. package/dist/types/voice.d.ts +0 -35
  80. package/dist/types/voice.js +0 -19
  81. package/dist/types/voice.js.map +0 -1
  82. package/dist/types/voiceEngine.d.ts +0 -1
  83. package/dist/types/voiceEngine.js +0 -2
  84. 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"}
@@ -4,3 +4,6 @@
4
4
  export * from './screenshot';
5
5
  export * from './screenplay';
6
6
  export * from './storage';
7
+ export * from './emotionParser';
8
+ export * from './streamTextAccumulator';
9
+ export * from './chatServiceHttpClient';
@@ -4,4 +4,7 @@
4
4
  export * from './screenshot';
5
5
  export * from './screenplay';
6
6
  export * from './storage';
7
+ export * from './emotionParser';
8
+ export * from './streamTextAccumulator';
9
+ export * from './chatServiceHttpClient';
7
10
  //# sourceMappingURL=index.js.map
@@ -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"}
@@ -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 match = text.match(EMOTION_REGEX);
14
- if (match) {
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 `[${screenplay.emotion}] ${screenplay.text}`;
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":"AAEA;;;GAGG;AACH,MAAM,aAAa,GAAG,eAAe,CAAC;AACtC,MAAM,qBAAqB,GAAG,iBAAiB,CAAC;AAEhD;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAExC,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACvC,4DAA4D;QAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACjE,OAAO;YACL,OAAO;YACP,IAAI,EAAE,SAAS;SAChB,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,CAAC;AAClB,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,IAAI,UAAU,CAAC,OAAO,KAAK,UAAU,CAAC,IAAI,EAAE,CAAC;IACtD,CAAC;IACD,OAAO,UAAU,CAAC,IAAI,CAAC;AACzB,CAAC"}
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.14.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
- }