mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
Merge c257a11eea into 00c3d848d8
This commit is contained in:
commit
f6cbd4e32c
5 changed files with 61 additions and 2 deletions
|
|
@ -27,6 +27,7 @@ def build_write_denied_paths(home: str) -> set[str]:
|
|||
os.path.join(home, ".ssh", "id_ed25519"),
|
||||
os.path.join(home, ".ssh", "config"),
|
||||
str(hermes_home / ".env"),
|
||||
os.path.join(home, ".hermes", ".env"),
|
||||
os.path.join(home, ".bashrc"),
|
||||
os.path.join(home, ".zshrc"),
|
||||
os.path.join(home, ".profile"),
|
||||
|
|
|
|||
|
|
@ -9402,6 +9402,7 @@ class AIAgent:
|
|||
if not self.quiet_mode:
|
||||
_print_preview = _summarize_user_message_for_log(user_message)
|
||||
self._safe_print(f"💬 Starting conversation: '{_print_preview[:60]}{'...' if len(_print_preview) > 60 else ''}'")
|
||||
|
||||
|
||||
# ── System prompt (cached per session for prefix caching) ──
|
||||
# Built once on first call, reused for all subsequent calls.
|
||||
|
|
|
|||
|
|
@ -342,6 +342,8 @@ class TestMinimaxSwitchModelCredentialGuard:
|
|||
agent.client = None
|
||||
agent._anthropic_client = MagicMock()
|
||||
agent._fallback_chain = []
|
||||
agent._fallback_activated = False
|
||||
agent._fallback_index = 0
|
||||
|
||||
with patch("agent.anthropic_adapter.build_anthropic_client") as mock_build, \
|
||||
patch("agent.anthropic_adapter.resolve_anthropic_token", return_value="sk-ant-leaked") as mock_resolve, \
|
||||
|
|
|
|||
|
|
@ -756,7 +756,7 @@ class TestAgentCacheSpilloverLive:
|
|||
runner = self._runner()
|
||||
|
||||
N_THREADS = 8
|
||||
PER_THREAD = 20 # 8 * 20 = 160 inserts into a 16-slot cache
|
||||
PER_THREAD = 3 # 8 * 3 = 24 inserts into a 16-slot cache
|
||||
|
||||
def worker(tid: int):
|
||||
for j in range(PER_THREAD):
|
||||
|
|
@ -949,8 +949,8 @@ class TestAgentCacheIdleResume:
|
|||
(full teardown — session is done), cache-eviction path uses
|
||||
release_clients() (soft — session may resume).
|
||||
"""
|
||||
from run_agent import AIAgent
|
||||
import run_agent as _ra
|
||||
from run_agent import AIAgent
|
||||
|
||||
# Agent A: evicted from cache (soft) — terminal survives.
|
||||
# Agent B: session expired (hard) — terminal torn down.
|
||||
|
|
|
|||
|
|
@ -4797,3 +4797,58 @@ class TestMemoryProviderTurnStart:
|
|||
import inspect
|
||||
src = inspect.getsource(AIAgent.run_conversation)
|
||||
assert "on_turn_start(self._user_turn_count" in src
|
||||
|
||||
|
||||
class TestMultimodalMessagePreview:
|
||||
"""run_conversation must not crash when user_message is a list (images)."""
|
||||
|
||||
def test_multimodal_list_message_does_not_crash(self, agent):
|
||||
"""When user_message is a multimodal list, the log preview should
|
||||
extract text parts instead of calling .replace() on a list."""
|
||||
multimodal_msg = [
|
||||
{"type": "text", "text": "Describe this image"},
|
||||
{"type": "image_url", "image_url": {"url": "data:image/png;base64,abc"}},
|
||||
]
|
||||
|
||||
fake_response = MagicMock()
|
||||
fake_response.choices = [
|
||||
MagicMock(
|
||||
message=MagicMock(
|
||||
content="I see an image.",
|
||||
tool_calls=None,
|
||||
role="assistant",
|
||||
),
|
||||
finish_reason="stop",
|
||||
)
|
||||
]
|
||||
fake_response.usage = MagicMock(prompt_tokens=10, completion_tokens=5, total_tokens=15)
|
||||
agent._interruptible_api_call = MagicMock(return_value=fake_response)
|
||||
agent._persist_session = lambda *a, **kw: None
|
||||
agent._save_trajectory = lambda *a, **kw: None
|
||||
agent._save_session_log = lambda *a, **kw: None
|
||||
|
||||
result = agent.run_conversation(multimodal_msg)
|
||||
assert result["completed"] is True
|
||||
assert "final_response" in result
|
||||
|
||||
def test_multimodal_no_text_parts(self, agent):
|
||||
"""A multimodal message with only images should produce a safe preview."""
|
||||
multimodal_msg = [
|
||||
{"type": "image_url", "image_url": {"url": "data:image/png;base64,abc"}},
|
||||
]
|
||||
|
||||
fake_response = MagicMock()
|
||||
fake_response.choices = [
|
||||
MagicMock(
|
||||
message=MagicMock(content="Image.", tool_calls=None, role="assistant"),
|
||||
finish_reason="stop",
|
||||
)
|
||||
]
|
||||
fake_response.usage = MagicMock(prompt_tokens=10, completion_tokens=5, total_tokens=15)
|
||||
agent._interruptible_api_call = MagicMock(return_value=fake_response)
|
||||
agent._persist_session = lambda *a, **kw: None
|
||||
agent._save_trajectory = lambda *a, **kw: None
|
||||
agent._save_session_log = lambda *a, **kw: None
|
||||
|
||||
result = agent.run_conversation(multimodal_msg)
|
||||
assert result["completed"] is True
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue