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
3 changes: 3 additions & 0 deletions locales/ja/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,9 @@
"InputAudio": "音声",
"SearchGrounding": "検索機能を利用する",
"SearchGroundingDescription": "マルチモーダル機能利用時は、検索機能は自動的に無効になります。",
"DynamicRetrieval": "動的検索",
"DynamicRetrievalDescription": "モデルが検索を実行するタイミングしきい値を設定します。0の場合は常に検索を実行し、1の場合は検索を実行しません。",
"DynamicRetrievalThreshold": "動的しきい値",
"UpdateRealtimeAPISettings": "リアルタイムAPI設定を更新",
"UpdateRealtimeAPISettingsInfo": "APIキー、Azure Endpoint、ボイスタイプ、モデル、システムプロンプトを更新した際は更新ボタンを押して、新しいWebSocketセッションを開始してください。",
"AzureEndpoint": "Azure Endpoint",
Expand Down
4 changes: 2 additions & 2 deletions src/components/Live2DComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Application, Ticker, DisplayObject } from 'pixi.js'
import { useEffect, useRef, useState } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import { Live2DModel } from 'pixi-live2d-display-lipsyncpatch/cubism4'
import homeStore from '@/features/stores/home'
import settingsStore from '@/features/stores/settings'
Expand All @@ -18,7 +18,7 @@ const setModelPosition = (
model.y = app.renderer.height / 2
}

const Live2DComponent = () => {
const Live2DComponent = (): JSX.Element => {
console.log('Live2DComponent rendering')

const canvasContainerRef = useRef<HTMLCanvasElement>(null)
Expand Down
1 change: 1 addition & 0 deletions src/components/live2DViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const Live2DComponent = dynamic(
() => {
console.log('Loading Live2DComponent...')
return import('./Live2DComponent')
.then((mod) => mod.default)
.then((mod) => {
console.log('Live2DComponent loaded successfully')
return mod
Expand Down
49 changes: 44 additions & 5 deletions src/components/settings/modelProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ import { TextButton } from '../textButton'
import { useCallback } from 'react'
import Image from 'next/image'
import { Listbox } from '@headlessui/react'
import {
multiModalAIServices,
googleSearchGroundingModels,
} from '@/features/stores/settings'
import { multiModalAIServices } from '@/features/stores/settings'
import {
AudioModeInputType,
OpenAITTSVoice,
Expand All @@ -19,10 +16,11 @@ import {
RealtimeAPIModeAzureVoice,
} from '@/features/constants/settings'
import {
defaultModels,
getModels,
getOpenAIRealtimeModels,
getOpenAIAudioModels,
googleSearchGroundingModels,
defaultModels,
} from '@/features/constants/aiModels'
import toastStore from '@/features/stores/toast'
import webSocketStore from '@/features/stores/websocketStore'
Expand Down Expand Up @@ -89,6 +87,9 @@ const ModelProvider = () => {
const fireworksKey = settingsStore((s) => s.fireworksKey)
const difyKey = settingsStore((s) => s.difyKey)
const useSearchGrounding = settingsStore((s) => s.useSearchGrounding)
const dynamicRetrievalThreshold = settingsStore(
(s) => s.dynamicRetrievalThreshold
)
const deepseekKey = settingsStore((s) => s.deepseekKey)
const openrouterKey = settingsStore((s) => s.openrouterKey)
const maxPastMessages = settingsStore((s) => s.maxPastMessages)
Expand Down Expand Up @@ -573,6 +574,44 @@ const ModelProvider = () => {
{useSearchGrounding ? t('StatusOn') : t('StatusOff')}
</TextButton>
</div>

{useSearchGrounding &&
googleSearchGroundingModels.includes(
selectAIModel as any
) && (
<>
<div className="mt-6 mb-4 text-xl font-bold">
{t('DynamicRetrieval')}
</div>
<div className="my-4">
{t('DynamicRetrievalDescription')}
</div>

<div className="my-4">
<div className="mb-2 font-medium">
{t('DynamicRetrievalThreshold')}:{' '}
{dynamicRetrievalThreshold.toFixed(1)}
</div>
<div className="flex items-center">
<input
type="range"
min="0"
max="1"
step="0.1"
value={dynamicRetrievalThreshold}
onChange={(e) => {
settingsStore.setState({
dynamicRetrievalThreshold: parseFloat(
e.target.value
),
})
}}
className="mt-2 mb-4 input-range"
/>
</div>
</div>
</>
)}
</div>
</>
)
Expand Down
4 changes: 1 addition & 3 deletions src/features/chat/vercelAIChat.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { Message } from '../messages/messages'
import i18next from 'i18next'
import settingsStore, {
multiModalAIServiceKey,
} from '@/features/stores/settings'
import toastStore from '@/features/stores/toast'
import {
isVercelLocalAIService,
AIService,
} from '@/features/constants/settings'
import settingsStore from '../stores/settings'

const getAIConfig = () => {
const ss = settingsStore.getState()
Expand Down
16 changes: 14 additions & 2 deletions src/features/constants/aiModels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ export const aiModels: Record<AIService, string[]> = {
'claude-3-5-haiku-20241022',
],
google: [
'gemini-2.0-flash-001',
'gemini-2.5-pro-preview-05-06',
'gemini-2.5-flash-preview-04-17',
'gemini-2.5-pro-exp-03-25',
'gemini-2.0-flash',
'gemini-1.5-flash-latest',
'gemini-1.5-flash-8b-latest',
'gemini-1.5-pro-latest',
Expand Down Expand Up @@ -95,7 +98,10 @@ export const slideConvertModels: Partial<Record<AIService, string[]>> = {
'claude-3-5-haiku-20241022',
],
google: [
'gemini-2.0-flash-001',
'gemini-2.5-pro-preview-05-06',
'gemini-2.5-flash-preview-04-17',
'gemini-2.5-pro-exp-03-25',
'gemini-2.0-flash',
'gemini-1.5-flash-latest',
'gemini-1.5-flash-8b-latest',
'gemini-1.5-pro-latest',
Expand Down Expand Up @@ -228,3 +234,9 @@ export const openAITTSModels = ['tts-1', 'tts-1-hd', 'gpt-4o-mini-tts'] as const
export function getOpenAITTSModels(): string[] {
return [...openAITTSModels]
}

export const googleSearchGroundingModels = [
'gemini-1.5-flash-latest',
'gemini-1.5-pro-latest',
'gemini-1.5-flash-8b-latest',
] as const
8 changes: 3 additions & 5 deletions src/features/stores/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
SpeechRecognitionMode,
WhisperTranscriptionModel,
} from '../constants/settings'
import { googleSearchGroundingModels } from '../constants/aiModels'

export const multiModalAIServices = [
'openai',
Expand All @@ -25,11 +26,6 @@ export const multiModalAIServices = [
] as const
export type multiModalAIServiceKey = (typeof multiModalAIServices)[number]

export const googleSearchGroundingModels = [
'gemini-1.5-flash-latest',
'gemini-1.5-pro-latest',
'gemini-2.0-flash-001',
] as const
export type googleSearchGroundingModelKey =
(typeof googleSearchGroundingModels)[number]

Expand Down Expand Up @@ -175,6 +171,7 @@ interface General {
messageReceiverEnabled: boolean
clientId: string
useSearchGrounding: boolean
dynamicRetrievalThreshold: number
maxPastMessages: number
useVideoAsBackground: boolean
temperature: number
Expand Down Expand Up @@ -384,6 +381,7 @@ const settingsStore = create<SettingsState>()(
clientId: '',
useSearchGrounding:
process.env.NEXT_PUBLIC_USE_SEARCH_GROUNDING === 'true',
dynamicRetrievalThreshold: 0.3,
maxPastMessages:
parseInt(process.env.NEXT_PUBLIC_MAX_PAST_MESSAGES || '10') || 10,
useVideoAsBackground:
Expand Down
17 changes: 16 additions & 1 deletion src/pages/api/ai/vercel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
streamAiText,
generateAiText,
} from '../services/vercelAi'
import { googleSearchGroundingModels } from '@/features/constants/aiModels'

export const config = {
runtime: 'edge',
Expand Down Expand Up @@ -39,6 +40,7 @@ export default async function handler(req: NextRequest) {
azureEndpoint,
stream,
useSearchGrounding,
dynamicRetrievalThreshold,
temperature = 1.0,
maxTokens = 4096,
} = await req.json()
Expand Down Expand Up @@ -142,7 +144,20 @@ export default async function handler(req: NextRequest) {
aiService === 'google' &&
useSearchGrounding &&
modifiedMessages.every((msg) => typeof msg.content === 'string')
const options = isUseSearchGrounding ? { useSearchGrounding: true } : {}

let options = {}
if (isUseSearchGrounding) {
options = {
useSearchGrounding: true,
...(dynamicRetrievalThreshold !== undefined &&
googleSearchGroundingModels.includes(modifiedModel as any) && {
dynamicRetrievalConfig: {
dynamicThreshold: dynamicRetrievalThreshold,
},
}),
}
}

console.log('options', options)

// ストリーミングレスポンスまたは一括レスポンスの生成
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@
".next/types/**/*.ts",
"src/types/**/*.d.ts"
],
"exclude": ["node_modules", ".mypy_cache", "scripts"]
"exclude": ["node_modules", ".mypy_cache", "scripts", "website"]
}