|
@@ -26,7 +26,7 @@ from pathlib import Path
|
|
|
from typing import Any
|
|
from typing import Any
|
|
|
|
|
|
|
|
VERSION = 1
|
|
VERSION = 1
|
|
|
-PLUGIN_VERSION = "1.2.1"
|
|
|
|
|
|
|
+PLUGIN_VERSION = "1.2.2"
|
|
|
def _plugin_fingerprint():
|
|
def _plugin_fingerprint():
|
|
|
root = Path(__file__).parent
|
|
root = Path(__file__).parent
|
|
|
digest = hashlib.sha256()
|
|
digest = hashlib.sha256()
|
|
@@ -92,6 +92,7 @@ def register_context(ctx):
|
|
|
def _refresh_agent_tools(agent, binding):
|
|
def _refresh_agent_tools(agent, binding):
|
|
|
if binding.workspace_memory:
|
|
if binding.workspace_memory:
|
|
|
_isolate_profile_memory(agent, binding)
|
|
_isolate_profile_memory(agent, binding)
|
|
|
|
|
+ _isolate_profile_context(agent, binding)
|
|
|
from model_tools import get_tool_definitions, get_toolset_for_tool
|
|
from model_tools import get_tool_definitions, get_toolset_for_tool
|
|
|
if not hasattr(agent, "_yaoyao_base_toolsets"):
|
|
if not hasattr(agent, "_yaoyao_base_toolsets"):
|
|
|
agent._yaoyao_base_toolsets = getattr(agent, "enabled_toolsets", None)
|
|
agent._yaoyao_base_toolsets = getattr(agent, "enabled_toolsets", None)
|
|
@@ -335,7 +336,8 @@ def capabilities(profile: str = "default") -> dict:
|
|
|
raise BridgeError(f"Profile {profile} 尚未安装或启用夭夭工具桥,请检查该 Profile 的插件与工具集设置", 503, "profile_tools_unavailable")
|
|
raise BridgeError(f"Profile {profile} 尚未安装或启用夭夭工具桥,请检查该 Profile 的插件与工具集设置", 503, "profile_tools_unavailable")
|
|
|
return {"version": VERSION, "ready": True, "in_process": True, "profile": profile, "native_tools": True,
|
|
return {"version": VERSION, "ready": True, "in_process": True, "profile": profile, "native_tools": True,
|
|
|
"computer_runtime_version": 2, "plugin_version": PLUGIN_VERSION, "plugin_fingerprint": PLUGIN_FINGERPRINT,
|
|
"computer_runtime_version": 2, "plugin_version": PLUGIN_VERSION, "plugin_fingerprint": PLUGIN_FINGERPRINT,
|
|
|
- "memory_isolation": True, "memory_isolation_transport": "bridge-bind-v1", "memory_extraction": True}
|
|
|
|
|
|
|
+ "memory_isolation": True, "memory_isolation_transport": "bridge-bind-v1", "memory_extraction": True,
|
|
|
|
|
+ "isolated_context_files": True}
|
|
|
finally:
|
|
finally:
|
|
|
reset_hermes_home_override(context)
|
|
reset_hermes_home_override(context)
|
|
|
except Exception as exc:
|
|
except Exception as exc:
|
|
@@ -518,6 +520,7 @@ def bind(owner: tuple[str, str], body: dict, *, wait_seconds: float = 20) -> dic
|
|
|
if workspace_memory:
|
|
if workspace_memory:
|
|
|
_isolate_profile_memory(agent, binding)
|
|
_isolate_profile_memory(agent, binding)
|
|
|
session["_yaoyao_workspace_memory"] = True
|
|
session["_yaoyao_workspace_memory"] = True
|
|
|
|
|
+ _isolate_profile_context(agent, binding)
|
|
|
if policy:
|
|
if policy:
|
|
|
# Private runtime state survives unbind so a stale tool call cannot
|
|
# Private runtime state survives unbind so a stale tool call cannot
|
|
|
# fall back to the unrestricted native Profile after revocation.
|
|
# fall back to the unrestricted native Profile after revocation.
|
|
@@ -757,6 +760,23 @@ def call_tool(args: dict, **kwargs) -> str | dict:
|
|
|
|
|
|
|
|
# Native Hermes remains the only owner of Profile configuration, skills and
|
|
# Native Hermes remains the only owner of Profile configuration, skills and
|
|
|
# authenticated integrations. The Runner never opens those files itself.
|
|
# authenticated integrations. The Runner never opens those files itself.
|
|
|
|
|
+def _isolate_profile_context(agent, binding):
|
|
|
|
|
+ """Disable automatic host instruction files only for isolated Bot sessions.
|
|
|
|
|
+
|
|
|
|
|
+ Apply on every bind/rebuild, including inherited children, before the model
|
|
|
|
|
+ runs. Skills have their own loader; history and Profile config stay intact.
|
|
|
|
|
+ """
|
|
|
|
|
+ if (binding.computer_policy or {}).get("mode") != "isolated":
|
|
|
|
|
+ return
|
|
|
|
|
+ invalidate = getattr(agent, "_invalidate_system_prompt", None)
|
|
|
|
|
+ if not all(hasattr(agent, name) for name in ("skip_context_files", "load_soul_identity")) or not callable(invalidate):
|
|
|
|
|
+ raise BridgeError("当前 Hermes 不支持工具桥的会话上下文隔离", 409, "context_isolation_unavailable")
|
|
|
|
|
+ agent.skip_context_files = True
|
|
|
|
|
+ # This override loads SOUL even when skip_context_files is true.
|
|
|
|
|
+ agent.load_soul_identity = False
|
|
|
|
|
+ invalidate()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
def _isolate_profile_memory(agent, binding):
|
|
def _isolate_profile_memory(agent, binding):
|
|
|
"""Apply the existing agent controls before any prompt, without editing Profile config.
|
|
"""Apply the existing agent controls before any prompt, without editing Profile config.
|
|
|
|
|
|