Skip to content

Conversation

@zerob13
Copy link
Collaborator

@zerob13 zerob13 commented Aug 19, 2025

  • 修复了内存泄漏问题

  • 修复了DeepLink 和 Artifacts 带来的安全漏洞

  • 为提供商设置添加搜索功能

  • 为 API 密钥输入添加密码可见性切换

  • 添加了Vercel AI 和AWS Bedrock 新供应商

  • 为 OpenRouter 添加全面的 OpenAI 推理模型支持

  • 增加了GPT5系列模型的更完善支持

  • 为 GPT-OSS 模型添加 reasoning_effort 参数支持

  • 添加架构兼容性检查和 Visual C++ Redistribu 支持

  • 解决使用 Ctrl+Shift+N 创建新窗口时的焦点闪烁问题

  • 为 PopoverContent 添加可滚动支持以防止溢出

  • Fixed memory leak issues

  • Fixed security vulnerabilities caused by DeepLink and Artifacts

  • Added search functionality for provider settings

  • Added password visibility toggle for API key inputs

  • Added new providers: Vercel AI and AWS Bedrock

  • Added comprehensive OpenAI reasoning models support for OpenRouter

  • Enhanced support for GPT-5 series models

  • Added reasoning_effort parameter support for GPT-OSS models

  • Added architecture compatibility checks and Visual C++ Redistributable support

  • Resolved focus flicker issue when creating new windows with Ctrl+Shift+N

  • Added scrollable support to PopoverContent to prevent overflow

Summary by CodeRabbit

  • New Features

    • Added AWS Bedrock provider with credentials, model management, and icon.
    • Added Vercel AI Gateway provider.
    • Expanded model support: GPT-5 family, OpenAI O1/O3 variants, and GLM-4.5V; introduced reasoningEffort/verbosity controls with persistence.
    • Secured SVG rendering and deeplink handling via sanitization.
    • Windows installer now checks system architecture and installs required VC++ runtime.
    • Provider list search; API key visibility toggles in multiple settings screens.
  • Bug Fixes

    • Corrected model enable toggle in onboarding.
    • Tabs now fully close when destroyed.

yyhhyyyyyy and others added 16 commits August 15, 2025 09:47
#751)

* feat: add OpenRouter GPT-5 reasoning effort and verbosity support

* feat: add comprehensive OpenAI reasoning models support for OpenRouter
…table installation support (#752)

* feat: add architecture compatibility checks and Visual C++ Redistributable installation support

* fix: include NSIS installer script in the build configuration
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 19, 2025

Walkthrough

Adds Windows NSIS installer pre-checks, introduces AWS Bedrock and Vercel AI Gateway providers, propagates reasoningEffort/verbosity through presenters, updates DB schema and shared types, expands model configs (GPT‑5/O1/O3, GLM‑4.5V), implements SVG sanitization (main/lib/renderer + i18n), adjusts UI (provider search, Bedrock settings, API key toggles), and bumps dependencies.

Changes

Cohort / File(s) Summary
Installer integration
electron-builder.yml, build/nsis-installer.nsh
Include custom NSIS script; add architecture and VC++ redist checks with optional download/installation; gated for installer (not uninstaller).
Dependency/version updates
package.json
Version bump 0.3.0→0.3.1; add AWS SDK Bedrock deps; update electron devDependency.
Lint config
.oxlintrc.json
Convert ignore entries to recursive globs (path/**).
SVG sanitization pipeline
src/main/lib/svgSanitizer.ts, src/main/presenter/devicePresenter/index.ts, src/renderer/src/components/artifacts/SvgArtifact.vue, src/renderer/src/i18n/*/artifacts.json
Add SVGSanitizer with options and singleton; expose DevicePresenter.sanitizeSvgContent; update SvgArtifact to async sanitize and render states; add i18n strings for sanitization UI.
Deep link hardening
src/main/presenter/deeplinkPresenter/index.ts
Sanitize message and string params; remove autoSend; add helpers with limits and pattern blocks; enhanced logging.
Providers: types and base
src/shared/presenter.d.ts, src/main/presenter/llmProviderPresenter/baseProvider.ts
Add AWS_BEDROCK_PROVIDER and AwsBedrockCredential; add DevicePresenter.sanitizeSvgContent; add default model fetch timeout and accessor.
Providers: factory and API
src/main/presenter/llmProviderPresenter/index.ts, src/main/presenter/threadPresenter/index.ts
Wire VercelAIGateway and AwsBedrock providers; extend startStreamCompletion to pass reasoningEffort/verbosity; on concurrency max, emit error event.
New providers
src/main/presenter/llmProviderPresenter/providers/awsBedrockProvider.ts, src/main/presenter/llmProviderPresenter/providers/vercelAIGatewayProvider.ts
Implement AWS Bedrock provider (model listing, completions, streaming, tools, checks); add Vercel AI Gateway provider delegating to OpenAI-compatible flows.
Provider capability propagation
src/main/presenter/llmProviderPresenter/providers/openAICompatibleProvider.ts, .../openAIResponsesProvider.ts, .../providers/ollamaProvider.ts
Add reasoningEffort/verbosity handling (GPT‑5 detection widened); unify model fetch timeout; improve function-call parsing; add Ollama thinking field handling and streaming reasoning events.
Model/provider configs
src/main/presenter/configPresenter/modelDefaultSettings.ts, src/main/presenter/configPresenter/providerModelSettings.ts, src/main/presenter/configPresenter/providers.ts, .../providers/zhipuProvider.ts
Add GPT‑5 and O1/O3 variants, add/rename entries (o1-pro), add GLM‑4.5V; add providers Vercel AI Gateway and AWS Bedrock (disabled by default).
DB schema & conversations
src/main/presenter/sqlitePresenter/tables/conversations.ts
Migration v6: add reasoning_effort, verbosity; CRUD paths map to settings; update latest version.
Renderer settings & search
src/renderer/src/components/settings/ModelProviderSettings.vue, .../BedrockProviderSettingsDetail.vue, .../ModelScopeMcpSync.vue
Add provider search/filter with debounced input; add Bedrock settings panel (credentials, verify, model mgmt); compact MCP Sync UI.
UI: API key visibility toggles
src/renderer/src/components/settings/AnthropicProviderSettingsDetail.vue, .../OllamaProviderSettingsDetail.vue, .../ProviderApiConfig.vue, src/renderer/src/views/WelcomeView.vue
Add show/hide API key controls with toggle buttons; minor fix to model enable handler in WelcomeView.
Chat and title state
src/renderer/src/stores/chat.ts, src/renderer/src/components/TitleView.vue
Extend chatConfig with thinkingBudget, reasoningEffort, verbosity; simplify bindings for reasoningEffort/verbosity.
GPT‑5 UI logic
src/renderer/src/components/ChatConfig.vue, .../ModelConfigDialog.vue
Change GPT‑5 detection to includes; gate temperature by supportsReasoningEffort; update visibility and validation logic.
Bedrock assets/icons
src/renderer/src/components/icons/ModelIcon.vue
Add AWS Bedrock icon and invert rule.
i18n provider texts
src/renderer/src/i18n/*/settings.json
Add provider.search and provider.bedrockLimitTip across locales.
Misc small tweaks
scripts/generate-i18n-types.js, src/main/presenter/tabPresenter.ts
Simplify regex (no behavior change); destroy tab now closes WebContents (not just DevTools).

Sequence Diagram(s)

sequenceDiagram
  participant C as SvgArtifact.vue
  participant D as DevicePresenter
  participant S as SVGSanitizer
  C->>D: sanitizeSvgContent(svg)
  D->>S: sanitize(svg)
  S-->>D: sanitized SVG or null
  D-->>C: result
  C->>C: Render loading/error/sanitized content
Loading
sequenceDiagram
  participant T as ThreadPresenter
  participant L as LLMProviderPresenter
  participant P as Provider (OpenAI/Bedrock/...)
  T->>L: startStreamCompletion(..., thinkingBudget, reasoningEffort, verbosity)
  L->>P: coreStream(messages, modelConfig{...})
  P-->>L: stream events (text/tool/reasoning/usage/error/stop)
  L-->>T: forwarded events (including concurrency error when full)
Loading
sequenceDiagram
  participant User as Installer
  participant NSIS as customInit
  NSIS->>NSIS: checkArchitectureCompatibility
  alt incompatible
    NSIS-->>User: Show mismatch message and abort
  else compatible
    NSIS->>NSIS: checkVCRedist
    alt missing
      NSIS->>NSIS: Download & run VC++ Redist
      NSIS->>NSIS: Re-check or abort on failure
    end
  end
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Poem

A rabbit taps keys in a moonlit nook,
New streams now reason, with verbose hooks.
Bedrock paths open, Vercel at the gate,
SVGs scrubbed clean—no risky fate.
Installers double-check, models abound—
Thump-thump! ships this build, safe and sound. 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@zerob13 zerob13 deleted the branch main August 19, 2025 04:26
@zerob13 zerob13 closed this Aug 19, 2025
@zerob13 zerob13 reopened this Aug 19, 2025
@zerob13
Copy link
Collaborator Author

zerob13 commented Aug 19, 2025

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 19, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 22

🔭 Outside diff range comments (9)
src/renderer/src/components/settings/ModelScopeMcpSync.vue (2)

151-155: Coerce and clamp options before invoking presenter

Ensure numbers are in the expected domain and avoid passing reactive objects directly (copying avoids accidental mutations downstream).

-    // 调用简化的同步API,所有的格式转换和导入都在服务端处理
-    const result = await llmP.syncModelScopeMcpServers(props.provider.id, syncOptions)
+    // 调用简化的同步API,所有的格式转换和导入都在服务端处理
+    const allowedSizes = new Set([10, 25, 50, 100])
+    const size = Number(syncOptions.page_size) || 50
+    const pageSize = allowedSizes.has(size) ? size : 50
+    const pageNumber = Math.max(1, Number(syncOptions.page_number) || 1)
+    const opts = { page_number: pageNumber, page_size: pageSize }
+    const result = await llmP.syncModelScopeMcpServers(props.provider.id, opts)

121-126: Ensure provider props include required fields
LLM_PROVIDER defines id, name, and apiType but does not include apiKey. If this component needs provider.apiKey, please update one of the following:

  • Extend the shared type in src/shared/presenter.d.ts:
     export type LLM_PROVIDER = {
       id: string
       name: string
       apiType: string
  • apiKey: string
    }
- Or narrow the props in `ModelScopeMcpSync.vue` to explicitly require `apiKey`:
```ts
const props = defineProps<{
  provider: Pick<LLM_PROVIDER, 'id'> & { apiKey: string }
}>()

Files to update:

  • src/shared/presenter.d.ts
  • src/renderer/src/components/settings/ModelScopeMcpSync.vue
src/main/presenter/deeplinkPresenter/index.ts (5)

265-289: Fix potential TDZ crash in waitForTabReady (clearTimeout before initialization).

clearTimeout(timeoutId) can be executed before timeoutId is initialized, throwing due to TDZ. Hoist and guard.

   private async waitForTabReady(tabId: number): Promise<void> {
     return new Promise((resolve) => {
       let resolved = false
+      let timeoutId: ReturnType<typeof setTimeout> | null = null
       const onTabReady = (readyTabId: number) => {
         if (readyTabId === tabId && !resolved) {
           resolved = true
           console.log(`[Deeplink] Tab ${tabId} renderer is ready`)
           eventBus.off('tab:renderer-ready', onTabReady)
-          clearTimeout(timeoutId)
+          if (timeoutId) clearTimeout(timeoutId)
           resolve()
         }
       }

       eventBus.on('tab:renderer-ready', onTabReady)

-      const timeoutId = setTimeout(() => {
+      timeoutId = setTimeout(() => {
         if (!resolved) {
           resolved = true
           eventBus.off('tab:renderer-ready', onTabReady)
           console.log(`[Deeplink] Timeout waiting for tab ${tabId}, proceeding anyway`)
           resolve()
         }
       }, 3000)
     })
   }

315-334: Support 'http' MCP server type to match shared types and avoid rejecting valid configs.

Shared MCPServerConfig allows 'http', but this block rejects anything except 'stdio'/'sse'. This breaks deeplinks for HTTP MCP servers.

-        let determinedType: 'sse' | 'stdio' | null = null
+        let determinedType: 'sse' | 'stdio' | 'http' | null = null
...
-        if (serverConfig.type) {
-          if (serverConfig.type === 'stdio' || serverConfig.type === 'sse') {
+        if (serverConfig.type) {
+          if (serverConfig.type === 'stdio' || serverConfig.type === 'sse' || serverConfig.type === 'http') {
             determinedType = serverConfig.type
             // Validate required fields based on explicit type
             if (determinedType === 'stdio' && !determinedCommand) {
               console.error(
                 `Server ${serverName} is type 'stdio' but missing required 'command' field`
               )
               continue
             }
-            if (determinedType === 'sse' && !determinedUrl) {
-              console.error(`Server ${serverName} is type 'sse' but missing required 'url' field`)
+            if ((determinedType === 'sse' || determinedType === 'http') && !determinedUrl) {
+              console.error(`Server ${serverName} is type '${determinedType}' but missing required 'url' field`)
               continue
             }
           } else {
             console.error(
-              `Server ${serverName} provided invalid 'type' value: ${serverConfig.type}, should be 'stdio' or 'sse'`
+              `Server ${serverName} provided invalid 'type' value: ${serverConfig.type}, should be 'stdio' | 'sse' | 'http'`
             )
             continue
           }

368-379: Treat 'http' like network type for defaults and field mapping.

Network types ('sse'/'http') should get network icon and baseUrl mapping.

           icons: determinedType === 'stdio' ? '🔌' : '🌐', // Different default icons
...
-          command: determinedType === 'stdio' ? determinedCommand! : defaultConfig.command!,
-          baseUrl: determinedType === 'sse' ? determinedUrl! : defaultConfig.baseUrl!
+          command: determinedType === 'stdio' ? determinedCommand! : defaultConfig.command!,
+          baseUrl: determinedType === 'sse' || determinedType === 'http' ? determinedUrl! : defaultConfig.baseUrl!

Also applies to: 398-401


383-391: Guard env merging against undefined and invalid JSON.

Spreading undefined throws and JSON.parse can fail. Default to {} and parse safely, otherwise one bad server aborts the whole install.

-          env: {
-            ...(typeof defaultConfig.env === 'string'
-              ? JSON.parse(defaultConfig.env)
-              : defaultConfig.env),
-            ...(typeof serverConfig.env === 'string'
-              ? JSON.parse(serverConfig.env)
-              : serverConfig.env)
-          },
+          env: {
+            ...((typeof defaultConfig.env === 'string'
+              ? JSON.parse(defaultConfig.env)
+              : defaultConfig.env) || {}),
+            ...((typeof serverConfig.env === 'string'
+              ? (() => {
+                  try { return JSON.parse(serverConfig.env as string) } catch {
+                    console.warn(`Invalid env JSON for server ${serverName}, ignoring`)
+                    return {}
+                  }
+                })()
+              : serverConfig.env) || {})
+          },

403-407: Redact secrets from logs when printing server configs.

env, headers, tokens may appear in finalConfig. Avoid logging full config.

-        console.log(
-          `Preparing to install MCP server: ${serverName} (type: ${determinedType})`,
-          finalConfig
-        )
+        console.log(
+          `Preparing to install MCP server: ${serverName} (type: ${determinedType})`,
+          { ...finalConfig, env: '[redacted]' }
+        )
src/main/presenter/threadPresenter/index.ts (1)

1480-1491: Align startStreamCompletion signature across implementation and tests

All thread-presenter calls have been updated to pass the new eventId and optional parameters in the correct order, and the LlmProviderPresenter implementation exactly matches the ILlmProviderPresenter interface. However, the unit tests for llmProviderPresenter.startStreamCompletion are still using the old three-parameter form and will fail to compile/run.

Please update the test cases in

  • test/main/presenter/llmProviderPresenter.test.ts (around lines 172, 218, 258, 364, 412)
    to pass at least the required fourth argument eventId (and any additional optional args as needed), for example:
- const stream = llmProviderPresenter.startStreamCompletion(
-   'mock-openai-api',
-   messages,
-   'mock-gpt-thinking',
- )
+ const stream = llmProviderPresenter.startStreamCompletion(
+   'mock-openai-api',
+   messages,
+   'mock-gpt-thinking',           // modelId
+   `test-event-${Date.now()}`,    // eventId
+   /* temperature? */,            // if needed
+   /* maxTokens? */,              // if needed
+   /* enabledMcpTools? */,
+   /* thinkingBudget? */,
+   /* reasoningEffort? */,
+   /* verbosity? */
+)
src/main/presenter/configPresenter/modelDefaultSettings.ts (1)

878-899: Verify the rename from o1-mini to o1-pro.

The model entry has been renamed from o1-mini to o1-pro with different parameters. This is a breaking change for existing configurations using the o1-mini identifier.

This rename could break existing user configurations. Please verify:

  1. Is this rename intentional?
  2. Are there migration strategies in place for users who have o1-mini configured?
  3. Should both entries exist to maintain backward compatibility?
#!/bin/bash
# Check for any references to o1-mini in the codebase
rg -n "o1-mini" --type ts --type json -g "!node_modules/**" -g "!dist/**"
🧹 Nitpick comments (53)
src/renderer/src/components/settings/ModelScopeMcpSync.vue (4)

135-139: Type syncOptions to prevent accidental type drift

Explicitly typing syncOptions guards against v-model induced string values and keeps the contract with the presenter clear.

-// 同步选项
-const syncOptions = reactive({
+// 同步选项
+type SyncOptions = {
+  page_number: number
+  page_size: number
+}
+const syncOptions = reactive<SyncOptions>({
   page_number: 1,
   page_size: 50
 })

84-89: Add role and live-region to error message for a11y

Screen readers won’t announce updates unless marked as alerts or live regions.

-      <div
-        v-if="errorMessage"
-        class="p-2 bg-destructive/10 border border-destructive/20 rounded text-xs text-destructive"
-      >
+      <div
+        v-if="errorMessage"
+        role="alert"
+        aria-live="polite"
+        class="p-2 bg-destructive/10 border border-destructive/20 rounded text-xs text-destructive"
+      >

58-61: Announce sync results to assistive tech

Make the results region live so changes (imported/skipped/errors) are announced.

-      <div v-if="syncResult" class="flex items-center gap-1 text-xs">
+      <div v-if="syncResult" class="flex items-center gap-1 text-xs" aria-live="polite">

157-159: Gate console logging behind DEV or switch to a user-facing toast

Avoid noisy logs in production builds.

-    if (result.imported > 0) {
-      console.log('MCP servers imported successfully:', result)
-    }
+    if (result.imported > 0 && import.meta.env.DEV) {
+      console.debug('MCP servers imported successfully:', result)
+    }
.oxlintrc.json (1)

10-15: Glob patterns likely only ignore root-level dirs; consider making them repo-wide

If you intend to ignore these folders anywhere in the repo (monorepo/packages/examples), prefer **/dir/** over dir/**. Current patterns only ignore at repo root.

Apply this diff if global ignore is desired:

-    "build/**",
-    "resources/**",
-    "scripts/**",
-    "runtime/**",
-    "docs/**",
-    "test/**"
+    "**/build/**",
+    "**/resources/**",
+    "**/scripts/**",
+    "**/runtime/**",
+    "**/docs/**",
+    "**/test/**"
build/nsis-installer.nsh (4)

77-83: Preserve and restore $5 since it’s now used for redist arch

If you adopt arch-aware redist detection, $5 is used. Preserve it like the other registers.

Apply this diff:

   Push $0
   Push $1
   Push $2
   Push $3
-  Push $4
+  Push $4
+  Push $5
@@
   ContinueInstall:
+    Pop $5
     Pop $4
     Pop $3
     Pop $2
     Pop $1
     Pop $0

Also applies to: 123-128


84-96: Edge: Aborting without popping preserved registers is safe here but can be balanced

Because Abort exits the installer init, the leaked stack entries won’t be observed. Still, popping before Abort keeps the stack balanced in case of future macro reuse.

If you want to be thorough, pop the saved registers just before each Abort.


98-121: Optional: verify the downloaded VC++ installer’s Authenticode signature

Relying solely on HTTPS and a redirect link is weaker than verifying signature. If feasible, add a signature check (e.g., via a WinVerifyTrust plugin) before ExecWait.

Do you plan to bundle or allow using a signature verification plugin (e.g., WinVerifyTrust) in your NSIS toolchain? If yes, I can draft the snippet.


19-75: Architecture detection approach is reasonable

Using ${RunningX64} plus env var probing for ARM64 is pragmatic and should work across common configurations. If future Windows versions change env var semantics, we can revisit with System::Call to GetNativeSystemInfo/IsWow64Process2.

scripts/generate-i18n-types.js (1)

12-12: Regex change LGTM; small hardening: safely quote non-identifier keys

The simplified character classes are equivalent. Consider JSON-stringifying non-identifier keys to handle embedded quotes safely.

-  return /^[a-zA-Z$][a-zA-Z0-9_$]*$/.test(key) ? key : `'${key}'`
+  return /^[a-zA-Z$][a-zA-Z0-9_$]*$/.test(key) ? key : JSON.stringify(key)
src/renderer/src/i18n/zh-TW/settings.json (1)

443-444: Consistency + punctuation polish for zh-TW

  • Use 「設定」 instead of 「設置」 for zh-TW consistency.
  • Use the ideographic comma 「、」 to separate model names inside full-width parentheses.

Apply this diff:

-    "settingsApplied": "設置已應用",
-    "bedrockLimitTip": "* 僅支援 Anthropic Claude(包括 Opus,Sonnet,Haiku 模型)"
+    "settingsApplied": "設定已套用",
+    "bedrockLimitTip": "* 僅支援 Anthropic Claude(包括 Opus、Sonnet、Haiku 模型)"
package.json (1)

60-62: Align AWS SDK client versions to minimize duplicate deps

Bedrock and Bedrock Runtime clients are on different patch levels. Aligning them helps avoid duplicate smithy packages and reduces install size.

Apply this diff:

-    "@aws-sdk/client-bedrock": "^3.840.0",
-    "@aws-sdk/client-bedrock-runtime": "^3.842.0",
+    "@aws-sdk/client-bedrock": "^3.842.0",
+    "@aws-sdk/client-bedrock-runtime": "^3.842.0",
src/renderer/src/i18n/ko-KR/settings.json (1)

228-228: Unify terminology and fix grammar

  • Prefer “서비스 제공업체” (already used elsewhere) over “프로바이더” for consistency.
  • Past tense is more natural for “settings applied”.

Apply this diff:

-    "search": "프로바이더 플랫폼 검색…",
+    "search": "서비스 제공업체 검색…",
-    "settingsApplied": "설정이 적용됩니다",
+    "settingsApplied": "설정이 적용되었습니다",

Also applies to: 443-443

src/renderer/src/i18n/zh-TW/artifacts.json (1)

41-42: Typography: use ellipsis character

Use the single-character ellipsis 「…」 to match common zh-TW typography. Optional stylistic tweak.

Apply this diff:

-  "sanitizingSvg": "正在淨化SVG內容...",
-  "svgSanitizationFailed": "SVG內容未通過安全驗證"
+  "sanitizingSvg": "正在淨化SVG內容…",
+  "svgSanitizationFailed": "SVG內容未通過安全驗證"
src/renderer/src/i18n/ja-JP/artifacts.json (1)

41-42: Natural Japanese phrasing + ellipsis

  • Prefer “サニタイズ中…” for ongoing action.
  • Fix grammar: 「のセキュリティ検証に失敗しました」.

Apply this diff:

-  "sanitizingSvg": "SVGコンテンツの浄化...",
-  "svgSanitizationFailed": "SVGコンテンツにセキュリティ検証に失敗しました"
+  "sanitizingSvg": "SVGコンテンツをサニタイズ中…",
+  "svgSanitizationFailed": "SVGコンテンツのセキュリティ検証に失敗しました"
src/renderer/src/i18n/zh-CN/artifacts.json (1)

39-42: SVG sanitization i18n keys added — LGTM with minor zh-CN phrasing/spacing nitpicks

The strings are clear. For zh-CN typography, adding a space around “SVG” improves readability.

Apply this diff for the three keys:

-  "sanitizingSvg": "正在净化SVG内容...",
-  "svgSanitizationFailed": "SVG内容未通过安全验证",
-  "noSvgContent": "没有可用的SVG内容"
+  "sanitizingSvg": "正在净化 SVG 内容...",
+  "svgSanitizationFailed": "SVG 内容未通过安全验证",
+  "noSvgContent": "没有可用的 SVG 内容"
src/renderer/src/components/icons/ModelIcon.vue (1)

154-169: Consolidate dark-mode invert logic and avoid repeated toLowerCase calls

Minor cleanup to reduce repetition and make it easier to append future providers.

Apply this diff to simplify the computed block:

 const invert = computed(() => {
-  if (!props.isDark) {
-    return false
-  }
-  if (
-    props.modelId.toLowerCase() === 'openai' ||
-    props.modelId.toLowerCase().includes('openai-responses') ||
-    props.modelId.toLowerCase().includes('openrouter') ||
-    props.modelId.toLowerCase().includes('ollama') ||
-    props.modelId.toLowerCase().includes('grok') ||
-    props.modelId.toLowerCase().includes('groq') ||
-    props.modelId.toLowerCase().includes('github') ||
-    props.modelId.toLowerCase().includes('moonshot') ||
-    props.modelId.toLowerCase().includes('lmstudio') ||
-    props.modelId.toLowerCase().includes('aws-bedrock')
-  ) {
-    return true
-  }
-  return false
+  if (!props.isDark) return false
+  const id = props.modelId.toLowerCase()
+  if (id === 'openai') return true
+  const invertKeys = [
+    'openai-responses',
+    'openrouter',
+    'ollama',
+    'grok',
+    'groq',
+    'github',
+    'moonshot',
+    'lmstudio',
+    'aws-bedrock',
+  ]
+  return invertKeys.some((k) => id.includes(k))
 })
src/renderer/src/i18n/ru-RU/settings.json (1)

443-445: Fix Russian phrasing: past-tense toast and Bedrock tip grammar

  • “settingsApplied” should be past tense to match other locales (“Settings applied”).
  • Bedrock tip: use singular verb with the brand or clarify subject.
-    "settingsApplied": "Применяются настройки",
-    "bedrockLimitTip": "* Поддерживает только Anthropic Claude (включая модели Opus, Sonnet, Haiku)"
+    "settingsApplied": "Настройки применены",
+    "bedrockLimitTip": "* Поддерживается только Anthropic Claude (включая модели Opus, Sonnet, Haiku)"
src/renderer/src/i18n/zh-CN/settings.json (1)

443-445: Bedrock tip punctuation for zh-CN

Use the ‘、’ list separator inside full-width parentheses for zh-CN.

-    "bedrockLimitTip": "* 仅支持 Anthropic Claude(包括 Opus,Sonnet,Haiku 模型)"
+    "bedrockLimitTip": "* 仅支持 Anthropic Claude(包括 Opus、Sonnet、Haiku 模型)"
src/renderer/src/i18n/ko-KR/artifacts.json (1)

40-42: Polish Korean phrasing and typographic ellipsis for clarity and correctness

  • Prefer “콘텐츠” over “컨텐츠”.
  • Use progressive form “정화 중…” and the ellipsis character “…” for UI status.
  • Slightly refine failure phrasing.

Apply this diff:

-  "noSvgContent": "사용 가능한 SVG 컨텐츠가 없습니다",
-  "sanitizingSvg": "SVG 컨텐츠 정화 ...",
-  "svgSanitizationFailed": "SVG 컨텐츠는 보안 검증에 실패했습니다"
+  "noSvgContent": "사용 가능한 SVG 콘텐츠가 없습니다",
+  "sanitizingSvg": "SVG 콘텐츠 정화 중…",
+  "svgSanitizationFailed": "SVG 콘텐츠가 보안 검증을 통과하지 못했습니다"
src/main/presenter/llmProviderPresenter/baseProvider.ts (1)

33-33: Clarify time unit in constant name

Suffix with “_MS” and use numeric separators for readability. Keeps the value intact.

Apply this diff:

-  protected static readonly DEFAULT_MODEL_FETCH_TIMEOUT = 12000 // 提升到12秒作为通用默认值
+  protected static readonly DEFAULT_MODEL_FETCH_TIMEOUT_MS = 12_000 // 提升到12秒作为通用默认值

Note: If you apply this rename, also update references (see next comment).

src/renderer/src/i18n/en-US/artifacts.json (1)

39-42: Use Unicode ellipsis and “Failed to …” phrasing in i18n artifacts
Align with project typography and failure-style across all locales:

  • Update src/renderer/src/i18n/en-US/artifacts.json:
    -  "copyImageFailedDesc": "Could not copy image to clipboard.",
    -  "sanitizingSvg": "Sanitizing SVG content...",
    +  "copyImageFailedDesc": "Failed to copy image to clipboard",
    +  "sanitizingSvg": "Sanitizing SVG content…",
  • In every other artifacts.json (ru-RU, zh-TW, zh-HK, zh-CN, ko-KR, ja-JP, fa-IR, fr-FR), locate the sanitizingSvg entry and replace any ASCII ellipsis (... or ...) with the single Unicode ellipsis character () for consistent typography.
src/renderer/src/i18n/zh-HK/artifacts.json (1)

40-42: Add spacing around “SVG 內容” for consistency with existing keys

Elsewhere in this locale (e.g., “SVG 預覽”), “SVG” is spaced from Chinese text. Align these three new strings to that convention.

-  "noSvgContent": "沒有可用的SVG內容",
-  "sanitizingSvg": "正在淨化SVG內容...",
-  "svgSanitizationFailed": "SVG內容未通過安全驗證"
+  "noSvgContent": "沒有可用的 SVG 內容",
+  "sanitizingSvg": "正在淨化 SVG 內容...",
+  "svgSanitizationFailed": "SVG 內容未通過安全驗證"
src/renderer/src/i18n/fa-IR/artifacts.json (1)

40-42: Polish Persian translations for clarity and naturalness

These read a bit unnatural. Suggested improvements below maintain the intended meaning and better match common UI phrasing.

-  "noSvgContent": "بدون محتوای SVG در دسترس نیست",
-  "sanitizingSvg": "تصفیه محتوای SVG ...",
-  "svgSanitizationFailed": "محتوای SVG تأیید امنیتی را شکست داد"
+  "noSvgContent": "هیچ محتوای SVG در دسترس نیست",
+  "sanitizingSvg": "در حال پاک‌سازی محتوای SVG…",
+  "svgSanitizationFailed": "محتوای SVG در تأیید امنیتی پذیرفته نشد"
src/renderer/src/i18n/zh-HK/settings.json (1)

228-229: Unify provider search phrasing and punctuation; refine Bedrock tip list punctuation

  • Use “服務商” consistently (drop “平台”) to align with the rest of this section.
  • Use the same ellipsis style across the file (this file mostly uses “...”, not “…”).
  • Prefer the Chinese list separator “、” inside full-width brackets.
-    "search": "搜尋服務商平台…",
+    "search": "搜尋服務商...",
@@
-    "settingsApplied": "設置已應用",
-    "bedrockLimitTip": "* 僅支持 Anthropic Claude(包括 Opus,Sonnet,Haiku 模型)"
+    "settingsApplied": "設置已應用",
+    "bedrockLimitTip": "* 僅支持 Anthropic Claude(包括 Opus、Sonnet、Haiku)"

Follow-up: there’s broader inconsistency in this file between “搜索” and “搜尋”, and “設定” vs “設置”. If desired, I can run through the file to normalize zh‑HK terminology in one pass.

Also applies to: 443-445

src/renderer/src/components/settings/ModelConfigDialog.vue (2)

399-401: Align contextLength max validation with the input max and i18n

The input uses a max of 10,000,000 and the i18n message also references 10,000,000, but validation allows up to 100,000,000. Align to 10,000,000 to avoid confusion.

-  } else if (config.value.contextLength > 100_000_000) {
+  } else if (config.value.contextLength > 10_000_000) {

492-499: Tighten detection of “supportsReasoningEffort” to valid enum values

A plain null/undefined check can produce false positives if an empty string sneaks in. Consider validating against the allowed set.

-const supportsReasoningEffort = computed(() => {
-  return config.value.reasoningEffort !== undefined && config.value.reasoningEffort !== null
-})
+const supportsReasoningEffort = computed(() => {
+  const v = config.value.reasoningEffort
+  return v === 'minimal' || v === 'low' || v === 'medium' || v === 'high'
+})
src/main/presenter/sqlitePresenter/tables/conversations.ts (1)

117-160: Insert: use SQL NULL for enabled_mcp_tools instead of string "NULL"

Minor correctness: storing the literal string "NULL" makes the column a non-null “NULL” string. Prefer actual SQL NULL.

-      settings.enabledMcpTools ? JSON.stringify(settings.enabledMcpTools) : 'NULL',
+      settings.enabledMcpTools ? JSON.stringify(settings.enabledMcpTools) : null,
src/main/presenter/deeplinkPresenter/index.ts (1)

295-304: Add size guard before decoding Base64 JSON to avoid memory blowups.

A very large code param could spike memory usage.

     try {
+      // Basic size guard (Base64 inflates ~33%)
+      if (jsonBase64.length > 1_500_000) {
+        console.error('MCP config payload too large')
+        return
+      }
       // 解码 Base64 并解析 JSON
       const jsonString = Buffer.from(jsonBase64, 'base64').toString('utf-8')
src/main/lib/svgSanitizer.ts (2)

59-66: Honor allowScripts option (currently ignored).

Option exists but scripts are always stripped. Either remove the option or gate removal by it. Gating keeps defaults secure and makes the option meaningful.

-      // 2. Remove script tags and their content
-      sanitized = this.removeScriptTags(sanitized)
+      // 2. Remove script tags and their content
+      if (!this.options.allowScripts) {
+        sanitized = this.removeScriptTags(sanitized)
+      }

288-291: Case-insensitive validation of opening tag.

Use a regex to accept <svg in any case and with attributes.

-    if (!output.trim().startsWith('<svg')) {
+    if (!/^\s*<svg\b/i.test(output)) {
       return false
     }
src/shared/presenter.d.ts (1)

132-135: Reduce duplication of union types with type aliases.

'minimal' | 'low' | 'medium' | 'high' and 'low' | 'medium' | 'high' appear multiple times. Consider centralizing to type ReasoningEffort and type Verbosity to keep types DRY.

Example:

export type ReasoningEffort = 'minimal' | 'low' | 'medium' | 'high'
export type Verbosity = 'low' | 'medium' | 'high'

Also applies to: 153-156

src/renderer/src/components/TitleView.vue (1)

261-274: Avoid as any when updating store config.

Prefer a properly typed payload (e.g., a Partial<CONVERSATION_SETTINGS> in the store method) to keep type guarantees.

If updating the store signature isn’t possible now, consider a local helper with a typed shape to avoid any.

src/renderer/src/components/settings/OllamaProviderSettingsDetail.vue (2)

27-35: Disable autocomplete for API key input.

Helps prevent accidental storage/fill of secrets.

           <Input
             :id="`${provider.id}-apikey`"
             v-model="apiKey"
             :type="showApiKey ? 'text' : 'password'"
             :placeholder="t('settings.provider.keyPlaceholder')"
             style="padding-right: 2.5rem !important"
+            autocomplete="off"
+            autocapitalize="off"
+            spellcheck="false"
             @blur="handleApiKeyChange(String($event.target.value))"
             @keyup.enter="handleApiKeyEnter(apiKey)"
           />

37-41: Minor accessibility and form-safety tweaks to the toggle button.

Explicitly set type="button" and add an aria-label.

-          <Button
+          <Button
             variant="ghost"
             size="sm"
             class="absolute right-2 top-1/2 transform -translate-y-1/2 h-7 w-7 p-0 hover:bg-transparent"
+            type="button"
+            :aria-label="showApiKey ? t('settings.provider.hideKey') : t('settings.provider.showKey')"
             @click="showApiKey = !showApiKey"
           >
src/renderer/src/i18n/en-US/settings.json (1)

443-445: Nit: polish Bedrock tip phrasing for clarity.

Minor wording improvement for end-user clarity.

Apply:

-    "bedrockLimitTip": "* Only Anthropic Claude supported (including Opus, Sonnet, Haiku models)"
+    "bedrockLimitTip": "* Only Anthropic Claude models are supported (Opus, Sonnet, Haiku)"
src/renderer/src/components/settings/ProviderApiConfig.vue (1)

45-67: Good UX addition; add small security & a11y tweaks and avoid inline !important.

  • Disable autocomplete/spellcheck for API keys.
  • Provide an aria-label for the eye button.
  • Replace inline padding with a utility class to avoid !important.

Apply:

-        <Input
+        <Input
           :id="`${provider.id}-apikey`"
           :model-value="apiKey"
           :type="showApiKey ? 'text' : 'password'"
           :placeholder="t('settings.provider.keyPlaceholder')"
-          style="padding-right: 2.5rem !important"
+          class="pr-10"
+          autocomplete="off"
+          autocapitalize="off"
+          spellcheck="false"
           @blur="handleApiKeyChange($event.target.value)"
           @keyup.enter="$emit('validate-key', apiKey)"
           @update:model-value="apiKey = String($event)"
         />
         <Button
           variant="ghost"
           size="sm"
           class="absolute right-2 top-1/2 transform -translate-y-1/2 h-7 w-7 p-0 hover:bg-transparent"
           @click="showApiKey = !showApiKey"
+          :aria-label="showApiKey ? 'Hide API key' : 'Show API key'"
         >
src/renderer/src/components/settings/AnthropicProviderSettingsDetail.vue (1)

56-77: Consistent API key visibility toggle; add a11y and disable autocomplete.

Mirror the ProviderApiConfig improvements for consistency:

  • Turn off autocomplete/spellcheck on the key field.
  • Add aria-label to the toggle button.
  • Use utility padding instead of inline !important.

Apply:

-          <Input
+          <Input
             :id="`${provider.id}-apikey`"
             v-model="apiKey"
             :type="showApiKey ? 'text' : 'password'"
             :placeholder="t('settings.provider.keyPlaceholder')"
-            style="padding-right: 2.5rem !important"
+            class="pr-10"
+            autocomplete="off"
+            autocapitalize="off"
+            spellcheck="false"
             @blur="handleApiKeyChange(String($event.target.value))"
             @keyup.enter="handleApiKeyEnter(apiKey)"
           />
           <Button
             variant="ghost"
             size="sm"
             class="absolute right-2 top-1/2 transform -translate-y-1/2 h-7 w-7 p-0 hover:bg-transparent"
             @click="showApiKey = !showApiKey"
+            :aria-label="showApiKey ? 'Hide API key' : 'Show API key'"
           >
src/main/presenter/devicePresenter/index.ts (1)

464-507: Consider moving the size limit to a configuration constant.

The 1MB size limit is hardcoded in the method. Consider extracting it to a constant at the class level for better maintainability and configurability.

Apply this refactor to improve maintainability:

 export class DevicePresenter implements IDevicePresenter {
+  private static readonly MAX_SVG_SIZE = 1024 * 1024 // 1MB
+
   static getDefaultHeaders(): Record<string, string> {

   ...

   async sanitizeSvgContent(svgContent: string): Promise<string | null> {
     try {
       console.log('Sanitizing SVG content, length:', svgContent.length)

       // 基本输入验证
       if (!svgContent || typeof svgContent !== 'string') {
         console.warn('Invalid SVG content provided')
         return null
       }

       // 长度限制检查
-      if (svgContent.length > 1024 * 1024) {
-        // 1MB limit
+      if (svgContent.length > DevicePresenter.MAX_SVG_SIZE) {
         console.warn('SVG content exceeds size limit')
         return null
       }
src/main/presenter/threadPresenter/index.ts (1)

1470-1491: Reduce duplication when plucking conversation settings before streaming.

You repeat the same destructuring in three places. Consider a tiny helper to fetch the latest conversation + settings bundle to keep the call sites cleaner and reduce drift if the interface evolves again.

Also applies to: 1588-1597, 3676-3685

src/renderer/src/stores/settings.ts (1)

1557-1565: Consider secure storage for long-lived cloud credentials.

ElectronStore persists in plaintext. If possible, back these with the OS keychain (e.g., keytar) and only cache ephemeral tokens/settings in ElectronStore.

src/renderer/src/components/artifacts/SvgArtifact.vue (1)

76-89: Avoid double-sanitizing on mount (watch with immediate already covers it).

The immediate watch triggers sanitize on mount; onMounted triggers it again. Remove one to avoid redundant calls.

-onMounted(() => {
-  if (props.block.content) {
-    sanitizeSvgContent(props.block.content)
-  }
-})
src/main/presenter/llmProviderPresenter/providers/ollamaProvider.ts (1)

496-506: Gate reasoning_effort behind a backend‐capability check
Passing reasoning_effort whenever modelConfig.reasoningEffort is set can trigger 4xx errors on Ollama builds that don’t recognize it. We should only spread that option if the target build actually supports it.

Suggestions:

  • Maintain a list or map of models that support reasoning_effort (keyed by modelId) and only spread when modelConfig.reasoningEffort && supportedByModel(modelId, 'reasoning_effort').
  • If the Ollama client offers a metadata or “listModels” endpoint, inspect each model’s capabilities for "reasoning_effort".
  • As a fallback, catch a 4xx response and retry the request without the unsupported field.

Location to update:
• src/main/presenter/llmProviderPresenter/providers/ollamaProvider.ts around lines 503–506.

src/main/presenter/llmProviderPresenter/providers/openAICompatibleProvider.ts (1)

541-541: Same concern with GPT-5 detection pattern.

The same includes('gpt-5') pattern is used here for determining max_completion_tokens. This should be consistent with the logic at Line 220.

Consider extracting this logic into a helper method to maintain consistency:

+  private isGPT5Model(modelId: string): boolean {
+    return modelId.startsWith('gpt-5') || modelId.includes('/gpt-5');
+  }
+
   // Then use it in both places:
-      modelId.includes('gpt-5')
+      this.isGPT5Model(modelId)
src/renderer/src/components/settings/ModelProviderSettings.vue (1)

196-207: Consider case sensitivity in provider filtering.

The filterProviders function performs case-insensitive filtering, which is good. However, consider trimming the search query to handle accidental spaces.

 const filterProviders = (providers: LLM_PROVIDER[]) => {
-  if (!searchQuery.value.trim()) {
+  const query = searchQuery.value.trim()
+  if (!query) {
     return providers
   }
-  const query = searchQuery.value.toLowerCase().trim()
+  const lowerQuery = query.toLowerCase()
   return providers.filter(
     (provider) =>
-      t(provider.name).toLowerCase().includes(query) ||
-      provider.id.toLowerCase().includes(query) ||
-      (provider.apiType && provider.apiType.toLowerCase().includes(query))
+      t(provider.name).toLowerCase().includes(lowerQuery) ||
+      provider.id.toLowerCase().includes(lowerQuery) ||
+      (provider.apiType && provider.apiType.toLowerCase().includes(lowerQuery))
   )
 }
src/main/presenter/llmProviderPresenter/providers/awsBedrockProvider.ts (8)

96-100: Inconsistent language in error messages and logs

The codebase mixes Chinese and English in error messages and console logs. For better maintainability and international usability, consider standardizing on one language (preferably English for system logs).

-      console.error('获取AWS Bedrock Anthropic模型列表出错:', error)
+      console.error('Failed to fetch AWS Bedrock Anthropic models:', error)
-    console.log('从API获取模型列表失败,使用默认模型配置')
+    console.log('Failed to fetch models from API, using default model configuration')

168-169: Localization inconsistency in error messages

Similar to the previous comment, the error message uses Chinese while most of the codebase uses English.

-        return { isOk: false, errorMsg: '未初始化 AWS Bedrock SDK' }
+        return { isOk: false, errorMsg: 'AWS Bedrock SDK not initialized' }

186-186: Use the instance's default model instead of hardcoding

The check method hardcodes this.defaultModel but it's better to use the actual model being configured to ensure the check is valid for the specific model being used.


200-200: Standardize error message language

-      return { isOk: false, errorMsg: `API 检查失败: ${errorMessage}` }
+      return { isOk: false, errorMsg: `API check failed: ${errorMessage}` }

640-640: Remove or guard debug console.log statements

Debug logging statements should be removed or wrapped in a debug flag check before production deployment.

-    console.log('modelConfig', modelConfig, modelId)
+    // Only log in debug mode
+    if (process.env.DEBUG) {
+      console.log('modelConfig', modelConfig, modelId)
+    }

676-678: Consider making thinking budget configurable

The thinking budget is hardcoded to 1024 tokens. Consider making this configurable through modelConfig for better flexibility.

       if (modelId.includes('claude-3-7')) {
-        payload.thinking = { budget_tokens: 1024, type: 'enabled' }
+        payload.thinking = { 
+          budget_tokens: modelConfig.thinkingBudget || 1024, 
+          type: 'enabled' 
+        }
       }

794-795: Consolidate error handling for JSON parsing

There are nested try-catch blocks with similar error messages for JSON parsing. Consider consolidating the error handling.

             try {
               // Try to parse complete JSON
               const jsonStr = accumulatedJson.trim()
               if (jsonStr && (jsonStr.startsWith('{') || jsonStr.startsWith('['))) {
-                try {
-                  const jsonObject = JSON.parse(jsonStr)
-                  if (jsonObject && typeof jsonObject === 'object') {
-                    currentToolInputs = { ...currentToolInputs, ...jsonObject }
-                  }
-                } catch (e) {
-                  console.error('解析完整JSON失败:', e)
-                }
+                const jsonObject = JSON.parse(jsonStr)
+                if (jsonObject && typeof jsonObject === 'object') {
+                  currentToolInputs = { ...currentToolInputs, ...jsonObject }
+                }
               }
             } catch (e) {
-              console.error('处理累积JSON失败:', e)
+              console.error('Failed to parse accumulated JSON:', e)
             }

Also applies to: 798-799


910-915: Standardize error messages in stream error handling

       console.error('AWS Bedrock Claude coreStream error:', error)
       yield {
         type: 'error',
-        error_message: error instanceof Error ? error.message : '未知错误'
+        error_message: error instanceof Error ? error.message : 'Unknown error'
       }

Comment on lines +15 to +17
Function checkVCRedist
ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" "Installed"
FunctionEnd
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

VC++ Redistributable check is x64-only; add arch-aware detection (+reg view)

Currently this only inspects the x64 key. ARM64 builds will mis-detect and fail to install the correct redist. Also, force the 64-bit registry view to avoid WOW64 redirection issues.

Apply this diff:

-  Function checkVCRedist
-    ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" "Installed"
-  FunctionEnd
+  Function checkVCRedist
+    ; Decide which VC++ runtime architecture to check:
+    ; Prefer app arch ($3). If universal, pick the system arch ($1).
+    StrCpy $5 $3
+    ${If} $5 == "universal"
+      StrCpy $5 $1
+    ${EndIf}
+    ${If} $5 == "arm64"
+      ReadRegDWORD /reg64 $0 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\arm64" "Installed"
+    ${Else}
+      ; Default to x64
+      ReadRegDWORD /reg64 $0 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" "Installed"
+    ${EndIf}
+  FunctionEnd

Note: This relies on $1 (system arch) and $3 (app arch) set by checkArchitectureCompatibility, which you already call before checkVCRedist.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Function checkVCRedist
ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" "Installed"
FunctionEnd
Function checkVCRedist
; Decide which VC++ runtime architecture to check:
; Prefer app arch ($3). If universal, pick the system arch ($1).
StrCpy $5 $3
${If} $5 == "universal"
StrCpy $5 $1
${EndIf}
${If} $5 == "arm64"
ReadRegDWORD /reg64 $0 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\arm64" "Installed"
${Else}
; Default to x64
ReadRegDWORD /reg64 $0 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" "Installed"
${EndIf}
FunctionEnd
🤖 Prompt for AI Agents
In build/nsis-installer.nsh around lines 15-17, the VC++ Redistributable check
currently only reads the x64 registry key and can mis-detect on ARM64 or when
WOW64 registry redirection occurs; update checkVCRedist to pick the correct
registry subkey based on the arch values set earlier ($1 = system arch, $3 = app
arch) (use "x64", "x86" or "arm64" in the path:
SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\<arch>) and force the 64-bit
registry view with SetRegView 64 before ReadRegDWORD to avoid WOW64 redirection;
after the read restore the previous view if needed and handle missing key the
same as before.

Comment on lines +100 to +113
MessageBox MB_YESNO "\
NOTE: ${PRODUCT_NAME} requires $\r$\n\
'Microsoft Visual C++ Redistributable'$\r$\n\
to function properly.$\r$\n$\r$\n\
Download and install now?" /SD IDYES IDYES InstallVCRedist IDNO DontInstall
InstallVCRedist:
inetc::get /CAPTION " " /BANNER "Downloading Microsoft Visual C++ Redistributable..." "https://aka.ms/vs/17/release/vc_redist.x64.exe" "$TEMP\vc_redist.x64.exe"
ExecWait "$TEMP\vc_redist.x64.exe /install /norestart"
;IfErrors InstallError ContinueInstall ; vc_redist exit code is unreliable :(
Call checkVCRedist
${If} $0 == "1"
Goto ContinueInstall
${EndIf}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Download/installer path is hardcoded to x64; select arm64 when needed and handle download errors

On ARM64 app/system, you should fetch and run vc_redist.arm64.exe. Also handle inetc::get result to fail fast if the download is canceled/blocked.

Apply this diff:

-    MessageBox MB_YESNO "\
+    MessageBox MB_YESNO "\
       NOTE: ${PRODUCT_NAME} requires $\r$\n\
       'Microsoft Visual C++ Redistributable'$\r$\n\
       to function properly.$\r$\n$\r$\n\
       Download and install now?" /SD IDYES IDYES InstallVCRedist IDNO DontInstall
     InstallVCRedist:
-      inetc::get /CAPTION " " /BANNER "Downloading Microsoft Visual C++ Redistributable..." "https://aka.ms/vs/17/release/vc_redist.x64.exe" "$TEMP\vc_redist.x64.exe"
-      ExecWait "$TEMP\vc_redist.x64.exe /install /norestart"
-      ;IfErrors InstallError ContinueInstall ; vc_redist exit code is unreliable :(
+      ; $5 is set in checkVCRedist to either "x64" or "arm64"
+      StrCpy $4 "$TEMP\vc_redist.$5.exe"
+      inetc::get /CAPTION " " /BANNER "Downloading Microsoft Visual C++ Redistributable..." "https://aka.ms/vs/17/release/vc_redist.$5.exe" "$4"
+      Pop $2
+      StrCmp $2 "OK" +2
+      Goto InstallError
+      ExecWait "$4 /install /norestart"
+      ; vc_redist exit code is unreliable; re-check the registry instead
       Call checkVCRedist
       ${If} $0 == "1"
         Goto ContinueInstall
       ${EndIf}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
MessageBox MB_YESNO "\
NOTE: ${PRODUCT_NAME} requires $\r$\n\
'Microsoft Visual C++ Redistributable'$\r$\n\
to function properly.$\r$\n$\r$\n\
Download and install now?" /SD IDYES IDYES InstallVCRedist IDNO DontInstall
InstallVCRedist:
inetc::get /CAPTION " " /BANNER "Downloading Microsoft Visual C++ Redistributable..." "https://aka.ms/vs/17/release/vc_redist.x64.exe" "$TEMP\vc_redist.x64.exe"
ExecWait "$TEMP\vc_redist.x64.exe /install /norestart"
;IfErrors InstallError ContinueInstall ; vc_redist exit code is unreliable :(
Call checkVCRedist
${If} $0 == "1"
Goto ContinueInstall
${EndIf}
MessageBox MB_YESNO "\
NOTE: ${PRODUCT_NAME} requires $\r$\n\
'Microsoft Visual C++ Redistributable'$\r$\n\
to function properly.$\r$\n$\r$\n\
Download and install now?" /SD IDYES IDYES InstallVCRedist IDNO DontInstall
InstallVCRedist:
; $5 is set in checkVCRedist to either "x64" or "arm64"
StrCpy $4 "$TEMP\vc_redist.$5.exe"
inetc::get /CAPTION " " /BANNER "Downloading Microsoft Visual C++ Redistributable..." "https://aka.ms/vs/17/release/vc_redist.$5.exe" "$4"
Pop $2
StrCmp $2 "OK" +2
Goto InstallError
ExecWait "$4 /install /norestart"
; vc_redist exit code is unreliable; re-check the registry instead
Call checkVCRedist
${If} $0 == "1"
Goto ContinueInstall
${EndIf}

Comment on lines +176 to +182
// Security: Validate and sanitize message content
msg = this.sanitizeMessageContent(decodeURIComponent(msg))
if (!msg) {
console.warn('Message content was rejected by security filters')
return
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid double-decoding URLSearchParams values (can throw and drop messages).

URL.searchParams.get() already returns decoded strings. Running decodeURIComponent again can throw on inputs like 100% ready and abort handling. Same for model/system/mentions.

Apply these diffs to rely on the already-decoded values:

-    // Security: Validate and sanitize message content
-    msg = this.sanitizeMessageContent(decodeURIComponent(msg))
+    // Security: Validate and sanitize message content
+    msg = this.sanitizeMessageContent(msg)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Security: Validate and sanitize message content
msg = this.sanitizeMessageContent(decodeURIComponent(msg))
if (!msg) {
console.warn('Message content was rejected by security filters')
return
}
// Security: Validate and sanitize message content
msg = this.sanitizeMessageContent(msg)
if (!msg) {
console.warn('Message content was rejected by security filters')
return
}
🤖 Prompt for AI Agents
In src/main/presenter/deeplinkPresenter/index.ts around lines 176 to 182, the
code is double-decoding URLSearchParams values which can throw (e.g., "100%
ready") and drop messages; remove decodeURIComponent calls and use the
already-decoded values returned by URL.searchParams.get() for msg, model,
system, and mentions, then pass those raw values into sanitizeMessageContent
(guarding for null/undefined before sanitization) and keep the existing
security-reject/return flow if sanitizeMessageContent returns falsy.

Comment on lines +186 to 192
modelId = this.sanitizeStringParameter(decodeURIComponent(modelId))
}

let systemPrompt = params.get('system')
if (systemPrompt && systemPrompt.trim() !== '') {
systemPrompt = decodeURIComponent(systemPrompt)
systemPrompt = this.sanitizeStringParameter(decodeURIComponent(systemPrompt))
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove redundant decodeURIComponent for model/system params.

Double-decoding can cause malformed URI errors and break deeplink processing.

-  if (modelId && modelId.trim() !== '') {
-      modelId = this.sanitizeStringParameter(decodeURIComponent(modelId))
-  }
+  if (modelId && modelId.trim() !== '') {
+      modelId = this.sanitizeStringParameter(modelId)
+  }

-  if (systemPrompt && systemPrompt.trim() !== '') {
-      systemPrompt = this.sanitizeStringParameter(decodeURIComponent(systemPrompt))
-  } else {
+  if (systemPrompt && systemPrompt.trim() !== '') {
+      systemPrompt = this.sanitizeStringParameter(systemPrompt)
+  } else {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
modelId = this.sanitizeStringParameter(decodeURIComponent(modelId))
}
let systemPrompt = params.get('system')
if (systemPrompt && systemPrompt.trim() !== '') {
systemPrompt = decodeURIComponent(systemPrompt)
systemPrompt = this.sanitizeStringParameter(decodeURIComponent(systemPrompt))
} else {
if (modelId && modelId.trim() !== '') {
modelId = this.sanitizeStringParameter(modelId)
}
let systemPrompt = params.get('system')
if (systemPrompt && systemPrompt.trim() !== '') {
systemPrompt = this.sanitizeStringParameter(systemPrompt)
} else {
🤖 Prompt for AI Agents
In src/main/presenter/deeplinkPresenter/index.ts around lines 186 to 192, the
code double-decodes the model and system query parameters which can cause
malformed URI errors; remove the redundant decodeURIComponent calls (i.e., use
the already-decoded value from params or decode once when reading the param) and
then pass that single-decoded string into sanitizeStringParameter so modelId and
systemPrompt are only decoded a single time before sanitization.

Comment on lines 199 to 203
mentions = decodeURIComponent(mentionsParam)
.split(',')
.map((mention) => mention.trim())
.map((mention) => this.sanitizeStringParameter(mention.trim()))
.filter((mention) => mention.length > 0)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Do not decode mentions twice; sanitize only.

mentionsParam is already decoded. Re-decoding risks exceptions and mis-splitting items containing encoded commas.

-      mentions = decodeURIComponent(mentionsParam)
-        .split(',')
-        .map((mention) => this.sanitizeStringParameter(mention.trim()))
+      mentions = mentionsParam
+        .split(',')
+        .map((mention) => this.sanitizeStringParameter(mention.trim()))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mentions = decodeURIComponent(mentionsParam)
.split(',')
.map((mention) => mention.trim())
.map((mention) => this.sanitizeStringParameter(mention.trim()))
.filter((mention) => mention.length > 0)
}
mentions = mentionsParam
.split(',')
.map((mention) => this.sanitizeStringParameter(mention.trim()))
.filter((mention) => mention.length > 0)
}
🤖 Prompt for AI Agents
In src/main/presenter/deeplinkPresenter/index.ts around lines 199 to 203, the
code re-decodes mentionsParam which is already decoded; remove the
decodeURIComponent call and operate directly on mentionsParam so you only
sanitize and split once. Replace the current chain with: if (mentionsParam) {
mentions = mentionsParam.split(',').map(m =>
this.sanitizeStringParameter(m.trim())).filter(m => m.length > 0) } ensuring no
double-decoding occurs.

Comment on lines +41 to +42
"sanitizingSvg": "Purification du contenu SVG ...",
"svgSanitizationFailed": "SVG Contenu Échec Vérification de sécurité"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Correct French phrasing

  • “Purification” is uncommon in UI; “Nettoyage …” reads better.
  • Fix grammar for the validation failure message.

Apply this diff:

-  "sanitizingSvg": "Purification du contenu SVG ...",
-  "svgSanitizationFailed": "SVG Contenu Échec Vérification de sécurité"
+  "sanitizingSvg": "Nettoyage du contenu SVG…",
+  "svgSanitizationFailed": "Échec de la vérification de sécurité du contenu SVG"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"sanitizingSvg": "Purification du contenu SVG ...",
"svgSanitizationFailed": "SVG Contenu Échec Vérification de sécurité"
"sanitizingSvg": "Nettoyage du contenu SVG",
"svgSanitizationFailed": "Échec de la vérification de sécurité du contenu SVG"
🤖 Prompt for AI Agents
In src/renderer/src/i18n/fr-FR/artifacts.json around lines 41 to 42, update the
French strings to use more natural phrasing: replace "Purification du contenu
SVG ..." with "Nettoyage du contenu SVG…" (use an ellipsis or three dots
consistently) and replace "SVG Contenu Échec Vérification de sécurité" with the
grammatically correct "Échec de la vérification de sécurité du contenu SVG".

Comment on lines +40 to +42
"noSvgContent": "Недоступного контента SVG",
"sanitizingSvg": "Очистить содержание SVG ...",
"svgSanitizationFailed": "Содержание SVG не удалась проверка безопасности"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix Russian grammar and wording

Current strings are ungrammatical. Suggested phrasing is idiomatic, keeps meaning, and improves UX.

Apply this diff:

-  "noSvgContent": "Недоступного контента SVG",
-  "sanitizingSvg": "Очистить содержание SVG ...",
-  "svgSanitizationFailed": "Содержание SVG не удалась проверка безопасности"
+  "noSvgContent": "Нет доступного SVG-контента",
+  "sanitizingSvg": "Очистка содержимого SVG…",
+  "svgSanitizationFailed": "Содержимое SVG не прошло проверку безопасности"
🤖 Prompt for AI Agents
In src/renderer/src/i18n/ru-RU/artifacts.json around lines 40 to 42, the Russian
strings are ungrammatical; replace the three values with corrected idiomatic
phrases: set "noSvgContent" to "Нет содержимого SVG", "sanitizingSvg" to
"Очистка содержимого SVG...", and "svgSanitizationFailed" to "Не удалось
безопасно очистить содержимое SVG" so the wording is grammatically correct and
improves UX.

Comment on lines +865 to +881
// 更新 AWS Bedrock Provider 的配置
const updateAwsBedrockProviderConfig = async (
providerId: string,
updates: Partial<AWS_BEDROCK_PROVIDER>
): Promise<void> => {
await updateProviderConfig(providerId, updates)
const currentProvider = providers.value.find((p) => p.id === providerId)!

// 只在特定条件下刷新模型列表
const needRefreshModels = ['accessKeyId', 'secretAccessKey', 'region'].some(
(key) => key in updates
)
if (needRefreshModels && currentProvider.enable) {
await refreshAllModels()
}
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Bedrock models may not refresh when credentials change (nested fields not detected).

updates will typically carry credentials under updates.credential; your needRefreshModels check looks for top-level keys and won’t trigger on nested credential changes.

Apply this diff to detect nested credential updates too:

-  // 只在特定条件下刷新模型列表
-  const needRefreshModels = ['accessKeyId', 'secretAccessKey', 'region'].some(
-    (key) => key in updates
-  )
+  // 只在特定条件下刷新模型列表(检测嵌套的 credential 变更)
+  const needRefreshModels =
+    'credential' in updates ||
+    ['accessKeyId', 'secretAccessKey', 'region'].some(
+      (key) => key in (updates.credential ?? {})
+    )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// 更新 AWS Bedrock Provider 的配置
const updateAwsBedrockProviderConfig = async (
providerId: string,
updates: Partial<AWS_BEDROCK_PROVIDER>
): Promise<void> => {
await updateProviderConfig(providerId, updates)
const currentProvider = providers.value.find((p) => p.id === providerId)!
// 只在特定条件下刷新模型列表
const needRefreshModels = ['accessKeyId', 'secretAccessKey', 'region'].some(
(key) => key in updates
)
if (needRefreshModels && currentProvider.enable) {
await refreshAllModels()
}
}
// 更新 AWS Bedrock Provider 的配置
const updateAwsBedrockProviderConfig = async (
providerId: string,
updates: Partial<AWS_BEDROCK_PROVIDER>
): Promise<void> => {
await updateProviderConfig(providerId, updates)
const currentProvider = providers.value.find((p) => p.id === providerId)!
// 只在特定条件下刷新模型列表(检测嵌套的 credential 变更)
const needRefreshModels =
'credential' in updates ||
['accessKeyId', 'secretAccessKey', 'region'].some(
(key) => key in (updates.credential ?? {})
)
if (needRefreshModels && currentProvider.enable) {
await refreshAllModels()
}
}
🤖 Prompt for AI Agents
In src/renderer/src/stores/settings.ts around lines 865 to 881, the
needRefreshModels boolean only checks for top-level keys and therefore misses
credential changes nested under updates.credential; update the condition to also
look inside updates.credential (e.g., check (updates.credential &&
['accessKeyId','secretAccessKey','region'].some(k => k in updates.credential)))
so that nested credential updates trigger refreshAllModels when the provider is
enabled.

Comment on lines +1557 to +1565
// AWS Bedrock
const setAwsBedrockCredential = async (credential: AwsBedrockCredential) => {
await configP.setSetting('awsBedrockCredential', JSON.stringify({ credential }))
}

const getAwsBedrockCredential = async (): Promise<AwsBedrockCredential | undefined> => {
return await configP.getSetting<AwsBedrockCredential | undefined>('awsBedrockCredential')
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Credential persistence bug: stored as JSON string but read as object.

setAwsBedrockCredential serializes to a string, but getAwsBedrockCredential returns it as AwsBedrockCredential. This will break consumers and mixes shapes ({credential} wrapper vs plain object).

Use a plain object and a stable shape:

-const setAwsBedrockCredential = async (credential: AwsBedrockCredential) => {
-  await configP.setSetting('awsBedrockCredential', JSON.stringify({ credential }))
-}
+const setAwsBedrockCredential = async (credential: AwsBedrockCredential) => {
+  await configP.setSetting('awsBedrockCredential', credential)
+}

-const getAwsBedrockCredential = async (): Promise<AwsBedrockCredential | undefined> => {
-  return await configP.getSetting<AwsBedrockCredential | undefined>('awsBedrockCredential')
-}
+const getAwsBedrockCredential = async (): Promise<AwsBedrockCredential | undefined> => {
+  return await configP.getSetting<AwsBedrockCredential | undefined>('awsBedrockCredential')
+}

If you intentionally need the { credential } wrapper, then also adjust the getter to parse and unwrap; otherwise the above is simpler and consistent.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// AWS Bedrock
const setAwsBedrockCredential = async (credential: AwsBedrockCredential) => {
await configP.setSetting('awsBedrockCredential', JSON.stringify({ credential }))
}
const getAwsBedrockCredential = async (): Promise<AwsBedrockCredential | undefined> => {
return await configP.getSetting<AwsBedrockCredential | undefined>('awsBedrockCredential')
}
// AWS Bedrock
const setAwsBedrockCredential = async (credential: AwsBedrockCredential) => {
await configP.setSetting('awsBedrockCredential', credential)
}
const getAwsBedrockCredential = async (): Promise<AwsBedrockCredential | undefined> => {
return await configP.getSetting<AwsBedrockCredential | undefined>('awsBedrockCredential')
}
🤖 Prompt for AI Agents
In src/renderer/src/stores/settings.ts around lines 1557 to 1565, the setter
persists a JSON string with a { credential } wrapper while the getter expects a
plain AwsBedrockCredential object; change the setter to store the credential as
a plain object (call configP.setSetting('awsBedrockCredential', credential)
without JSON.stringify and without the { credential } wrapper) so the stored
shape matches what getAwsBedrockCredential returns, or alternatively if you want
to keep the wrapper, update the getter to parse/unwrap the JSON string and
return the inner credential—pick one consistent shape and make both setter and
getter follow it.

Comment on lines +579 to 582
thinkingBudget?: number,
reasoningEffort?: 'minimal' | 'low' | 'medium' | 'high',
verbosity?: 'low' | 'medium' | 'high'
): AsyncGenerator<LLMAgentEvent, void, unknown>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

startStreamCompletion signature extension: request downstream updates.

Optional trailing params are backward-compatible, but ensure all implementations and call sites propagate thinkingBudget, reasoningEffort, and verbosity.

Run this to spot potential mismatches or ignored params:


🏁 Script executed:

#!/bin/bash
# Check ILlmProviderPresenter implementation and invocations for updated params
rg -nP --type=ts -C2 '\bstartStreamCompletion\s*\('
rg -nP --type=ts -C3 'function\s+startStreamCompletion\(|startStreamCompletion\s*=\s*\('

Length of output: 7850


Propagate new thinkingBudget, reasoningEffort, and verbosity params in all startStreamCompletion call sites

The signature was extended with three optional settings—ensure every invocation forwards them from the relevant context/settings. Key locations needing updates:

  • Renderer store

    • src/renderer/src/stores/chat.ts (lines ~251 & ~271):
      threadP.startStreamCompletion(...) ⇒ add (…, { thinkingBudget, reasoningEffort, verbosity }) pulled from the thread or global settings.
  • ThreadPresenter

    • src/main/presenter/threadPresenter/index.ts at each call to this.llmProviderPresenter.startStreamCompletion( (around lines 1478–1482, 1656–1660, 2658–2662, 2719–2723, 3730–3734):
      pass the current conversation’s settings object’s thinkingBudget, reasoningEffort, and verbosity.
  • LLMProviderPresenter tests

    • test/main/presenter/llmProviderPresenter.test.ts (multiple blocks at lines ~170–174, ~216–220, ~256–260, ~362–366, ~410–414):
      update startStreamCompletion('mock-openai-api', messages) calls to include default or test-specific values for the three new params.
🤖 Prompt for AI Agents
In src/shared/presenter.d.ts around lines 579–582 the startStreamCompletion
signature was extended with thinkingBudget, reasoningEffort, and verbosity;
update every call site to forward these three options: in
src/renderer/src/stores/chat.ts (around lines ~251 and ~271) pass the values
from the thread or global settings into threadP.startStreamCompletion(..., {
thinkingBudget, reasoningEffort, verbosity }); in
src/main/presenter/threadPresenter/index.ts at each call to
this.llmProviderPresenter.startStreamCompletion (around lines 1478–1482,
1656–1660, 2658–2662, 2719–2723, 3730–3734) pass the current
conversation.settings.{thinkingBudget, reasoningEffort, verbosity} as the
options argument; and in test/main/presenter/llmProviderPresenter.test.ts
(around lines ~170–174, ~216–220, ~256–260, ~362–366, ~410–414) update
startStreamCompletion('mock-openai-api', messages) calls to include default or
test-specific values for these three params so tests compile and reflect the new
signature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants