@rimori/react-client 0.4.11-next.3 → 0.4.11-next.4
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/components/ai/Avatar.d.ts +3 -1
- package/dist/components/ai/Avatar.js +8 -2
- package/dist/components/ai/BuddyAssistant.d.ts +3 -1
- package/dist/components/ai/BuddyAssistant.js +12 -4
- package/dist/components/audio/Playbutton.d.ts +4 -0
- package/dist/components/audio/Playbutton.js +4 -3
- package/package.json +3 -3
- package/src/components/ai/Avatar.tsx +11 -1
- package/src/components/ai/BuddyAssistant.tsx +15 -3
- package/src/components/audio/Playbutton.tsx +10 -2
|
@@ -10,6 +10,8 @@ interface Props {
|
|
|
10
10
|
autoStartConversation?: FirstMessages;
|
|
11
11
|
className?: string;
|
|
12
12
|
knowledgeId?: string;
|
|
13
|
+
/** Set to true to disable automatic dialect TTS from userInfo. Default: false (dialect enabled). */
|
|
14
|
+
disableDialect?: boolean;
|
|
13
15
|
}
|
|
14
|
-
export declare function Avatar({ avatarImageUrl, voiceId, agentTools, autoStartConversation, children, circleSize, className, cache, knowledgeId, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export declare function Avatar({ avatarImageUrl, voiceId, agentTools, autoStartConversation, children, circleSize, className, cache, knowledgeId, disableDialect, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
15
17
|
export {};
|
|
@@ -7,12 +7,18 @@ import { useChat } from '../../hooks/UseChatHook';
|
|
|
7
7
|
import { useRimori } from '../../providers/PluginProvider';
|
|
8
8
|
import { getFirstMessages } from './utils';
|
|
9
9
|
import { useTheme } from '../../hooks/ThemeSetter';
|
|
10
|
-
export function Avatar({ avatarImageUrl, voiceId, agentTools, autoStartConversation, children, circleSize = '300px', className, cache = false, knowledgeId, }) {
|
|
11
|
-
const { ai, event, plugin } = useRimori();
|
|
10
|
+
export function Avatar({ avatarImageUrl, voiceId, agentTools, autoStartConversation, children, circleSize = '300px', className, cache = false, knowledgeId, disableDialect = false, }) {
|
|
11
|
+
const { ai, event, plugin, userInfo } = useRimori();
|
|
12
12
|
const { isDark: isDarkThemeValue } = useTheme(plugin.theme);
|
|
13
13
|
const [agentReplying, setAgentReplying] = useState(false);
|
|
14
14
|
const [isProcessingMessage, setIsProcessingMessage] = useState(false);
|
|
15
|
+
const dialectTtsInstruction = !disableDialect && (userInfo === null || userInfo === void 0 ? void 0 : userInfo.dialect)
|
|
16
|
+
? `Speak with a ${userInfo.dialect} accent and pronunciation.`
|
|
17
|
+
: undefined;
|
|
15
18
|
const sender = useMemo(() => new MessageSender((...args) => ai.getVoice(...args), voiceId, cache), [voiceId, ai, cache]);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
sender.setInstructions(dialectTtsInstruction);
|
|
21
|
+
}, [sender, dialectTtsInstruction]);
|
|
16
22
|
const { messages, append, isLoading, lastMessage, setMessages } = useChat(agentTools, { knowledgeId });
|
|
17
23
|
useEffect(() => {
|
|
18
24
|
console.log('messages', messages);
|
|
@@ -15,5 +15,7 @@ export interface BuddyAssistantProps {
|
|
|
15
15
|
className?: string;
|
|
16
16
|
voiceSpeed?: number;
|
|
17
17
|
tools?: Tool[];
|
|
18
|
+
/** Set to true to disable automatic dialect from userInfo. Default: false (dialect enabled). */
|
|
19
|
+
disableDialect?: boolean;
|
|
18
20
|
}
|
|
19
|
-
export declare function BuddyAssistant({ systemPrompt, autoStartConversation, circleSize, chatPlaceholder, bottomAction, className, voiceSpeed, tools, }: BuddyAssistantProps): JSX.Element;
|
|
21
|
+
export declare function BuddyAssistant({ systemPrompt, autoStartConversation, circleSize, chatPlaceholder, bottomAction, className, voiceSpeed, tools, disableDialect, }: BuddyAssistantProps): JSX.Element;
|
|
@@ -9,11 +9,16 @@ import { HiMiniSpeakerWave, HiMiniSpeakerXMark } from 'react-icons/hi2';
|
|
|
9
9
|
import { BiSolidRightArrow } from 'react-icons/bi';
|
|
10
10
|
let idCounter = 0;
|
|
11
11
|
const genId = () => `ba-${++idCounter}`;
|
|
12
|
-
export function BuddyAssistant({ systemPrompt, autoStartConversation, circleSize = '160px', chatPlaceholder, bottomAction, className, voiceSpeed = 1, tools, }) {
|
|
12
|
+
export function BuddyAssistant({ systemPrompt, autoStartConversation, circleSize = '160px', chatPlaceholder, bottomAction, className, voiceSpeed = 1, tools, disableDialect = false, }) {
|
|
13
13
|
var _a;
|
|
14
|
-
const { ai, event, plugin } = useRimori();
|
|
14
|
+
const { ai, event, plugin, userInfo } = useRimori();
|
|
15
15
|
const { isDark } = useTheme(plugin.theme);
|
|
16
16
|
const buddy = (_a = plugin.getUserInfo()) === null || _a === void 0 ? void 0 : _a.study_buddy;
|
|
17
|
+
const dialect = !disableDialect ? userInfo === null || userInfo === void 0 ? void 0 : userInfo.dialect : undefined;
|
|
18
|
+
const dialectSystemSuffix = dialect
|
|
19
|
+
? `\n\nThe user is learning the regional ${dialect} dialect. Occasionally use typical regional vocabulary and expressions from this dialect to help them learn local language naturally.`
|
|
20
|
+
: '';
|
|
21
|
+
const dialectTtsInstruction = dialect ? `Speak with a ${dialect} accent and pronunciation.` : undefined;
|
|
17
22
|
const [ttsEnabled, setTtsEnabled] = useState(true);
|
|
18
23
|
const [chatInput, setChatInput] = useState('');
|
|
19
24
|
const [messages, setMessages] = useState([]);
|
|
@@ -24,6 +29,9 @@ export function BuddyAssistant({ systemPrompt, autoStartConversation, circleSize
|
|
|
24
29
|
ttsEnabledRef.current = ttsEnabled;
|
|
25
30
|
}, [ttsEnabled]);
|
|
26
31
|
const sender = useMemo(() => { var _a; return new MessageSender((...args) => ai.getVoice(...args), (_a = buddy === null || buddy === void 0 ? void 0 : buddy.voiceId) !== null && _a !== void 0 ? _a : ''); }, [buddy === null || buddy === void 0 ? void 0 : buddy.voiceId, ai]);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
sender.setInstructions(dialectTtsInstruction);
|
|
34
|
+
}, [sender, dialectTtsInstruction]);
|
|
27
35
|
// Setup sender callbacks and cleanup
|
|
28
36
|
useEffect(() => {
|
|
29
37
|
sender.setVoiceSpeed(voiceSpeed);
|
|
@@ -31,9 +39,9 @@ export function BuddyAssistant({ systemPrompt, autoStartConversation, circleSize
|
|
|
31
39
|
sender.setOnEndOfSpeech(() => setIsSpeaking(false));
|
|
32
40
|
return () => sender.cleanup();
|
|
33
41
|
}, [sender]);
|
|
34
|
-
// Build full API message list with system prompt
|
|
42
|
+
// Build full API message list with system prompt (dialect appended when enabled)
|
|
35
43
|
const buildApiMessages = (history) => [
|
|
36
|
-
{ role: 'system', content: systemPrompt },
|
|
44
|
+
{ role: 'system', content: systemPrompt + dialectSystemSuffix },
|
|
37
45
|
...history.map((m) => ({ role: m.role, content: m.content })),
|
|
38
46
|
];
|
|
39
47
|
const triggerAI = (history) => {
|
|
@@ -10,6 +10,10 @@ type AudioPlayerProps = {
|
|
|
10
10
|
enableSpeedAdjustment?: boolean;
|
|
11
11
|
playListenerEvent?: string;
|
|
12
12
|
size?: string;
|
|
13
|
+
/** Explicit TTS instruction string. If provided, overrides auto-dialect. */
|
|
14
|
+
ttsInstructions?: string;
|
|
15
|
+
/** Set to true to disable automatic dialect from userInfo. Default: false (dialect enabled). */
|
|
16
|
+
disableDialect?: boolean;
|
|
13
17
|
};
|
|
14
18
|
export declare const AudioPlayOptions: number[];
|
|
15
19
|
export type AudioPlayOptionType = 0.8 | 0.9 | 1.0 | 1.1 | 1.2 | 1.5;
|
|
@@ -14,12 +14,12 @@ import { useRimori } from '../../providers/PluginProvider';
|
|
|
14
14
|
import { EventBus } from '@rimori/client';
|
|
15
15
|
export const AudioPlayOptions = [0.8, 0.9, 1.0, 1.1, 1.2, 1.5];
|
|
16
16
|
let isFetchingAudio = false;
|
|
17
|
-
export const AudioPlayer = ({ text, voice, language, hide, playListenerEvent, initialSpeed = 1.0, playOnMount = false, enableSpeedAdjustment = false, cache = true, size = '25px', }) => {
|
|
17
|
+
export const AudioPlayer = ({ text, voice, language, hide, playListenerEvent, initialSpeed = 1.0, playOnMount = false, enableSpeedAdjustment = false, cache = true, size = '25px', ttsInstructions, disableDialect = false, }) => {
|
|
18
18
|
const [audioUrl, setAudioUrl] = useState(null);
|
|
19
19
|
const [speed, setSpeed] = useState(initialSpeed);
|
|
20
20
|
const [isPlaying, setIsPlaying] = useState(false);
|
|
21
21
|
const [isLoading, setIsLoading] = useState(false);
|
|
22
|
-
const { ai } = useRimori();
|
|
22
|
+
const { ai, userInfo } = useRimori();
|
|
23
23
|
const audioRef = useRef(null);
|
|
24
24
|
const eventBusListenerRef = useRef(null);
|
|
25
25
|
useEffect(() => {
|
|
@@ -33,7 +33,8 @@ export const AudioPlayer = ({ text, voice, language, hide, playListenerEvent, in
|
|
|
33
33
|
// Function to generate audio from text using API
|
|
34
34
|
const generateAudio = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
35
35
|
setIsLoading(true);
|
|
36
|
-
const
|
|
36
|
+
const effectiveInstructions = ttsInstructions !== null && ttsInstructions !== void 0 ? ttsInstructions : (!disableDialect && (userInfo === null || userInfo === void 0 ? void 0 : userInfo.dialect) ? `Speak with a ${userInfo.dialect} accent and pronunciation.` : undefined);
|
|
37
|
+
const blob = yield ai.getVoice(text, voice || (language ? 'aws_default' : 'openai_alloy'), 1, language, cache, effectiveInstructions);
|
|
37
38
|
setAudioUrl(URL.createObjectURL(blob));
|
|
38
39
|
setIsLoading(false);
|
|
39
40
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rimori/react-client",
|
|
3
|
-
"version": "0.4.11-next.
|
|
3
|
+
"version": "0.4.11-next.4",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"format": "prettier --write ."
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
|
-
"@rimori/client": "2.5.
|
|
27
|
+
"@rimori/client": "2.5.20-next.1",
|
|
28
28
|
"react": "^18.1.0",
|
|
29
29
|
"react-dom": "^18.1.0"
|
|
30
30
|
},
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@eslint/js": "^9.37.0",
|
|
50
|
-
"@rimori/client": "2.5.
|
|
50
|
+
"@rimori/client": "2.5.20-next.1",
|
|
51
51
|
"@types/react": "^18.3.21",
|
|
52
52
|
"eslint-config-prettier": "^10.1.8",
|
|
53
53
|
"eslint-plugin-prettier": "^5.5.4",
|
|
@@ -19,6 +19,8 @@ interface Props {
|
|
|
19
19
|
autoStartConversation?: FirstMessages;
|
|
20
20
|
className?: string;
|
|
21
21
|
knowledgeId?: string;
|
|
22
|
+
/** Set to true to disable automatic dialect TTS from userInfo. Default: false (dialect enabled). */
|
|
23
|
+
disableDialect?: boolean;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
export function Avatar({
|
|
@@ -31,15 +33,23 @@ export function Avatar({
|
|
|
31
33
|
className,
|
|
32
34
|
cache = false,
|
|
33
35
|
knowledgeId,
|
|
36
|
+
disableDialect = false,
|
|
34
37
|
}: Props) {
|
|
35
|
-
const { ai, event, plugin } = useRimori();
|
|
38
|
+
const { ai, event, plugin, userInfo } = useRimori();
|
|
36
39
|
const { isDark: isDarkThemeValue } = useTheme(plugin.theme);
|
|
37
40
|
const [agentReplying, setAgentReplying] = useState(false);
|
|
38
41
|
const [isProcessingMessage, setIsProcessingMessage] = useState(false);
|
|
42
|
+
const dialectTtsInstruction = !disableDialect && userInfo?.dialect
|
|
43
|
+
? `Speak with a ${userInfo.dialect} accent and pronunciation.`
|
|
44
|
+
: undefined;
|
|
39
45
|
const sender = useMemo(
|
|
40
46
|
() => new MessageSender((...args) => ai.getVoice(...args), voiceId, cache),
|
|
41
47
|
[voiceId, ai, cache],
|
|
42
48
|
);
|
|
49
|
+
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
sender.setInstructions(dialectTtsInstruction);
|
|
52
|
+
}, [sender, dialectTtsInstruction]);
|
|
43
53
|
const { messages, append, isLoading, lastMessage, setMessages } = useChat(agentTools, { knowledgeId });
|
|
44
54
|
|
|
45
55
|
useEffect(() => {
|
|
@@ -25,6 +25,8 @@ export interface BuddyAssistantProps {
|
|
|
25
25
|
className?: string;
|
|
26
26
|
voiceSpeed?: number;
|
|
27
27
|
tools?: Tool[];
|
|
28
|
+
/** Set to true to disable automatic dialect from userInfo. Default: false (dialect enabled). */
|
|
29
|
+
disableDialect?: boolean;
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
let idCounter = 0;
|
|
@@ -39,10 +41,16 @@ export function BuddyAssistant({
|
|
|
39
41
|
className,
|
|
40
42
|
voiceSpeed = 1,
|
|
41
43
|
tools,
|
|
44
|
+
disableDialect = false,
|
|
42
45
|
}: BuddyAssistantProps): JSX.Element {
|
|
43
|
-
const { ai, event, plugin } = useRimori();
|
|
46
|
+
const { ai, event, plugin, userInfo } = useRimori();
|
|
44
47
|
const { isDark } = useTheme(plugin.theme);
|
|
45
48
|
const buddy = plugin.getUserInfo()?.study_buddy;
|
|
49
|
+
const dialect = !disableDialect ? userInfo?.dialect : undefined;
|
|
50
|
+
const dialectSystemSuffix = dialect
|
|
51
|
+
? `\n\nThe user is learning the regional ${dialect} dialect. Occasionally use typical regional vocabulary and expressions from this dialect to help them learn local language naturally.`
|
|
52
|
+
: '';
|
|
53
|
+
const dialectTtsInstruction = dialect ? `Speak with a ${dialect} accent and pronunciation.` : undefined;
|
|
46
54
|
|
|
47
55
|
const [ttsEnabled, setTtsEnabled] = useState(true);
|
|
48
56
|
const [chatInput, setChatInput] = useState('');
|
|
@@ -60,6 +68,10 @@ export function BuddyAssistant({
|
|
|
60
68
|
[buddy?.voiceId, ai],
|
|
61
69
|
);
|
|
62
70
|
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
sender.setInstructions(dialectTtsInstruction);
|
|
73
|
+
}, [sender, dialectTtsInstruction]);
|
|
74
|
+
|
|
63
75
|
// Setup sender callbacks and cleanup
|
|
64
76
|
useEffect(() => {
|
|
65
77
|
sender.setVoiceSpeed(voiceSpeed);
|
|
@@ -68,9 +80,9 @@ export function BuddyAssistant({
|
|
|
68
80
|
return () => sender.cleanup();
|
|
69
81
|
}, [sender]);
|
|
70
82
|
|
|
71
|
-
// Build full API message list with system prompt
|
|
83
|
+
// Build full API message list with system prompt (dialect appended when enabled)
|
|
72
84
|
const buildApiMessages = (history: ChatMessage[]) => [
|
|
73
|
-
{ role: 'system' as const, content: systemPrompt },
|
|
85
|
+
{ role: 'system' as const, content: systemPrompt + dialectSystemSuffix },
|
|
74
86
|
...history.map((m) => ({ role: m.role, content: m.content })),
|
|
75
87
|
];
|
|
76
88
|
|
|
@@ -14,6 +14,10 @@ type AudioPlayerProps = {
|
|
|
14
14
|
enableSpeedAdjustment?: boolean;
|
|
15
15
|
playListenerEvent?: string;
|
|
16
16
|
size?: string;
|
|
17
|
+
/** Explicit TTS instruction string. If provided, overrides auto-dialect. */
|
|
18
|
+
ttsInstructions?: string;
|
|
19
|
+
/** Set to true to disable automatic dialect from userInfo. Default: false (dialect enabled). */
|
|
20
|
+
disableDialect?: boolean;
|
|
17
21
|
};
|
|
18
22
|
|
|
19
23
|
export const AudioPlayOptions = [0.8, 0.9, 1.0, 1.1, 1.2, 1.5];
|
|
@@ -32,12 +36,14 @@ export const AudioPlayer: React.FC<AudioPlayerProps> = ({
|
|
|
32
36
|
enableSpeedAdjustment = false,
|
|
33
37
|
cache = true,
|
|
34
38
|
size = '25px',
|
|
39
|
+
ttsInstructions,
|
|
40
|
+
disableDialect = false,
|
|
35
41
|
}) => {
|
|
36
42
|
const [audioUrl, setAudioUrl] = useState<string | null>(null);
|
|
37
43
|
const [speed, setSpeed] = useState(initialSpeed);
|
|
38
44
|
const [isPlaying, setIsPlaying] = useState(false);
|
|
39
45
|
const [isLoading, setIsLoading] = useState(false);
|
|
40
|
-
const { ai } = useRimori();
|
|
46
|
+
const { ai, userInfo } = useRimori();
|
|
41
47
|
const audioRef = useRef<HTMLAudioElement | null>(null);
|
|
42
48
|
const eventBusListenerRef = useRef<{ off: () => void } | null>(null);
|
|
43
49
|
|
|
@@ -52,7 +58,9 @@ export const AudioPlayer: React.FC<AudioPlayerProps> = ({
|
|
|
52
58
|
const generateAudio = async () => {
|
|
53
59
|
setIsLoading(true);
|
|
54
60
|
|
|
55
|
-
const
|
|
61
|
+
const effectiveInstructions = ttsInstructions
|
|
62
|
+
?? (!disableDialect && userInfo?.dialect ? `Speak with a ${userInfo.dialect} accent and pronunciation.` : undefined);
|
|
63
|
+
const blob = await ai.getVoice(text, voice || (language ? 'aws_default' : 'openai_alloy'), 1, language, cache, effectiveInstructions);
|
|
56
64
|
setAudioUrl(URL.createObjectURL(blob));
|
|
57
65
|
setIsLoading(false);
|
|
58
66
|
};
|