- F1: RuntimeService.list_runs 公共 Run 发现(工作区/会话/状态筛选); task_public_payload 序列化收敛至 models.py 核心层单一实现(Web/公共入口同构, helpers.py 旧实现删除,无新旧双轨) - F2: tasks/api.py 7 处、api_v1.py 3 处、chat/approval.py 6 处全部转调 runtime_service;HTTP 轮询透传 window_start 缺口水位;死导入清零 - F3: _resources_for_query 补 principal workspace_id 一致性校验 (跨工作区查询必须重新认证) - F4: config 新增 ASTRION_IGNORE_DOTENV 逃生门(.env 对 ASTRION_DATA_ROOT 的 优先覆盖是刻意设计,保留);验收测试自包含(假模型 127.0.0.1:9 快失败)+ 隔离生效断言;lifecycle 改 api_request_start 装配证据断言; 新增审批等待链验收(approval 档真实工具循环:等待→公共入口批准→继续); chain 首段改双客户端场景(B 经 list_runs 发现 A 的 Run 并观察/取消) - execution_plane/base.py 注释修正:命令校验/路径授权仍在旧链路(审核 §4) - 全量 75 测试:失败恰为 4 项存量,与改造无关
67 lines
2.9 KiB
Python
67 lines
2.9 KiB
Python
"""Execution Plane 契约:Runtime ↔ 执行环境分层接口(docs/execution_contract.md §3)。
|
||
|
||
定位:工具编排层(core/main_terminal_parts/tools_execution.py)通过本接口触达
|
||
执行环境;现有 Host/Docker 实现仍由 terminal_ops/file_manager 等承载(默认路径),
|
||
本接口是「替身执行器 / 未来远端执行后端」的统一接入点。
|
||
|
||
首版接口面(E1-E4,归纳自现状调用点,未发明新能力):
|
||
- E1 run_command(前台命令)
|
||
- E2 run_command_background(后台命令登记)
|
||
- E3 write_file / E4 edit_file(文件写)
|
||
|
||
结果结构与现有真实后端保持一致(调用方按同一结构消费):
|
||
- run_command: {success, status, output, return_code, truncated, elapsed_ms}
|
||
status ∈ {"completed", "timeout", "error", "cancelled"}
|
||
- run_command_background: {success, command_id, status}(status="running_background")
|
||
- write_file/edit_file: {success, path, original_file, new_file}
|
||
(original_file/new_file 为写前/后全文,编辑摘要链路依赖)
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from typing import Any, Dict, List, Optional, Protocol, runtime_checkable
|
||
|
||
|
||
@runtime_checkable
|
||
class ExecutionBackend(Protocol):
|
||
"""执行环境后端协议。实现方:FakeExecutionBackend(替身)、未来 Host/Docker 适配器。
|
||
|
||
注意:本协议只承诺「执行语义」,不承诺安全边界。当前权限裁决(permission mode)
|
||
与审批介入在 Runtime 编排层完成;但**命令校验(_validate_command/FORBIDDEN_COMMANDS)
|
||
与路径授权(_validate_path/禁读清单)仍由旧 terminal_ops/file_manager 链路承担**——
|
||
经本接口注入的后端分支并不会自动获得这些校验。未来接入真实 ExecutionBackend
|
||
(Host/Docker 迁入)时,必须准确分配并保留这些校验,不能按「上层已完成全部检查」
|
||
误读(审核 §4)。OS 层强制力(Seatbelt/bwrap/DAC+Landlock)是最终边界。
|
||
"""
|
||
|
||
async def run_command(
|
||
self,
|
||
command: str,
|
||
*,
|
||
timeout: float,
|
||
sandbox_write_access: bool,
|
||
network_permission: str,
|
||
) -> Dict[str, Any]:
|
||
"""E1 前台命令执行。"""
|
||
...
|
||
|
||
def run_command_background(
|
||
self,
|
||
command: str,
|
||
*,
|
||
timeout: float,
|
||
conversation_id: Optional[str],
|
||
wait_seconds: float,
|
||
network_permission: str,
|
||
sandbox_write_access: bool,
|
||
) -> Dict[str, Any]:
|
||
"""E2 后台命令登记(立即返回 command_id,执行异步进行)。"""
|
||
...
|
||
|
||
def write_file(self, path: str, content: str, *, mode: str = "w") -> Dict[str, Any]:
|
||
"""E3 文件写入(mode "w" 覆盖 / "a" 追加)。"""
|
||
...
|
||
|
||
def edit_file(self, path: str, replacements: List[Dict[str, Any]]) -> Dict[str, Any]:
|
||
"""E4 文件精确替换(replacements 元素含 old_string/new_string/replace_all)。"""
|
||
...
|