From 31edef55cc5a04e2bfa895a41577b3acf78576da Mon Sep 17 00:00:00 2001 From: wjiayis Date: Sun, 25 Jan 2026 16:18:48 +0800 Subject: [PATCH 1/4] fix: remove definition of currentConversation as it is not used --- webapp/_webapp/package-lock.json | 39 +++++++++++++++++-- .../src/views/settings/setting-text-input.tsx | 2 +- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/webapp/_webapp/package-lock.json b/webapp/_webapp/package-lock.json index aefcb68b..71561f45 100644 --- a/webapp/_webapp/package-lock.json +++ b/webapp/_webapp/package-lock.json @@ -21,6 +21,8 @@ "@types/diff": "^8.0.0", "@uidotdev/usehooks": "^2.4.1", "axios": "^1.9.0", + "baseline-browser-mapping": "^2.9.12", + "caniuse-lite": "^1.0.30001762", "diff": "^8.0.2", "events": "^3.3.0", "framer-motion": "^12.15.0", @@ -42,6 +44,7 @@ "@codemirror/view": "^6.37.1", "@eslint/js": "^9.28.0", "@grafana/faro-rollup-plugin": "^0.7.0", + "@types/bun": "^1.3.5", "@types/chrome": "^0.0.326", "@types/codemirror": "^5.60.16", "@types/events": "^3.0.3", @@ -4971,6 +4974,16 @@ "url": "https://github.com/sponsors/tannerlinsley" } }, + "node_modules/@types/bun": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@types/bun/-/bun-1.3.6.tgz", + "integrity": "sha512-uWCv6FO/8LcpREhenN1d1b6fcspAB+cefwD7uti8C8VffIv0Um08TKMn98FynpTiU38+y2dUO55T11NgDt8VAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bun-types": "1.3.6" + } + }, "node_modules/@types/chrome": { "version": "0.0.326", "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.326.tgz", @@ -5576,6 +5589,15 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.18", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.18.tgz", + "integrity": "sha512-e23vBV1ZLfjb9apvfPk4rHVu2ry6RIr2Wfs+O324okSidrX7pTAnEJPCh/O5BtRlr7QtZI7ktOP3vsqr7Z5XoA==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -5645,6 +5667,16 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/bun-types": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.3.6.tgz", + "integrity": "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -5678,10 +5710,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001720", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001720.tgz", - "integrity": "sha512-Ec/2yV2nNPwb4DnTANEV99ZWwm3ZWfdlfkQbWSDDt+PsXEVYwlhPH8tdMaPunYTKKmz7AnHi2oNEi1GcmKCD8g==", - "dev": true, + "version": "1.0.30001766", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz", + "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==", "funding": [ { "type": "opencollective", diff --git a/webapp/_webapp/src/views/settings/setting-text-input.tsx b/webapp/_webapp/src/views/settings/setting-text-input.tsx index a67e9e27..b2d454b7 100644 --- a/webapp/_webapp/src/views/settings/setting-text-input.tsx +++ b/webapp/_webapp/src/views/settings/setting-text-input.tsx @@ -29,7 +29,7 @@ export function createSettingsTextInput(settingKey: K) { password = false, }: SettingsTextInputProps) { const { settings, isUpdating, updateSettings } = useSettingStore(); - const { currentConversation, setCurrentConversation } = useConversationStore(); + const { setCurrentConversation } = useConversationStore(); const [value, setValue] = useState(""); const [originalValue, setOriginalValue] = useState(""); const [isEditing, setIsEditing] = useState(false); From c1f4f5046f439d5dbd7548efb0652925c001309e Mon Sep 17 00:00:00 2001 From: wjiayis Date: Sun, 25 Jan 2026 16:26:19 +0800 Subject: [PATCH 2/4] fix: change matching from substring to exact, to prevent gpt-4.1-mini from matching to gpt-4.0 --- webapp/_webapp/src/views/settings/setting-text-input.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/_webapp/src/views/settings/setting-text-input.tsx b/webapp/_webapp/src/views/settings/setting-text-input.tsx index b2d454b7..23eab3ad 100644 --- a/webapp/_webapp/src/views/settings/setting-text-input.tsx +++ b/webapp/_webapp/src/views/settings/setting-text-input.tsx @@ -59,7 +59,7 @@ export function createSettingsTextInput(settingKey: K) { // try to find a model that matches the current slug const currentSlugLower = latest.modelSlug.toLowerCase(); const matchingModel = response.models.find(m => - currentSlugLower.includes(m.name.toLowerCase()) + currentSlugLower === m.name.toLowerCase() ); // fall back to the first model in the list const newSlug = matchingModel?.slug ?? response.models[0].slug; From bb5137cee5404bb042e8ade9b17cd32ff6db9325 Mon Sep 17 00:00:00 2001 From: wjiayis Date: Sun, 25 Jan 2026 17:22:56 +0800 Subject: [PATCH 3/4] chore: revert changes to package-lock.json --- webapp/_webapp/package-lock.json | 39 ++++---------------------------- 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/webapp/_webapp/package-lock.json b/webapp/_webapp/package-lock.json index 71561f45..aefcb68b 100644 --- a/webapp/_webapp/package-lock.json +++ b/webapp/_webapp/package-lock.json @@ -21,8 +21,6 @@ "@types/diff": "^8.0.0", "@uidotdev/usehooks": "^2.4.1", "axios": "^1.9.0", - "baseline-browser-mapping": "^2.9.12", - "caniuse-lite": "^1.0.30001762", "diff": "^8.0.2", "events": "^3.3.0", "framer-motion": "^12.15.0", @@ -44,7 +42,6 @@ "@codemirror/view": "^6.37.1", "@eslint/js": "^9.28.0", "@grafana/faro-rollup-plugin": "^0.7.0", - "@types/bun": "^1.3.5", "@types/chrome": "^0.0.326", "@types/codemirror": "^5.60.16", "@types/events": "^3.0.3", @@ -4974,16 +4971,6 @@ "url": "https://github.com/sponsors/tannerlinsley" } }, - "node_modules/@types/bun": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/@types/bun/-/bun-1.3.6.tgz", - "integrity": "sha512-uWCv6FO/8LcpREhenN1d1b6fcspAB+cefwD7uti8C8VffIv0Um08TKMn98FynpTiU38+y2dUO55T11NgDt8VAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "bun-types": "1.3.6" - } - }, "node_modules/@types/chrome": { "version": "0.0.326", "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.326.tgz", @@ -5589,15 +5576,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, - "node_modules/baseline-browser-mapping": { - "version": "2.9.18", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.18.tgz", - "integrity": "sha512-e23vBV1ZLfjb9apvfPk4rHVu2ry6RIr2Wfs+O324okSidrX7pTAnEJPCh/O5BtRlr7QtZI7ktOP3vsqr7Z5XoA==", - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.js" - } - }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -5667,16 +5645,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/bun-types": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.3.6.tgz", - "integrity": "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -5710,9 +5678,10 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001766", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz", - "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==", + "version": "1.0.30001720", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001720.tgz", + "integrity": "sha512-Ec/2yV2nNPwb4DnTANEV99ZWwm3ZWfdlfkQbWSDDt+PsXEVYwlhPH8tdMaPunYTKKmz7AnHi2oNEi1GcmKCD8g==", + "dev": true, "funding": [ { "type": "opencollective", From af3ca28c6d5b21ce2b8bf3caaf88f6526cf390b7 Mon Sep 17 00:00:00 2001 From: wjiayis Date: Sun, 25 Jan 2026 21:42:58 +0800 Subject: [PATCH 4/4] refactor: use IsCustom and not redefine logic in NewAIClientV2 --- internal/services/toolkit/client/client_v2.go | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/internal/services/toolkit/client/client_v2.go b/internal/services/toolkit/client/client_v2.go index 9f2bb0b9..3c672c66 100644 --- a/internal/services/toolkit/client/client_v2.go +++ b/internal/services/toolkit/client/client_v2.go @@ -63,21 +63,33 @@ func NewAIClientV2( logger *logger.Logger, ) *AIClientV2 { database := db.Database("paperdebugger") + + llmProvider := &models.LLMProviderConfig{ + APIKey: cfg.OpenAIAPIKey, + } + + var baseUrl string + var apiKey string + var modelSlug string - if cfg.InferenceBaseURL != "" && cfg.InferenceAPIKey != "" { - oaiClient := openai.NewClient( - option.WithBaseURL(cfg.InferenceBaseURL+"/openrouter"), - option.WithAPIKey(cfg.InferenceAPIKey), - ) - CheckOpenAIWorksV2(oaiClient, cfg.InferenceBaseURL+"/openrouter", "openai/gpt-5-nano", logger) + // User specified their own API key, use the OpenAI-compatible endpoint + if llmProvider != nil && llmProvider.IsCustom() { + baseUrl = cfg.OpenAIBaseURL + apiKey = cfg.OpenAIAPIKey + modelSlug = "gpt-5-nano" + // Use the default inference endpoint } else { - oaiClient := openai.NewClient( - option.WithBaseURL(cfg.OpenAIBaseURL), - option.WithAPIKey(cfg.OpenAIAPIKey), - ) - CheckOpenAIWorksV2(oaiClient, cfg.OpenAIBaseURL, "gpt-5-nano", logger) + baseUrl = cfg.InferenceBaseURL + "/openrouter" + apiKey = cfg.InferenceAPIKey + modelSlug = "openai/gpt-5-nano" } + oaiClient := openai.NewClient( + option.WithBaseURL(baseUrl), + option.WithAPIKey(apiKey), + ) + CheckOpenAIWorksV2(oaiClient, baseUrl, modelSlug, logger) + toolRegistry := initializeToolkitV2(db, projectService, cfg, logger) toolCallHandler := handler.NewToolCallHandlerV2(toolRegistry)