Skip to content

Commit fb6577b

Browse files
committed
fix: address namespace resolver review feedback
1 parent e4a97d4 commit fb6577b

File tree

3 files changed

+126
-56
lines changed

3 files changed

+126
-56
lines changed

openviking/core/directories.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ async def initialize_user_directories(self, ctx: RequestContext) -> int:
180180
"""Initialize user-space tree lazily for the current user."""
181181
if "user" not in PRESET_DIRECTORIES:
182182
return 0
183-
policy = self._load_namespace_policy(ctx)
183+
policy = await self._load_namespace_policy(ctx)
184184
user_space_root = ctx.user.canonical_user_root(policy)
185185
user_parent = VikingURI(user_space_root).parent
186186
user_tree = PRESET_DIRECTORIES["user"]
@@ -201,7 +201,7 @@ async def initialize_agent_directories(self, ctx: RequestContext) -> int:
201201
"""Initialize agent-space tree lazily for the current user+agent."""
202202
if "agent" not in PRESET_DIRECTORIES:
203203
return 0
204-
policy = self._load_namespace_policy(ctx)
204+
policy = await self._load_namespace_policy(ctx)
205205
agent_space_root = ctx.user.canonical_agent_root(policy)
206206
agent_parent = VikingURI(agent_space_root).parent
207207
agent_tree = PRESET_DIRECTORIES["agent"]
@@ -358,11 +358,11 @@ async def _ensure_namespace_policy(self, ctx: RequestContext) -> NamespacePolicy
358358
viking_fs = get_viking_fs()
359359
policy = self._namespace_policy_overrides.pop(ctx.account_id, None)
360360
if policy is None:
361-
policy = viking_fs.get_namespace_resolver(ctx).policy
361+
policy = (await viking_fs.get_namespace_resolver(ctx)).policy
362362
return await persist_namespace_policy(viking_fs, ctx.account_id, policy)
363363

364364
@staticmethod
365-
def _load_namespace_policy(ctx: RequestContext) -> NamespacePolicy:
365+
async def _load_namespace_policy(ctx: RequestContext) -> NamespacePolicy:
366366
from openviking.storage.viking_fs import get_viking_fs
367367

368-
return get_viking_fs().get_namespace_resolver(ctx).policy
368+
return (await get_viking_fs().get_namespace_resolver(ctx)).policy

openviking/core/namespace.py

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd.
2+
# SPDX-License-Identifier: AGPL-3.0
13
"""Account-scoped namespace policy and canonical URI resolution helpers."""
24

35
from __future__ import annotations
@@ -6,9 +8,12 @@
68
from dataclasses import dataclass
79
from typing import Any, Optional
810

11+
from openviking_cli.utils import run_async
12+
from openviking_cli.utils.logger import get_logger
913
from openviking_cli.utils.uri import VikingURI
1014

1115
NAMESPACE_POLICY_PATH_TEMPLATE = "/local/{account_id}/_system/setting.json"
16+
logger = get_logger(__name__)
1217

1318
_ROOT_METADATA_FILES = {".abstract.md", ".overview.md"}
1419
_USER_STRUCTURE_DIRS = {"memories", "profile.md"}
@@ -195,8 +200,10 @@ def _ensure_parent_dirs(viking_fs: Any, path: str) -> None:
195200
parent = "/" + "/".join(parts[:index])
196201
try:
197202
viking_fs.agfs.mkdir(parent)
198-
except Exception:
199-
pass
203+
except FileExistsError:
204+
continue
205+
except Exception as exc:
206+
logger.debug("Failed to create parent directory %s: %s", parent, exc)
200207

201208

202209
def _coerce_bytes(viking_fs: Any, result: Any) -> bytes:
@@ -223,7 +230,36 @@ async def load_namespace_policy(viking_fs: Any, account_id: str) -> NamespacePol
223230
payload = await viking_fs.decrypt_bytes(account_id, payload)
224231
data = json.loads(payload.decode("utf-8"))
225232
return NamespacePolicy.from_dict(data)
226-
except Exception:
233+
except Exception as exc:
234+
logger.debug(
235+
"Falling back to default namespace policy for account %s from %s: %s",
236+
account_id,
237+
path,
238+
exc,
239+
)
240+
return NamespacePolicy()
241+
242+
243+
def load_namespace_policy_sync(viking_fs: Any, account_id: str) -> NamespacePolicy:
244+
"""Synchronously read the persisted account policy for sync-only call sites."""
245+
path = namespace_policy_path(account_id)
246+
try:
247+
try:
248+
raw = viking_fs.agfs.read(path, 0, -1)
249+
except TypeError:
250+
raw = viking_fs.agfs.read(path)
251+
payload = _coerce_bytes(viking_fs, raw)
252+
if getattr(viking_fs, "_encryptor", None):
253+
payload = run_async(viking_fs.decrypt_bytes(account_id, payload))
254+
data = json.loads(payload.decode("utf-8"))
255+
return NamespacePolicy.from_dict(data)
256+
except Exception as exc:
257+
logger.debug(
258+
"Synchronously falling back to default namespace policy for account %s from %s: %s",
259+
account_id,
260+
path,
261+
exc,
262+
)
227263
return NamespacePolicy()
228264

229265

@@ -239,7 +275,11 @@ async def persist_namespace_policy(
239275
content = await viking_fs.encrypt_bytes(account_id, content)
240276
_ensure_parent_dirs(viking_fs, path)
241277
viking_fs.agfs.write(path, content)
242-
cache = getattr(viking_fs, "_namespace_policy_cache", None)
243-
if isinstance(cache, dict):
244-
cache[account_id] = resolved
278+
cache_setter = getattr(viking_fs, "_set_cached_namespace_policy", None)
279+
if callable(cache_setter):
280+
cache_setter(account_id, resolved)
281+
else:
282+
cache = getattr(viking_fs, "_namespace_policy_cache", None)
283+
if isinstance(cache, dict):
284+
cache[account_id] = resolved
245285
return resolved

0 commit comments

Comments
 (0)