Skip to content

Commit e831f39

Browse files
committed
refactor: add 2.0 flash model w/ attachment capability, some refactors
1 parent a3a29e1 commit e831f39

12 files changed

Lines changed: 85 additions & 75 deletions

File tree

apps/backend-convex/functions/threads/action.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { simpleMessagesToString } from '@local/common/src/aisdk'
1+
import { simpleMessagesToString } from '@local/common/src/chat'
22
import { openrouter } from '@openrouter/ai-sdk-provider'
33
import { generateText } from 'ai'
44
import { v } from 'convex/values'

apps/backend-convex/utils/agent.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { AgentObject } from '@local/common/src/aisdk'
1+
import type { AgentObject } from '@local/common/src/chat'
22
import type { LanguageModelV1 } from '@openrouter/ai-sdk-provider'
33
import { createAnthropic } from '@ai-sdk/anthropic'
44
import { createGoogleGenerativeAI } from '@ai-sdk/google'
@@ -17,6 +17,8 @@ export function getAgentModel({ provider, model, apiKey }: AgentObject): Languag
1717
return openrouter('mistralai/devstral-small:free')
1818
case 'llama-4-scout':
1919
return openrouter('meta-llama/llama-4-scout:free')
20+
case 'gemini-2.0-flash-exp':
21+
return openrouter('google/gemini-2.0-flash-exp:free')
2022
default:
2123
throw new Error(`Invalid model for hosted provider`)
2224
}

apps/backend-convex/utils/message.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { AgentObject } from '@local/common/src/aisdk'
1+
import type { AgentObject } from '@local/common/src/chat'
22
import type { Doc } from '../convex/_generated/dataModel'
33

44
export interface BuiltMessage {

apps/frontend/app/components/chat/ChatRootApp.vue

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script setup lang="ts">
2+
import type { AgentsSettings, HostedProvider } from '@local/common/src/chat'
23
import type { Doc } from 'backend-convex/convex/_generated/dataModel'
34
import { keyBy } from '@namesmt/utils'
45
import { useIDBKeyval } from '@vueuse/integrations/useIDBKeyval'
@@ -7,14 +8,14 @@ import { SidebarProvider } from '@/lib/shadcn/components/ui/sidebar'
78
// Load all async data
89
const { data: threads, isFinished: threadsLoaded } = useIDBKeyval<Doc<'threads'>[]>('chat/threads', [])
910
const { data: pinnedThreadIds, isFinished: pinnedThreadIdsLoaded } = useIDBKeyval<string[]>('chat/pinnedThreadIds', [])
10-
const { data: agentsSetting, isFinished: agentsSettingLoaded } = useIDBKeyval<AgentsSetting>('chat/agentsSetting', {
11+
const { data: agentsSettings, isFinished: agentsSettingsLoaded } = useIDBKeyval<AgentsSettings>('chat/agentsSettings', {
1112
providers: {
1213
},
1314
selectedAgent: 'hosted/qwen3-32b',
1415
})
1516
1617
await until(computed(() =>
17-
threadsLoaded.value && agentsSettingLoaded.value && pinnedThreadIdsLoaded.value,
18+
threadsLoaded.value && agentsSettingsLoaded.value && pinnedThreadIdsLoaded.value,
1819
)).toBeTruthy({ timeout: 60000, throwOnTimeout: true })
1920
2021
// ## Threads
@@ -47,18 +48,28 @@ const hostedProvider = computed<HostedProvider>(() => ({
4748
'llama-4-scout': {
4849
enabled: true,
4950
},
51+
'gemini-2.0-flash-exp': {
52+
enabled: true,
53+
attachments: ['image/png', 'image/jpeg', 'image/webp', 'application/pdf', 'text/plain'],
54+
},
5055
},
5156
default: 'qwen3-32b',
5257
}))
5358
5459
const activeAgent = computed(() => {
55-
let [provider, model] = agentsSetting.value.selectedAgent?.split(/\/(.*)/) as
56-
[keyof typeof agentsSetting.value.providers | 'hosted', string]
60+
let [provider, model]: [string, string] = agentsSettings.value.selectedAgent?.split(/\/(.*)/) as any
5761
58-
if (!provider || !model || (provider !== 'hosted' && !agentsSetting.value.providers[provider]))
62+
if (!provider || !model || (provider !== 'hosted' && !agentsSettings.value.providers[provider]))
5963
[provider, model] = ['hosted', hostedProvider.value.default!]
6064
61-
return { provider, model, apiKey: agentsSetting.value.providers[provider]?.apiKey }
65+
return {
66+
provider,
67+
model,
68+
modelSettings: provider === 'hosted'
69+
? hostedProvider.value.models[model]
70+
: agentsSettings.value.providers[provider]?.models[model],
71+
apiKey: agentsSettings.value.providers[provider]?.apiKey,
72+
}
6273
})
6374
6475
provideChatContext({
@@ -68,7 +79,7 @@ provideChatContext({
6879
activeThread,
6980
7081
hostedProvider,
71-
agentsSetting,
82+
agentsSettings,
7283
activeAgent,
7384
7485
insaneUI: useLocalState('chat/insaneUI', () => false),

apps/frontend/app/components/chat/interface/AgentSelector.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script setup lang="ts">
22
const chatContext = useChatContext()
33
const enabledProviders = computed(() =>
4-
Object.entries(chatContext.agentsSetting.value.providers).filter(([_, v]) => v.enabled),
4+
Object.entries(chatContext.agentsSettings.value.providers).filter(([_, v]) => v.enabled),
55
)
66
77
const activeAgentDisplay = computed(() => displayActiveAgent(chatContext.activeAgent.value))
@@ -25,7 +25,7 @@ const activeAgentDisplay = computed(() => displayActiveAgent(chatContext.activeA
2525
<DropdownMenuItem
2626
v-for="[model] of Object.entries(chatContext.hostedProvider.value.models).filter((([_m, v]) => v.enabled))"
2727
:key="model"
28-
@click="chatContext.agentsSetting.value.selectedAgent = `hosted/${model}`"
28+
@click="chatContext.agentsSettings.value.selectedAgent = `hosted/${model}`"
2929
>
3030
{{ model }}
3131
</DropdownMenuItem>
@@ -36,7 +36,7 @@ const activeAgentDisplay = computed(() => displayActiveAgent(chatContext.activeA
3636
<DropdownMenuItem
3737
v-for="[model] of Object.entries(providerSettings.models).filter((([_m, v]) => v.enabled))"
3838
:key="model"
39-
@click="chatContext.agentsSetting.value.selectedAgent = `${provider}/${model}`"
39+
@click="chatContext.agentsSettings.value.selectedAgent = `${provider}/${model}`"
4040
>
4141
{{ model }}
4242
</DropdownMenuItem>

apps/frontend/app/components/chat/settings/GeneralSettingsSheet.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import Switch from '~/lib/shadcn/components/ui/switch/Switch.vue'
1212
1313
const { $auth } = useNuxtApp()
1414
const sidebarContext = useSidebar()
15-
const { agentsSetting } = useChatContext()
15+
const { agentsSettings } = useChatContext()
1616
const { locale, locales, setLocale } = useI18n()
1717
const computedNextLocale = computed(() => {
1818
const currentLocaleIndex = locales.value.findIndex(lO => lO.code === locale.value)
@@ -24,8 +24,8 @@ const supportedProvidersCommon = ['openrouter', 'openai', 'google', 'anthropic',
2424
2525
// Bootstraping object data for the supported providers
2626
for (const provider of supportedProvidersCommon) {
27-
if (!agentsSetting.value.providers[provider]) {
28-
agentsSetting.value.providers[provider] = {
27+
if (!agentsSettings.value.providers[provider]) {
28+
agentsSettings.value.providers[provider] = {
2929
enabled: false,
3030
apiKey: '',
3131
models: {
@@ -98,7 +98,7 @@ const [DefineShortcutLi, ReuseShortcutLi] = createReusableTemplate<{ title: stri
9898
</SheetHeader>
9999

100100
<div
101-
v-for="[provider, setting] of supportedProvidersCommon.map((p) => [p, agentsSetting.providers[p]!] as const)"
101+
v-for="[provider, setting] of supportedProvidersCommon.map((p) => [p, agentsSettings.providers[p]!] as const)"
102102
:key="provider"
103103
class="flex items-center justify-between gap-2"
104104
>

apps/frontend/app/components/chat/settings/ProviderSettingsDialog.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script setup lang="ts">
2+
import type { CommonProviderAgentsSettings } from '@local/common/src/chat'
23
import {
34
Dialog,
45
DialogContent,
@@ -22,7 +23,7 @@ const {
2223
settings,
2324
} = defineProps<{
2425
name: string
25-
settings: CommonProviderAgentsSetting
26+
settings: CommonProviderAgentsSettings
2627
}>()
2728
2829
const modelsRef = ref(Object.keys(settings.models))
@@ -31,7 +32,7 @@ watch(modelsRef, () => {
3132
settings.models = modelsRef.value.reduce((obj, m) => {
3233
obj[m] = { enabled: true }
3334
return obj
34-
}, {} as CommonProviderAgentsSetting['models'])
35+
}, {} as CommonProviderAgentsSettings['models'])
3536
})
3637
</script>
3738

apps/frontend/app/utils/chat.ts

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,16 @@
11
import type { Message } from '@ai-sdk/vue'
2-
import type { AgentObject } from '@local/common/src/aisdk'
2+
import type { AgentObject, AgentsSettings, HostedProvider } from '@local/common/src/chat'
33
import type { Doc, Id } from 'backend-convex/convex/_generated/dataModel'
44
import { createContext } from 'reka-ui'
55

6-
export interface AgentsSetting {
7-
providers: {
8-
/**
9-
* Note that `hosted` will not be accessible here and not persisted to IDB
10-
*/
11-
[name: string]: CommonProviderAgentsSetting
12-
}
13-
/**
14-
* A special string in format of `provider/model`, `model` could be empty
15-
* so that the default model is always used (in the future where we add multi-acounts settings link)
16-
*
17-
* Note that `selectedAgent` is not the source of truth whether
18-
* which model is used, bad config will fallback to default hosted model.
19-
*/
20-
selectedAgent: string
21-
}
22-
23-
export interface CommonProviderAgentsSetting {
24-
enabled: boolean
25-
apiKey?: string
26-
models: {
27-
[key: string]: {
28-
enabled: boolean
29-
}
30-
}
31-
default?: string
32-
}
33-
34-
export interface HostedProvider {
35-
enabled: true
36-
apiKey?: string
37-
models: {
38-
[key: string]: {
39-
enabled: boolean
40-
}
41-
}
42-
default: string
43-
}
44-
456
export interface ChatContext {
467
threads: Ref<Doc<'threads'>[]>
478
threadsKeyed: ComputedRef<Record<Doc<'threads'>['_id'], Doc<'threads'>>>
489
pinnedThreadIds: Ref<string[]>
4910
activeThread: ComputedRef<Doc<'threads'> | undefined>
5011

5112
hostedProvider: ComputedRef<HostedProvider>
52-
agentsSetting: Ref<AgentsSetting>
13+
agentsSettings: Ref<AgentsSettings>
5314
/**
5415
* The resolved active agent
5516
*/

i18n.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ checksums:
1212
chat.alert.shareThread.title: e00e8208d2dd52a00a4cbccdc57199e3
1313
chat.components.chatSearchDialog.enterToSend.p2: 8200cd3e922c0c7e39704491c3e5773a
1414
chat.components.chatSearchDialog.noResultsFound: 8e37a23d37d7b4f501a20991a0d311ea
15-
chat.components.chatSearchDialog.placeholder: 276dc6685b4414d6dfbb0df54d74b8bd
15+
chat.components.chatSearchDialog.placeholder: 2d652853f7644696961d0e41102ab5b6
1616
chat.interface.selectOrStart: 5ae94ab41d0b599f36924f5db15dd16d
1717
chat.interface.sendToStart: 6ba07995188dc929a2de0e8f0bb4d1ea
1818
chat.message.branch: 8ee786a7be37ef90ade2cd00741f8dd0

locals/common/src/aisdk.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)