mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-05-04 22:13:59 +00:00
Compare commits
1 Commits
main
...
260504-fea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0efb8a2c39 |
32
.monkeycode/MEMORY.md
Normal file
32
.monkeycode/MEMORY.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# 用户指令记忆
|
||||
|
||||
本文件记录了用户的指令、偏好和教导,用于在未来的交互中提供参考。
|
||||
|
||||
## 格式
|
||||
|
||||
### 用户指令条目
|
||||
用户指令条目应遵循以下格式:
|
||||
|
||||
[用户指令摘要]
|
||||
- Date: [YYYY-MM-DD]
|
||||
- Context: [提及的场景或时间]
|
||||
- Instructions:
|
||||
- [用户教导或指示的内容,逐行描述]
|
||||
|
||||
### 项目知识条目
|
||||
Agent 在任务执行过程中发现的条目应遵循以下格式:
|
||||
|
||||
[项目知识摘要]
|
||||
- Date: [YYYY-MM-DD]
|
||||
- Context: Agent 在执行 [具体任务描述] 时发现
|
||||
- Category: [代码结构|代码模式|代码生成|构建方法|测试方法|依赖关系|环境配置]
|
||||
- Instructions:
|
||||
- [具体的知识点,逐行描述]
|
||||
|
||||
## 去重策略
|
||||
- 添加新条目前,检查是否存在相似或相同的指令
|
||||
- 若发现重复,跳过新条目或与已有条目合并
|
||||
- 合并时,更新上下文或日期信息
|
||||
- 这有助于避免冗余条目,保持记忆文件整洁
|
||||
|
||||
## 条目
|
||||
@@ -219,6 +219,8 @@ public class ChatServiceFacade implements IChatService {
|
||||
|
||||
*/
|
||||
private SseEmitter handleThinkingMode(ChatRequest chatRequest) {
|
||||
String npxCommand = resolveNpxCommand();
|
||||
|
||||
// 配置监督者模型
|
||||
OpenAiChatModel plannerModel = OpenAiChatModel.builder()
|
||||
.baseUrl(chatRequest.getChatModelVo().getApiHost())
|
||||
@@ -228,7 +230,7 @@ public class ChatServiceFacade implements IChatService {
|
||||
|
||||
// Bing 搜索 MCP 客户端
|
||||
McpTransport bingTransport = new StdioMcpTransport.Builder()
|
||||
.command(List.of("C:\\Program Files\\nodejs\\npx.cmd", "-y", "bing-cn-mcp"))
|
||||
.command(List.of(npxCommand, "-y", "bing-cn-mcp"))
|
||||
.logEvents(true)
|
||||
.build();
|
||||
|
||||
@@ -240,7 +242,7 @@ public class ChatServiceFacade implements IChatService {
|
||||
|
||||
// Playwright MCP 客户端 - 浏览器自动化工具
|
||||
McpTransport playwrightTransport = new StdioMcpTransport.Builder()
|
||||
.command(List.of("C:\\Program Files\\nodejs\\npx.cmd", "-y", "@playwright/mcp@latest"))
|
||||
.command(List.of(npxCommand, "-y", "@playwright/mcp@latest"))
|
||||
.logEvents(true)
|
||||
.build();
|
||||
|
||||
@@ -253,7 +255,7 @@ public class ChatServiceFacade implements IChatService {
|
||||
// 允许 AI 读取、写入、搜索文件(基于当前项目根目录)
|
||||
String userDir = System.getProperty("user.dir");
|
||||
McpTransport filesystemTransport = new StdioMcpTransport.Builder()
|
||||
.command(List.of("C:\\Program Files\\nodejs\\npx.cmd", "-y",
|
||||
.command(List.of(npxCommand, "-y",
|
||||
"@modelcontextprotocol/server-filesystem", userDir))
|
||||
.logEvents(true)
|
||||
|
||||
@@ -344,6 +346,18 @@ public class ChatServiceFacade implements IChatService {
|
||||
return chatRequest.getEmitter();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据运行平台选择 npx 命令,避免 Linux/macOS 环境下固定使用 npx.cmd 导致失败。
|
||||
*/
|
||||
private String resolveNpxCommand() {
|
||||
String customNpxCommand = System.getenv("MCP_NPX_COMMAND");
|
||||
if (StringUtils.isNotBlank(customNpxCommand)) {
|
||||
return customNpxCommand;
|
||||
}
|
||||
String osName = System.getProperty("os.name", "").toLowerCase();
|
||||
return osName.contains("win") ? "npx.cmd" : "npx";
|
||||
}
|
||||
|
||||
/**
|
||||
* 支持外部 handler 的对话接口(跨模块调用)
|
||||
* 同时发送到 SSE 和外部 handler
|
||||
@@ -618,4 +632,3 @@ public class ChatServiceFacade implements IChatService {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
52
scripts/continuous_runner.py
Normal file
52
scripts/continuous_runner.py
Normal file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Run a shell command continuously for a fixed duration.
|
||||
|
||||
Example:
|
||||
python3 scripts/continuous_runner.py --cmd "mvn -pl ruoyi-modules/ruoyi-chat -DskipTests compile"
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import subprocess
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(description="Run command continuously with retry")
|
||||
parser.add_argument("--cmd", required=True, help="Command to run each round")
|
||||
parser.add_argument("--minutes", type=int, default=30, help="Total running minutes")
|
||||
parser.add_argument("--interval", type=int, default=5, help="Seconds between rounds")
|
||||
parser.add_argument("--stop-on-success", action="store_true", help="Stop after first success")
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main() -> int:
|
||||
args = parse_args()
|
||||
deadline = datetime.now() + timedelta(minutes=args.minutes)
|
||||
|
||||
print(f"start={datetime.now().isoformat(timespec='seconds')}")
|
||||
print(f"end={deadline.isoformat(timespec='seconds')}")
|
||||
print(f"cmd={args.cmd}")
|
||||
|
||||
round_no = 0
|
||||
while datetime.now() < deadline:
|
||||
round_no += 1
|
||||
print(f"\n[{datetime.now().isoformat(timespec='seconds')}] round={round_no}")
|
||||
result = subprocess.run(args.cmd, shell=True)
|
||||
print(f"exit_code={result.returncode}")
|
||||
|
||||
if result.returncode == 0 and args.stop_on_success:
|
||||
print("stop_on_success=true, exiting")
|
||||
return 0
|
||||
|
||||
if datetime.now() < deadline:
|
||||
time.sleep(max(0, args.interval))
|
||||
|
||||
print(f"done={datetime.now().isoformat(timespec='seconds')}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user