feat(vscode): 重构 Qwen 交互模型并优化权限请求 UI

- 重构 QwenAgentManager 类,支持处理多种类型的消息更新
- 改进权限请求界面,增加详细信息展示和选项选择功能
- 新增工具调用卡片组件,用于展示工具调用相关信息
- 优化消息流处理逻辑,支持不同类型的内容块
- 调整会话切换和新会话创建的处理方式
This commit is contained in:
yiliang114
2025-11-18 01:00:25 +08:00
parent eeeb1d490a
commit 28892996b3
8 changed files with 1245 additions and 162 deletions

View File

@@ -22,11 +22,22 @@ export interface ChatMessage {
timestamp: number;
}
interface ToolCallUpdateData {
toolCallId: string;
kind?: string;
title?: string;
status?: string;
rawInput?: unknown;
content?: Array<Record<string, unknown>>;
locations?: Array<{ path: string; line?: number | null }>;
}
export class QwenAgentManager {
private connection: AcpConnection;
private sessionReader: QwenSessionReader;
private onMessageCallback?: (message: ChatMessage) => void;
private onStreamChunkCallback?: (chunk: string) => void;
private onToolCallCallback?: (update: ToolCallUpdateData) => void;
private onPermissionRequestCallback?: (
request: AcpPermissionRequest,
) => Promise<string>;
@@ -342,19 +353,91 @@ export class QwenAgentManager {
private handleSessionUpdate(data: AcpSessionUpdate): void {
const update = data.update;
if (update.sessionUpdate === 'agent_message_chunk') {
if (update.content?.text && this.onStreamChunkCallback) {
this.onStreamChunkCallback(update.content.text);
}
} else if (update.sessionUpdate === 'tool_call') {
// Handle tool call updates
const toolCall = update as { title?: string; status?: string };
const title = toolCall.title || 'Tool Call';
const status = toolCall.status || 'pending';
switch (update.sessionUpdate) {
case 'user_message_chunk':
// Handle user message chunks if needed
if (update.content?.text && this.onStreamChunkCallback) {
this.onStreamChunkCallback(update.content.text);
}
break;
if (this.onStreamChunkCallback) {
this.onStreamChunkCallback(`\n🔧 ${title} [${status}]\n`);
case 'agent_message_chunk':
// Handle assistant message chunks
if (update.content?.text && this.onStreamChunkCallback) {
this.onStreamChunkCallback(update.content.text);
}
break;
case 'agent_thought_chunk':
// Handle thinking chunks - could be displayed differently in UI
if (update.content?.text && this.onStreamChunkCallback) {
this.onStreamChunkCallback(update.content.text);
}
break;
case 'tool_call': {
// Handle new tool call
if (this.onToolCallCallback && 'toolCallId' in update) {
this.onToolCallCallback({
toolCallId: update.toolCallId as string,
kind: (update.kind as string) || undefined,
title: (update.title as string) || undefined,
status: (update.status as string) || undefined,
rawInput: update.rawInput,
content: update.content as
| Array<Record<string, unknown>>
| undefined,
locations: update.locations as
| Array<{ path: string; line?: number | null }>
| undefined,
});
}
break;
}
case 'tool_call_update': {
// Handle tool call status update
if (this.onToolCallCallback && 'toolCallId' in update) {
this.onToolCallCallback({
toolCallId: update.toolCallId as string,
kind: (update.kind as string) || undefined,
title: (update.title as string) || undefined,
status: (update.status as string) || undefined,
rawInput: update.rawInput,
content: update.content as
| Array<Record<string, unknown>>
| undefined,
locations: update.locations as
| Array<{ path: string; line?: number | null }>
| undefined,
});
}
break;
}
case 'plan': {
// Handle plan updates - could be displayed as a task list
if ('entries' in update && this.onStreamChunkCallback) {
const entries = update.entries as Array<{
content: string;
priority: string;
status: string;
}>;
const planText =
'\n📋 Plan:\n' +
entries
.map(
(entry, i) => `${i + 1}. [${entry.priority}] ${entry.content}`,
)
.join('\n');
this.onStreamChunkCallback(planText);
}
break;
}
default:
console.log('[QwenAgentManager] Unhandled session update type');
break;
}
}
@@ -366,6 +449,10 @@ export class QwenAgentManager {
this.onStreamChunkCallback = callback;
}
onToolCall(callback: (update: ToolCallUpdateData) => void): void {
this.onToolCallCallback = callback;
}
onPermissionRequest(
callback: (request: AcpPermissionRequest) => Promise<string>,
): void {
@@ -379,4 +466,8 @@ export class QwenAgentManager {
get isConnected(): boolean {
return this.connection.isConnected;
}
get currentSessionId(): string | null {
return this.connection.currentSessionId;
}
}