Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -182,5 +182,15 @@
"OpenAITTSModel": "Model",
"OpenAITTSSpeed": "Speed",
"UsingAzureTTS": "Using Azure OpenAI",
"AzureTTSInfo": "Using Azure OpenAI. It supports multiple languages."
"AzureTTSInfo": "Using Azure OpenAI. It supports multiple languages.",
"SendMessage": {
"title": "AITuberKit External Adapter",
"directSendTitle": "Directly speak to AI character",
"directSendDescription": "You can send the message directly to the AI character. If multiple messages are sent, they are processed in order. The voice model is the one selected in the AITuberKit settings.",
"aiGenerateTitle": "Generate AI response and then speak",
"aiGenerateDescription": "The AI generates a response from the message sent and then speaks it. If multiple messages are sent, they are processed in order. The AI model and voice model are the ones selected in the AITuberKit settings. The system prompt can be selected to use the AITuberKit system prompt or a custom system prompt. If you want to load the past conversation history, include the string [conversation_history] in the system prompt or user message.",
"useCurrentSystemPrompt": "Use AITuberKit system prompt",
"userInputTitle": "Send user input",
"userInputDescription": "The message sent is processed the same as when input from the AITuberKit input form. If multiple messages are sent, they are processed in order. The AI model and voice model are the ones selected in the AITuberKit settings. The system prompt and conversation history are the values set in AITuberKit."
}
}
12 changes: 11 additions & 1 deletion locales/ja/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -183,5 +183,15 @@
"OpenAITTSModel": "モデル",
"OpenAITTSSpeed": "話速",
"UsingAzureTTS": "Azure OpenAIを使用する",
"AzureTTSInfo": "Azure OpenAIを使用しています。多言語に対応可能です。"
"AzureTTSInfo": "Azure OpenAIを使用しています。多言語に対応可能です。",
"SendMessage": {
"title": "AITuberKit 外部アダプター",
"directSendTitle": "AIキャラにそのまま発言させる",
"directSendDescription": "送信したメッセージをそのままAIキャラに発言させることができます。複数送信した場合は順番に処理されます。\n音声モデルはAITuberKitの設定で選択したものが使用されます。",
"aiGenerateTitle": "AIで回答を生成してから発言させる",
"aiGenerateDescription": "送信したメッセージからAIが回答を生成し、その回答をAIキャラに発言させます。複数送信した場合は順番に処理されます。\nAIモデルおよび音声モデルはAITuberKitの設定で選択したものが使用されます。\nシステムプロンプトはAITuberKitのシステムプロンプトを使用するか、カスタムのシステムプロンプトを使用するかを選択できます。\n過去の会話履歴を読み込ませる場合は、システムプロンプト または ユーザーメッセージの任意の位置に [conversation_history] という文字列を含めてください。",
"useCurrentSystemPrompt": "AITuberKitのシステムプロンプトを利用する",
"userInputTitle": "ユーザー入力を送信する",
"userInputDescription": "送信したメッセージはAITuberKitの入力フォームから入力された場合と同じ処理がされます。複数送信した場合は順番に処理されます。\nAIモデルおよび音声モデルはAITuberKitの設定で選択したものが使用されます。\nシステムプロンプトや会話履歴はAITuberKitの値が使用されます。"
}
}
12 changes: 11 additions & 1 deletion locales/ko/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -182,5 +182,15 @@
"OpenAITTSModel": "모델",
"OpenAITTSSpeed": "말 속도",
"UsingAzureTTS": "Azure OpenAI 사용",
"AzureTTSInfo": "Azure OpenAI를 사용하고 있습니다. 다국어에 대응할 수 있습니다."
"AzureTTSInfo": "Azure OpenAI를 사용하고 있습니다. 다국어에 대응할 수 있습니다.",
"SendMessage": {
"title": "AITuberKit 외부 어댑터",
"directSendTitle": "AI 캐릭터에 직접 말하기",
"directSendDescription": "보낸 메시지를 그대로 AI 캐릭터에게 말하게 할 수 있습니다. 여러 메시지를 보낸 경우 순서대로 처리됩니다.\n음성 모델은 AITuberKit의 설정에서 선택한 것이 사용됩니다.",
"aiGenerateTitle": "AI가 답변을 생성한 후 말하기",
"aiGenerateDescription": "보낸 메시지에서 AI가 답변을 생성하고, 그 답변을 AI 캐릭터에게 말하게 할 수 있습니다. 여러 메시지를 보낸 경우 순서대로 처리됩니다.\nAI 모델과 음성 모델은 AITuberKit의 설정에서 선택한 것이 사용됩니다.\n시스템 프롬프트는 AITuberKit의 시스템 프롬프트를 사용하거나, 커스텀 시스템 프롬프트를 사용하거나 선택할 수 있습니다.\n과거 대화 기록을 불러오려면 시스템 프롬프트 또는 사용자 메시지의 임의의 위치에 [conversation_history]라는 문자열을 포함해 주세요.",
"useCurrentSystemPrompt": "AITuberKit의 시스템 프롬프트를 사용하기",
"userInputTitle": "사용자 입력 보내기",
"userInputDescription": "보낸 메시지는 AITuberKit의 입력 폼에서 입력한 경우와 동일한 처리가 됩니다. 여러 메시지를 보낸 경우 순서대로 처리됩니다.\nAI 모델과 음성 모델은 AITuberKit의 설정에서 선택한 것이 사용됩니다.\n시스템 프롬프트와 대화 기록은 AITuberKit의 값이 사용됩니다."
}
}
12 changes: 11 additions & 1 deletion locales/zh/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -182,5 +182,15 @@
"OpenAITTSModel": "模型",
"OpenAITTSSpeed": "話速",
"UsingAzureTTS": "使用 Azure OpenAI",
"AzureTTSInfo": "使用 Azure OpenAI。它支援多種語言。"
"AzureTTSInfo": "使用 Azure OpenAI。它支援多種語言。",
"SendMessage": {
"title": "AITuberKit 外部適配器",
"directSendTitle": "AI角色直接發言",
"directSendDescription": "發送的訊息將直接由AI角色發言。如果發送多個訊息,將按順序處理。\n語音模型將使用AITuberKit的設定中選擇的模型。",
"aiGenerateTitle": "AI生成回答後發言",
"aiGenerateDescription": "從發送的訊息中由AI生成回答,然後由AI角色發言。如果發送多個訊息,將按順序處理。\nAI模型和語音模型將使用AITuberKit的設定中選擇的模型。\n系統提示可以選擇使用AITuberKit的系統提示或自定義的系統提示。\n如果需要讀取過去的會話記錄,請在系統提示或用戶訊息的任意位置包含 [conversation_history] 字串。",
"useCurrentSystemPrompt": "使用AITuberKit的系統提示",
"userInputTitle": "用戶輸入發送",
"userInputDescription": "發送的訊息將與AITuberKit的輸入框中輸入的訊息相同。如果發送多個訊息,將按順序處理。\nAI模型和語音模型將使用AITuberKit的設定中選擇的模型。\n系統提示和會話記錄將使用AITuberKit的值。"
}
}
10 changes: 1 addition & 9 deletions src/components/form.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { useCallback, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'

import settingsStore from '@/features/stores/settings'
import homeStore from '@/features/stores/home'
import menuStore from '@/features/stores/menu'
Expand All @@ -17,14 +15,8 @@ export const Form = () => {
const slideVisible = menuStore((s) => s.slideVisible)
const slidePlaying = slideStore((s) => s.isPlaying)
const chatProcessingCount = homeStore((s) => s.chatProcessingCount)

const [delayedText, setDelayedText] = useState('')

const { t } = useTranslation()
const handleSendChat = handleSendChatFn({
NotConnectedToExternalAssistant: t('NotConnectedToExternalAssistant'),
APIKeyNotEntered: t('APIKeyNotEntered'),
})
const handleSendChat = handleSendChatFn()

useEffect(() => {
// テキストと画像がそろったら、チャットを送信
Expand Down
68 changes: 62 additions & 6 deletions src/components/messageReceiver.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,79 @@
import { useEffect, useState, useCallback } from 'react'
import { speakMessageHandler } from '@/features/chat/handlers'
import {
speakMessageHandler,
processAIResponse,
handleSendChatFn,
} from '@/features/chat/handlers'
import settingsStore from '@/features/stores/settings'
import homeStore from '@/features/stores/home'
import { Message } from '@/features/messages/messages'

class Message {
class ReceivedMessage {
timestamp: number
message: string
type: 'direct_send' | 'ai_generate' | 'user_input'
systemPrompt?: string
useCurrentSystemPrompt?: boolean

constructor(timestamp: number, message: string) {
constructor(
timestamp: number,
message: string,
type: 'direct_send' | 'ai_generate' | 'user_input',
systemPrompt?: string,
useCurrentSystemPrompt?: boolean
) {
this.timestamp = timestamp
this.message = message
this.type = type
this.systemPrompt = systemPrompt
this.useCurrentSystemPrompt = useCurrentSystemPrompt
}
}

const MessageReceiver = () => {
const [lastTimestamp, setLastTimestamp] = useState(0)
const clientId = settingsStore((state) => state.clientId)

const speakMessage = useCallback((messages: Message[]) => {
messages.forEach((message) => speakMessageHandler(message.message))
const speakMessage = useCallback(async (messages: ReceivedMessage[]) => {
const hs = homeStore.getState()
const ss = settingsStore.getState()

for (const message of messages) {
if (message.type === 'direct_send') {
await speakMessageHandler(message.message)
} else if (message.type === 'ai_generate') {
const conversationHistory = [
...hs.chatLog.slice(-10),
{ role: 'user', content: message.message },
]
.map((m) => `${m.role}: ${m.content}`)
.join('\n')
const systemPrompt = message.useCurrentSystemPrompt
? ss.systemPrompt
: message.systemPrompt
const messages: Message[] = [
{
role: 'system',
content: systemPrompt?.replace(
'[conversation_history]',
conversationHistory
),
},
{
role: 'user',
content: message.message.replace(
'[conversation_history]',
conversationHistory
),
},
]
await processAIResponse(hs.chatLog, messages)
} else if (message.type === 'user_input') {
await handleSendChatFn()(message.message)
} else {
console.error('Invalid message type:', message.type)
}
}
}, [])

useEffect(() => {
Expand Down Expand Up @@ -47,7 +103,7 @@ const MessageReceiver = () => {
const intervalId = setInterval(fetchMessages, 1000)

return () => clearInterval(intervalId)
}, [clientId, speakMessage])
}, [clientId, lastTimestamp, speakMessage])

return <></>
}
Expand Down
7 changes: 1 addition & 6 deletions src/components/youtubeManager.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import { FC } from 'react'
import useYoutube from './useYoutube'
import { handleSendChatFn } from '@/features/chat/handlers'
import { useTranslation } from 'react-i18next'

export const YoutubeManager: FC = () => {
const { t } = useTranslation()
const handleSendChat = handleSendChatFn({
NotConnectedToExternalAssistant: t('NotConnectedToExternalAssistant'),
APIKeyNotEntered: t('APIKeyNotEntered'),
})
const handleSendChat = handleSendChatFn()

useYoutube({ handleSendChat })

Expand Down
Loading
Loading