feat: 知识图谱工具支持 + 智能体事件处理
- dialogService: 添加智能体 SSE 事件处理 - toolExecutor: 添加 knowledge_save/knowledge_load 工具 - messageArea: 添加智能体消息渲染支持 - 添加 CLAUDE.md 项目配置
This commit is contained in:
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
9
.idea/IC-Coder-Plugin.iml
generated
Normal file
9
.idea/IC-Coder-Plugin.iml
generated
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
16
.idea/codeStyles/Project.xml
generated
Normal file
16
.idea/codeStyles/Project.xml
generated
Normal file
@ -0,0 +1,16 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<JSCodeStyleSettings version="0">
|
||||
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
||||
</JSCodeStyleSettings>
|
||||
<JavaCodeStyleSettings>
|
||||
<option name="ENABLE_JAVADOC_FORMATTING" value="false" />
|
||||
</JavaCodeStyleSettings>
|
||||
<codeStyleSettings language="JavaScript">
|
||||
<option name="IF_BRACE_FORCE" value="3" />
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
||||
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||
<option name="FOR_BRACE_FORCE" value="3" />
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</state>
|
||||
</component>
|
||||
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
||||
6
.idea/misc.xml
generated
Normal file
6
.idea/misc.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" default="true" project-jdk-name="openjdk-25" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/IC-Coder-Plugin.iml" filepath="$PROJECT_DIR$/.idea/IC-Coder-Plugin.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
90
CLAUDE.md
Normal file
90
CLAUDE.md
Normal file
@ -0,0 +1,90 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
IC Coder Plugin 是一个 VS Code 扩展,为 Verilog/FPGA 开发提供智能辅助功能,包括代码生成、文件操作、iverilog 仿真和 VCD 波形查看。
|
||||
|
||||
## Build Commands
|
||||
|
||||
```bash
|
||||
# 安装依赖
|
||||
pnpm install
|
||||
|
||||
# 编译 (开发模式)
|
||||
pnpm run compile
|
||||
|
||||
# 监听模式编译
|
||||
pnpm run watch
|
||||
|
||||
# 生产环境打包
|
||||
pnpm run package
|
||||
|
||||
# 代码检查
|
||||
pnpm run lint
|
||||
|
||||
# 运行测试
|
||||
pnpm run test
|
||||
|
||||
# 编译测试文件
|
||||
pnpm run compile-tests
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
- 按 F5 在 VS Code 中启动调试模式
|
||||
- 使用 webpack 打包,入口文件为 `src/extension.ts`
|
||||
- 输出目录为 `dist/`
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
src/
|
||||
├── extension.ts # 插件入口,注册命令和视图
|
||||
├── panels/
|
||||
│ ├── ICHelperPanel.ts # 主聊天面板 (WebviewPanel)
|
||||
│ └── VCDViewerPanel.ts # VCD 波形查看器面板
|
||||
├── views/
|
||||
│ ├── ICViewProvider.ts # 侧边栏视图提供者
|
||||
│ └── webviewContent.ts # Webview HTML 内容 (大文件,使用搜索)
|
||||
├── utils/
|
||||
│ ├── messageHandler.ts # 消息处理核心逻辑 (大文件,使用搜索)
|
||||
│ ├── iverilogRunner.ts # iverilog 编译和仿真执行
|
||||
│ ├── chatHistoryManager.ts # 会话历史管理
|
||||
│ ├── createFiles.ts # 文件创建工具
|
||||
│ └── readFiles.ts # 文件读取工具
|
||||
├── types/
|
||||
│ └── chatHistory.ts # 消息类型定义 (LangChain4j 格式)
|
||||
└── test/ # 测试文件
|
||||
```
|
||||
|
||||
### Key Components
|
||||
|
||||
**消息流程**: Webview -> `onDidReceiveMessage` -> `messageHandler.ts` -> 后端处理 -> `panel.webview.postMessage` -> Webview
|
||||
|
||||
**消息类型** (`src/types/chatHistory.ts`):
|
||||
- `MessageType.SYSTEM` / `USER` / `AI` / `TOOL_EXECUTION_RESULT`
|
||||
- 兼容 LangChain4j 格式
|
||||
|
||||
**iverilog 集成** (`tools/iverilog/`):
|
||||
- 内置 Windows x64 版本的 iverilog/vvp
|
||||
- 通过 `IVERILOG_ROOT` 环境变量配置库路径
|
||||
- 支持命令: "生成 VCD"、"运行仿真"、"生成波形"
|
||||
|
||||
## VS Code Extension Points
|
||||
|
||||
- 命令: `ic-coder.openPanel`, `ic-coder.openChat`, `ic-coder.openVCDViewer`
|
||||
- 侧边栏视图: `ic-coder.mainView`
|
||||
- 激活事件: `onLanguage:verilog`, `onLanguage:vhdl`, `onStartupFinished`
|
||||
|
||||
## Dependencies
|
||||
|
||||
- `vcdrom`, `vcd-stream`, `waveql` - VCD 波形处理
|
||||
- `@wavedrom/doppler`, `onml` - 波形渲染
|
||||
- `iconv-lite` - 编码转换
|
||||
|
||||
## Notes
|
||||
|
||||
- `webviewContent.ts` 和 `messageHandler.ts` 文件较大,建议使用搜索而非完整读取
|
||||
- 当前仅支持 Windows 平台的 iverilog,其他平台需用户自行安装
|
||||
@ -97,7 +97,7 @@
|
||||
"properties": {
|
||||
"icCoder.backendUrl": {
|
||||
"type": "string",
|
||||
"default": "http://192.168.1.108:2233",
|
||||
"default": "http://localhost:2233",
|
||||
"description": "后端服务地址"
|
||||
},
|
||||
"icCoder.timeout": {
|
||||
|
||||
@ -13,7 +13,7 @@ import type { DialogRequest, ToolCallRequest, AskUserEvent } from '../types/api'
|
||||
* 消息段落类型
|
||||
*/
|
||||
export interface MessageSegment {
|
||||
type: 'text' | 'tool' | 'question';
|
||||
type: 'text' | 'tool' | 'question' | 'agent';
|
||||
content?: string;
|
||||
toolName?: string;
|
||||
toolStatus?: 'running' | 'success' | 'error';
|
||||
@ -21,6 +21,22 @@ export interface MessageSegment {
|
||||
askId?: string;
|
||||
question?: string;
|
||||
options?: string[];
|
||||
// 智能体相关字段
|
||||
agentId?: string;
|
||||
agentName?: string;
|
||||
agentStatus?: 'running' | 'completed' | 'error';
|
||||
agentSteps?: AgentStep[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 智能体执行步骤
|
||||
*/
|
||||
export interface AgentStep {
|
||||
step: number;
|
||||
toolName: string;
|
||||
toolInput?: unknown;
|
||||
toolResult?: string;
|
||||
status: 'running' | 'completed' | 'error';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,28 +180,42 @@ export class DialogSession {
|
||||
onToolCall: async (data: ToolCallRequest) => {
|
||||
const toolName = data.params.name;
|
||||
console.log('[DialogSession] onToolCall:', toolName);
|
||||
// 检查是否已经有相同的工具段落(可能由 onToolStart 添加)
|
||||
const lastToolSegment = this.segments.filter(s => s.type === 'tool').pop();
|
||||
if (lastToolSegment && lastToolSegment.toolName === toolName && lastToolSegment.toolStatus === 'running') {
|
||||
console.log('[DialogSession] onToolCall: 跳过重复的工具段落:', toolName);
|
||||
|
||||
// 检查是否有活跃的智能体(如果有,工具执行会显示在智能体卡片内,不需要单独显示)
|
||||
const hasActiveAgent = this.segments.some(
|
||||
s => s.type === 'agent' && s.agentStatus === 'running'
|
||||
);
|
||||
|
||||
if (hasActiveAgent) {
|
||||
console.log('[DialogSession] onToolCall: 智能体执行中,跳过工具段落:', toolName);
|
||||
} else {
|
||||
this.addToolSegment(toolName, 'running');
|
||||
// 实时发送段落更新
|
||||
callbacks.onSegmentUpdate?.(this.segments);
|
||||
// 检查是否已经有相同的工具段落(可能由 onToolStart 添加)
|
||||
const lastToolSegment = this.segments.filter(s => s.type === 'tool').pop();
|
||||
if (lastToolSegment && lastToolSegment.toolName === toolName && lastToolSegment.toolStatus === 'running') {
|
||||
console.log('[DialogSession] onToolCall: 跳过重复的工具段落:', toolName);
|
||||
} else {
|
||||
this.addToolSegment(toolName, 'running');
|
||||
// 实时发送段落更新
|
||||
callbacks.onSegmentUpdate?.(this.segments);
|
||||
}
|
||||
}
|
||||
|
||||
// 注意:不在这里调用 callbacks.onToolStart,避免与 onToolStart 事件重复
|
||||
try {
|
||||
await executeToolCall(data, this.toolContext);
|
||||
this.updateToolSegment(toolName, 'success', '执行完成');
|
||||
// 实时发送段落更新
|
||||
callbacks.onSegmentUpdate?.(this.segments);
|
||||
if (!hasActiveAgent) {
|
||||
this.updateToolSegment(toolName, 'success', '执行完成');
|
||||
// 实时发送段落更新
|
||||
callbacks.onSegmentUpdate?.(this.segments);
|
||||
}
|
||||
// 也不调用 callbacks.onToolComplete,避免重复
|
||||
} catch (error) {
|
||||
const errorMsg = error instanceof Error ? error.message : '未知错误';
|
||||
this.updateToolSegment(toolName, 'error', errorMsg);
|
||||
if (!hasActiveAgent) {
|
||||
this.updateToolSegment(toolName, 'error', errorMsg);
|
||||
callbacks.onSegmentUpdate?.(this.segments);
|
||||
}
|
||||
callbacks.onToolError?.(toolName, errorMsg);
|
||||
// 实时发送段落更新
|
||||
callbacks.onSegmentUpdate?.(this.segments);
|
||||
}
|
||||
},
|
||||
|
||||
@ -257,6 +287,69 @@ export class DialogSession {
|
||||
callbacks.onNotification?.(data.message);
|
||||
},
|
||||
|
||||
// 智能体事件处理
|
||||
onAgentStart: (data) => {
|
||||
console.log('[DialogSession] onAgentStart:', data.agentId);
|
||||
this.finalizeTextSegment();
|
||||
this.segments.push({
|
||||
type: 'agent',
|
||||
agentId: data.agentId,
|
||||
agentName: data.agentName,
|
||||
content: data.instruction,
|
||||
agentStatus: 'running',
|
||||
agentSteps: []
|
||||
});
|
||||
callbacks.onSegmentUpdate?.(this.segments);
|
||||
},
|
||||
|
||||
onAgentProgress: (data) => {
|
||||
console.log('[DialogSession] onAgentProgress:', data.agentId, data.step, data.status);
|
||||
const agentSegment = this.segments.find(
|
||||
s => s.type === 'agent' && s.agentId === data.agentId
|
||||
);
|
||||
if (agentSegment && agentSegment.agentSteps) {
|
||||
if (data.status === 'running') {
|
||||
agentSegment.agentSteps.push({
|
||||
step: data.step,
|
||||
toolName: data.toolName,
|
||||
toolInput: data.toolInput,
|
||||
status: 'running'
|
||||
});
|
||||
} else {
|
||||
const step = agentSegment.agentSteps.find(s => s.step === data.step);
|
||||
if (step) {
|
||||
step.status = data.status;
|
||||
step.toolResult = data.toolResult;
|
||||
}
|
||||
}
|
||||
callbacks.onSegmentUpdate?.(this.segments);
|
||||
}
|
||||
},
|
||||
|
||||
onAgentComplete: (data) => {
|
||||
console.log('[DialogSession] onAgentComplete:', data.agentId);
|
||||
const agentSegment = this.segments.find(
|
||||
s => s.type === 'agent' && s.agentId === data.agentId
|
||||
);
|
||||
if (agentSegment) {
|
||||
agentSegment.agentStatus = 'completed';
|
||||
agentSegment.content = data.summary;
|
||||
callbacks.onSegmentUpdate?.(this.segments);
|
||||
}
|
||||
},
|
||||
|
||||
onAgentError: (data) => {
|
||||
console.log('[DialogSession] onAgentError:', data.agentId, data.error);
|
||||
const agentSegment = this.segments.find(
|
||||
s => s.type === 'agent' && s.agentId === data.agentId
|
||||
);
|
||||
if (agentSegment) {
|
||||
agentSegment.agentStatus = 'error';
|
||||
agentSegment.content = data.error;
|
||||
callbacks.onSegmentUpdate?.(this.segments);
|
||||
}
|
||||
},
|
||||
|
||||
onOpen: () => {
|
||||
console.log('[DialogSession] SSE 连接已建立');
|
||||
},
|
||||
|
||||
@ -117,6 +117,13 @@ async function executeFileRead(args: FileReadArgs): Promise<string> {
|
||||
*/
|
||||
async function executeFileWrite(args: FileWriteArgs): Promise<string> {
|
||||
await createOrOverwriteFile(args.path, args.content);
|
||||
|
||||
// Verilog 文件添加知识图谱提示
|
||||
const isVerilogFile = args.path.endsWith('.v') || args.path.endsWith('.sv');
|
||||
if (isVerilogFile) {
|
||||
return `文件已写入: ${args.path}\n\n[提示] 如有新信号或规则,请更新知识图谱`;
|
||||
}
|
||||
|
||||
return `文件已写入: ${args.path}`;
|
||||
}
|
||||
|
||||
@ -154,6 +161,12 @@ async function executeFileDelete(args: FileDeleteArgs): Promise<string> {
|
||||
// 删除文件
|
||||
fs.unlinkSync(absolutePath);
|
||||
|
||||
// Verilog 文件添加知识图谱提示
|
||||
const isVerilogFile = filePath.endsWith('.v') || filePath.endsWith('.sv');
|
||||
if (isVerilogFile) {
|
||||
return `文件已删除: ${filePath}\n\n[提示] 请删除知识图谱中相关节点`;
|
||||
}
|
||||
|
||||
return `文件已删除: ${filePath}`;
|
||||
}
|
||||
|
||||
|
||||
@ -528,6 +528,89 @@ export function getMessageAreaStyles(): string {
|
||||
border-radius: 4px;
|
||||
font-size: 12px;}
|
||||
|
||||
/* 智能体卡片样式 */
|
||||
.segment-agent {
|
||||
margin: 8px 0;
|
||||
}
|
||||
.agent-card {
|
||||
border: 1px solid var(--vscode-input-border);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background: var(--vscode-editor-background);
|
||||
}
|
||||
.agent-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 12px;
|
||||
background: var(--vscode-sideBar-background);
|
||||
border-bottom: 1px solid var(--vscode-input-border);
|
||||
}
|
||||
.agent-icon {
|
||||
font-size: 16px;
|
||||
}
|
||||
.agent-name {
|
||||
font-weight: 500;
|
||||
flex: 1;
|
||||
}
|
||||
.agent-status {
|
||||
font-size: 11px;
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.agent-status.running {
|
||||
background: var(--vscode-inputValidation-infoBackground);
|
||||
color: var(--vscode-inputValidation-infoForeground);
|
||||
}
|
||||
.agent-status.completed {
|
||||
background: #28a745;
|
||||
color: white;
|
||||
}
|
||||
.agent-status.error {
|
||||
background: #dc3545;
|
||||
color: white;
|
||||
}
|
||||
.agent-body {
|
||||
padding: 8px;
|
||||
}
|
||||
.agent-steps-container {
|
||||
max-height: 150px;
|
||||
overflow-y: auto;
|
||||
font-size: 12px;
|
||||
}
|
||||
.agent-step {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 4px;
|
||||
background: var(--vscode-list-hoverBackground);
|
||||
}
|
||||
.agent-step:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.step-icon {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.step-name {
|
||||
font-weight: 500;
|
||||
color: var(--vscode-foreground);
|
||||
}
|
||||
.step-result {
|
||||
color: var(--vscode-descriptionForeground);
|
||||
font-size: 11px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.agent-step-placeholder {
|
||||
color: var(--vscode-descriptionForeground);
|
||||
font-style: italic;
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
${getWaveformPreviewContent()}
|
||||
`;
|
||||
}
|
||||
@ -903,6 +986,41 @@ export function getMessageAreaScript(): string {
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
} else if (segment.type === 'agent') {
|
||||
// 智能体卡片渲染
|
||||
segmentDiv.className += ' segment-agent';
|
||||
const statusText = segment.agentStatus === 'completed' ? '完成'
|
||||
: segment.agentStatus === 'error' ? '错误' : '执行中';
|
||||
const statusClass = segment.agentStatus || 'running';
|
||||
|
||||
const stepsHtml = (segment.agentSteps || []).map(step => {
|
||||
const icon = step.status === 'completed' ? '✅' : step.status === 'error' ? '❌' : '🔄';
|
||||
const result = step.toolResult ? \`: \${step.toolResult.substring(0, 50)}\${step.toolResult.length > 50 ? '...' : ''}\` : '';
|
||||
return \`<div class="agent-step"><span class="step-icon">\${icon}</span><span class="step-name">\${step.toolName}</span><span class="step-result">\${result}</span></div>\`;
|
||||
}).join('');
|
||||
|
||||
segmentDiv.innerHTML = \`
|
||||
<div class="agent-card">
|
||||
<div class="agent-header">
|
||||
<span class="agent-icon">🤖</span>
|
||||
<span class="agent-name">\${segment.agentName || '智能体'}</span>
|
||||
<span class="agent-status \${statusClass}">\${statusText}</span>
|
||||
</div>
|
||||
<div class="agent-body">
|
||||
<div class="agent-steps-container">
|
||||
\${stepsHtml || '<div class="agent-step-placeholder">等待执行...</div>'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
\`;
|
||||
|
||||
// 自动滚动到最新步骤
|
||||
setTimeout(() => {
|
||||
const container = segmentDiv.querySelector('.agent-steps-container');
|
||||
if (container) {
|
||||
container.scrollTop = container.scrollHeight;
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
currentSegmentedMessage.appendChild(segmentDiv);
|
||||
@ -1045,6 +1163,33 @@ export function getMessageAreaScript(): string {
|
||||
</div>
|
||||
</div>
|
||||
\`;
|
||||
} else if (segment.type === 'agent') {
|
||||
// 智能体卡片渲染
|
||||
segmentDiv.className += ' segment-agent';
|
||||
const statusText = segment.agentStatus === 'completed' ? '完成'
|
||||
: segment.agentStatus === 'error' ? '错误' : '执行中';
|
||||
const statusClass = segment.agentStatus || 'running';
|
||||
|
||||
const stepsHtml = (segment.agentSteps || []).map(step => {
|
||||
const icon = step.status === 'completed' ? '✅' : step.status === 'error' ? '❌' : '🔄';
|
||||
const result = step.toolResult ? \`: \${step.toolResult.substring(0, 50)}\${step.toolResult.length > 50 ? '...' : ''}\` : '';
|
||||
return \`<div class="agent-step"><span class="step-icon">\${icon}</span><span class="step-name">\${step.toolName}</span><span class="step-result">\${result}</span></div>\`;
|
||||
}).join('');
|
||||
|
||||
segmentDiv.innerHTML = \`
|
||||
<div class="agent-card">
|
||||
<div class="agent-header">
|
||||
<span class="agent-icon">🤖</span>
|
||||
<span class="agent-name">\${segment.agentName || '智能体'}</span>
|
||||
<span class="agent-status \${statusClass}">\${statusText}</span>
|
||||
</div>
|
||||
<div class="agent-body">
|
||||
<div class="agent-steps-container">
|
||||
\${stepsHtml || '<div class="agent-step-placeholder">等待执行...</div>'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
\`;
|
||||
}
|
||||
|
||||
container.appendChild(segmentDiv);
|
||||
|
||||
@ -377,6 +377,7 @@ export function getWebviewContent(iconUri?: string): string {
|
||||
<button class="quick-btn" onclick="quickAction('counter')">生成计数器</button>
|
||||
<button class="quick-btn" onclick="quickAction('fsm')">生成状态机</button>
|
||||
<button class="quick-btn" onclick="quickAction('testbench')">生成测试平台</button>
|
||||
<button class="quick-btn" onclick="quickAction('explore')">知识探索</button>
|
||||
</div>
|
||||
|
||||
${getInputAreaContent()}
|
||||
@ -399,7 +400,8 @@ export function getWebviewContent(iconUri?: string): string {
|
||||
const questions = {
|
||||
counter: '生成一个4位同步计数器',
|
||||
fsm: '生成一个状态机',
|
||||
testbench: '生成测试平台'
|
||||
testbench: '生成测试平台',
|
||||
explore: '请启动知识探索智能体,分析当前项目结构'
|
||||
};
|
||||
if (questions[type]) {
|
||||
messageInput.value = questions[type];
|
||||
|
||||
Reference in New Issue
Block a user