Skip to content

Commit f48aa42

Browse files
committed
feat: 添加 GPT OpenAI Platform 支持及清屏功能
- 新增 GptOpenaiPlatformChatService 支持字节跳动内部 GPT 平台 - 实现 /clear 命令完整重置会话状态 - 添加 clearCount 状态强制 Static 组件重新挂载 - 优化孤儿 tool 消息过滤逻辑 - 更新文档和配置支持新功能
1 parent 41e0784 commit f48aa42

13 files changed

Lines changed: 702 additions & 64 deletions

File tree

.blade/settings.local.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
"allow": [
44
"TestTool",
55
"Bash(git status)",
6-
"Bash(git diff *)"
6+
"Bash(git diff *)",
7+
"Bash(ls -l)",
8+
"Write(**/*.md)"
79
],
810
"ask": [],
911
"deny": []

BLADE.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,38 +29,46 @@ always respond in Chinese
2929
- **HookExecutor.ts**: Hook 执行器
3030
- **Matcher.ts**: 匹配器,决定 Hook 是否触发
3131
- **SecureProcessExecutor.ts**: 安全进程执行器
32+
- **OutputParser.ts**: Hook 输出解析器,解析 Hook 命令的输出
33+
- **HookExecutionGuard.ts**: Hook 执行保护器,保证单次工具调用只触发一次 Hook
3234

3335
### 3. Context 管理 (`src/context/`)
3436
统一管理会话和上下文:
3537
- **ContextManager.ts**: 核心上下文管理器,支持内存/持久化存储
3638
- **CompactionService.ts**: 上下文压缩服务,防止 token 超限
3739
- **TokenCounter.ts**: Token 计数器
40+
- **FileAnalyzer.ts**: 文件分析服务,从对话中提取重点文件并读取内容
3841

3942
### 4. Tool 系统 (`src/tools/`)
4043
- **builtin/**: 内置工具(文件操作、Git、网络等)
4144
- **registry/**: 工具注册表
4245
- **execution/**: 工具执行管线
4346
- **validation/**: 工具参数验证
4447
- **MCP 集成**: 支持 Model Context Protocol 扩展
48+
- **FileLockManager.ts**: 文件锁管理器,防止对同一文件的并发编辑
4549

4650
### 5. 服务层 (`src/services/`)
4751
- **OpenAIChatService.ts**: OpenAI API 服务
4852
- **AnthropicChatService.ts**: Anthropic API 服务
53+
- **GptOpenaiPlatformChatService.ts**: 通用 OpenAI 平台兼容服务,支持自定义 API 端点
4954
- **SessionService.ts**: 会话管理服务
5055

5156
### 6. Slash 命令 (`src/slash-commands/`)
5257
- **builtinCommands.ts**: 内置命令(/compact, /init, /model 等)
58+
- **ide.ts**: IDE 集成命令(/ide, /ide status, /ide connect, /ide install, /ide disconnect)
5359
- **UIActionMapper.ts**: UI 动作映射器
5460

5561
### 7. MCP 集成 (`src/mcp/`)
5662
- **McpRegistry.ts**: MCP 注册表
5763
- **McpClient.ts**: MCP 客户端
5864
- **loadProjectMcpConfig.ts**: 项目 MCP 配置加载
65+
- **HealthMonitor.ts**: MCP 健康监控器,周期性检查连接状态并自动触发重连
5966

6067
### 8. UI 层 (`src/ui/`)
6168
- **App.tsx**: 主应用组件
6269
- **components/**: UI 组件(BladeInterface, LoadingIndicator 等)
6370
- **contexts/**: React Context(SessionContext, AppContext 等)
71+
- **utils/security.ts**: 安全工具函数,处理敏感信息的格式化和过滤
6472

6573
### 9. 配置系统 (`src/config/`)
6674
- **ConfigManager.ts**: 配置管理器
@@ -70,6 +78,12 @@ always respond in Chinese
7078
- **blade.tsx**: 入口文件
7179
- **commands/**: 命令实现(config, doctor, mcp, update 等)
7280

81+
### 11. IDE 集成 (`src/ide/`)
82+
- **ideClient.ts**: IDE 客户端,处理与 IDE 的 WebSocket 通信
83+
- **ideContext.ts**: IDE 上下文,管理 IDE 相关信息和状态
84+
- **ideInstaller.ts**: IDE 安装器,检测和安装 VS Code 插件
85+
- **detectIde.ts**: IDE 检测器,检测当前运行环境
86+
7387
## 开发命令
7488

7589
### 构建与运行
@@ -104,9 +118,26 @@ bun run test:cli
104118
# 覆盖率测试
105119
bun run test:coverage
106120

121+
# 分类覆盖率测试
122+
bun run test:unit:coverage
123+
bun run test:integration:coverage
124+
bun run test:cli:coverage
125+
107126
# 监听模式
108127
bun run test:watch
109128

129+
# 分类监听测试
130+
bun run test:unit:watch
131+
bun run test:integration:watch
132+
bun run test:cli:watch
133+
134+
# 调试和详细测试
135+
bun run test:debug
136+
bun run test:verbose
137+
138+
# 性能测试
139+
bun run test:performance
140+
110141
# CI 模式(带覆盖率)
111142
bun run test:ci
112143
```
@@ -223,6 +254,9 @@ Agent 实例不保存会话状态,所有状态通过 context 参数传入。
223254
5. **性能**: 注意 token 使用,大文件操作需要流式处理
224255
6. **测试**: 新功能必须包含测试用例
225256
7. **文档**: 公共 API 需要 JSDoc 注释
257+
8. **并发安全**: 文件操作使用 FileLockManager 确保并发安全
258+
9. **安全过滤**: 敏感信息(如 API Key)在输出时会被自动过滤
259+
10. **健康监控**: MCP 连接支持健康监控和自动重连机制
226260

227261
## 项目结构
228262
```
@@ -239,6 +273,7 @@ src/
239273
├── prompts/ # 提示词管理
240274
├── services/ # 服务层
241275
├── slash-commands/ # Slash 命令
276+
├── store/ # 全局状态管理 (基于 Zustand)
242277
├── tools/ # 工具系统
243278
├── ui/ # UI 组件
244279
└── utils/ # 工具函数

src/agent/Agent.ts

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -609,17 +609,9 @@ IMPORTANT: Execute according to the approved plan above. Follow the steps exactl
609609
logger.debug('可用工具数量:', tools.length);
610610
logger.debug('================================\n');
611611

612-
// 3. 过滤孤儿 tool 消息(防止 API 400 错误)
613-
const filteredMessages = this.filterOrphanToolMessages(messages);
614-
if (filteredMessages.length < messages.length) {
615-
logger.debug(
616-
`🔧 过滤掉 ${messages.length - filteredMessages.length} 条孤儿 tool 消息`
617-
);
618-
}
619-
620-
// 4. 直接调用 ChatService(OpenAI SDK 已内置重试机制)
612+
// 3. 直接调用 ChatService(各 provider 自行处理消息过滤)
621613
const turnResult = await this.chatService.chat(
622-
filteredMessages,
614+
messages,
623615
tools,
624616
options?.signal
625617
);
@@ -1176,39 +1168,6 @@ IMPORTANT: Execute according to the approved plan above. Follow the steps exactl
11761168
return await this.runLoop(message, chatContext, options);
11771169
}
11781170

1179-
/**
1180-
* 过滤孤儿 tool 消息
1181-
*
1182-
* 孤儿 tool 消息是指 tool_call_id 对应的 assistant 消息不存在的 tool 消息。
1183-
* 这种情况通常发生在上下文压缩后,导致 OpenAI API 返回 400 错误。
1184-
*
1185-
* @param messages - 原始消息列表
1186-
* @returns 过滤后的消息列表
1187-
*/
1188-
private filterOrphanToolMessages(messages: Message[]): Message[] {
1189-
// 收集所有可用的 tool_call ID
1190-
const availableToolCallIds = new Set<string>();
1191-
for (const msg of messages) {
1192-
if (msg.role === 'assistant' && msg.tool_calls) {
1193-
for (const tc of msg.tool_calls) {
1194-
availableToolCallIds.add(tc.id);
1195-
}
1196-
}
1197-
}
1198-
1199-
// 过滤掉孤儿 tool 消息
1200-
return messages.filter((msg) => {
1201-
if (msg.role === 'tool') {
1202-
// 缺失 tool_call_id 的 tool 消息直接丢弃(否则会触发 API 400)
1203-
if (!msg.tool_call_id) {
1204-
return false;
1205-
}
1206-
return availableToolCallIds.has(msg.tool_call_id);
1207-
}
1208-
return true; // 保留其他所有消息
1209-
});
1210-
}
1211-
12121171
/**
12131172
* 带系统提示的聊天接口
12141173
*/

src/config/types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/**
77
* LLM API 提供商类型
88
*/
9-
export type ProviderType = 'openai-compatible' | 'anthropic';
9+
export type ProviderType = 'openai-compatible' | 'anthropic' | 'gpt-openai-platform';
1010

1111
/**
1212
* 权限模式枚举
@@ -66,6 +66,9 @@ export interface ModelConfig {
6666
// Thinking 模型配置(如 DeepSeek R1)
6767
supportsThinking?: boolean; // 手动覆盖自动检测结果
6868
thinkingBudget?: number; // 思考 token 预算(可选)
69+
70+
// GPT OpenAI Platform 特有配置
71+
apiVersion?: string; // API 版本(如 '2024-03-01-preview')
6972
}
7073

7174
export interface BladeConfig {

src/services/ChatServiceInterface.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import type { ChatCompletionMessageToolCall } from 'openai/resources/chat';
77
import type { ProviderType } from '../config/types.js';
88
import { createLogger, LogCategory } from '../logging/Logger.js';
9+
import { GptOpenaiPlatformChatService } from './GptOpenaiPlatformChatService.js';
910
import { OpenAIChatService } from './OpenAIChatService.js';
1011

1112
const logger = createLogger(LogCategory.SERVICE);
@@ -34,6 +35,7 @@ export interface ChatConfig {
3435
maxContextTokens?: number; // 上下文窗口大小(用于压缩判断)
3536
maxOutputTokens?: number; // 输出 token 限制(传给 API 的 max_tokens)
3637
timeout?: number;
38+
apiVersion?: string; // GPT OpenAI Platform 专用:API 版本(如 '2024-03-01-preview')
3739
}
3840

3941
/**
@@ -118,6 +120,9 @@ export function createChatService(config: ChatConfig): IChatService {
118120
case 'openai-compatible':
119121
return new OpenAIChatService(config);
120122

123+
case 'gpt-openai-platform':
124+
return new GptOpenaiPlatformChatService(config);
125+
121126
case 'anthropic':
122127
// Anthropic 暂未实现,抛出友好错误
123128
throw new Error(

0 commit comments

Comments
 (0)