From bda130158670f2dab7f290d2e36088d51eb32692 Mon Sep 17 00:00:00 2001 From: pty819 Date: Mon, 20 Apr 2026 09:10:08 +0800 Subject: [PATCH] fix(openviking): route viking_read to correct endpoint for file URIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit viking_read was calling /content/abstract and /content/overview for ALL URIs, but these endpoints only accept directory URIs — file URIs cause a 500 INTERNAL error. Fix: call fs/stat first to determine URI type (isDir), then route: - directory URIs → /content/abstract | /content/overview | /content/read - file URIs → /content/read (handles both types, unlike abstract/overview) Fixes #12755 --- plugins/memory/openviking/__init__.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/plugins/memory/openviking/__init__.py b/plugins/memory/openviking/__init__.py index 86d7ad5efb..2820c71bd0 100644 --- a/plugins/memory/openviking/__init__.py +++ b/plugins/memory/openviking/__init__.py @@ -576,13 +576,27 @@ class OpenVikingMemoryProvider(MemoryProvider): return tool_error("uri is required") level = args.get("level", "overview") - # Map our level names to OpenViking GET endpoints - if level == "abstract": - resp = self._client.get("/api/v1/content/abstract", params={"uri": uri}) - elif level == "full": + + # Determine URI type so we route to the correct endpoint. + # abstract/overview are directory-only; files must use /content/download. + try: + stat_resp = self._client.get("/api/v1/fs/stat", params={"uri": uri}) + is_dir = stat_resp.get("result", {}).get("isDir", False) + except Exception: + is_dir = False + + if is_dir: + # Directory — route by level as before + if level == "abstract": + resp = self._client.get("/api/v1/content/abstract", params={"uri": uri}) + elif level == "full": + resp = self._client.get("/api/v1/content/read", params={"uri": uri}) + else: # overview + resp = self._client.get("/api/v1/content/overview", params={"uri": uri}) + else: + # File — abstract/overview endpoints don't support files; + # use /content/read which handles both types. resp = self._client.get("/api/v1/content/read", params={"uri": uri}) - else: # overview - resp = self._client.get("/api/v1/content/overview", params={"uri": uri}) result = resp.get("result", "") # result is a plain string from the content endpoints