#### 1. AI agent

Agent模块负责处理request工作流，生成prompt与LLM交互。

> Agent代码:
> <http://ishangsf.com:8100/ken/agent>
>
> websocket接口地址:
> <ws://47.117.75.243:8080/ws>
>
> 接口文档:
> <http://ishangsf.com:8100/ken/agent/src/branch/main/README.md>
>
> 前端接口测试案例代码:
> <http://ishangsf.com:8100/ken/agent/src/branch/main/examples>
> 
> 测试api_key: “***simpletest2025***_xxxx” xxxx为任意字符串

Agent 有三模式运行，由plugin在request的model参数决定，运行模式在交互过程对agent是透明的。

> 1. agent local model：就是agent调用本地部署的LLM模型
> 2. agent remote api：就是agent调用openai或deepseek等外部服务的api (改下llm就看实现)
> 3. plugin remote api：由plugin调用openai或deepseek等外部服务的api (未实现，要改ideservice)

##### 1.1 安装与运行

```shell
# linux
make
./build/bin/agent run

# windows
go build -o ../build/bin/agent.exe src/main.go
./build/bin/agent.exe run
```

##### 1.2系统框架

<img src="assets/架构.png" alt="drawing" style="width:700px;"/>

ideservice 是须要plugin提供给agent的一些获取IDE信息的基础功能，为穿透NAT需要websocket连接。

##### 1.3 workflow

```mermaid
sequenceDiagram
    plugin->>agent: request
    agent-->>ideservice: more info
    ideservice-->>agent: file, symbol
    agent->>plugin: result
```

agent有可能会多次向ideservice询问更多的信息，这对于plugin是透明的。


##### 1.4 Task Pool

章节2中所有带cmd参数带前缀“exec”的request都是涉及LLM模型调用的。
Agent用一个FIFO队列缓存所有用户的未处理任务，当队列长度过大时agent会拒绝新来的任务。
同一APIkey同时能建立5个链接，一个连接只能有一个任务在队列，同时提交两个task, 前一个会被取消。

#### 2. Agent协议

plugin通过websocket连接agent。如果使用https, 需要设置client接受agent的https认证证书。

##### 2.1 身份认证

建立连接时带header "X-Api-Key" : api_key，
或 uri带api_key参数： ws://47.117.75.243:8080/ws?api_key=simpletest2025_001
如果api_key不对agent主动断开连接

```javascript
let client = new ws.WebSocket('wss://host:8080/ws', {headers: {
  ["X-Api-Key"]: "simpletest2025_001",
}}) 
```

##### 2.2 获取Agent支持的模型 （list_model）

```javascript
request:
{
    "request_id": 123,            // 随机生成 （必填）
    "cmd"       : "list_model"
}

response:
{
    "request_id": 123,                                            // 同request
    "models"    : ["local deepseek-R1:32b", "deepseek-R1:32b"]    // （必填）
}
```

##### 2.3 生成代码解释 (exec_explain)

```javascript
request:
{
    "cmd"          : "exec_explain",
    "request_id"   : 123,                       // 随机生成 （必填）
    "language"     : "en",                      // 语言, en-英文, zh-中文，默认为 en  （可选）
    "selected_text": text_context,              // 选取的代码片段 （必填）
    "visible_text" : text_context,              // ide窗口可见的代码片段 （必填）
    "model"        : "local deepseek-r1:32b",   //（必填）
    "stream"       : false                      // stream方式返回（可选）
}

text_context:
{
    "filepath": "example\\\\game.py",  // 文件路径 
    "range": {
	    "start": { "line": 33, "character": 0},   // 从33行0字符开始
	    "end"  : { "line": 45, "character": 41}   // 到45行41字符结束
	},
    "text": "..." // 源码片段
}

成功返回:
{
    "request_id"   : 123,     // 同request（必填）
    "msg"          : "",      // 返回内容
    "stream_seq_id": 0,       // stream=true时才有, 从0开始（可选）
    "stream_finsh" : false,   // stream=true时才有, true-stream结束（可选）
}

失败返回:
{
    "request_id": 123,         // 同request（必填）
    "error"     : "cancelled"  // 出错信息，没有就是调用成功（必填）
}
```

##### 2.4 生成代码文档 (exec_docstring)

目前只支持python

```javascript
request:
{
    "cmd"          : "exec_docstring",
    "request_id"   : 123,                       // 随机生成 （必填）
    "language"     : "en",                      // 语言, en-英文, zh-中文，默认为 en  （可选）
    "selected_text": text_context,              // 选取的代码片段 （必填）
    "model"        : "local deepseek-r1:32b",   //（必填）
    "stream"       : false                      // stream方式返回 （可选）
}

返回json格式同 2.3
```

##### 2.5 代码优化 (exec_optimize)

//TODO 未测试效果, prompt该如何描述优化？

```javascript
request:
{
    "cmd"          : "exec_optimize",
    "request_id"   : 123,                // 随机生成 （必填）
    "language"     : "en",               // 语言, en-英文, zh-中文，默认为 en  （可选）
    "selected_text": "",                 // 选取的代码片段 （必填）
    "model"        : "local deepseek-r1:32b", //（必填）
    "stream"       : false               // stream方式返回 （可选）
}

返回json格式同 2.3
```

##### 2.6 生成单元测试代码 (exec_fix)

```javascript
request:
{
    "cmd"          : "exec_fix",
    "request_id"   : 123,                // 随机生成 （必填）
    "language"     : "en",               // 语言, en-英文, zh-中文，默认为 en  （可选）
    "selected_text": "",                 // 选取的代码片段 （必填）
    "model"        : "local deepseek-r1:32b",//（必填）
    "stream"       : false               // stream方式返回 （可选）
}

返回json格式同 2.3
```

##### 2.7 生成单元测试代码 (exec_unittest)

// TODO 与ideservice交互

目前仅支持英文回复, 流程对devchat做了简化

```mermaid
sequenceDiagram
    plugin->>agent: exec_unittest_recommend 请求测试建议
    agent->>plugin: 测试建议
    plugin->>agent: exec_unittest_code 请求测试代码
    plugin->>agent: 测试代码
```

```javascript
请求测试建议:
{
    "cmd"       : "exec_unittest_recommend",
    "request_id": 123,  // 随机生成 （必填）
    "language"  : "en", // 语言, en-英文, zh-中文，默认为 en  （可选）

    "user_prompt"  : "",  // 用户定制化描述 （可选）
    "file_content" : "..."                   // 整个文件内容（必填）
    "filepath"     : "\\example\\game.py",   // 文件路径（必填）
    "func_name"    : "next_turn",            // 函数名 （必填）
    "func_location": {   // 函数位置（必填）
        "start": { "line": 33, "character": 0},
        "end"  : { "line": 45, "character": 41},
	},
    "func_symbols": [ // function 内的所以变量名和函数名 （必填）
        {
            "name": "next_turn", 
            "kind": "Function", 
            "range": {   // 位置
                "start": { "line": 33, "character": 0},
                "end"  : { "line": 45, "character": 41}
            },    
            "children": [
                {
                    "name": "WIDTH", 
                    "kind": "Constant", 
                    "range": {   // 位置
                        "start": { "line": 33, "character": 0},
                        "end"  : { "line": 45, "character": 41}
                    },
                    "children": [
                        ...
                    ]
                },
            ]
        },
        ...
    ],           
    "model"           : "local deepseek-r1:32b",   //（必填）
    "stream"          : false                      // stream方式返回 （可选）
}
返回json格式同 2.3

请求测试代码：
{
    "cmd"           : "exec_unittest_code",
    "request_id"    : 123,                     // 随机生成 （必填）
    "language"      : "en",                    // 语言, en-英文, zh-中文，默认为 en  （可选）
    "test_cases_str": "",                      // exec_unittest_recommend 提供的 （必填）

    // 如果task_id为空须填写：
    "function_name"    : ""               // 函数名 （可选）
    "user_prompt"      : ""               // 定制化描述  （可选）
    "file_path"        : "./src/test.py"  // 文件在项目里的相对路径 （可选）
    "relevant_content" : ""               // the relevant source code of the function （可选）
    "reference_content": ""               // the relevant source code of the function （可选）

    "stream": false  // stream方式返回（可选）
}
返回json格式同 2.3
```

##### 2.8 和大模型对话 (exec_chat)

```javascript
request:
{
    "cmd"       : "exec_chat",
    "request_id": 123,                       // 随机生成 （必填）
    "msg"       : "",                        // 内容 （必填）
    "model"     : "local deepseek-r1:32b",   //（必填）
    "stream"    : false                      // stream方式返回（可选）
}
返回json格式同 2.3
```

#### 3. ide_service协议

开发优先级低，解决2.7“与ideservice交互”问题前未用到

是由 agent 向 ide_service 请求，参考
<https://github.com/devchat-ai/devchat-vscode/blob/main/src/ide_services/services.ts>

只保留以下服务，

```javascript
    "/get_document_symbols": {
        keys: ["abspath"],
        handler: getDocumentSymbols,
    },
    "/find_def_locations": {
        keys: ["abspath", "line", "character"],
        handler: findDefinitionLocations,
    },
    "/find_type_def_locations": {
        keys: ["abspath", "line", "character"],
        handler: findTypeDefinitionLocations,
    },
```

#### 3. 功能覆盖

<img src="assets/功能覆盖.png"/>

