refactor: root-package imports (svc/runtime/interfaces) and fix PYTHONPATH

- Rename platform/ to svc/ to avoid shadowing stdlib platform.
- Replace from oclaw.* with from svc/runtime/interfaces; update -m CLI paths.
- tests/conftest: prepend repo root to sys.path (no parent-folder package name).
- CI: paths and offline_eval script under repo root.
- Ops scripts: PYTHONPATH must be repo root for python -m runtime.* (fixes gateway/WhatsApp sidecar startup).
- Fix default oclaw.json path in tabular/file attachment limits; stabilize attachment test config.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-05-13 14:51:17 +08:00
parent 7941b27f58
commit 420abac9f1
405 changed files with 1316 additions and 1345 deletions

View file

@ -1,36 +1,21 @@
from __future__ import annotations
import importlib
import sys
from pathlib import Path
def _normalize_sys_path_for_repo_layout() -> None:
"""
Allow running pytest from the ``oclaw`` subdirectory.
"""Put the repository root (contains ``svc/``, ``runtime/``, ``interfaces/``) first on ``sys.path``.
When cwd is ``.../chatgpt/oclaw``, Python may resolve ``import platform``
to ``oclaw/platform`` instead of stdlib ``platform``. We force sys.path to
prefer repository root (which contains the ``oclaw`` package directory).
First-party imports use top-level packages ``svc``, ``runtime``, and ``interfaces``; they do not
depend on the checkout directory being named ``oclaw``.
"""
this_file = Path(__file__).resolve()
oclaw_dir = this_file.parents[1]
repo_root = oclaw_dir.parent
oclaw_dir_str = str(oclaw_dir)
repo_root_str = str(repo_root)
sys.path[:] = [p for p in sys.path if p and Path(p).resolve() != oclaw_dir]
if repo_root_str not in sys.path:
sys.path.insert(0, repo_root_str)
mod = sys.modules.get("platform")
if mod is not None:
mod_file = str(getattr(mod, "__file__", "") or "")
if "oclaw\\platform" in mod_file.replace("/", "\\"):
sys.modules.pop("platform", None)
importlib.import_module("platform")
repo_root = this_file.parents[1]
rr = str(repo_root.resolve())
sys.path[:] = [p for p in sys.path if p and Path(p).resolve() != repo_root]
if rr not in sys.path:
sys.path.insert(0, rr)
_normalize_sys_path_for_repo_layout()

View file

@ -7,9 +7,9 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.config.paths import db_path
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.config.paths import db_path
from svc.persistence.sqlite_store import SqliteStore
class AdminAuditPaginationApiTests(unittest.TestCase):

View file

@ -7,9 +7,9 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.config.paths import db_path
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.config.paths import db_path
from svc.persistence.sqlite_store import SqliteStore
class AdminAuthRBACTests(unittest.TestCase):

View file

@ -9,8 +9,8 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
class AdminChatStreamAsyncTaskTests(unittest.TestCase):

View file

@ -9,8 +9,8 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
class AdminChatWikiEventsApiTests(unittest.TestCase):

View file

@ -8,8 +8,8 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
class AdminInternalToolsPreviewApiTests(unittest.TestCase):

View file

@ -8,8 +8,8 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
class AdminInternalToolsReloadApiTests(unittest.TestCase):

View file

@ -8,9 +8,9 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from oclaw.runtime.tools.exposure_plan import build_llm_tools_plan
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
from runtime.tools.exposure_plan import build_llm_tools_plan
class AdminLLMPreviewPlannerConsistencyTests(unittest.TestCase):

View file

@ -8,8 +8,8 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
class AdminLLMToolsPreviewApiTests(unittest.TestCase):

View file

@ -9,8 +9,8 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
class AdminMcpToolWireRoleModeApiTests(unittest.TestCase):

View file

@ -8,8 +8,8 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
class AdminOclawRunsApiTests(unittest.TestCase):

View file

@ -8,8 +8,8 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
class AdminOclawTasksApiTests(unittest.TestCase):

View file

@ -9,8 +9,8 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
class AdminSessionMonitorApiTests(unittest.TestCase):

View file

@ -10,8 +10,8 @@ from unittest.mock import patch
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
class AdminSkillsApiTests(unittest.TestCase):
@ -311,7 +311,7 @@ class AdminSkillsApiTests(unittest.TestCase):
_ = (slug, version)
return z.resolve().as_uri(), "1.0.0"
with patch("oclaw.interfaces.admin.skills_api.get_market_adapter", return_value=_FakeAdapter()):
with patch("interfaces.admin.skills_api.get_market_adapter", return_value=_FakeAdapter()):
r = self.client.post(
"/admin/api/skills/market/install",
json={"slug": "owner/demo3"},

View file

@ -8,8 +8,8 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
class AdminToolPolicyOclawRetryCodesTests(unittest.TestCase):

View file

@ -8,8 +8,8 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
class AdminToolsExposureTraceSettingApiTests(unittest.TestCase):

View file

@ -8,8 +8,8 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
class AdminToolsSelfCheckApiTests(unittest.TestCase):

View file

@ -4,7 +4,7 @@ from pathlib import Path
import pytest
from oclaw.runtime.agent_context import loader as loader_mod
from runtime.agent_context import loader as loader_mod
def _set_project_root(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:

View file

@ -1,7 +1,7 @@
from __future__ import annotations
from oclaw.runtime.agent_core_attempt import _should_after_turn_memory
from oclaw.runtime.types import StandardMessage
from runtime.agent_core_attempt import _should_after_turn_memory
from runtime.types import StandardMessage
def _msg(interaction_mode: str, extra: dict | None = None) -> StandardMessage:

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from oclaw.platform.llm.transports.anthropic_messages import parse_anthropic_stream_events
from svc.llm.transports.anthropic_messages import parse_anthropic_stream_events
def test_anthropic_stream_parses_text_and_tool_use() -> None:

View file

@ -9,9 +9,9 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.files.attachment_assets import AttachmentAssetStore
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.files.attachment_assets import AttachmentAssetStore
from svc.persistence.sqlite_store import SqliteStore
def _pw_hash(pw: str) -> str:

View file

@ -2,7 +2,7 @@ from __future__ import annotations
from pathlib import Path
from oclaw.runtime.tools.public.attachment_local_url_tool import attachment_local_url_tool
from runtime.tools.public.attachment_local_url_tool import attachment_local_url_tool
class _FakeMeta:
@ -31,7 +31,7 @@ def test_attachment_local_url_rejects_invalid_id() -> None:
def test_attachment_local_url_builds_absolute_url(monkeypatch) -> None:
monkeypatch.setattr("oclaw.runtime.tools.public.attachment_local_url_tool.AttachmentAssetStore", _FakeStore)
monkeypatch.setattr("runtime.tools.public.attachment_local_url_tool.AttachmentAssetStore", _FakeStore)
spec = attachment_local_url_tool()
aid = "a" * 64
out = spec.handler({"attachment_id": aid})
@ -44,7 +44,7 @@ def test_attachment_local_url_builds_absolute_url(monkeypatch) -> None:
def test_attachment_local_url_verbose_includes_debug_fields(monkeypatch) -> None:
monkeypatch.setattr("oclaw.runtime.tools.public.attachment_local_url_tool.AttachmentAssetStore", _FakeStore)
monkeypatch.setattr("runtime.tools.public.attachment_local_url_tool.AttachmentAssetStore", _FakeStore)
spec = attachment_local_url_tool()
aid = "a" * 64
out = spec.handler({"attachment_id": aid, "verbose": True})
@ -55,7 +55,7 @@ def test_attachment_local_url_verbose_includes_debug_fields(monkeypatch) -> None
def test_attachment_local_url_is_visible_in_public_registry() -> None:
from oclaw.runtime.tools.catalog import default_registry
from runtime.tools.catalog import default_registry
names = [t.name for t in default_registry(expert="network_ops+memory", specialist="ops").list()]
assert "attachment_local_url" in names

View file

@ -3,9 +3,9 @@ from __future__ import annotations
import json
from pathlib import Path
from oclaw.platform.persistence.sqlite_store import SqliteStore
from oclaw.runtime.direct_loop import _build_model_context
from oclaw.platform.llm.chat_models import RuleBasedChatModel
from svc.persistence.sqlite_store import SqliteStore
from runtime.direct_loop import _build_model_context
from svc.llm.chat_models import RuleBasedChatModel
def test_large_text_attachment_is_guarded_in_history_context(tmp_path: Path) -> None:

View file

@ -2,7 +2,7 @@ from __future__ import annotations
from pathlib import Path
import oclaw.platform.config.paths as paths_mod
import svc.config.paths as paths_mod
def _mkdir(p: Path) -> None:

View file

@ -2,7 +2,7 @@ from __future__ import annotations
import json
from oclaw.runtime.tools.public.bailian_webparser_tool import bailian_webparser_tool
from runtime.tools.public.bailian_webparser_tool import bailian_webparser_tool
class _SseResp:

View file

@ -5,7 +5,7 @@ from pathlib import Path
import pytest
from oclaw.platform.config import bootstrap_env as be
from svc.config import bootstrap_env as be
@pytest.fixture(autouse=True)

View file

@ -2,8 +2,8 @@ from __future__ import annotations
from unittest.mock import patch
from oclaw.runtime.tools.base import ToolSpec
from oclaw.runtime.tools.catalog import materialize_tool_specs
from runtime.tools.base import ToolSpec
from runtime.tools.catalog import materialize_tool_specs
def _mk_spec(name: str) -> ToolSpec:
@ -29,10 +29,10 @@ def _mk_spec_with_risk(name: str, *, risk: str, tags: set[str] | None = None) ->
def test_catalog_loads_role_scoped_expert_tools() -> None:
with patch(
"oclaw.runtime.tools.catalog.materialize_tools_for_expert",
"runtime.tools.catalog.materialize_tools_for_expert",
return_value=[_mk_spec("custom_tool_a"), _mk_spec("custom_tool_b")],
):
with patch("oclaw.runtime.tools.catalog.materialize_public_tools", return_value=[_mk_spec("system_time")]):
with patch("runtime.tools.catalog.materialize_public_tools", return_value=[_mk_spec("system_time")]):
specs = materialize_tool_specs(expert="generalist")
names = {x.name for x in specs}
assert "system_time" in names
@ -42,10 +42,10 @@ def test_catalog_loads_role_scoped_expert_tools() -> None:
def test_catalog_deduplicates_same_tool_name() -> None:
with patch(
"oclaw.runtime.tools.catalog.materialize_tools_for_expert",
"runtime.tools.catalog.materialize_tools_for_expert",
return_value=[_mk_spec("system_time"), _mk_spec("custom_tool_a")],
):
with patch("oclaw.runtime.tools.catalog.materialize_public_tools", return_value=[_mk_spec("system_time")]):
with patch("runtime.tools.catalog.materialize_public_tools", return_value=[_mk_spec("system_time")]):
specs = materialize_tool_specs(expert="generalist")
names = [x.name for x in specs]
assert names.count("system_time") == 1
@ -54,11 +54,11 @@ def test_catalog_deduplicates_same_tool_name() -> None:
def test_catalog_prefers_lower_risk_on_name_conflict() -> None:
with patch(
"oclaw.runtime.tools.catalog.materialize_tools_for_expert",
"runtime.tools.catalog.materialize_tools_for_expert",
return_value=[_mk_spec_with_risk("dup_tool", risk="high")],
):
with patch(
"oclaw.runtime.tools.catalog.materialize_public_tools",
"runtime.tools.catalog.materialize_public_tools",
return_value=[_mk_spec_with_risk("dup_tool", risk="low")],
):
specs = materialize_tool_specs(expert="generalist")
@ -69,11 +69,11 @@ def test_catalog_prefers_lower_risk_on_name_conflict() -> None:
def test_catalog_prefers_expert_when_risk_equal() -> None:
with patch(
"oclaw.runtime.tools.catalog.materialize_tools_for_expert",
"runtime.tools.catalog.materialize_tools_for_expert",
return_value=[_mk_spec_with_risk("dup_tool", risk="low", tags={"expert"})],
):
with patch(
"oclaw.runtime.tools.catalog.materialize_public_tools",
"runtime.tools.catalog.materialize_public_tools",
return_value=[_mk_spec_with_risk("dup_tool", risk="low", tags={"public"})],
):
specs = materialize_tool_specs(expert="generalist")

View file

@ -2,8 +2,8 @@ from __future__ import annotations
from pathlib import Path
from oclaw.platform.persistence.sqlite_store import SqliteStore
from oclaw.runtime.tools.catalog import materialize_tool_specs
from svc.persistence.sqlite_store import SqliteStore
from runtime.tools.catalog import materialize_tool_specs
def _seed_single_mcp_tool(store: SqliteStore) -> None:

View file

@ -4,7 +4,7 @@ import os
import pytest
from oclaw.platform.integrations import cc_mini_vendor as m
from svc.integrations import cc_mini_vendor as m
def test_cc_mini_pythonpath_prepends_src_when_available() -> None:

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from oclaw.runtime.application.gateway.inbound_service import (
from runtime.application.gateway.inbound_service import (
_resolve_channel_dispatch,
)

View file

@ -2,7 +2,7 @@ from __future__ import annotations
from types import SimpleNamespace
from oclaw.interfaces.admin.chat_api import _filter_internal_instruction_user_messages
from interfaces.admin.chat_api import _filter_internal_instruction_user_messages
def test_filter_internal_instruction_user_messages_hides_polluted_user_row() -> None:

View file

@ -2,7 +2,7 @@
from __future__ import annotations
from oclaw.interfaces.admin.chat_api import _parse_attachments_payload
from interfaces.admin.chat_api import _parse_attachments_payload
def test_parse_attachments_payload_preserves_image_ref() -> None:

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from oclaw.interfaces.admin.chat_api import (
from interfaces.admin.chat_api import (
_persist_session_dialog_chat_settings,
_persist_user_menu_chat_settings,
_resolve_mode_settings,

View file

@ -9,8 +9,8 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
MINI_PNG = base64.b64decode(
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="

View file

@ -10,8 +10,8 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
class ChatSessionFullSmokeTests(unittest.TestCase):

View file

@ -10,8 +10,8 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from svc.persistence.sqlite_store import SqliteStore
def _pw_hash(pw: str) -> str:

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from oclaw.runtime.tools.skills import clawhub_client
from runtime.tools.skills import clawhub_client
def test_get_skill_detail_handles_latest_version_object(monkeypatch) -> None:

View file

@ -5,7 +5,7 @@ import json
import pytest
from oclaw.runtime.tools.public.cloudflare_image_generate_tool import _to_image_bytes
from runtime.tools.public.cloudflare_image_generate_tool import _to_image_bytes
def test_to_image_bytes_accepts_direct_image_content_type() -> None:

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from oclaw.runtime.tools.catalog import default_registry
from runtime.tools.catalog import default_registry
def test_cloudflare_image_generate_in_public_registry() -> None:

View file

@ -2,9 +2,9 @@ from __future__ import annotations
from types import SimpleNamespace
from oclaw.platform.persistence.sqlite_store import SqliteStore
from oclaw.runtime.direct_loop import run_oclaw_direct_loop
from oclaw.runtime.tools.base import ToolRegistry, ToolSpec
from svc.persistence.sqlite_store import SqliteStore
from runtime.direct_loop import run_oclaw_direct_loop
from runtime.tools.base import ToolRegistry, ToolSpec
class _Model:

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from oclaw.runtime.direct_loop import _split_reasoning_and_body
from runtime.direct_loop import _split_reasoning_and_body
def test_split_reasoning_extracts_thinking_tags() -> None:

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from oclaw.runtime.dsml_tool_parse import (
from runtime.dsml_tool_parse import (
normalize_dsml_markup,
strip_first_dsml_tool_calls_block,
try_parse_deepseek_v4_dsml_tool_calls,

View file

@ -2,7 +2,7 @@ from __future__ import annotations
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from interfaces.http.fastapi_app import create_app
def test_inbound_route_uses_given_channel() -> None:

View file

@ -2,7 +2,7 @@ from __future__ import annotations
from fastapi import FastAPI
from oclaw.interfaces.http import fastapi_app as app_mod
from interfaces.http import fastapi_app as app_mod
def test_run_startup_hooks_runs_prebuild_warmup(monkeypatch) -> None:

View file

@ -8,16 +8,16 @@ import zipfile
from pathlib import Path
import pandas as pd
import oclaw.platform.files.file_attachments as fa
from oclaw.platform.files.file_attachments import process_file_data
from oclaw.platform.files.tabular_attachment_store import (
import svc.files.file_attachments as fa
from svc.files.file_attachments import process_file_data
from svc.files.tabular_attachment_store import (
aggregate_table,
analyze_table_full_scan,
query_table,
run_table_sql,
save_workbook,
)
from oclaw.platform.files.text_attachment_store import query_text_document
from svc.files.text_attachment_store import query_text_document
def _zip_bytes(files: dict[str, bytes]) -> bytes:
@ -335,12 +335,37 @@ def test_large_csv_emits_tabular_ref_and_can_query() -> None:
assert str(got.get("engine") or "") in {"builtin_sqlite", "mcp_sqlite"}
def test_medium_csv_enters_tool_mode_with_default_threshold() -> None:
rows = ["c1,c2"] + [f"{i},row-{i}" for i in range(0, 6000)]
payload = ("\n".join(rows)).encode("utf-8")
out = process_file_data("medium-default.csv", payload)
tab_refs = [x for x in out if isinstance(x, dict) and str(x.get("type") or "") == "tabular_ref"]
assert tab_refs
def test_medium_csv_enters_tool_mode_with_default_threshold(tmp_path: Path, monkeypatch) -> None:
"""Isolate from repo ``oclaw.json`` (may raise ``tool_mode_min_rows`` above this test's row count)."""
cfg = {
"plugins": {
"entries": {
"memory-wiki": {
"auto": {
"attachments": {
"tabular": {
"tool_mode_enabled": True,
"tool_mode_min_rows": 5000,
"tool_mode_max_bytes": 30 * 1024 * 1024,
}
}
}
}
}
}
}
cfg_path = tmp_path / "oclaw.json"
cfg_path.write_text(json.dumps(cfg), encoding="utf-8")
monkeypatch.setenv("AIA_OCLAW_CONFIG_PATH", str(cfg_path))
fa._attachments_limits.cache_clear()
try:
rows = ["c1,c2"] + [f"{i},row-{i}" for i in range(0, 6000)]
payload = ("\n".join(rows)).encode("utf-8")
out = process_file_data("medium-default.csv", payload)
tab_refs = [x for x in out if isinstance(x, dict) and str(x.get("type") or "") == "tabular_ref"]
assert tab_refs
finally:
fa._attachments_limits.cache_clear()
def test_large_csv_can_aggregate_grouped_sum() -> None:
@ -578,7 +603,7 @@ def test_excel_sheet_count_cap_applies_in_tool_mode(tmp_path: Path, monkeypatch)
def test_attachment_asset_store_mp4_load_bytes_roundtrip(tmp_path: Path) -> None:
"""Regression: ``load_bytes`` must resolve ``.mp4`` on-disk blobs (not only image extensions)."""
from oclaw.platform.files.attachment_assets import AttachmentAssetStore
from svc.files.attachment_assets import AttachmentAssetStore
ast = AttachmentAssetStore(str(tmp_path))
payload = b"\x00\x00\x00\x18ftypmp42\x00\x00\x00\x00mp42isom" + b"vid" * 400

View file

@ -2,7 +2,7 @@ from __future__ import annotations
import pytest
from oclaw.runtime.prompt_templates.frontmatter import parse_frontmatter_dict, parse_markdown_document
from runtime.prompt_templates.frontmatter import parse_frontmatter_dict, parse_markdown_document
def test_parse_yaml_frontmatter_nested_metadata() -> None:

View file

@ -3,7 +3,7 @@ from __future__ import annotations
import importlib.util
from pathlib import Path
from oclaw.interfaces.gateway.server_plugins import load_gateway_plugins
from interfaces.gateway.server_plugins import load_gateway_plugins
def _load_image_core_generate_image():

View file

@ -2,36 +2,36 @@ from __future__ import annotations
from typing import Any
from oclaw.interfaces.gateway.server_methods.agent import agent_handlers
from oclaw.interfaces.gateway.server_methods.agents import agents_handlers
from oclaw.interfaces.gateway.server_methods.chat import chat_handlers
from oclaw.interfaces.gateway.server_methods.send import send_handlers
from oclaw.interfaces.gateway.server_methods.image import image_handlers
from oclaw.interfaces.gateway.server_methods.skills import skills_handlers
from oclaw.interfaces.gateway.server_methods.system import system_handlers
from oclaw.interfaces.gateway.server_methods.cron import cron_handlers
from oclaw.interfaces.gateway.server_methods.devices import device_handlers
from oclaw.interfaces.gateway.server_methods.models import models_handlers
from oclaw.interfaces.gateway.server_methods.models_auth_status import (
from interfaces.gateway.server_methods.agent import agent_handlers
from interfaces.gateway.server_methods.agents import agents_handlers
from interfaces.gateway.server_methods.chat import chat_handlers
from interfaces.gateway.server_methods.send import send_handlers
from interfaces.gateway.server_methods.image import image_handlers
from interfaces.gateway.server_methods.skills import skills_handlers
from interfaces.gateway.server_methods.system import system_handlers
from interfaces.gateway.server_methods.cron import cron_handlers
from interfaces.gateway.server_methods.devices import device_handlers
from interfaces.gateway.server_methods.models import models_handlers
from interfaces.gateway.server_methods.models_auth_status import (
invalidate_model_auth_status_cache,
models_auth_status_handlers,
)
from oclaw.interfaces.gateway.server_methods.push import push_handlers
from oclaw.interfaces.gateway.server_methods.channels import channels_handlers
from oclaw.interfaces.gateway.server_methods.update import update_handlers
from oclaw.interfaces.gateway.server_methods.voicewake import voicewake_handlers
from oclaw.interfaces.gateway.server_methods.wizard import wizard_handlers
from oclaw.interfaces.gateway.server_methods.tts import tts_handlers
from oclaw.interfaces.gateway.server_methods.web import web_handlers
from oclaw.interfaces.gateway.server_methods.tools_catalog import tools_catalog_handlers
from oclaw.interfaces.gateway.server_methods.tools_effective import tools_effective_handlers
from oclaw.interfaces.gateway.server_methods.talk import talk_handlers
from oclaw.interfaces.gateway.server_methods.usage import usage_handlers
from oclaw.interfaces.gateway.server_methods.exec_approvals import exec_approvals_handlers
from oclaw.interfaces.gateway.server_methods.nodes_pending import node_pending_handlers
from oclaw.interfaces.gateway.server_methods.nodes import node_handlers
from oclaw.interfaces.gateway.server_methods.sessions import sessions_handlers
from oclaw.interfaces.gateway.server_methods.doctor import doctor_handlers
from interfaces.gateway.server_methods.push import push_handlers
from interfaces.gateway.server_methods.channels import channels_handlers
from interfaces.gateway.server_methods.update import update_handlers
from interfaces.gateway.server_methods.voicewake import voicewake_handlers
from interfaces.gateway.server_methods.wizard import wizard_handlers
from interfaces.gateway.server_methods.tts import tts_handlers
from interfaces.gateway.server_methods.web import web_handlers
from interfaces.gateway.server_methods.tools_catalog import tools_catalog_handlers
from interfaces.gateway.server_methods.tools_effective import tools_effective_handlers
from interfaces.gateway.server_methods.talk import talk_handlers
from interfaces.gateway.server_methods.usage import usage_handlers
from interfaces.gateway.server_methods.exec_approvals import exec_approvals_handlers
from interfaces.gateway.server_methods.nodes_pending import node_pending_handlers
from interfaces.gateway.server_methods.nodes import node_handlers
from interfaces.gateway.server_methods.sessions import sessions_handlers
from interfaces.gateway.server_methods.doctor import doctor_handlers
def _call(handler, *, params: dict[str, Any], context: dict[str, Any] | None = None, client: dict[str, Any] | None = None):
@ -310,7 +310,7 @@ def test_cron_add_and_run_fallback() -> None:
def test_image_generate_falls_back_to_registered_openai_provider() -> None:
# Get providers via plugin load, then inject into gateway context.
from oclaw.interfaces.gateway.server_plugins import load_gateway_plugins
from interfaces.gateway.server_plugins import load_gateway_plugins
plugin_out = load_gateway_plugins(
cfg={"plugins": {"enabled": ["openai"]}},

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from oclaw.interfaces.gateway.server_methods.telegram_send_normalize import normalize_transport_target_for_channel
from interfaces.gateway.server_methods.telegram_send_normalize import normalize_transport_target_for_channel
def test_normalize_transport_target_for_channel_non_telegram_passthrough() -> None:

View file

@ -2,7 +2,7 @@ from __future__ import annotations
import os
from oclaw.platform.llm.transports.google_gemini_sse import GoogleGeminiChatModel
from svc.llm.transports.google_gemini_sse import GoogleGeminiChatModel
def test_gemini_tool_decl_uses_parameters_json_schema() -> None:

View file

@ -3,9 +3,9 @@ from __future__ import annotations
import json
from pathlib import Path
from oclaw.runtime.chat.agent_messages import build_llm_messages
from oclaw.platform.llm.chat_models import RuleBasedChatModel
from oclaw.platform.persistence.sqlite_store import SqliteStore
from runtime.chat.agent_messages import build_llm_messages
from svc.llm.chat_models import RuleBasedChatModel
from svc.persistence.sqlite_store import SqliteStore
def test_get_messages_limit_preserves_tool_pairing(tmp_path: Path) -> None:

View file

@ -2,8 +2,8 @@ from __future__ import annotations
import json
from oclaw.platform.persistence.sqlite_store import SqliteStore
from oclaw.runtime.chat.history_tool_result_compact import compact_tool_results_in_session_history
from svc.persistence.sqlite_store import SqliteStore
from runtime.chat.history_tool_result_compact import compact_tool_results_in_session_history
def test_compact_tool_results_in_session_history_rewrites_large_tool_message(tmp_path) -> None: # noqa: ANN001

View file

@ -2,7 +2,7 @@
from __future__ import annotations
from oclaw.platform.llm.image_legacy_client import send_legacy_image_messages
from svc.llm.image_legacy_client import send_legacy_image_messages
def test_legacy_fails_when_only_ocr_env_configured(monkeypatch: object) -> None:
@ -46,7 +46,7 @@ def test_legacy_accepts_explicit_kwargs_without_expert_env(monkeypatch: object)
return R()
import oclaw.platform.llm.image_legacy_client as mod
import svc.llm.image_legacy_client as mod
monkeypatch.setattr(mod, "post_with_retry", fake_post)
out = send_legacy_image_messages(

View file

@ -4,13 +4,13 @@ import json
import pytest
from oclaw.platform.llm.image_http_common import (
from svc.llm.image_http_common import (
dashscope_multimodal_http_ok,
dashscope_native_multimodal_url_from_compatible_base,
extract_text_and_images,
)
from oclaw.platform.llm.image_http_common import build_extract_diag_empty
from oclaw.platform.llm.image_legacy_client import (
from svc.llm.image_http_common import build_extract_diag_empty
from svc.llm.image_legacy_client import (
collect_legacy_lane_images_from_attachments,
collect_legacy_lane_images_with_session_fallback,
legacy_image_assistant_body_with_placeholder,
@ -18,8 +18,8 @@ from oclaw.platform.llm.image_legacy_client import (
normalize_legacy_output_image_urls,
parse_message_attachments_json,
)
from oclaw.platform.llm.image_legacy_client import _http_content_blocks
from oclaw.platform.llm.image_legacy_client import _openai_compatible_vision_content
from svc.llm.image_legacy_client import _http_content_blocks
from svc.llm.image_legacy_client import _openai_compatible_vision_content
def test_openai_compatible_vision_has_type_per_part() -> None:

View file

@ -2,7 +2,7 @@ from __future__ import annotations
from dataclasses import dataclass
from oclaw.runtime.application.gateway.inbound_service import (
from runtime.application.gateway.inbound_service import (
_collect_reply_attachments_from_history,
_collect_recent_tool_attachments,
_maybe_add_media_path_for_wechat_reply,
@ -74,7 +74,7 @@ def test_maybe_add_media_path_for_wechat_reply_sets_media_path(monkeypatch) -> N
return Path("D:/tmp/fake.png")
monkeypatch.setattr(
"oclaw.platform.files.attachment_assets.AttachmentAssetStore.get_local_path",
"svc.files.attachment_assets.AttachmentAssetStore.get_local_path",
_fake_get_local_path,
)
r = {"channel": "wechat", "text": "hi", "attachments": [{"type": "image_ref", "attachment_id": "a1"}]}
@ -94,7 +94,7 @@ def test_maybe_expand_reply_attachments_for_channel_converts_ref_to_base64(monke
return b"abc", _Meta()
monkeypatch.setattr(
"oclaw.platform.files.attachment_assets.AttachmentAssetStore.load_bytes",
"svc.files.attachment_assets.AttachmentAssetStore.load_bytes",
_fake_load_bytes,
)
r = {"channel": "wechat", "attachments": [{"type": "image_ref", "attachment_id": "a1"}]}
@ -117,7 +117,7 @@ def test_maybe_expand_reply_attachments_for_channel_works_for_whatsapp(monkeypat
return b"wa", _Meta()
monkeypatch.setattr(
"oclaw.platform.files.attachment_assets.AttachmentAssetStore.load_bytes",
"svc.files.attachment_assets.AttachmentAssetStore.load_bytes",
_fake_load_bytes,
)
r = {"channel": "whatsapp", "attachments": [{"type": "image_ref", "attachment_id": "wa1"}]}

View file

@ -3,18 +3,18 @@ from __future__ import annotations
import tempfile
from pathlib import Path
from oclaw.runtime.tools.catalog import default_registry
from oclaw.runtime.tools.public.local_sdk import LocalAdapter
from oclaw.runtime.tools.public.edit_file_tool import edit_file_tool
from oclaw.runtime.tools.public.run_command_tool import run_command_tool
from oclaw.runtime.tools.public.read_file_tool import read_file_tool
from oclaw.runtime.tools.public.write_file_tool import write_file_tool
from oclaw.runtime.tools.public_registry import clear_public_tool_cache
from oclaw.runtime.tools.public.list_directory_tool import list_directory_tool
from oclaw.runtime.tools.public.search_files_tool import search_files_tool
from oclaw.runtime.tools.public.get_cwd_tool import get_cwd_tool
from oclaw.runtime.tools.public.get_env_tool import get_env_tool
from oclaw.runtime.tools.public.set_env_tool import set_env_tool
from runtime.tools.catalog import default_registry
from runtime.tools.public.local_sdk import LocalAdapter
from runtime.tools.public.edit_file_tool import edit_file_tool
from runtime.tools.public.run_command_tool import run_command_tool
from runtime.tools.public.read_file_tool import read_file_tool
from runtime.tools.public.write_file_tool import write_file_tool
from runtime.tools.public_registry import clear_public_tool_cache
from runtime.tools.public.list_directory_tool import list_directory_tool
from runtime.tools.public.search_files_tool import search_files_tool
from runtime.tools.public.get_cwd_tool import get_cwd_tool
from runtime.tools.public.get_env_tool import get_env_tool
from runtime.tools.public.set_env_tool import set_env_tool
def test_local_public_read_tool_visible_by_default() -> None:
@ -74,7 +74,7 @@ def test_run_command_tool_handler(monkeypatch) -> None:
def run_command(self, *, command: str, cwd: str | None = None, timeout: int = 300):
return {"ok": True, "command": command, "cwd": cwd, "timeout": timeout}
monkeypatch.setattr("oclaw.runtime.tools.public.run_command_tool.get_local_adapter", lambda: _Adapter())
monkeypatch.setattr("runtime.tools.public.run_command_tool.get_local_adapter", lambda: _Adapter())
spec = run_command_tool()
out = spec.handler({"command": "echo hi", "cwd": "repo", "timeout": 9})
assert out.get("ok") is True
@ -105,7 +105,7 @@ def test_edit_file_tool_handler(monkeypatch) -> None:
"replacement": replacement,
}
monkeypatch.setattr("oclaw.runtime.tools.public.edit_file_tool.get_local_adapter", lambda: _Adapter())
monkeypatch.setattr("runtime.tools.public.edit_file_tool.get_local_adapter", lambda: _Adapter())
spec = edit_file_tool()
out = spec.handler({"path": "a.py", "search": "foo", "replace": "bar"})
assert out.get("ok") is True
@ -225,10 +225,10 @@ def test_run_command_reads_db_toggle_without_ops_db_env(tmp_path: Path, monkeypa
monkeypatch.setenv("AIA_ENABLE_RUN_COMMAND", "0")
db_file = tmp_path / "ops.sqlite"
from oclaw.platform.persistence.sqlite_store import SqliteStore
from svc.persistence.sqlite_store import SqliteStore
SqliteStore(str(db_file)).set_setting("AIA_ENABLE_RUN_COMMAND", "1")
monkeypatch.setattr("oclaw.platform.config.paths.db_path", lambda: str(db_file))
monkeypatch.setattr("svc.config.paths.db_path", lambda: str(db_file))
out = LocalAdapter().run_command(command="echo hi", timeout=10)
assert out.get("ok") is True, out

View file

@ -5,8 +5,8 @@ import tempfile
import unittest
from pathlib import Path
from oclaw.platform.persistence.sqlite_store import SqliteStore
from oclaw.runtime.tools.mcp.adapter import materialize_mcp_tools, materialize_mcp_tools_for_specialist
from svc.persistence.sqlite_store import SqliteStore
from runtime.tools.mcp.adapter import materialize_mcp_tools, materialize_mcp_tools_for_specialist
class McpAdapterTests(unittest.TestCase):
@ -147,7 +147,7 @@ class McpAdapterTests(unittest.TestCase):
self.assertIn("mcp__echo-b__ping", names)
def test_mcp_local_env_file_path_prefers_src_local(self) -> None:
from oclaw.runtime.operations import mcp_env
from runtime.operations import mcp_env
p = mcp_env.mcp_local_env_file_path()
self.assertEqual(p.name, "mcp_local.env")
@ -156,7 +156,7 @@ class McpAdapterTests(unittest.TestCase):
self.assertIn("_local", parts)
def test_mcp_env_allowlist_keys_default_when_unset(self) -> None:
from oclaw.runtime.operations import mcp_env
from runtime.operations import mcp_env
old = os.environ.pop("OPS_MCP_ENV_ALLOWLIST", None)
old_aia = os.environ.pop("AIA_MCP_ENV_ALLOWLIST", None)
@ -182,7 +182,7 @@ class McpAdapterTests(unittest.TestCase):
os.environ["OPS_MCP_ENV_ALLOWLIST_EXTRA"] = old_ops_extra
def test_mcp_env_allowlist_extra_merges_with_default(self) -> None:
from oclaw.runtime.operations import mcp_env
from runtime.operations import mcp_env
old_aia = os.environ.pop("AIA_MCP_ENV_ALLOWLIST", None)
old_extra = os.environ.pop("AIA_MCP_ENV_ALLOWLIST_EXTRA", None)
@ -203,7 +203,7 @@ class McpAdapterTests(unittest.TestCase):
os.environ["OPS_MCP_ENV_ALLOWLIST_EXTRA"] = old_ops_extra
def test_mcp_env_allowlist_explicit_replace_plus_extra(self) -> None:
from oclaw.runtime.operations import mcp_env
from runtime.operations import mcp_env
old_aia = os.environ.pop("AIA_MCP_ENV_ALLOWLIST", None)
old_extra = os.environ.pop("AIA_MCP_ENV_ALLOWLIST_EXTRA", None)

View file

@ -9,10 +9,10 @@ from pathlib import Path
from fastapi.testclient import TestClient
from oclaw.interfaces.http.fastapi_app import create_app
from oclaw.interfaces.admin import routes as admin_routes
from oclaw.platform.config.paths import db_path
from oclaw.platform.persistence.sqlite_store import SqliteStore
from interfaces.http.fastapi_app import create_app
from interfaces.admin import routes as admin_routes
from svc.config.paths import db_path
from svc.persistence.sqlite_store import SqliteStore
class McpAdminApiTests(unittest.TestCase):

View file

@ -2,8 +2,8 @@ from __future__ import annotations
import unittest
from oclaw.interfaces.admin.mcp_e2e_probe import build_mcp_e2e_probe_plans, parse_mcp_bound_tool_name
from oclaw.runtime.tools.base import ToolRegistry, ToolSpec
from interfaces.admin.mcp_e2e_probe import build_mcp_e2e_probe_plans, parse_mcp_bound_tool_name
from runtime.tools.base import ToolRegistry, ToolSpec
class McpE2eProbeTests(unittest.TestCase):

View file

@ -7,8 +7,8 @@ import unittest
from pathlib import Path
from unittest import mock
from oclaw.platform.persistence.sqlite_store import SqliteStore
from oclaw.runtime.tools.mcp.filesystem_argv import augment_filesystem_mcp_argv, build_mcp_process_command
from svc.persistence.sqlite_store import SqliteStore
from runtime.tools.mcp.filesystem_argv import augment_filesystem_mcp_argv, build_mcp_process_command
def _wincase_set(items: list[str]) -> set[str]:

View file

@ -2,14 +2,14 @@ from __future__ import annotations
import unittest
from oclaw.runtime.tools.mcp.installer import (
from runtime.tools.mcp.installer import (
_safe_server_id,
detect_local_dependencies,
install_mcp_server,
preflight_mcp_server,
uninstall_mcp_server,
)
from oclaw.runtime.tools.mcp.manifest import McpServerManifest
from runtime.tools.mcp.manifest import McpServerManifest
class McpInstallerTests(unittest.TestCase):

View file

@ -3,13 +3,13 @@ from __future__ import annotations
import unittest
from unittest.mock import patch
from oclaw.runtime.tools.mcp.market import infer_install_template, search_mcp_market, trending_mcp_market
from runtime.tools.mcp.market import infer_install_template, search_mcp_market, trending_mcp_market
class McpMarketTests(unittest.TestCase):
@patch("oclaw.runtime.tools.mcp.market.search_github_repos")
@patch("oclaw.runtime.tools.mcp.market.search_npm_packages")
@patch("oclaw.runtime.tools.mcp.market.search_pypi_packages")
@patch("runtime.tools.mcp.market.search_github_repos")
@patch("runtime.tools.mcp.market.search_npm_packages")
@patch("runtime.tools.mcp.market.search_pypi_packages")
def test_aggregate_results(self, pypi_mock, npm_mock, gh_mock) -> None:
gh_mock.return_value = [{"source_type": "github", "name": "a"}]
npm_mock.return_value = [{"source_type": "npm", "name": "b"}]
@ -28,7 +28,7 @@ class McpMarketTests(unittest.TestCase):
self.assertEqual(t2["entry_command"], "python")
self.assertEqual(t2["entry_args"][:1], ["-m"])
@patch("oclaw.runtime.tools.mcp.market.search_mcp_market")
@patch("runtime.tools.mcp.market.search_mcp_market")
def test_trending_cache(self, search_mock) -> None:
search_mock.return_value = [{"source_type": "github", "name": "a", "stars": 9}]
rows = trending_mcp_market(force_refresh=True, per_source_limit=2)

View file

@ -4,9 +4,9 @@ import tempfile
import unittest
from pathlib import Path
from oclaw.platform.persistence.sqlite_store import SqliteStore
from oclaw.runtime.tools.mcp.manifest import McpServerManifest
from oclaw.runtime.tools.mcp.registry import McpRegistry
from svc.persistence.sqlite_store import SqliteStore
from runtime.tools.mcp.manifest import McpServerManifest
from runtime.tools.mcp.registry import McpRegistry
class McpRegistryTests(unittest.TestCase):

View file

@ -7,7 +7,7 @@ import unittest
from pathlib import Path
from unittest.mock import patch
from oclaw.runtime.tools.mcp.runtime import McpProcessRuntime
from runtime.tools.mcp.runtime import McpProcessRuntime
class McpRuntimeTests(unittest.TestCase):
@ -71,7 +71,7 @@ class McpRuntimeTests(unittest.TestCase):
finally:
rt.stop()
@patch("oclaw.runtime.operations.mcp_env.mcp_local_env_merged", return_value={"MCP_ONLY_FROM_FILE": "fileval"})
@patch("runtime.operations.mcp_env.mcp_local_env_merged", return_value={"MCP_ONLY_FROM_FILE": "fileval"})
def test_mcp_local_env_keys_passed_without_allowlist_name(self, _mock_merged: object) -> None:
os.environ["MCP_ONLY_FROM_FILE"] = "liveval"
try:

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from oclaw.runtime.tools.mcp.adapter import materialize_mcp_skills_for_specialist
from runtime.tools.mcp.adapter import materialize_mcp_skills_for_specialist
class _Store:

View file

@ -4,7 +4,7 @@ import tempfile
import unittest
from pathlib import Path
from oclaw.platform.persistence.sqlite_store import SqliteStore
from svc.persistence.sqlite_store import SqliteStore
class McpStoreTests(unittest.TestCase):

View file

@ -11,12 +11,12 @@ import tempfile
import unittest
from pathlib import Path
from oclaw.runtime.agents.network_ops_agent import NetworkOpsAgent
from oclaw.platform.llm.chat_models import RuleBasedChatModel
from oclaw.platform.persistence.sqlite_store import SqliteStore
from oclaw.runtime.tools.mcp.adapter import materialize_mcp_tools_for_specialist
from oclaw.runtime.tools.mcp.filesystem_argv import build_mcp_process_command, collect_filesystem_mcp_extra_roots
from oclaw.runtime.tools.mcp.runtime import McpProcessRuntime
from runtime.agents.network_ops_agent import NetworkOpsAgent
from svc.llm.chat_models import RuleBasedChatModel
from svc.persistence.sqlite_store import SqliteStore
from runtime.tools.mcp.adapter import materialize_mcp_tools_for_specialist
from runtime.tools.mcp.filesystem_argv import build_mcp_process_command, collect_filesystem_mcp_extra_roots
from runtime.tools.mcp.runtime import McpProcessRuntime
class McpWorkspaceFilesystemE2ETests(unittest.TestCase):

View file

@ -3,7 +3,7 @@ from __future__ import annotations
import base64
import os
from oclaw.runtime.chat.media_redact import ingest_embedded_image_blobs_as_refs, redact_embedded_image_blobs
from runtime.chat.media_redact import ingest_embedded_image_blobs_as_refs, redact_embedded_image_blobs
def test_redact_nested_mcp_image_block() -> None:

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from oclaw.runtime.tools.catalog import materialize_tool_specs
from runtime.tools.catalog import materialize_tool_specs
def test_memory_tools_only_expose_canonical_names() -> None:

View file

@ -4,8 +4,8 @@ import tempfile
import unittest
from pathlib import Path
from oclaw.runtime.orchestration.memory import maybe_write_turn_memory, semantic_retrieve
from oclaw.platform.persistence.sqlite_store import SqliteStore
from runtime.orchestration.memory import maybe_write_turn_memory, semantic_retrieve
from svc.persistence.sqlite_store import SqliteStore
class MemoryVectorTests(unittest.TestCase):

View file

@ -5,9 +5,9 @@ import os
from pathlib import Path
import sys
from oclaw.interfaces.gateway.python_extensions_loader import build_python_extensions_registry
from oclaw.interfaces.gateway.server_plugins import load_gateway_plugins
from oclaw.runtime.tools.catalog import materialize_tool_specs
from interfaces.gateway.python_extensions_loader import build_python_extensions_registry
from interfaces.gateway.server_plugins import load_gateway_plugins
from runtime.tools.catalog import materialize_tool_specs
def _load_memory_wiki_api_module():

View file

@ -5,7 +5,7 @@ from pathlib import Path
import sys
from types import SimpleNamespace
from oclaw.platform.config.paths import PROJECT_ROOT
from svc.config.paths import PROJECT_ROOT
def _wiki_search_handler(tmp_path: Path):

View file

@ -2,8 +2,8 @@ from __future__ import annotations
from pathlib import Path
from oclaw.platform.config.paths import PROJECT_ROOT
from oclaw.runtime.tools.public.memory_wiki_tools import (
from svc.config.paths import PROJECT_ROOT
from runtime.tools.public.memory_wiki_tools import (
memory_wiki_apply_tool,
memory_wiki_get_tool,
memory_wiki_lint_tool,

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from oclaw.runtime.chat.model_path_audit import ensure_no_tool_or_embedded_image_payload
from runtime.chat.model_path_audit import ensure_no_tool_or_embedded_image_payload
def test_audit_accepts_plain_system_user_messages() -> None:

View file

@ -6,7 +6,7 @@ import pytest
def test_netx_query_ume_ne_inventory_forwards_params(monkeypatch: pytest.MonkeyPatch) -> None:
import oclaw.runtime.tools.experts.network_ops.netx_tools as nt
import runtime.tools.experts.network_ops.netx_tools as nt
calls: list[tuple[str, str, dict[str, Any] | None]] = []
@ -25,7 +25,7 @@ def test_netx_query_ume_ne_inventory_forwards_params(monkeypatch: pytest.MonkeyP
def test_netx_get_ume_ne_requires_id(monkeypatch: pytest.MonkeyPatch) -> None:
import oclaw.runtime.tools.experts.network_ops.netx_tools as nt
import runtime.tools.experts.network_ops.netx_tools as nt
monkeypatch.setattr(nt, "_http_json", lambda *a, **k: {"ok": True, "data": {}})
spec = nt.netx_get_ume_ne_tool()
@ -35,7 +35,7 @@ def test_netx_get_ume_ne_requires_id(monkeypatch: pytest.MonkeyPatch) -> None:
def test_netx_get_ume_ne_quotes_path(monkeypatch: pytest.MonkeyPatch) -> None:
import oclaw.runtime.tools.experts.network_ops.netx_tools as nt
import runtime.tools.experts.network_ops.netx_tools as nt
paths: list[str] = []

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from oclaw.runtime.relay_pointer import build_acp_relay_result, validate_relay_share_envelope
from runtime.relay_pointer import build_acp_relay_result, validate_relay_share_envelope
def test_validate_relay_share_envelope_ok() -> None:

View file

@ -2,12 +2,12 @@ from __future__ import annotations
from pathlib import Path
from oclaw.runtime.agent_core_run import AgentCoreRunInput, run_agent_core
from oclaw.runtime.gateway import OclawGateway
from oclaw.runtime.types import StandardMessage
from oclaw.platform.llm.chat_models import LLMResponse, StaticTextChatModel
from oclaw.platform.persistence.sqlite_store import SqliteStore
from oclaw.runtime.tools.base import ToolRegistry
from runtime.agent_core_run import AgentCoreRunInput, run_agent_core
from runtime.gateway import OclawGateway
from runtime.types import StandardMessage
from svc.llm.chat_models import LLMResponse, StaticTextChatModel
from svc.persistence.sqlite_store import SqliteStore
from runtime.tools.base import ToolRegistry
class _FailOnceModel:

View file

@ -4,11 +4,11 @@ from pathlib import Path
import pytest
from oclaw.runtime.agent_core_run import AgentCoreRunInput, run_agent_core
from oclaw.runtime.types import StandardMessage
from oclaw.platform.llm.chat_models import StaticTextChatModel
from oclaw.platform.persistence.sqlite_store import SqliteStore
from oclaw.runtime.tools.base import ToolRegistry
from runtime.agent_core_run import AgentCoreRunInput, run_agent_core
from runtime.types import StandardMessage
from svc.llm.chat_models import StaticTextChatModel
from svc.persistence.sqlite_store import SqliteStore
from runtime.tools.base import ToolRegistry
def _msg(session_id: str, *, metadata: dict | None = None) -> StandardMessage:

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from oclaw.runtime.command_parser import parse_internal_command
from runtime.command_parser import parse_internal_command
def test_parse_internal_command_basic() -> None:

View file

@ -1,7 +1,7 @@
from __future__ import annotations
from oclaw.runtime.tools.base import ToolSpec
from oclaw.runtime.tools.catalog import _apply_declared_tool_policy
from runtime.tools.base import ToolSpec
from runtime.tools.catalog import _apply_declared_tool_policy
def _tool(name: str, tags: set[str]) -> ToolSpec:

View file

@ -6,7 +6,7 @@ from typing import Any
def test_wait_for_agent_job_is_non_blocking_pending(monkeypatch) -> None:
from oclaw.interfaces.ws import server_methods_bridge as bridge
from interfaces.ws import server_methods_bridge as bridge
class DummyLock:
def __enter__(self) -> None:
@ -51,7 +51,7 @@ def test_wait_for_agent_job_is_non_blocking_pending(monkeypatch) -> None:
def test_turn_runner_emits_delta_only(monkeypatch) -> None:
from oclaw.interfaces.ws import turn_runner
from interfaces.ws import turn_runner
@dataclass
class DummyResult:

View file

@ -4,10 +4,10 @@ import json
from types import SimpleNamespace
import pytest
from oclaw.platform.llm.chat_models import LLMResponse
from oclaw.runtime.gateway import OclawGateway
from oclaw.runtime.tools.base import ToolRegistry, ToolSpec
from oclaw.runtime.types import StandardMessage
from svc.llm.chat_models import LLMResponse
from runtime.gateway import OclawGateway
from runtime.tools.base import ToolRegistry, ToolSpec
from runtime.types import StandardMessage
def test_gateway_async_trace_payload_has_pipeline_and_oc_stage(monkeypatch: pytest.MonkeyPatch) -> None:
@ -28,7 +28,7 @@ def test_gateway_async_trace_payload_has_pipeline_and_oc_stage(monkeypatch: pyte
return T()
monkeypatch.setattr("oclaw.runtime.gateway.ensure_worker_started", lambda store: "worker-1")
monkeypatch.setattr("runtime.gateway.ensure_worker_started", lambda store: "worker-1")
gw = OclawGateway(store=Store())
msg = StandardMessage(
@ -69,7 +69,7 @@ def test_gateway_received_trace_includes_relay_pointer_stats(monkeypatch: pytest
return T()
monkeypatch.setattr("oclaw.runtime.gateway.ensure_worker_started", lambda store: "worker-1")
monkeypatch.setattr("runtime.gateway.ensure_worker_started", lambda store: "worker-1")
gw = OclawGateway(store=Store())
msg = StandardMessage(
@ -119,7 +119,7 @@ def test_gateway_async_task_payload_preserves_relay_envelope(monkeypatch: pytest
return T()
monkeypatch.setattr("oclaw.runtime.gateway.ensure_worker_started", lambda store: "worker-1")
monkeypatch.setattr("runtime.gateway.ensure_worker_started", lambda store: "worker-1")
gw = OclawGateway(store=Store())
msg = StandardMessage(
session_id="sid-3",
@ -165,7 +165,7 @@ def test_gateway_async_task_payload_preserves_acp_ids(monkeypatch: pytest.Monkey
return T()
monkeypatch.setattr("oclaw.runtime.gateway.ensure_worker_started", lambda store: "worker-1")
monkeypatch.setattr("runtime.gateway.ensure_worker_started", lambda store: "worker-1")
gw = OclawGateway(store=Store())
msg = StandardMessage(
session_id="sid-4",
@ -249,7 +249,7 @@ def test_gateway_expert_plan_execution_mode_runs_v2_with_plan_prompt(monkeypatch
captured["system_prompt"] = str(getattr(data, "system_prompt", "") or "")
return SimpleNamespace(outcome=SimpleNamespace(final_text="plan_llm_reply", turn_uuid="turn-1"))
monkeypatch.setattr("oclaw.runtime.gateway.run_agent_core", _run_agent_core_ok)
monkeypatch.setattr("runtime.gateway.run_agent_core", _run_agent_core_ok)
gw = OclawGateway(store=Store())
msg = StandardMessage(
@ -309,7 +309,7 @@ def test_gateway_expert_plan_mode_filters_non_readonly_tools(monkeypatch: pytest
captured["tool_names"] = [t.name for t in tools.list()] if hasattr(tools, "list") else []
return SimpleNamespace(outcome=SimpleNamespace(final_text="ok", turn_uuid="turn-1"))
monkeypatch.setattr("oclaw.runtime.gateway.run_agent_core", _run_agent_core_ok)
monkeypatch.setattr("runtime.gateway.run_agent_core", _run_agent_core_ok)
gw = OclawGateway(store=Store())
msg = StandardMessage(
@ -368,7 +368,7 @@ def test_gateway_expert_agent_mode_injects_plan_control_tools(monkeypatch: pytes
captured["tool_names"] = [t.name for t in tools.list()] if hasattr(tools, "list") else []
return SimpleNamespace(outcome=SimpleNamespace(final_text="ok", turn_uuid="turn-1"))
monkeypatch.setattr("oclaw.runtime.gateway.run_agent_core", _run_agent_core_ok)
monkeypatch.setattr("runtime.gateway.run_agent_core", _run_agent_core_ok)
store = Store()
store.kv["AIA_EXPERT_PLAN_AGENT_V2_ENABLED"] = "1"
@ -413,7 +413,7 @@ def test_gateway_comprehensive_mode_manager_first_selects_specialist(monkeypatch
self.system_prompt = ""
monkeypatch.setattr(
"oclaw.runtime.gateway.get_manager_prompt_prebuild",
"runtime.gateway.get_manager_prompt_prebuild",
lambda **kwargs: {
"manager_context": "manager",
"allowed_fixed": ("generalist", "ops", "memory", "image"),
@ -428,7 +428,7 @@ def test_gateway_comprehensive_mode_manager_first_selects_specialist(monkeypatch
captured["persisted_user_text"] = getattr(data, "persisted_user_text", None)
return SimpleNamespace(outcome=SimpleNamespace(final_text="specialist_answer"))
monkeypatch.setattr("oclaw.runtime.gateway.run_agent_core", _run_agent_core)
monkeypatch.setattr("runtime.gateway.run_agent_core", _run_agent_core)
chosen: dict[str, str] = {}
@ -482,7 +482,7 @@ def test_gateway_comprehensive_mode_writes_task_assignment_reasoning(monkeypatch
self.system_prompt = ""
monkeypatch.setattr(
"oclaw.runtime.gateway.get_manager_prompt_prebuild",
"runtime.gateway.get_manager_prompt_prebuild",
lambda **kwargs: {
"manager_context": "manager",
"allowed_fixed": ("generalist", "ops", "memory", "image"),
@ -490,7 +490,7 @@ def test_gateway_comprehensive_mode_writes_task_assignment_reasoning(monkeypatch
},
)
monkeypatch.setattr(
"oclaw.runtime.gateway.run_agent_core",
"runtime.gateway.run_agent_core",
lambda **kwargs: SimpleNamespace(outcome=SimpleNamespace(final_text="specialist_answer")),
)
@ -541,7 +541,7 @@ def test_gateway_comprehensive_ignores_wiki_inject_flags(monkeypatch: pytest.Mon
self.system_prompt = ""
monkeypatch.setattr(
"oclaw.runtime.gateway.get_manager_prompt_prebuild",
"runtime.gateway.get_manager_prompt_prebuild",
lambda **kwargs: {
"manager_context": "manager",
"allowed_fixed": ("generalist", "ops", "memory", "image"),
@ -556,7 +556,7 @@ def test_gateway_comprehensive_ignores_wiki_inject_flags(monkeypatch: pytest.Mon
captured["metadata"] = dict(getattr(msg, "metadata", {}) or {})
return SimpleNamespace(outcome=SimpleNamespace(final_text="ok"))
monkeypatch.setattr("oclaw.runtime.gateway.run_agent_core", _run_agent_core)
monkeypatch.setattr("runtime.gateway.run_agent_core", _run_agent_core)
gw = OclawGateway(store=Store())
msg = StandardMessage(
@ -604,7 +604,7 @@ def test_gateway_comprehensive_mode_has_manager_final_pass(monkeypatch: pytest.M
self.system_prompt = ""
monkeypatch.setattr(
"oclaw.runtime.gateway.get_manager_prompt_prebuild",
"runtime.gateway.get_manager_prompt_prebuild",
lambda **kwargs: {
"manager_context": "manager",
"allowed_fixed": ("generalist", "ops", "memory", "image"),
@ -612,7 +612,7 @@ def test_gateway_comprehensive_mode_has_manager_final_pass(monkeypatch: pytest.M
},
)
monkeypatch.setattr(
"oclaw.runtime.gateway.run_agent_core",
"runtime.gateway.run_agent_core",
lambda **kwargs: SimpleNamespace(outcome=SimpleNamespace(final_text="specialist_answer")),
)
@ -660,14 +660,14 @@ def test_gateway_comprehensive_mode_dynamic_agent_dispatches_instruction_only(mo
self.system_prompt = ""
monkeypatch.setattr(
"oclaw.runtime.gateway.get_manager_prompt_prebuild",
"runtime.gateway.get_manager_prompt_prebuild",
lambda **kwargs: {
"manager_context": "manager",
"allowed_fixed": ("generalist", "ops", "memory", "image"),
"allowed_fixed_quoted": '"generalist", "ops", "memory", "image"',
},
)
monkeypatch.setattr("oclaw.runtime.gateway.build_ephemeral_executor", lambda *args, **kwargs: _Exec(model=object()))
monkeypatch.setattr("runtime.gateway.build_ephemeral_executor", lambda *args, **kwargs: _Exec(model=object()))
captured: dict = {}
@ -676,7 +676,7 @@ def test_gateway_comprehensive_mode_dynamic_agent_dispatches_instruction_only(mo
captured["exec_text"] = getattr(getattr(data, "msg", None), "text", None)
return SimpleNamespace(outcome=SimpleNamespace(final_text="dynamic_specialist_answer"))
monkeypatch.setattr("oclaw.runtime.gateway.run_agent_core", _run_agent_core)
monkeypatch.setattr("runtime.gateway.run_agent_core", _run_agent_core)
gw = OclawGateway(store=Store())
msg = StandardMessage(
@ -723,7 +723,7 @@ def test_gateway_comprehensive_mode_ignores_manager_self_and_dispatches_speciali
self.system_prompt = ""
monkeypatch.setattr(
"oclaw.runtime.gateway.get_manager_prompt_prebuild",
"runtime.gateway.get_manager_prompt_prebuild",
lambda **kwargs: {
"manager_context": "manager",
"allowed_fixed": ("generalist", "ops", "memory", "image"),
@ -745,7 +745,7 @@ def test_gateway_comprehensive_mode_ignores_manager_self_and_dispatches_speciali
return _Out()
monkeypatch.setattr("oclaw.runtime.gateway.run_agent_core", _run_agent_core)
monkeypatch.setattr("runtime.gateway.run_agent_core", _run_agent_core)
gw = OclawGateway(store=Store())
msg = StandardMessage(
@ -800,7 +800,7 @@ def test_gateway_comprehensive_mode_suppresses_instruction_echo(monkeypatch: pyt
self.system_prompt = ""
monkeypatch.setattr(
"oclaw.runtime.gateway.get_manager_prompt_prebuild",
"runtime.gateway.get_manager_prompt_prebuild",
lambda **kwargs: {
"manager_context": "manager",
"allowed_fixed": ("generalist", "ops", "memory", "image"),
@ -818,7 +818,7 @@ def test_gateway_comprehensive_mode_suppresses_instruction_echo(monkeypatch: pyt
return _Out()
monkeypatch.setattr("oclaw.runtime.gateway.run_agent_core", _run_agent_core)
monkeypatch.setattr("runtime.gateway.run_agent_core", _run_agent_core)
gw = OclawGateway(store=Store())
msg = StandardMessage(
@ -856,17 +856,17 @@ def test_gateway_command_hook_uses_parsed_command_and_context(monkeypatch: pytes
return T()
monkeypatch.setattr("oclaw.runtime.gateway.ensure_worker_started", lambda store: "worker-1")
monkeypatch.setattr("oclaw.runtime.gateway.initialize_hooks_runtime", lambda **kwargs: 0)
monkeypatch.setattr("runtime.gateway.ensure_worker_started", lambda store: "worker-1")
monkeypatch.setattr("runtime.gateway.initialize_hooks_runtime", lambda **kwargs: 0)
monkeypatch.setattr(
"oclaw.runtime.gateway.get_active_hooks_config",
"runtime.gateway.get_active_hooks_config",
lambda: {"hooks": {"internal": {"enabled": True, "entries": {"session-memory": {"messages": 33}}}}},
)
def _capture(**kwargs):
calls.append(dict(kwargs))
monkeypatch.setattr("oclaw.runtime.gateway.trigger_hook_event", _capture)
monkeypatch.setattr("runtime.gateway.trigger_hook_event", _capture)
gw = OclawGateway(store=Store())
msg = StandardMessage(

View file

@ -3,8 +3,8 @@ from __future__ import annotations
import os
from pathlib import Path
from oclaw.runtime.agents.factory import build_gateway_executor
from oclaw.platform.persistence.sqlite_store import SqliteStore
from runtime.agents.factory import build_gateway_executor
from svc.persistence.sqlite_store import SqliteStore
def test_build_gateway_executor_defaults_to_generalist(tmp_path: Path) -> None:

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from oclaw.runtime.hooks.gmail_watcher import start_gmail_watcher
from runtime.hooks.gmail_watcher import start_gmail_watcher
def test_start_gmail_watcher_top_level_hooks_disabled() -> None:

View file

@ -2,8 +2,8 @@ from __future__ import annotations
from dataclasses import dataclass, field
from oclaw.runtime.hooks.gmail_watcher import GmailWatcherResult
from oclaw.runtime.hooks.gmail_watcher_lifecycle import start_gmail_watcher_with_logs
from runtime.hooks.gmail_watcher import GmailWatcherResult
from runtime.hooks.gmail_watcher_lifecycle import start_gmail_watcher_with_logs
@dataclass

View file

@ -7,8 +7,8 @@ import shutil
import pytest
from pathlib import Path
from oclaw.runtime.hooks.internal_hooks import clear_hooks, create_hook_event, trigger_hook
from oclaw.runtime.hooks.loader import load_internal_hooks
from runtime.hooks.internal_hooks import clear_hooks, create_hook_event, trigger_hook
from runtime.hooks.loader import load_internal_hooks
def _load_module(module_path: Path):
@ -97,8 +97,8 @@ def test_bootstrap_extra_files_only_injects_allowed_basenames(tmp_path: Path) ->
def test_workspace_hook_discovery_supports_package_manifest_hooks(tmp_path: Path) -> None:
from oclaw.runtime.hooks.workspace import load_hook_entries_from_dir
from oclaw.runtime.hooks.hook_types import ensure_entry_dict
from runtime.hooks.workspace import load_hook_entries_from_dir
from runtime.hooks.hook_types import ensure_entry_dict
hooks_root = tmp_path / "hooks"
pkg = hooks_root / "pack-a"
@ -135,7 +135,7 @@ def test_workspace_hook_discovery_supports_package_manifest_hooks(tmp_path: Path
def test_hook_frontmatter_metadata_normalization() -> None:
from oclaw.runtime.hooks.frontmatter import parse_frontmatter, resolve_oclaw_metadata
from runtime.hooks.frontmatter import parse_frontmatter, resolve_oclaw_metadata
content = (
"---\n"
@ -176,8 +176,8 @@ def test_hook_frontmatter_metadata_normalization() -> None:
def test_hook_invocation_policy_disables_loading_even_when_config_enabled(tmp_path: Path) -> None:
from oclaw.runtime.hooks.loader import load_internal_hooks
from oclaw.runtime.hooks.internal_hooks import clear_hooks, create_hook_event, trigger_hook
from runtime.hooks.loader import load_internal_hooks
from runtime.hooks.internal_hooks import clear_hooks, create_hook_event, trigger_hook
hooks_root = tmp_path / "hooks"
demo = hooks_root / "demo"
@ -214,8 +214,8 @@ def test_hook_invocation_policy_disables_loading_even_when_config_enabled(tmp_pa
def test_should_include_hook_respects_requires_env_and_config(monkeypatch) -> None:
from oclaw.runtime.hooks.config import should_include_hook
from oclaw.runtime.hooks.hook_types import ensure_hook_entry
from runtime.hooks.config import should_include_hook
from runtime.hooks.hook_types import ensure_hook_entry
entry_raw = {
"hook": {"name": "demo", "source": "oclaw-managed"},
@ -236,8 +236,8 @@ def test_should_include_hook_respects_requires_env_and_config(monkeypatch) -> No
def test_should_include_hook_respects_os_allowlist() -> None:
from oclaw.runtime.hooks.config import should_include_hook
from oclaw.runtime.hooks.hook_types import ensure_hook_entry
from runtime.hooks.config import should_include_hook
from runtime.hooks.hook_types import ensure_hook_entry
entry = ensure_hook_entry({
"hook": {"name": "demo", "source": "oclaw-managed"},
@ -249,8 +249,8 @@ def test_should_include_hook_respects_os_allowlist() -> None:
def test_should_include_hook_requires_bins_all_must_exist() -> None:
from oclaw.runtime.hooks.config import should_include_hook
from oclaw.runtime.hooks.hook_types import ensure_hook_entry
from runtime.hooks.config import should_include_hook
from runtime.hooks.hook_types import ensure_hook_entry
entry = ensure_hook_entry({
"hook": {"name": "demo", "source": "oclaw-managed"},
@ -262,8 +262,8 @@ def test_should_include_hook_requires_bins_all_must_exist() -> None:
def test_should_include_hook_requires_any_bins_at_least_one() -> None:
from oclaw.runtime.hooks.config import should_include_hook
from oclaw.runtime.hooks.hook_types import ensure_hook_entry
from runtime.hooks.config import should_include_hook
from runtime.hooks.hook_types import ensure_hook_entry
entry_ok = ensure_hook_entry({
"hook": {"name": "demo", "source": "oclaw-managed"},
@ -281,8 +281,8 @@ def test_should_include_hook_requires_any_bins_at_least_one() -> None:
def test_should_include_hook_requires_config_path_truthy() -> None:
from oclaw.runtime.hooks.config import should_include_hook
from oclaw.runtime.hooks.hook_types import ensure_hook_entry
from runtime.hooks.config import should_include_hook
from runtime.hooks.hook_types import ensure_hook_entry
entry = ensure_hook_entry({
"hook": {"name": "demo", "source": "oclaw-managed"},
@ -296,7 +296,7 @@ def test_should_include_hook_requires_config_path_truthy() -> None:
def test_parse_hook_manifest_core_roundtrip() -> None:
from oclaw.runtime.hooks.hook_manifest_core import parse_hook_manifest
from runtime.hooks.hook_manifest_core import parse_hook_manifest
fm = {
"name": "demo-hook",
@ -327,8 +327,8 @@ def test_parse_hook_manifest_core_roundtrip() -> None:
def test_compat_wrappers_accept_dict_entries() -> None:
from oclaw.runtime.hooks.config import should_include_hook_compat
from oclaw.runtime.hooks.policy import resolve_hook_entries_compat
from runtime.hooks.config import should_include_hook_compat
from runtime.hooks.policy import resolve_hook_entries_compat
entry = {
"hook": {"name": "demo", "description": "", "source": "oclaw-managed", "filePath": "", "baseDir": "", "handlerPath": ""},
@ -344,7 +344,7 @@ def test_compat_wrappers_accept_dict_entries() -> None:
def test_ensure_hook_entry_normalizes_unknown_source() -> None:
from oclaw.runtime.hooks.hook_types import ensure_hook_entry
from runtime.hooks.hook_types import ensure_hook_entry
row = {"hook": {"name": "x", "source": "unknown-source"}}
entry = ensure_hook_entry(row)
@ -352,8 +352,8 @@ def test_ensure_hook_entry_normalizes_unknown_source() -> None:
def test_should_include_hook_remote_eligibility_overrides_local_runtime() -> None:
from oclaw.runtime.hooks.config import should_include_hook
from oclaw.runtime.hooks.hook_types import ensure_hook_entry
from runtime.hooks.config import should_include_hook
from runtime.hooks.hook_types import ensure_hook_entry
entry = ensure_hook_entry(
{
@ -380,7 +380,7 @@ def test_should_include_hook_remote_eligibility_overrides_local_runtime() -> Non
def test_workspace_discovers_enabled_plugin_hook_dirs(tmp_path: Path) -> None:
from oclaw.runtime.hooks.workspace import load_workspace_hook_entries
from runtime.hooks.workspace import load_workspace_hook_entries
ws = tmp_path / "ws"
plugin_root = ws / ".openclaw" / "extensions" / "sample-bundle"
@ -413,7 +413,7 @@ def test_workspace_discovers_enabled_plugin_hook_dirs(tmp_path: Path) -> None:
def test_workspace_skips_disabled_plugin_hook_dirs(tmp_path: Path) -> None:
from oclaw.runtime.hooks.workspace import load_workspace_hook_entries
from runtime.hooks.workspace import load_workspace_hook_entries
ws = tmp_path / "ws"
plugin_root = ws / ".openclaw" / "extensions" / "sample-bundle"
@ -438,13 +438,13 @@ def test_workspace_skips_disabled_plugin_hook_dirs(tmp_path: Path) -> None:
def test_legacy_internal_hook_handler_loads_from_workspace_relative_path(tmp_path: Path) -> None:
from oclaw.runtime.hooks.internal_hooks import (
from runtime.hooks.internal_hooks import (
clear_hooks,
create_hook_event,
set_hooks_enabled,
trigger_hook,
)
from oclaw.runtime.hooks.loader import load_internal_hooks
from runtime.hooks.loader import load_internal_hooks
(tmp_path / "hooks").mkdir(parents=True, exist_ok=True)
legacy_path = tmp_path / "legacy_handler.py"
@ -476,7 +476,7 @@ def test_legacy_internal_hook_handler_loads_from_workspace_relative_path(tmp_pat
def test_legacy_internal_hook_handler_rejects_path_escape(tmp_path: Path) -> None:
from oclaw.runtime.hooks.loader import load_internal_hooks
from runtime.hooks.loader import load_internal_hooks
(tmp_path / "hooks").mkdir(parents=True, exist_ok=True)
cfg = {
@ -491,7 +491,7 @@ def test_legacy_internal_hook_handler_rejects_path_escape(tmp_path: Path) -> Non
def test_build_workspace_hook_status_reports_summary(tmp_path: Path) -> None:
from oclaw.runtime.hooks.hooks_status import build_workspace_hook_status
from runtime.hooks.hooks_status import build_workspace_hook_status
ws = tmp_path / "ws"
ok_dir = ws / "hooks" / "ok-hook"
@ -532,7 +532,7 @@ def test_build_workspace_hook_status_reports_summary(tmp_path: Path) -> None:
def test_build_workspace_hook_status_includes_install_options_and_missing_bins(tmp_path: Path) -> None:
from oclaw.runtime.hooks.hooks_status import build_workspace_hook_status
from runtime.hooks.hooks_status import build_workspace_hook_status
ws = tmp_path / "ws"
hook_dir = ws / "hooks" / "installable-hook"
@ -572,7 +572,7 @@ def test_build_workspace_hook_status_includes_install_options_and_missing_bins(t
def test_build_workspace_hook_status_selects_best_install_suggestion(tmp_path: Path) -> None:
from oclaw.runtime.hooks.hooks_status import build_workspace_hook_status
from runtime.hooks.hooks_status import build_workspace_hook_status
ws = tmp_path / "ws"
hook_dir = ws / "hooks" / "smart-install-hook"
@ -608,7 +608,7 @@ def test_build_workspace_hook_status_selects_best_install_suggestion(tmp_path: P
def test_hook_dir_prefers_handler_py_over_ts_and_sh(tmp_path: Path) -> None:
from oclaw.runtime.hooks.workspace import load_hook_entries_from_dir
from runtime.hooks.workspace import load_hook_entries_from_dir
h = tmp_path / "h"
h.mkdir()
@ -631,7 +631,7 @@ def test_hook_dir_prefers_handler_py_over_ts_and_sh(tmp_path: Path) -> None:
def test_hook_dir_selects_ts_over_sh_when_no_py(tmp_path: Path) -> None:
from oclaw.runtime.hooks.workspace import load_hook_entries_from_dir
from runtime.hooks.workspace import load_hook_entries_from_dir
h = tmp_path / "h2"
h.mkdir()
@ -653,7 +653,7 @@ def test_hook_dir_selects_ts_over_sh_when_no_py(tmp_path: Path) -> None:
def test_hook_dir_prefers_mjs_over_sh_and_bash(tmp_path: Path) -> None:
from oclaw.runtime.hooks.workspace import load_hook_entries_from_dir
from runtime.hooks.workspace import load_hook_entries_from_dir
h = tmp_path / "h4"
h.mkdir()
@ -676,7 +676,7 @@ def test_hook_dir_prefers_mjs_over_sh_and_bash(tmp_path: Path) -> None:
def test_hook_dir_selects_sh_when_only_shell(tmp_path: Path) -> None:
from oclaw.runtime.hooks.workspace import load_hook_entries_from_dir
from runtime.hooks.workspace import load_hook_entries_from_dir
h = tmp_path / "h3"
h.mkdir()
@ -698,8 +698,8 @@ def test_hook_dir_selects_sh_when_only_shell(tmp_path: Path) -> None:
@pytest.mark.skipif(shutil.which("bash") is None, reason="bash not available")
def test_sh_hook_merges_stdout_context(tmp_path: Path) -> None:
from oclaw.runtime.hooks.internal_hooks import clear_hooks, create_hook_event, trigger_hook
from oclaw.runtime.hooks.loader import load_internal_hooks
from runtime.hooks.internal_hooks import clear_hooks, create_hook_event, trigger_hook
from runtime.hooks.loader import load_internal_hooks
hooks = tmp_path / "hooks"
h = hooks / "sh-hook"
@ -744,8 +744,8 @@ def test_sh_hook_merges_stdout_context(tmp_path: Path) -> None:
@pytest.mark.skipif(shutil.which("node") is None, reason="node not available")
def test_mjs_module_hook_mutates_context(tmp_path: Path) -> None:
from oclaw.runtime.hooks.internal_hooks import clear_hooks, create_hook_event, trigger_hook
from oclaw.runtime.hooks.loader import load_internal_hooks
from runtime.hooks.internal_hooks import clear_hooks, create_hook_event, trigger_hook
from runtime.hooks.loader import load_internal_hooks
hooks = tmp_path / "hooks"
h = hooks / "jmod"
@ -783,8 +783,8 @@ def test_mjs_module_hook_mutates_context(tmp_path: Path) -> None:
@pytest.mark.skipif(shutil.which("node") is None, reason="node not available")
def test_mjs_script_mode_hook_merges_stdout(tmp_path: Path) -> None:
from oclaw.runtime.hooks.internal_hooks import clear_hooks, create_hook_event, trigger_hook
from oclaw.runtime.hooks.loader import load_internal_hooks
from runtime.hooks.internal_hooks import clear_hooks, create_hook_event, trigger_hook
from runtime.hooks.loader import load_internal_hooks
hooks = tmp_path / "hooks2"
h = hooks / "jscr"

View file

@ -4,7 +4,7 @@ import argparse
import json
from pathlib import Path
from oclaw.runtime.hooks.user_config_hooks import apply_hook_entry_enabled, load_storage_config_document, save_storage_config_document
from runtime.hooks.user_config_hooks import apply_hook_entry_enabled, load_storage_config_document, save_storage_config_document
def test_apply_hook_entry_enabled_roundtrip(tmp_path, monkeypatch) -> None:
@ -52,7 +52,7 @@ def test_hooks_enable_disable_workspace_hook(tmp_path, monkeypatch) -> None:
)
(h / "handler.py").write_text("def handle(event):\n return None\n", encoding="utf-8")
from oclaw.runtime.operations.hooks_cmd import _cmd_hooks_disable, _cmd_hooks_enable
from runtime.operations.hooks_cmd import _cmd_hooks_disable, _cmd_hooks_enable
assert _cmd_hooks_enable(argparse.Namespace(workspace=str(ws), name="toggle-hook")) == 0
doc = json.loads((tmp_path / "cfg.json").read_text(encoding="utf-8"))

View file

@ -2,9 +2,9 @@ from __future__ import annotations
import platform
from oclaw.runtime.hooks.config import should_include_hook
from oclaw.runtime.hooks.eligibility_from_metadata import hook_eligibility_from_message_metadata
from oclaw.runtime.hooks.hook_types import HookEntry, HookInvocation, HookRef
from runtime.hooks.config import should_include_hook
from runtime.hooks.eligibility_from_metadata import hook_eligibility_from_message_metadata
from runtime.hooks.hook_types import HookEntry, HookInvocation, HookRef
def _entry(*, name: str = "x", bins: tuple[str, ...] = (), os_list: tuple[str, ...] = ()) -> HookEntry:

View file

@ -3,8 +3,8 @@ from __future__ import annotations
import json
from pathlib import Path
from oclaw.runtime.hooks.eligibility_from_metadata import hook_eligibility_from_message_metadata
from oclaw.runtime.hooks_runtime import (
from runtime.hooks.eligibility_from_metadata import hook_eligibility_from_message_metadata
from runtime.hooks_runtime import (
_reset_hooks_runtime_state_for_test,
initialize_hooks_runtime,
resolve_runtime_config,
@ -42,8 +42,8 @@ def test_initialize_hooks_runtime_passes_remote_eligibility(monkeypatch, tmp_pat
_reset_hooks_runtime_state_for_test()
empty_bundled = tmp_path / "empty-bundled"
empty_bundled.mkdir(parents=True, exist_ok=True)
monkeypatch.setattr("oclaw.runtime.hooks_runtime.runtime_hooks_bundled_root", lambda: str(empty_bundled))
monkeypatch.setattr("oclaw.runtime.hooks.merge_skill_hook_dirs.discover_workspace_skill_manifests", lambda: ())
monkeypatch.setattr("runtime.hooks_runtime.runtime_hooks_bundled_root", lambda: str(empty_bundled))
monkeypatch.setattr("runtime.hooks.merge_skill_hook_dirs.discover_workspace_skill_manifests", lambda: ())
ws = tmp_path / "workspace"
hook_dir = ws / "hooks" / "demo"
@ -76,8 +76,8 @@ def test_initialize_hooks_runtime_loads_when_metadata_bins_present_reports_requi
_reset_hooks_runtime_state_for_test()
empty_bundled = tmp_path / "empty-bundled"
empty_bundled.mkdir(parents=True, exist_ok=True)
monkeypatch.setattr("oclaw.runtime.hooks_runtime.runtime_hooks_bundled_root", lambda: str(empty_bundled))
monkeypatch.setattr("oclaw.runtime.hooks.merge_skill_hook_dirs.discover_workspace_skill_manifests", lambda: ())
monkeypatch.setattr("runtime.hooks_runtime.runtime_hooks_bundled_root", lambda: str(empty_bundled))
monkeypatch.setattr("runtime.hooks.merge_skill_hook_dirs.discover_workspace_skill_manifests", lambda: ())
ws = tmp_path / "workspace"
hook_dir = ws / "hooks" / "demo"

View file

@ -2,7 +2,7 @@ from __future__ import annotations
from pathlib import Path
from oclaw.runtime.hooks_runtime import _reset_hooks_runtime_state_for_test, initialize_hooks_runtime
from runtime.hooks_runtime import _reset_hooks_runtime_state_for_test, initialize_hooks_runtime
def test_initialize_hooks_runtime_invokes_gmail_lifecycle(monkeypatch, tmp_path: Path) -> None:
@ -13,13 +13,13 @@ def test_initialize_hooks_runtime_invokes_gmail_lifecycle(monkeypatch, tmp_path:
calls.append(cfg)
monkeypatch.setattr(
"oclaw.runtime.hooks.gmail_watcher_lifecycle.start_gmail_watcher_with_logs",
"runtime.hooks.gmail_watcher_lifecycle.start_gmail_watcher_with_logs",
_cap,
)
bundled = tmp_path / "bundled"
bundled.mkdir()
monkeypatch.setattr("oclaw.runtime.hooks_runtime.runtime_hooks_bundled_root", lambda: str(bundled))
monkeypatch.setattr("oclaw.runtime.hooks.merge_skill_hook_dirs.discover_workspace_skill_manifests", lambda: ())
monkeypatch.setattr("runtime.hooks_runtime.runtime_hooks_bundled_root", lambda: str(bundled))
monkeypatch.setattr("runtime.hooks.merge_skill_hook_dirs.discover_workspace_skill_manifests", lambda: ())
ws = tmp_path / "ws"
ws.mkdir()

View file

@ -4,9 +4,9 @@ from pathlib import Path
import pytest
from oclaw.runtime.memory_stage import after_turn_memory, render_memory_context_block
from oclaw.runtime.types import OclawMemoryContext
from oclaw.platform.persistence.sqlite_store import SqliteStore
from runtime.memory_stage import after_turn_memory, render_memory_context_block
from runtime.types import OclawMemoryContext
from svc.persistence.sqlite_store import SqliteStore
def test_render_memory_context_block_contains_sections() -> None:
@ -28,7 +28,7 @@ def test_after_turn_memory_invokes_maybe_write_turn_memory(tmp_path: Path, monke
calls.append({"store": store, **kwargs})
return {"ok": True, "written": 0, "reason": "stub"}
monkeypatch.setattr("oclaw.runtime.orchestration.memory.maybe_write_turn_memory", _fake_maybe_write)
monkeypatch.setattr("runtime.orchestration.memory.maybe_write_turn_memory", _fake_maybe_write)
store = SqliteStore(str(tmp_path / "m.sqlite"))
store.create_session("s1")

View file

@ -7,7 +7,7 @@ import sys
def test_build_hooks_status_report_empty_workspace(tmp_path, monkeypatch) -> None:
monkeypatch.chdir(tmp_path)
from oclaw.runtime.operations.hooks_cmd import build_hooks_status_report
from runtime.operations.hooks_cmd import build_hooks_status_report
r = build_hooks_status_report(str(tmp_path), config={"hooks": {"internal": {"enabled": True}}})
assert "summary" in r and "hooks" in r
@ -16,7 +16,7 @@ def test_build_hooks_status_report_empty_workspace(tmp_path, monkeypatch) -> Non
def test_hooks_list_json(capsys, tmp_path, monkeypatch) -> None:
monkeypatch.chdir(tmp_path)
from oclaw.runtime.operations.hooks_cmd import _cmd_hooks_list
from runtime.operations.hooks_cmd import _cmd_hooks_list
ns = argparse.Namespace(workspace=str(tmp_path), json=True, eligible=False, verbose=False)
assert _cmd_hooks_list(ns) == 0
@ -28,7 +28,7 @@ def test_hooks_list_json(capsys, tmp_path, monkeypatch) -> None:
def test_hooks_check_text(capsys, tmp_path, monkeypatch) -> None:
monkeypatch.chdir(tmp_path)
from oclaw.runtime.operations.hooks_cmd import _cmd_hooks_check
from runtime.operations.hooks_cmd import _cmd_hooks_check
ns = argparse.Namespace(workspace=str(tmp_path), json=False)
assert _cmd_hooks_check(ns) == 0
@ -37,7 +37,7 @@ def test_hooks_check_text(capsys, tmp_path, monkeypatch) -> None:
def test_hooks_info_missing(capsys, tmp_path, monkeypatch) -> None:
monkeypatch.chdir(tmp_path)
from oclaw.runtime.operations.hooks_cmd import _cmd_hooks_info
from runtime.operations.hooks_cmd import _cmd_hooks_info
ns = argparse.Namespace(workspace=str(tmp_path), name="nonexistent-hook-xyz", json=False)
assert _cmd_hooks_info(ns) == 1
@ -45,7 +45,7 @@ def test_hooks_info_missing(capsys, tmp_path, monkeypatch) -> None:
def test_hooks_install_deprecated_exits_2(capsys) -> None:
from oclaw.runtime.operations.hooks_cmd import _cmd_hooks_install
from runtime.operations.hooks_cmd import _cmd_hooks_install
ns = argparse.Namespace(spec="foo@1.0.0", link=False, pin=False)
assert _cmd_hooks_install(ns) == 2
@ -54,14 +54,14 @@ def test_hooks_install_deprecated_exits_2(capsys) -> None:
def test_hooks_install_missing_spec_exits_1(capsys) -> None:
from oclaw.runtime.operations.hooks_cmd import _cmd_hooks_install
from runtime.operations.hooks_cmd import _cmd_hooks_install
assert _cmd_hooks_install(argparse.Namespace(spec="", link=False, pin=False)) == 1
assert "missing" in capsys.readouterr().err.lower()
def test_hooks_update_deprecated_exits_2(capsys) -> None:
from oclaw.runtime.operations.hooks_cmd import _cmd_hooks_update
from runtime.operations.hooks_cmd import _cmd_hooks_update
assert _cmd_hooks_update(argparse.Namespace(hook_id="pack-a", all=False, dry_run=True)) == 2
err = capsys.readouterr().err
@ -69,7 +69,7 @@ def test_hooks_update_deprecated_exits_2(capsys) -> None:
def test_main_hooks_install_invocation(capsys) -> None:
from oclaw.runtime.operations import main as cli_main
from runtime.operations import main as cli_main
code = cli_main(["hooks", "install", "some-spec@1"])
assert code == 2
@ -78,7 +78,7 @@ def test_main_hooks_install_invocation(capsys) -> None:
def test_main_hooks_list_invocation(tmp_path, monkeypatch) -> None:
monkeypatch.chdir(tmp_path)
from oclaw.runtime.operations import main as cli_main
from runtime.operations import main as cli_main
old = sys.stdout
buf = StringIO()
@ -97,7 +97,7 @@ def test_resolve_cli_workspace_uses_env_over_cwd(tmp_path, monkeypatch) -> None:
expected = tmp_path / "repo-root"
expected.mkdir(parents=True)
monkeypatch.setenv("OCLAW_WORKSPACE", str(expected))
from oclaw.runtime.operations.hooks_cmd import _resolve_cli_workspace
from runtime.operations.hooks_cmd import _resolve_cli_workspace
ns = argparse.Namespace(workspace="")
assert _resolve_cli_workspace(ns) == str(expected)
@ -107,7 +107,7 @@ def test_resolve_cli_workspace_falls_back_to_workspace_root(tmp_path, monkeypatc
monkeypatch.chdir(tmp_path)
monkeypatch.delenv("OCLAW_WORKSPACE", raising=False)
monkeypatch.setenv("OPS_WORKSPACE_ROOT", str(tmp_path))
from oclaw.runtime.operations.hooks_cmd import _resolve_cli_workspace
from runtime.operations.hooks_cmd import _resolve_cli_workspace
ns = argparse.Namespace(workspace="")
assert _resolve_cli_workspace(ns) == str(tmp_path.resolve())

View file

@ -2,7 +2,7 @@ from __future__ import annotations
from pathlib import Path
from oclaw.runtime.project_context_prompt import build_project_context_block
from runtime.project_context_prompt import build_project_context_block
class _Store:
@ -17,21 +17,21 @@ def test_build_project_context_block_reads_workspace_bootstrap(monkeypatch, tmp_
ws = tmp_path / "runtime" / "workspaces" / "main"
ws.mkdir(parents=True, exist_ok=True)
(ws / "TOOLS.md").write_text("tooling note", encoding="utf-8")
monkeypatch.setattr("oclaw.runtime.project_context_prompt.PROJECT_ROOT", tmp_path)
monkeypatch.setattr("runtime.project_context_prompt.PROJECT_ROOT", tmp_path)
out = build_project_context_block(store=_Store())
assert "[project_context]" in out
assert "[TOOLS.md]" in out
def test_build_project_context_block_empty_when_no_files(monkeypatch, tmp_path: Path) -> None:
monkeypatch.setattr("oclaw.runtime.project_context_prompt.PROJECT_ROOT", tmp_path)
monkeypatch.setattr("runtime.project_context_prompt.PROJECT_ROOT", tmp_path)
out = build_project_context_block(store=_Store())
assert out == ""
def test_build_project_context_block_fallback_to_project_root(monkeypatch, tmp_path: Path) -> None:
(tmp_path / "TOOLS.md").write_text("legacy root tools", encoding="utf-8")
monkeypatch.setattr("oclaw.runtime.project_context_prompt.PROJECT_ROOT", tmp_path)
monkeypatch.setattr("runtime.project_context_prompt.PROJECT_ROOT", tmp_path)
out = build_project_context_block(store=_Store())
assert "[TOOLS.md]" in out
assert "legacy root tools" in out
@ -41,16 +41,16 @@ def test_build_project_context_block_triggers_bootstrap_for_each_root(monkeypatc
ws_agent = tmp_path / "runtime" / "workspaces" / "main"
ws_agent.mkdir(parents=True, exist_ok=True)
(ws_agent / "TOOLS.md").write_text("agent root", encoding="utf-8")
monkeypatch.setattr("oclaw.runtime.project_context_prompt.PROJECT_ROOT", tmp_path)
monkeypatch.setattr("runtime.project_context_prompt.PROJECT_ROOT", tmp_path)
calls: list[dict] = []
def _capture(**kwargs):
calls.append(dict(kwargs))
monkeypatch.setattr("oclaw.runtime.project_context_prompt.trigger_hook_event", _capture)
monkeypatch.setattr("runtime.project_context_prompt.trigger_hook_event", _capture)
monkeypatch.setattr(
"oclaw.runtime.project_context_prompt.get_active_hooks_config",
"runtime.project_context_prompt.get_active_hooks_config",
lambda: {"hooks": {"internal": {"enabled": True}}},
)
_ = build_project_context_block(store=_Store())
@ -68,16 +68,16 @@ def test_project_context_bootstrap_includes_agent_id_when_config_matches(monkeyp
ws_social.mkdir(parents=True, exist_ok=True)
(ws_agent / "TOOLS.md").write_text("agent root", encoding="utf-8")
(ws_social / "TOOLS.md").write_text("social root", encoding="utf-8")
monkeypatch.setattr("oclaw.runtime.project_context_prompt.PROJECT_ROOT", tmp_path)
monkeypatch.setattr("runtime.project_context_prompt.PROJECT_ROOT", tmp_path)
calls: list[dict] = []
def _capture(**kwargs):
calls.append(dict(kwargs))
monkeypatch.setattr("oclaw.runtime.project_context_prompt.trigger_hook_event", _capture)
monkeypatch.setattr("runtime.project_context_prompt.trigger_hook_event", _capture)
monkeypatch.setattr(
"oclaw.runtime.project_context_prompt.get_active_hooks_config",
"runtime.project_context_prompt.get_active_hooks_config",
lambda: {
"hooks": {"internal": {"enabled": True}},
"agents": {

View file

@ -1,7 +1,7 @@
from __future__ import annotations
from oclaw.runtime.relay_pointer import build_manifest_from_attachment_refs
from oclaw.runtime.types import RelayShareEnvelope, SharedAttachmentManifest, SharedFilePointer
from runtime.relay_pointer import build_manifest_from_attachment_refs
from runtime.types import RelayShareEnvelope, SharedAttachmentManifest, SharedFilePointer
def test_shared_pointer_roundtrip_with_extra_fields() -> None:

View file

@ -5,7 +5,7 @@ from pathlib import Path
import pytest
from oclaw.runtime.relay_pointer import (
from runtime.relay_pointer import (
RelayPointerError,
build_pointer_uri,
decode_base64_payload,

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from oclaw.runtime.agents.specialists import default_system_prefix_for_specialist
from runtime.agents.specialists import default_system_prefix_for_specialist
def test_specialist_prompts_loaded_from_oclaw_tree() -> None:

View file

@ -1,8 +1,8 @@
from __future__ import annotations
from oclaw.platform.llm.chat_models import LLMResponse
from oclaw.runtime.router import decide_route
from oclaw.runtime.types import StandardMessage, normalize_interaction_mode, normalize_requested_specialist
from svc.llm.chat_models import LLMResponse
from runtime.router import decide_route
from runtime.types import StandardMessage, normalize_interaction_mode, normalize_requested_specialist
def _msg(text: str, attachments: list[dict] | None = None) -> StandardMessage:

View file

@ -2,8 +2,8 @@ from __future__ import annotations
from pathlib import Path
from oclaw.runtime.skills import build_skill_manifest, discover_workspace_skill_manifests, load_skill_manifest
from oclaw.runtime.tools.base import ToolRegistry, ToolSpec
from runtime.skills import build_skill_manifest, discover_workspace_skill_manifests, load_skill_manifest
from runtime.tools.base import ToolRegistry, ToolSpec
def test_load_skill_manifest_with_oclaw_metadata(tmp_path: Path) -> None:

View file

@ -1,7 +1,7 @@
from __future__ import annotations
from oclaw.platform.config.paths import PROJECT_ROOT
from oclaw.interfaces.http.fastapi_app import _resolve_startup_workspace_dir, _resolve_startup_workspace_dirs
from svc.config.paths import PROJECT_ROOT
from interfaces.http.fastapi_app import _resolve_startup_workspace_dir, _resolve_startup_workspace_dirs
def test_resolve_startup_workspace_dir_from_agents_default() -> None:

View file

@ -4,11 +4,11 @@ from pathlib import Path
import pytest
from oclaw.runtime.skills import workspace_skills_layout_signature
from oclaw.runtime.system_prompt import build_oclaw_executor_system_prompt
from oclaw.runtime.types import OclawMemoryContext
from oclaw.platform.persistence.sqlite_store import SqliteStore
from oclaw.runtime.tools.base import ToolRegistry, ToolSpec
from runtime.skills import workspace_skills_layout_signature
from runtime.system_prompt import build_oclaw_executor_system_prompt
from runtime.types import OclawMemoryContext
from svc.persistence.sqlite_store import SqliteStore
from runtime.tools.base import ToolRegistry, ToolSpec
def _spec(name: str) -> ToolSpec:
@ -70,7 +70,7 @@ def test_build_oclaw_executor_system_prompt_with_tools_has_skills(tmp_path: Path
def test_executor_static_prompt_cache_invalidates_on_settings_change(monkeypatch: pytest.MonkeyPatch) -> None:
from oclaw.runtime import system_prompt as sp
from runtime import system_prompt as sp
class DummyStore:
def __init__(self) -> None:
@ -143,7 +143,7 @@ def test_workspace_skills_layout_signature_changes_on_skill_md_edit(monkeypatch:
def test_executor_static_prompt_cache_invalidates_on_workspace_skills_layout_change(monkeypatch: pytest.MonkeyPatch) -> None:
from oclaw.runtime import system_prompt as sp
from runtime import system_prompt as sp
class DummyStore:
def get_setting(self, key: str) -> str:
@ -204,7 +204,7 @@ def test_executor_static_prompt_cache_invalidates_on_workspace_skills_layout_cha
def test_executor_static_prompt_cache_invalidates_on_skill_role_binding_change(monkeypatch: pytest.MonkeyPatch) -> None:
from oclaw.runtime import system_prompt as sp
from runtime import system_prompt as sp
class DummyStore:
def __init__(self) -> None:
@ -265,7 +265,7 @@ def test_executor_static_prompt_cache_invalidates_on_skill_role_binding_change(m
def test_executor_static_prompt_cache_invalidates_on_workspace_revision_change(monkeypatch: pytest.MonkeyPatch) -> None:
from oclaw.runtime import system_prompt as sp
from runtime import system_prompt as sp
class DummyStore:
def get_setting(self, key: str) -> str:

Some files were not shown because too many files have changed in this diff Show more