@vibe-forge/client 0.4.0 → 0.5.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 (63) hide show
  1. package/cli.cjs +1 -0
  2. package/dist/assets/{arc-DgIxeTMg.js → arc-C4ymrcSQ.js} +1 -1
  3. package/dist/assets/{blockDiagram-c4efeb88-CEAob3X9.js → blockDiagram-c4efeb88-CeB7-kgP.js} +1 -1
  4. package/dist/assets/{c4Diagram-c83219d4-DwIxpDKd.js → c4Diagram-c83219d4-C935Im8S.js} +1 -1
  5. package/dist/assets/channel-84s1ACzD.js +1 -0
  6. package/dist/assets/{classDiagram-beda092f-Cz1q8u_0.js → classDiagram-beda092f-B9IV13KI.js} +1 -1
  7. package/dist/assets/{classDiagram-v2-2358418a-CImgTuwd.js → classDiagram-v2-2358418a-CXF_K4fE.js} +1 -1
  8. package/dist/assets/clone-B2E8tddE.js +1 -0
  9. package/dist/assets/{createText-1719965b-C1_HJcCc.js → createText-1719965b-DwX8iC5F.js} +1 -1
  10. package/dist/assets/{edges-96097737-BU8qStzd.js → edges-96097737-9P1uH1RE.js} +1 -1
  11. package/dist/assets/{erDiagram-0228fc6a-DNA1Fz2L.js → erDiagram-0228fc6a-ixeGTFvg.js} +1 -1
  12. package/dist/assets/{flowDb-c6c81e3f-DjiCStMN.js → flowDb-c6c81e3f-G1gSTTBI.js} +1 -1
  13. package/dist/assets/{flowDiagram-50d868cf-CSDi0-RD.js → flowDiagram-50d868cf-CzrG99nD.js} +1 -1
  14. package/dist/assets/flowDiagram-v2-4f6560a1-CJfJYbME.js +1 -0
  15. package/dist/assets/{flowchart-elk-definition-6af322e1-DrhIMas7.js → flowchart-elk-definition-6af322e1-sFCoysWa.js} +1 -1
  16. package/dist/assets/{ganttDiagram-a2739b55-CTZnUP5z.js → ganttDiagram-a2739b55-Ccsk_Lru.js} +1 -1
  17. package/dist/assets/{gitGraphDiagram-82fe8481-COOW7jTi.js → gitGraphDiagram-82fe8481-CwathJ6H.js} +1 -1
  18. package/dist/assets/{graph-CIkpD4Kx.js → graph-DRCU-8Rz.js} +1 -1
  19. package/dist/assets/{index-5325376f-aVVRRTIu.js → index-5325376f-Bq-fg2i_.js} +1 -1
  20. package/dist/assets/{index-D1giUI7r.css → index-CHMuZ5-1.css} +1 -1
  21. package/dist/assets/{index-DRSI_ZIL.js → index-cGZvDhhU.js} +165 -137
  22. package/dist/assets/{infoDiagram-8eee0895-DQpZ1LVD.js → infoDiagram-8eee0895-JBcUkJ6T.js} +1 -1
  23. package/dist/assets/{journeyDiagram-c64418c1-DoKguIuk.js → journeyDiagram-c64418c1-DsdQU-R8.js} +1 -1
  24. package/dist/assets/{layout-Tnmha8Nh.js → layout-s0slG1OL.js} +1 -1
  25. package/dist/assets/{line-BQR2SOyl.js → line-CymFqgW6.js} +1 -1
  26. package/dist/assets/{linear-DlG0eemV.js → linear-lDQVZ6aQ.js} +1 -1
  27. package/dist/assets/{mermaid.core-BnwYO0He.js → mermaid.core-Cmlqga_E.js} +4 -4
  28. package/dist/assets/{mindmap-definition-8da855dc-BllYwDID.js → mindmap-definition-8da855dc-CqqTDJn_.js} +1 -1
  29. package/dist/assets/{pieDiagram-a8764435-DwCkhPVc.js → pieDiagram-a8764435-BL2Ajx7Z.js} +1 -1
  30. package/dist/assets/{quadrantDiagram-1e28029f-c40GKTU0.js → quadrantDiagram-1e28029f-ClL_3ASt.js} +1 -1
  31. package/dist/assets/{requirementDiagram-08caed73-DnQp2Tk6.js → requirementDiagram-08caed73-CB1RgE3K.js} +1 -1
  32. package/dist/assets/{sankeyDiagram-a04cb91d-CnJrs13b.js → sankeyDiagram-a04cb91d-tgleEYiD.js} +1 -1
  33. package/dist/assets/{sequenceDiagram-c5b8d532-1YBwnpKu.js → sequenceDiagram-c5b8d532-DlatQT5R.js} +1 -1
  34. package/dist/assets/{stateDiagram-1ecb1508-BFBxQ6Fh.js → stateDiagram-1ecb1508-B--MLqRs.js} +1 -1
  35. package/dist/assets/{stateDiagram-v2-c2b004d7-Dmechvv2.js → stateDiagram-v2-c2b004d7-CRMZ6Dpx.js} +1 -1
  36. package/dist/assets/{styles-b4e223ce-DWWfWX8O.js → styles-b4e223ce-CPiYHfUz.js} +1 -1
  37. package/dist/assets/{styles-ca3715f6-CKKvZxaU.js → styles-ca3715f6-B9UKPAzX.js} +1 -1
  38. package/dist/assets/{styles-d45a18b0-dKMOUh9p.js → styles-d45a18b0-BC1Ak1So.js} +1 -1
  39. package/dist/assets/{svgDrawCommon-b86b1483-CBgjChPM.js → svgDrawCommon-b86b1483-DV8R0g-n.js} +1 -1
  40. package/dist/assets/{timeline-definition-faaaa080-NCt-HHmb.js → timeline-definition-faaaa080-CiqGS5DC.js} +1 -1
  41. package/dist/assets/{xychartDiagram-f5964ef8-BJhXS4dG.js → xychartDiagram-f5964ef8-h6VSD3GE.js} +1 -1
  42. package/dist/index.html +2 -2
  43. package/package.json +7 -6
  44. package/src/api/sessions.ts +3 -1
  45. package/src/components/Chat.tsx +6 -0
  46. package/src/components/ConfigView.tsx +25 -25
  47. package/src/components/chat/ChatHistoryView.tsx +10 -0
  48. package/src/components/chat/Sender/Sender.scss +80 -17
  49. package/src/components/chat/Sender/Sender.tsx +22 -0
  50. package/src/components/config/ConfigSourceSwitch.tsx +12 -34
  51. package/src/components/config/channelDefinitions.ts +2 -2
  52. package/src/components/config/recordEditors/ChannelRecordEditor.tsx +33 -33
  53. package/src/components/sidebar/SessionItem.scss +17 -0
  54. package/src/components/sidebar/SessionItem.tsx +21 -13
  55. package/src/hooks/chat/use-chat-adapter.ts +81 -0
  56. package/src/hooks/chat/use-chat-models.tsx +73 -9
  57. package/src/hooks/chat/use-chat-session-actions.ts +9 -3
  58. package/src/hooks/chat/use-chat-session-messages.ts +17 -5
  59. package/src/hooks/chat/use-chat-session.ts +7 -1
  60. package/src/resources/adapters.ts +20 -0
  61. package/dist/assets/channel-DhtnrNJ6.js +0 -1
  62. package/dist/assets/clone-7bHB6YkC.js +0 -1
  63. package/dist/assets/flowDiagram-v2-4f6560a1-_13Sz5Wh.js +0 -1
@@ -0,0 +1,81 @@
1
+ import { createElement, type ReactNode } from 'react'
2
+ import { useEffect, useMemo, useState } from 'react'
3
+ import useSWR from 'swr'
4
+
5
+ import { getConfig } from '#~/api.js'
6
+ import type { ConfigResponse } from '@vibe-forge/core'
7
+ import { getAdapterDisplay } from '#~/resources/adapters.js'
8
+
9
+ const ADAPTER_STORAGE_KEY = 'vf_chat_adapter'
10
+
11
+ export function useChatAdapter() {
12
+ const [selectedAdapter, setSelectedAdapter] = useState<string | undefined>(() => {
13
+ try {
14
+ const raw = localStorage.getItem(ADAPTER_STORAGE_KEY)
15
+ return raw == null || raw.trim() === '' ? undefined : raw
16
+ } catch {
17
+ return undefined
18
+ }
19
+ })
20
+
21
+ const { data: configRes } = useSWR<ConfigResponse>('/api/config', getConfig)
22
+
23
+ const mergedAdapters = useMemo(() => {
24
+ return configRes?.sources?.merged?.adapters ?? {}
25
+ }, [configRes?.sources?.merged?.adapters])
26
+
27
+ const defaultAdapter = configRes?.sources?.merged?.general?.defaultAdapter
28
+
29
+ const adapterOptions = useMemo<Array<{ value: string; label: ReactNode }>>(() => {
30
+ const keys = Object.keys(mergedAdapters)
31
+ return keys.map((key) => {
32
+ const display = getAdapterDisplay(key)
33
+ return {
34
+ value: key,
35
+ label: createElement('span', { className: 'adapter-option' }, [
36
+ display.icon != null
37
+ ? createElement('img', {
38
+ key: 'icon',
39
+ className: 'adapter-option__icon',
40
+ src: display.icon,
41
+ alt: '',
42
+ 'aria-hidden': true
43
+ })
44
+ : null,
45
+ createElement('span', { key: 'text', className: 'adapter-option__text' }, display.title)
46
+ ])
47
+ }
48
+ })
49
+ }, [mergedAdapters])
50
+
51
+ // Auto-select: use stored value if valid, else config default, else first available
52
+ useEffect(() => {
53
+ const keys = Object.keys(mergedAdapters)
54
+ if (keys.length === 0) {
55
+ setSelectedAdapter(undefined)
56
+ return
57
+ }
58
+ setSelectedAdapter((prev) => {
59
+ if (prev != null && keys.includes(prev)) return prev
60
+ if (defaultAdapter && keys.includes(defaultAdapter as string)) return defaultAdapter as string
61
+ return keys[0]
62
+ })
63
+ }, [defaultAdapter, mergedAdapters])
64
+
65
+ // Persist to localStorage
66
+ useEffect(() => {
67
+ try {
68
+ if (selectedAdapter == null || selectedAdapter.trim() === '') {
69
+ localStorage.removeItem(ADAPTER_STORAGE_KEY)
70
+ } else {
71
+ localStorage.setItem(ADAPTER_STORAGE_KEY, selectedAdapter)
72
+ }
73
+ } catch {}
74
+ }, [selectedAdapter])
75
+
76
+ return {
77
+ selectedAdapter,
78
+ setSelectedAdapter,
79
+ adapterOptions
80
+ }
81
+ }
@@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'
2
2
  import { useTranslation } from 'react-i18next'
3
3
  import useSWR from 'swr'
4
4
 
5
- import type { ConfigResponse, ModelServiceConfig, RecommendedModelConfig } from '@vibe-forge/core'
5
+ import type { AdapterBuiltinModel, ConfigResponse, ModelServiceConfig, RecommendedModelConfig } from '@vibe-forge/core'
6
6
  import { getConfig } from '#~/api.js'
7
7
 
8
8
  export interface ModelSelectOption {
@@ -16,7 +16,11 @@ export interface ModelSelectGroup {
16
16
  options: ModelSelectOption[]
17
17
  }
18
18
 
19
- export function useChatModels() {
19
+ export function useChatModels({
20
+ selectedAdapter
21
+ }: {
22
+ selectedAdapter?: string
23
+ } = {}) {
20
24
  const { t } = useTranslation()
21
25
  const [selectedModel, setSelectedModel] = useState<string | undefined>(() => {
22
26
  try {
@@ -41,6 +45,30 @@ export function useChatModels() {
41
45
  ))
42
46
  }, [configRes?.sources?.merged?.general?.recommendedModels])
43
47
 
48
+ const adapterBuiltinModels = useMemo(() => {
49
+ const raw = configRes?.sources?.merged?.adapterBuiltinModels
50
+ return (raw ?? {}) as Record<string, AdapterBuiltinModel[]>
51
+ }, [configRes?.sources?.merged?.adapterBuiltinModels])
52
+
53
+ const activeBuiltinModels = useMemo(() => {
54
+ if (selectedAdapter && adapterBuiltinModels[selectedAdapter]) {
55
+ return { [selectedAdapter]: adapterBuiltinModels[selectedAdapter] }
56
+ }
57
+ return adapterBuiltinModels
58
+ }, [adapterBuiltinModels, selectedAdapter])
59
+
60
+ const activeBuiltinModelValues = useMemo(() => (
61
+ Object.values(activeBuiltinModels).flat().map(model => model.value)
62
+ ), [activeBuiltinModels])
63
+
64
+ const builtinModelSet = useMemo(() => {
65
+ const set = new Set<string>()
66
+ for (const models of Object.values(activeBuiltinModels)) {
67
+ for (const m of models) set.add(m.value)
68
+ }
69
+ return set
70
+ }, [activeBuiltinModels])
71
+
44
72
  const modelServiceEntries = useMemo(() => Object.entries(mergedModelServices), [mergedModelServices])
45
73
 
46
74
  const availableModels = useMemo(() => {
@@ -61,7 +89,7 @@ export function useChatModels() {
61
89
  const availableModelValues = useMemo(() => availableModels.map(item => item.model), [availableModels])
62
90
  const availableModelKey = useMemo(() => availableModelValues.join('|'), [availableModelValues])
63
91
  const availableModelSet = useMemo(() => new Set(availableModelValues), [availableModelKey])
64
- const hasAvailableModels = availableModelValues.length > 0
92
+ const hasAvailableModels = availableModelValues.length > 0 || builtinModelSet.size > 0
65
93
  const modelToService = useMemo(() => {
66
94
  const map = new Map<string, { key: string; title: string }>()
67
95
  for (const entry of availableModels) {
@@ -76,25 +104,35 @@ export function useChatModels() {
76
104
  const formatModelWithService = useCallback((model: string | undefined) => {
77
105
  const normalizedModel = typeof model === 'string' ? model.trim() : ''
78
106
  if (normalizedModel === '') return undefined
107
+ // Builtin adapter models pass through as-is (no service prefix)
108
+ if (builtinModelSet.has(normalizedModel)) return normalizedModel
79
109
  if (normalizedModel.includes(',')) return normalizedModel
80
110
  const resolvedService = modelToService.get(normalizedModel)?.key ?? defaultModelService
81
111
  return resolvedService ? `${resolvedService},${normalizedModel}` : normalizedModel
82
- }, [defaultModelService, modelToService])
112
+ }, [builtinModelSet, defaultModelService, modelToService])
83
113
  const resolvedDefaultModel = useMemo(() => {
84
- if (!hasAvailableModels) return undefined
114
+ if (defaultModel && builtinModelSet.has(defaultModel)) return defaultModel
115
+ if (activeBuiltinModelValues.length > 0) {
116
+ return activeBuiltinModelValues[0]
117
+ }
85
118
  if (defaultModel && availableModelSet.has(defaultModel)) return defaultModel
86
119
  if (defaultModelService && mergedModelServices[defaultModelService]) {
87
120
  const service = mergedModelServices[defaultModelService]
88
121
  const models = Array.isArray(service?.models) ? service?.models.filter(item => typeof item === 'string') : []
89
122
  if (models.length > 0) return models[0]
90
123
  }
91
- return availableModelValues[0]
124
+ if (availableModelValues.length > 0) return availableModelValues[0]
125
+ // Fall back to first builtin model from the active adapter
126
+ const firstBuiltin = Object.values(activeBuiltinModels).flat()[0]
127
+ return firstBuiltin?.value
92
128
  }, [
129
+ activeBuiltinModels,
130
+ activeBuiltinModelValues,
93
131
  availableModelSet,
94
132
  availableModelValues,
133
+ builtinModelSet,
95
134
  defaultModel,
96
135
  defaultModelService,
97
- hasAvailableModels,
98
136
  mergedModelServices
99
137
  ])
100
138
  const selectedModelWithService = useMemo(() => (
@@ -107,10 +145,13 @@ export function useChatModels() {
107
145
  return
108
146
  }
109
147
  setSelectedModel((prev) => {
110
- if (prev != null && availableModelSet.has(prev)) return prev
148
+ if (prev != null) {
149
+ const isValid = availableModelSet.has(prev) || builtinModelSet.has(prev)
150
+ if (isValid) return prev
151
+ }
111
152
  return resolvedDefaultModel
112
153
  })
113
- }, [availableModelSet, hasAvailableModels, resolvedDefaultModel])
154
+ }, [availableModelSet, builtinModelSet, hasAvailableModels, resolvedDefaultModel, selectedAdapter])
114
155
 
115
156
  useEffect(() => {
116
157
  try {
@@ -235,8 +276,31 @@ export function useChatModels() {
235
276
  options: recommendedOptions
236
277
  })
237
278
  }
279
+
280
+ // Adapter builtin model groups (filtered to active adapter)
281
+ for (const [adapterKey, models] of Object.entries(activeBuiltinModels)) {
282
+ if (!Array.isArray(models) || models.length === 0) continue
283
+ const adapterTitle = t('chat.modelGroupBuiltin', {
284
+ adapter: adapterKey,
285
+ defaultValue: `${adapterKey} (Default)`
286
+ })
287
+ groups.push({
288
+ label: (
289
+ <div className='model-group-label'>
290
+ <div className='model-group-title'>{adapterTitle}</div>
291
+ </div>
292
+ ),
293
+ options: models.map(m => buildOption({
294
+ value: m.value,
295
+ title: m.title,
296
+ description: m.description
297
+ }))
298
+ })
299
+ }
300
+
238
301
  return [...groups, ...serviceGroups]
239
302
  }, [
303
+ activeBuiltinModels,
240
304
  availableModelSet,
241
305
  modelToService,
242
306
  mergedModelServices,
@@ -4,9 +4,9 @@ import { useTranslation } from 'react-i18next'
4
4
  import { useNavigate } from 'react-router-dom'
5
5
  import { useSWRConfig } from 'swr'
6
6
 
7
- import type { ChatMessageContent, Session } from '@vibe-forge/core'
8
7
  import { createSession } from '#~/api.js'
9
8
  import { connectionManager } from '#~/connectionManager.js'
9
+ import type { ChatMessageContent, Session } from '@vibe-forge/core'
10
10
  import type { PermissionMode } from './use-chat-permission-mode'
11
11
 
12
12
  export function useChatSessionActions({
@@ -14,12 +14,14 @@ export function useChatSessionActions({
14
14
  modelForQuery,
15
15
  hasAvailableModels,
16
16
  permissionMode,
17
+ adapter,
17
18
  onClearMessages
18
19
  }: {
19
20
  session?: Session
20
21
  modelForQuery?: string
21
22
  hasAvailableModels: boolean
22
23
  permissionMode: PermissionMode
24
+ adapter?: string
23
25
  onClearMessages: () => void
24
26
  }) {
25
27
  const { message } = App.useApp()
@@ -40,7 +42,8 @@ export function useChatSessionActions({
40
42
  setIsCreating(true)
41
43
  try {
42
44
  const { session: newSession } = await createSession(undefined, text.trim(), undefined, modelForQuery, {
43
- permissionMode
45
+ permissionMode,
46
+ adapter
44
47
  })
45
48
 
46
49
  await mutate('/api/sessions', (prev: { sessions: Session[] } | undefined) => {
@@ -65,6 +68,7 @@ export function useChatSessionActions({
65
68
  text: text.trim()
66
69
  })
67
70
  }, [
71
+ adapter,
68
72
  hasAvailableModels,
69
73
  isThinking,
70
74
  message,
@@ -87,7 +91,8 @@ export function useChatSessionActions({
87
91
  setIsCreating(true)
88
92
  try {
89
93
  const { session: newSession } = await createSession(undefined, undefined, content, modelForQuery, {
90
- permissionMode
94
+ permissionMode,
95
+ adapter
91
96
  })
92
97
 
93
98
  await mutate('/api/sessions', (prev: { sessions: Session[] } | undefined) => {
@@ -113,6 +118,7 @@ export function useChatSessionActions({
113
118
  content
114
119
  })
115
120
  }, [
121
+ adapter,
116
122
  hasAvailableModels,
117
123
  isThinking,
118
124
  message,
@@ -2,9 +2,9 @@ import { App } from 'antd'
2
2
  import { useEffect, useRef, useState } from 'react'
3
3
  import { useSWRConfig } from 'swr'
4
4
 
5
- import type { AskUserQuestionParams, ChatMessage, Session, SessionInfo, WSEvent } from '@vibe-forge/core'
6
5
  import { getSessionMessages } from '#~/api.js'
7
6
  import { connectionManager } from '#~/connectionManager.js'
7
+ import type { AskUserQuestionParams, ChatMessage, Session, SessionInfo, WSEvent } from '@vibe-forge/core'
8
8
  import type { PermissionMode } from './use-chat-permission-mode'
9
9
 
10
10
  const applyMessageEvent = (currentMessages: ChatMessage[], data: WSEvent) => {
@@ -38,11 +38,13 @@ export function useChatSessionMessages({
38
38
  session,
39
39
  modelForQuery,
40
40
  permissionMode,
41
+ adapter,
41
42
  setInteractionRequest
42
43
  }: {
43
44
  session?: Session
44
45
  modelForQuery?: string
45
46
  permissionMode: PermissionMode
47
+ adapter?: string
46
48
  setInteractionRequest: (value: { id: string; payload: AskUserQuestionParams } | null) => void
47
49
  }) {
48
50
  const { message } = App.useApp()
@@ -53,6 +55,7 @@ export function useChatSessionMessages({
53
55
  const isInitialLoadRef = useRef<boolean>(true)
54
56
  const lastConnectedModelRef = useRef<string | undefined>(undefined)
55
57
  const lastConnectedPermissionModeRef = useRef<string | undefined>(undefined)
58
+ const lastConnectedAdapterRef = useRef<string | undefined>(undefined)
56
59
 
57
60
  useEffect(() => {
58
61
  setMessages([])
@@ -141,23 +144,32 @@ export function useChatSessionMessages({
141
144
  lastConnectedPermissionModeRef.current != null &&
142
145
  normalizedPermissionMode !== lastConnectedPermissionModeRef.current &&
143
146
  session?.status !== 'running'
144
- if (modelChanged || permissionModeChanged) {
147
+ const normalizedAdapter = adapter ?? ''
148
+ const adapterChanged = adapter != null &&
149
+ lastConnectedAdapterRef.current != null &&
150
+ normalizedAdapter !== lastConnectedAdapterRef.current &&
151
+ session?.status !== 'running'
152
+ if (modelChanged || permissionModeChanged || adapterChanged) {
145
153
  connectionManager.send(session.id, { type: 'terminate_session' })
146
154
  connectionManager.close(session.id)
147
155
  }
148
156
  lastConnectedModelRef.current = normalizedModel
149
157
  lastConnectedPermissionModeRef.current = normalizedPermissionMode
158
+ lastConnectedAdapterRef.current = normalizedAdapter
150
159
 
151
160
  const timer = setTimeout(() => {
152
161
  if (isDisposed) return
153
162
 
154
163
  const connectionParams: Record<string, string> = {}
155
- if (modelForQuery) {
156
- connectionParams.model = modelForQuery
164
+ if (modelForQuery) {
165
+ connectionParams.model = modelForQuery
157
166
  }
158
167
  if (permissionMode) {
159
168
  connectionParams.permissionMode = permissionMode
160
169
  }
170
+ if (adapter) {
171
+ connectionParams.adapter = adapter
172
+ }
161
173
 
162
174
  cleanup = connectionManager.connect(session.id, {
163
175
  onOpen() {
@@ -239,7 +251,7 @@ export function useChatSessionMessages({
239
251
  clearTimeout(timer)
240
252
  cleanup?.()
241
253
  }
242
- }, [message, modelForQuery, mutate, permissionMode, session?.id, session?.status, setInteractionRequest])
254
+ }, [adapter, message, modelForQuery, mutate, permissionMode, session?.id, session?.status, setInteractionRequest])
243
255
 
244
256
  return {
245
257
  messages,
@@ -1,6 +1,7 @@
1
1
  import { useTranslation } from 'react-i18next'
2
2
 
3
3
  import type { Session } from '@vibe-forge/core'
4
+ import { useChatAdapter } from './use-chat-adapter'
4
5
  import { useChatInteraction } from './use-chat-interaction'
5
6
  import { useChatModels } from './use-chat-models'
6
7
  import { useChatPermissionMode } from './use-chat-permission-mode'
@@ -13,13 +14,14 @@ export function useChatSession({
13
14
  session?: Session
14
15
  }) {
15
16
  const { t } = useTranslation()
17
+ const { selectedAdapter, setSelectedAdapter, adapterOptions } = useChatAdapter()
16
18
  const {
17
19
  selectedModel,
18
20
  selectedModelWithService,
19
21
  setSelectedModel,
20
22
  modelOptions,
21
23
  hasAvailableModels
22
- } = useChatModels()
24
+ } = useChatModels({ selectedAdapter })
23
25
  const { permissionMode, setPermissionMode, permissionModeOptions } = useChatPermissionMode()
24
26
  const { activeView, setActiveView } = useChatView()
25
27
  const { interactionRequest, setInteractionRequest, handleInteractionResponse } = useChatInteraction({
@@ -29,6 +31,7 @@ export function useChatSession({
29
31
  session,
30
32
  modelForQuery: selectedModelWithService,
31
33
  permissionMode,
34
+ adapter: selectedAdapter,
32
35
  setInteractionRequest
33
36
  })
34
37
  const isThinking = session?.status === 'running'
@@ -51,6 +54,9 @@ export function useChatSession({
51
54
  permissionMode,
52
55
  setPermissionMode,
53
56
  permissionModeOptions,
57
+ selectedAdapter,
58
+ setSelectedAdapter,
59
+ adapterOptions,
54
60
  hasAvailableModels,
55
61
  modelUnavailable: !hasAvailableModels
56
62
  }
@@ -0,0 +1,20 @@
1
+ import { adapterDisplayName as claudeCodeDisplayName, adapterIcon as claudeCodeIcon } from '@vibe-forge/adapter-claude-code/icon'
2
+ import { adapterDisplayName as codexDisplayName, adapterIcon as codexIcon } from '@vibe-forge/adapter-codex/icon'
3
+
4
+ export const adapterDisplayMap = {
5
+ 'claude-code': {
6
+ title: claudeCodeDisplayName,
7
+ icon: claudeCodeIcon
8
+ },
9
+ codex: {
10
+ title: codexDisplayName,
11
+ icon: codexIcon
12
+ }
13
+ } as const
14
+
15
+ export const getAdapterDisplay = (adapterKey: string) => {
16
+ return adapterDisplayMap[adapterKey as keyof typeof adapterDisplayMap] ?? {
17
+ title: adapterKey,
18
+ icon: undefined
19
+ }
20
+ }
@@ -1 +0,0 @@
1
- import{al as o,am as n}from"./mermaid.core-BnwYO0He.js";const l=(a,r)=>o.lang.round(n.parse(a)[r]);export{l as c};
@@ -1 +0,0 @@
1
- import{a as r}from"./graph-CIkpD4Kx.js";var a=4;function n(o){return r(o,a)}export{n as c};
@@ -1 +0,0 @@
1
- import{f as o,p as e}from"./flowDb-c6c81e3f-DjiCStMN.js";import{f as a,g as t}from"./styles-d45a18b0-dKMOUh9p.js";import{ar as i}from"./mermaid.core-BnwYO0He.js";import"./graph-CIkpD4Kx.js";import"./layout-Tnmha8Nh.js";import"./index-DRSI_ZIL.js";import"./index-5325376f-aVVRRTIu.js";import"./clone-7bHB6YkC.js";import"./edges-96097737-BU8qStzd.js";import"./createText-1719965b-C1_HJcCc.js";import"./line-BQR2SOyl.js";import"./array-BKyUJesY.js";import"./path-CbwjOpE9.js";import"./channel-DhtnrNJ6.js";const n={parser:e,db:o,renderer:t,styles:a,init:r=>{r.flowchart||(r.flowchart={}),r.flowchart.arrowMarkerAbsolute=r.arrowMarkerAbsolute,i({flowchart:{arrowMarkerAbsolute:r.arrowMarkerAbsolute}}),t.setConf(r.flowchart),o.clear(),o.setGen("gen-2")}};export{n as diagram};