mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-02 02:01:47 +00:00
fix(openviking): pre-check fs/stat to route file URIs before hitting directory-only endpoints
Adds a deterministic pre-check on top of htsh's exception-based fallback: before calling /content/abstract or /content/overview on a non-pseudo URI, probe /api/v1/fs/stat. If the server says the URI is a file, route straight to /content/read instead of eating a failing 500 round-trip. This is the same idea pty819 and chennest independently landed in PRs #12757 and #12937 — merged here on top of htsh's broader fix so we keep pseudo-URI normalization and v0.3.3 browse-shape handling while avoiding the slow exception path on servers that return a raised 500 every time. The exception fallback from #5886 stays in place for environments where fs/stat is unavailable or returns an unfamiliar shape. Also credits pty819, chennest, and htsh in AUTHOR_MAP so future release notes attribute them correctly.
This commit is contained in:
parent
10e43edc09
commit
5d253e65b7
3 changed files with 128 additions and 7 deletions
|
|
@ -71,11 +71,91 @@ class TestOpenVikingRead:
|
|||
{"uri": "viking://user/hermes/memories/profile.md"},
|
||||
)]
|
||||
|
||||
def test_overview_file_uri_falls_back_to_content_read_on_summary_error(self):
|
||||
def test_overview_file_uri_routes_straight_to_content_read_via_stat_probe(self):
|
||||
"""Pre-check via fs/stat: file URIs skip the directory-only endpoint entirely."""
|
||||
provider = OpenVikingMemoryProvider()
|
||||
file_uri = "viking://user/hermes/memories/entities/mem_abc.md"
|
||||
provider._client = FakeVikingClient(
|
||||
{
|
||||
(
|
||||
"/api/v1/fs/stat",
|
||||
(("uri", file_uri),),
|
||||
): {"result": {"isDir": False}},
|
||||
(
|
||||
"/api/v1/content/read",
|
||||
(("uri", file_uri),),
|
||||
): {"result": {"content": "full content"}},
|
||||
}
|
||||
)
|
||||
|
||||
result = json.loads(provider._tool_read({"uri": file_uri, "level": "overview"}))
|
||||
|
||||
assert result["uri"] == file_uri
|
||||
assert result["resolved_uri"] == file_uri
|
||||
assert result["level"] == "overview"
|
||||
assert result["fallback"] == "content/read"
|
||||
assert result["content"] == "full content"
|
||||
assert provider._client.calls == [
|
||||
("/api/v1/fs/stat", {"uri": file_uri}),
|
||||
("/api/v1/content/read", {"uri": file_uri}),
|
||||
]
|
||||
|
||||
def test_overview_dir_uri_skips_stat_when_pseudo_summary(self):
|
||||
"""Pseudo-URI path already resolves to dir, so no stat probe needed."""
|
||||
provider = OpenVikingMemoryProvider()
|
||||
provider._client = FakeVikingClient(
|
||||
{
|
||||
(
|
||||
"/api/v1/content/overview",
|
||||
(("uri", "viking://user/hermes"),),
|
||||
): {"result": "overview"},
|
||||
}
|
||||
)
|
||||
|
||||
result = json.loads(provider._tool_read({"uri": "viking://user/hermes/.overview.md", "level": "overview"}))
|
||||
|
||||
assert result["content"] == "overview"
|
||||
# No fs/stat call — normalization already determined it's a directory.
|
||||
assert provider._client.calls == [
|
||||
("/api/v1/content/overview", {"uri": "viking://user/hermes"}),
|
||||
]
|
||||
|
||||
def test_overview_directory_uri_uses_stat_probe_then_overview(self):
|
||||
"""Non-pseudo directory URI: stat → isDir=True → summary endpoint."""
|
||||
provider = OpenVikingMemoryProvider()
|
||||
dir_uri = "viking://user/hermes/memories"
|
||||
provider._client = FakeVikingClient(
|
||||
{
|
||||
(
|
||||
"/api/v1/fs/stat",
|
||||
(("uri", dir_uri),),
|
||||
): {"result": {"isDir": True}},
|
||||
(
|
||||
"/api/v1/content/overview",
|
||||
(("uri", dir_uri),),
|
||||
): {"result": "dir overview"},
|
||||
}
|
||||
)
|
||||
|
||||
result = json.loads(provider._tool_read({"uri": dir_uri, "level": "overview"}))
|
||||
|
||||
assert result["content"] == "dir overview"
|
||||
assert "fallback" not in result
|
||||
assert provider._client.calls == [
|
||||
("/api/v1/fs/stat", {"uri": dir_uri}),
|
||||
("/api/v1/content/overview", {"uri": dir_uri}),
|
||||
]
|
||||
|
||||
def test_overview_file_uri_falls_back_via_exception_when_stat_indeterminate(self):
|
||||
"""If fs/stat raises or returns unknown shape, legacy exception fallback still kicks in."""
|
||||
provider = OpenVikingMemoryProvider()
|
||||
file_uri = "viking://user/hermes/memories/entities/mem_abc.md"
|
||||
provider._client = FakeVikingClient(
|
||||
{
|
||||
(
|
||||
"/api/v1/fs/stat",
|
||||
(("uri", file_uri),),
|
||||
): RuntimeError("stat unavailable"),
|
||||
(
|
||||
"/api/v1/content/overview",
|
||||
(("uri", file_uri),),
|
||||
|
|
@ -90,11 +170,11 @@ class TestOpenVikingRead:
|
|||
result = json.loads(provider._tool_read({"uri": file_uri, "level": "overview"}))
|
||||
|
||||
assert result["uri"] == file_uri
|
||||
assert result["resolved_uri"] == file_uri
|
||||
assert result["level"] == "overview"
|
||||
assert result["fallback"] == "content/read"
|
||||
assert result["content"] == "fallback full content"
|
||||
assert provider._client.calls == [
|
||||
("/api/v1/fs/stat", {"uri": file_uri}),
|
||||
("/api/v1/content/overview", {"uri": file_uri}),
|
||||
("/api/v1/content/read", {"uri": file_uri}),
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue