ga: map Bash/PowerShell tool calls to code_run; conductor: restrict CORS/WS origin & trusted host to localhost; mem SOP: prune stale facts, L2 keeps file pointers
This commit is contained in:
1 parent
be17b0adc5
commit
5ec4b12b63
3 files changed
+20
-6
No files matched your search
@@ -16,6 +16,7 @@ def try_call_generator(func, *args, **kwargs):
|
|||||||
class BaseHandler:
|
class BaseHandler:
|
||||||
def turn_end_callback(self, response, tool_calls, tool_results, turn, next_prompt, exit_reason): return next_prompt
|
def turn_end_callback(self, response, tool_calls, tool_results, turn, next_prompt, exit_reason): return next_prompt
|
||||||
def dispatch(self, tool_name, args, response, index=0, tool_num=1):
|
def dispatch(self, tool_name, args, response, index=0, tool_num=1):
|
||||||
|
if tool_name in ('Bash', 'PowerShell'): tool_name, args = 'code_run', {**args, 'type': tool_name.lower(), 'script': args.get('command') or args.get('cmd') or args.get('script') or ''}
|
||||||
method_name = f"do_{tool_name}"
|
method_name = f"do_{tool_name}"
|
||||||
if hasattr(self, method_name):
|
if hasattr(self, method_name):
|
||||||
args['_index'] = index; args['_tool_num'] = tool_num
|
args['_index'] = index; args['_tool_num'] = tool_num
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from contextlib import asynccontextmanager, suppress
|
|||||||
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Request, HTTPException
|
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Request, HTTPException
|
||||||
from fastapi.responses import FileResponse, PlainTextResponse, JSONResponse
|
from fastapi.responses import FileResponse, PlainTextResponse, JSONResponse
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
from starlette.middleware.trustedhost import TrustedHostMiddleware
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
FRONTENDS_DIR = os.path.dirname(os.path.abspath(__file__))
|
FRONTENDS_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
@@ -133,7 +134,11 @@ async def lifespan(app: FastAPI):
|
|||||||
|
|
||||||
|
|
||||||
app = FastAPI(title="Conductor", lifespan=lifespan)
|
app = FastAPI(title="Conductor", lifespan=lifespan)
|
||||||
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"])
|
# 只放行本机页面(conductor.html 同源 / 桌面端 Tauri / vite dev),防恶意网页跨站调用
|
||||||
|
LOCAL_ORIGIN = re.compile(r"^(https?://(127\.0\.0\.1|localhost|\[::1\])(:\d+)?|tauri://localhost|https?://tauri\.localhost)$")
|
||||||
|
app.add_middleware(CORSMiddleware, allow_origin_regex=LOCAL_ORIGIN.pattern, allow_methods=["*"], allow_headers=["*"])
|
||||||
|
# 防 DNS rebinding;--key 远程模式或 ::1 监听时不启用
|
||||||
|
if not args.key and args.host != "::1": app.add_middleware(TrustedHostMiddleware, allowed_hosts=["127.0.0.1", "localhost"])
|
||||||
|
|
||||||
class RemoteAuth:
|
class RemoteAuth:
|
||||||
def __init__(self, app): self.app = app
|
def __init__(self, app): self.app = app
|
||||||
@@ -732,6 +737,8 @@ def api_approval(body: ApprovalIn):
|
|||||||
|
|
||||||
@app.websocket("/ws")
|
@app.websocket("/ws")
|
||||||
async def websocket(ws: WebSocket):
|
async def websocket(ws: WebSocket):
|
||||||
|
# WebSocket 不受 CORS 约束,需自行校验 Origin(非浏览器客户端不带 Origin,放行;--key 远程模式由 RemoteAuth 的 Basic 鉴权把关)
|
||||||
|
if (origin := ws.headers.get("origin")) and not args.key and not LOCAL_ORIGIN.match(origin): return await ws.close(code=1008)
|
||||||
await ws.accept()
|
await ws.accept()
|
||||||
ws_clients.add(ws)
|
ws_clients.add(ws)
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -7,18 +7,21 @@
|
|||||||
* **定义**:凡是经过行动验证的有效配置、避坑指南、关键路径,在重构(Refactoring/GC)时**严禁丢弃**。
|
* **定义**:凡是经过行动验证的有效配置、避坑指南、关键路径,在重构(Refactoring/GC)时**严禁丢弃**。
|
||||||
* **操作**:可以压缩文字、可以迁移层级(从 L2 移到 L3),但绝不能丢失信息的准确性和可追溯性。
|
* **操作**:可以压缩文字、可以迁移层级(从 L2 移到 L3),但绝不能丢失信息的准确性和可追溯性。
|
||||||
* 记忆修改时请极度小心,尽量不要overwrite或code run。只能少量patch,改不动宁愿不改。
|
* 记忆修改时请极度小心,尽量不要overwrite或code run。只能少量patch,改不动宁愿不改。
|
||||||
|
* 错误、过时信息不在保护范围内,应立刻遗忘(删除)而非在记忆中留下标记,除非转化为简短纠错经验
|
||||||
3. **禁止存储易变状态 (No Volatile State)**
|
3. **禁止存储易变状态 (No Volatile State)**
|
||||||
* **定义**:严禁存储随时间/会话高频变化的数据。
|
* **定义**:严禁存储随时间/会话高频变化的数据。
|
||||||
* **示例**:当前时间戳、临时 Session ID、正在运行的 PID、某个具体绝对路径、连接的设备信息
|
* **示例**:当前时间戳、临时 Session ID、正在运行的 PID、某个具体绝对路径、连接的设备信息
|
||||||
|
* 清理记忆时发现易变状态应立刻删除
|
||||||
4. **最小充分指针 (Minimum Sufficient Pointer)**
|
4. **最小充分指针 (Minimum Sufficient Pointer)**
|
||||||
* 上层只留能定位下层的最短标识,多一词即冗余。
|
* 上层只留能定位下层的最短标识,多一词即冗余
|
||||||
> **绝对禁止写入:非用户要求的模型固有臆想规定或限制,如“不准删除,需要备份,需要比对sha”等等**
|
* L4已经保留了所有会话记录,L2/L3仅允许归纳筛选后的精华信息
|
||||||
|
> **绝对禁止写入非用户要求的模型固有臆想规定或限制,如“不准删除,需要备份,需要比对sha”等等**
|
||||||
---
|
---
|
||||||
## 记忆层级架构
|
## 记忆层级架构
|
||||||
```
|
```
|
||||||
L1: global_mem_insight.txt (极简索引层 - 严格控制 ≤30 行)
|
L1: global_mem_insight.txt (极简索引层 - 严格控制 ≤30 行)
|
||||||
↓ 导航指向 (Pointer)
|
↓ 导航指向 (Pointer)
|
||||||
L2: global_mem.txt (事实库层 - 现短但会膨胀)
|
L2: global_mem.txt (精简事实+文件指针)
|
||||||
↓ 详细引用 (Reference)
|
↓ 详细引用 (Reference)
|
||||||
L3: ../memory/ (记录库层 - 包含 .md/.py 等各类文件)
|
L3: ../memory/ (记录库层 - 包含 .md/.py 等各类文件)
|
||||||
L4: ../memory/L4_raw_sessions/ (历史会话层 - scheduler反射自动收集,可定位过往上下文)
|
L4: ../memory/L4_raw_sessions/ (历史会话层 - scheduler反射自动收集,可定位过往上下文)
|
||||||
@@ -43,9 +46,11 @@ L4: ../memory/L4_raw_sessions/ (历史会话层 - scheduler反射自动收集,
|
|||||||
### L2:全局事实库 (global_mem.txt)
|
### L2:全局事实库 (global_mem.txt)
|
||||||
**职责**:存储全局环境性事实(路径、凭证、配置、常量等)。
|
**职责**:存储全局环境性事实(路径、凭证、配置、常量等)。
|
||||||
**特征**:
|
**特征**:
|
||||||
- 趋势:随环境扩展而膨胀(可接受)
|
- 趋势:随环境扩展而少量膨胀、大量事实只留事实文件路径
|
||||||
- 内容:按 `## [SECTION]` 组织的事实条目
|
- 内容:按 `## [SECTION]` 组织的事实条目
|
||||||
- 同步:变化时更新 L1 的相应 TOPIC 导航行,只能导航
|
- 同步:变化时更新 L1 的相应 TOPIC 导航行,只能导航
|
||||||
|
- 维护时过期事实应当清理/替换而非仅标注
|
||||||
|
- 同一事件大量事实应当另外使用文件存储,L2仅留文件路径
|
||||||
**禁止**:禁止存储易变状态、禁止存储猜测、严禁存储大模型可推理的通用常识
|
**禁止**:禁止存储易变状态、禁止存储猜测、严禁存储大模型可推理的通用常识
|
||||||
---
|
---
|
||||||
### L3:任务级精简记录库 (../memory/)
|
### L3:任务级精简记录库 (../memory/)
|
||||||
@@ -80,7 +85,8 @@ L4: ../memory/L4_raw_sessions/ (历史会话层 - scheduler反射自动收集,
|
|||||||
|
|
||||||
是『环境特异性事实』? (IP、非标路径、凭证、ID、API 密钥等,大模型 Zero-shot 无法生成准确)
|
是『环境特异性事实』? (IP、非标路径、凭证、ID、API 密钥等,大模型 Zero-shot 无法生成准确)
|
||||||
├─ YES → L2 (global_mem.txt)
|
├─ YES → L2 (global_mem.txt)
|
||||||
│ 然后 → 按频率归入 L1 第一层(key→value)或第二层(仅关键词)
|
│ 量大 → 独立文件,L2 留路径
|
||||||
|
| 然后 → L1中增加或归纳融入1个索引词
|
||||||
│
|
│
|
||||||
└─ NO
|
└─ NO
|
||||||
↓
|
↓
|
||||||
|
|||||||
Reference in new issue
Block a user