Skip to content

perf: 缓存 IDEA 环境检测与 i18n 参数正则 (#33 子项 3、4)#40

Open
appergb wants to merge 24 commits into
OrionStarAI:opensourcefrom
appergb:perf/issue-33-render-hotpath
Open

perf: 缓存 IDEA 环境检测与 i18n 参数正则 (#33 子项 3、4)#40
appergb wants to merge 24 commits into
OrionStarAI:opensourcefrom
appergb:perf/issue-33-render-hotpath

Conversation

@appergb

@appergb appergb commented May 31, 2026

Copy link
Copy Markdown

关联 issue

Partially addresses #33(本 PR 处理频率最高、最安全的两项;其余拆分为后续 PR,见下文)

本 PR 改动

子项 ③ —— IDEA 环境检测每次按键都重算

  • App.tsxuseInput 处理器内每次按键都调用 detectIDEAEnvironment()i18n.tsgetCancelKeyHint 每次也重算同样的环境判断。
  • 环境在进程生命周期内不变 → 改为模块加载时算一次的常量(IS_IDEA_ENVIRONMENT / IS_IDEA_TERMINAL)。

子项 ④ —— t() / tp() 每个参数都 new RegExp

  • simpleI18n.ts(core)与 i18n.ts(cli)在每次调用、每个参数上都 new RegExp('{param}', 'g'),且发生在每次渲染路径上。
  • 改为模块级 Map<string, RegExp> 缓存按参数名编译的正则。全局正则的 lastIndex 会被 String.prototype.replace 重置,复用安全(已用测试覆盖重复调用稳定性)。

测试

  • 新增 packages/core/src/utils/simpleI18n.test.ts(3 例):参数替换正确、重复调用结果一致(验证缓存正则复用安全)、无参数时原样返回。npx vitest run3 passed
  • npm run typecheck(core + cli)→ 均通过。
  • 既有 App.test.tsx 的失败为改动前既已存在(base 上同样 13 failed),与本 PR 无关。
  • 新增行均符合 Prettier;eslint 错误数与改动前一致(未引入新问题)。

其余子项(拆分为后续 PR,附原因)

  • ① 工具 schema 声明缓存getFunctionDeclarations 结果同时依赖工具集合和当前模型shouldUseTolerantMode(getModel()) 驱动 sanitizeParameters,且模型可中途切换),并且 this.tools 有 6 处增删点;缓存失效若遗漏会导致「新发现的 MCP 工具未下发给模型」这类隐蔽正确性问题,需单独 PR 充分测试所有变更路径。
  • ② plan mode 100ms 轮询 → 事件:需要给 Config.setPlanModeActive 增加事件机制并在 App 订阅,跨 core/cli,且有 App.test 回归风险。
  • ⑤ 压缩边界 JSON.stringify 估长:改动会影响压缩截断点(findIndexAfterFraction 有针对性断言测试),且该路径仅在压缩时触发(非每渲染/每按键),收益低风险偏高。
  • ⑥ 流式 pending 列表用下标作 key:需要每个 pending 项有稳定唯一 id;当前为 id: 0 占位,且 pending 列表通常极小,单独评估更稳妥。

jiangmuran and others added 24 commits February 11, 2026 14:28
- 新增 MermaidBlock 组件,支持流式感知的异步渲染
  - 流式阶段防抖 300ms,代码块闭合后立即渲染
  - 渲染失败时回退到上次成功的 SVG,避免图表消失
  - 通过 MutationObserver 监听 VSCode 主题切换并重新渲染
- 将 markdownComponents 重构为 MarkdownRenderer(React.memo + useMemo)
  稳定流式输出期间的组件引用,避免每次 token 更新导致
  MermaidBlock 卸载重建和 SVG 闪烁
- 修复自动滚动逻辑,通过 ResizeObserver 捕获异步内容高度变化,
  并用 scrollHeight 守卫排除内容缩小导致的误判
- webview 新增 mermaid@11.13.0 依赖
- 新增 .mermaid-block 和 .mermaid-error-badge 样式

Signed-off-by: huangdengdui <huangdengdui@cmcm.com>
Signed-off-by: huangdengdui <huangdengdui@cmcm.com>
统一要求 AI 在响应中使用相对路径+行号格式引用文件
(如 src/routes/index.ts:42),便于 VSCode 等 IDE
插件场景将文件引用渲染为可点击的跳转链接。

涉及:cursor、claude-code、gemini3、vscode、default 风格

Signed-off-by: huangdengdui <huangdengdui@cmcm.com>
工具通过提示词告知大模型 new_string 是"精确字面文本",没有特殊符号限制。

但实现使用 JS 的 String.prototype.replaceAll(string, string),
该方法会将替换字符串中的 $'、$`、$& 等特殊模式展开:
例如 $' 展开为匹配位置之后的所有内容,导致文件内容静默损坏,
工具却仍返回"Successfully modified",大模型无法感知错误。
这与给大模型的使用描述提示词不符。

将替换参数改为函数形式 replaceAll(oldString, () => newString),
函数返回值不触发任何特殊模式解析,使实现与使用描述保持一致。

Signed-off-by: huangdengdui <huangdengdui@cmcm.com>
    根本原因:
    config.initialize() 通过 setImmediate 异步触发 discoverMcpToolsAsync(),
    工具发现完成后结果存入全局缓存 globalDiscoveredTools。但 waitForMcpDiscovery()
    仅等待发现状态变为 COMPLETED,从未将缓存中的工具同步到当前 toolRegistry
    实例,导致非交互模式下 toolRegistry.getFunctionDeclarations() 始终只返回
    内置工具,AI 无法感知和调用任何 MCP 工具。

    修复方案:
    - waitForMcpDiscovery 新增 config 参数
    - 三种状态(COMPLETED/NOT_STARTED/IN_PROGRESS)均在等待后调用
      toolRegistry.discoverMcpTools(),触发从全局缓存的同步
    - 新增 waitForMCPDiscoveryComplete 导入

Signed-off-by: huangdengdui <huangdengdui@cmcm.com>
Signed-off-by: huangdengdui <huangdengdui@cmcm.com>
…I#33)

Addresses the two highest-frequency hot-path items from OrionStarAI#33:

- IDEA/JetBrains terminal detection ran on every keystroke (App.tsx
  useInput handler) and on every cancel-key hint render (i18n.ts). The
  environment is constant for the process lifetime, so compute it once
  at module load.
- t()/tp() rebuilt a global RegExp for every parameter on every call,
  on per-render paths. Cache compiled `{param}` regexes by name in a
  module-level Map (a global regex has its lastIndex reset by
  String.prototype.replace, so reuse is safe).

Adds unit tests for core simpleI18n parameter substitution, including
that repeated calls with the cached regex stay correct.

The remaining OrionStarAI#33 items (tool-schema declaration cache, plan-mode
polling -> event, compression length estimation, streaming list key)
are deferred to focused follow-up PRs: each needs cross-cutting changes
(tool-mutation invalidation that is model-dependent, Config eventing,
compression cut-off behavior, a guaranteed-stable list key) with higher
regression risk than these two safe memoizations.
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.

3 participants