Compare commits
3 Commits
feat/Knowl
...
feat/codeT
| Author | SHA1 | Date | |
|---|---|---|---|
| 394faa4328 | |||
| 4e06d08106 | |||
| 3b0dca6467 |
@ -42,9 +42,9 @@ const ENV_CONFIG: Record<Environment, IccoderConfig> = {
|
||||
},
|
||||
/** 测试服务器环境 - 通过 Gateway 路由 */
|
||||
test: {
|
||||
backendUrl: "http://192.168.1.108:2029/iccoder",
|
||||
backendUrlStrongeLoop: "http://192.168.1.108:2029",
|
||||
loginUrl: "http://192.168.1.108:2005/login",
|
||||
backendUrl: "http://192.168.1.134:2233",
|
||||
backendUrlStrongeLoop: "http://192.168.1.134:2233",
|
||||
loginUrl: "http://192.168.1.134/login",
|
||||
timeout: 60000,
|
||||
userId: "default-user",
|
||||
serviceTier: "max",
|
||||
|
||||
@ -90,21 +90,12 @@ export async function selectConversation(
|
||||
|
||||
panel.webview.postMessage({ command: "clearChat" });
|
||||
|
||||
const segments: any[] = [];
|
||||
let i = 0;
|
||||
|
||||
while (i < taskSession.messages.length) {
|
||||
const message = taskSession.messages[i];
|
||||
|
||||
if (message.type === MessageType.USER) {
|
||||
if (segments.length > 0) {
|
||||
panel.webview.postMessage({
|
||||
command: "receiveSegments",
|
||||
segments: [...segments],
|
||||
});
|
||||
segments.length = 0;
|
||||
}
|
||||
|
||||
const textContent = message.contents?.find((c) => c.type === "TEXT");
|
||||
if (textContent && "text" in textContent) {
|
||||
panel.webview.postMessage({
|
||||
@ -115,12 +106,15 @@ export async function selectConversation(
|
||||
i++;
|
||||
} else if (message.type === MessageType.AI) {
|
||||
if (message.segments && message.segments.length > 0) {
|
||||
// 直接发送 segments
|
||||
panel.webview.postMessage({
|
||||
command: "receiveSegments",
|
||||
segments: message.segments,
|
||||
});
|
||||
i++;
|
||||
} else {
|
||||
// 构建当前 AI 消息的 segments 并发送
|
||||
const segments: any[] = [];
|
||||
|
||||
if (message.text) {
|
||||
segments.push({ type: "text", content: message.text });
|
||||
}
|
||||
@ -138,7 +132,7 @@ export async function selectConversation(
|
||||
nextMsg.id === toolReq.id
|
||||
) {
|
||||
toolResult = nextMsg.text;
|
||||
i++;
|
||||
i++; // 跳过工具执行结果消息
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,64 +145,26 @@ export async function selectConversation(
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
while (i < taskSession.messages.length) {
|
||||
const nextMsg = taskSession.messages[i];
|
||||
if (nextMsg.type === MessageType.USER) {
|
||||
break;
|
||||
}
|
||||
if (nextMsg.type === MessageType.AI) {
|
||||
if (nextMsg.segments && nextMsg.segments.length > 0) {
|
||||
break;
|
||||
}
|
||||
if (nextMsg.text) {
|
||||
segments.push({ type: "text", content: nextMsg.text });
|
||||
}
|
||||
if (
|
||||
nextMsg.toolExecutionRequests &&
|
||||
nextMsg.toolExecutionRequests.length > 0
|
||||
) {
|
||||
for (const toolReq of nextMsg.toolExecutionRequests) {
|
||||
let toolResult = "";
|
||||
if (i + 1 < taskSession.messages.length) {
|
||||
const resultMsg = taskSession.messages[i + 1];
|
||||
if (
|
||||
resultMsg.type === MessageType.TOOL_EXECUTION_RESULT &&
|
||||
resultMsg.id === toolReq.id
|
||||
) {
|
||||
toolResult = resultMsg.text;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
segments.push({
|
||||
type: "tool",
|
||||
toolName: toolReq.name,
|
||||
askId: toolReq.id,
|
||||
toolResult: toolResult,
|
||||
});
|
||||
}
|
||||
}
|
||||
i++;
|
||||
} else if (nextMsg.type === MessageType.TOOL_EXECUTION_RESULT) {
|
||||
i++;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
if (segments.length > 0) {
|
||||
panel.webview.postMessage({
|
||||
command: "receiveSegments",
|
||||
segments: segments,
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
i++;
|
||||
} else {
|
||||
// 处理其他类型的消息(如 SYSTEM, TOOL_EXECUTION_RESULT 等)
|
||||
if (message.type === MessageType.TOOL_EXECUTION_RESULT) {
|
||||
// 工具执行结果已经在上面的 AI 消息处理中被处理了,这里跳过
|
||||
i++;
|
||||
} else {
|
||||
// 其他类型消息,如 SYSTEM
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (segments.length > 0) {
|
||||
panel.webview.postMessage({
|
||||
command: "receiveSegments",
|
||||
segments: segments,
|
||||
});
|
||||
}
|
||||
|
||||
// 发送任务完成消息(历史记录)
|
||||
panel.webview.postMessage({
|
||||
command: "taskCompleteHistory",
|
||||
|
||||
@ -45,6 +45,8 @@ export interface MessageSegment {
|
||||
toolDescription?: string;
|
||||
askId?: string;
|
||||
questions?: import("../types/api").QuestionItem[];
|
||||
answered?: boolean;
|
||||
answers?: { [questionIndex: string]: string[] };
|
||||
// 智能体相关字段
|
||||
agentId?: string;
|
||||
agentName?: string;
|
||||
@ -125,6 +127,7 @@ export class DialogSession {
|
||||
private toolContext: ToolExecutorContext;
|
||||
private accumulatedText = "";
|
||||
private isActive = false;
|
||||
private wasAbortedByUser = false;
|
||||
private hasCompleted = false; // 标记是否已收到 complete 事件
|
||||
private segments: MessageSegment[] = [];
|
||||
private currentTextSegment: MessageSegment | null = null;
|
||||
@ -216,6 +219,10 @@ export class DialogSession {
|
||||
return this.isActive;
|
||||
}
|
||||
|
||||
get abortedByUser(): boolean {
|
||||
return this.wasAbortedByUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载知识图谱数据
|
||||
* 从 .iccoder/knowledge.json 读取
|
||||
@ -1076,6 +1083,7 @@ export class DialogSession {
|
||||
abort(): void {
|
||||
// 先标记完成,防止 onClose 重复触发
|
||||
const wasActive = this.isActive;
|
||||
this.wasAbortedByUser = true;
|
||||
this.hasCompleted = true;
|
||||
this.isActive = false;
|
||||
|
||||
@ -1125,6 +1133,7 @@ export class DialogSession {
|
||||
// 直接调用 receiveAnswer,传递 taskId 作为 fallbackTaskId
|
||||
// 如果 pendingQuestions 中有问题,走正常流程
|
||||
// 如果没有,receiveAnswer 会使用 fallbackTaskId 直接发送到后端
|
||||
this.markQuestionAnswered(askId, selected, customInput, answers);
|
||||
await userInteractionManager.receiveAnswer(
|
||||
askId,
|
||||
selected,
|
||||
@ -1133,6 +1142,30 @@ export class DialogSession {
|
||||
this.taskId
|
||||
);
|
||||
}
|
||||
|
||||
private markQuestionAnswered(
|
||||
askId: string,
|
||||
selected?: string[],
|
||||
customInput?: string,
|
||||
answers?: { [questionIndex: string]: string[] }
|
||||
): void {
|
||||
const normalizedAnswers =
|
||||
answers && Object.keys(answers).length > 0
|
||||
? answers
|
||||
: { "0": customInput ? [customInput] : selected || [] };
|
||||
|
||||
for (let i = this.segments.length - 1; i >= 0; i--) {
|
||||
const segment = this.segments[i];
|
||||
if (
|
||||
segment.askId === askId &&
|
||||
(segment.type === "question" || segment.type === "plan")
|
||||
) {
|
||||
segment.answered = true;
|
||||
segment.answers = normalizedAnswers;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -362,7 +362,11 @@ async function handleUserMessageWithBackend(
|
||||
.map((s) => s.content)
|
||||
.join("\n");
|
||||
|
||||
await historyManager.addAiMessage(textContent, undefined, segments);
|
||||
const finalText = currentSession?.abortedByUser
|
||||
? `${textContent}\n\n[对话已被用户中止]`
|
||||
: textContent;
|
||||
|
||||
await historyManager.addAiMessage(finalText, undefined, segments);
|
||||
console.log("[MessageHandler] AI响应已保存到历史记录");
|
||||
} catch (error) {
|
||||
console.error("[MessageHandler] 保存AI响应历史失败:", error);
|
||||
@ -506,9 +510,11 @@ export async function handleUserAnswer(
|
||||
* 中止当前对话
|
||||
*/
|
||||
export async function abortCurrentDialog(): Promise<void> {
|
||||
if (currentSession) {
|
||||
const session = currentSession;
|
||||
if (false && session) {
|
||||
// 历史保存统一走 onComplete,避免手动中止时重复写入
|
||||
// 保存当前已有的对话内容
|
||||
const segments = currentSession.getSegments();
|
||||
const segments = session!.getSegments();
|
||||
if (segments && segments.length > 0) {
|
||||
try {
|
||||
const historyManager = ChatHistoryManager.getInstance();
|
||||
|
||||
@ -147,8 +147,10 @@ export function getSegmentRendererScript(): string {
|
||||
options: segment.options || [],
|
||||
multiSelect: false
|
||||
}] : []);
|
||||
const isAnswered = answeredQuestions.has(segment.askId);
|
||||
const savedAnswers = answeredQuestions.get(segment.askId) || {};
|
||||
const segmentAnswers = segment.answers || {};
|
||||
const runtimeAnswers = answeredQuestions.get(segment.askId) || {};
|
||||
const savedAnswers = Object.keys(segmentAnswers).length > 0 ? segmentAnswers : runtimeAnswers;
|
||||
const isAnswered = segment.answered === true || answeredQuestions.has(segment.askId);
|
||||
if (isAnswered) {
|
||||
segmentDiv.classList.add('answered');
|
||||
}
|
||||
|
||||
@ -894,6 +894,9 @@ export function getWebviewContent(
|
||||
if (messagesContainer) {
|
||||
messagesContainer.innerHTML = '';
|
||||
}
|
||||
if (typeof answeredQuestions !== 'undefined' && answeredQuestions.clear) {
|
||||
answeredQuestions.clear();
|
||||
}
|
||||
// 重置输入框布局到居中
|
||||
if (typeof window.resetInputAreaLayout === 'function') {
|
||||
window.resetInputAreaLayout();
|
||||
|
||||
Reference in New Issue
Block a user