Skip to content

feat: support chat agent rules and context management#4578

Merged
erha19 merged 26 commits intomainfrom
feat/support-chat-agent-rules
Jun 4, 2025
Merged

feat: support chat agent rules and context management#4578
erha19 merged 26 commits intomainfrom
feat/support-chat-agent-rules

Conversation

@erha19
Copy link
Copy Markdown
Member

@erha19 erha19 commented Jun 3, 2025

Types

  • 🎉 New Features
  • 💄 Style Changes

Background or solution

  1. 支持兼容 Cursor 的 Agent Rules 能力
  2. 支持在输入框顶部同步当前上下文内容
image

Changelog

support chat agent rules and context management

Summary by CodeRabbit

  • 新功能

    • 全面引入 AI 规则体系,支持全局规则和项目规则,为 AI Agent 提供系统级指导。
    • 新增规则管理界面,支持查看、编辑、创建和应用规则。
    • 聊天输入与上下文支持规则类型引用,消息中可插入规则标签。
    • 聊天上下文与提示增强,支持规则内容序列化并影响 AI 行为。
    • 规则配置支持多语言(含中英文),并集成全新规则相关图标。
    • 聊天组件新增对规则模式的支持,提升上下文管理和交互体验。
    • 提供规则相关命令和资源管理,支持规则文件的打开与编辑。
  • 样式优化

    • 聊天、附件、Mention 标签等多处样式优化,提升 RTL(从右到左)文本显示与溢出处理。
    • 新增规则界面样式,优化规则列表和编辑区的视觉体验。
  • 文档与本地化

    • 新增 MDC 解析器说明文档,详述规则文件格式与解析逻辑。
    • 补充中英文规则相关界面和提示的本地化内容,完善用户引导。
  • 其他优化

    • 移除未使用的依赖和无关代码,提升性能与可维护性。
    • 优化滚动条渲染逻辑,改善编辑器横向滚动体验。
    • 优化聊天代理服务,简化系统提示及异步注册逻辑。

@opensumi opensumi Bot added the 🎨 feature feature required label Jun 3, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 3, 2025

## Walkthrough

本次更新为 AI Native 模块引入了“规则(Rules)”体系,支持全局与项目级规则的管理、序列化与编辑。涉及新增 RulesService、UI 组件、依赖注入、MDC 解析器、上下文序列化与 Prompt 构建逻辑。并扩展了提及输入(MentionInput)、消息处理、样式、国际化、设置项等,全面提升 AI 聊天与上下文的可控性和可扩展性。

## Changes

| 文件/分组                                               | 变更摘要 |
|--------------------------------------------------------|----------|
| `src/browser/rules/rules.service.ts`, `rules.view.tsx`, `rules.contribution.ts`, `rules.module.less` | 新增 RulesService、RulesView 组件、贡献类与样式,实现规则的管理、编辑与 UI 展示 |
| `src/browser/index.ts`                                 | 注入 RulesServiceToken,注册 RulesContribution,实现依赖注入与贡献 |
| `src/common/mdc-parser.ts`, `MDC_PARSER_README.md`     | 新增 MDC(YAML frontmatter + Markdown)解析与序列化工具及文档 |
| `src/common/types.ts`                                  | 新增 ProjectRule 接口定义规则结构 |
| `src/common/llm-context.ts`                            | LLMContextService 增加规则相关方法与事件,序列化结构扩展规则内容 |
| `src/browser/context/llm-context.service.ts`           | 支持规则的上下文管理、序列化、通知与清理,集成 RulesService |
| `src/common/prompts/context-prompt-provider.ts`        | Prompt 构建逻辑扩展支持规则上下文,附加当前行内容、规则块等 |
| `src/browser/components/mention-input/types.ts`, `mention-input.tsx`, `ChatMentionInput.tsx` | 支持规则类型的提及(MentionType.RULE),UI 及上下文处理同步支持规则 |
| `src/browser/chat/chat.view.tsx`                       | 聊天消息处理支持 `{{@rule:...}}` 占位符,消息内容预处理逻辑调整 |
| `src/browser/chat/chat-proxy.service.ts`               | 移除对 AppConfig、ChatServiceToken、OS 名称的依赖,简化 Agent 注册 |
| `src/browser/preferences/schema.ts`, `core-common/src/settings/ai-native.ts` | 新增全局规则设置项及枚举 |
| `src/common/index.ts`                                  | 导出 mdc-parser 和 tool-invocation-registry |
| `src/core-common/src/types/ai-native/index.ts`         | 新增 RulesServiceToken 依赖注入符号 |
| `src/i18n/src/common/en-US.lang.ts`, `zh-CN.lang.ts`   | 新增规则相关的国际化字符串 |
| `components/src/icon/iconfont/iconMap.ts`, `iconfont.css`, `iconfont.html` | 新增 rules/settings 图标及样式 |
| `src/browser/components/ChatToolRender.module.less`, `components.module.less`, `mention-input/mention-input.module.less`, `debug-call-stack.module.less` | 优化文本方向、溢出、省略号等样式,提升多语言与长文本兼容性 |
| `src/browser/contrib/intelligent-completions/diff-computer.ts` | 局部变量声明由 let 改为 const |
| 其余若干文件(如移除未用 import)                      | 清理无用依赖,优化引入 |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant ChatView
    participant MentionInput
    participant LLMContextService
    participant RulesService
    participant RulesView

    User->>ChatView: 输入消息,选择@规则
    ChatView->>MentionInput: 展示规则、文件、文件夹等提及项
    MentionInput->>RulesService: 获取项目规则列表
    MentionInput->>LLMContextService: 添加规则到上下文
    ChatView->>LLMContextService: 获取序列化上下文(含规则)
    LLMContextService->>RulesService: 获取全局/项目规则内容
    ChatView->>ChatProxyService: 发送消息及上下文
    User->>RulesView: 打开规则管理界面
    RulesView->>RulesService: 读取/更新规则内容
    RulesService-->>RulesView: 规则变更通知

Possibly related PRs

Suggested reviewers

  • Aaaaash
  • Ricbet

<!-- walkthrough_end -->


---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 62e5b89e573a7311580408a865aa8b5e5c5c5b7f and c35c6eff635d7d8e4b8c4d795c90791ddf036970.

</details>

<details>
<summary>⛔ Files ignored due to path filters (1)</summary>

* `yarn.lock` is excluded by `!**/yarn.lock`, `!**/*.lock`

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `packages/ai-native/package.json` (1 hunks)

</details>

<details>
<summary>✅ Files skipped from review due to trivial changes (1)</summary>

* packages/ai-native/package.json

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (9)</summary>

* GitHub Check: 🚀🚀🚀 Next Version for pull request
* GitHub Check: unittest (ubuntu-latest, 18.x, node)
* GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
* GitHub Check: build (ubuntu-latest, 20.x)
* GitHub Check: unittest (macos-latest, 18.x, jsdom)
* GitHub Check: unittest (macos-latest, 18.x, node)
* GitHub Check: build-windows
* GitHub Check: build (macos-latest, 20.x)
* GitHub Check: ubuntu-latest, Node.js 20.x

</details>

</details>
<!-- internal state start -->


<!-- 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= -->

<!-- internal state end -->
<!-- tips_start -->

---

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.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=opensumi/core&utm_content=4578):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `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. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- 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 src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### 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](https://docs.coderabbit.ai/guides/configure-coderabbit) 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`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

Copy link
Copy Markdown
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: 16

🧹 Nitpick comments (20)
packages/ai-native/src/common/types.ts (1)

138-145: 新增 ProjectRule 接口,应补充字段文档注释
建议为 ProjectRule 接口及其各属性添加 JSDoc 注释,说明各字段的含义与使用场景,提升可读性与可维护性。例如:

/**
 * 项目级规则配置
 */
export interface ProjectRule {
  /** 规则所属文件路径 */
  path: string;
  /** 规则正文内容 */
  content: string;
  /** 规则描述,用于在 UI 中展示 */
  description?: string;
  /** 适用路径匹配模式,支持单个或多个 glob 表达式 */
  globs?: string | string[];
  /** 是否始终应用 */
  alwaysApply?: boolean;
}
packages/ai-native/src/browser/components/mention-input/mention-input.module.less (1)

32-35: 精简 .mention_tag 边距设置
目前使用了两条 margin 声明,可合并为:

.mention_tag {
  height: 20px;
  margin: -3px 2px 0;
  vertical-align: middle;
}

以减少冗余。

packages/ai-native/src/browser/rules/rules.module.less (1)

17-17: 建议使用更具语义化的字体堆栈。

当前使用 var(--monaco-monospace-font) 作为等宽字体,建议添加回退字体以确保在变量未定义时的兼容性。

-    font-family: var(--monaco-monospace-font);
+    font-family: var(--monaco-monospace-font, 'Consolas', 'Monaco', 'Courier New', monospace);
packages/ai-native/src/browser/rules/rules.view.tsx (2)

42-42: 改进规则警告逻辑的表达性。

当前的警告逻辑比较复杂,建议提取为更具表达性的函数名或添加注释说明。

-const hasWarning = (rule: ProjectRule) => !rule.description && !rule.alwaysApply && !rule.globs;
+const hasWarning = (rule: ProjectRule) => {
+  // 当规则没有描述、不自动应用且没有匹配模式时显示警告
+  return !rule.description && !rule.alwaysApply && !rule.globs;
+};

83-83: 移除内联样式,使用 CSS 类。

内联样式 style={{ resize: 'none' }} 应该移到 CSS 文件中以保持样式的一致性。

在 CSS 文件中添加:

+  .user_rules_textarea {
+    resize: none;
+  }

然后在 JSX 中:

-          style={{ resize: 'none' }}
+          className={styles.user_rules_textarea}
packages/ai-native/src/common/llm-context.ts (1)

69-69: 改进类型注释的一致性。

新增的 selection 属性应该添加注释说明其用途,保持与其他属性的文档一致性。

   language: string;
+  /** 选中的行范围 */
   selection?: [number, number];
packages/i18n/src/common/zh-CN.lang.ts (1)

1307-1307: 验证全局规则描述的翻译质量。

描述文本"这些规则将发送到所有聊天、Agent 中"可以更精确地表达功能。

建议优化为更清晰的表述:

-    'preference.ai.native.globalRules.description': '这些规则将发送到所有聊天、Agent 中。',
+    'preference.ai.native.globalRules.description': '这些规则将应用于所有 AI 聊天和 Agent 对话中,作为系统级指导原则。',
packages/ai-native/src/browser/chat/chat-proxy.service.ts (1)

127-128: 应用静态分析建议:使用可选链式调用

根据静态分析工具的建议,这里可以使用可选链式调用来简化代码。

-              if (commandHandler && commandHandler.providerPrompt) {
+              if (commandHandler?.providerPrompt) {
🧰 Tools
🪛 Biome (1.9.4)

[error] 127-128: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/ai-native/src/browser/components/ChatMentionInput.tsx (1)

123-171: 建议将中文注释改为英文

expandFolderPaths 辅助函数实现良好,能够正确展开文件夹路径为层级结构。但第123行的中文注释应改为英文以保持代码一致性。

-  // 拆分目录路径为多个层级的辅助函数
+  // Helper function to expand folder paths into hierarchical levels
packages/ai-native/src/browser/rules/rules.service.ts (3)

63-114: 初始化逻辑完善,建议小幅改进

项目规则初始化实现良好,支持多个配置目录并设置了文件监听。建议:

  1. 将中文注释改为英文
  2. 使用可选链操作符简化代码
-    // 如果存在 .sumi, 默认从 .sumi 中获取
+    // If .sumi exists, get rules from .sumi by default
-    if (dir && dir.isDirectory) {
-      const files = dir.children?.filter((file) => !file.isDirectory && file.uri.endsWith('.mdc'));
+    if (dir?.isDirectory) {
+      const files = dir.children?.filter((file) => !file.isDirectory && file.uri.endsWith('.mdc'));
🧰 Tools
🪛 Biome (1.9.4)

[error] 91-92: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


120-168: 文件创建逻辑完善,建议改进正则表达式可读性

新规则创建功能实现良好,包含了完整的验证逻辑。建议将控制字符的正则表达式改为更可读的形式:

-        const invalidCharsRegex = /[<>:"/\\|?*\x00-\x1F]/;
+        // Regex for invalid filename characters including control characters (ASCII 0-31)
+        const invalidCharsRegex = /[<>:"/\\|?*]|[\x00-\x1F]/;

这样可以更清楚地表明正则表达式的意图,避免静态分析工具的误报。

🧰 Tools
🪛 Biome (1.9.4)

[error] 127-127: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)


[error] 127-127: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)


1-189: 考虑添加缓存机制优化性能

RulesService 整体实现良好。建议考虑为规则文件添加缓存机制,避免频繁的文件系统访问,特别是在规则文件较多的情况下。

🧰 Tools
🪛 Biome (1.9.4)

[error] 91-92: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 127-127: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)


[error] 127-127: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)

packages/ai-native/src/browser/context/llm-context.service.ts (3)

101-117: 考虑使用 URI 的标准化比较方式

当前使用 uri.toString() 进行规则路径比较可能会因为 URI 格式差异导致问题(例如末尾斜杠、编码差异等)。建议使用更可靠的比较方式。

-    if (this.attachedRules.some((rule) => rule.path === uri.toString())) {
+    const uriString = uri.toString();
+    if (this.attachedRules.some((rule) => URI.parse(rule.path).toString() === uriString)) {
       return;
     }

-    const rule = this.rulesService.projectRules.find((rule) => rule.path === uri.toString());
+    const rule = this.rulesService.projectRules.find((rule) => URI.parse(rule.path).toString() === uriString);

286-319: 建议改进错误处理

当前的错误处理直接返回空字符串,这可能会隐藏潜在的问题。建议至少记录错误信息以便调试。

     } catch {
-      return '';
+    } catch (error) {
+      console.warn(`Failed to get folder structure for ${folder}:`, error);
+      return `[error] Unable to read folder structure`;
     }

395-455: 规则附加逻辑实现完善

该方法很好地处理了多种规则附加场景:基于文件 glob 匹配、Agent 请求的规则和始终应用的规则。glob 模式规范化逻辑确保了匹配的一致性。

建议后续考虑将复杂的规则匹配逻辑提取到单独的方法中以提高可维护性。

packages/ai-native/src/common/MDC_PARSER_README.md (1)

9-16: 代码块缺少语言标识符

Markdown 代码块应该指定语言以获得正确的语法高亮。

-```
+```yaml
---
description:
globs:
alwaysApply: false
---
icejs is a react-like framework
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

9-9: Fenced code blocks should have a language specified
null

(MD040, fenced-code-language)

packages/ai-native/src/common/mdc-parser.ts (1)

32-69: YAML 值解析实现较为基础

当前实现仅支持简单的 YAML 值类型,不支持嵌套数组、对象等复杂结构。对于当前的使用场景可能足够,但建议考虑使用成熟的 YAML 解析库(如 js-yaml)以获得更完整的 YAML 支持。

packages/ai-native/src/common/prompts/context-prompt-provider.ts (3)

26-29: 去重逻辑实现合理

避免当前文件与附件文件重复是正确的做法。不过需要注意,如果附件中的文件没有行选择范围,而当前文件有行号信息,可能会丢失当前行的上下文。

考虑在比较时也检查行选择信息,以保留更精确的上下文。


71-91: 方法签名更新合理,建议提取参数类型

新增的规则参数支持了 PR 的核心功能。不过方法参数较多,建议提取为独立的类型定义以提高可维护性。

interface PromptTemplateParams {
  attachedFiles: AttachFileContext[];
  attachedFolders: string[];
  currentFile: {
    path: string;
    languageId: string;
    content: string;
    currentLine?: number;
    lineContent?: string;
  } | null;
  attachedRules: string[];
  globalRules: string[];
  userMessage: string;
}

129-135: 文件内容格式支持行选择范围

添加行范围信息有助于 AI 更精确地理解上下文。实现正确。

第 131 行的可选链操作符是多余的,因为已经检查了 file.selection 的存在性:

-\`\`\`${file.path}${file.selection ? `, lines: ${file.selection?.[0]}-${file.selection?.[1]}` : ''}
+\`\`\`${file.path}${file.selection ? `, lines: ${file.selection[0]}-${file.selection[1]}` : ''}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e68714e and b16efbb.

⛔ Files ignored due to path filters (5)
  • packages/components/src/icon/iconfont/iconfont.eot is excluded by !**/*.eot
  • packages/components/src/icon/iconfont/iconfont.svg is excluded by !**/*.svg
  • packages/components/src/icon/iconfont/iconfont.ttf is excluded by !**/*.ttf
  • packages/components/src/icon/iconfont/iconfont.woff is excluded by !**/*.woff
  • packages/components/src/icon/iconfont/iconfont.woff2 is excluded by !**/*.woff2
📒 Files selected for processing (42)
  • packages/ai-native/src/browser/chat/chat-proxy.service.ts (2 hunks)
  • packages/ai-native/src/browser/chat/chat.view.tsx (3 hunks)
  • packages/ai-native/src/browser/components/ChatMentionInput.tsx (8 hunks)
  • packages/ai-native/src/browser/components/ChatToolRender.module.less (1 hunks)
  • packages/ai-native/src/browser/components/components.module.less (1 hunks)
  • packages/ai-native/src/browser/components/mention-input/mention-input.module.less (2 hunks)
  • packages/ai-native/src/browser/components/mention-input/mention-input.tsx (6 hunks)
  • packages/ai-native/src/browser/components/mention-input/types.ts (1 hunks)
  • packages/ai-native/src/browser/context/llm-context.service.ts (11 hunks)
  • packages/ai-native/src/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.ts (1 hunks)
  • packages/ai-native/src/browser/contrib/intelligent-completions/diff-computer.ts (1 hunks)
  • packages/ai-native/src/browser/contrib/terminal/terminal.feature.registry.ts (1 hunks)
  • packages/ai-native/src/browser/index.ts (4 hunks)
  • packages/ai-native/src/browser/mcp/base-apply.service.ts (0 hunks)
  • packages/ai-native/src/browser/mcp/tools/getDiagnosticsByPath.ts (1 hunks)
  • packages/ai-native/src/browser/mcp/tools/getOpenEditorFileDiagnostics.ts (1 hunks)
  • packages/ai-native/src/browser/mcp/tools/handlers/ListDir.ts (1 hunks)
  • packages/ai-native/src/browser/mcp/tools/runTerminalCmd.ts (1 hunks)
  • packages/ai-native/src/browser/preferences/schema.ts (1 hunks)
  • packages/ai-native/src/browser/rules/rules.contribution.ts (1 hunks)
  • packages/ai-native/src/browser/rules/rules.module.less (1 hunks)
  • packages/ai-native/src/browser/rules/rules.service.ts (1 hunks)
  • packages/ai-native/src/browser/rules/rules.view.tsx (1 hunks)
  • packages/ai-native/src/browser/widget/inline-stream-diff/live-preview.component.tsx (0 hunks)
  • packages/ai-native/src/common/MDC_PARSER_README.md (1 hunks)
  • packages/ai-native/src/common/index.ts (1 hunks)
  • packages/ai-native/src/common/llm-context.ts (4 hunks)
  • packages/ai-native/src/common/mdc-parser.ts (1 hunks)
  • packages/ai-native/src/common/prompts/context-prompt-provider.ts (6 hunks)
  • packages/ai-native/src/common/types.ts (1 hunks)
  • packages/ai-native/src/node/base-language-model.ts (0 hunks)
  • packages/components/src/icon/iconfont/iconMap.ts (2 hunks)
  • packages/components/src/icon/iconfont/iconfont.css (2 hunks)
  • packages/components/src/icon/iconfont/iconfont.html (2 hunks)
  • packages/components/src/scrollbars/index.tsx (1 hunks)
  • packages/core-browser/src/style/icon/ide-iconfont.ts (1 hunks)
  • packages/core-common/src/settings/ai-native.ts (1 hunks)
  • packages/core-common/src/types/ai-native/index.ts (1 hunks)
  • packages/debug/src/browser/view/frames/debug-call-stack.module.less (1 hunks)
  • packages/editor/src/browser/editor.view.tsx (1 hunks)
  • packages/i18n/src/common/en-US.lang.ts (2 hunks)
  • packages/i18n/src/common/zh-CN.lang.ts (2 hunks)
💤 Files with no reviewable changes (3)
  • packages/ai-native/src/node/base-language-model.ts
  • packages/ai-native/src/browser/mcp/base-apply.service.ts
  • packages/ai-native/src/browser/widget/inline-stream-diff/live-preview.component.tsx
🧰 Additional context used
🧬 Code Graph Analysis (7)
packages/ai-native/src/browser/index.ts (1)
packages/core-common/src/types/ai-native/index.ts (1)
  • RulesServiceToken (305-305)
packages/editor/src/browser/editor.view.tsx (1)
packages/components/src/scrollbars/index.tsx (1)
  • Scrollbars (41-200)
packages/ai-native/src/browser/chat/chat-proxy.service.ts (2)
packages/ai-native/src/common/index.ts (4)
  • IChatAgentRequest (213-220)
  • IChatAgentResult (226-228)
  • IChatAgentCommand (230-235)
  • IChatAgentWelcomeMessage (286-289)
packages/utils/src/stream.ts (1)
  • listenReadable (24-37)
packages/ai-native/src/common/llm-context.ts (1)
packages/ai-native/src/common/types.ts (1)
  • ProjectRule (139-145)
packages/ai-native/src/browser/rules/rules.service.ts (2)
packages/ai-native/src/common/types.ts (1)
  • ProjectRule (139-145)
packages/ai-native/src/common/mdc-parser.ts (4)
  • IMDCParseResult (14-17)
  • parseMDC (172-200)
  • IMDCContent (22-25)
  • serializeMDC (207-224)
packages/ai-native/src/browser/components/mention-input/mention-input.tsx (1)
packages/ai-native/src/common/types.ts (1)
  • ProjectRule (139-145)
packages/ai-native/src/browser/context/llm-context.service.ts (6)
packages/core-common/src/types/ai-native/index.ts (1)
  • RulesServiceToken (305-305)
packages/ai-native/src/common/types.ts (1)
  • ProjectRule (139-145)
packages/ai-native/src/common/llm-context.ts (1)
  • FileContext (57-60)
packages/markers/src/common/match.ts (1)
  • relativePath (45-68)
packages/ai-native/src/browser/rules/rules.service.ts (1)
  • globalRules (52-57)
packages/utils/src/types.ts (1)
  • isString (38-44)
🪛 Biome (1.9.4)
packages/ai-native/src/browser/chat/chat-proxy.service.ts

[error] 127-128: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/ai-native/src/browser/rules/rules.service.ts

[error] 91-92: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 127-127: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)


[error] 127-127: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)

🪛 markdownlint-cli2 (0.17.2)
packages/ai-native/src/common/MDC_PARSER_README.md

9-9: Fenced code blocks should have a language specified
null

(MD040, fenced-code-language)

🪛 GitHub Check: ubuntu-latest, Node.js 20.x
packages/ai-native/src/browser/components/mention-input/mention-input.tsx

[failure] 4-4:
Cannot find module '@opensumi/ide-ai-native/lib/common/types' or its corresponding type declarations.

🪛 GitHub Check: build (ubuntu-latest, 20.x)
packages/ai-native/src/browser/components/mention-input/mention-input.tsx

[failure] 4-4:
Cannot find module '@opensumi/ide-ai-native/lib/common/types' or its corresponding type declarations.

🪛 GitHub Check: unittest (ubuntu-latest, 18.x, node)
packages/ai-native/src/browser/components/mention-input/mention-input.tsx

[failure] 4-4:
Cannot find module '@opensumi/ide-ai-native/lib/common/types' or its corresponding type declarations.

🪛 GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
packages/ai-native/src/browser/components/mention-input/mention-input.tsx

[failure] 4-4:
Cannot find module '@opensumi/ide-ai-native/lib/common/types' or its corresponding type declarations.

🪛 GitHub Actions: CI
packages/ai-native/src/browser/components/mention-input/mention-input.tsx

[error] 4-4: TypeScript error TS2307: Cannot find module '@opensumi/ide-ai-native/lib/common/types' or its corresponding type declarations.

🪛 GitHub Actions: E2E Test
packages/ai-native/src/browser/components/mention-input/mention-input.tsx

[error] 4-4: TypeScript error TS2307: Cannot find module '@opensumi/ide-ai-native/lib/common/types' or its corresponding type declarations.

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-windows
🔇 Additional comments (44)
packages/ai-native/src/browser/mcp/tools/getDiagnosticsByPath.ts (1)

5-5: 清理未使用的导入
成功移除了 Injectable,只保留了实际使用的 Autowired,减少了冗余并保持了与相关 MCP 工具文件的一致性。

packages/ai-native/src/browser/mcp/tools/getOpenEditorFileDiagnostics.ts (1)

5-5: 移除未使用的 Injectable 导入
该文件未使用 Injectable 装饰器,移除多余导入能够减少冗余依赖、提升代码可读性与维护性。

packages/ai-native/src/browser/contrib/intelligent-completions/diff-computer.ts (1)

270-271: 良好的代码质量改进!

let 改为 const 是一个很好的改进,因为 rewriteDiffResult 变量在声明后没有被重新赋值。使用 const 更清楚地表达了变量不会被修改的意图,提高了代码的可读性和安全性。

packages/ai-native/src/browser/contrib/intelligent-completions/decoration/additions-deletions.decoration.ts (1)

1-1: 优化导入:移除未使用的 IModelDeltaDecoration
已删除对 IModelDeltaDecoration 的导入,可减少冗余并提升代码可维护性。

packages/ai-native/src/browser/contrib/terminal/terminal.feature.registry.ts (1)

3-3: 清理无用导入:移除 listenReadable 并使用 listenGroupReadable
@opensumi/ide-utils/lib/stream 中剔除了未使用的 listenReadable,并保留或引入了实际使用的 listenGroupReadable,保持了代码整洁。

packages/debug/src/browser/view/frames/debug-call-stack.module.less (1)

148-150: 已添加 unicode-bidi: plaintext 来增强双向文本渲染
该改动与其他组件中对双向文本渲染的调整保持一致,能改善 RTL 文本的可读性。

packages/ai-native/src/browser/mcp/tools/runTerminalCmd.ts (1)

5-5: 移除未使用的 Deferred 导入,保持代码整洁
清理了无用依赖,符合项目整体的代码卫生优化趋势。

packages/ai-native/src/browser/mcp/tools/handlers/ListDir.ts (1)

2-2: 移除未使用的 Throttler 导入并新增 URI 用于路径处理
URI 已被用于文件路径解析和展示名称获取,清理无用代码且功能保持一致。

packages/ai-native/src/browser/components/mention-input/types.ts (1)

60-61: MentionType 枚举中新增 RULE,支持规则类型
该更改为新引入的规则功能奠定基础,符合上下文中对规则提及的需求。

packages/editor/src/browser/editor.view.tsx (1)

574-574: Scrollbars 添加 hiddenHorizontal={true},隐藏水平滚动条
该改动与新版 Scrollbars 组件的更新保持一致,可防止水平滚动装饰元素被渲染。

packages/ai-native/src/browser/components/ChatToolRender.module.less (1)

55-55: 确认双向文本渲染设置
新增的 unicode-bidi: plaintext; 与已有的 direction: rtl; 配合,可改善工具标签中字母和阿拉伯语等双向文本的显示,和其他模块保持一致。

packages/core-common/src/settings/ai-native.ts (1)

47-51: 新增全局规则设置枚举
AINativeSettingSectionsId 中添加了新的 GlobalRules = 'ai.native.globalRules' 成员,用于全局规则偏好,分组注释清晰、格式规范。

packages/core-common/src/types/ai-native/index.ts (1)

305-305: 新增规则服务 DI Token
RulesServiceToken 已按照项目 DI Token 规范添加,Symbol 名称与常量名一致,可用于后续依赖注入。

packages/ai-native/src/common/index.ts (1)

337-339: 统一导出工具注册和 MDC 解析模块
在公共入口文件中新增 tool-invocation-registrymdc-parser 的 re-export,方便外部统一引用,位置和格式合理。

packages/components/src/icon/iconfont/iconMap.ts (2)

163-163: 自动生成图标映射:rules
该文件由脚本自动生成,仅新增了 rules 图标映射,与生成脚本资源同步即可,无需手动更改。


173-173: 自动生成图标映射:settings
该文件由脚本自动生成,仅新增了 settings 图标映射,与生成脚本资源同步即可,无需手动更改。

packages/components/src/icon/iconfont/iconfont.css (2)

3-8: 更新了 iconfont 资源链接,保持与 ide-iconfont.ts 同步
已将字体文件 URL 更新至新版本,确保对应的 CSS/JS CDN 地址一致。


19-25: 新增 Rules 与 Settings 图标类
添加了 .kticon-rules.kticon-settings,请确认 iconMap.tsiconfont.html 中也已同步映射和演示。

packages/core-browser/src/style/icon/ide-iconfont.ts (1)

1-1: 同步更新图标 CSS 引用地址
IDE_ICONFONT_CN_CSS 已切换至新 Alibaba CDN 链接,IDE_ICONFONT_CN_JS 通过正则派生无需额外修改。

packages/ai-native/src/browser/components/mention-input/mention-input.module.less (1)

259-260: unicode-bidi: plaintext 用于优化 RTL 文本截断
.mention_item_description 添加了 unicode-bidi: plaintext,能更好地配合 direction: rtl 实现省略号截断,提升多语言兼容性。

packages/ai-native/src/browser/components/components.module.less (1)

623-629: 样式改进看起来很好!

这些CSS属性的添加很好地解决了附件文本的显示问题:

  • max-width: 100px 限制文本宽度
  • text-overflow: ellipsisoverflow: hidden 提供文本截断
  • unicode-bidi: plaintext 为混合文本方向提供良好支持
  • direction: rtl 配合 unicode-bidi 实现从右到左的文本溢出效果

这些改进增强了用户界面的可读性和国际化支持。

packages/components/src/icon/iconfont/iconfont.html (2)

7-7: 版本更新正确

字体文件URL和版本号从v3.8.2更新到v3.9.0,与新功能的添加保持一致。

Also applies to: 88-89


95-106: 新图标添加符合规范

新增的"rules"和"settings"图标按照现有模式正确实现:

  • 使用了正确的HTML结构和aria-label
  • 图标名称和类名保持一致
  • 符合无障碍访问标准

这些图标将支持新的规则管理功能。

packages/ai-native/src/browser/index.ts (2)

20-20: 导入声明正确

正确导入了RulesServiceToken和Rules相关的服务类,遵循了项目的导入规范。

Also applies to: 81-82


125-125: 依赖注入配置正确

Rules服务的注册配置正确:

  • RulesContribution添加到contributionProvider中,用于注册UI贡献
  • RulesServiceToken绑定到RulesService类,建立了正确的依赖注入关系

这样的配置使Rules功能可以被其他组件正确注入和使用。

Also applies to: 223-226

packages/ai-native/src/common/llm-context.ts (1)

26-30: 🛠️ Refactor suggestion

添加方法文档注释。

新增的 addRuleToContext 方法缺少文档注释,应该保持与其他方法相同的文档风格。

+  /**
+   * 添加规则到 context 中
+   */
   addRuleToContext(uri: URI, isManual?: boolean): void;

Likely an incorrect or invalid review comment.

packages/ai-native/src/browser/components/mention-input/mention-input.tsx (2)

190-190: 验证 useEffect 依赖数组的更改

将依赖数组从 [contextService] 更改为 [] 可能是性能优化,但需要确认这不会导致内存泄漏或事件监听器未正确清理。

请确认 contextService 实例在组件生命周期内是否会发生变化,以及这种更改是否安全。


729-734: 规则类型的提及处理实现正确

规则类型的提及处理逻辑与文件和文件夹类型保持一致,正确添加了图标和上下文服务调用。

packages/ai-native/src/browser/chat/chat.view.tsx (2)

620-625: 消息净化逻辑正确实现

正确地在创建请求前移除 LLM 上下文键,同时在历史记录中保留原始消息内容(包含规则引用),这种处理方式是合理的。


741-752: 规则模式处理与现有模式保持一致

规则模式的处理逻辑与现有的文件、文件夹和代码模式处理保持一致,正确地提取规则名称并格式化为上下文键。

packages/ai-native/src/browser/rules/rules.contribution.ts (2)

39-105: 规则贡献实现结构良好

这个新的贡献类遵循了 OpenSumi 的贡献模式,正确实现了多个接口,并通过依赖注入管理服务。编辑器组件注册、资源提供者和命令注册的实现都很规范。


56-58: 在应用启动时初始化项目规则

onStart 方法中初始化项目规则是合适的时机,确保在应用完全启动后规则服务可用。

packages/i18n/src/common/en-US.lang.ts (1)

1542-1543: 本地化条目完整且结构良好!

新增的规则相关本地化字符串覆盖了功能的各个方面,包括用户规则、项目规则、错误提示等。

Also applies to: 1605-1622

packages/ai-native/src/browser/components/ChatMentionInput.tsx (3)

13-19: 导入和依赖注入正确!

规则功能所需的导入和服务注入都已正确添加。

Also applies to: 34-35, 88-88, 93-96


352-419: Rule 提及类型实现完善!

实现包含了完整的搜索和排序逻辑:

  • 正确获取项目规则
  • 搜索优先级合理(文件名匹配 > 描述匹配)
  • 结果限制为10条避免过多选项

代码质量高,逻辑清晰。


438-444: 规则按钮添加正确!

在页脚左侧添加了规则按钮,配置了正确的图标和点击处理函数。

packages/ai-native/src/browser/rules/rules.service.ts (2)

22-62: 服务结构设计良好!

RulesService 的基础结构合理:

  • 依赖注入配置正确
  • 事件发射器用于通知规则变更
  • 全局规则和项目规则分离管理

116-118: 辅助方法实现正确!

openRuleupdateGlobalRules 和 MDC 解析方法都实现简洁且包含了适当的错误处理。

Also applies to: 170-189

packages/ai-native/src/browser/context/llm-context.service.ts (1)

264-284: 文件夹序列化实现改进良好!

将方法改为异步并返回格式化的文件夹结构信息,提供了更好的上下文可读性。

packages/ai-native/src/common/mdc-parser.ts (3)

172-200: MDC 解析实现合理

使用正则表达式提取 frontmatter 并具有良好的错误处理和降级策略。


231-257: 验证逻辑完善

对所有预期字段进行了全面的类型检查,包括对 globs 数组元素的递归验证。


137-165: 🛠️ Refactor suggestion

数组项序列化可能产生无效的 YAML

在第 149 行使用 JSON.stringify 序列化非字符串数组项可能产生无效的 YAML 格式(例如对于布尔值会产生 "true" 而不是 true)。

         for (const item of value) {
-          lines.push(`  - ${typeof item === 'string' ? item : JSON.stringify(item)}`);
+          if (typeof item === 'string') {
+            // 字符串需要检查是否需要引号
+            if (item.includes(':') || item.includes('#') || item.includes('\n') || item.trim() !== item) {
+              lines.push(`  - "${item.replace(/"/g, '\\"')}"`);
+            } else {
+              lines.push(`  - ${item}`);
+            }
+          } else {
+            lines.push(`  - ${item}`);
+          }
         }

Likely an incorrect or invalid review comment.

packages/ai-native/src/common/prompts/context-prompt-provider.ts (2)

5-5: 代码更改符合预期

引入 AttachFileContext 类型用于支持文件附件的详细上下文信息。


93-104: 提示词结构优化合理

将全局规则放在最前面,附加规则放在额外数据块中,这种层次结构清晰地体现了规则的优先级。

Comment thread packages/ai-native/src/browser/preferences/schema.ts
Comment thread packages/components/src/scrollbars/index.tsx Outdated
Comment thread packages/ai-native/src/browser/rules/rules.module.less
Comment thread packages/ai-native/src/browser/rules/rules.module.less
Comment thread packages/ai-native/src/browser/rules/rules.view.tsx Outdated
Comment thread packages/ai-native/src/browser/chat/chat-proxy.service.ts
Comment thread packages/ai-native/src/browser/components/mention-input/mention-input.tsx Outdated
Comment thread packages/ai-native/src/browser/context/llm-context.service.ts
Comment thread packages/ai-native/src/common/mdc-parser.ts
Comment thread packages/ai-native/src/common/prompts/context-prompt-provider.ts
Copy link
Copy Markdown
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: 0

♻️ Duplicate comments (1)
packages/ai-native/src/browser/context/llm-context.service.ts (1)

386-394: Shell默认值逻辑仍需改进

当terminal.type为'default'时,代码总是默认为'zsh',这在Windows系统上是不正确的。应该根据操作系统选择合适的默认shell。

-    const shell = this.preferenceService.get<string>('terminal.type', 'zsh');
-    const shellName = shell === 'default' ? 'zsh' : shell;
+    const shell = this.preferenceService.get<string>('terminal.type', 'default');
+    let shellName = shell;
+    if (shell === 'default') {
+      shellName = platform === 'windows' ? 'cmd' : 'zsh';
+    }
🧹 Nitpick comments (1)
packages/ai-native/src/browser/components/mention-input/mention-input.tsx (1)

1238-1249: 规则删除逻辑需要优化

当前的规则删除实现通过清空所有上下文再重新添加的方式比较低效。建议实现专门的removeRuleFromContext方法调用。

-            onClick={() => {
-              // 由于没有专门的删除规则方法,我们重新构建规则列表
-              contextService?.cleanFileContext();
-              // 重新添加除了当前要删除的规则之外的所有上下文
-              attachedFiles.files.forEach((file) => contextService?.addFileToContext(file.uri, file.selection, true));
-              attachedFiles.folders.forEach((folder) => contextService?.addFolderToContext(folder.uri, true));
-              attachedFiles.rules.forEach((r, i) => {
-                if (i !== index) {
-                  contextService?.addRuleToContext(new URI(r.path), true);
-                }
-              });
-            }}
+            onClick={() => removeContext(MentionType.RULE, new URI(rule.path))}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b16efbb and 3bce41b.

📒 Files selected for processing (6)
  • packages/ai-native/src/browser/components/mention-input/mention-input.module.less (6 hunks)
  • packages/ai-native/src/browser/components/mention-input/mention-input.tsx (11 hunks)
  • packages/ai-native/src/browser/context/llm-context.service.ts (12 hunks)
  • packages/ai-native/src/common/llm-context.ts (5 hunks)
  • packages/i18n/src/common/en-US.lang.ts (3 hunks)
  • packages/i18n/src/common/zh-CN.lang.ts (3 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/i18n/src/common/en-US.lang.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/ai-native/src/common/llm-context.ts
  • packages/i18n/src/common/zh-CN.lang.ts
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: build (ubuntu-latest, 20.x)
  • GitHub Check: build-windows
  • GitHub Check: build (macos-latest, 20.x)
  • GitHub Check: unittest (macos-latest, 18.x, node)
  • GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
  • GitHub Check: unittest (ubuntu-latest, 18.x, node)
  • GitHub Check: unittest (macos-latest, 18.x, jsdom)
  • GitHub Check: ubuntu-latest, Node.js 20.x
🔇 Additional comments (14)
packages/ai-native/src/browser/components/mention-input/mention-input.module.less (4)

32-34: LGTM!修复了mention tag的垂直对齐问题

通过设置固定高度和负的margin-top值,有效解决了mention tag在编辑器中的垂直对齐问题。


268-268: 改进RTL文本处理

添加unicode-bidi: plaintext;配合direction: rtl;能更好地处理从右到左的文本渲染,特别是在文本截断场景下。


356-360: 统一图标字体样式

为mention图标添加伪元素样式,确保字体大小和背景尺寸的一致性。


424-571: 新增上下文预览UI样式完整且考虑周全

新增的context preview相关样式提供了:

  • 清晰的布局和间距设计
  • 优雅的悬停效果和交互动画
  • 移除按钮的视觉反馈(缩放和颜色变化)
  • 响应式的宽度限制和文本截断

样式设计符合现代UI标准,交互体验良好。

packages/ai-native/src/browser/context/llm-context.service.ts (4)

39-50: 依赖注入配置正确

新增的依赖注入包括RulesService、PreferenceService、ITerminalApiService和IApplicationService,为规则管理功能提供了必要的服务支持。


101-117: 规则上下文管理方法实现合理

addRuleToContext方法包含了适当的参数验证、重复检查和规则存在性验证,确保只有有效的规则才会被添加到上下文中。


184-200: 移除上下文方法实现一致

新增的removeFolderFromContextremoveRuleFromContext方法与现有的removeFileFromContext保持了一致的实现模式,确保了API的统一性。


413-473: 规则序列化逻辑设计完善

serializeAttachedRules方法实现了智能的规则匹配逻辑:

  • 支持Agent请求的规则
  • 支持始终应用的规则
  • 支持基于glob模式的文件匹配规则

XML格式的包装和规则描述格式化也很合适,便于AI理解和使用。

packages/ai-native/src/browser/components/mention-input/mention-input.tsx (6)

4-4: 导入路径问题已修复

从静态分析和AI摘要可以看出,导入路径已经改为相对路径../../../common/types,解决了之前的TypeScript编译错误。


71-76: 状态结构扩展合理

attachedFiles状态中添加rules数组,与现有的filesfolders保持一致的结构设计。


78-86: Mention tag跟踪机制设计良好

使用ref来跟踪mention tag的状态变化,能够有效检测tag的删除并相应地清理上下文,避免了数据不一致的问题。


222-259: 删除检测逻辑实现精确

通过比较当前和之前的mention tag集合,精确识别被删除的tag并调用相应的清理方法。支持FILE、FOLDER和RULE三种类型的清理,逻辑完整。


787-792: RULE类型集成完整

为RULE类型添加了专用的图标处理和上下文服务调用,与现有的FILE和FOLDER类型保持一致的处理模式。


1178-1273: 上下文预览UI实现优秀

新的renderContextPreview方法提供了:

  • 清晰的视觉呈现,显示所有附加的文件、文件夹和规则
  • 直观的删除操作,每个项目都有独立的删除按钮
  • 良好的用户体验,空状态下显示标题引导用户操作
  • 适当的文本截断和相对路径显示

代码结构清晰,功能完整。

@erha19
Copy link
Copy Markdown
Member Author

erha19 commented Jun 3, 2025

/next

Copy link
Copy Markdown
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: 1

♻️ Duplicate comments (1)
packages/ai-native/src/browser/context/llm-context.service.ts (1)

392-396: Shell 默认值逻辑需要改进

当 terminal.type 为 'default' 时,代码总是默认为 'zsh',这在 Windows 系统上是不正确的。应该根据操作系统选择合适的默认 shell。

-    const shell = this.preferenceService.get<string>('terminal.type', 'zsh');
-    let shellName = shell;
-    if (shell === 'default') {
-      shellName = this.applicationService.backendOS === OperatingSystem.Windows ? 'cmd' : 'zsh';
-    }
+    const shell = this.preferenceService.get<string>('terminal.type', 'default');
+    let shellName = shell;
+    if (shell === 'default') {
+      shellName = this.applicationService.backendOS === OperatingSystem.Windows ? 'cmd' : 'zsh';
+    }
🧹 Nitpick comments (3)
packages/ai-native/src/browser/chat/chat-proxy.service.ts (1)

128-129: 使用可选链简化条件检查

根据静态分析提示,可以使用可选链来简化条件检查逻辑。

-              if (commandHandler && commandHandler.providerPrompt) {
+              if (commandHandler?.providerPrompt) {
🧰 Tools
🪛 Biome (1.9.4)

[error] 128-129: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/ai-native/src/browser/context/llm-context.service.ts (1)

304-337: 优化文件夹结构获取的性能

getFormattedFolderStructure 方法为每个子项都进行异步文件系统调用,这可能导致性能问题。对于包含大量文件的文件夹,建议添加限制或使用批量操作。

   private async getFormattedFolderStructure(folder: string): Promise<string> {
     const result: string[] = [];
+    const MAX_ITEMS = 100; // 限制显示的最大项目数
     try {
       const stat = await this.fileService.getFileStat(folder);
+      const children = stat?.children?.slice(0, MAX_ITEMS) || [];
+      const hasMore = (stat?.children?.length || 0) > MAX_ITEMS;

-      for (const child of stat?.children || []) {
+      for (const child of children) {
         // ... 现有逻辑
       }
+      
+      if (hasMore) {
+        result.push(`... and ${(stat?.children?.length || 0) - MAX_ITEMS} more items`);
+      }
     } catch {
       return '';
     }
packages/ai-native/src/common/prompts/context-prompt-provider.ts (1)

147-164: 简化当前文件部分的构建逻辑

buildCurrentFileSection 方法可以通过使用模板字符串来简化字符串拼接逻辑,提高可读性。

   private buildCurrentFileSection(
     fileInfo: { path: string; languageId: string; content: string; currentLine?: number; lineContent?: string } | null,
   ): string {
     if (!fileInfo) {
       return '';
     }

-    let currentFileSection = `<current_file>\nPath: ${fileInfo.path}`;
-
-    if (fileInfo.currentLine && fileInfo.lineContent) {
-      currentFileSection += `\nCurrently selected line: ${fileInfo.currentLine}`;
-      currentFileSection += `\nLine ${fileInfo.currentLine} content: \`${fileInfo.lineContent}\``;
-    }
-
-    currentFileSection += '\n</current_file>';
-
-    return currentFileSection;
+    const lineInfo = fileInfo.currentLine && fileInfo.lineContent
+      ? `\nCurrently selected line: ${fileInfo.currentLine}\nLine ${fileInfo.currentLine} content: \`${fileInfo.lineContent}\``
+      : '';
+
+    return `<current_file>\nPath: ${fileInfo.path}${lineInfo}\n</current_file>`;
   }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3bce41b and 5402413.

📒 Files selected for processing (10)
  • packages/ai-native/src/browser/chat/chat-proxy.service.ts (3 hunks)
  • packages/ai-native/src/browser/context/llm-context.service.ts (12 hunks)
  • packages/ai-native/src/browser/rules/rules.view.tsx (1 hunks)
  • packages/ai-native/src/common/mdc-parser.ts (1 hunks)
  • packages/ai-native/src/common/prompts/context-prompt-provider.ts (6 hunks)
  • packages/ai-native/src/common/prompts/system-prompt.ts (1 hunks)
  • packages/components/src/scrollbars/index.tsx (1 hunks)
  • packages/components/src/scrollbars/styles.less (2 hunks)
  • packages/i18n/src/common/en-US.lang.ts (3 hunks)
  • packages/i18n/src/common/zh-CN.lang.ts (3 hunks)
✅ Files skipped from review due to trivial changes (2)
  • packages/components/src/scrollbars/styles.less
  • packages/ai-native/src/common/prompts/system-prompt.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/components/src/scrollbars/index.tsx
  • packages/ai-native/src/browser/rules/rules.view.tsx
  • packages/i18n/src/common/zh-CN.lang.ts
  • packages/i18n/src/common/en-US.lang.ts
  • packages/ai-native/src/common/mdc-parser.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/ai-native/src/common/prompts/context-prompt-provider.ts (2)
packages/ai-native/src/common/llm-context.ts (1)
  • AttachFileContext (76-82)
packages/ai-native/src/browser/rules/rules.service.ts (1)
  • globalRules (52-57)
🪛 Biome (1.9.4)
packages/ai-native/src/browser/chat/chat-proxy.service.ts

[error] 128-129: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
  • GitHub Check: unittest (macos-latest, 18.x, jsdom)
  • GitHub Check: unittest (macos-latest, 18.x, node)
  • GitHub Check: unittest (ubuntu-latest, 18.x, node)
  • GitHub Check: ubuntu-latest, Node.js 20.x
  • GitHub Check: build (ubuntu-latest, 20.x)
  • GitHub Check: build-windows
  • GitHub Check: build (macos-latest, 20.x)
🔇 Additional comments (3)
packages/ai-native/src/browser/chat/chat-proxy.service.ts (1)

107-174: 异步注册代理的改进很好

将代理注册移到 getBackendOS() 的异步回调中是一个很好的改进,确保了在获取到后端操作系统信息后再进行注册,避免了潜在的竞态条件问题。

🧰 Tools
🪛 Biome (1.9.4)

[error] 128-129: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/ai-native/src/common/prompts/context-prompt-provider.ts (2)

57-62: 当前行内容获取逻辑改进良好

使用 Monaco Editor 的 getLineContent API 直接获取行内容是一个很好的性能改进,避免了分割整个文件内容的开销。这个实现正确地处理了编辑器和模型的存在性检查。


26-29: 当前文件去重逻辑正确

检查当前文件是否已经在附加文件列表中,如果是则设为 null 的逻辑是正确的,避免了重复信息在提示中出现。

Comment thread packages/ai-native/src/browser/context/llm-context.service.ts
@opensumi
Copy link
Copy Markdown
Contributor

opensumi Bot commented Jun 3, 2025

🎉 PR Next publish successful!

3.9.1-next-1748939097.0

Copy link
Copy Markdown
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: 0

🧹 Nitpick comments (2)
packages/ai-native/src/browser/context/llm-context.service.ts (2)

380-414: 全局规则序列化实现良好,shell 逻辑已部分改进

该方法正确实现了全局规则的序列化,构建了结构化的用户信息和规则部分。Shell 逻辑相比之前的版本有所改进,现在会根据操作系统选择合适的默认 shell。

但是,shell 逻辑仍有改进空间:对于 Windows 系统,'cmd' 可能不是最佳选择,'powershell' 在现代 Windows 环境中更常用。

考虑进一步优化 shell 选择逻辑:

-    if (shell === 'default') {
-      shellName = this.applicationService.backendOS === OperatingSystem.Windows ? 'cmd' : 'zsh';
-    }
+    if (shell === 'default') {
+      if (this.applicationService.backendOS === OperatingSystem.Windows) {
+        shellName = 'powershell';
+      } else if (this.applicationService.backendOS === OperatingSystem.Linux) {
+        shellName = 'bash';
+      } else {
+        shellName = 'zsh'; // macOS
+      }
+    }

416-473: 规则辅助方法实现良好,已解决之前的复杂性问题

这些辅助方法很好地解决了之前评论中提到的规则序列化逻辑过于复杂的问题。代码被合理地拆分为专用的辅助方法,提高了可读性和可维护性。

不过仍有一些优化机会:

  1. normalizeGlobs 方法中存在冗余逻辑,可以简化:
-  private normalizeGlobs(globs: string | string[]): string[] {
-    const globArray = isString(globs) ? globs.split(',') : globs || [];
+  private normalizeGlobs(globs: string | string[]): string[] {
+    const globArray = isString(globs) ? globs.split(',') : (globs || []);
     return globArray.map((glob) => {
       const p = glob.trim();
       return p.startsWith('**') ? p : `**/${p}`;
     });
   }
  1. 考虑缓存 parseGlob 结果以避免重复解析相同的模式。
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5402413 and 62e5b89.

📒 Files selected for processing (3)
  • packages/ai-native/src/browser/components/mention-input/types.ts (3 hunks)
  • packages/ai-native/src/browser/context/llm-context.service.ts (12 hunks)
  • packages/ai-native/src/common/mdc-parser.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/ai-native/src/common/mdc-parser.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/ai-native/src/browser/components/mention-input/types.ts
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: ubuntu-latest, Node.js 20.x
  • GitHub Check: build (macos-latest, 20.x)
  • GitHub Check: build (ubuntu-latest, 20.x)
  • GitHub Check: build-windows
  • GitHub Check: unittest (macos-latest, 18.x, node)
  • GitHub Check: unittest (macos-latest, 18.x, jsdom)
  • GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
  • GitHub Check: unittest (ubuntu-latest, 18.x, node)
🔇 Additional comments (11)
packages/ai-native/src/browser/context/llm-context.service.ts (11)

2-23: 导入语句合理且必要

新增的导入语句都是为了支持规则管理功能所必需的,包括偏好设置服务、规则服务、工具函数等,结构清晰合理。


39-50: 依赖注入配置正确

新增的服务依赖注入配置合理,包括规则服务、偏好设置服务、终端服务和应用服务,都正确使用了 @Autowired 装饰器。


101-117: 规则添加方法实现良好

addRuleToContext 方法正确处理了空值检查、重复检测和规则查找逻辑,实现清晰合理。


193-200: 规则移除方法实现正确

removeRuleFromContext 方法正确实现了根据路径查找并移除规则的逻辑,符合预期行为。


60-60: 正确添加了规则状态管理

在类中添加 attachedRules 属性用于跟踪附加的规则,与现有的文件和文件夹管理保持一致。


66-66: 事件通知正确包含规则信息

上下文变更事件正确包含了 attachedRules 属性,确保UI能够及时获取规则状态更新。


156-156: 清理方法正确处理规则

cleanFileContext 方法正确清理了附加的规则,保持了状态一致性。


184-191: 文件夹移除方法实现合理

removeFolderFromContext 方法遵循了与文件移除相同的模式,实现简洁明了。


276-279: 序列化方法更新合理

正确在序列化结果中包含了 attachedRulesglobalRules,调用了相应的专用序列化方法。


282-302: 文件夹序列化增强实现优秀

新的文件夹序列化方法提供了清晰的结构化输出,包含有意义的标题和详细的文件夹内容描述,大大提升了上下文信息的可读性。


304-337: 文件夹结构格式化方法实现全面

getFormattedFolderStructure 方法正确处理了目录、文件和符号链接的不同类型,使用清晰的前缀标识,并提供了有用的元信息如目录项目数量。错误处理也很恰当。

@erha19
Copy link
Copy Markdown
Member Author

erha19 commented Jun 3, 2025

/next

@erha19
Copy link
Copy Markdown
Member Author

erha19 commented Jun 3, 2025

/next

@opensumi
Copy link
Copy Markdown
Contributor

opensumi Bot commented Jun 3, 2025

🎉 PR Next publish successful!

3.9.1-next-1748943529.0

@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 3, 2025

Codecov Report

Attention: Patch coverage is 3.21716% with 361 lines in your changes missing coverage. Please review.

Project coverage is 52.65%. Comparing base (e68714e) to head (c35c6ef).
Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
...-native/src/browser/context/llm-context.service.ts 0.00% 86 Missing and 19 partials ⚠️
packages/ai-native/src/common/mdc-parser.ts 5.40% 75 Missing and 30 partials ⚠️
...kages/ai-native/src/browser/rules/rules.service.ts 0.00% 75 Missing and 18 partials ⚠️
...s/ai-native/src/browser/chat/chat-proxy.service.ts 0.00% 25 Missing and 3 partials ⚠️
...tive/src/common/prompts/context-prompt-provider.ts 0.00% 13 Missing and 8 partials ⚠️
packages/ai-native/src/browser/index.ts 0.00% 2 Missing ⚠️
...tive/src/browser/components/mention-input/types.ts 0.00% 1 Missing ⚠️
...tions/decoration/additions-deletions.decoration.ts 0.00% 1 Missing ⚠️
...wser/contrib/terminal/terminal.feature.registry.ts 0.00% 1 Missing ⚠️
...tive/src/browser/mcp/tools/getDiagnosticsByPath.ts 0.00% 1 Missing ⚠️
... and 3 more
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #4578       +/-   ##
===========================================
+ Coverage   12.07%   52.65%   +40.57%     
===========================================
  Files        1673     1684       +11     
  Lines      102620   104042     +1422     
  Branches    20965    22726     +1761     
===========================================
+ Hits        12394    54780    +42386     
+ Misses      76037    40948    -35089     
+ Partials    14189     8314     -5875     
Flag Coverage Δ
jsdom 48.18% <3.21%> (?)
node 12.06% <2.68%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@erha19 erha19 merged commit 281361f into main Jun 4, 2025
16 of 20 checks passed
@erha19 erha19 deleted the feat/support-chat-agent-rules branch June 4, 2025 07:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🎨 feature feature required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants