Skip to content

Commit 2173302

Browse files
committed
Consolidate web configuration editing into a shared component and enable configuration updates within the settings view
- inline 'edit web configuration form footer' within Panel - move 'edit web configuration form' to `apps/editor/src/views/shared/components` - create actions (`apps/editor/src/views/actions`) for handlers: 'pick model', 'pick chatbot' and 'pick reasoning effort'. - use `apps/editor/src/views/shared/components/EditWebConfigurationForm/EditWebConfigurationForm.tsx` in `apps/editor/src/views/settings/frontend/Settings.tsx`, create settings-specific handlers that use the shared actions: pick chatbot, pick model, pick reasoning effort. - `apps/editor/src/views/panel/backend/message-handlers/handle-update-web-configuration.ts` should use `apps/editor/src/views/utils/generate-unique-name.ts` - move 'are web configurations equal' to shared utils - handle updating web configuration in settings
1 parent c8b64ac commit 2173302

25 files changed

Lines changed: 517 additions & 291 deletions

‎apps/editor/src/views/actions/duplicate-web-configuration.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export const duplicate_web_configuration = async (params: {
1414

1515
const original_index = current_web_configurations.findIndex((c, i) => (c.name ?? `unnamed-${i}`) === original_name)
1616

17-
if (original_index === -1) {
17+
if (original_index == -1) {
1818
vscode.window.showErrorMessage(
1919
dictionary.error_message.PRESET_NOT_FOUND(`with name ${original_name}`)
2020
)
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import * as vscode from 'vscode'
2+
import { CHATBOTS } from '@shared/constants/chatbots'
3+
4+
export const pick_chatbot = async (params: {
5+
current_chatbot_id?: string
6+
}): Promise<keyof typeof CHATBOTS | undefined> => {
7+
const chatbots = Object.entries(CHATBOTS)
8+
9+
const items: vscode.QuickPickItem[] = chatbots.map(([chatbot, { url }]) => ({
10+
label: chatbot,
11+
description:
12+
chatbot == 'Open WebUI'
13+
? 'localhost'
14+
: url.replace(/^https?:\/\//, '').split('/')[0]
15+
}))
16+
17+
const quick_pick = vscode.window.createQuickPick()
18+
quick_pick.items = items
19+
quick_pick.title = 'Chatbots'
20+
quick_pick.placeholder = 'Choose a chatbot'
21+
quick_pick.buttons = [
22+
{
23+
iconPath: new vscode.ThemeIcon('close'),
24+
tooltip: 'Close'
25+
}
26+
]
27+
28+
if (params.current_chatbot_id) {
29+
const active_item = items.find((item) => item.label == params.current_chatbot_id)
30+
if (active_item) {
31+
quick_pick.activeItems = [active_item]
32+
}
33+
}
34+
35+
quick_pick.onDidTriggerButton((button) => {
36+
if (button.tooltip === 'Close') {
37+
quick_pick.hide()
38+
}
39+
})
40+
41+
return new Promise<keyof typeof CHATBOTS | undefined>((resolve) => {
42+
let accepted = false
43+
quick_pick.onDidAccept(() => {
44+
accepted = true
45+
const selected = quick_pick.selectedItems[0]?.label as keyof typeof CHATBOTS | undefined
46+
quick_pick.hide()
47+
resolve(selected)
48+
})
49+
50+
quick_pick.onDidHide(() => {
51+
if (!accepted) resolve(undefined)
52+
quick_pick.dispose()
53+
})
54+
55+
quick_pick.show()
56+
})
57+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import * as vscode from 'vscode'
2+
import axios from 'axios'
3+
import { CHATBOTS } from '@shared/constants/chatbots'
4+
import { dictionary } from '@shared/constants/dictionary'
5+
import { Logger } from '@shared/utils/logger'
6+
7+
export const pick_model = async (params: {
8+
chatbot_name: string
9+
current_model_id?: string
10+
}): Promise<string | undefined> => {
11+
try {
12+
let items: (vscode.QuickPickItem & { model_id: string })[] = []
13+
14+
if (params.chatbot_name == 'OpenRouter') {
15+
const response = await axios.get('https://openrouter.ai/api/v1/models')
16+
const models = response.data.data
17+
18+
items = models.map((model: any) => ({
19+
label: model.name,
20+
model_id: model.id
21+
}))
22+
} else {
23+
const chatbot_config = CHATBOTS[params.chatbot_name as keyof typeof CHATBOTS]
24+
if (chatbot_config && chatbot_config.models) {
25+
items = Object.entries(chatbot_config.models).map(([id, data]) => ({
26+
label: (data as any).label || id,
27+
model_id: id
28+
}))
29+
}
30+
}
31+
32+
const quick_pick = vscode.window.createQuickPick()
33+
quick_pick.items = items
34+
quick_pick.title = 'Models'
35+
quick_pick.placeholder = 'Choose a model'
36+
37+
if (params.current_model_id) {
38+
const active_item = items.find((i) => i.model_id === params.current_model_id)
39+
if (active_item) quick_pick.activeItems = [active_item]
40+
}
41+
42+
quick_pick.buttons = [
43+
{
44+
iconPath: new vscode.ThemeIcon('close'),
45+
tooltip: 'Close'
46+
}
47+
]
48+
49+
quick_pick.onDidTriggerButton((button) => {
50+
if (button.tooltip == 'Close') {
51+
quick_pick.hide()
52+
}
53+
})
54+
55+
return new Promise<string | undefined>((resolve) => {
56+
let accepted = false
57+
quick_pick.onDidAccept(() => {
58+
accepted = true
59+
const selected = quick_pick.selectedItems[0] as any
60+
quick_pick.hide()
61+
resolve(selected?.model_id)
62+
})
63+
64+
quick_pick.onDidHide(() => {
65+
if (!accepted) resolve(undefined)
66+
quick_pick.dispose()
67+
})
68+
69+
quick_pick.show()
70+
})
71+
} catch (error) {
72+
Logger.error({
73+
function_name: 'pick_model',
74+
message: 'Error picking model',
75+
data: error
76+
})
77+
vscode.window.showErrorMessage(
78+
params.chatbot_name == 'OpenRouter'
79+
? dictionary.error_message.FAILED_TO_FETCH_OPEN_ROUTER_MODELS
80+
: 'Failed to pick model'
81+
)
82+
return undefined
83+
}
84+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import * as vscode from 'vscode'
2+
3+
export const pick_reasoning_effort = async (params: {
4+
supported_efforts: string[]
5+
current_effort?: string
6+
}): Promise<{ effort?: string } | undefined> => {
7+
const items: (vscode.QuickPickItem & { effort?: string })[] = [
8+
{ label: 'Unset', effort: undefined },
9+
...params.supported_efforts.map((effort) => ({
10+
label: effort.charAt(0).toUpperCase() + effort.slice(1),
11+
effort
12+
}))
13+
]
14+
15+
const quick_pick = vscode.window.createQuickPick()
16+
quick_pick.items = items
17+
quick_pick.title = 'Reasoning Efforts'
18+
quick_pick.placeholder = 'Choose a reasoning effort'
19+
20+
if (params.current_effort) {
21+
const active_item = items.find((i) => i.effort === params.current_effort)
22+
if (active_item) quick_pick.activeItems = [active_item]
23+
} else {
24+
quick_pick.activeItems = [items[0]]
25+
}
26+
27+
quick_pick.buttons = [
28+
{
29+
iconPath: new vscode.ThemeIcon('close'),
30+
tooltip: 'Close'
31+
}
32+
]
33+
34+
quick_pick.onDidTriggerButton((button) => {
35+
if (button.tooltip == 'Close') {
36+
quick_pick.hide()
37+
}
38+
})
39+
40+
return new Promise<{ effort?: string } | undefined>((resolve) => {
41+
let accepted = false
42+
quick_pick.onDidAccept(() => {
43+
accepted = true
44+
const selected = quick_pick.selectedItems[0] as any
45+
quick_pick.hide()
46+
resolve(selected ? { effort: selected.effort } : undefined)
47+
})
48+
49+
quick_pick.onDidHide(() => {
50+
if (!accepted) resolve(undefined)
51+
quick_pick.dispose()
52+
})
53+
54+
quick_pick.show()
55+
})
56+
}
Lines changed: 7 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,16 @@
1-
import * as vscode from 'vscode'
21
import { PanelProvider } from '@/views/panel/backend/panel-provider'
3-
import { CHATBOTS } from '@shared/constants/chatbots'
42
import { PickChatbotMessage } from '@/views/panel/types/messages'
3+
import { pick_chatbot } from '@/views/actions/pick-chatbot'
54

65
export const handle_pick_chatbot = async (
76
panel_provider: PanelProvider,
87
message: PickChatbotMessage
98
): Promise<void> => {
10-
const chatbots = Object.entries(CHATBOTS)
11-
12-
const items: vscode.QuickPickItem[] = chatbots.map(([chatbot, { url }]) => ({
13-
label: chatbot,
14-
description:
15-
chatbot == 'Open WebUI'
16-
? 'localhost'
17-
: url.replace(/^https?:\/\//, '').split('/')[0]
18-
}))
19-
20-
const quick_pick = vscode.window.createQuickPick()
21-
quick_pick.items = items
22-
quick_pick.title = 'Chatbots'
23-
quick_pick.placeholder = 'Choose a chatbot'
24-
quick_pick.buttons = [
25-
{
26-
iconPath: new vscode.ThemeIcon('close'),
27-
tooltip: 'Close'
28-
}
29-
]
30-
31-
if (message.chatbot_id) {
32-
const active_item = items.find((item) => item.label == message.chatbot_id)
33-
if (active_item) {
34-
quick_pick.activeItems = [active_item]
35-
}
36-
}
37-
38-
quick_pick.onDidTriggerButton((button) => {
39-
if (button.tooltip === 'Close') {
40-
quick_pick.hide()
41-
}
42-
})
43-
44-
return new Promise<void>((resolve) => {
45-
quick_pick.onDidAccept(() => {
46-
const selected = quick_pick.selectedItems[0]
47-
if (selected) {
48-
panel_provider.send_message({
49-
command: 'NEWLY_PICKED_CHATBOT',
50-
chatbot_id: selected.label
51-
})
52-
}
53-
quick_pick.hide()
54-
})
55-
56-
quick_pick.onDidHide(() => {
57-
quick_pick.dispose()
58-
resolve()
9+
const selected = await pick_chatbot({ current_chatbot_id: message.chatbot_id })
10+
if (selected) {
11+
panel_provider.send_message({
12+
command: 'NEWLY_PICKED_CHATBOT',
13+
chatbot_id: selected
5914
})
60-
61-
quick_pick.show()
62-
})
15+
}
6316
}
Lines changed: 9 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,19 @@
1-
import * as vscode from 'vscode'
21
import { PanelProvider } from '@/views/panel/backend/panel-provider'
3-
import { dictionary } from '@shared/constants/dictionary'
4-
import { Logger } from '@shared/utils/logger'
5-
import axios from 'axios'
6-
import { CHATBOTS } from '@shared/constants/chatbots'
72
import { PickModelMessage } from '@/views/panel/types/messages'
3+
import { pick_model } from '@/views/actions/pick-model'
84

95
export const handle_pick_model = async (
106
panel_provider: PanelProvider,
117
message: PickModelMessage
128
): Promise<void> => {
13-
try {
14-
let items: (vscode.QuickPickItem & { model_id: string })[] = []
15-
16-
if (message.chatbot_name == 'OpenRouter') {
17-
const response = await axios.get('https://openrouter.ai/api/v1/models')
18-
const models = response.data.data
19-
20-
items = models.map((model: any) => ({
21-
label: model.name,
22-
model_id: model.id
23-
}))
24-
} else {
25-
const chatbot_config =
26-
CHATBOTS[message.chatbot_name as keyof typeof CHATBOTS]
27-
if (chatbot_config && chatbot_config.models) {
28-
items = Object.entries(chatbot_config.models).map(([id, data]) => ({
29-
label: (data as any).label || id,
30-
model_id: id
31-
}))
32-
}
33-
}
34-
35-
const quick_pick = vscode.window.createQuickPick()
36-
quick_pick.items = items
37-
quick_pick.title = 'Models'
38-
quick_pick.placeholder = 'Choose a model'
39-
40-
if (message.current_model_id) {
41-
const active_item = items.find(
42-
(i) => i.model_id === message.current_model_id
43-
)
44-
if (active_item) quick_pick.activeItems = [active_item]
45-
}
46-
47-
quick_pick.buttons = [
48-
{
49-
iconPath: new vscode.ThemeIcon('close'),
50-
tooltip: 'Close'
51-
}
52-
]
53-
54-
quick_pick.onDidTriggerButton((button) => {
55-
if (button.tooltip == 'Close') {
56-
quick_pick.hide()
57-
}
58-
})
59-
60-
return new Promise<void>((resolve) => {
61-
quick_pick.onDidAccept(() => {
62-
const selected = quick_pick.selectedItems[0] as any
63-
if (selected) {
64-
panel_provider.send_message({
65-
command: 'NEWLY_PICKED_MODEL',
66-
model_id: selected.model_id
67-
})
68-
}
69-
quick_pick.hide()
70-
})
71-
72-
quick_pick.onDidHide(() => {
73-
quick_pick.dispose()
74-
resolve()
75-
})
76-
77-
quick_pick.show()
78-
})
79-
} catch (error) {
80-
Logger.error({
81-
function_name: 'handle_pick_model',
82-
message: 'Error picking model',
83-
data: error
9+
const selected = await pick_model({
10+
chatbot_name: message.chatbot_name,
11+
current_model_id: message.current_model_id
12+
})
13+
if (selected) {
14+
panel_provider.send_message({
15+
command: 'NEWLY_PICKED_MODEL',
16+
model_id: selected
8417
})
85-
vscode.window.showErrorMessage(
86-
message.chatbot_name == 'OpenRouter'
87-
? dictionary.error_message.FAILED_TO_FETCH_OPEN_ROUTER_MODELS
88-
: 'Failed to pick model'
89-
)
9018
}
9119
}

0 commit comments

Comments
 (0)