diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e021bf7..7428b93f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,10 +15,10 @@ jobs: - name: Install dependencies run: python -m pip install -r requirements.txt ruff mypy - name: Lint changed architecture modules - run: ruff check oclaw/interfaces oclaw/runtime/extensions oclaw/tests/test_oclaw_gateway_optimizations.py + run: ruff check interfaces runtime svc tests/test_oclaw_gateway_optimizations.py - name: Type check critical gateway modules - run: mypy --ignore-missing-imports oclaw/interfaces/gateway/context_builder.py oclaw/interfaces/ws/server_methods_bridge.py oclaw/interfaces/ws/turn_runner.py + run: mypy --ignore-missing-imports interfaces/gateway/context_builder.py interfaces/ws/server_methods_bridge.py interfaces/ws/turn_runner.py - name: Run tests - run: python -m pytest -q oclaw/tests + run: python -m pytest -q tests - name: Offline eval sanity - run: python oclaw/scripts/offline_eval.py + run: python runtime/operations/scripts/offline_eval.py diff --git a/README.md b/README.md index 1c8868a2..b5b0e3c8 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ Chinese zero-to-running checklist: see **开箱即用(从零跑起来)** at - `gateway/`: method handlers and protocol bridging - `application/`: use-cases and orchestration services - `infrastructure/`: runtime-facing integrations/adapters -- `platform/`: shared platform capabilities (llm, persistence, config, files) +- `svc/`: shared platform capabilities (llm, persistence, config, files) - `tools/`: tool registry, MCP adapters, public/system tools - `skills/`: installable skills and runtime manifests diff --git a/__init__.py b/__init__.py index 540ddb6c..6fd897fd 100644 --- a/__init__.py +++ b/__init__.py @@ -1,5 +1 @@ -"""Oclaw v2 package root. - -All production code in this repository lives under this package root. -""" - +"""Repository marker (optional). Imports use top-level ``svc``, ``runtime``, ``interfaces``.""" diff --git a/desktop/README.md b/desktop/README.md index 6c9dab87..e68c1d9e 100644 --- a/desktop/README.md +++ b/desktop/README.md @@ -24,7 +24,7 @@ npm run dev The app will: 1. Pick an available local port (default prefers `8787`). -2. Start backend using `python -m oclaw.runtime.operations gateway start --host 127.0.0.1 --port `. +2. Start backend using `python -m runtime.operations gateway start --host 127.0.0.1 --port `. 3. Open `http://127.0.0.1:/chat` in the desktop window. Logs are written under: diff --git a/desktop/main.js b/desktop/main.js index c1d40740..89ae4f34 100644 --- a/desktop/main.js +++ b/desktop/main.js @@ -253,7 +253,7 @@ async function startBackendProcess() { AIA_DESKTOP_MODE: "1", }); - const args = ["-m", "oclaw.runtime.operations", "gateway", "start", "--host", host, "--port", String(port)]; + const args = ["-m", "runtime.operations", "gateway", "start", "--host", host, "--port", String(port)]; backendProc = spawn(pythonBin, args, { cwd: APP_ROOT, env, @@ -343,7 +343,7 @@ async function startChannelProcess() { try { const cleanupRes = await runPythonInline( pythonBin, - "from oclaw.runtime.operations.runtime import cleanup_orphan_service_processes; k=cleanup_orphan_service_processes('channel:wecom'); print('killed=' + ','.join(str(x) for x in k))", + "from runtime.operations.runtime import cleanup_orphan_service_processes; k=cleanup_orphan_service_processes('channel:wecom'); print('killed=' + ','.join(str(x) for x in k))", { AIA_DATA_DIR: DATA_ROOT }, ); if (!cleanupRes.ok) { @@ -359,7 +359,7 @@ async function startChannelProcess() { AIA_DATA_DIR: DATA_ROOT, AIA_DESKTOP_MODE: "1", }); - const args = ["-m", "oclaw.runtime.operations", "channel", "wecom", "start", "--mode", "ws", "--interval", "3.0", "--deliver-outbound"]; + const args = ["-m", "runtime.operations", "channel", "wecom", "start", "--mode", "ws", "--interval", "3.0", "--deliver-outbound"]; channelStopping = false; channelProc = spawn(pythonBin, args, { cwd: APP_ROOT, diff --git a/docs/ENVIRONMENT_VARIABLES.md b/docs/ENVIRONMENT_VARIABLES.md index 74a9b27f..813e8fcc 100644 --- a/docs/ENVIRONMENT_VARIABLES.md +++ b/docs/ENVIRONMENT_VARIABLES.md @@ -506,7 +506,7 @@ - 生效:`oclaw/app_server/fastapi_main.py`, `oclaw/runtime/operations/main.py` - `OCLAW_UVICORN_WS_MAX_SIZE` - - 默认:未设置时由 `oclaw.interfaces.http.fastapi_app:main` 使用与 `MAX_PAYLOAD_BYTES`(约 25MB)相同的值传入 uvicorn `ws_max_size` + - 默认:未设置时由 `interfaces.http.fastapi_app:main` 使用与 `MAX_PAYLOAD_BYTES`(约 25MB)相同的值传入 uvicorn `ws_max_size` - 作用:**uvicorn 对 WebSocket 单帧的字节上限**(与 hello 里 `maxPayload` 应对齐)。uvicorn 自带默认约 **16MB**;两张高清图经 base64 塞进一条 `chat.send` 常超过 16MB,服务端直接断连,浏览器侧表现为 **`ws_closed`** / 请求失败 - 说明:若用命令行 `uvicorn ...` 启动而未走 `fastapi_app.main()`,需自行加 `--ws-max-size` 或设置本变量(取决于你的启动入口是否读取) - 生效:`oclaw/interfaces/http/fastapi_app.py` diff --git a/docs/OCLAW_COMPAT_REMOVAL_CHECKLIST.md b/docs/OCLAW_COMPAT_REMOVAL_CHECKLIST.md index 593cb23c..d06d495d 100644 --- a/docs/OCLAW_COMPAT_REMOVAL_CHECKLIST.md +++ b/docs/OCLAW_COMPAT_REMOVAL_CHECKLIST.md @@ -4,8 +4,8 @@ Use this checklist to verify readiness and post-delete safety for `oclaw/app_ser ## Import graph checks - [x] `rg "src\.app_server\."` has no runtime/code matches (tests excluded or updated). -- [x] CLI/runtime startup paths import from `oclaw.interfaces.*` only. -- [x] WebSocket entrypoint imports resolve through `oclaw.interfaces.ws.*`. +- [x] CLI/runtime startup paths import from `interfaces.*` only. +- [x] WebSocket entrypoint imports resolve through `interfaces.ws.*`. ## Behavior parity checks - [x] HTTP gateway smoke tests pass (`/health`, `/inbound`, `/gateway/method`, `/ws` handshake). diff --git a/docs/OCLAW_MIGRATION_GUIDE.md b/docs/OCLAW_MIGRATION_GUIDE.md index e450ce48..bc9a47ca 100644 --- a/docs/OCLAW_MIGRATION_GUIDE.md +++ b/docs/OCLAW_MIGRATION_GUIDE.md @@ -26,10 +26,10 @@ This repository now uses **repo-root relative** runtime wiring. ## Runtime notes - Gateway HTTP method adapter: `POST /gateway/method` - WS dispatch first resolves method handlers from shared dispatcher. -- Inbound payload use-case entrypoint: `oclaw.runtime.application.gateway.process_inbound_payload_usecase` -- HTTP app entrypoint moved to: `oclaw.interfaces.http.fastapi_app` -- WS entrypoint moved to: `oclaw.interfaces.ws.entrypoint` -- WS runtime bridge path: `oclaw.interfaces.ws.runtime` +- Inbound payload use-case entrypoint: `runtime.application.gateway.process_inbound_payload_usecase` +- HTTP app entrypoint moved to: `interfaces.http.fastapi_app` +- WS entrypoint moved to: `interfaces.ws.entrypoint` +- WS runtime bridge path: `interfaces.ws.runtime` - WS runtime implementation seam: - `oclaw/interfaces/ws/runtime_impl.py` - `runtime.py` points to this module as stable import surface. diff --git a/docs/PROMPT_STYLE_GUIDE.md b/docs/PROMPT_STYLE_GUIDE.md index 8a733045..5edc52f6 100644 --- a/docs/PROMPT_STYLE_GUIDE.md +++ b/docs/PROMPT_STYLE_GUIDE.md @@ -1,7 +1,7 @@ # Prompt Style Guide ## Goal -- System/builtin model-facing prompt templates live under `runtime/workspaces/_system/`; role-specific copy lives under `runtime/workspaces//` (e.g. `ROLE_SYSTEM.md`). Load via `oclaw.runtime.prompt_templates`. +- System/builtin model-facing prompt templates live under `runtime/workspaces/_system/`; role-specific copy lives under `runtime/workspaces//` (e.g. `ROLE_SYSTEM.md`). Load via `runtime.prompt_templates`. - Business code must inject variables only; no long inline prompt strings. ## Template Contract diff --git a/docs/RUNBOOK.md b/docs/RUNBOOK.md index c6fe7b3c..c27de902 100644 --- a/docs/RUNBOOK.md +++ b/docs/RUNBOOK.md @@ -11,7 +11,7 @@ ## 1. 统一入口(只保留最新) -所有运维命令统一通过 `scripts/`,不要再使用 `python -m oclaw.runtime.operations ...` 或历史 `.bat` 方式。 +所有运维命令统一通过 `scripts/`,不要再使用 `python -m runtime.operations ...` 或历史 `.bat` 方式。 补充:工具脚本也统一放在 `scripts/`(例如 `seed_mcp_registry.py`、`ws_probe.py`)。 diff --git a/interfaces/admin/chat_api.py b/interfaces/admin/chat_api.py index 8a611e92..0528c551 100644 --- a/interfaces/admin/chat_api.py +++ b/interfaces/admin/chat_api.py @@ -15,26 +15,26 @@ from pathlib import Path from fastapi import APIRouter, Body, File, Header, HTTPException, Query, UploadFile from fastapi.responses import Response, StreamingResponse -from oclaw.runtime.operations.mcp_env import apply_gateway_mcp_env_to_os -from oclaw.runtime.agents.specialists import specialist_ids -from oclaw.runtime.agents.factory import build_gateway_executor -from oclaw.runtime.chat.agent import GenerationInterrupted -from oclaw.platform.config.paths import db_path -from oclaw.platform.files.attachment_assets import AttachmentAssetStore -from oclaw.platform.files.file_attachments import ( +from runtime.operations.mcp_env import apply_gateway_mcp_env_to_os +from runtime.agents.specialists import specialist_ids +from runtime.agents.factory import build_gateway_executor +from runtime.chat.agent import GenerationInterrupted +from svc.config.paths import db_path +from svc.files.attachment_assets import AttachmentAssetStore +from svc.files.file_attachments import ( DEFAULT_TABULAR_CELL_CHARS, DEFAULT_TABULAR_COLUMNS, DEFAULT_MAX_EXCEL_SHEETS, DEFAULT_TABULAR_ROWS_READ, clear_attachment_limits_cache, ) -from oclaw.interfaces.ws.common import normalize_ws_attachments -from oclaw.platform.files.session_export import export_session_json, export_session_markdown -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.gateway import OclawGateway -from oclaw.runtime.plan_agent_v2.switch import v2_feature_enabled -from oclaw.runtime.types import StandardMessage, normalize_interaction_mode, normalize_requested_specialist -from oclaw.runtime.chat.history_tool_result_compact import compact_tool_results_in_session_history +from interfaces.ws.common import normalize_ws_attachments +from svc.files.session_export import export_session_json, export_session_markdown +from svc.persistence.sqlite_store import SqliteStore +from runtime.gateway import OclawGateway +from runtime.plan_agent_v2.switch import v2_feature_enabled +from runtime.types import StandardMessage, normalize_interaction_mode, normalize_requested_specialist +from runtime.chat.history_tool_result_compact import compact_tool_results_in_session_history def _oclaw_config_path() -> Path: diff --git a/interfaces/admin/mcp_e2e_probe.py b/interfaces/admin/mcp_e2e_probe.py index 9662f5f0..d03e1616 100644 --- a/interfaces/admin/mcp_e2e_probe.py +++ b/interfaces/admin/mcp_e2e_probe.py @@ -3,8 +3,8 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools.base import ToolRegistry, ToolSpec -from oclaw.runtime.tools.tool_validation import validate_tool_arguments +from runtime.tools.base import ToolRegistry, ToolSpec +from runtime.tools.tool_validation import validate_tool_arguments def parse_mcp_bound_tool_name(full_name: str) -> tuple[str, str] | None: diff --git a/interfaces/admin/models_api.py b/interfaces/admin/models_api.py index 1b28b14f..f32258c0 100644 --- a/interfaces/admin/models_api.py +++ b/interfaces/admin/models_api.py @@ -12,16 +12,16 @@ from typing import Any from fastapi import APIRouter, Body, Header, HTTPException, Query from fastapi.responses import Response -from oclaw.runtime.agents.factory import DEFAULT_OLLAMA_BASE_URL, DEFAULT_OLLAMA_MODEL -from oclaw.runtime.agents.specialists import ( +from runtime.agents.factory import DEFAULT_OLLAMA_BASE_URL, DEFAULT_OLLAMA_MODEL +from runtime.agents.specialists import ( AGENT_PROFILE_BINDINGS_KEY, agent_role_ids, dump_agent_profile_bindings, parse_agent_profile_bindings, ) -from oclaw.platform.config.paths import db_path -from oclaw.runtime.orchestration.evaluation import eval_summary -from oclaw.platform.persistence.sqlite_store import ( +from svc.config.paths import db_path +from runtime.orchestration.evaluation import eval_summary +from svc.persistence.sqlite_store import ( LLM_BUILTIN_OLLAMA_PROFILE_ID, SqliteStore, active_llm_profile_setting_key, diff --git a/interfaces/admin/routes.py b/interfaces/admin/routes.py index b996563e..56520b5e 100644 --- a/interfaces/admin/routes.py +++ b/interfaces/admin/routes.py @@ -16,12 +16,12 @@ from fastapi import APIRouter, Body, Header, Query from fastapi import HTTPException from fastapi.responses import HTMLResponse -from oclaw.runtime.operations.mcp_env import apply_gateway_mcp_env_to_os -from oclaw.runtime.agents.factory import build_gateway_executor -from oclaw.runtime.gateway import OclawGateway -from oclaw.runtime.types import StandardMessage, normalize_interaction_mode, normalize_requested_specialist -from oclaw.runtime.operations.providers.registry import build_channel_registry -from oclaw.runtime.operations.runtime import ( +from runtime.operations.mcp_env import apply_gateway_mcp_env_to_os +from runtime.agents.factory import build_gateway_executor +from runtime.gateway import OclawGateway +from runtime.types import StandardMessage, normalize_interaction_mode, normalize_requested_specialist +from runtime.operations.providers.registry import build_channel_registry +from runtime.operations.runtime import ( cleanup_service_processes_by_pid, detect_orphan_service_processes, is_pid_running, @@ -29,37 +29,37 @@ from oclaw.runtime.operations.runtime import ( list_service_process_pids, status_services, ) -from oclaw.runtime.operations.stack import cmd_stack_down, cmd_stack_status, cmd_stack_up -from oclaw.runtime.orchestration.vector_store import read_vector_memory_runtime -from oclaw.platform.config.paths import PROJECT_ROOT, db_path -from oclaw.platform.config.passwords import load_expected_password -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.agents.specialists import discover_specialist_ids, parse_agent_profile_bindings -from oclaw.runtime.tools.mcp.installer import ( +from runtime.operations.stack import cmd_stack_down, cmd_stack_status, cmd_stack_up +from runtime.orchestration.vector_store import read_vector_memory_runtime +from svc.config.paths import PROJECT_ROOT, db_path +from svc.config.passwords import load_expected_password +from svc.persistence.sqlite_store import SqliteStore +from runtime.agents.specialists import discover_specialist_ids, parse_agent_profile_bindings +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.market import search_mcp_market, trending_mcp_market -from oclaw.runtime.tools.mcp.manifest import McpServerManifest -from oclaw.runtime.operations.mcp_registry_export import ( +from runtime.tools.mcp.market import search_mcp_market, trending_mcp_market +from runtime.tools.mcp.manifest import McpServerManifest +from runtime.operations.mcp_registry_export import ( build_mcp_install_export_document, mcp_migrated_json_path, persist_mcp_migrated_file, ) -from oclaw.runtime.tools.mcp.filesystem_argv import build_mcp_process_command -from oclaw.runtime.tools.mcp.registry import McpRegistry -from oclaw.runtime.tools.mcp.runtime import McpProcessRuntime -from oclaw.interfaces.admin.mcp_e2e_probe import build_mcp_e2e_probe_plans -from oclaw.runtime.tools.catalog import default_registry -from oclaw.runtime.chat.tool_runtime import ToolExecutionContext, ToolExecutor -from oclaw.platform.llm.chat_models import LLMToolCall -from oclaw.runtime.agent_core_attempt import ALL_ATTEMPT_ERROR_CODES -from oclaw.runtime.agent_core_run import DEFAULT_RETRYABLE_ERROR_CODES, resolve_retryable_error_codes -from oclaw.runtime.prompt_prebuild import run_runtime_prewarm, runtime_prewarm_prompts_snapshot, runtime_prewarm_status -from oclaw.runtime.workspaces.experts import ( +from runtime.tools.mcp.filesystem_argv import build_mcp_process_command +from runtime.tools.mcp.registry import McpRegistry +from runtime.tools.mcp.runtime import McpProcessRuntime +from interfaces.admin.mcp_e2e_probe import build_mcp_e2e_probe_plans +from runtime.tools.catalog import default_registry +from runtime.chat.tool_runtime import ToolExecutionContext, ToolExecutor +from svc.llm.chat_models import LLMToolCall +from runtime.agent_core_attempt import ALL_ATTEMPT_ERROR_CODES +from runtime.agent_core_run import DEFAULT_RETRYABLE_ERROR_CODES, resolve_retryable_error_codes +from runtime.prompt_prebuild import run_runtime_prewarm, runtime_prewarm_prompts_snapshot, runtime_prewarm_status +from runtime.workspaces.experts import ( create_expert, delete_expert, list_experts, @@ -446,8 +446,8 @@ def build_admin_router() -> APIRouter: ctx = _resolve_auth(store, authorization) _require_permission(ctx, "admin:tenant:write") - from oclaw.runtime.tools.expert_registry import clear_expert_tool_cache - from oclaw.runtime.tools.public_registry import clear_public_tool_cache + from runtime.tools.expert_registry import clear_expert_tool_cache + from runtime.tools.public_registry import clear_public_tool_cache clear_public_tool_cache() clear_expert_tool_cache() @@ -504,7 +504,7 @@ def build_admin_router() -> APIRouter: store = SqliteStore(db_path()) ctx = _resolve_auth(store, authorization) _require_permission(ctx, "admin:tenant:write") - from oclaw.runtime.tools.exposure_plan import build_internal_tool_specs + from runtime.tools.exposure_plan import build_internal_tool_specs r = str(role or "").strip().lower() available_roles = _ordered_roles() @@ -543,8 +543,8 @@ def build_admin_router() -> APIRouter: ctx = _resolve_auth(store, authorization) _require_permission(ctx, "admin:tenant:write") - from oclaw.platform.llm.tool_wire_policy import load_role_mode_for_role, load_tool_policies_dict_for_role - from oclaw.runtime.tools.exposure_plan import build_internal_tool_specs, build_llm_tools_plan + from svc.llm.tool_wire_policy import load_role_mode_for_role, load_tool_policies_dict_for_role + from runtime.tools.exposure_plan import build_internal_tool_specs, build_llm_tools_plan roles = _ordered_roles() items: list[dict[str, Any]] = [] @@ -607,7 +607,7 @@ def build_admin_router() -> APIRouter: store = SqliteStore(db_path()) ctx = _resolve_auth(store, authorization) _require_permission(ctx, "admin:tenant:write") - from oclaw.runtime.tools.exposure_plan import build_llm_tools_plan + from runtime.tools.exposure_plan import build_llm_tools_plan r = str(role or "").strip().lower() available_roles = _ordered_roles() @@ -2295,7 +2295,7 @@ def build_admin_router() -> APIRouter: store = SqliteStore(db_path()) ctx = _resolve_auth(store, authorization) _require_permission(ctx, "admin:tenant:write") - from oclaw.platform.llm.tool_wire_policy import build_tool_wire_snapshot + from svc.llm.tool_wire_policy import build_tool_wire_snapshot return build_tool_wire_snapshot(store, role=str(role or "").strip().lower() or None) @@ -2304,7 +2304,7 @@ def build_admin_router() -> APIRouter: payload: dict[str, Any] | None = Body(default=None), authorization: str | None = Header(default=None), ) -> dict[str, Any]: - from oclaw.platform.llm.tool_wire_policy import SETTINGS_KEY_ADMIN_CONFIG, load_merged_admin_config + from svc.llm.tool_wire_policy import SETTINGS_KEY_ADMIN_CONFIG, load_merged_admin_config payload = payload or {} store = SqliteStore(db_path()) @@ -2356,7 +2356,7 @@ def build_admin_router() -> APIRouter: payload: dict[str, Any] | None = Body(default=None), authorization: str | None = Header(default=None), ) -> dict[str, Any]: - from oclaw.platform.llm.tool_wire_policy import SETTINGS_KEY_ROLE_MODE_BY_ROLE + from svc.llm.tool_wire_policy import SETTINGS_KEY_ROLE_MODE_BY_ROLE payload = payload or {} store = SqliteStore(db_path()) @@ -2396,7 +2396,7 @@ def build_admin_router() -> APIRouter: role: str | None = Query(default=None), authorization: str | None = Header(default=None), ) -> dict[str, Any]: - from oclaw.platform.llm.tool_wire_policy import SETTINGS_KEY_PENALTY_STATE, SETTINGS_KEY_PENALTY_STATE_BY_ROLE + from svc.llm.tool_wire_policy import SETTINGS_KEY_PENALTY_STATE, SETTINGS_KEY_PENALTY_STATE_BY_ROLE store = SqliteStore(db_path()) ctx = _resolve_auth(store, authorization) @@ -2433,7 +2433,7 @@ def build_admin_router() -> APIRouter: payload: dict[str, Any] | None = Body(default=None), authorization: str | None = Header(default=None), ) -> dict[str, Any]: - from oclaw.platform.llm.tool_wire_policy import ( + from svc.llm.tool_wire_policy import ( SETTINGS_KEY_TOOL_POLICIES, SETTINGS_KEY_TOOL_POLICIES_BY_ROLE, load_tool_policies_dict_for_role, @@ -2504,7 +2504,7 @@ def build_admin_router() -> APIRouter: payload: dict[str, Any] | None = Body(default=None), authorization: str | None = Header(default=None), ) -> dict[str, Any]: - from oclaw.platform.llm.tool_wire_policy import ( + from svc.llm.tool_wire_policy import ( SETTINGS_KEY_TOOL_POLICIES, SETTINGS_KEY_TOOL_POLICIES_BY_ROLE, load_tool_policies_dict_for_role, @@ -3604,8 +3604,8 @@ def build_admin_router() -> APIRouter: if tenant_id: _require_tenant_scope(ctx, tenant_id) user_id = str(payload.get("user_id") or "").strip() or None - from oclaw.platform.embeddings.embedding_client import build_default_embedding_client - from oclaw.runtime.orchestration.vector_store import build_vector_store, MemoryVectorItem + from svc.embeddings.embedding_client import build_default_embedding_client + from runtime.orchestration.vector_store import build_vector_store, MemoryVectorItem client = build_default_embedding_client() vector = build_vector_store(store) @@ -4114,9 +4114,9 @@ def build_admin_router() -> APIRouter: "offset": int(off), } - from oclaw.interfaces.admin.chat_api import include_chat_routes - from oclaw.interfaces.admin.models_api import include_model_mgmt_routes - from oclaw.interfaces.admin.skills_api import include_skill_routes + from interfaces.admin.chat_api import include_chat_routes + from interfaces.admin.models_api import include_model_mgmt_routes + from interfaces.admin.skills_api import include_skill_routes include_chat_routes(router, resolve_auth=_resolve_auth) include_model_mgmt_routes(router, resolve_auth=_resolve_auth) diff --git a/interfaces/admin/skills_api.py b/interfaces/admin/skills_api.py index 51010085..185baad7 100644 --- a/interfaces/admin/skills_api.py +++ b/interfaces/admin/skills_api.py @@ -7,8 +7,8 @@ from typing import Any from fastapi import APIRouter, Body, Header, HTTPException -from oclaw.runtime.agents.factory import build_gateway_executor -from oclaw.runtime.skill_installer import ( +from runtime.agents.factory import build_gateway_executor +from runtime.skill_installer import ( auto_install_skill_from_payload, create_skill_from_template, create_workspace_skill, @@ -19,7 +19,7 @@ from oclaw.runtime.skill_installer import ( set_skill_enabled, uninstall_skill, ) -from oclaw.runtime.skill_role_binding import ( +from runtime.skill_role_binding import ( SKILL_ROLE_BINDING_ENABLED_SETTING, SKILL_ROLE_BINDING_KEY, SKILL_ROLE_BINDING_MANAGER_INHERIT_SETTING, @@ -30,12 +30,12 @@ from oclaw.runtime.skill_role_binding import ( skill_role_binding_enabled_env_present, skill_role_binding_enabled_stored, ) -from oclaw.runtime.skills_prompt import collect_skill_catalog_entries -from oclaw.runtime.skills import _allowed_tool_names_after_wire_policy, discover_workspace_skill_manifests -from oclaw.runtime.skills_market import get_market_adapter, normalize_skill_market_provider_setting -from oclaw.runtime.tools.skills_runtime.subprocess_exec import run_skill_runtime_entry -from oclaw.platform.config.paths import db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore +from runtime.skills_prompt import collect_skill_catalog_entries +from runtime.skills import _allowed_tool_names_after_wire_policy, discover_workspace_skill_manifests +from runtime.skills_market import get_market_adapter, normalize_skill_market_provider_setting +from runtime.tools.skills_runtime.subprocess_exec import run_skill_runtime_entry +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore _SKILL_MARKET_PROVIDER_KEY = "AIA_SKILL_MARKET_PROVIDER" diff --git a/interfaces/channels/wecom/longconn_runner.py b/interfaces/channels/wecom/longconn_runner.py index 399c48a5..78e1f274 100644 --- a/interfaces/channels/wecom/longconn_runner.py +++ b/interfaces/channels/wecom/longconn_runner.py @@ -11,11 +11,11 @@ from collections import deque from pathlib import Path from typing import Any -from oclaw.runtime.application.gateway import process_inbound_payload_usecase -from oclaw.interfaces.channels.wecom.normalize import normalize_wecom_event, normalize_wecom_event_batch -from oclaw.platform.config.paths import db_path -from oclaw.platform.integrations.wecom_client import WeComClient -from oclaw.platform.persistence.sqlite_store import SqliteStore +from runtime.application.gateway import process_inbound_payload_usecase +from interfaces.channels.wecom.normalize import normalize_wecom_event, normalize_wecom_event_batch +from svc.config.paths import db_path +from svc.integrations.wecom_client import WeComClient +from svc.persistence.sqlite_store import SqliteStore def _safe_json(obj: Any) -> str: diff --git a/interfaces/channels/wecom/wecom_bridge.py b/interfaces/channels/wecom/wecom_bridge.py index c8af7d22..ffc91182 100644 --- a/interfaces/channels/wecom/wecom_bridge.py +++ b/interfaces/channels/wecom/wecom_bridge.py @@ -2,7 +2,7 @@ from __future__ import annotations from typing import Any -from oclaw.interfaces.channels.base import ChannelAdapter, InboundMessage, OutboundMessage +from interfaces.channels.base import ChannelAdapter, InboundMessage, OutboundMessage class WeComAdapter(ChannelAdapter): diff --git a/interfaces/gateway/context_builder.py b/interfaces/gateway/context_builder.py index 4a9fc1f4..5df33b16 100644 --- a/interfaces/gateway/context_builder.py +++ b/interfaces/gateway/context_builder.py @@ -2,9 +2,9 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.skill_installer import install_skill_from_registry_archive -from oclaw.runtime.tools.skills.clawhub_client import get_skill_detail as clawhub_get_skill_detail -from oclaw.runtime.tools.skills.clawhub_client import search_skills as clawhub_search_skills +from runtime.skill_installer import install_skill_from_registry_archive +from runtime.tools.skills.clawhub_client import get_skill_detail as clawhub_get_skill_detail +from runtime.tools.skills.clawhub_client import search_skills as clawhub_search_skills def build_common_gateway_context(*, store: Any) -> dict[str, Any]: diff --git a/interfaces/gateway/dispatcher.py b/interfaces/gateway/dispatcher.py index c61d183e..39cc848c 100644 --- a/interfaces/gateway/dispatcher.py +++ b/interfaces/gateway/dispatcher.py @@ -1,12 +1,12 @@ from __future__ import annotations -from oclaw.interfaces.gateway.server_methods.agent import agent_handlers -from oclaw.interfaces.gateway.server_methods.chat import chat_handlers -from oclaw.interfaces.gateway.server_methods.commands import commands_handlers -from oclaw.interfaces.gateway.server_methods.connect import connect_handlers -from oclaw.interfaces.gateway.server_methods.sessions import sessions_handlers -from oclaw.interfaces.gateway.server_methods.skills import skills_handlers -from oclaw.interfaces.gateway.server_methods.shared_types import GatewayRequestHandlers +from interfaces.gateway.server_methods.agent import agent_handlers +from interfaces.gateway.server_methods.chat import chat_handlers +from interfaces.gateway.server_methods.commands import commands_handlers +from interfaces.gateway.server_methods.connect import connect_handlers +from interfaces.gateway.server_methods.sessions import sessions_handlers +from interfaces.gateway.server_methods.skills import skills_handlers +from interfaces.gateway.server_methods.shared_types import GatewayRequestHandlers def build_gateway_method_handlers() -> GatewayRequestHandlers: diff --git a/interfaces/gateway/http_adapter.py b/interfaces/gateway/http_adapter.py index 695b0468..d0423376 100644 --- a/interfaces/gateway/http_adapter.py +++ b/interfaces/gateway/http_adapter.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.platform.config.paths import db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore from .context_builder import build_common_gateway_context from .dispatcher import build_gateway_method_handlers diff --git a/interfaces/gateway/python_extensions_loader.py b/interfaces/gateway/python_extensions_loader.py index 4e3e3e4b..1e436121 100644 --- a/interfaces/gateway/python_extensions_loader.py +++ b/interfaces/gateway/python_extensions_loader.py @@ -8,8 +8,8 @@ from types import ModuleType from typing import Any, Iterable from types import SimpleNamespace -from oclaw.platform.config.runtime_paths import runtime_extensions_root -from oclaw.runtime.extensions.plugin_api import PluginEntry +from svc.config.runtime_paths import runtime_extensions_root +from runtime.extensions.plugin_api import PluginEntry def _sanitize_module_name(value: str) -> str: diff --git a/interfaces/gateway/server_methods/agent.py b/interfaces/gateway/server_methods/agent.py index 9f0a937e..57f705fa 100644 --- a/interfaces/gateway/server_methods/agent.py +++ b/interfaces/gateway/server_methods/agent.py @@ -2,7 +2,7 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.agents.agent_scope import resolve_agent_id_from_session_key, resolve_session_agent_id +from runtime.agents.agent_scope import resolve_agent_id_from_session_key, resolve_session_agent_id from .shared_types import GatewayRequestHandlers from .validation import error_shape diff --git a/interfaces/gateway/server_methods/dispatcher.py b/interfaces/gateway/server_methods/dispatcher.py index 02cb5899..2c9739c0 100644 --- a/interfaces/gateway/server_methods/dispatcher.py +++ b/interfaces/gateway/server_methods/dispatcher.py @@ -1,6 +1,6 @@ """Compatibility bridge to the new oclaw dispatcher.""" -from oclaw.interfaces.gateway.dispatcher import build_gateway_method_handlers, method_names +from interfaces.gateway.dispatcher import build_gateway_method_handlers, method_names __all__ = ["build_gateway_method_handlers", "method_names"] diff --git a/interfaces/gateway/server_methods/image.py b/interfaces/gateway/server_methods/image.py index 70e676fb..a4c2cb6e 100644 --- a/interfaces/gateway/server_methods/image.py +++ b/interfaces/gateway/server_methods/image.py @@ -4,7 +4,7 @@ import importlib.util from pathlib import Path from typing import Any, Callable -from oclaw.platform.config.runtime_paths import runtime_extensions_root +from svc.config.runtime_paths import runtime_extensions_root from .shared_types import GatewayRequestHandlers from .validation import error_shape diff --git a/interfaces/gateway/server_methods/sessions.py b/interfaces/gateway/server_methods/sessions.py index 27b523a4..5584f5fc 100644 --- a/interfaces/gateway/server_methods/sessions.py +++ b/interfaces/gateway/server_methods/sessions.py @@ -2,7 +2,7 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.agents.agent_scope import resolve_default_agent_id +from runtime.agents.agent_scope import resolve_default_agent_id from .shared_types import GatewayRequestHandlers from .telegram_send_normalize import normalize_transport_target_for_channel diff --git a/interfaces/gateway/server_methods/skills.py b/interfaces/gateway/server_methods/skills.py index 3905399f..42e50d03 100644 --- a/interfaces/gateway/server_methods/skills.py +++ b/interfaces/gateway/server_methods/skills.py @@ -3,14 +3,14 @@ from __future__ import annotations import json from typing import Any -from oclaw.runtime.skill_installer import ( +from runtime.skill_installer import ( create_skill_from_template, install_skill_from_local_dir, install_skill_from_registry_archive, list_skills_with_status, set_skill_enabled, ) -from oclaw.runtime.skills import discover_workspace_skill_manifests, load_skill_manifest +from runtime.skills import discover_workspace_skill_manifests, load_skill_manifest from .shared_types import GatewayRequestHandlers from .validation import error_shape diff --git a/interfaces/gateway/server_methods/telegram_send_normalize.py b/interfaces/gateway/server_methods/telegram_send_normalize.py index 3eab1313..0f7fda38 100644 --- a/interfaces/gateway/server_methods/telegram_send_normalize.py +++ b/interfaces/gateway/server_methods/telegram_send_normalize.py @@ -2,7 +2,7 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.extensions.telegram import ( +from runtime.extensions.telegram import ( normalize_telegram_messaging_target, parse_telegram_reply_to_message_id, parse_telegram_target, diff --git a/interfaces/gateway/server_plugins.py b/interfaces/gateway/server_plugins.py index 719497b2..17667729 100644 --- a/interfaces/gateway/server_plugins.py +++ b/interfaces/gateway/server_plugins.py @@ -4,7 +4,7 @@ from dataclasses import dataclass from pathlib import Path from typing import Any, Callable -from oclaw.platform.config.runtime_paths import runtime_extensions_root +from svc.config.runtime_paths import runtime_extensions_root from .python_extensions_loader import build_python_extensions_registry GatewayHandler = Callable[..., Any] diff --git a/interfaces/gateway/server_startup_plugins.py b/interfaces/gateway/server_startup_plugins.py index 98b8506e..f310a92d 100644 --- a/interfaces/gateway/server_startup_plugins.py +++ b/interfaces/gateway/server_startup_plugins.py @@ -3,8 +3,8 @@ from __future__ import annotations from dataclasses import dataclass from typing import Any, Callable -from oclaw.runtime.agents.agent_scope import resolve_agent_workspace_dir, resolve_default_agent_id -from oclaw.runtime.agents.subagent_registry import init_subagent_registry +from runtime.agents.agent_scope import resolve_agent_workspace_dir, resolve_default_agent_id +from runtime.agents.subagent_registry import init_subagent_registry from .server_plugins import GatewayPluginLoadResult, load_gateway_plugins diff --git a/interfaces/http/fastapi_app.py b/interfaces/http/fastapi_app.py index d59600a9..ba088f06 100644 --- a/interfaces/http/fastapi_app.py +++ b/interfaces/http/fastapi_app.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.platform.config.bootstrap_env import load_system_env +from svc.config.bootstrap_env import load_system_env load_system_env() @@ -17,24 +17,24 @@ from fastapi import Request from fastapi.responses import HTMLResponse from fastapi.staticfiles import StaticFiles -from oclaw.runtime.application.gateway import process_inbound_payload_usecase -from oclaw.interfaces.gateway.http_adapter import dispatch_gateway_http_method -from oclaw.interfaces.ws import ws_gateway_loop -from oclaw.interfaces.ws.common import MAX_PAYLOAD_BYTES -from oclaw.interfaces.admin.routes import admin_static_dir, build_admin_router -from oclaw.runtime.agents.agent_scope import list_agent_ids, resolve_agent_workspace_dir, resolve_default_agent_id -from oclaw.interfaces.gateway.server_startup_plugins import prepare_gateway_plugin_bootstrap -from oclaw.runtime.hooks_runtime import ( +from runtime.application.gateway import process_inbound_payload_usecase +from interfaces.gateway.http_adapter import dispatch_gateway_http_method +from interfaces.ws import ws_gateway_loop +from interfaces.ws.common import MAX_PAYLOAD_BYTES +from interfaces.admin.routes import admin_static_dir, build_admin_router +from runtime.agents.agent_scope import list_agent_ids, resolve_agent_workspace_dir, resolve_default_agent_id +from interfaces.gateway.server_startup_plugins import prepare_gateway_plugin_bootstrap +from runtime.hooks_runtime import ( initialize_hooks_runtime, resolve_runtime_config, trigger_hook_event, ) -from oclaw.runtime.skills import skill_runtime_diagnostics -from oclaw.runtime.prompt_prebuild import run_runtime_prewarm -from oclaw.platform.config.paths import PROJECT_ROOT, db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.interfaces.http.weixin_ilink_api import router as weixin_ilink_router -from oclaw.runtime.workspaces.experts import warm_expert_workspace_cache +from runtime.skills import skill_runtime_diagnostics +from runtime.prompt_prebuild import run_runtime_prewarm +from svc.config.paths import PROJECT_ROOT, db_path +from svc.persistence.sqlite_store import SqliteStore +from interfaces.http.weixin_ilink_api import router as weixin_ilink_router +from runtime.workspaces.experts import warm_expert_workspace_cache def _resolve_startup_workspace_dir(cfg: dict[str, Any]) -> str: @@ -314,7 +314,7 @@ def main() -> int: ws_max_size = int(MAX_PAYLOAD_BYTES) ws_max_size = max(1024, min(int(ws_max_size), 200_000_000)) uvicorn.run( - "oclaw.interfaces.http.fastapi_app:create_app", + "interfaces.http.fastapi_app:create_app", host=host, port=port, reload=False, diff --git a/interfaces/http/weixin_ilink_api.py b/interfaces/http/weixin_ilink_api.py index 42cb979a..5cb094aa 100644 --- a/interfaces/http/weixin_ilink_api.py +++ b/interfaces/http/weixin_ilink_api.py @@ -11,7 +11,7 @@ from fastapi import APIRouter, Header, HTTPException, Request def _process_inbound_payload_usecase(payload: dict[str, Any]) -> dict[str, Any]: # Lazy import to avoid circular imports during FastAPI app bootstrap. - from oclaw.runtime.application.gateway import process_inbound_payload_usecase + from runtime.application.gateway import process_inbound_payload_usecase return process_inbound_payload_usecase(payload) diff --git a/interfaces/ws/auth_and_hello.py b/interfaces/ws/auth_and_hello.py index 69f18a6f..1c76dabb 100644 --- a/interfaces/ws/auth_and_hello.py +++ b/interfaces/ws/auth_and_hello.py @@ -4,8 +4,8 @@ import hashlib import os from typing import Any -from oclaw.platform.config.paths import db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore def build_hello_ok_payload( diff --git a/interfaces/ws/common.py b/interfaces/ws/common.py index 593b31c2..76b04512 100644 --- a/interfaces/ws/common.py +++ b/interfaces/ws/common.py @@ -5,7 +5,7 @@ import os import time from typing import Any -from oclaw.platform.files.file_attachments import process_file_data +from svc.files.file_attachments import process_file_data PROTOCOL_VERSION = 3 MAX_PAYLOAD_BYTES = 26_214_400 diff --git a/interfaces/ws/runtime_helpers.py b/interfaces/ws/runtime_helpers.py index 9e16e97b..5225713e 100644 --- a/interfaces/ws/runtime_helpers.py +++ b/interfaces/ws/runtime_helpers.py @@ -6,7 +6,7 @@ from typing import Any from starlette.websockets import WebSocketDisconnect -from oclaw.interfaces.ws.common import WS_REQUIRE_AUTH +from interfaces.ws.common import WS_REQUIRE_AUTH async def recv_frame( diff --git a/interfaces/ws/runtime_impl.py b/interfaces/ws/runtime_impl.py index 1159bfb8..93faac13 100644 --- a/interfaces/ws/runtime_impl.py +++ b/interfaces/ws/runtime_impl.py @@ -11,9 +11,9 @@ import threading from fastapi import WebSocket -from oclaw.interfaces.gateway.dispatcher import build_gateway_method_handlers, method_names -from oclaw.interfaces.ws.auth_and_hello import build_hello_ok_payload, resolve_ws_auth as resolve_ws_auth_payload -from oclaw.interfaces.ws.common import ( +from interfaces.gateway.dispatcher import build_gateway_method_handlers, method_names +from interfaces.ws.auth_and_hello import build_hello_ok_payload, resolve_ws_auth as resolve_ws_auth_payload +from interfaces.ws.common import ( MAX_BUFFERED_BYTES, MAX_PAYLOAD_BYTES, PREAUTH_HANDSHAKE_TIMEOUT_MS, @@ -31,19 +31,19 @@ from oclaw.interfaces.ws.common import ( now_ms as _now_ms, origin_is_allowed, ) -from oclaw.interfaces.ws.events import ( +from interfaces.ws.events import ( emit_agent_event as emit_agent_event_impl, emit_chat_event as emit_chat_event_impl, send_event as send_event_impl, send_res as send_res_impl, ) -from oclaw.interfaces.ws.runtime_dispatch import dispatch_connected as dispatch_connected_impl -from oclaw.interfaces.ws.runtime_helpers import handle_connect as handle_connect_impl, recv_frame as recv_frame_impl -from oclaw.interfaces.ws.runtime_loop import close_ws as close_ws_impl, run_connection_loop -from oclaw.interfaces.ws.server_methods_bridge import build_gateway_context, dispatch_via_server_methods -from oclaw.interfaces.ws.turn_runner import run_agent_turn_via_bridge -from oclaw.interfaces.ws.ws_schema import format_validation_errors, get_ws_schemas, validate_or_errors -from oclaw.runtime.relay_pointer import validate_relay_share_envelope +from interfaces.ws.runtime_dispatch import dispatch_connected as dispatch_connected_impl +from interfaces.ws.runtime_helpers import handle_connect as handle_connect_impl, recv_frame as recv_frame_impl +from interfaces.ws.runtime_loop import close_ws as close_ws_impl, run_connection_loop +from interfaces.ws.server_methods_bridge import build_gateway_context, dispatch_via_server_methods +from interfaces.ws.turn_runner import run_agent_turn_via_bridge +from interfaces.ws.ws_schema import format_validation_errors, get_ws_schemas, validate_or_errors +from runtime.relay_pointer import validate_relay_share_envelope _LOG = logging.getLogger(__name__) diff --git a/interfaces/ws/schema_impl.py b/interfaces/ws/schema_impl.py index b9d82a13..9a7e9594 100644 --- a/interfaces/ws/schema_impl.py +++ b/interfaces/ws/schema_impl.py @@ -6,7 +6,7 @@ from typing import Any from jsonschema import Draft202012Validator -from oclaw.platform.config.runtime_paths import ws_protocol_schemas_root +from svc.config.runtime_paths import ws_protocol_schemas_root _SCHEMA_DIR = ws_protocol_schemas_root() diff --git a/interfaces/ws/server_methods_bridge.py b/interfaces/ws/server_methods_bridge.py index 91e31561..776e64be 100644 --- a/interfaces/ws/server_methods_bridge.py +++ b/interfaces/ws/server_methods_bridge.py @@ -4,9 +4,9 @@ import asyncio import uuid from typing import Any, Callable -from oclaw.platform.config.paths import db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.interfaces.gateway.context_builder import build_common_gateway_context +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore +from interfaces.gateway.context_builder import build_common_gateway_context def build_gateway_context( diff --git a/interfaces/ws/turn_runner.py b/interfaces/ws/turn_runner.py index 83e49bba..8aa704da 100644 --- a/interfaces/ws/turn_runner.py +++ b/interfaces/ws/turn_runner.py @@ -7,11 +7,11 @@ import uuid from datetime import datetime from typing import Any, Callable -from oclaw.runtime.agents.factory import build_gateway_executor -from oclaw.runtime.gateway import OclawGateway -from oclaw.runtime.types import StandardMessage -from oclaw.platform.config.paths import db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore +from runtime.agents.factory import build_gateway_executor +from runtime.gateway import OclawGateway +from runtime.types import StandardMessage +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore def _persisted_chat_attachments_nonempty(raw: Any) -> bool: diff --git a/platform/__init__.py b/platform/__init__.py deleted file mode 100644 index ee187a23..00000000 --- a/platform/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -from __future__ import annotations - -import importlib.util -import sysconfig -from pathlib import Path - - -def _load_stdlib_platform() -> object | None: - stdlib_dir = Path(sysconfig.get_paths().get("stdlib") or "") - platform_py = (stdlib_dir / "platform.py").resolve() - if not platform_py.exists(): - return None - spec = importlib.util.spec_from_file_location("_stdlib_platform", str(platform_py)) - if spec is None or spec.loader is None: - return None - module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - return module - - -_stdlib = _load_stdlib_platform() -if _stdlib is not None: - for _name in dir(_stdlib): - if _name in {"__name__", "__package__", "__loader__", "__spec__", "__file__", "__cached__"}: - continue - globals()[_name] = getattr(_stdlib, _name) - __all__ = list(getattr(_stdlib, "__all__", [])) -else: - __all__ = [] - diff --git a/platform/llm/__init__.py b/platform/llm/__init__.py deleted file mode 100644 index 02d9b577..00000000 --- a/platform/llm/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# oclaw.platform.llm package diff --git a/platform/llm/transports/__init__.py b/platform/llm/transports/__init__.py deleted file mode 100644 index 9ce87228..00000000 --- a/platform/llm/transports/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# oclaw.platform.llm.transports package diff --git a/runtime/agent_context/loader.py b/runtime/agent_context/loader.py index 31d599bf..c8569d4c 100644 --- a/runtime/agent_context/loader.py +++ b/runtime/agent_context/loader.py @@ -5,7 +5,7 @@ import threading from pathlib import Path from typing import Any -from oclaw.platform.config.paths import PROJECT_ROOT +from svc.config.paths import PROJECT_ROOT _ROLE_CONTEXT_CACHE_LOCK = threading.Lock() _ROLE_CONTEXT_CACHE: dict[tuple[str, tuple[Any, ...], tuple[tuple[str, str], ...]], str] = {} diff --git a/runtime/agent_core_attempt.py b/runtime/agent_core_attempt.py index fa30c897..088126e3 100644 --- a/runtime/agent_core_attempt.py +++ b/runtime/agent_core_attempt.py @@ -4,11 +4,11 @@ import json from dataclasses import dataclass from typing import Any, Callable, Optional -from oclaw.runtime.chat.turn_types import TurnRunOutcome -from oclaw.runtime.direct_loop import run_direct_loop -from oclaw.runtime.memory_stage import after_turn_memory -from oclaw.runtime.types import AttemptState, OclawMemoryContext, StandardMessage -from oclaw.runtime.orchestration.trace import new_span_id +from runtime.chat.turn_types import TurnRunOutcome +from runtime.direct_loop import run_direct_loop +from runtime.memory_stage import after_turn_memory +from runtime.types import AttemptState, OclawMemoryContext, StandardMessage +from runtime.orchestration.trace import new_span_id def _workspace_owner_session_id_from_msg(msg: StandardMessage) -> str | None: md = msg.metadata if isinstance(msg.metadata, dict) else {} diff --git a/runtime/agent_core_run.py b/runtime/agent_core_run.py index 64afc491..c36e9722 100644 --- a/runtime/agent_core_run.py +++ b/runtime/agent_core_run.py @@ -4,12 +4,12 @@ import uuid from dataclasses import dataclass from typing import Any, Callable, Optional -from oclaw.runtime.chat.turn_types import TurnRunOutcome -from oclaw.runtime.agent_core_attempt import ALL_ATTEMPT_ERROR_CODES -from oclaw.runtime.agent_core_attempt import AttemptRunnerInput, run_attempt -from oclaw.runtime.memory_stage import compact_memory_context -from oclaw.runtime.types import AttemptState, OclawMemoryContext, RunState, StandardMessage -from oclaw.runtime.orchestration.trace import new_span_id +from runtime.chat.turn_types import TurnRunOutcome +from runtime.agent_core_attempt import ALL_ATTEMPT_ERROR_CODES +from runtime.agent_core_attempt import AttemptRunnerInput, run_attempt +from runtime.memory_stage import compact_memory_context +from runtime.types import AttemptState, OclawMemoryContext, RunState, StandardMessage +from runtime.orchestration.trace import new_span_id _AGENT_CORE_OC_STAGE: dict[str, str] = { "run_started": "run_start", diff --git a/runtime/agents/factory.py b/runtime/agents/factory.py index 3216a979..d6d04e0d 100644 --- a/runtime/agents/factory.py +++ b/runtime/agents/factory.py @@ -5,10 +5,10 @@ from __future__ import annotations import os from typing import Any -from oclaw.runtime.agents.agent_scope import resolve_default_agent_id -from oclaw.runtime.agents.network_ops_agent import NetworkOpsAgent -from oclaw.runtime.agents.specialist_agent import SpecialistProfile -from oclaw.runtime.agents.specialists import ( +from runtime.agents.agent_scope import resolve_default_agent_id +from runtime.agents.network_ops_agent import NetworkOpsAgent +from runtime.agents.specialist_agent import SpecialistProfile +from runtime.agents.specialists import ( AGENT_PROFILE_BINDINGS_KEY, normalize_specialist_id, agent_role_ids, @@ -20,21 +20,21 @@ from oclaw.runtime.agents.specialists import ( expert_name_for_specialist, parse_agent_profile_bindings, ) -from oclaw.runtime.chat.agent import Agent -from oclaw.runtime.orchestration.inventory import inventory_snapshot -from oclaw.runtime.orchestration.memory import upsert_knowledge_chunks -from oclaw.platform.llm.chat_models import GoogleGeminiChatModel, OpenAIChatModel, RuleBasedChatModel, StaticTextChatModel -from oclaw.platform.llm.transports.anthropic_messages import AnthropicMessagesModel -from oclaw.platform.llm.transports.openai_responses import OpenAIResponsesModel -from oclaw.platform.persistence.sqlite_store import ( +from runtime.chat.agent import Agent +from runtime.orchestration.inventory import inventory_snapshot +from runtime.orchestration.memory import upsert_knowledge_chunks +from svc.llm.chat_models import GoogleGeminiChatModel, OpenAIChatModel, RuleBasedChatModel, StaticTextChatModel +from svc.llm.transports.anthropic_messages import AnthropicMessagesModel +from svc.llm.transports.openai_responses import OpenAIResponsesModel +from svc.persistence.sqlite_store import ( SqliteStore, active_llm_profile_setting_key, agent_profile_bindings_setting_key, is_administrator_model_pool, ) -from oclaw.runtime.prompt_templates import render_prompt -from oclaw.runtime.tools.catalog import default_registry -from oclaw.runtime.tools.plugin_loader import sync_plugin_metadata +from runtime.prompt_templates import render_prompt +from runtime.tools.catalog import default_registry +from runtime.tools.plugin_loader import sync_plugin_metadata def _openai_missing_key_user_message(lang: str) -> str: diff --git a/runtime/agents/network_ops_agent.py b/runtime/agents/network_ops_agent.py index 0a8150a5..a08a7e46 100644 --- a/runtime/agents/network_ops_agent.py +++ b/runtime/agents/network_ops_agent.py @@ -2,10 +2,10 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.chat.agent import Agent -from oclaw.runtime.agent_context import build_role_system_context -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.tools import default_registry +from runtime.chat.agent import Agent +from runtime.agent_context import build_role_system_context +from svc.persistence.sqlite_store import SqliteStore +from runtime.tools import default_registry # Ops 专家走与 specialists 相同的工作区框架:runtime/workspaces/ops/{SOUL,ROLE_SYSTEM}.md NETWORK_SYSTEM_PROMPT_ZH = build_role_system_context("ops") diff --git a/runtime/agents/specialist_agent.py b/runtime/agents/specialist_agent.py index 3bf41907..23e307e2 100644 --- a/runtime/agents/specialist_agent.py +++ b/runtime/agents/specialist_agent.py @@ -9,11 +9,11 @@ from collections.abc import Callable from dataclasses import dataclass, field from typing import Any, Optional -from oclaw.runtime.chat.agent import Agent -from oclaw.runtime.chat.agent import GenerationInterrupted -from oclaw.runtime.agents.network_ops_agent import NetworkOpsAgent -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.platform.llm.image_legacy_client import ( +from runtime.chat.agent import Agent +from runtime.chat.agent import GenerationInterrupted +from runtime.agents.network_ops_agent import NetworkOpsAgent +from svc.persistence.sqlite_store import SqliteStore +from svc.llm.image_legacy_client import ( IMAGE_SPECIALIST_DEFAULT_PROMPT_ZH, collect_legacy_lane_images_from_attachments, collect_legacy_lane_images_with_session_fallback, @@ -21,19 +21,19 @@ from oclaw.platform.llm.image_legacy_client import ( legacy_image_turn_bundle, send_legacy_image_messages, ) -from oclaw.platform.llm.video_generation_client import ( +from svc.llm.video_generation_client import ( VIDEO_SPECIALIST_DEFAULT_PROMPT_ZH, legacy_video_assistant_body_with_placeholder, legacy_video_turn_bundle, send_video_generation_request, ) -from oclaw.runtime.tools import default_registry -from oclaw.runtime.agents.specialists import expert_name_for_specialist +from runtime.tools import default_registry +from runtime.agents.specialists import expert_name_for_specialist -from oclaw.runtime.chat.turn_types import TurnRunOutcome -from oclaw.runtime.relay_pointer import build_manifest_from_attachment_refs -from oclaw.runtime.types import RelayShareEnvelope -from oclaw.runtime.orchestration.protocol import ( +from runtime.chat.turn_types import TurnRunOutcome +from runtime.relay_pointer import build_manifest_from_attachment_refs +from runtime.types import RelayShareEnvelope +from runtime.orchestration.protocol import ( AgentTask, PlanStep, SpecialistDelivery, @@ -361,8 +361,8 @@ class SpecialistAgentRunner: path_policy_tenant_id=_path_tenant, path_policy_user_id=_path_user, ) - from oclaw.runtime.gateway import OclawGateway - from oclaw.runtime.types import StandardMessage + from runtime.gateway import OclawGateway + from runtime.types import StandardMessage gw = OclawGateway(store=self.store) msg = StandardMessage( diff --git a/runtime/agents/specialists.py b/runtime/agents/specialists.py index 12385b20..9e21a769 100644 --- a/runtime/agents/specialists.py +++ b/runtime/agents/specialists.py @@ -4,8 +4,8 @@ from dataclasses import dataclass import json from typing import Any -from oclaw.runtime.agent_context import build_role_system_context -from oclaw.runtime.workspaces.experts import specialist_registry_snapshot +from runtime.agent_context import build_role_system_context +from runtime.workspaces.experts import specialist_registry_snapshot SpecialistId = str diff --git a/runtime/application/gateway/inbound_service.py b/runtime/application/gateway/inbound_service.py index 04fa009f..844bc7a4 100644 --- a/runtime/application/gateway/inbound_service.py +++ b/runtime/application/gateway/inbound_service.py @@ -4,9 +4,9 @@ import hashlib import re from typing import Any -from oclaw.interfaces.channels.base import InboundMessage, OutboundMessage -from oclaw.interfaces.channels.wecom.wecom_bridge import WeComAdapter -from oclaw.runtime.types import normalize_interaction_mode, normalize_requested_specialist +from interfaces.channels.base import InboundMessage, OutboundMessage +from interfaces.channels.wecom.wecom_bridge import WeComAdapter +from runtime.types import normalize_interaction_mode, normalize_requested_specialist _CHANNEL_DISPATCH_INTERACTION_KEY_PREFIX = "channel.dispatch.interaction_mode." _CHANNEL_DISPATCH_SPECIALIST_KEY_PREFIX = "channel.dispatch.specialist." @@ -36,7 +36,7 @@ def _resolve_channel_dispatch(store: Any, *, channel: str, account: dict[str, An def _build_admin_gateway_executor(store: Any, *, tenant_id: str, specialist: str, session_id: str) -> Any: - from oclaw.runtime.agents.factory import build_gateway_executor + from runtime.agents.factory import build_gateway_executor return build_gateway_executor( store, @@ -71,8 +71,8 @@ def _handle_productivity_commands(*, text: str, tenant_id: str, user_id: str) -> if t in ("帮助", "菜单", "help", "/help"): return _menu_text() - from oclaw.platform.config.paths import db_path - from oclaw.platform.persistence.sqlite_store import SqliteStore + from svc.config.paths import db_path + from svc.persistence.sqlite_store import SqliteStore store = SqliteStore(db_path()) @@ -114,7 +114,7 @@ def _handle_productivity_commands(*, text: str, tenant_id: str, user_id: str) -> content = t[len("加知识 ") :].strip() if not content: return "知识内容不能为空。示例:加知识 办公室WiFi密码是12345678" - from oclaw.runtime.tools.experts.productivity.kb_tools import kb_add_tool + from runtime.tools.experts.productivity.kb_tools import kb_add_tool res = kb_add_tool().handler({"tenant_id": tenant_id, "user_id": user_id, "text": content}) if not res.get("ok"): @@ -125,7 +125,7 @@ def _handle_productivity_commands(*, text: str, tenant_id: str, user_id: str) -> q = t[len("查知识 ") :].strip() if not q: return "请提供关键词。示例:查知识 WiFi 密码" - from oclaw.runtime.tools.experts.productivity.kb_tools import kb_search_tool + from runtime.tools.experts.productivity.kb_tools import kb_search_tool res = kb_search_tool().handler({"tenant_id": tenant_id, "query": q, "limit": 5}) if not res.get("ok"): @@ -202,7 +202,7 @@ def _ensure_administrator_owner(store: Any) -> dict[str, Any] | None: user = store.get_user_by_username(tenant_id=tenant_id, username="administrator") if not user: try: - from oclaw.platform.config.passwords import load_expected_password + from svc.config.passwords import load_expected_password except Exception: load_expected_password = None # type: ignore pwd = load_expected_password(store) if callable(load_expected_password) else None @@ -366,7 +366,7 @@ def _collect_recent_tool_attachments(*, store: Any, session_id: str) -> list[dic def _maybe_add_media_path_for_wechat_reply(reply: dict[str, Any]) -> None: """For wechat/weixin sidecar, prefer a local file path for media send.""" try: - from oclaw.platform.files.attachment_assets import AttachmentAssetStore + from svc.files.attachment_assets import AttachmentAssetStore except Exception: return if not isinstance(reply, dict): @@ -421,7 +421,7 @@ def _maybe_expand_reply_attachments_for_channel(reply: dict[str, Any]) -> None: try: import base64 - from oclaw.platform.files.attachment_assets import AttachmentAssetStore + from svc.files.attachment_assets import AttachmentAssetStore except Exception: return ast = AttachmentAssetStore() @@ -495,7 +495,7 @@ def _should_suppress_channel_reply(*, channel: str, text: str) -> bool: def process_inbound_payload(payload: dict[str, Any]) -> dict[str, Any]: - from oclaw.runtime.operations.mcp_env import apply_gateway_mcp_env_to_os + from runtime.operations.mcp_env import apply_gateway_mcp_env_to_os apply_gateway_mcp_env_to_os() channel_name = str(payload.get("channel") or "wecom").strip().lower() @@ -505,8 +505,8 @@ def process_inbound_payload(payload: dict[str, Any]) -> dict[str, Any]: else: adapter = None inbound = _parse_generic_inbound(channel_name, payload) - from oclaw.platform.persistence.sqlite_store import SqliteStore - from oclaw.platform.config.paths import db_path + from svc.persistence.sqlite_store import SqliteStore + from svc.config.paths import db_path store = SqliteStore(db_path()) if channel_name == "wecom": @@ -567,8 +567,8 @@ def process_inbound_payload(payload: dict[str, Any]) -> dict[str, Any]: if not ident: reply = "账号初始化失败,请检查 administrator/tenant 配置。" if ident: - from oclaw.runtime.orchestration.policy import ActionPolicyContext, PolicyEngine - from oclaw.runtime.orchestration.security import has_explicit_confirmation_token + from runtime.orchestration.policy import ActionPolicyContext, PolicyEngine + from runtime.orchestration.security import has_explicit_confirmation_token tenant_id = str(ident.get("tenant_id") or "") user_id = str(ident.get("user_id") or "") @@ -630,8 +630,8 @@ def process_inbound_payload(payload: dict[str, Any]) -> dict[str, Any]: user_text = (inbound.text or "").strip() if user_text: try: - from oclaw.runtime.gateway import OclawGateway - from oclaw.runtime.types import StandardMessage + from runtime.gateway import OclawGateway + from runtime.types import StandardMessage interaction_mode, selected_specialist = _resolve_channel_dispatch( store, channel=inbound.channel, account=account diff --git a/runtime/chat/agent.py b/runtime/chat/agent.py index 16a393b1..2a48f71c 100644 --- a/runtime/chat/agent.py +++ b/runtime/chat/agent.py @@ -9,9 +9,9 @@ from collections.abc import Callable from dataclasses import dataclass from typing import Any, Optional -from oclaw.runtime.tools.base import ToolRegistry -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.platform.llm.chat_models import ( +from runtime.tools.base import ToolRegistry +from svc.persistence.sqlite_store import SqliteStore +from svc.llm.chat_models import ( ChatModel, LLMResponse, LLMToolCall, @@ -22,8 +22,8 @@ from oclaw.platform.llm.chat_models import ( build_default_model, gemini_openai_compat_client, ) -from oclaw.runtime.prompt_templates import render_prompt_for_lang -from oclaw.runtime.tools.tool_validation import validate_tool_arguments +from runtime.prompt_templates import render_prompt_for_lang +from runtime.tools.tool_validation import validate_tool_arguments logger = logging.getLogger(__name__) @@ -81,13 +81,13 @@ class Agent: def _format_ollama_failure_banner(self, exc: BaseException) -> str: # Backward compat wrapper; implementation lives in `src.chat.agent_errors`. - from oclaw.runtime.chat.agent_errors import format_ollama_failure_banner + from runtime.chat.agent_errors import format_ollama_failure_banner return format_ollama_failure_banner(lang=self.lang, exc=exc) def _format_openai_transport_error(self, exc: BaseException) -> str: # Backward compat wrapper; implementation lives in `src.chat.agent_errors`. - from oclaw.runtime.chat.agent_errors import format_openai_transport_error + from runtime.chat.agent_errors import format_openai_transport_error return format_openai_transport_error(lang=self.lang, exc=exc) @@ -197,8 +197,8 @@ class Agent: interaction_mode: str | None = None, selected_specialist: str | None = None, ) -> str: - from oclaw.runtime.gateway import OclawGateway - from oclaw.runtime.types import StandardMessage + from runtime.gateway import OclawGateway + from runtime.types import StandardMessage tenant_id = str(path_policy_tenant_id or "").strip() user_id = str(path_policy_user_id or "").strip() @@ -256,7 +256,7 @@ class Agent: return str(res.reply_text or "") def _build_llm_messages(self, session_id: str) -> list[dict[str, Any]]: - from oclaw.runtime.chat.agent_messages import build_llm_messages + from runtime.chat.agent_messages import build_llm_messages msgs = self.store.get_messages(session_id=session_id, limit=self.config.max_messages) trunc_raw = str(self.store.get_setting("AIA_TOOL_CONTEXT_TRUNCATE_ENABLED") or "").strip().lower() diff --git a/runtime/chat/agent_errors.py b/runtime/chat/agent_errors.py index d06a3c59..156ac4ec 100644 --- a/runtime/chat/agent_errors.py +++ b/runtime/chat/agent_errors.py @@ -6,7 +6,7 @@ from __future__ import annotations """ from typing import Any -from oclaw.runtime.prompt_templates import render_prompt +from runtime.prompt_templates import render_prompt def format_ollama_failure_banner(*, lang: str, exc: BaseException) -> str: diff --git a/runtime/chat/agent_messages.py b/runtime/chat/agent_messages.py index 9915e404..a0c9e6dc 100644 --- a/runtime/chat/agent_messages.py +++ b/runtime/chat/agent_messages.py @@ -13,12 +13,12 @@ import os import re from typing import Any -from oclaw.platform.llm.chat_models import _normalize_image_b64_payload, gemini_openai_compat_client, ChatModel -from oclaw.runtime.chat.media_redact import redact_embedded_image_blobs -from oclaw.runtime.chat.tool_runtime import tool_llm_message_max_chars, truncate_tool_result_for_llm_messages -from oclaw.runtime.prompt_templates import render_prompt -from oclaw.platform.files.attachment_assets import attachment_id_to_data_url -from oclaw.runtime.relay_pointer import parse_pointer_uri +from svc.llm.chat_models import _normalize_image_b64_payload, gemini_openai_compat_client, ChatModel +from runtime.chat.media_redact import redact_embedded_image_blobs +from runtime.chat.tool_runtime import tool_llm_message_max_chars, truncate_tool_result_for_llm_messages +from runtime.prompt_templates import render_prompt +from svc.files.attachment_assets import attachment_id_to_data_url +from runtime.relay_pointer import parse_pointer_uri logger = logging.getLogger(__name__) _THINK_BLOCK_RE = re.compile(r"\s*(.*?)\s*\s*", flags=re.IGNORECASE | re.DOTALL) @@ -207,7 +207,7 @@ def build_llm_messages( When ``active_turn_uuid`` matches a tool/user row ``turn_uuid``, that turn is treated as the in-flight MCP turn: tool JSON is not stripped of nested image payloads here (see also - :func:`~oclaw.runtime.direct_loop._guard_tool_results_for_llm_context`). Omit or leave empty + :func:`~runtime.direct_loop._guard_tool_results_for_llm_context`). Omit or leave empty to apply image-blob stripping for every tool row (safe default for callers without turn context). Only the **last** user message may expand attachments into native multimodal ``input_image`` diff --git a/runtime/chat/history_tool_result_compact.py b/runtime/chat/history_tool_result_compact.py index 7cf24b9d..995eb27e 100644 --- a/runtime/chat/history_tool_result_compact.py +++ b/runtime/chat/history_tool_result_compact.py @@ -4,8 +4,8 @@ import json from dataclasses import dataclass from typing import Any -from oclaw.runtime.chat.media_redact import redact_embedded_image_blobs -from oclaw.runtime.direct_loop import ( +from runtime.chat.media_redact import redact_embedded_image_blobs +from runtime.direct_loop import ( _OCLAW_TOOL_RESULT_HARD_CAP_CHARS, _image_tool_result_replay_cap_chars, _video_tool_result_replay_cap_chars, diff --git a/runtime/chat/media_redact.py b/runtime/chat/media_redact.py index b31362ba..7965acf8 100644 --- a/runtime/chat/media_redact.py +++ b/runtime/chat/media_redact.py @@ -7,7 +7,7 @@ from __future__ import annotations import base64 import os from typing import Any -from oclaw.platform.files.attachment_assets import AttachmentAssetStore +from svc.files.attachment_assets import AttachmentAssetStore _IMAGE_CONTENT_TYPES = frozenset({"image", "input_image"}) _BASE64_PAYLOAD_KEYS = ("data", "image_base64", "base64", "content_base64", "body_base64") diff --git a/runtime/chat/tool_runtime.py b/runtime/chat/tool_runtime.py index 6e02fbb8..e8c24aa3 100644 --- a/runtime/chat/tool_runtime.py +++ b/runtime/chat/tool_runtime.py @@ -17,16 +17,16 @@ from concurrent.futures import TimeoutError as FuturesTimeoutError from dataclasses import dataclass from typing import Any, Callable, Optional -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.tools.base import ToolRegistry -from oclaw.platform.llm.chat_models import LLMToolCall -from oclaw.runtime.tools.tool_validation import validate_tool_arguments -from oclaw.runtime.chat.media_redact import ingest_embedded_image_blobs_as_refs -from oclaw.runtime.tools.path_guard import ( +from svc.persistence.sqlite_store import SqliteStore +from runtime.tools.base import ToolRegistry +from svc.llm.chat_models import LLMToolCall +from runtime.tools.tool_validation import validate_tool_arguments +from runtime.chat.media_redact import ingest_embedded_image_blobs_as_refs +from runtime.tools.path_guard import ( workspace_path_access_scope, workspace_write_namespace_scope, ) -from oclaw.runtime.chat.tool_invocation_context import tool_workspace_lane_scope +from runtime.chat.tool_invocation_context import tool_workspace_lane_scope logger = logging.getLogger(__name__) _tool_exec_log = logging.getLogger("oclaw.tool_exec") @@ -628,7 +628,7 @@ class ToolExecutor: if not ctx.trace_id: return try: - from oclaw.runtime.orchestration.trace import new_span_id + from runtime.orchestration.trace import new_span_id ctx.store.add_trace_event( session_id=ctx.session_id, diff --git a/runtime/core/agent_execution.py b/runtime/core/agent_execution.py index b5258c4f..78f8ee51 100644 --- a/runtime/core/agent_execution.py +++ b/runtime/core/agent_execution.py @@ -1,8 +1,8 @@ from __future__ import annotations -from oclaw.runtime.agent_core_run import AgentCoreRunInput, run_agent_core -from oclaw.runtime.direct_loop import run_direct_loop -from oclaw.runtime.memory_stage import build_memory_context +from runtime.agent_core_run import AgentCoreRunInput, run_agent_core +from runtime.direct_loop import run_direct_loop +from runtime.memory_stage import build_memory_context __all__ = ["AgentCoreRunInput", "run_agent_core", "run_direct_loop", "build_memory_context"] diff --git a/runtime/direct_loop.py b/runtime/direct_loop.py index 57e975d9..56268509 100644 --- a/runtime/direct_loop.py +++ b/runtime/direct_loop.py @@ -12,20 +12,20 @@ from pathlib import Path from types import SimpleNamespace from typing import Any, Callable, Optional -from oclaw.runtime.chat.agent_messages import build_llm_messages, get_last_build_llm_messages_stats -from oclaw.runtime.chat.media_redact import redact_embedded_image_blobs -from oclaw.runtime.chat.tool_runtime import ToolExecutionConfig -from oclaw.runtime.chat.turn_types import TurnRunOutcome -from oclaw.runtime.skill_executor import SkillExecutionContext, SkillExecutor -from oclaw.runtime.skills import build_skill_manifest -from oclaw.platform.llm.chat_models import ChatModel -from oclaw.runtime.system_prompt import build_oclaw_executor_system_prompt -from oclaw.runtime.types import OclawMemoryContext -from oclaw.runtime.orchestration.trace import new_span_id -from oclaw.runtime.tools.base import ToolRegistry -from oclaw.runtime.hooks_runtime import trigger_hook_event -from oclaw.runtime.dsml_tool_parse import strip_first_dsml_tool_calls_block, try_parse_deepseek_v4_dsml_tool_calls -from oclaw.runtime.tools.experts.network_ops.netx_tools import ops_netx_system_context_extension +from runtime.chat.agent_messages import build_llm_messages, get_last_build_llm_messages_stats +from runtime.chat.media_redact import redact_embedded_image_blobs +from runtime.chat.tool_runtime import ToolExecutionConfig +from runtime.chat.turn_types import TurnRunOutcome +from runtime.skill_executor import SkillExecutionContext, SkillExecutor +from runtime.skills import build_skill_manifest +from svc.llm.chat_models import ChatModel +from runtime.system_prompt import build_oclaw_executor_system_prompt +from runtime.types import OclawMemoryContext +from runtime.orchestration.trace import new_span_id +from runtime.tools.base import ToolRegistry +from runtime.hooks_runtime import trigger_hook_event +from runtime.dsml_tool_parse import strip_first_dsml_tool_calls_block, try_parse_deepseek_v4_dsml_tool_calls +from runtime.tools.experts.network_ops.netx_tools import ops_netx_system_context_extension _OCLAW_TOOL_RESULT_HARD_CAP_CHARS = 24_000 _OCLAW_ATTACHMENT_TEXT_REPLAY_CAP_CHARS = 4_000 @@ -726,7 +726,7 @@ def _prepare_llm_tools( raw_llm_tools = [s.as_openai_tool() for s in skill_specs] else: raw_llm_tools = tools.as_openai_tools() - from oclaw.runtime.tools.exposure_plan import build_llm_tools_plan + from runtime.tools.exposure_plan import build_llm_tools_plan plan = build_llm_tools_plan( store=store, @@ -1136,7 +1136,7 @@ def _maybe_image_specialist_legacy_gateway_turn( ) -> TurnRunOutcome | None: """When the UI selects **image** specialist, skip Responses/chat-model transports. - Vision/gen HTTP goes through :func:`oclaw.platform.llm.image_legacy_client.send_legacy_image_messages` + Vision/gen HTTP goes through :func:`svc.llm.image_legacy_client.send_legacy_image_messages` (``/chat/completions`` lane). Disable with ``AIA_IMAGE_SPECIALIST_DISABLE_LEGACY_GATEWAY_LANE=1``. End-to-end notes and safe edit boundaries: ``docs/IMAGE_SPECIALIST_LANE.md``. @@ -1151,7 +1151,7 @@ def _maybe_image_specialist_legacy_gateway_turn( if str(skill_binding_role or "").strip().lower() != "image": return None - from oclaw.platform.llm.image_legacy_client import ( + from svc.llm.image_legacy_client import ( IMAGE_SPECIALIST_DEFAULT_PROMPT_ZH, collect_legacy_lane_images_with_session_fallback, legacy_image_assistant_body_with_placeholder, @@ -1241,7 +1241,7 @@ def _maybe_video_specialist_legacy_gateway_turn( ) -> TurnRunOutcome | None: """When the UI selects **video** specialist, skip Responses/chat-model transports. - Uses DashScope async ``video-synthesis`` (see :mod:`oclaw.platform.llm.video_generation_client`). + Uses DashScope async ``video-synthesis`` (see :mod:`svc.llm.video_generation_client`). With a user image (or session image fallback), sends ``input.img_url`` for **image-to-video**; otherwise **text-to-video**. Disable with ``AIA_VIDEO_SPECIALIST_DISABLE_LEGACY_GATEWAY_LANE=1``. """ @@ -1255,8 +1255,8 @@ def _maybe_video_specialist_legacy_gateway_turn( if str(skill_binding_role or "").strip().lower() != "video": return None - from oclaw.platform.llm.image_legacy_client import collect_legacy_lane_images_with_session_fallback - from oclaw.platform.llm.video_generation_client import ( + from svc.llm.image_legacy_client import collect_legacy_lane_images_with_session_fallback + from svc.llm.video_generation_client import ( VIDEO_SPECIALIST_DEFAULT_PROMPT_ZH, legacy_video_assistant_body_with_placeholder, legacy_video_turn_bundle, diff --git a/runtime/dsml_tool_parse.py b/runtime/dsml_tool_parse.py index 8c80a364..5ede1ab3 100644 --- a/runtime/dsml_tool_parse.py +++ b/runtime/dsml_tool_parse.py @@ -15,7 +15,7 @@ import re import uuid from typing import Any -from oclaw.platform.llm.transports.base import LLMToolCall +from svc.llm.transports.base import LLMToolCall # Official DeepSeek-V4 DSML token uses FULLWIDTH VERTICAL LINE (U+FF5C). _DSML_PIPE = "\uFF5C" diff --git a/runtime/extensions/anthropic/index.py b/runtime/extensions/anthropic/index.py index 5672521f..182418ad 100644 --- a/runtime/extensions/anthropic/index.py +++ b/runtime/extensions/anthropic/index.py @@ -1,7 +1,7 @@ from __future__ import annotations from .api import build_anthropic_provider -from oclaw.runtime.extensions.plugin_api import PluginEntry, define_plugin_entry +from runtime.extensions.plugin_api import PluginEntry, define_plugin_entry PLUGIN_ID = "anthropic" diff --git a/runtime/extensions/deepseek/index.py b/runtime/extensions/deepseek/index.py index 025d128b..b359f008 100644 --- a/runtime/extensions/deepseek/index.py +++ b/runtime/extensions/deepseek/index.py @@ -1,7 +1,7 @@ from __future__ import annotations from .api import build_deepseek_provider -from oclaw.runtime.extensions.plugin_api import PluginEntry, define_plugin_entry +from runtime.extensions.plugin_api import PluginEntry, define_plugin_entry PROVIDER_ID = "deepseek" diff --git a/runtime/extensions/image-generation-core/index.py b/runtime/extensions/image-generation-core/index.py index 4ac98f60..53bf0c94 100644 --- a/runtime/extensions/image-generation-core/index.py +++ b/runtime/extensions/image-generation-core/index.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.runtime.extensions.plugin_api import PluginEntry, define_plugin_entry +from runtime.extensions.plugin_api import PluginEntry, define_plugin_entry from .api import list_runtime_image_generation_providers diff --git a/runtime/extensions/kimi-coding/index.py b/runtime/extensions/kimi-coding/index.py index d19f6158..4696e69b 100644 --- a/runtime/extensions/kimi-coding/index.py +++ b/runtime/extensions/kimi-coding/index.py @@ -1,7 +1,7 @@ from __future__ import annotations from .api import build_kimi_coding_provider -from oclaw.runtime.extensions.plugin_api import PluginEntry, define_plugin_entry +from runtime.extensions.plugin_api import PluginEntry, define_plugin_entry PLUGIN_ID = "kimi" diff --git a/runtime/extensions/memory-core/index.py b/runtime/extensions/memory-core/index.py index 4ae21f81..55ba19e0 100644 --- a/runtime/extensions/memory-core/index.py +++ b/runtime/extensions/memory-core/index.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.runtime.extensions.plugin_api import PluginEntry, define_plugin_entry +from runtime.extensions.plugin_api import PluginEntry, define_plugin_entry PLUGIN_ID = "memory-core" PLUGIN_NAME = "Memory (Core)" diff --git a/runtime/extensions/memory-lancedb/api.py b/runtime/extensions/memory-lancedb/api.py index 8a187959..46e13083 100644 --- a/runtime/extensions/memory-lancedb/api.py +++ b/runtime/extensions/memory-lancedb/api.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.runtime.extensions.plugin_api import PluginEntry, define_plugin_entry +from runtime.extensions.plugin_api import PluginEntry, define_plugin_entry __all__ = ["PluginEntry", "define_plugin_entry"] diff --git a/runtime/extensions/memory-lancedb/index.py b/runtime/extensions/memory-lancedb/index.py index bd25ff78..47a0e60d 100644 --- a/runtime/extensions/memory-lancedb/index.py +++ b/runtime/extensions/memory-lancedb/index.py @@ -3,7 +3,7 @@ from __future__ import annotations import html import re -from oclaw.runtime.extensions.plugin_api import PluginEntry, define_plugin_entry +from runtime.extensions.plugin_api import PluginEntry, define_plugin_entry PROMPT_INJECTION_PATTERNS = ( re.compile(r"ignore (all|any|previous|above|prior) instructions", re.I), diff --git a/runtime/extensions/memory-wiki/index.py b/runtime/extensions/memory-wiki/index.py index e2af3a38..962be38c 100644 --- a/runtime/extensions/memory-wiki/index.py +++ b/runtime/extensions/memory-wiki/index.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.runtime.extensions.plugin_api import PluginEntry, define_plugin_entry +from runtime.extensions.plugin_api import PluginEntry, define_plugin_entry from .api import build_plugin_config_schema, build_wiki_tool_specs diff --git a/runtime/extensions/openai/index.py b/runtime/extensions/openai/index.py index 2a8cb3c9..7d19f46a 100644 --- a/runtime/extensions/openai/index.py +++ b/runtime/extensions/openai/index.py @@ -5,7 +5,7 @@ from .api import ( build_openai_image_generation_provider, build_openai_provider, ) -from oclaw.runtime.extensions.plugin_api import PluginEntry, define_plugin_entry +from runtime.extensions.plugin_api import PluginEntry, define_plugin_entry def register_openai_plugin(api) -> None: diff --git a/runtime/extensions/plugin_api.py b/runtime/extensions/plugin_api.py index 66c8af78..5607512f 100644 --- a/runtime/extensions/plugin_api.py +++ b/runtime/extensions/plugin_api.py @@ -1,5 +1,5 @@ from __future__ import annotations -from oclaw.runtime.extensions.api.plugin_api import PluginApi, PluginEntry, PluginLogger, PluginRuntime, define_plugin_entry +from runtime.extensions.api.plugin_api import PluginApi, PluginEntry, PluginLogger, PluginRuntime, define_plugin_entry __all__ = ["PluginApi", "PluginEntry", "PluginLogger", "PluginRuntime", "define_plugin_entry"] diff --git a/runtime/extensions/qwen/index.py b/runtime/extensions/qwen/index.py index 703f8cfb..9d7beff0 100644 --- a/runtime/extensions/qwen/index.py +++ b/runtime/extensions/qwen/index.py @@ -1,7 +1,7 @@ from __future__ import annotations from .api import QWEN_BASE_URL, build_qwen_provider -from oclaw.runtime.extensions.plugin_api import PluginEntry, define_plugin_entry +from runtime.extensions.plugin_api import PluginEntry, define_plugin_entry PROVIDER_ID = "qwen" diff --git a/runtime/extensions/telegram/index.py b/runtime/extensions/telegram/index.py index 3478dfae..1f61d63b 100644 --- a/runtime/extensions/telegram/index.py +++ b/runtime/extensions/telegram/index.py @@ -1,7 +1,7 @@ from __future__ import annotations from .api import telegram_plugin -from oclaw.runtime.extensions.plugin_api import PluginEntry, define_plugin_entry +from runtime.extensions.plugin_api import PluginEntry, define_plugin_entry def register_telegram_channel(api) -> None: diff --git a/runtime/gateway.py b/runtime/gateway.py index 0712d6b4..efad3e7e 100644 --- a/runtime/gateway.py +++ b/runtime/gateway.py @@ -10,39 +10,39 @@ from dataclasses import dataclass from pathlib import Path from typing import Any, Callable, Optional -from oclaw.runtime.agents.factory import build_ephemeral_executor -from oclaw.runtime.hooks.eligibility_from_metadata import hook_eligibility_from_message_metadata -from oclaw.runtime.hooks_runtime import ( +from runtime.agents.factory import build_ephemeral_executor +from runtime.hooks.eligibility_from_metadata import hook_eligibility_from_message_metadata +from runtime.hooks_runtime import ( get_active_hooks_config, initialize_hooks_runtime, trigger_hook_event, ) -from oclaw.runtime.relay_pointer import summarize_relay_ttl -from oclaw.runtime.skills import build_skill_manifest -from oclaw.runtime.prompt_prebuild import get_manager_prompt_prebuild -from oclaw.runtime.types import ( +from runtime.relay_pointer import summarize_relay_ttl +from runtime.skills import build_skill_manifest +from runtime.prompt_prebuild import get_manager_prompt_prebuild +from runtime.types import ( OclawSessionContext, StandardMessage, normalize_interaction_mode, normalize_requested_specialist, ) -from oclaw.platform.config.paths import PROJECT_ROOT -from oclaw.runtime.prompt_templates import render_prompt +from svc.config.paths import PROJECT_ROOT +from runtime.prompt_templates import render_prompt -from oclaw.runtime.command_parser import parse_internal_command -from oclaw.runtime.core.agent_execution import AgentCoreRunInput, build_memory_context, run_agent_core -from oclaw.runtime.router import decide_route -from oclaw.runtime.worker import ensure_worker_started -from oclaw.runtime.orchestration.trace import new_span_id, new_trace_id -from oclaw.runtime.chat.tool_runtime import compact_turn_tool_messages_for_storage -from oclaw.runtime.chat.model_path_audit import ensure_no_tool_or_embedded_image_payload -from oclaw.runtime.session_auto_title import ( +from runtime.command_parser import parse_internal_command +from runtime.core.agent_execution import AgentCoreRunInput, build_memory_context, run_agent_core +from runtime.router import decide_route +from runtime.worker import ensure_worker_started +from runtime.orchestration.trace import new_span_id, new_trace_id +from runtime.chat.tool_runtime import compact_turn_tool_messages_for_storage +from runtime.chat.model_path_audit import ensure_no_tool_or_embedded_image_payload +from runtime.session_auto_title import ( AUTO_TITLE_SYSTEM_PROMPT_EN, AUTO_TITLE_SYSTEM_PROMPT_ZH, finalize_auto_title, ) -from oclaw.runtime.tools.base import ToolRegistry -from oclaw.runtime.tools.public.local_sdk import local_adapter_startup_self_check +from runtime.tools.base import ToolRegistry +from runtime.tools.public.local_sdk import local_adapter_startup_self_check logger = logging.getLogger(__name__) @@ -953,8 +953,8 @@ class OclawGateway: system_prompt_override = "" tools_override = None if interaction_mode == "expert": - from oclaw.runtime.plan_agent_v2.gateway_adapter import evaluate_gateway_expert_turn_shadow - from oclaw.runtime.plan_agent_v2.tool_specs import DEFAULT_SESSION_KEY, materialize_plan_mode_v2_tools + from runtime.plan_agent_v2.gateway_adapter import evaluate_gateway_expert_turn_shadow + from runtime.plan_agent_v2.tool_specs import DEFAULT_SESSION_KEY, materialize_plan_mode_v2_tools execution_mode = str(base_metadata.get("execution_mode") or "agent").strip().lower() if execution_mode not in {"agent", "plan"}: @@ -1022,7 +1022,7 @@ class OclawGateway: except Exception: plan_mode = "" if plan_mode == "plan": - from oclaw.runtime.plan_agent_v2.tool_policy import filter_tools_for_mode + from runtime.plan_agent_v2.tool_policy import filter_tools_for_mode if isinstance(tools_override, ToolRegistry): filtered = filter_tools_for_mode(registry=tools_override, mode="plan") diff --git a/runtime/hooks/README.md b/runtime/hooks/README.md index cb77646d..dce36276 100644 --- a/runtime/hooks/README.md +++ b/runtime/hooks/README.md @@ -59,7 +59,7 @@ For role-specific behavior, contributors can add files under `data/wiki/experts/ #### Quick check ```bash -python -m oclaw.runtime.operations hooks info session-bootstrap --workspace "D:/project/chatgpt/oclaw" --json +python -m runtime.operations hooks info session-bootstrap --workspace "D:/project/chatgpt/oclaw" --json ``` Expected key fields: `enabled_by_config=true`, `eligible=true`, `loadable=true`. @@ -99,7 +99,7 @@ Legend: **Done** / **Partial** / **TODO** | package.json `openclaw.hooks` / `oclaw.hooks` | Done | | plugin hook dirs (`.codex-plugin` + `hooks`) | Done | | legacy `hooks.internal.handlers` | Done | -| `hooks list/check/info` CLI (`python -m oclaw.runtime.operations hooks …`) | Done | +| `hooks list/check/info` CLI (`python -m runtime.operations hooks …`) | Done | | `hooks enable` / `hooks disable` (config file patch) | Done | | install / update hook packs (npm/git; TS `install.ts` / `update.ts`) | Partial (`hooks install` / `hooks update` print deprecation + manual/OpenClaw guidance; no npm/git runner) | | gmail watcher family | Partial (config gates + ``initialize_hooks_runtime`` → ``start_gmail_watcher_with_logs``; ``gog``/API loop not ported). Set ``OCLAW_SKIP_GMAIL_WATCHER=1`` (or ``OPENCLAW_SKIP_GMAIL_WATCHER``) to no-op. | @@ -122,14 +122,14 @@ pytest tests/test_oclaw_hooks_bundled_parity.py tests/test_oclaw_hooks_runtime.p ### Operations CLI (from parent of this repo on `sys.path`, see `tests/conftest.py`) ```bash -python -m oclaw.runtime.operations hooks list -python -m oclaw.runtime.operations hooks list --eligible --verbose -python -m oclaw.runtime.operations hooks check --json -python -m oclaw.runtime.operations hooks info session-memory --workspace /path/to/workspace -python -m oclaw.runtime.operations hooks enable session-memory --workspace /path/to/workspace -python -m oclaw.runtime.operations hooks disable command-logger --workspace /path/to/workspace -python -m oclaw.runtime.operations hooks install ./path-or-npm-spec # deprecated, exit 2 + hints -python -m oclaw.runtime.operations hooks update --dry-run # deprecated, exit 2 + hints +python -m runtime.operations hooks list +python -m runtime.operations hooks list --eligible --verbose +python -m runtime.operations hooks check --json +python -m runtime.operations hooks info session-memory --workspace /path/to/workspace +python -m runtime.operations hooks enable session-memory --workspace /path/to/workspace +python -m runtime.operations hooks disable command-logger --workspace /path/to/workspace +python -m runtime.operations hooks install ./path-or-npm-spec # deprecated, exit 2 + hints +python -m runtime.operations hooks update --dry-run # deprecated, exit 2 + hints ``` Uses the same merged config as the agent runtime (including skill `hooks/` extra dirs via `merge_skill_hook_extra_dirs_into_config`). diff --git a/runtime/hooks/_selftest.py b/runtime/hooks/_selftest.py index 98ce9ee6..1c15925c 100644 --- a/runtime/hooks/_selftest.py +++ b/runtime/hooks/_selftest.py @@ -9,8 +9,8 @@ OCLAW_DIR = HOOKS_PY_DIR.parent if str(OCLAW_DIR) not in sys.path: sys.path.insert(0, str(OCLAW_DIR)) -from oclaw.runtime.hooks.internal_hooks import create_hook_event, trigger_hook # noqa: E402 -from oclaw.runtime.hooks.loader import load_internal_hooks # noqa: E402 +from runtime.hooks.internal_hooks import create_hook_event, trigger_hook # noqa: E402 +from runtime.hooks.loader import load_internal_hooks # noqa: E402 def main() -> int: diff --git a/runtime/hooks/bundled/session-memory/handler.py b/runtime/hooks/bundled/session-memory/handler.py index e25dd096..4168058d 100644 --- a/runtime/hooks/bundled/session-memory/handler.py +++ b/runtime/hooks/bundled/session-memory/handler.py @@ -122,8 +122,8 @@ def handle(event: Any) -> None: # Fetch recent messages from sqlite. try: _ensure_repo_imports() - from oclaw.platform.config.paths import db_path # type: ignore - from oclaw.platform.persistence.sqlite_store import SqliteStore # type: ignore + from svc.config.paths import db_path # type: ignore + from svc.persistence.sqlite_store import SqliteStore # type: ignore store = SqliteStore(db_path()) msgs = store.get_messages(session_id=session_id, limit=max_msgs_n) diff --git a/runtime/hooks/merge_skill_hook_dirs.py b/runtime/hooks/merge_skill_hook_dirs.py index b6b44262..50385b18 100644 --- a/runtime/hooks/merge_skill_hook_dirs.py +++ b/runtime/hooks/merge_skill_hook_dirs.py @@ -3,7 +3,7 @@ from __future__ import annotations from pathlib import Path from typing import Any -from oclaw.runtime.skills import discover_workspace_skill_manifests +from runtime.skills import discover_workspace_skill_manifests def merge_skill_hook_extra_dirs_into_config(cfg: dict[str, Any]) -> dict[str, Any]: diff --git a/runtime/hooks/user_config_hooks.py b/runtime/hooks/user_config_hooks.py index 6f16f9d0..814b8683 100644 --- a/runtime/hooks/user_config_hooks.py +++ b/runtime/hooks/user_config_hooks.py @@ -5,7 +5,7 @@ import os from pathlib import Path from typing import Any -from oclaw.platform.config.paths import PROJECT_ROOT +from svc.config.paths import PROJECT_ROOT def resolve_hooks_config_storage_path() -> Path: diff --git a/runtime/hooks_runtime.py b/runtime/hooks_runtime.py index 56370de0..d78aa04a 100644 --- a/runtime/hooks_runtime.py +++ b/runtime/hooks_runtime.py @@ -9,10 +9,10 @@ from dataclasses import dataclass from pathlib import Path from typing import Any -from oclaw.runtime.hooks.hook_types import HookEligibilityContext -from oclaw.runtime.hooks.merge_skill_hook_dirs import merge_skill_hook_extra_dirs_into_config -from oclaw.platform.config.paths import PROJECT_ROOT -from oclaw.platform.config.runtime_paths import runtime_hooks_bundled_root +from runtime.hooks.hook_types import HookEligibilityContext +from runtime.hooks.merge_skill_hook_dirs import merge_skill_hook_extra_dirs_into_config +from svc.config.paths import PROJECT_ROOT +from svc.config.runtime_paths import runtime_hooks_bundled_root @dataclass @@ -42,7 +42,7 @@ class _GmailWatcherLogAdapter: def _maybe_start_gmail_watcher_with_logs(resolved_cfg: dict[str, Any]) -> None: """After hooks load: parity hook for OpenClaw gateway post-attach Gmail lifecycle.""" try: - from oclaw.runtime.hooks.gmail_watcher_lifecycle import start_gmail_watcher_with_logs + from runtime.hooks.gmail_watcher_lifecycle import start_gmail_watcher_with_logs start_gmail_watcher_with_logs(cfg=resolved_cfg, log=_GmailWatcherLogAdapter()) except Exception: @@ -128,7 +128,7 @@ def initialize_hooks_runtime( return int(_STATE.loaded_count or 0) try: oclaw_dir = _ensure_oclaw_path() - from oclaw.runtime import hooks as hooks_mod # type: ignore + from runtime import hooks as hooks_mod # type: ignore bundled_dir = runtime_hooks_bundled_root() resolved_cfg = merge_skill_hook_extra_dirs_into_config(dict(cfg or resolve_runtime_config() or {})) diff --git a/runtime/memory_stage.py b/runtime/memory_stage.py index ab997574..d326600e 100644 --- a/runtime/memory_stage.py +++ b/runtime/memory_stage.py @@ -4,9 +4,9 @@ import json from pathlib import Path from typing import Any -from oclaw.runtime.types import OclawMemoryContext -from oclaw.runtime.orchestration.memory import semantic_retrieve, session_memory_digest -from oclaw.runtime.prompt_templates import render_runtime_prompt +from runtime.types import OclawMemoryContext +from runtime.orchestration.memory import semantic_retrieve, session_memory_digest +from runtime.prompt_templates import render_runtime_prompt _SPECIALIST_FLAGS_SETTING_KEY = "AIA_CHAT_SPECIALIST_FLAGS_JSON" @@ -145,8 +145,8 @@ def after_turn_memory( assistant_text=assistant_text, ) try: - from oclaw.runtime.orchestration.memory import maybe_write_turn_memory - from oclaw.platform.persistence.sqlite_store import SqliteStore + from runtime.orchestration.memory import maybe_write_turn_memory + from svc.persistence.sqlite_store import SqliteStore if isinstance(store, SqliteStore): maybe_write_turn_memory( diff --git a/runtime/operations/hooks_cmd.py b/runtime/operations/hooks_cmd.py index c793d0b4..e9470863 100644 --- a/runtime/operations/hooks_cmd.py +++ b/runtime/operations/hooks_cmd.py @@ -19,21 +19,21 @@ _DEPREC_UPDATE = ( " • If you use the OpenClaw app: use `openclaw plugins update`.\n" ) -from oclaw.platform.config.runtime_paths import runtime_hooks_bundled_root -from oclaw.runtime.hooks.config import should_include_hook -from oclaw.runtime.hooks.frontmatter import resolve_hook_key -from oclaw.runtime.hooks.hooks_status import build_workspace_hook_status -from oclaw.runtime.hooks.hook_types import HookEntry -from oclaw.runtime.hooks.merge_skill_hook_dirs import merge_skill_hook_extra_dirs_into_config -from oclaw.runtime.hooks.user_config_hooks import ( +from svc.config.runtime_paths import runtime_hooks_bundled_root +from runtime.hooks.config import should_include_hook +from runtime.hooks.frontmatter import resolve_hook_key +from runtime.hooks.hooks_status import build_workspace_hook_status +from runtime.hooks.hook_types import HookEntry +from runtime.hooks.merge_skill_hook_dirs import merge_skill_hook_extra_dirs_into_config +from runtime.hooks.user_config_hooks import ( apply_hook_entry_enabled, load_storage_config_document, resolve_hooks_config_storage_path, save_storage_config_document, ) -from oclaw.runtime.hooks.workspace import load_workspace_hook_entries -from oclaw.runtime.hooks_runtime import resolve_runtime_config -from oclaw.runtime.tools.path_guard import workspace_root +from runtime.hooks.workspace import load_workspace_hook_entries +from runtime.hooks_runtime import resolve_runtime_config +from runtime.tools.path_guard import workspace_root def _resolve_cli_workspace(ns: argparse.Namespace) -> str: @@ -196,7 +196,7 @@ def _cmd_hooks_info(args: argparse.Namespace) -> int: if args.json: print(json.dumps({"error": "not_found", "hook": name}, indent=2)) else: - print(f'Hook "{name}" not found. Try: python -m oclaw.runtime.operations hooks list') + print(f'Hook "{name}" not found. Try: python -m runtime.operations hooks list') return 1 if args.json: print(json.dumps(row, indent=2, default=str)) @@ -223,7 +223,7 @@ def _cmd_hooks_enable(args: argparse.Namespace) -> int: name = str(getattr(args, "name", "") or "").strip() entry = find_hook_entry_for_name(ws, name, config=None) if entry is None: - print(f'Hook "{name}" not found. Try: python -m oclaw.runtime.operations hooks list --workspace ...') + print(f'Hook "{name}" not found. Try: python -m runtime.operations hooks list --workspace ...') return 1 if entry.hook.source == "oclaw-plugin": print("Plugin-managed hooks cannot be enabled via this CLI; enable or configure the plugin instead.") diff --git a/runtime/operations/main.py b/runtime/operations/main.py index 0c4fd7f3..07356149 100644 --- a/runtime/operations/main.py +++ b/runtime/operations/main.py @@ -4,10 +4,10 @@ import argparse import os import sys -from oclaw.runtime.operations.hooks_cmd import register_hooks_parser -from oclaw.runtime.operations.memory import register_memory_parser -from oclaw.runtime.operations.providers.registry import build_channel_registry -from oclaw.runtime.operations.stack import register_stack_parser +from runtime.operations.hooks_cmd import register_hooks_parser +from runtime.operations.memory import register_memory_parser +from runtime.operations.providers.registry import build_channel_registry +from runtime.operations.stack import register_stack_parser def _cmd_gateway_start(args: argparse.Namespace) -> int: @@ -15,16 +15,16 @@ def _cmd_gateway_start(args: argparse.Namespace) -> int: os.environ["AIA_ASSISTANT_GATEWAY_HOST"] = args.host if args.port is not None: os.environ["AIA_ASSISTANT_GATEWAY_PORT"] = str(args.port) - from oclaw.runtime.operations.mcp_env import apply_gateway_mcp_env_to_os + from runtime.operations.mcp_env import apply_gateway_mcp_env_to_os apply_gateway_mcp_env_to_os() - from oclaw.interfaces.http.fastapi_app import main as fastapi_main + from interfaces.http.fastapi_app import main as fastapi_main return fastapi_main() def _build_parser() -> argparse.ArgumentParser: - p = argparse.ArgumentParser(prog="python -m oclaw.runtime.operations", description="Unified operational CLI") + p = argparse.ArgumentParser(prog="python -m runtime.operations", description="Unified operational CLI") root_sub = p.add_subparsers(dest="root_cmd", required=True) registry = build_channel_registry() diff --git a/runtime/operations/mcp_env.py b/runtime/operations/mcp_env.py index 218fc8b7..4ea8face 100644 --- a/runtime/operations/mcp_env.py +++ b/runtime/operations/mcp_env.py @@ -5,7 +5,7 @@ from __future__ import annotations import os from pathlib import Path -from oclaw.platform.config.paths import PROJECT_ROOT, db_path +from svc.config.paths import PROJECT_ROOT, db_path _DEFAULT_ALLOWLIST = ( "BRAVE_API_KEY,GOOGLE_OAUTH_CREDENTIALS,GOOGLE_CALENDAR_MCP_TOKEN_PATH," diff --git a/runtime/operations/mcp_registry_export.py b/runtime/operations/mcp_registry_export.py index 3e12301b..4cbb6fbf 100644 --- a/runtime/operations/mcp_registry_export.py +++ b/runtime/operations/mcp_registry_export.py @@ -8,9 +8,9 @@ from datetime import datetime, timezone from pathlib import Path from typing import Any -from oclaw.platform.config.paths import PROJECT_ROOT -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.tools.mcp.registry import McpRegistry +from svc.config.paths import PROJECT_ROOT +from svc.persistence.sqlite_store import SqliteStore +from runtime.tools.mcp.registry import McpRegistry _EXPORT_FILENAME = "mcp_registry_migrated.json" _LOCAL_DIR = (PROJECT_ROOT / "_local").resolve() diff --git a/runtime/operations/providers/wecom.py b/runtime/operations/providers/wecom.py index 55130410..cde3b2b6 100644 --- a/runtime/operations/providers/wecom.py +++ b/runtime/operations/providers/wecom.py @@ -6,9 +6,9 @@ import secrets import sys from argparse import _SubParsersAction -from oclaw.interfaces.channels.wecom.longconn_runner import run_forever as run_wecom_longconn -from oclaw.platform.config.paths import db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore +from interfaces.channels.wecom.longconn_runner import run_forever as run_wecom_longconn +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore from .base import ChannelProvider @@ -101,7 +101,7 @@ class WecomProvider(ChannelProvider): return run_wecom_longconn() def _cmd_status(self, _args: argparse.Namespace) -> int: - from oclaw.runtime.operations.scripts.wecom_status import main as status_main + from runtime.operations.scripts.wecom_status import main as status_main return status_main() @@ -150,7 +150,7 @@ class WecomProvider(ChannelProvider): return 0 def _cmd_smoke(self, args: argparse.Namespace) -> int: - from oclaw.runtime.operations.scripts.wecom_smoke_test import main as smoke_main + from runtime.operations.scripts.wecom_smoke_test import main as smoke_main old = sys.argv try: @@ -206,6 +206,6 @@ class WecomProvider(ChannelProvider): print("ok=1") print("mode=bot_api") print(f"bot_id={args.bot_id}") - print("next=python -m oclaw.runtime.operations channel wecom start") + print("next=python -m runtime.operations channel wecom start") return 0 diff --git a/runtime/operations/runtime.py b/runtime/operations/runtime.py index 789a6376..751a6320 100644 --- a/runtime/operations/runtime.py +++ b/runtime/operations/runtime.py @@ -9,7 +9,7 @@ from dataclasses import dataclass from pathlib import Path from typing import Any -from oclaw.platform.config.paths import db_path +from svc.config.paths import db_path def _runtime_file() -> Path: @@ -76,13 +76,13 @@ def _python_bin() -> str: def _service_signature(name: str) -> str | None: n = str(name or "").strip().lower() if n == "gateway": - return "-m oclaw.runtime.operations gateway start" + return "-m runtime.operations gateway start" if n == "ui": - return "-m oclaw.runtime.operations ui start" + return "-m runtime.operations ui start" if n.startswith("channel:"): ch = n.split(":", 1)[1].strip() if ch: - return f"-m oclaw.runtime.operations channel {ch} start" + return f"-m runtime.operations channel {ch} start" return None diff --git a/runtime/operations/scripts/create_bind_code.py b/runtime/operations/scripts/create_bind_code.py index 3a0145b2..6231f55a 100644 --- a/runtime/operations/scripts/create_bind_code.py +++ b/runtime/operations/scripts/create_bind_code.py @@ -3,8 +3,8 @@ from __future__ import annotations import secrets import sys -from oclaw.platform.config.paths import db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore def main() -> int: diff --git a/runtime/operations/scripts/generate_forwarders.py b/runtime/operations/scripts/generate_forwarders.py index 8f99aa82..029f9bcb 100644 --- a/runtime/operations/scripts/generate_forwarders.py +++ b/runtime/operations/scripts/generate_forwarders.py @@ -2,7 +2,7 @@ from __future__ import annotations from pathlib import Path -from oclaw.platform.config.runtime_paths import oclaw_root +from svc.config.runtime_paths import oclaw_root _PS1_FORWARDERS: dict[str, str] = { diff --git a/runtime/operations/scripts/install_extra_mcp_batch.py b/runtime/operations/scripts/install_extra_mcp_batch.py index 7ba1e789..642d7e31 100644 --- a/runtime/operations/scripts/install_extra_mcp_batch.py +++ b/runtime/operations/scripts/install_extra_mcp_batch.py @@ -11,9 +11,9 @@ from pathlib import Path ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT)) -from oclaw.platform.config.paths import db_path # noqa: E402 -from oclaw.platform.persistence.sqlite_store import SqliteStore # noqa: E402 -from oclaw.runtime.tools.mcp.installer import McpServerManifest, _safe_server_id, install_mcp_server # noqa: E402 +from svc.config.paths import db_path # noqa: E402 +from svc.persistence.sqlite_store import SqliteStore # noqa: E402 +from runtime.tools.mcp.installer import McpServerManifest, _safe_server_id, install_mcp_server # noqa: E402 # (server_id_seed, npm package ref, entry_args for npx) diff --git a/runtime/operations/scripts/install_mcp_context7.py b/runtime/operations/scripts/install_mcp_context7.py index c1e6e408..2827d939 100644 --- a/runtime/operations/scripts/install_mcp_context7.py +++ b/runtime/operations/scripts/install_mcp_context7.py @@ -14,10 +14,10 @@ from pathlib import Path ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT)) -from oclaw.platform.config.paths import db_path # noqa: E402 -from oclaw.platform.persistence.sqlite_store import SqliteStore # noqa: E402 -from oclaw.runtime.tools.mcp.installer import McpServerManifest, install_mcp_server # noqa: E402 -from oclaw.runtime.tools.mcp.runtime import McpProcessRuntime # noqa: E402 +from svc.config.paths import db_path # noqa: E402 +from svc.persistence.sqlite_store import SqliteStore # noqa: E402 +from runtime.tools.mcp.installer import McpServerManifest, install_mcp_server # noqa: E402 +from runtime.tools.mcp.runtime import McpProcessRuntime # noqa: E402 _BINDING_KEY = "mcp_specialist_server_binding" diff --git a/runtime/operations/scripts/install_mcp_sqlite_brave_calendar.py b/runtime/operations/scripts/install_mcp_sqlite_brave_calendar.py index 4dcde2ec..f64df79a 100644 --- a/runtime/operations/scripts/install_mcp_sqlite_brave_calendar.py +++ b/runtime/operations/scripts/install_mcp_sqlite_brave_calendar.py @@ -13,10 +13,10 @@ from pathlib import Path ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT)) -from oclaw.platform.config.paths import db_path # noqa: E402 -from oclaw.platform.persistence.sqlite_store import SqliteStore # noqa: E402 -from oclaw.runtime.tools.mcp.installer import McpServerManifest, install_mcp_server # noqa: E402 -from oclaw.runtime.tools.mcp.runtime import McpProcessRuntime # noqa: E402 +from svc.config.paths import db_path # noqa: E402 +from svc.persistence.sqlite_store import SqliteStore # noqa: E402 +from runtime.tools.mcp.installer import McpServerManifest, install_mcp_server # noqa: E402 +from runtime.tools.mcp.runtime import McpProcessRuntime # noqa: E402 def _sync_tools(store: SqliteStore, server_id: str) -> bool: diff --git a/runtime/operations/scripts/probe_openai_responses_image.py b/runtime/operations/scripts/probe_openai_responses_image.py index 219130c7..fc32778a 100644 --- a/runtime/operations/scripts/probe_openai_responses_image.py +++ b/runtime/operations/scripts/probe_openai_responses_image.py @@ -25,7 +25,7 @@ if str(_REPO_ROOT) not in sys.path: # Same bootstrap as gateway: ``interfaces/http/fastapi_app.py`` calls ``load_system_env()`` so # ``oclaw/_local/system.env`` is merged before reading ``OPENAI_*``. try: - from oclaw.platform.config.bootstrap_env import load_system_env + from svc.config.bootstrap_env import load_system_env load_system_env() except ImportError: diff --git a/runtime/operations/scripts/seed_mcp_registry.py b/runtime/operations/scripts/seed_mcp_registry.py index c9791162..9f57ccd6 100644 --- a/runtime/operations/scripts/seed_mcp_registry.py +++ b/runtime/operations/scripts/seed_mcp_registry.py @@ -15,9 +15,9 @@ from pathlib import Path ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT)) -from oclaw.platform.config.paths import PROJECT_ROOT, db_path # noqa: E402 -from oclaw.platform.persistence.sqlite_store import SqliteStore # noqa: E402 -from oclaw.runtime.tools.mcp.installer import McpServerManifest, _safe_server_id, install_mcp_server # noqa: E402 +from svc.config.paths import PROJECT_ROOT, db_path # noqa: E402 +from svc.persistence.sqlite_store import SqliteStore # noqa: E402 +from runtime.tools.mcp.installer import McpServerManifest, _safe_server_id, install_mcp_server # noqa: E402 def _subst_repo(path_str: str) -> str: diff --git a/runtime/operations/scripts/set_wecom_auto_bind.py b/runtime/operations/scripts/set_wecom_auto_bind.py index 3dc4a194..888e0c0a 100644 --- a/runtime/operations/scripts/set_wecom_auto_bind.py +++ b/runtime/operations/scripts/set_wecom_auto_bind.py @@ -2,8 +2,8 @@ from __future__ import annotations import sys -from oclaw.platform.config.paths import db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore def _to_bool(v: str) -> str: diff --git a/runtime/operations/scripts/set_wecom_config.py b/runtime/operations/scripts/set_wecom_config.py index 410fcaee..c9c804d8 100644 --- a/runtime/operations/scripts/set_wecom_config.py +++ b/runtime/operations/scripts/set_wecom_config.py @@ -2,8 +2,8 @@ from __future__ import annotations import sys -from oclaw.platform.config.paths import db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore def main() -> int: diff --git a/runtime/operations/scripts/start_all.ps1 b/runtime/operations/scripts/start_all.ps1 index 45eff2e8..ff50b3a1 100644 --- a/runtime/operations/scripts/start_all.ps1 +++ b/runtime/operations/scripts/start_all.ps1 @@ -43,9 +43,8 @@ if (-not $repoRoot) { # Fallback: old relative layout assumption $repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) } -$repoParent = Split-Path -Parent $repoRoot Set-Location $repoRoot -$env:PYTHONPATH = $repoParent +$env:PYTHONPATH = $repoRoot $env:PYTHONSAFEPATH = "1" $env:AIA_WORKSPACE_ROOT = $repoRoot $env:OPS_WORKSPACE_ROOT = $repoRoot diff --git a/runtime/operations/scripts/start_desktop.ps1 b/runtime/operations/scripts/start_desktop.ps1 index 19f59020..c3437a50 100644 --- a/runtime/operations/scripts/start_desktop.ps1 +++ b/runtime/operations/scripts/start_desktop.ps1 @@ -8,7 +8,6 @@ $ErrorActionPreference = "Stop" $repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) -$repoParent = Split-Path -Parent $repoRoot $desktopDir = Join-Path $repoRoot "desktop" $runDir = Join-Path $PSScriptRoot ".run" New-Item -ItemType Directory -Force -Path $runDir | Out-Null @@ -22,7 +21,7 @@ if (-not (Test-Path $desktopDir)) { } Set-Location $desktopDir -$env:PYTHONPATH = $repoParent +$env:PYTHONPATH = $repoRoot $env:PYTHONSAFEPATH = "1" $env:AIA_WORKSPACE_ROOT = $repoRoot $env:OPS_WORKSPACE_ROOT = $repoRoot diff --git a/runtime/operations/scripts/start_gateway.ps1 b/runtime/operations/scripts/start_gateway.ps1 index ecc6ace1..6c6b9b43 100644 --- a/runtime/operations/scripts/start_gateway.ps1 +++ b/runtime/operations/scripts/start_gateway.ps1 @@ -39,7 +39,6 @@ if (-not $repoRoot) { # Fallback: old relative layout assumption $repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) } -$repoParent = Split-Path -Parent $repoRoot Set-Location $repoRoot $runDir = Join-Path $PSScriptRoot ".run" @@ -49,7 +48,8 @@ $pidFile = Join-Path $runDir "gateway.pid" Write-Step "Project root: $repoRoot" Write-Step "Working directory: $repoRoot" -$env:PYTHONPATH = $repoParent +# Repo root must be on PYTHONPATH (top-level packages: runtime, svc, interfaces). +$env:PYTHONPATH = $repoRoot $env:PYTHONSAFEPATH = "1" $env:AIA_WORKSPACE_ROOT = $repoRoot $env:OPS_WORKSPACE_ROOT = $repoRoot @@ -95,7 +95,7 @@ if ($WithWikiWorker) { if ($Background) { Write-Step "Starting gateway in background" - $p = Start-Process -FilePath $pythonExe -ArgumentList @("-m","oclaw.runtime.operations","gateway","start","--host",$BindHost,"--port",$Port) -WorkingDirectory $repoRoot -PassThru -WindowStyle Hidden + $p = Start-Process -FilePath $pythonExe -ArgumentList @("-m","runtime.operations","gateway","start","--host",$BindHost,"--port",$Port) -WorkingDirectory $repoRoot -PassThru -WindowStyle Hidden Set-Content -Path $pidFile -Value "$($p.Id)" -Encoding ascii Write-Host "gateway.pid = $pidFile" -ForegroundColor DarkGray Write-Host "PID = $($p.Id)" -ForegroundColor Green @@ -103,7 +103,7 @@ if ($Background) { } Write-Step "Starting gateway (foreground)" -& $pythonExe -m oclaw.runtime.operations gateway start --host $BindHost --port $Port +& $pythonExe -m runtime.operations gateway start --host $BindHost --port $Port diff --git a/runtime/operations/scripts/start_ops.ps1 b/runtime/operations/scripts/start_ops.ps1 index 5dab38b4..d440e729 100644 --- a/runtime/operations/scripts/start_ops.ps1 +++ b/runtime/operations/scripts/start_ops.ps1 @@ -37,13 +37,12 @@ if (-not $repoRoot) { # Fallback: old relative layout assumption $repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) } -$repoParent = Split-Path -Parent $repoRoot Set-Location $repoRoot Write-Step "Project root: $repoRoot" Write-Step "Working directory: $repoRoot" -$env:PYTHONPATH = $repoParent +$env:PYTHONPATH = $repoRoot $env:PYTHONSAFEPATH = "1" $env:AIA_WORKSPACE_ROOT = $repoRoot $env:OPS_WORKSPACE_ROOT = $repoRoot @@ -72,21 +71,21 @@ if (-not $SkipInstall) { if (-not $SkipConfigHint) { Write-Step "Current WeCom status" try { - & $pythonExe -m oclaw.runtime.operations channel wecom status + & $pythonExe -m runtime.operations channel wecom status } catch { Write-Host "[WARN] Unable to read WeCom status yet." -ForegroundColor Yellow } Write-Host "" Write-Host "If WeCom is not configured yet, run this first:" -ForegroundColor Yellow - Write-Host " python -m oclaw.runtime.operations channel wecom config --help" + Write-Host " python -m runtime.operations channel wecom config --help" Write-Host "" } Write-Step "Stopping previous stack (safe if not running)" -& $pythonExe -m oclaw.runtime.operations stack down +& $pythonExe -m runtime.operations stack down -Write-Step "Starting stack: python -m oclaw.runtime.operations stack up --channel $Channel" -& $pythonExe -m oclaw.runtime.operations stack up --channel $Channel +Write-Step "Starting stack: python -m runtime.operations stack up --channel $Channel" +& $pythonExe -m runtime.operations stack up --channel $Channel Write-Host "" Write-Host "Started successfully." -ForegroundColor Green @@ -94,8 +93,8 @@ Write-Host "Admin: http://127.0.0.1:8787/admin" Write-Host "Chat: http://127.0.0.1:8787/chat" Write-Host "" Write-Host "Useful commands:" -Write-Host " python -m oclaw.runtime.operations stack status" -Write-Host " python -m oclaw.runtime.operations stack down" +Write-Host " python -m runtime.operations stack status" +Write-Host " python -m runtime.operations stack down" diff --git a/runtime/operations/scripts/start_wiki_worker.ps1 b/runtime/operations/scripts/start_wiki_worker.ps1 index 36219177..729e6afb 100644 --- a/runtime/operations/scripts/start_wiki_worker.ps1 +++ b/runtime/operations/scripts/start_wiki_worker.ps1 @@ -10,7 +10,6 @@ function Resolve-RepoRoot { } $repoRoot = Resolve-RepoRoot -$repoParent = Split-Path -Parent $repoRoot $runDir = Join-Path $PSScriptRoot ".run" $null = New-Item -ItemType Directory -Force -Path $runDir -ErrorAction SilentlyContinue $pidFile = Join-Path $runDir "wiki_worker.pid" @@ -30,7 +29,7 @@ function Test-IsWikiWorkerPid([int]$procId) { try { $wmi = Get-CimInstance Win32_Process -Filter "ProcessId = $procId" -ErrorAction Stop $cmd = [string]($wmi.CommandLine) - return $cmd -like "*oclaw.runtime.workers.wiki.main*" + return $cmd -like "*runtime.workers.wiki.main*" } catch { return $false } @@ -46,14 +45,14 @@ if (Test-Path $venvPython) { } $pythonExe = "python" } -$env:PYTHONPATH = $repoParent +$env:PYTHONPATH = $repoRoot $env:PYTHONSAFEPATH = "1" $env:AIA_WORKSPACE_ROOT = $repoRoot $env:OPS_WORKSPACE_ROOT = $repoRoot $env:OCLAW_WORKSPACE = $repoRoot if (-not $Background) { - & $pythonExe -m oclaw.runtime.workers.wiki.main + & $pythonExe -m runtime.workers.wiki.main exit 0 } @@ -67,7 +66,7 @@ if (Test-Path $pidFile) { } } -$p = Start-Process -FilePath $pythonExe -ArgumentList @("-m", "oclaw.runtime.workers.wiki.main") -WorkingDirectory $repoRoot -PassThru -WindowStyle Hidden -RedirectStandardOutput $outLog -RedirectStandardError $errLog +$p = Start-Process -FilePath $pythonExe -ArgumentList @("-m", "runtime.workers.wiki.main") -WorkingDirectory $repoRoot -PassThru -WindowStyle Hidden -RedirectStandardOutput $outLog -RedirectStandardError $errLog Set-Content -Path $pidFile -Value $p.Id -Encoding ascii Write-Host "[ok] started wiki worker pid=$($p.Id) out=$outLog err=$errLog" diff --git a/runtime/operations/scripts/status_ops.ps1 b/runtime/operations/scripts/status_ops.ps1 index 50262ec4..11f53e50 100644 --- a/runtime/operations/scripts/status_ops.ps1 +++ b/runtime/operations/scripts/status_ops.ps1 @@ -5,9 +5,8 @@ function Write-Step([string]$msg) { } $repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) -$repoParent = Split-Path -Parent $repoRoot Set-Location $repoRoot -$env:PYTHONPATH = $repoParent +$env:PYTHONPATH = $repoRoot $env:PYTHONSAFEPATH = "1" $env:AIA_WORKSPACE_ROOT = $repoRoot $env:OPS_WORKSPACE_ROOT = $repoRoot @@ -23,11 +22,11 @@ if (Test-Path $venvPython) { Write-Step "Project root: $repoRoot" Write-Step "Working directory: $repoRoot" Write-Step "Stack status" -& $pythonExe -m oclaw.runtime.operations stack status +& $pythonExe -m runtime.operations stack status Write-Host "" Write-Step "WeCom status" -& $pythonExe -m oclaw.runtime.operations channel wecom status +& $pythonExe -m runtime.operations channel wecom status Write-Host "" Write-Host "Admin: http://127.0.0.1:8787/admin" diff --git a/runtime/operations/scripts/stop_ops.ps1 b/runtime/operations/scripts/stop_ops.ps1 index ea8030b9..38277928 100644 --- a/runtime/operations/scripts/stop_ops.ps1 +++ b/runtime/operations/scripts/stop_ops.ps1 @@ -30,9 +30,8 @@ if (-not $repoRoot) { # Fallback: old relative layout assumption $repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) } -$repoParent = Split-Path -Parent $repoRoot Set-Location $repoRoot -$env:PYTHONPATH = $repoParent +$env:PYTHONPATH = $repoRoot $env:PYTHONSAFEPATH = "1" $env:AIA_WORKSPACE_ROOT = $repoRoot $env:OPS_WORKSPACE_ROOT = $repoRoot @@ -50,7 +49,7 @@ Write-Step "Working directory: $repoRoot" Write-Step "Stopping stack services..." try { - & $pythonExe -m oclaw.runtime.operations stack down + & $pythonExe -m runtime.operations stack down Write-Host "Stack stopped." -ForegroundColor Green } catch { Write-Host "[WARN] stack down failed: $($_.Exception.Message)" -ForegroundColor Yellow @@ -61,7 +60,7 @@ try { Write-Step "Current status" try { - & $pythonExe -m oclaw.runtime.operations stack status + & $pythonExe -m runtime.operations stack status } catch { Write-Host "[WARN] Unable to read status after stop." -ForegroundColor Yellow } diff --git a/runtime/operations/scripts/switch_wecom_bot.py b/runtime/operations/scripts/switch_wecom_bot.py index 39c96894..0e55d39f 100644 --- a/runtime/operations/scripts/switch_wecom_bot.py +++ b/runtime/operations/scripts/switch_wecom_bot.py @@ -2,8 +2,8 @@ from __future__ import annotations import sys -from oclaw.platform.config.paths import db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore _CLEAR_KEYS = [ @@ -40,7 +40,7 @@ def main() -> int: print("mode=bot_api") print(f"bot_id={bot_id}") print("cleared=" + ",".join(_CLEAR_KEYS)) - print("next=python -m oclaw.runtime.operations stack up --channel wecom") + print("next=python -m runtime.operations stack up --channel wecom") return 0 diff --git a/runtime/operations/scripts/unbind_wecom_bot.py b/runtime/operations/scripts/unbind_wecom_bot.py index 937322d9..01b10625 100644 --- a/runtime/operations/scripts/unbind_wecom_bot.py +++ b/runtime/operations/scripts/unbind_wecom_bot.py @@ -1,7 +1,7 @@ from __future__ import annotations -from oclaw.platform.config.paths import db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore _CLEAR_KEYS = [ @@ -39,7 +39,7 @@ def main() -> int: print(f"deleted_channel_identity={ident_deleted}") print(f"deleted_channel_session={sess_deleted}") print("cleared_settings=" + ",".join(_CLEAR_KEYS)) - print("next=python -m oclaw.runtime.operations channel wecom config set --type bot --bot-id --bot-secret ") + print("next=python -m runtime.operations channel wecom config set --type bot --bot-id --bot-secret ") return 0 diff --git a/runtime/operations/scripts/verify_forwarders.py b/runtime/operations/scripts/verify_forwarders.py index 3f6e99b2..27d130b3 100644 --- a/runtime/operations/scripts/verify_forwarders.py +++ b/runtime/operations/scripts/verify_forwarders.py @@ -2,7 +2,7 @@ from __future__ import annotations from pathlib import Path -from oclaw.platform.config.runtime_paths import oclaw_root, runtime_operations_scripts_root +from svc.config.runtime_paths import oclaw_root, runtime_operations_scripts_root def verify_forwarders() -> tuple[bool, list[str]]: diff --git a/runtime/operations/scripts/wecom_smoke_test.py b/runtime/operations/scripts/wecom_smoke_test.py index d7b15138..d42a8f17 100644 --- a/runtime/operations/scripts/wecom_smoke_test.py +++ b/runtime/operations/scripts/wecom_smoke_test.py @@ -4,9 +4,9 @@ import json import sys import uuid -from oclaw.platform.config.paths import db_path -from oclaw.platform.integrations.wecom_client import WeComClient -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.config.paths import db_path +from svc.integrations.wecom_client import WeComClient +from svc.persistence.sqlite_store import SqliteStore def main() -> int: diff --git a/runtime/operations/scripts/wecom_status.py b/runtime/operations/scripts/wecom_status.py index e37b070b..e9bb7e96 100644 --- a/runtime/operations/scripts/wecom_status.py +++ b/runtime/operations/scripts/wecom_status.py @@ -3,9 +3,9 @@ from __future__ import annotations import json from datetime import datetime, timezone -from oclaw.platform.config.paths import db_path -from oclaw.platform.integrations.wecom_client import WeComClient -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.config.paths import db_path +from svc.integrations.wecom_client import WeComClient +from svc.persistence.sqlite_store import SqliteStore def _fmt_ts(ts: str) -> str: diff --git a/runtime/operations/scripts/wiki_auto_smoke_test.py b/runtime/operations/scripts/wiki_auto_smoke_test.py index 775650ae..a6cced56 100644 --- a/runtime/operations/scripts/wiki_auto_smoke_test.py +++ b/runtime/operations/scripts/wiki_auto_smoke_test.py @@ -11,8 +11,8 @@ _REPO_ROOT = Path(__file__).resolve().parents[2] if str(_REPO_ROOT) not in sys.path: sys.path.insert(0, str(_REPO_ROOT)) -from oclaw.platform.config.paths import PROJECT_ROOT, db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.config.paths import PROJECT_ROOT, db_path +from svc.persistence.sqlite_store import SqliteStore def _load_cfg() -> dict: diff --git a/runtime/operations/stack.py b/runtime/operations/stack.py index 9a690f4c..a87bb11f 100644 --- a/runtime/operations/stack.py +++ b/runtime/operations/stack.py @@ -13,7 +13,7 @@ def cmd_stack_up(args: argparse.Namespace) -> int: gateway_cmd = default_python_command( [ "-m", - "oclaw.runtime.operations", + "runtime.operations", "gateway", "start", "--host", @@ -27,7 +27,7 @@ def cmd_stack_up(args: argparse.Namespace) -> int: channel_cmd = default_python_command( [ "-m", - "oclaw.runtime.operations", + "runtime.operations", "channel", args.channel, "start", @@ -51,7 +51,7 @@ def cmd_stack_up(args: argparse.Namespace) -> int: print("ok=1") for name, pid in started: print(f"{name}_pid={pid}") - print("hint=use `python -m oclaw.runtime.operations stack status` to check running services") + print("hint=use `python -m runtime.operations stack status` to check running services") return 0 diff --git a/runtime/orchestration/evaluation.py b/runtime/orchestration/evaluation.py index c89bda3b..70ec9cc3 100644 --- a/runtime/orchestration/evaluation.py +++ b/runtime/orchestration/evaluation.py @@ -3,7 +3,7 @@ from __future__ import annotations from collections import defaultdict from typing import Any -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.persistence.sqlite_store import SqliteStore def log_eval_event( diff --git a/runtime/orchestration/inventory.py b/runtime/orchestration/inventory.py index 0eb9b9ca..0e7cd32c 100644 --- a/runtime/orchestration/inventory.py +++ b/runtime/orchestration/inventory.py @@ -2,7 +2,7 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools import tool_inventory +from runtime.tools import tool_inventory def inventory_snapshot() -> dict[str, Any]: diff --git a/runtime/orchestration/memory.py b/runtime/orchestration/memory.py index 2dbf8a04..5ac89b51 100644 --- a/runtime/orchestration/memory.py +++ b/runtime/orchestration/memory.py @@ -5,9 +5,9 @@ import re import uuid from typing import Any -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.platform.embeddings.embedding_client import build_default_embedding_client -from oclaw.runtime.orchestration.vector_store import ( +from svc.persistence.sqlite_store import SqliteStore +from svc.embeddings.embedding_client import build_default_embedding_client +from runtime.orchestration.vector_store import ( MemoryVectorItem, read_vector_memory_runtime, semantic_search, diff --git a/runtime/orchestration/security.py b/runtime/orchestration/security.py index 42b77fd0..47935232 100644 --- a/runtime/orchestration/security.py +++ b/runtime/orchestration/security.py @@ -2,7 +2,7 @@ from __future__ import annotations from dataclasses import dataclass -from oclaw.runtime.orchestration.protocol import AgentTask +from runtime.orchestration.protocol import AgentTask _HIGH_RISK_ACTIONS = ("删除", "drop", "重启", "批量", "扫描", "写入", "变更") diff --git a/runtime/orchestration/session_mapping.py b/runtime/orchestration/session_mapping.py index 47a8b300..f55379b6 100644 --- a/runtime/orchestration/session_mapping.py +++ b/runtime/orchestration/session_mapping.py @@ -2,7 +2,7 @@ from __future__ import annotations from dataclasses import dataclass -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.persistence.sqlite_store import SqliteStore @dataclass(frozen=True) diff --git a/runtime/orchestration/tool_adapter.py b/runtime/orchestration/tool_adapter.py index 48fc8163..700787d8 100644 --- a/runtime/orchestration/tool_adapter.py +++ b/runtime/orchestration/tool_adapter.py @@ -3,7 +3,7 @@ from __future__ import annotations import time from typing import Any -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.persistence.sqlite_store import SqliteStore class ToolAuditAdapter: diff --git a/runtime/orchestration/vector_store.py b/runtime/orchestration/vector_store.py index d9f1e53c..3b71781d 100644 --- a/runtime/orchestration/vector_store.py +++ b/runtime/orchestration/vector_store.py @@ -6,8 +6,8 @@ from dataclasses import dataclass from datetime import datetime, timezone from typing import Any, Protocol -from oclaw.platform.embeddings.embedding_client import EmbeddingClient -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.embeddings.embedding_client import EmbeddingClient +from svc.persistence.sqlite_store import SqliteStore def _utc_now_iso() -> str: diff --git a/runtime/plan_agent_v2/compat.py b/runtime/plan_agent_v2/compat.py index d18bab92..e5700f5a 100644 --- a/runtime/plan_agent_v2/compat.py +++ b/runtime/plan_agent_v2/compat.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import Any from .adapter import PlanAgentV2Decision -from oclaw.runtime.gateway import OclawGatewayResult +from runtime.gateway import OclawGatewayResult def legacy_gateway_result_keys() -> set[str]: diff --git a/runtime/plan_agent_v2/gateway_adapter.py b/runtime/plan_agent_v2/gateway_adapter.py index e5f6c3bf..231d22e6 100644 --- a/runtime/plan_agent_v2/gateway_adapter.py +++ b/runtime/plan_agent_v2/gateway_adapter.py @@ -5,7 +5,7 @@ from typing import Any from .adapter import PlanAgentV2Decision, evaluate_for_expert_mode from .switch import should_route_to_v2 -from oclaw.runtime.types import StandardMessage +from runtime.types import StandardMessage @dataclass(frozen=True) diff --git a/runtime/plan_agent_v2/tool_policy.py b/runtime/plan_agent_v2/tool_policy.py index 33394d6a..5f6384ff 100644 --- a/runtime/plan_agent_v2/tool_policy.py +++ b/runtime/plan_agent_v2/tool_policy.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import Iterable from .models import PLAN_MODE_PLAN -from oclaw.runtime.tools.base import ToolRegistry, ToolSpec +from runtime.tools.base import ToolRegistry, ToolSpec _DEFAULT_PLAN_ALLOWLIST = frozenset( diff --git a/runtime/plan_agent_v2/tool_specs.py b/runtime/plan_agent_v2/tool_specs.py index 6f873645..ec6ee6e5 100644 --- a/runtime/plan_agent_v2/tool_specs.py +++ b/runtime/plan_agent_v2/tool_specs.py @@ -5,7 +5,7 @@ from typing import Any from .manager import PlanModeManagerV2 from .models import PLAN_MODE_PLAN from .trace import emit_plan_agent_v2_trace -from oclaw.runtime.tools.base import ToolSpec +from runtime.tools.base import ToolSpec DEFAULT_SESSION_KEY = "AIA_PLAN_AGENT_V2_DEFAULT_SESSION_ID" diff --git a/runtime/plan_agent_v2/trace.py b/runtime/plan_agent_v2/trace.py index b242ed03..7df2e5e8 100644 --- a/runtime/plan_agent_v2/trace.py +++ b/runtime/plan_agent_v2/trace.py @@ -19,7 +19,7 @@ def emit_plan_agent_v2_trace( merged.setdefault("pipeline", "plan_agent_v2") merged.setdefault("ts_ms", int(time.time() * 1000)) try: - from oclaw.runtime.orchestration.trace import new_span_id + from runtime.orchestration.trace import new_span_id store.add_trace_event( session_id=str(session_id or ""), diff --git a/runtime/plan_agent_v2_adapter.py b/runtime/plan_agent_v2_adapter.py index 59da0316..34cea22d 100644 --- a/runtime/plan_agent_v2_adapter.py +++ b/runtime/plan_agent_v2_adapter.py @@ -1,2 +1,2 @@ -from oclaw.runtime.plan_agent_v2.adapter import * # noqa: F403 +from runtime.plan_agent_v2.adapter import * # noqa: F403 diff --git a/runtime/plan_agent_v2_compat.py b/runtime/plan_agent_v2_compat.py index 16ec4edf..798b4475 100644 --- a/runtime/plan_agent_v2_compat.py +++ b/runtime/plan_agent_v2_compat.py @@ -1,2 +1,2 @@ -from oclaw.runtime.plan_agent_v2.compat import * # noqa: F403 +from runtime.plan_agent_v2.compat import * # noqa: F403 diff --git a/runtime/plan_agent_v2_gateway_adapter.py b/runtime/plan_agent_v2_gateway_adapter.py index 71b8fb45..0a63f058 100644 --- a/runtime/plan_agent_v2_gateway_adapter.py +++ b/runtime/plan_agent_v2_gateway_adapter.py @@ -1,2 +1,2 @@ -from oclaw.runtime.plan_agent_v2.gateway_adapter import * # noqa: F403 +from runtime.plan_agent_v2.gateway_adapter import * # noqa: F403 diff --git a/runtime/plan_agent_v2_gateway_cutover.py b/runtime/plan_agent_v2_gateway_cutover.py index 5588a486..1cf606b3 100644 --- a/runtime/plan_agent_v2_gateway_cutover.py +++ b/runtime/plan_agent_v2_gateway_cutover.py @@ -5,12 +5,12 @@ import uuid from dataclasses import dataclass from typing import Any -from oclaw.runtime.gateway import OclawGatewayResult -from oclaw.runtime.plan_agent_v2 import ( +from runtime.gateway import OclawGatewayResult +from runtime.plan_agent_v2 import ( build_shadow_gateway_result, evaluate_gateway_expert_turn_shadow, ) -from oclaw.runtime.types import StandardMessage +from runtime.types import StandardMessage @dataclass(frozen=True) diff --git a/runtime/plan_agent_v2_manager.py b/runtime/plan_agent_v2_manager.py index 56a3b100..656684ac 100644 --- a/runtime/plan_agent_v2_manager.py +++ b/runtime/plan_agent_v2_manager.py @@ -1,2 +1,2 @@ -from oclaw.runtime.plan_agent_v2.manager import * # noqa: F403 +from runtime.plan_agent_v2.manager import * # noqa: F403 diff --git a/runtime/plan_agent_v2_models.py b/runtime/plan_agent_v2_models.py index a8129709..7b3eafbd 100644 --- a/runtime/plan_agent_v2_models.py +++ b/runtime/plan_agent_v2_models.py @@ -1,2 +1,2 @@ -from oclaw.runtime.plan_agent_v2.models import * # noqa: F403 +from runtime.plan_agent_v2.models import * # noqa: F403 diff --git a/runtime/plan_agent_v2_prompt_injector.py b/runtime/plan_agent_v2_prompt_injector.py index a63e1ce8..fd3ba06c 100644 --- a/runtime/plan_agent_v2_prompt_injector.py +++ b/runtime/plan_agent_v2_prompt_injector.py @@ -1,2 +1,2 @@ -from oclaw.runtime.plan_agent_v2.prompt_injector import * # noqa: F403 +from runtime.plan_agent_v2.prompt_injector import * # noqa: F403 diff --git a/runtime/plan_agent_v2_state_store.py b/runtime/plan_agent_v2_state_store.py index af051d9a..cdb916de 100644 --- a/runtime/plan_agent_v2_state_store.py +++ b/runtime/plan_agent_v2_state_store.py @@ -1,2 +1,2 @@ -from oclaw.runtime.plan_agent_v2.state_store import * # noqa: F403 +from runtime.plan_agent_v2.state_store import * # noqa: F403 diff --git a/runtime/plan_agent_v2_switch.py b/runtime/plan_agent_v2_switch.py index ae3dd708..32dbd56a 100644 --- a/runtime/plan_agent_v2_switch.py +++ b/runtime/plan_agent_v2_switch.py @@ -1,2 +1,2 @@ -from oclaw.runtime.plan_agent_v2.switch import * # noqa: F403 +from runtime.plan_agent_v2.switch import * # noqa: F403 diff --git a/runtime/plan_agent_v2_tool_policy.py b/runtime/plan_agent_v2_tool_policy.py index 020db81d..1f080589 100644 --- a/runtime/plan_agent_v2_tool_policy.py +++ b/runtime/plan_agent_v2_tool_policy.py @@ -1,2 +1,2 @@ -from oclaw.runtime.plan_agent_v2.tool_policy import * # noqa: F403 +from runtime.plan_agent_v2.tool_policy import * # noqa: F403 diff --git a/runtime/plan_agent_v2_tool_specs.py b/runtime/plan_agent_v2_tool_specs.py index ef948084..21858d7e 100644 --- a/runtime/plan_agent_v2_tool_specs.py +++ b/runtime/plan_agent_v2_tool_specs.py @@ -1,2 +1,2 @@ -from oclaw.runtime.plan_agent_v2.tool_specs import * # noqa: F403 +from runtime.plan_agent_v2.tool_specs import * # noqa: F403 diff --git a/runtime/plan_agent_v2_trace.py b/runtime/plan_agent_v2_trace.py index 140b653d..744591bb 100644 --- a/runtime/plan_agent_v2_trace.py +++ b/runtime/plan_agent_v2_trace.py @@ -1,2 +1,2 @@ -from oclaw.runtime.plan_agent_v2.trace import * # noqa: F403 +from runtime.plan_agent_v2.trace import * # noqa: F403 diff --git a/runtime/project_context_prompt.py b/runtime/project_context_prompt.py index 975f00ec..749ab1dd 100644 --- a/runtime/project_context_prompt.py +++ b/runtime/project_context_prompt.py @@ -4,10 +4,10 @@ import os from pathlib import Path from typing import Any -from oclaw.runtime.agents.agent_scope import resolve_agent_id_by_workspace_path -from oclaw.runtime.hooks_runtime import get_active_hooks_config, trigger_hook_event -from oclaw.platform.config.paths import PROJECT_ROOT -from oclaw.runtime.prompt_templates import render_runtime_prompt +from runtime.agents.agent_scope import resolve_agent_id_by_workspace_path +from runtime.hooks_runtime import get_active_hooks_config, trigger_hook_event +from svc.config.paths import PROJECT_ROOT +from runtime.prompt_templates import render_runtime_prompt _PROJECT_CONTEXT_FILES: tuple[str, ...] = ( "TOOLS.md", diff --git a/runtime/prompt_prebuild.py b/runtime/prompt_prebuild.py index 36c168ec..6eb2ff71 100644 --- a/runtime/prompt_prebuild.py +++ b/runtime/prompt_prebuild.py @@ -4,16 +4,16 @@ import threading import time from typing import Any -from oclaw.platform.config.paths import db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.agent_context import build_role_system_context -from oclaw.runtime.agents.specialists import discover_specialist_ids -from oclaw.runtime.direct_loop import tool_wire_freeze_status, warm_tool_wire_cache -from oclaw.runtime.skill_role_binding import SKILL_ROLE_BINDING_KEY -from oclaw.runtime.skills import workspace_skills_layout_signature -from oclaw.runtime.system_prompt import get_executor_prompt_static, warm_executor_prompt_cache -from oclaw.runtime.tools.catalog import default_registry -from oclaw.runtime.workspaces.experts import expert_workspace_signature_token, list_experts +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore +from runtime.agent_context import build_role_system_context +from runtime.agents.specialists import discover_specialist_ids +from runtime.direct_loop import tool_wire_freeze_status, warm_tool_wire_cache +from runtime.skill_role_binding import SKILL_ROLE_BINDING_KEY +from runtime.skills import workspace_skills_layout_signature +from runtime.system_prompt import get_executor_prompt_static, warm_executor_prompt_cache +from runtime.tools.catalog import default_registry +from runtime.workspaces.experts import expert_workspace_signature_token, list_experts _MANAGER_PREBUILD_CACHE_LOCK = threading.Lock() _MANAGER_PREBUILD_CACHE: dict[tuple[Any, ...], dict[str, Any]] = {} diff --git a/runtime/prompt_templates/loader.py b/runtime/prompt_templates/loader.py index 94723cb3..d12b1cf5 100644 --- a/runtime/prompt_templates/loader.py +++ b/runtime/prompt_templates/loader.py @@ -6,8 +6,8 @@ from functools import lru_cache from pathlib import Path from typing import Any -from oclaw.platform.config.paths import PROJECT_ROOT -from oclaw.runtime.prompt_templates.frontmatter import parse_markdown_document +from svc.config.paths import PROJECT_ROOT +from runtime.prompt_templates.frontmatter import parse_markdown_document _VAR_RE = re.compile(r"\{\{\s*([a-zA-Z0-9_]+)\s*\}\}") diff --git a/runtime/relay_pointer.py b/runtime/relay_pointer.py index 9937e500..3c9b9204 100644 --- a/runtime/relay_pointer.py +++ b/runtime/relay_pointer.py @@ -8,7 +8,7 @@ from dataclasses import dataclass from pathlib import Path from typing import Any -from oclaw.runtime.types import SharedAttachmentManifest, SharedFilePointer +from runtime.types import SharedAttachmentManifest, SharedFilePointer _SAFE_FILE_NAME = re.compile(r"^[A-Za-z0-9._-]{1,128}$") _SAFE_SCOPE_ID = re.compile(r"^[A-Za-z0-9._-]{1,128}$") diff --git a/runtime/router.py b/runtime/router.py index 1cba33a5..285e1a69 100644 --- a/runtime/router.py +++ b/runtime/router.py @@ -5,10 +5,10 @@ import os from dataclasses import dataclass from typing import Any -from oclaw.runtime.types import StandardMessage -from oclaw.runtime.types import normalize_interaction_mode, normalize_requested_specialist -from oclaw.runtime.prompt_templates import render_runtime_prompt -from oclaw.runtime.chat.model_path_audit import ensure_no_tool_or_embedded_image_payload +from runtime.types import StandardMessage +from runtime.types import normalize_interaction_mode, normalize_requested_specialist +from runtime.prompt_templates import render_runtime_prompt +from runtime.chat.model_path_audit import ensure_no_tool_or_embedded_image_payload @dataclass(frozen=True) diff --git a/runtime/skill_executor.py b/runtime/skill_executor.py index 60ba5f52..5303975b 100644 --- a/runtime/skill_executor.py +++ b/runtime/skill_executor.py @@ -3,16 +3,16 @@ from __future__ import annotations from dataclasses import dataclass from typing import Any, Callable, Optional -from oclaw.runtime.chat.tool_runtime import ( +from runtime.chat.tool_runtime import ( ToolExecutionConfig, ToolExecutionContext, ToolExecutor, ) -from oclaw.runtime.hooks.hook_types import HookEligibilityContext -from oclaw.runtime.hooks_runtime import get_active_hooks_config, initialize_hooks_runtime, trigger_hook_event -from oclaw.runtime.orchestration.trace import new_span_id -from oclaw.platform.llm.chat_models import LLMToolCall -from oclaw.runtime.tools.base import ToolRegistry +from runtime.hooks.hook_types import HookEligibilityContext +from runtime.hooks_runtime import get_active_hooks_config, initialize_hooks_runtime, trigger_hook_event +from runtime.orchestration.trace import new_span_id +from svc.llm.chat_models import LLMToolCall +from runtime.tools.base import ToolRegistry @dataclass(frozen=True) diff --git a/runtime/skill_installer.py b/runtime/skill_installer.py index 820a4fe6..4a9cecc1 100644 --- a/runtime/skill_installer.py +++ b/runtime/skill_installer.py @@ -17,19 +17,19 @@ from dataclasses import dataclass from pathlib import Path from typing import Any -from oclaw.runtime.skills_market import get_market_adapter -from oclaw.runtime.skill_role_binding import ( +from runtime.skills_market import get_market_adapter +from runtime.skill_role_binding import ( SKILL_ROLE_BINDING_ENABLED_SETTING, SKILL_ROLE_BINDING_KEY, normalize_skill_role_binding, ordered_binding_roles, ) -from oclaw.runtime.skills import ( +from runtime.skills import ( default_skills_root, discover_workspace_skill_manifests, load_skill_manifest, ) -from oclaw.runtime.skills_workspace_lane import skills_home_containing_workspace_lane +from runtime.skills_workspace_lane import skills_home_containing_workspace_lane _DISABLED_SKILLS_KEY = "AIA_SKILL_DISABLED_NAMES" _AUTO_INSTALL_KEY = "AIA_SKILL_AUTO_INSTALL_ENABLED" @@ -459,7 +459,7 @@ def _resolve_registry_archive_url(url: str) -> str: # Resolve via clawhub client first (matches test + avoids adapter drift). try: if len(segs) >= 2: - from oclaw.runtime.tools.skills.clawhub_client import get_skill_detail + from runtime.tools.skills.clawhub_client import get_skill_detail slug = str(segs[-1] or "").strip() if slug: diff --git a/runtime/skill_role_binding.py b/runtime/skill_role_binding.py index 1ef3785b..be93e054 100644 --- a/runtime/skill_role_binding.py +++ b/runtime/skill_role_binding.py @@ -4,7 +4,7 @@ import json import os from typing import Any -from oclaw.runtime.agents.specialists import discover_specialist_ids +from runtime.agents.specialists import discover_specialist_ids SKILL_ROLE_BINDING_KEY = "skill_role_binding" SKILL_ROLE_BINDING_ENABLED_SETTING = "AIA_SKILL_ROLE_BINDING_ENABLED" @@ -100,7 +100,7 @@ def allowed_workspace_skill_names_for_role(*, store: Any, role: str) -> set[str] r = str(role or "").strip().lower() if not r: return set() - from oclaw.runtime.skills import discover_public_workspace_skill_names + from runtime.skills import discover_public_workspace_skill_names public = discover_public_workspace_skill_names() mapping = normalize_skill_role_binding( @@ -122,7 +122,7 @@ def allowed_workspace_skill_names_for_role(*, store: Any, role: str) -> set[str] def _all_installed_skill_names(store: Any) -> set[str]: - from oclaw.runtime.skills import discover_workspace_skill_manifests + from runtime.skills import discover_workspace_skill_manifests return {str(m.name).strip() for m in discover_workspace_skill_manifests() if str(m.name or "").strip()} diff --git a/runtime/skills.py b/runtime/skills.py index cef2322f..f761ed04 100644 --- a/runtime/skills.py +++ b/runtime/skills.py @@ -8,17 +8,17 @@ from dataclasses import dataclass, field from pathlib import Path from typing import TYPE_CHECKING, Any -from oclaw.platform.config.paths import PROJECT_ROOT -from oclaw.platform.config.runtime_paths import runtime_skills_root -from oclaw.runtime.prompt_templates.frontmatter import parse_frontmatter_dict, split_markdown_frontmatter -from oclaw.runtime.skill_manifest_core import ( +from svc.config.paths import PROJECT_ROOT +from svc.config.runtime_paths import runtime_skills_root +from runtime.prompt_templates.frontmatter import parse_frontmatter_dict, split_markdown_frontmatter +from runtime.skill_manifest_core import ( SkillInstallSpec, normalize_frontmatter, parse_skill_frontmatter, ) if TYPE_CHECKING: - from oclaw.runtime.tools.base import ToolRegistry, ToolSpec + from runtime.tools.base import ToolRegistry, ToolSpec @dataclass(frozen=True) @@ -221,7 +221,7 @@ def _allowed_tool_names_after_wire_policy( ) -> tuple[set[str], list[str]]: raw = registry.as_openai_tools() try: - from oclaw.platform.llm.tool_wire_policy import prepare_openai_tools_for_llm_api + from svc.llm.tool_wire_policy import prepare_openai_tools_for_llm_api prepared = prepare_openai_tools_for_llm_api( raw, diff --git a/runtime/skills_market.py b/runtime/skills_market.py index 1c10b58a..00b95dd4 100644 --- a/runtime/skills_market.py +++ b/runtime/skills_market.py @@ -3,9 +3,9 @@ from __future__ import annotations from dataclasses import dataclass from typing import Any, Protocol -from oclaw.runtime.tools.skills.clawhub_client import get_skill_detail, search_skills -from oclaw.runtime.tools.skills.cocoloop_client import get_skill_detail_by_slug as cocoloop_get_skill_detail -from oclaw.runtime.tools.skills.cocoloop_client import search_store_skills as cocoloop_search_skills +from runtime.tools.skills.clawhub_client import get_skill_detail, search_skills +from runtime.tools.skills.cocoloop_client import get_skill_detail_by_slug as cocoloop_get_skill_detail +from runtime.tools.skills.cocoloop_client import search_store_skills as cocoloop_search_skills def normalize_skill_market_provider_setting(raw: str | None) -> str: diff --git a/runtime/skills_prompt.py b/runtime/skills_prompt.py index 5b714af0..17c7ff2b 100644 --- a/runtime/skills_prompt.py +++ b/runtime/skills_prompt.py @@ -4,13 +4,13 @@ import json import os from typing import Any -from oclaw.runtime.skill_role_binding import ( +from runtime.skill_role_binding import ( allowed_workspace_skill_names_for_role, should_apply_workspace_role_filter, ) -from oclaw.runtime.skills import discover_workspace_skill_manifests -from oclaw.runtime.skills_workspace_lane import skill_dir_private_lane_segment -from oclaw.runtime.tools.base import ToolRegistry +from runtime.skills import discover_workspace_skill_manifests +from runtime.skills_workspace_lane import skill_dir_private_lane_segment +from runtime.tools.base import ToolRegistry def _skill_runtime_enabled(store: Any) -> bool: diff --git a/runtime/skills_workspace_lane.py b/runtime/skills_workspace_lane.py index ba1e0ff2..89fcdb15 100644 --- a/runtime/skills_workspace_lane.py +++ b/runtime/skills_workspace_lane.py @@ -25,7 +25,7 @@ def skill_dir_private_lane_segment(skill_dir: str | Path, *, skills_home: Path | Flat ``_workspace//`` (single segment) → ``None``. """ - from oclaw.runtime.skills import default_skills_root + from runtime.skills import default_skills_root home = Path(skills_home).resolve() if skills_home else default_skills_root().resolve() ws = (home / "_workspace").resolve() @@ -59,7 +59,7 @@ def resolve_auto_install_parent( - role installs: ``_workspace//`` (same level as ``public``, e.g. ``generalist``, ``ops``) - legacy session bucket: ``_workspace/_agent//`` when no binding role is available """ - from oclaw.runtime.skills import default_skills_root + from runtime.skills import default_skills_root base = Path(skills_home).resolve() if skills_home else default_skills_root().resolve() ws = base / "_workspace" diff --git a/runtime/system_prompt.py b/runtime/system_prompt.py index 3c353981..3e2902bc 100644 --- a/runtime/system_prompt.py +++ b/runtime/system_prompt.py @@ -5,20 +5,20 @@ import threading from pathlib import Path from typing import Any -from oclaw.platform.config.paths import PROJECT_ROOT -from oclaw.runtime.memory_stage import render_memory_context_block -from oclaw.runtime.project_context_prompt import build_project_context_block -from oclaw.runtime.skill_role_binding import SKILL_ROLE_BINDING_KEY -from oclaw.runtime.skills import workspace_skills_layout_signature -from oclaw.runtime.skills_prompt import build_skills_catalog_block -from oclaw.runtime.skills_workspace_lane import ( +from svc.config.paths import PROJECT_ROOT +from runtime.memory_stage import render_memory_context_block +from runtime.project_context_prompt import build_project_context_block +from runtime.skill_role_binding import SKILL_ROLE_BINDING_KEY +from runtime.skills import workspace_skills_layout_signature +from runtime.skills_prompt import build_skills_catalog_block +from runtime.skills_workspace_lane import ( fs_safe_workspace_lane_segment, workspace_lane_segment, ) -from oclaw.runtime.types import OclawMemoryContext -from oclaw.runtime.workspaces.experts import expert_workspace_signature_token -from oclaw.runtime.prompt_templates import render_runtime_prompt -from oclaw.runtime.tools.base import ToolRegistry +from runtime.types import OclawMemoryContext +from runtime.workspaces.experts import expert_workspace_signature_token +from runtime.prompt_templates import render_runtime_prompt +from runtime.tools.base import ToolRegistry _EXECUTOR_STATIC_PROMPT_CACHE_LOCK = threading.Lock() _EXECUTOR_STATIC_PROMPT_CACHE: dict[tuple[Any, ...], str] = {} diff --git a/runtime/tools/__init__.py b/runtime/tools/__init__.py index 3ee1aaeb..3c9babae 100644 --- a/runtime/tools/__init__.py +++ b/runtime/tools/__init__.py @@ -2,7 +2,7 @@ from __future__ import annotations -from oclaw.runtime.tools.catalog import ( +from runtime.tools.catalog import ( TOOL_FACTORIES, default_registry, materialize_tool_specs, diff --git a/runtime/tools/catalog.py b/runtime/tools/catalog.py index feb775c3..a8756a57 100644 --- a/runtime/tools/catalog.py +++ b/runtime/tools/catalog.py @@ -7,14 +7,14 @@ import os from pathlib import Path from typing import Any -from oclaw.interfaces.gateway.python_extensions_loader import build_python_extensions_registry -from oclaw.platform.config.paths import PROJECT_ROOT -from oclaw.runtime.tools.base import ToolRegistry, ToolSpec -from oclaw.runtime.tools.expert_registry import materialize_tools_for_expert -from oclaw.runtime.tools.mcp.adapter import materialize_mcp_tools_for_specialist -from oclaw.runtime.tools.public_registry import materialize_public_tools -from oclaw.runtime.tools.skills_runtime.materialize_skill_tools import materialize_executable_skill_tools -from oclaw.runtime.skills import SkillSpec, materialize_skills_from_tool_specs +from interfaces.gateway.python_extensions_loader import build_python_extensions_registry +from svc.config.paths import PROJECT_ROOT +from runtime.tools.base import ToolRegistry, ToolSpec +from runtime.tools.expert_registry import materialize_tools_for_expert +from runtime.tools.mcp.adapter import materialize_mcp_tools_for_specialist +from runtime.tools.public_registry import materialize_public_tools +from runtime.tools.skills_runtime.materialize_skill_tools import materialize_executable_skill_tools +from runtime.skills import SkillSpec, materialize_skills_from_tool_specs logger = logging.getLogger(__name__) # Tools hidden from model-facing registry to enforce auto-install only policy. diff --git a/runtime/tools/evals/assistant_runner.py b/runtime/tools/evals/assistant_runner.py index 95273e51..d79caaeb 100644 --- a/runtime/tools/evals/assistant_runner.py +++ b/runtime/tools/evals/assistant_runner.py @@ -5,9 +5,9 @@ from dataclasses import dataclass from pathlib import Path from typing import Any -from oclaw.runtime.application.gateway import process_inbound_payload_usecase -from oclaw.platform.config.paths import db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore +from runtime.application.gateway import process_inbound_payload_usecase +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore @dataclass(frozen=True) diff --git a/runtime/tools/evals/runner.py b/runtime/tools/evals/runner.py index 3deeffbb..559fbf1b 100644 --- a/runtime/tools/evals/runner.py +++ b/runtime/tools/evals/runner.py @@ -6,12 +6,12 @@ from pathlib import Path from dataclasses import dataclass from typing import Any -from oclaw.runtime.agents.factory import build_gateway_executor -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.orchestration.evaluation import eval_summary -from oclaw.platform.config.paths import db_path -from oclaw.runtime.gateway import OclawGateway -from oclaw.runtime.types import StandardMessage +from runtime.agents.factory import build_gateway_executor +from svc.persistence.sqlite_store import SqliteStore +from runtime.orchestration.evaluation import eval_summary +from svc.config.paths import db_path +from runtime.gateway import OclawGateway +from runtime.types import StandardMessage @dataclass(frozen=True) diff --git a/runtime/tools/expert_registry.py b/runtime/tools/expert_registry.py index 92bd811a..30ccf13c 100644 --- a/runtime/tools/expert_registry.py +++ b/runtime/tools/expert_registry.py @@ -7,7 +7,7 @@ from collections.abc import Callable from pathlib import Path from typing import Any -from oclaw.runtime.tools.base import ToolSpec +from runtime.tools.base import ToolSpec logger = logging.getLogger(__name__) @@ -52,7 +52,7 @@ def discover_expert_tool_factories() -> dict[str, list[ToolFactory]]: for module_path in sorted(expert_dir.glob("*.py")): if module_path.name == "__init__.py": continue - mod_name = f"oclaw.runtime.tools.experts.{expert}.{module_path.stem}" + mod_name = f"runtime.tools.experts.{expert}.{module_path.stem}" module = _load_module_from_path(module_path, mod_name) if module is None: continue @@ -145,7 +145,7 @@ def preview_expert_tools(expert: str | None) -> dict[str, Any]: for module_path in sorted(expert_dir.glob("*.py")): if module_path.name == "__init__.py": continue - mod_name = f"oclaw.runtime.tools.experts.{ex}.{module_path.stem}" + mod_name = f"runtime.tools.experts.{ex}.{module_path.stem}" module = None try: module = _load_module_from_path(module_path, mod_name) diff --git a/runtime/tools/experts/generalist/generalist_tools.py b/runtime/tools/experts/generalist/generalist_tools.py index ff28d30d..6f29200b 100644 --- a/runtime/tools/experts/generalist/generalist_tools.py +++ b/runtime/tools/experts/generalist/generalist_tools.py @@ -1,6 +1,6 @@ """通识专家工具清单。""" -from oclaw.runtime.tools.base import ToolSpec +from runtime.tools.base import ToolSpec def system_info_tool() -> ToolSpec: diff --git a/runtime/tools/experts/generalist/system_info.py b/runtime/tools/experts/generalist/system_info.py index 0e60ba8a..1c896902 100644 --- a/runtime/tools/experts/generalist/system_info.py +++ b/runtime/tools/experts/generalist/system_info.py @@ -4,7 +4,7 @@ import datetime import time from typing import Any -from oclaw.runtime.tools.base import ToolSpec +from runtime.tools.base import ToolSpec def system_info_tool() -> ToolSpec: diff --git a/runtime/tools/experts/network_ops/netx_tools.py b/runtime/tools/experts/network_ops/netx_tools.py index 960791ab..225816f8 100644 --- a/runtime/tools/experts/network_ops/netx_tools.py +++ b/runtime/tools/experts/network_ops/netx_tools.py @@ -14,7 +14,7 @@ from typing import Any import httpx -from oclaw.runtime.tools.base import ToolSpec +from runtime.tools.base import ToolSpec _UME_RAW_GROUP_FIELDS = [ "alarm_alarm_key", diff --git a/runtime/tools/experts/productivity/kb_tools.py b/runtime/tools/experts/productivity/kb_tools.py index f1935e5f..915f233e 100644 --- a/runtime/tools/experts/productivity/kb_tools.py +++ b/runtime/tools/experts/productivity/kb_tools.py @@ -3,10 +3,10 @@ from __future__ import annotations import hashlib from typing import Any -from oclaw.platform.config.paths import db_path -from oclaw.platform.embeddings.embedding_client import build_default_embedding_client -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.tools.base import ToolSpec +from svc.config.paths import db_path +from svc.embeddings.embedding_client import build_default_embedding_client +from svc.persistence.sqlite_store import SqliteStore +from runtime.tools.base import ToolSpec def _chunk_id(source: str, text: str) -> str: @@ -64,7 +64,7 @@ def kb_search_tool() -> ToolSpec: if not tenant_id or not query: return {"ok": False, "error": "tenant_id and query are required"} store = SqliteStore(db_path()) - from oclaw.runtime.orchestration.memory import retrieve_context + from runtime.orchestration.memory import retrieve_context rows = retrieve_context(store, query, limit=max(1, min(limit, 6))) filtered = [r for r in rows if str(r.get("source") or "").startswith(f"builtin:tenant:{tenant_id}:")] diff --git a/runtime/tools/experts/productivity/todo_tools.py b/runtime/tools/experts/productivity/todo_tools.py index c37901a8..5e4677e0 100644 --- a/runtime/tools/experts/productivity/todo_tools.py +++ b/runtime/tools/experts/productivity/todo_tools.py @@ -2,9 +2,9 @@ from __future__ import annotations from typing import Any -from oclaw.platform.config.paths import db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.tools.base import ToolSpec +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore +from runtime.tools.base import ToolSpec def _require(s: str, name: str) -> str: diff --git a/runtime/tools/exposure_plan.py b/runtime/tools/exposure_plan.py index 4c4ad880..5d7ef7fa 100644 --- a/runtime/tools/exposure_plan.py +++ b/runtime/tools/exposure_plan.py @@ -4,20 +4,20 @@ import os from dataclasses import dataclass from typing import Any -from oclaw.platform.llm.tool_schema import default_max_openai_tools_json_bytes -from oclaw.platform.llm.tool_wire_policy import ( +from svc.llm.tool_schema import default_max_openai_tools_json_bytes +from svc.llm.tool_wire_policy import ( load_merged_admin_config, load_role_mode_for_role, load_tool_policies_dict_for_role, prepare_openai_tools_for_llm_api, wire_graduation_effective, ) -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.catalog import _is_truthy -from oclaw.runtime.tools.expert_registry import materialize_tools_for_expert, preview_expert_tools -from oclaw.runtime.tools.mcp.adapter import materialize_mcp_tools_for_specialist -from oclaw.runtime.tools.plugin_loader import materialize_plugin_tools -from oclaw.runtime.tools.public_registry import materialize_public_tools, preview_public_tools +from runtime.tools.base import ToolSpec +from runtime.tools.catalog import _is_truthy +from runtime.tools.expert_registry import materialize_tools_for_expert, preview_expert_tools +from runtime.tools.mcp.adapter import materialize_mcp_tools_for_specialist +from runtime.tools.plugin_loader import materialize_plugin_tools +from runtime.tools.public_registry import materialize_public_tools, preview_public_tools @dataclass(frozen=True) diff --git a/runtime/tools/mcp/adapter.py b/runtime/tools/mcp/adapter.py index 0b66377e..9e2d353f 100644 --- a/runtime/tools/mcp/adapter.py +++ b/runtime/tools/mcp/adapter.py @@ -5,12 +5,12 @@ import json import os from typing import Any -from oclaw.runtime.operations.mcp_env import mcp_env_allowlist_keys -from oclaw.runtime.skills import SkillSpec, materialize_skills_from_tool_specs -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.mcp.filesystem_argv import build_mcp_process_command -from oclaw.runtime.tools.mcp.runtime import McpProcessRuntime -from oclaw.runtime.tools.public.bailian_webparser_tool import bailian_webparser_tool +from runtime.operations.mcp_env import mcp_env_allowlist_keys +from runtime.skills import SkillSpec, materialize_skills_from_tool_specs +from runtime.tools.base import ToolSpec +from runtime.tools.mcp.filesystem_argv import build_mcp_process_command +from runtime.tools.mcp.runtime import McpProcessRuntime +from runtime.tools.public.bailian_webparser_tool import bailian_webparser_tool @dataclass diff --git a/runtime/tools/mcp/registry.py b/runtime/tools/mcp/registry.py index 0dea490c..41f7e22a 100644 --- a/runtime/tools/mcp/registry.py +++ b/runtime/tools/mcp/registry.py @@ -3,8 +3,8 @@ from __future__ import annotations from dataclasses import asdict from typing import Any -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.tools.mcp.manifest import McpServerManifest +from svc.persistence.sqlite_store import SqliteStore +from runtime.tools.mcp.manifest import McpServerManifest class McpRegistry: diff --git a/runtime/tools/mcp/runtime.py b/runtime/tools/mcp/runtime.py index 4a448ba3..0b5a97d3 100644 --- a/runtime/tools/mcp/runtime.py +++ b/runtime/tools/mcp/runtime.py @@ -25,7 +25,7 @@ class McpProcessRuntime: def _build_runtime_env(env_allowlist: list[str] | None) -> dict[str, str] | None: if env_allowlist is None: return None - from oclaw.runtime.operations.mcp_env import mcp_local_env_merged + from runtime.operations.mcp_env import mcp_local_env_merged keep_keys = {"PATH", "PATHEXT", "SYSTEMROOT", "WINDIR", "COMSPEC", "TEMP", "TMP", "HOME", "USERPROFILE", "APPDATA", "LOCALAPPDATA", "PROGRAMDATA", "PROGRAMFILES", "PROGRAMFILES(X86)", "SYSTEMDRIVE"} env: dict[str, str] = {} diff --git a/runtime/tools/path_guard.py b/runtime/tools/path_guard.py index 268af312..de924df7 100644 --- a/runtime/tools/path_guard.py +++ b/runtime/tools/path_guard.py @@ -8,7 +8,7 @@ from dataclasses import dataclass from pathlib import Path from typing import Any, Iterator -from oclaw.platform.config.paths import PROJECT_ROOT +from svc.config.paths import PROJECT_ROOT _TLS = threading.local() diff --git a/runtime/tools/plugin_loader.py b/runtime/tools/plugin_loader.py index 8767dac1..5c7e19e9 100644 --- a/runtime/tools/plugin_loader.py +++ b/runtime/tools/plugin_loader.py @@ -4,7 +4,7 @@ import logging from dataclasses import dataclass from typing import Any, Callable -from oclaw.runtime.tools.base import ToolSpec +from runtime.tools.base import ToolSpec logger = logging.getLogger(__name__) diff --git a/runtime/tools/public/apply_patch_tool.py b/runtime/tools/public/apply_patch_tool.py index 654c97bf..db2bc00f 100644 --- a/runtime/tools/public/apply_patch_tool.py +++ b/runtime/tools/public/apply_patch_tool.py @@ -3,8 +3,8 @@ from __future__ import annotations import hashlib from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.path_guard import resolve_workspace_path +from runtime.tools.base import ToolSpec +from runtime.tools.path_guard import resolve_workspace_path def apply_patch_tool() -> ToolSpec: diff --git a/runtime/tools/public/attachment_local_url_tool.py b/runtime/tools/public/attachment_local_url_tool.py index 17c82a62..e206474d 100644 --- a/runtime/tools/public/attachment_local_url_tool.py +++ b/runtime/tools/public/attachment_local_url_tool.py @@ -4,8 +4,8 @@ import re from typing import Any from pathlib import Path -from oclaw.platform.files.attachment_assets import AttachmentAssetStore -from oclaw.runtime.tools.base import ToolSpec +from svc.files.attachment_assets import AttachmentAssetStore +from runtime.tools.base import ToolSpec _ATTACHMENT_ID_RE = re.compile(r"^[a-f0-9]{64}$") diff --git a/runtime/tools/public/bailian_webparser_tool.py b/runtime/tools/public/bailian_webparser_tool.py index 85848c42..167ce939 100644 --- a/runtime/tools/public/bailian_webparser_tool.py +++ b/runtime/tools/public/bailian_webparser_tool.py @@ -7,7 +7,7 @@ import urllib.parse import urllib.request from typing import Any -from oclaw.runtime.tools.base import ToolSpec +from runtime.tools.base import ToolSpec _WEBPARSER_SSE_URL = "https://dashscope.aliyuncs.com/api/v1/mcps/WebParser/sse" _UA = ( diff --git a/runtime/tools/public/bulk_apply_patch_tool.py b/runtime/tools/public/bulk_apply_patch_tool.py index fe79dcce..a14683f1 100644 --- a/runtime/tools/public/bulk_apply_patch_tool.py +++ b/runtime/tools/public/bulk_apply_patch_tool.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.path_guard import resolve_workspace_path +from runtime.tools.base import ToolSpec +from runtime.tools.path_guard import resolve_workspace_path def bulk_apply_patch_tool() -> ToolSpec: diff --git a/runtime/tools/public/cloudflare_image_generate_tool.py b/runtime/tools/public/cloudflare_image_generate_tool.py index 0b27e3ab..95d583e2 100644 --- a/runtime/tools/public/cloudflare_image_generate_tool.py +++ b/runtime/tools/public/cloudflare_image_generate_tool.py @@ -10,9 +10,9 @@ from urllib import request as urllib_request from PIL import Image -from oclaw.platform.files.attachment_assets import AttachmentAssetStore -from oclaw.runtime.operations.mcp_env import apply_gateway_mcp_env_to_os -from oclaw.runtime.tools.base import ToolSpec +from svc.files.attachment_assets import AttachmentAssetStore +from runtime.operations.mcp_env import apply_gateway_mcp_env_to_os +from runtime.tools.base import ToolSpec def _to_image_bytes(resp_body: bytes, content_type: str) -> tuple[bytes, str]: diff --git a/runtime/tools/public/delete_file_tool.py b/runtime/tools/public/delete_file_tool.py index a48c61e1..e0f2dd55 100644 --- a/runtime/tools/public/delete_file_tool.py +++ b/runtime/tools/public/delete_file_tool.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.public.local_sdk import get_local_adapter +from runtime.tools.base import ToolSpec +from runtime.tools.public.local_sdk import get_local_adapter def delete_file_tool() -> ToolSpec: diff --git a/runtime/tools/public/edit_file_tool.py b/runtime/tools/public/edit_file_tool.py index 9d5872f0..cd6b0ed4 100644 --- a/runtime/tools/public/edit_file_tool.py +++ b/runtime/tools/public/edit_file_tool.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.public.local_sdk import get_local_adapter +from runtime.tools.base import ToolSpec +from runtime.tools.public.local_sdk import get_local_adapter def edit_file_tool() -> ToolSpec: diff --git a/runtime/tools/public/get_cwd_tool.py b/runtime/tools/public/get_cwd_tool.py index dbdbae5a..816b46f9 100644 --- a/runtime/tools/public/get_cwd_tool.py +++ b/runtime/tools/public/get_cwd_tool.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.public.local_sdk import get_local_adapter +from runtime.tools.base import ToolSpec +from runtime.tools.public.local_sdk import get_local_adapter def get_cwd_tool() -> ToolSpec: diff --git a/runtime/tools/public/get_env_tool.py b/runtime/tools/public/get_env_tool.py index 0c3b51b3..d7a3cf32 100644 --- a/runtime/tools/public/get_env_tool.py +++ b/runtime/tools/public/get_env_tool.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.public.local_sdk import get_local_adapter +from runtime.tools.base import ToolSpec +from runtime.tools.public.local_sdk import get_local_adapter def get_env_tool() -> ToolSpec: diff --git a/runtime/tools/public/git_tools.py b/runtime/tools/public/git_tools.py index ebb8f7d1..34601d8b 100644 --- a/runtime/tools/public/git_tools.py +++ b/runtime/tools/public/git_tools.py @@ -3,8 +3,8 @@ from __future__ import annotations import subprocess from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.path_guard import resolve_workspace_path, sanitize_git_ref, truncate_text +from runtime.tools.base import ToolSpec +from runtime.tools.path_guard import resolve_workspace_path, sanitize_git_ref, truncate_text def _git(command: str, *, cwd: str) -> dict[str, Any]: diff --git a/runtime/tools/public/glob_tool.py b/runtime/tools/public/glob_tool.py index 10556954..9f774611 100644 --- a/runtime/tools/public/glob_tool.py +++ b/runtime/tools/public/glob_tool.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.path_guard import resolve_workspace_path +from runtime.tools.base import ToolSpec +from runtime.tools.path_guard import resolve_workspace_path def glob_tool() -> ToolSpec: diff --git a/runtime/tools/public/image_edit_tool.py b/runtime/tools/public/image_edit_tool.py index ac42f379..d380e5a1 100644 --- a/runtime/tools/public/image_edit_tool.py +++ b/runtime/tools/public/image_edit_tool.py @@ -7,8 +7,8 @@ from typing import Any from PIL import Image -from oclaw.platform.files.attachment_assets import AttachmentAssetStore -from oclaw.runtime.tools.base import ToolSpec +from svc.files.attachment_assets import AttachmentAssetStore +from runtime.tools.base import ToolSpec def image_edit_tool() -> ToolSpec: diff --git a/runtime/tools/public/index_workspace_tool.py b/runtime/tools/public/index_workspace_tool.py index 3cc826ad..175c759f 100644 --- a/runtime/tools/public/index_workspace_tool.py +++ b/runtime/tools/public/index_workspace_tool.py @@ -2,16 +2,16 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools.base import ToolSpec +from runtime.tools.base import ToolSpec def index_workspace_tool() -> ToolSpec: def handler(args: dict[str, Any]) -> dict[str, Any]: max_files = int(args.get("max_files") or 120) try: - from oclaw.platform.persistence.sqlite_store import SqliteStore - from oclaw.platform.config.paths import db_path - from oclaw.runtime.tools.workspace_indexer import index_workspace + from svc.persistence.sqlite_store import SqliteStore + from svc.config.paths import db_path + from runtime.tools.workspace_indexer import index_workspace store = SqliteStore(db_path()) st = index_workspace(store, max_files=max(1, min(max_files, 800))) diff --git a/runtime/tools/public/kill_process_tool.py b/runtime/tools/public/kill_process_tool.py index 46a36beb..7f8ea479 100644 --- a/runtime/tools/public/kill_process_tool.py +++ b/runtime/tools/public/kill_process_tool.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.public.local_sdk import get_local_adapter +from runtime.tools.base import ToolSpec +from runtime.tools.public.local_sdk import get_local_adapter def kill_process_tool() -> ToolSpec: diff --git a/runtime/tools/public/list_directory_tool.py b/runtime/tools/public/list_directory_tool.py index 6e90b182..815305c4 100644 --- a/runtime/tools/public/list_directory_tool.py +++ b/runtime/tools/public/list_directory_tool.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.public.local_sdk import get_local_adapter +from runtime.tools.base import ToolSpec +from runtime.tools.public.local_sdk import get_local_adapter def list_directory_tool() -> ToolSpec: diff --git a/runtime/tools/public/list_processes_tool.py b/runtime/tools/public/list_processes_tool.py index 460b5d9d..e35f4ff6 100644 --- a/runtime/tools/public/list_processes_tool.py +++ b/runtime/tools/public/list_processes_tool.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.public.local_sdk import get_local_adapter +from runtime.tools.base import ToolSpec +from runtime.tools.public.local_sdk import get_local_adapter def list_processes_tool() -> ToolSpec: diff --git a/runtime/tools/public/list_workspace_tree_tool.py b/runtime/tools/public/list_workspace_tree_tool.py index 3341b26e..c717b9a3 100644 --- a/runtime/tools/public/list_workspace_tree_tool.py +++ b/runtime/tools/public/list_workspace_tree_tool.py @@ -3,8 +3,8 @@ from __future__ import annotations from pathlib import Path from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.path_guard import resolve_workspace_path +from runtime.tools.base import ToolSpec +from runtime.tools.path_guard import resolve_workspace_path def list_workspace_tree_tool() -> ToolSpec: diff --git a/runtime/tools/public/local_sdk.py b/runtime/tools/public/local_sdk.py index d18ba6dd..15bf4de9 100644 --- a/runtime/tools/public/local_sdk.py +++ b/runtime/tools/public/local_sdk.py @@ -9,7 +9,7 @@ from datetime import datetime, timezone from pathlib import Path from typing import Any -from oclaw.runtime.tools.path_guard import resolve_workspace_path, truncate_text +from runtime.tools.path_guard import resolve_workspace_path, truncate_text @dataclass(frozen=True) @@ -80,14 +80,14 @@ class LocalAdapter: dbp = str(os.getenv("OPS_ASSISTANT_DB_PATH") or "").strip() try: if not dbp: - from oclaw.platform.config.paths import db_path + from svc.config.paths import db_path dbp = str(db_path() or "").strip() except Exception: dbp = "" if dbp: try: - from oclaw.platform.persistence.sqlite_store import SqliteStore + from svc.persistence.sqlite_store import SqliteStore store = SqliteStore(dbp) raw_db = str(store.get_setting("AIA_ENABLE_RUN_COMMAND") or "").strip() diff --git a/runtime/tools/public/memory_wiki_tools.py b/runtime/tools/public/memory_wiki_tools.py index e77510ee..84767b08 100644 --- a/runtime/tools/public/memory_wiki_tools.py +++ b/runtime/tools/public/memory_wiki_tools.py @@ -5,8 +5,8 @@ import sys from types import SimpleNamespace from typing import Any, Callable -from oclaw.platform.config.paths import PROJECT_ROOT -from oclaw.runtime.tools.base import ToolSpec +from svc.config.paths import PROJECT_ROOT +from runtime.tools.base import ToolSpec def _plugin_cfg() -> dict[str, Any]: diff --git a/runtime/tools/public/mkdir_tool.py b/runtime/tools/public/mkdir_tool.py index 261060a2..ca0bdf0e 100644 --- a/runtime/tools/public/mkdir_tool.py +++ b/runtime/tools/public/mkdir_tool.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.public.local_sdk import get_local_adapter +from runtime.tools.base import ToolSpec +from runtime.tools.public.local_sdk import get_local_adapter def mkdir_tool() -> ToolSpec: diff --git a/runtime/tools/public/move_file_tool.py b/runtime/tools/public/move_file_tool.py index d686412d..772d5974 100644 --- a/runtime/tools/public/move_file_tool.py +++ b/runtime/tools/public/move_file_tool.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.public.local_sdk import get_local_adapter +from runtime.tools.base import ToolSpec +from runtime.tools.public.local_sdk import get_local_adapter def move_file_tool() -> ToolSpec: diff --git a/runtime/tools/public/multi_edit_file_tool.py b/runtime/tools/public/multi_edit_file_tool.py index f0c22837..3f0b2a00 100644 --- a/runtime/tools/public/multi_edit_file_tool.py +++ b/runtime/tools/public/multi_edit_file_tool.py @@ -3,8 +3,8 @@ from __future__ import annotations from pathlib import Path from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.path_guard import resolve_workspace_path +from runtime.tools.base import ToolSpec +from runtime.tools.path_guard import resolve_workspace_path def multi_edit_file_tool() -> ToolSpec: diff --git a/runtime/tools/public/query_image_attachment_tool.py b/runtime/tools/public/query_image_attachment_tool.py index ff8aedc5..da54ddeb 100644 --- a/runtime/tools/public/query_image_attachment_tool.py +++ b/runtime/tools/public/query_image_attachment_tool.py @@ -2,14 +2,14 @@ from __future__ import annotations from typing import Any -from oclaw.platform.files.attachment_assets import attachment_id_to_data_url -from oclaw.platform.llm.image_ocr_client import ( +from svc.files.attachment_assets import attachment_id_to_data_url +from svc.llm.image_ocr_client import ( VISION_DESCRIBE_PROMPT_ZH, VISION_OCR_EXTRACT_PROMPT_ZH, send_ocr_image_messages, vision_llm_backend_status, ) -from oclaw.runtime.tools.base import ToolSpec +from runtime.tools.base import ToolSpec def query_image_attachment_tool() -> ToolSpec: diff --git a/runtime/tools/public/query_text_attachment_tool.py b/runtime/tools/public/query_text_attachment_tool.py index d7bedd01..8f7d90bd 100644 --- a/runtime/tools/public/query_text_attachment_tool.py +++ b/runtime/tools/public/query_text_attachment_tool.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.platform.files.text_attachment_store import query_text_document -from oclaw.runtime.tools.base import ToolSpec +from svc.files.text_attachment_store import query_text_document +from runtime.tools.base import ToolSpec def query_text_attachment_tool() -> ToolSpec: diff --git a/runtime/tools/public/query_video_attachment_tool.py b/runtime/tools/public/query_video_attachment_tool.py index 07fb0b6e..bfabcf35 100644 --- a/runtime/tools/public/query_video_attachment_tool.py +++ b/runtime/tools/public/query_video_attachment_tool.py @@ -8,14 +8,14 @@ import tempfile from pathlib import Path from typing import Any -from oclaw.platform.files.attachment_assets import AttachmentAssetStore -from oclaw.platform.files.text_attachment_store import ( +from svc.files.attachment_assets import AttachmentAssetStore +from svc.files.text_attachment_store import ( DEFAULT_TEXT_CHUNK_OVERLAP, DEFAULT_TEXT_CHUNK_SIZE, save_text_document, ) -from oclaw.runtime.extensions.openai.api import OPENAI_DEFAULT_AUDIO_TRANSCRIPTION_MODEL -from oclaw.runtime.tools.base import ToolSpec +from runtime.extensions.openai.api import OPENAI_DEFAULT_AUDIO_TRANSCRIPTION_MODEL +from runtime.tools.base import ToolSpec def _ffmpeg_exists() -> bool: diff --git a/runtime/tools/public/read_file_tool.py b/runtime/tools/public/read_file_tool.py index a49bbfaa..2cbd0660 100644 --- a/runtime/tools/public/read_file_tool.py +++ b/runtime/tools/public/read_file_tool.py @@ -3,8 +3,8 @@ from __future__ import annotations import hashlib from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.path_guard import resolve_workspace_path +from runtime.tools.base import ToolSpec +from runtime.tools.path_guard import resolve_workspace_path def read_file_tool() -> ToolSpec: diff --git a/runtime/tools/public/run_command_tool.py b/runtime/tools/public/run_command_tool.py index f4111f8e..34be32a2 100644 --- a/runtime/tools/public/run_command_tool.py +++ b/runtime/tools/public/run_command_tool.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.public.local_sdk import get_local_adapter +from runtime.tools.base import ToolSpec +from runtime.tools.public.local_sdk import get_local_adapter def run_command_tool() -> ToolSpec: diff --git a/runtime/tools/public/search_files_context_tool.py b/runtime/tools/public/search_files_context_tool.py index a0af4903..b37b04e7 100644 --- a/runtime/tools/public/search_files_context_tool.py +++ b/runtime/tools/public/search_files_context_tool.py @@ -4,8 +4,8 @@ import re from pathlib import Path from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.path_guard import resolve_workspace_path, truncate_text +from runtime.tools.base import ToolSpec +from runtime.tools.path_guard import resolve_workspace_path, truncate_text def search_files_context_tool() -> ToolSpec: diff --git a/runtime/tools/public/search_files_tool.py b/runtime/tools/public/search_files_tool.py index c6662f4b..37baabf1 100644 --- a/runtime/tools/public/search_files_tool.py +++ b/runtime/tools/public/search_files_tool.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.public.local_sdk import get_local_adapter +from runtime.tools.base import ToolSpec +from runtime.tools.public.local_sdk import get_local_adapter def search_files_tool() -> ToolSpec: diff --git a/runtime/tools/public/set_env_tool.py b/runtime/tools/public/set_env_tool.py index 35a1bf8d..5663ade8 100644 --- a/runtime/tools/public/set_env_tool.py +++ b/runtime/tools/public/set_env_tool.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.public.local_sdk import get_local_adapter +from runtime.tools.base import ToolSpec +from runtime.tools.public.local_sdk import get_local_adapter def set_env_tool() -> ToolSpec: diff --git a/runtime/tools/public/skill_auto_install_tool.py b/runtime/tools/public/skill_auto_install_tool.py index b8d5e7dd..72f5957c 100644 --- a/runtime/tools/public/skill_auto_install_tool.py +++ b/runtime/tools/public/skill_auto_install_tool.py @@ -3,16 +3,16 @@ from __future__ import annotations from pathlib import Path from typing import Any -from oclaw.platform.config.paths import db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.chat.tool_invocation_context import ( +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore +from runtime.chat.tool_invocation_context import ( current_tool_lane_sessions, current_tool_workspace_lane_role, ) -from oclaw.runtime.skill_installer import auto_install_skill_from_payload, install_skill_from_registry_archive -from oclaw.runtime.skills_market import get_market_adapter, normalize_skill_market_provider_setting -from oclaw.runtime.skills_workspace_lane import resolve_auto_install_parent -from oclaw.runtime.tools.base import ToolSpec +from runtime.skill_installer import auto_install_skill_from_payload, install_skill_from_registry_archive +from runtime.skills_market import get_market_adapter, normalize_skill_market_provider_setting +from runtime.skills_workspace_lane import resolve_auto_install_parent +from runtime.tools.base import ToolSpec def _store() -> SqliteStore: diff --git a/runtime/tools/public/skills_install_tool.py b/runtime/tools/public/skills_install_tool.py index 05aff54b..a2cb699f 100644 --- a/runtime/tools/public/skills_install_tool.py +++ b/runtime/tools/public/skills_install_tool.py @@ -3,12 +3,12 @@ from __future__ import annotations from pathlib import Path from typing import Any -from oclaw.platform.config.paths import db_path -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.skill_installer import install_skill_from_registry_archive -from oclaw.runtime.skills import default_skills_root -from oclaw.runtime.skills_market import get_market_adapter, normalize_skill_market_provider_setting -from oclaw.runtime.tools.base import ToolSpec +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore +from runtime.skill_installer import install_skill_from_registry_archive +from runtime.skills import default_skills_root +from runtime.skills_market import get_market_adapter, normalize_skill_market_provider_setting +from runtime.tools.base import ToolSpec def _store() -> SqliteStore: diff --git a/runtime/tools/public/system_time_tool.py b/runtime/tools/public/system_time_tool.py index ca4f2274..bc7fa8fb 100644 --- a/runtime/tools/public/system_time_tool.py +++ b/runtime/tools/public/system_time_tool.py @@ -3,7 +3,7 @@ from __future__ import annotations from datetime import datetime, timezone from typing import Any -from oclaw.runtime.tools.base import ToolSpec +from runtime.tools.base import ToolSpec def system_time_tool() -> ToolSpec: diff --git a/runtime/tools/public/tabular_attachment_tools.py b/runtime/tools/public/tabular_attachment_tools.py index d3cc045a..308f71e0 100644 --- a/runtime/tools/public/tabular_attachment_tools.py +++ b/runtime/tools/public/tabular_attachment_tools.py @@ -2,13 +2,13 @@ from __future__ import annotations from typing import Any -from oclaw.platform.files.tabular_attachment_store import ( +from svc.files.tabular_attachment_store import ( aggregate_table, analyze_table_full_scan, query_table, run_table_sql, ) -from oclaw.runtime.tools.base import ToolSpec +from runtime.tools.base import ToolSpec def query_tabular_attachment_tool() -> ToolSpec: diff --git a/runtime/tools/public/web_fetch_clean_tool.py b/runtime/tools/public/web_fetch_clean_tool.py index b3d71cc8..fc6f567b 100644 --- a/runtime/tools/public/web_fetch_clean_tool.py +++ b/runtime/tools/public/web_fetch_clean_tool.py @@ -6,7 +6,7 @@ import urllib.request from html import unescape from typing import Any -from oclaw.runtime.tools.base import ToolSpec +from runtime.tools.base import ToolSpec _UA = ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " diff --git a/runtime/tools/public/web_search_fast_tool.py b/runtime/tools/public/web_search_fast_tool.py index f5b7bf95..b40f2710 100644 --- a/runtime/tools/public/web_search_fast_tool.py +++ b/runtime/tools/public/web_search_fast_tool.py @@ -10,7 +10,7 @@ import urllib.request from html import unescape from typing import Any -from oclaw.runtime.tools.base import ToolSpec +from runtime.tools.base import ToolSpec _UA = ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " diff --git a/runtime/tools/public/write_file_tool.py b/runtime/tools/public/write_file_tool.py index b4f08feb..70f7e9f9 100644 --- a/runtime/tools/public/write_file_tool.py +++ b/runtime/tools/public/write_file_tool.py @@ -3,8 +3,8 @@ from __future__ import annotations from pathlib import Path from typing import Any -from oclaw.runtime.tools.base import ToolSpec -from oclaw.runtime.tools.path_guard import resolve_workspace_path +from runtime.tools.base import ToolSpec +from runtime.tools.path_guard import resolve_workspace_path def write_file_tool() -> ToolSpec: diff --git a/runtime/tools/public_registry.py b/runtime/tools/public_registry.py index ebea2076..655c6b12 100644 --- a/runtime/tools/public_registry.py +++ b/runtime/tools/public_registry.py @@ -7,7 +7,7 @@ from collections.abc import Callable from pathlib import Path from typing import Any -from oclaw.runtime.tools.base import ToolSpec +from runtime.tools.base import ToolSpec logger = logging.getLogger(__name__) @@ -42,7 +42,7 @@ def discover_public_tool_factories() -> list[ToolFactory]: for module_path in sorted(_PUBLIC_ROOT.glob("*.py")): if module_path.name == "__init__.py": continue - mod_name = f"oclaw.runtime.tools.public.{module_path.stem}" + mod_name = f"runtime.tools.public.{module_path.stem}" module = _load_module_from_path(module_path, mod_name) if module is None: continue @@ -92,7 +92,7 @@ def preview_public_tools() -> dict[str, Any]: for module_path in sorted(_PUBLIC_ROOT.glob("*.py")): if module_path.name == "__init__.py": continue - mod_name = f"oclaw.runtime.tools.public.{module_path.stem}" + mod_name = f"runtime.tools.public.{module_path.stem}" module = None try: module = _load_module_from_path(module_path, mod_name) diff --git a/runtime/tools/skills_runtime/materialize_skill_tools.py b/runtime/tools/skills_runtime/materialize_skill_tools.py index d111ccd5..da82ae9d 100644 --- a/runtime/tools/skills_runtime/materialize_skill_tools.py +++ b/runtime/tools/skills_runtime/materialize_skill_tools.py @@ -2,8 +2,8 @@ from __future__ import annotations from typing import Any -from oclaw.runtime.skills import discover_workspace_skill_manifests -from oclaw.runtime.tools.base import ToolSpec +from runtime.skills import discover_workspace_skill_manifests +from runtime.tools.base import ToolSpec def materialize_executable_skill_tools(*, store: Any | None = None) -> list[ToolSpec]: @@ -27,7 +27,7 @@ def materialize_executable_skill_tools(*, store: Any | None = None) -> list[Tool continue def _handler(args: dict[str, Any], *, _manifest=m, _rt=rt) -> dict[str, Any]: - from oclaw.runtime.tools.skills_runtime.subprocess_exec import run_skill_runtime_entry + from runtime.tools.skills_runtime.subprocess_exec import run_skill_runtime_entry source_meta = {} if isinstance(getattr(_manifest, "metadata_oclaw", None), dict): diff --git a/runtime/tools/skills_runtime/subprocess_exec.py b/runtime/tools/skills_runtime/subprocess_exec.py index 8abc345a..ee0e23d1 100644 --- a/runtime/tools/skills_runtime/subprocess_exec.py +++ b/runtime/tools/skills_runtime/subprocess_exec.py @@ -9,7 +9,7 @@ from dataclasses import dataclass from pathlib import Path from typing import Any -from oclaw.platform.config.paths import PROJECT_ROOT +from svc.config.paths import PROJECT_ROOT _PATH_KEYS = { diff --git a/runtime/tools/system_time_tool.py b/runtime/tools/system_time_tool.py index ccd8e0ac..039b6fef 100644 --- a/runtime/tools/system_time_tool.py +++ b/runtime/tools/system_time_tool.py @@ -1,7 +1,7 @@ from __future__ import annotations # Backward-compat import path. -from oclaw.runtime.tools.public.system_time_tool import system_time_tool +from runtime.tools.public.system_time_tool import system_time_tool __all__ = ["system_time_tool"] diff --git a/runtime/tools/workspace_indexer.py b/runtime/tools/workspace_indexer.py index 4f3d5ce6..566b92c7 100644 --- a/runtime/tools/workspace_indexer.py +++ b/runtime/tools/workspace_indexer.py @@ -5,9 +5,9 @@ from dataclasses import dataclass from pathlib import Path from typing import Any -from oclaw.platform.embeddings.embedding_client import build_default_embedding_client -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.platform.config.paths import PROJECT_ROOT +from svc.embeddings.embedding_client import build_default_embedding_client +from svc.persistence.sqlite_store import SqliteStore +from svc.config.paths import PROJECT_ROOT def _default_workspace_root() -> Path: diff --git a/runtime/types.py b/runtime/types.py index 24d791b5..39d30029 100644 --- a/runtime/types.py +++ b/runtime/types.py @@ -45,7 +45,7 @@ def normalize_requested_specialist(raw: Any) -> SpecialistId: # Accept dynamic specialists discovered from workspaces (e.g. "stock"). # Fallback to "generalist" when unknown. try: - from oclaw.runtime.agents.specialists import normalize_specialist_id + from runtime.agents.specialists import normalize_specialist_id return normalize_specialist_id(specialist) except Exception: diff --git a/runtime/worker.py b/runtime/worker.py index 6b163b65..ef759901 100644 --- a/runtime/worker.py +++ b/runtime/worker.py @@ -6,13 +6,13 @@ import time import uuid from typing import Any -from oclaw.runtime.agents.factory import build_gateway_executor -from oclaw.runtime.agent_core_run import AgentCoreRunInput, run_agent_core -from oclaw.runtime.memory_stage import build_memory_context -from oclaw.runtime.relay_pointer import build_acp_relay_result, validate_relay_share_envelope -from oclaw.runtime.types import StandardMessage -from oclaw.runtime.chat.model_path_audit import ensure_no_tool_or_embedded_image_payload -from oclaw.runtime.session_auto_title import ( +from runtime.agents.factory import build_gateway_executor +from runtime.agent_core_run import AgentCoreRunInput, run_agent_core +from runtime.memory_stage import build_memory_context +from runtime.relay_pointer import build_acp_relay_result, validate_relay_share_envelope +from runtime.types import StandardMessage +from runtime.chat.model_path_audit import ensure_no_tool_or_embedded_image_payload +from runtime.session_auto_title import ( AUTO_TITLE_SYSTEM_PROMPT_EN, AUTO_TITLE_SYSTEM_PROMPT_ZH, finalize_auto_title, diff --git a/runtime/workers/wiki/main.py b/runtime/workers/wiki/main.py index 7939c4b7..3c385f50 100644 --- a/runtime/workers/wiki/main.py +++ b/runtime/workers/wiki/main.py @@ -11,8 +11,8 @@ from pathlib import Path from types import SimpleNamespace from typing import Any -from oclaw.platform.config.paths import PROJECT_ROOT, db_path -from oclaw.platform.persistence.sqlite_store import OclawTask, SqliteStore +from svc.config.paths import PROJECT_ROOT, db_path +from svc.persistence.sqlite_store import OclawTask, SqliteStore def _load_oclaw_config() -> dict[str, Any]: diff --git a/runtime/workspaces/experts.py b/runtime/workspaces/experts.py index 7fffacd6..7beb01c8 100644 --- a/runtime/workspaces/experts.py +++ b/runtime/workspaces/experts.py @@ -6,7 +6,7 @@ import threading from pathlib import Path from typing import Any -from oclaw.platform.config.paths import PROJECT_ROOT +from svc.config.paths import PROJECT_ROOT _REQUIRED_FILES: tuple[str, ...] = ("SOUL.md",) _OPTIONAL_FILES: tuple[str, ...] = ("ROLE_SYSTEM.md",) diff --git a/scripts/wecom_smoke_test.py b/scripts/wecom_smoke_test.py index d4a207bd..975942a5 100644 --- a/scripts/wecom_smoke_test.py +++ b/scripts/wecom_smoke_test.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.runtime.operations.scripts.wecom_smoke_test import main +from runtime.operations.scripts.wecom_smoke_test import main if __name__ == "__main__": diff --git a/scripts/wecom_status.py b/scripts/wecom_status.py index 6feda157..57cb79e2 100644 --- a/scripts/wecom_status.py +++ b/scripts/wecom_status.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.runtime.operations.scripts.wecom_status import main +from runtime.operations.scripts.wecom_status import main if __name__ == "__main__": diff --git a/skills/session-bootstrap/SKILL.md b/skills/session-bootstrap/SKILL.md index 3b05ce36..0a6d67ec 100644 --- a/skills/session-bootstrap/SKILL.md +++ b/skills/session-bootstrap/SKILL.md @@ -85,4 +85,4 @@ description: 在新会话开始时自动完成身份唤醒、近期记忆加载 可用以下命令检查是否处于可加载状态: -`python -m oclaw.runtime.operations hooks info session-bootstrap --workspace "." --json` +`python -m runtime.operations hooks info session-bootstrap --workspace "." --json` diff --git a/skills/session-bootstrap/hooks/runtime/handler.py b/skills/session-bootstrap/hooks/runtime/handler.py index ec98a778..424c3f84 100644 --- a/skills/session-bootstrap/hooks/runtime/handler.py +++ b/skills/session-bootstrap/hooks/runtime/handler.py @@ -26,7 +26,7 @@ def _workspace_dir(event: Any) -> Path | None: def _repo_root() -> Path: - from oclaw.platform.config.paths import PROJECT_ROOT + from svc.config.paths import PROJECT_ROOT return Path(PROJECT_ROOT).resolve() diff --git a/svc/__init__.py b/svc/__init__.py new file mode 100644 index 00000000..394d74c3 --- /dev/null +++ b/svc/__init__.py @@ -0,0 +1 @@ +"""Shared services layer (LLM transports, persistence, configuration, files).""" diff --git a/platform/config/__init__.py b/svc/config/__init__.py similarity index 100% rename from platform/config/__init__.py rename to svc/config/__init__.py diff --git a/platform/config/bootstrap_env.py b/svc/config/bootstrap_env.py similarity index 100% rename from platform/config/bootstrap_env.py rename to svc/config/bootstrap_env.py diff --git a/platform/config/passwords.py b/svc/config/passwords.py similarity index 91% rename from platform/config/passwords.py rename to svc/config/passwords.py index f47dd2ad..85b4eacf 100644 --- a/platform/config/passwords.py +++ b/svc/config/passwords.py @@ -4,7 +4,7 @@ from __future__ import annotations import os -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.persistence.sqlite_store import SqliteStore _DEFAULT_BOOTSTRAP_PASSWORD = "admin123" diff --git a/platform/config/paths.py b/svc/config/paths.py similarity index 99% rename from platform/config/paths.py rename to svc/config/paths.py index eeb63d86..509c61c4 100644 --- a/platform/config/paths.py +++ b/svc/config/paths.py @@ -14,7 +14,7 @@ from pathlib import Path def _project_root() -> Path: if getattr(sys, "frozen", False): return Path(sys.executable).resolve().parent - # Source layout: /platform/config/paths.py + # Source layout: /svc/config/paths.py return Path(__file__).resolve().parents[2] diff --git a/platform/config/runtime_paths.py b/svc/config/runtime_paths.py similarity index 96% rename from platform/config/runtime_paths.py rename to svc/config/runtime_paths.py index 91134475..2a915f4a 100644 --- a/platform/config/runtime_paths.py +++ b/svc/config/runtime_paths.py @@ -2,7 +2,7 @@ from __future__ import annotations from pathlib import Path -from oclaw.platform.config.paths import PROJECT_ROOT +from svc.config.paths import PROJECT_ROOT def oclaw_root() -> Path: diff --git a/platform/embeddings/embedding_client.py b/svc/embeddings/embedding_client.py similarity index 100% rename from platform/embeddings/embedding_client.py rename to svc/embeddings/embedding_client.py diff --git a/platform/files/__init__.py b/svc/files/__init__.py similarity index 100% rename from platform/files/__init__.py rename to svc/files/__init__.py diff --git a/platform/files/archive_processor.py b/svc/files/archive_processor.py similarity index 100% rename from platform/files/archive_processor.py rename to svc/files/archive_processor.py diff --git a/platform/files/attachment_assets.py b/svc/files/attachment_assets.py similarity index 99% rename from platform/files/attachment_assets.py rename to svc/files/attachment_assets.py index c24ac983..a0264ff2 100644 --- a/platform/files/attachment_assets.py +++ b/svc/files/attachment_assets.py @@ -10,7 +10,7 @@ from dataclasses import dataclass from pathlib import Path from typing import Any, Final, Optional -from oclaw.platform.config.paths import attachments_dir +from svc.config.paths import attachments_dir _META_SUFFIX: Final[str] = ".meta.json" _ATTACHMENT_ID_RE: Final[re.Pattern[str]] = re.compile(r"^[a-f0-9]{64}$") # Must match extensions produced by ``save_bytes`` so ``load_bytes`` / ``get_local_path`` / ``gc`` can find blobs. diff --git a/platform/files/file_attachments.py b/svc/files/file_attachments.py similarity index 98% rename from platform/files/file_attachments.py rename to svc/files/file_attachments.py index c7ce2031..f8831062 100644 --- a/platform/files/file_attachments.py +++ b/svc/files/file_attachments.py @@ -17,8 +17,8 @@ from docx import Document from PIL import Image from PyPDF2 import PdfReader -from oclaw.platform.config.paths import PROJECT_ROOT -from oclaw.platform.files.archive_processor import ( +from svc.config.paths import PROJECT_ROOT +from svc.files.archive_processor import ( MAX_ARCHIVE_DEPTH, MAX_ARCHIVE_ENTRY_BYTES, MAX_ARCHIVE_FILE_COUNT, @@ -28,9 +28,9 @@ from oclaw.platform.files.archive_processor import ( is_safe_archive_member_name, process_archive, ) -from oclaw.platform.files.attachment_assets import AttachmentAssetStore -from oclaw.platform.files.tabular_attachment_store import save_dataframe, save_workbook -from oclaw.platform.files.text_attachment_store import ( +from svc.files.attachment_assets import AttachmentAssetStore +from svc.files.tabular_attachment_store import save_dataframe, save_workbook +from svc.files.text_attachment_store import ( DEFAULT_TEXT_CHUNK_OVERLAP, DEFAULT_TEXT_CHUNK_SIZE, DEFAULT_TEXT_INLINE_MAX_CHARS, @@ -208,7 +208,7 @@ def _safe_int(raw: Any, default: int, *, min_value: int = 1, max_value: int = 2_ @lru_cache(maxsize=1) def _attachments_limits() -> dict[str, Any]: cfg_path_raw = str(os.getenv("AIA_OCLAW_CONFIG_PATH") or "").strip() - cfg_path = Path(cfg_path_raw).expanduser() if cfg_path_raw else (Path(PROJECT_ROOT) / "oclaw" / "oclaw.json").resolve() + cfg_path = Path(cfg_path_raw).expanduser() if cfg_path_raw else (Path(PROJECT_ROOT) / "oclaw.json").resolve() if not cfg_path.is_absolute(): cfg_path = (Path(PROJECT_ROOT) / cfg_path).resolve() tabular_cfg: dict[str, Any] = {} diff --git a/platform/files/session_export.py b/svc/files/session_export.py similarity index 96% rename from platform/files/session_export.py rename to svc/files/session_export.py index 1a440602..ce5d6a1c 100644 --- a/platform/files/session_export.py +++ b/svc/files/session_export.py @@ -3,7 +3,7 @@ from __future__ import annotations import json from typing import Any -from oclaw.platform.persistence.sqlite_store import ChatMessage, SqliteStore +from svc.persistence.sqlite_store import ChatMessage, SqliteStore def export_session_json(store: SqliteStore, session_id: str, message_limit: int = 50_000) -> str: diff --git a/platform/files/tabular_attachment_store.py b/svc/files/tabular_attachment_store.py similarity index 99% rename from platform/files/tabular_attachment_store.py rename to svc/files/tabular_attachment_store.py index dcc800fe..cf0b33e3 100644 --- a/platform/files/tabular_attachment_store.py +++ b/svc/files/tabular_attachment_store.py @@ -12,8 +12,8 @@ from typing import Any import pandas as pd -from oclaw.platform.config.paths import PROJECT_ROOT -from oclaw.platform.config.paths import attachments_dir +from svc.config.paths import PROJECT_ROOT +from svc.config.paths import attachments_dir def _tabular_root() -> Path: @@ -102,7 +102,7 @@ def _tabular_sql_timeout_ms() -> int: if raw: return _clamp_timeout(raw) cfg_path_raw = str(os.getenv("AIA_OCLAW_CONFIG_PATH") or "").strip() - cfg_path = Path(cfg_path_raw).expanduser() if cfg_path_raw else (Path(PROJECT_ROOT) / "oclaw" / "oclaw.json").resolve() + cfg_path = Path(cfg_path_raw).expanduser() if cfg_path_raw else (Path(PROJECT_ROOT) / "oclaw.json").resolve() if not cfg_path.is_absolute(): cfg_path = (Path(PROJECT_ROOT) / cfg_path).resolve() try: diff --git a/platform/files/text_attachment_store.py b/svc/files/text_attachment_store.py similarity index 99% rename from platform/files/text_attachment_store.py rename to svc/files/text_attachment_store.py index 9a7316af..079ab5be 100644 --- a/platform/files/text_attachment_store.py +++ b/svc/files/text_attachment_store.py @@ -7,7 +7,7 @@ import sqlite3 from pathlib import Path from typing import Any -from oclaw.platform.config.paths import attachments_dir +from svc.config.paths import attachments_dir DEFAULT_TEXT_INLINE_MAX_CHARS = 12_000 diff --git a/platform/integrations/cc_mini_vendor.py b/svc/integrations/cc_mini_vendor.py similarity index 98% rename from platform/integrations/cc_mini_vendor.py rename to svc/integrations/cc_mini_vendor.py index a7dd2d7b..17e9b5fa 100644 --- a/platform/integrations/cc_mini_vendor.py +++ b/svc/integrations/cc_mini_vendor.py @@ -14,7 +14,7 @@ import sys from pathlib import Path from typing import Any -from oclaw.platform.config.paths import PROJECT_ROOT +from svc.config.paths import PROJECT_ROOT def cc_mini_root() -> Path: diff --git a/platform/integrations/wecom_client.py b/svc/integrations/wecom_client.py similarity index 97% rename from platform/integrations/wecom_client.py rename to svc/integrations/wecom_client.py index f1f5d68a..9b57052a 100644 --- a/platform/integrations/wecom_client.py +++ b/svc/integrations/wecom_client.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.persistence.sqlite_store import SqliteStore class WeComClient: diff --git a/platform/llm/MIT_LICENSE.txt b/svc/llm/MIT_LICENSE.txt similarity index 100% rename from platform/llm/MIT_LICENSE.txt rename to svc/llm/MIT_LICENSE.txt diff --git a/svc/llm/__init__.py b/svc/llm/__init__.py new file mode 100644 index 00000000..b90799f0 --- /dev/null +++ b/svc/llm/__init__.py @@ -0,0 +1 @@ +# svc.llm package diff --git a/platform/llm/chat_models.py b/svc/llm/chat_models.py similarity index 73% rename from platform/llm/chat_models.py rename to svc/llm/chat_models.py index 6db6643b..a64adbc7 100644 --- a/platform/llm/chat_models.py +++ b/svc/llm/chat_models.py @@ -8,16 +8,16 @@ Implementations live under `src.platform.llm.transports.*`. import os -from oclaw.platform.llm.tool_schema import shrink_openai_tools_payload_for_api -from oclaw.platform.llm.tool_schema import openai_tools_json_byte_length as _openai_tools_json_byte_length -from oclaw.platform.llm.transports.base import ChatModel, LLMResponse, LLMToolCall, normalize_image_b64_payload -from oclaw.platform.llm.transports.google_gemini_sse import GoogleGeminiChatModel -from oclaw.platform.llm.transports.openai_chat_completions import ( +from svc.llm.tool_schema import shrink_openai_tools_payload_for_api +from svc.llm.tool_schema import openai_tools_json_byte_length as _openai_tools_json_byte_length +from svc.llm.transports.base import ChatModel, LLMResponse, LLMToolCall, normalize_image_b64_payload +from svc.llm.transports.google_gemini_sse import GoogleGeminiChatModel +from svc.llm.transports.openai_chat_completions import ( OpenAIChatModel, _likely_gemini_openai_compat_base_url, _model_id_suggests_gemini, ) -from oclaw.platform.llm.transports.simple import RuleBasedChatModel, StaticTextChatModel +from svc.llm.transports.simple import RuleBasedChatModel, StaticTextChatModel # Backward-compat alias used by `src/chat/agent.py`. _normalize_image_b64_payload = normalize_image_b64_payload @@ -37,7 +37,7 @@ def build_default_model() -> ChatModel: return RuleBasedChatModel() if mode == "ollama": try: - from oclaw.runtime.agents.factory import DEFAULT_OLLAMA_BASE_URL, DEFAULT_OLLAMA_MODEL + from runtime.agents.factory import DEFAULT_OLLAMA_BASE_URL, DEFAULT_OLLAMA_MODEL return OpenAIChatModel(model=DEFAULT_OLLAMA_MODEL, api_key="ollama", base_url=DEFAULT_OLLAMA_BASE_URL) except Exception: diff --git a/platform/llm/image_http_common.py b/svc/llm/image_http_common.py similarity index 100% rename from platform/llm/image_http_common.py rename to svc/llm/image_http_common.py diff --git a/platform/llm/image_legacy_client.py b/svc/llm/image_legacy_client.py similarity index 97% rename from platform/llm/image_legacy_client.py rename to svc/llm/image_legacy_client.py index 6127af48..fd511dc0 100644 --- a/platform/llm/image_legacy_client.py +++ b/svc/llm/image_legacy_client.py @@ -3,9 +3,9 @@ Uses ``{"image":...}/{"text":...}`` or typed compatible-mode blocks on ``/chat/completions`` only. The **image specialist** uses this module from: -- :mod:`~oclaw.runtime.agents.specialist_agent` (orchestration temp sessions) -- :mod:`~oclaw.runtime.direct_loop` when ``skill_binding_role=="image"`` (**gateway /chat UI**), so vision - turns never hit :class:`~oclaw.platform.llm.transports.openai_responses.OpenAIResponsesModel` unless explicitly disabled via env. +- :mod:`~runtime.agents.specialist_agent` (orchestration temp sessions) +- :mod:`~runtime.direct_loop` when ``skill_binding_role=="image"`` (**gateway /chat UI**), so vision + turns never hit :class:`~svc.llm.transports.openai_responses.OpenAIResponsesModel` unless explicitly disabled via env. Alignment with Alibaba ``dashscope.MultiModalConversation`` examples (**message shape**): ``messages = [{"role": "user", "content": [{"image": ""}, {"text": "..."}]}]`` @@ -23,7 +23,7 @@ SDK-style extras: Compatibility roots: - ``compatible-mode/v1`` **默认**使用 OpenAI Chat Completions 视觉块(每条含 ``type``:``image_url`` / ``text``);百炼兼容网关否则会报 ``missing_required_parameter … content[n].type``。若网关只吃 DashScope 文档形态(无 ``type`` 的 ``{"image"}``/``{"text"}``),设置 ``AIA_IMAGE_EXPERT_COMPAT_USE_DASHSCOPE_NATIVE_BLOCKS=1``。 -For OpenAI-style ``image_url`` chat payloads (tool OCR / multimodal downgrade), use :mod:`oclaw.platform.llm.image_ocr_client`. +For OpenAI-style ``image_url`` chat payloads (tool OCR / multimodal downgrade), use :mod:`svc.llm.image_ocr_client`. Chat UI **图片专家**端到端说明(与其它链路隔离的变更边界)见仓库内 ``docs/IMAGE_SPECIALIST_LANE.md``. """ @@ -39,8 +39,8 @@ from typing import Any import httpx -from oclaw.platform.files.attachment_assets import AttachmentAssetStore -from oclaw.platform.llm.image_http_common import ( +from svc.files.attachment_assets import AttachmentAssetStore +from svc.llm.image_http_common import ( build_extract_diag_empty, compress_data_url_image, dashscope_multimodal_http_ok, @@ -57,7 +57,7 @@ from oclaw.platform.llm.image_http_common import ( post_with_retry, redact_response_for_debug, ) -from oclaw.runtime.prompt_templates import render_prompt +from runtime.prompt_templates import render_prompt IMAGE_SPECIALIST_DEFAULT_PROMPT_ZH = ( "请根据用户上传的图片作答:描述可见场景、物体与文字;不确定处请标明。" @@ -101,7 +101,7 @@ def collect_legacy_lane_images_from_attachments( max_images: int | None = None, ) -> list[str]: """Normalize incoming UI/store attachments to URLs/data URLs for :func:`send_legacy_image_messages`.""" - from oclaw.platform.files.attachment_assets import attachment_id_to_data_url + from svc.files.attachment_assets import attachment_id_to_data_url cap = max(1, min(int(max_images if max_images is not None else _max_legacy_input_images()), 12)) out: list[str] = [] diff --git a/platform/llm/image_ocr_client.py b/svc/llm/image_ocr_client.py similarity index 98% rename from platform/llm/image_ocr_client.py rename to svc/llm/image_ocr_client.py index 79f4a1c8..921ec9c8 100644 --- a/platform/llm/image_ocr_client.py +++ b/svc/llm/image_ocr_client.py @@ -6,7 +6,7 @@ from typing import Any import httpx -from oclaw.platform.llm.image_http_common import ( +from svc.llm.image_http_common import ( compress_data_url_image, env_ocr_lane_api_key, env_ocr_lane_base_url, @@ -17,7 +17,7 @@ from oclaw.platform.llm.image_http_common import ( join_url, post_with_retry, ) -from oclaw.runtime.prompt_templates import render_prompt +from runtime.prompt_templates import render_prompt # Shared with query_image_attachment and OpenAI-compat multimodal→text downgrade. VISION_OCR_EXTRACT_PROMPT_ZH = ( diff --git a/platform/llm/replay_policy.py b/svc/llm/replay_policy.py similarity index 95% rename from platform/llm/replay_policy.py rename to svc/llm/replay_policy.py index 3760a33f..40e18090 100644 --- a/platform/llm/replay_policy.py +++ b/svc/llm/replay_policy.py @@ -13,7 +13,7 @@ import os from dataclasses import dataclass from typing import Any -from oclaw.platform.llm.tool_call_id import DEFAULT_MAX_OPENAI_TOOL_CALL_ID_LEN +from svc.llm.tool_call_id import DEFAULT_MAX_OPENAI_TOOL_CALL_ID_LEN @dataclass(frozen=True) @@ -78,7 +78,7 @@ def apply_replay_policy_to_messages( """Apply repair + id sanitization in order.""" if not policy.enabled or not messages: return messages - from oclaw.platform.llm.tool_call_id import ( + from svc.llm.tool_call_id import ( repair_orphan_tool_messages, rewrite_openai_chat_messages_tool_ids, ) diff --git a/platform/llm/tool_call_id.py b/svc/llm/tool_call_id.py similarity index 100% rename from platform/llm/tool_call_id.py rename to svc/llm/tool_call_id.py diff --git a/platform/llm/tool_schema.py b/svc/llm/tool_schema.py similarity index 100% rename from platform/llm/tool_schema.py rename to svc/llm/tool_schema.py diff --git a/platform/llm/tool_wire_policy.py b/svc/llm/tool_wire_policy.py similarity index 98% rename from platform/llm/tool_wire_policy.py rename to svc/llm/tool_wire_policy.py index 5754ceb2..1065abae 100644 --- a/platform/llm/tool_wire_policy.py +++ b/svc/llm/tool_wire_policy.py @@ -12,7 +12,7 @@ import os from datetime import datetime, timedelta, timezone from typing import Any -from oclaw.platform.llm.tool_schema import MIN_OPENAI_FUNCTION_PARAMETERS, complete_openai_tools_wire_parameters +from svc.llm.tool_schema import MIN_OPENAI_FUNCTION_PARAMETERS, complete_openai_tools_wire_parameters logger = logging.getLogger(__name__) @@ -408,7 +408,7 @@ def prepare_openai_tools_for_llm_api( """Build wire ``tools[]``: optional graduated policy + byte cap.""" def _fallback_shrink(raw: list[dict[str, Any]], cap: int) -> list[dict[str, Any]]: - from oclaw.platform.llm.tool_schema import shrink_openai_tools_payload_for_api + from svc.llm.tool_schema import shrink_openai_tools_payload_for_api return shrink_openai_tools_payload_for_api(raw, max_json_bytes=cap) @@ -426,8 +426,8 @@ def prepare_openai_tools_for_llm_api( role_mode = "restricted" try: if store is None: - from oclaw.platform.config.paths import db_path - from oclaw.platform.persistence.sqlite_store import SqliteStore + from svc.config.paths import db_path + from svc.persistence.sqlite_store import SqliteStore store = SqliteStore(db_path()) # Role-scoped policies if configured; otherwise fall back to global. @@ -654,7 +654,7 @@ def _squeeze_to_budget( work.pop(i) if sz() > max_json_bytes: - from oclaw.platform.llm.tool_schema import shrink_openai_tools_payload_for_api + from svc.llm.tool_schema import shrink_openai_tools_payload_for_api work = shrink_openai_tools_payload_for_api(work, max_json_bytes=max_json_bytes) return work @@ -713,7 +713,7 @@ def penalty_row_status( def build_tool_wire_snapshot(store: Any, *, role: str | None = None) -> dict[str, Any]: """Aggregate MCP install list + usage + policies for Admin GET.""" - from oclaw.runtime.tools.mcp.registry import McpRegistry + from runtime.tools.mcp.registry import McpRegistry admin = load_merged_admin_config(store) role_norm = str(role or "").strip().lower() or None diff --git a/svc/llm/transports/__init__.py b/svc/llm/transports/__init__.py new file mode 100644 index 00000000..5c058b68 --- /dev/null +++ b/svc/llm/transports/__init__.py @@ -0,0 +1 @@ +# svc.llm.transports package diff --git a/platform/llm/transports/anthropic_messages.py b/svc/llm/transports/anthropic_messages.py similarity index 98% rename from platform/llm/transports/anthropic_messages.py rename to svc/llm/transports/anthropic_messages.py index a103f817..c1c7ba0b 100644 --- a/platform/llm/transports/anthropic_messages.py +++ b/svc/llm/transports/anthropic_messages.py @@ -7,7 +7,7 @@ import uuid from typing import Any, Optional from collections.abc import Callable, Iterable -from oclaw.platform.llm.transports.base import ChatModel, LLMResponse, LLMToolCall +from svc.llm.transports.base import ChatModel, LLMResponse, LLMToolCall logger = logging.getLogger(__name__) diff --git a/platform/llm/transports/base.py b/svc/llm/transports/base.py similarity index 100% rename from platform/llm/transports/base.py rename to svc/llm/transports/base.py diff --git a/platform/llm/transports/google_gemini_sse.py b/svc/llm/transports/google_gemini_sse.py similarity index 99% rename from platform/llm/transports/google_gemini_sse.py rename to svc/llm/transports/google_gemini_sse.py index 507e729e..3a2e3853 100644 --- a/platform/llm/transports/google_gemini_sse.py +++ b/svc/llm/transports/google_gemini_sse.py @@ -6,7 +6,7 @@ import uuid from typing import Any, Optional from collections.abc import Callable -from oclaw.platform.llm.transports.base import ChatModel, LLMResponse, LLMToolCall +from svc.llm.transports.base import ChatModel, LLMResponse, LLMToolCall class GoogleGeminiChatModel(ChatModel): diff --git a/platform/llm/transports/openai_chat_completions.py b/svc/llm/transports/openai_chat_completions.py similarity index 97% rename from platform/llm/transports/openai_chat_completions.py rename to svc/llm/transports/openai_chat_completions.py index 599af059..2087877c 100644 --- a/platform/llm/transports/openai_chat_completions.py +++ b/svc/llm/transports/openai_chat_completions.py @@ -8,8 +8,8 @@ import uuid from typing import Any, Optional from collections.abc import Callable -from oclaw.platform.llm.tool_schema import complete_openai_tools_wire_parameters -from oclaw.platform.llm.transports.base import ChatModel, LLMResponse, LLMToolCall, normalize_image_b64_payload, coerce_thought_signature_for_storage +from svc.llm.tool_schema import complete_openai_tools_wire_parameters +from svc.llm.transports.base import ChatModel, LLMResponse, LLMToolCall, normalize_image_b64_payload, coerce_thought_signature_for_storage logger = logging.getLogger(__name__) @@ -296,7 +296,7 @@ def _flatten_message_content_for_text_gateway(content: Any) -> str: return str(content or "") if _multimodal_downgrade_ocr_enabled() and _message_list_contains_image_block(content): try: - from oclaw.platform.llm.image_ocr_client import ( + from svc.llm.image_ocr_client import ( VISION_OCR_EXTRACT_PROMPT_ZH, send_ocr_image_messages, vision_llm_backend_status, @@ -465,7 +465,7 @@ class OpenAIChatModel(ChatModel): def _create_chat_completion(self, norm_msgs: list[dict[str, Any]], tools: list[dict[str, Any]], *, stream: bool): # replay_policy/tool_wire_policy live in sibling modules; import lazily to avoid cycles. try: - from oclaw.platform.llm.replay_policy import apply_replay_policy_to_messages, resolve_replay_policy + from svc.llm.replay_policy import apply_replay_policy_to_messages, resolve_replay_policy policy = resolve_replay_policy(self.base_url, self.model) if policy.enabled: @@ -540,9 +540,9 @@ class OpenAIChatModel(ChatModel): kwargs["extra_body"] = extra_body if use_tools: try: - from oclaw.platform.config.paths import db_path - from oclaw.platform.persistence.sqlite_store import SqliteStore - from oclaw.runtime.tools.exposure_plan import build_llm_tools_plan + from svc.config.paths import db_path + from svc.persistence.sqlite_store import SqliteStore + from runtime.tools.exposure_plan import build_llm_tools_plan plan = build_llm_tools_plan( store=SqliteStore(db_path()), diff --git a/platform/llm/transports/openai_responses.py b/svc/llm/transports/openai_responses.py similarity index 99% rename from platform/llm/transports/openai_responses.py rename to svc/llm/transports/openai_responses.py index 1f804f9e..31b5195a 100644 --- a/platform/llm/transports/openai_responses.py +++ b/svc/llm/transports/openai_responses.py @@ -8,7 +8,7 @@ import uuid from typing import Any, Optional from collections.abc import Callable, Iterable -from oclaw.platform.llm.transports.base import ChatModel, LLMResponse, LLMToolCall, normalize_image_b64_payload +from svc.llm.transports.base import ChatModel, LLMResponse, LLMToolCall, normalize_image_b64_payload logger = logging.getLogger(__name__) diff --git a/platform/llm/transports/simple.py b/svc/llm/transports/simple.py similarity index 98% rename from platform/llm/transports/simple.py rename to svc/llm/transports/simple.py index 2594bef3..33ade38a 100644 --- a/platform/llm/transports/simple.py +++ b/svc/llm/transports/simple.py @@ -5,7 +5,7 @@ import re from typing import Any, Optional from collections.abc import Callable -from oclaw.platform.llm.transports.base import ChatModel, LLMResponse, LLMToolCall +from svc.llm.transports.base import ChatModel, LLMResponse, LLMToolCall class StaticTextChatModel(ChatModel): diff --git a/platform/llm/video_generation_client.py b/svc/llm/video_generation_client.py similarity index 98% rename from platform/llm/video_generation_client.py rename to svc/llm/video_generation_client.py index 48d87a64..e4d42dab 100644 --- a/platform/llm/video_generation_client.py +++ b/svc/llm/video_generation_client.py @@ -1,7 +1,7 @@ """DashScope / Model Studio **text-to-video** and **image-to-video** (async: create task → poll). Used by the **video** specialist (Admin Chat + orchestration) to bypass the generic LLM tool loop, -analogous to :mod:`oclaw.platform.llm.image_legacy_client` for the image specialist. +analogous to :mod:`svc.llm.image_legacy_client` for the image specialist. **Text-to-video:** ``input`` only ``prompt`` (plus optional ``audio_url`` / ``negative_prompt`` for some models). Use a **t2v** model id. @@ -37,8 +37,8 @@ from typing import Any, Callable, Literal import httpx -from oclaw.platform.files.attachment_assets import AttachmentAssetStore -from oclaw.platform.llm.image_http_common import ( +from svc.files.attachment_assets import AttachmentAssetStore +from svc.llm.image_http_common import ( compress_data_url_image, dashscope_multimodal_http_ok, download_http_url_bytes, diff --git a/platform/persistence/__init__.py b/svc/persistence/__init__.py similarity index 100% rename from platform/persistence/__init__.py rename to svc/persistence/__init__.py diff --git a/platform/persistence/sqlite_store.py b/svc/persistence/sqlite_store.py similarity index 99% rename from platform/persistence/sqlite_store.py rename to svc/persistence/sqlite_store.py index 9a8723b2..069ae8e3 100644 --- a/platform/persistence/sqlite_store.py +++ b/svc/persistence/sqlite_store.py @@ -3067,7 +3067,7 @@ class SqliteStore: uid = str(user_id or "").strip() if not uid: return - from oclaw.runtime.agents.specialists import dump_agent_profile_bindings, parse_agent_profile_bindings + from runtime.agents.specialists import dump_agent_profile_bindings, parse_agent_profile_bindings seeded_key = f"llm_personal_pool_seeded:{uid}" act_key = active_llm_profile_setting_key(uid, username) diff --git a/tests/conftest.py b/tests/conftest.py index 50a87b82..b8d9d117 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -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() - diff --git a/tests/test_admin_audit_pagination_api.py b/tests/test_admin_audit_pagination_api.py index 821b1284..afed24dd 100644 --- a/tests/test_admin_audit_pagination_api.py +++ b/tests/test_admin_audit_pagination_api.py @@ -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): diff --git a/tests/test_admin_auth_rbac.py b/tests/test_admin_auth_rbac.py index dcca42e3..f96eefe9 100644 --- a/tests/test_admin_auth_rbac.py +++ b/tests/test_admin_auth_rbac.py @@ -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): diff --git a/tests/test_admin_chat_stream_async_task.py b/tests/test_admin_chat_stream_async_task.py index f491c77d..535434ff 100644 --- a/tests/test_admin_chat_stream_async_task.py +++ b/tests/test_admin_chat_stream_async_task.py @@ -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): diff --git a/tests/test_admin_chat_wiki_events_api.py b/tests/test_admin_chat_wiki_events_api.py index 8652582c..04e0c289 100644 --- a/tests/test_admin_chat_wiki_events_api.py +++ b/tests/test_admin_chat_wiki_events_api.py @@ -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): diff --git a/tests/test_admin_internal_tools_preview_api.py b/tests/test_admin_internal_tools_preview_api.py index b4543693..bd503dae 100644 --- a/tests/test_admin_internal_tools_preview_api.py +++ b/tests/test_admin_internal_tools_preview_api.py @@ -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): diff --git a/tests/test_admin_internal_tools_reload_api.py b/tests/test_admin_internal_tools_reload_api.py index 7e6ba95a..a52a6328 100644 --- a/tests/test_admin_internal_tools_reload_api.py +++ b/tests/test_admin_internal_tools_reload_api.py @@ -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): diff --git a/tests/test_admin_llm_preview_planner_consistency.py b/tests/test_admin_llm_preview_planner_consistency.py index bcf410f8..f22ff4d8 100644 --- a/tests/test_admin_llm_preview_planner_consistency.py +++ b/tests/test_admin_llm_preview_planner_consistency.py @@ -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): diff --git a/tests/test_admin_llm_tools_preview_api.py b/tests/test_admin_llm_tools_preview_api.py index 5f784df5..b6985dc4 100644 --- a/tests/test_admin_llm_tools_preview_api.py +++ b/tests/test_admin_llm_tools_preview_api.py @@ -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): diff --git a/tests/test_admin_mcp_tool_wire_role_mode_api.py b/tests/test_admin_mcp_tool_wire_role_mode_api.py index f552acc6..063df652 100644 --- a/tests/test_admin_mcp_tool_wire_role_mode_api.py +++ b/tests/test_admin_mcp_tool_wire_role_mode_api.py @@ -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): diff --git a/tests/test_admin_oclaw_runs_api.py b/tests/test_admin_oclaw_runs_api.py index 0e04d83d..2a79f982 100644 --- a/tests/test_admin_oclaw_runs_api.py +++ b/tests/test_admin_oclaw_runs_api.py @@ -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): diff --git a/tests/test_admin_oclaw_tasks_api.py b/tests/test_admin_oclaw_tasks_api.py index f36e3321..cbe1ffb4 100644 --- a/tests/test_admin_oclaw_tasks_api.py +++ b/tests/test_admin_oclaw_tasks_api.py @@ -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): diff --git a/tests/test_admin_session_monitor_api.py b/tests/test_admin_session_monitor_api.py index 37fdf55e..b62e1f67 100644 --- a/tests/test_admin_session_monitor_api.py +++ b/tests/test_admin_session_monitor_api.py @@ -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): diff --git a/tests/test_admin_skills_api.py b/tests/test_admin_skills_api.py index f3a50ee5..8a026366 100644 --- a/tests/test_admin_skills_api.py +++ b/tests/test_admin_skills_api.py @@ -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"}, diff --git a/tests/test_admin_tool_policy_oclaw_retry_codes.py b/tests/test_admin_tool_policy_oclaw_retry_codes.py index 17add3e2..77832b0e 100644 --- a/tests/test_admin_tool_policy_oclaw_retry_codes.py +++ b/tests/test_admin_tool_policy_oclaw_retry_codes.py @@ -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): diff --git a/tests/test_admin_tools_exposure_trace_setting_api.py b/tests/test_admin_tools_exposure_trace_setting_api.py index 9b0c2a59..54234887 100644 --- a/tests/test_admin_tools_exposure_trace_setting_api.py +++ b/tests/test_admin_tools_exposure_trace_setting_api.py @@ -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): diff --git a/tests/test_admin_tools_self_check_api.py b/tests/test_admin_tools_self_check_api.py index 9cc2ddb3..a75cabfb 100644 --- a/tests/test_admin_tools_self_check_api.py +++ b/tests/test_admin_tools_self_check_api.py @@ -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): diff --git a/tests/test_agent_context_loader.py b/tests/test_agent_context_loader.py index 326abb95..31eed568 100644 --- a/tests/test_agent_context_loader.py +++ b/tests/test_agent_context_loader.py @@ -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: diff --git a/tests/test_agent_core_attempt_memory_gate.py b/tests/test_agent_core_attempt_memory_gate.py index 823e2602..fbf1efab 100644 --- a/tests/test_agent_core_attempt_memory_gate.py +++ b/tests/test_agent_core_attempt_memory_gate.py @@ -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: diff --git a/tests/test_anthropic_transport.py b/tests/test_anthropic_transport.py index 73f3c5c3..e6e636e9 100644 --- a/tests/test_anthropic_transport.py +++ b/tests/test_anthropic_transport.py @@ -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: diff --git a/tests/test_attachment_acl_backfill.py b/tests/test_attachment_acl_backfill.py index bb3fdc49..93c98940 100644 --- a/tests/test_attachment_acl_backfill.py +++ b/tests/test_attachment_acl_backfill.py @@ -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: diff --git a/tests/test_attachment_local_url_public_tool.py b/tests/test_attachment_local_url_public_tool.py index bc9a5e2e..51d79711 100644 --- a/tests/test_attachment_local_url_public_tool.py +++ b/tests/test_attachment_local_url_public_tool.py @@ -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 diff --git a/tests/test_attachment_text_replay_guard.py b/tests/test_attachment_text_replay_guard.py index da5dfdf2..f6300b15 100644 --- a/tests/test_attachment_text_replay_guard.py +++ b/tests/test_attachment_text_replay_guard.py @@ -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: diff --git a/tests/test_backup_retention.py b/tests/test_backup_retention.py index 0a66d19e..cfeaff38 100644 --- a/tests/test_backup_retention.py +++ b/tests/test_backup_retention.py @@ -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: diff --git a/tests/test_bailian_webparser_tool.py b/tests/test_bailian_webparser_tool.py index a00291b2..26779040 100644 --- a/tests/test_bailian_webparser_tool.py +++ b/tests/test_bailian_webparser_tool.py @@ -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: diff --git a/tests/test_bootstrap_env.py b/tests/test_bootstrap_env.py index 3d2f8e6b..5b4a5ef5 100644 --- a/tests/test_bootstrap_env.py +++ b/tests/test_bootstrap_env.py @@ -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) diff --git a/tests/test_catalog_expert_role_loading.py b/tests/test_catalog_expert_role_loading.py index 01a4c9a6..10d7f843 100644 --- a/tests/test_catalog_expert_role_loading.py +++ b/tests/test_catalog_expert_role_loading.py @@ -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") diff --git a/tests/test_catalog_mcp_integration.py b/tests/test_catalog_mcp_integration.py index 66921f83..f022cdea 100644 --- a/tests/test_catalog_mcp_integration.py +++ b/tests/test_catalog_mcp_integration.py @@ -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: diff --git a/tests/test_cc_mini_vendor.py b/tests/test_cc_mini_vendor.py index 56060244..3f482bb4 100644 --- a/tests/test_cc_mini_vendor.py +++ b/tests/test_cc_mini_vendor.py @@ -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: diff --git a/tests/test_channel_dispatch_defaults.py b/tests/test_channel_dispatch_defaults.py index cd7d27eb..184b9420 100644 --- a/tests/test_channel_dispatch_defaults.py +++ b/tests/test_channel_dispatch_defaults.py @@ -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, ) diff --git a/tests/test_chat_api_message_filter.py b/tests/test_chat_api_message_filter.py index e175f640..590c047c 100644 --- a/tests/test_chat_api_message_filter.py +++ b/tests/test_chat_api_message_filter.py @@ -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: diff --git a/tests/test_chat_attachments_payload.py b/tests/test_chat_attachments_payload.py index 13747791..5de65e8c 100644 --- a/tests/test_chat_attachments_payload.py +++ b/tests/test_chat_attachments_payload.py @@ -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: diff --git a/tests/test_chat_mode_execution_persistence.py b/tests/test_chat_mode_execution_persistence.py index 903352f3..1e8cab2a 100644 --- a/tests/test_chat_mode_execution_persistence.py +++ b/tests/test_chat_mode_execution_persistence.py @@ -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, diff --git a/tests/test_chat_profile_api.py b/tests/test_chat_profile_api.py index d514d400..d3694a30 100644 --- a/tests/test_chat_profile_api.py +++ b/tests/test_chat_profile_api.py @@ -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==" diff --git a/tests/test_chat_session_full_smoke.py b/tests/test_chat_session_full_smoke.py index 3152e452..e819f8ae 100644 --- a/tests/test_chat_session_full_smoke.py +++ b/tests/test_chat_session_full_smoke.py @@ -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): diff --git a/tests/test_chat_session_isolation.py b/tests/test_chat_session_isolation.py index f80e6353..7acc0082 100644 --- a/tests/test_chat_session_isolation.py +++ b/tests/test_chat_session_isolation.py @@ -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: diff --git a/tests/test_clawhub_client.py b/tests/test_clawhub_client.py index 69c4cf58..656133b8 100644 --- a/tests/test_clawhub_client.py +++ b/tests/test_clawhub_client.py @@ -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: diff --git a/tests/test_cloudflare_image_generate_tool.py b/tests/test_cloudflare_image_generate_tool.py index 58f33fdc..1aa8e56f 100644 --- a/tests/test_cloudflare_image_generate_tool.py +++ b/tests/test_cloudflare_image_generate_tool.py @@ -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: diff --git a/tests/test_cloudflare_image_public_tool_visibility.py b/tests/test_cloudflare_image_public_tool_visibility.py index fee2b231..76e7771b 100644 --- a/tests/test_cloudflare_image_public_tool_visibility.py +++ b/tests/test_cloudflare_image_public_tool_visibility.py @@ -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: diff --git a/tests/test_direct_loop_empty_assistant_response.py b/tests/test_direct_loop_empty_assistant_response.py index 8b35ef2c..e9525104 100644 --- a/tests/test_direct_loop_empty_assistant_response.py +++ b/tests/test_direct_loop_empty_assistant_response.py @@ -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: diff --git a/tests/test_direct_loop_reasoning_split.py b/tests/test_direct_loop_reasoning_split.py index 14210415..afcf593e 100644 --- a/tests/test_direct_loop_reasoning_split.py +++ b/tests/test_direct_loop_reasoning_split.py @@ -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: diff --git a/tests/test_dsml_tool_parse.py b/tests/test_dsml_tool_parse.py index 22245052..0a1e5cdf 100644 --- a/tests/test_dsml_tool_parse.py +++ b/tests/test_dsml_tool_parse.py @@ -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, diff --git a/tests/test_fastapi_inbound.py b/tests/test_fastapi_inbound.py index c300bf0b..e0664df0 100644 --- a/tests/test_fastapi_inbound.py +++ b/tests/test_fastapi_inbound.py @@ -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: diff --git a/tests/test_fastapi_startup_prebuild.py b/tests/test_fastapi_startup_prebuild.py index b323ff77..af4e0356 100644 --- a/tests/test_fastapi_startup_prebuild.py +++ b/tests/test_fastapi_startup_prebuild.py @@ -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: diff --git a/tests/test_file_attachments.py b/tests/test_file_attachments.py index b6af82fc..a1c4fbc3 100644 --- a/tests/test_file_attachments.py +++ b/tests/test_file_attachments.py @@ -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 diff --git a/tests/test_frontmatter_yaml.py b/tests/test_frontmatter_yaml.py index 29ad51dd..b2804f52 100644 --- a/tests/test_frontmatter_yaml.py +++ b/tests/test_frontmatter_yaml.py @@ -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: diff --git a/tests/test_gateway_image_generation_chain.py b/tests/test_gateway_image_generation_chain.py index f310d006..199c1bc2 100644 --- a/tests/test_gateway_image_generation_chain.py +++ b/tests/test_gateway_image_generation_chain.py @@ -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(): diff --git a/tests/test_gateway_server_methods.py b/tests/test_gateway_server_methods.py index 46d5c4d1..ece340d6 100644 --- a/tests/test_gateway_server_methods.py +++ b/tests/test_gateway_server_methods.py @@ -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"]}}, diff --git a/tests/test_gateway_telegram_send_normalize.py b/tests/test_gateway_telegram_send_normalize.py index 601abc3f..26e5829a 100644 --- a/tests/test_gateway_telegram_send_normalize.py +++ b/tests/test_gateway_telegram_send_normalize.py @@ -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: diff --git a/tests/test_gemini_sse_transport.py b/tests/test_gemini_sse_transport.py index 8162849e..dd7a39f1 100644 --- a/tests/test_gemini_sse_transport.py +++ b/tests/test_gemini_sse_transport.py @@ -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: diff --git a/tests/test_get_messages_preserve_tool_pairing.py b/tests/test_get_messages_preserve_tool_pairing.py index cfc626f6..43248c64 100644 --- a/tests/test_get_messages_preserve_tool_pairing.py +++ b/tests/test_get_messages_preserve_tool_pairing.py @@ -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: diff --git a/tests/test_history_tool_result_compact.py b/tests/test_history_tool_result_compact.py index 698faad0..864be346 100644 --- a/tests/test_history_tool_result_compact.py +++ b/tests/test_history_tool_result_compact.py @@ -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 diff --git a/tests/test_image_expert_env_lane.py b/tests/test_image_expert_env_lane.py index a54e77f8..0af5369b 100644 --- a/tests/test_image_expert_env_lane.py +++ b/tests/test_image_expert_env_lane.py @@ -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( diff --git a/tests/test_image_legacy_gateway_lane.py b/tests/test_image_legacy_gateway_lane.py index 5e7efc8f..b404249f 100644 --- a/tests/test_image_legacy_gateway_lane.py +++ b/tests/test_image_legacy_gateway_lane.py @@ -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: diff --git a/tests/test_inbound_service_reply_suppress.py b/tests/test_inbound_service_reply_suppress.py index b0f14dd9..882e4cf6 100644 --- a/tests/test_inbound_service_reply_suppress.py +++ b/tests/test_inbound_service_reply_suppress.py @@ -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"}]} diff --git a/tests/test_local_public_tools.py b/tests/test_local_public_tools.py index 5745372e..b5533a27 100644 --- a/tests/test_local_public_tools.py +++ b/tests/test_local_public_tools.py @@ -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 diff --git a/tests/test_mcp_adapter.py b/tests/test_mcp_adapter.py index 26694b18..267bb242 100644 --- a/tests/test_mcp_adapter.py +++ b/tests/test_mcp_adapter.py @@ -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) diff --git a/tests/test_mcp_admin_api.py b/tests/test_mcp_admin_api.py index 9b0d87ee..25f074da 100644 --- a/tests/test_mcp_admin_api.py +++ b/tests/test_mcp_admin_api.py @@ -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): diff --git a/tests/test_mcp_e2e_probe.py b/tests/test_mcp_e2e_probe.py index cb354a32..7b9b8ae9 100644 --- a/tests/test_mcp_e2e_probe.py +++ b/tests/test_mcp_e2e_probe.py @@ -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): diff --git a/tests/test_mcp_filesystem_argv.py b/tests/test_mcp_filesystem_argv.py index 162f0e83..be980f04 100644 --- a/tests/test_mcp_filesystem_argv.py +++ b/tests/test_mcp_filesystem_argv.py @@ -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]: diff --git a/tests/test_mcp_installer.py b/tests/test_mcp_installer.py index ac9e6195..3301dd63 100644 --- a/tests/test_mcp_installer.py +++ b/tests/test_mcp_installer.py @@ -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): diff --git a/tests/test_mcp_market.py b/tests/test_mcp_market.py index ede3abb4..7c2fa2c4 100644 --- a/tests/test_mcp_market.py +++ b/tests/test_mcp_market.py @@ -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) diff --git a/tests/test_mcp_registry.py b/tests/test_mcp_registry.py index 8a51038f..0ff3b77f 100644 --- a/tests/test_mcp_registry.py +++ b/tests/test_mcp_registry.py @@ -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): diff --git a/tests/test_mcp_runtime.py b/tests/test_mcp_runtime.py index e971bf31..b098aeb5 100644 --- a/tests/test_mcp_runtime.py +++ b/tests/test_mcp_runtime.py @@ -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: diff --git a/tests/test_mcp_skill_adapter.py b/tests/test_mcp_skill_adapter.py index 652b2e96..ea4843e1 100644 --- a/tests/test_mcp_skill_adapter.py +++ b/tests/test_mcp_skill_adapter.py @@ -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: diff --git a/tests/test_mcp_store.py b/tests/test_mcp_store.py index 182417cc..d4476dfb 100644 --- a/tests/test_mcp_store.py +++ b/tests/test_mcp_store.py @@ -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): diff --git a/tests/test_mcp_workspace_filesystem_e2e.py b/tests/test_mcp_workspace_filesystem_e2e.py index 3cf95a70..48b67d82 100644 --- a/tests/test_mcp_workspace_filesystem_e2e.py +++ b/tests/test_mcp_workspace_filesystem_e2e.py @@ -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): diff --git a/tests/test_media_redact.py b/tests/test_media_redact.py index bb1e90f5..bcae99f2 100644 --- a/tests/test_media_redact.py +++ b/tests/test_media_redact.py @@ -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: diff --git a/tests/test_memory_tool_aliases.py b/tests/test_memory_tool_aliases.py index 81d23505..700a12c2 100644 --- a/tests/test_memory_tool_aliases.py +++ b/tests/test_memory_tool_aliases.py @@ -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: diff --git a/tests/test_memory_vector.py b/tests/test_memory_vector.py index 40ec63d2..a62e207d 100644 --- a/tests/test_memory_vector.py +++ b/tests/test_memory_vector.py @@ -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): diff --git a/tests/test_memory_wiki_plugin.py b/tests/test_memory_wiki_plugin.py index 7d3be10f..dc48c529 100644 --- a/tests/test_memory_wiki_plugin.py +++ b/tests/test_memory_wiki_plugin.py @@ -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(): diff --git a/tests/test_memory_wiki_search_api.py b/tests/test_memory_wiki_search_api.py index b81a50c3..3ea57d12 100644 --- a/tests/test_memory_wiki_search_api.py +++ b/tests/test_memory_wiki_search_api.py @@ -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): diff --git a/tests/test_memory_wiki_tools_loader.py b/tests/test_memory_wiki_tools_loader.py index 039a4750..d0d11ed3 100644 --- a/tests/test_memory_wiki_tools_loader.py +++ b/tests/test_memory_wiki_tools_loader.py @@ -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, diff --git a/tests/test_model_path_audit.py b/tests/test_model_path_audit.py index 91cca02d..199f540b 100644 --- a/tests/test_model_path_audit.py +++ b/tests/test_model_path_audit.py @@ -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: diff --git a/tests/test_netx_ume_ne_tools.py b/tests/test_netx_ume_ne_tools.py index f2f44091..20f1e770 100644 --- a/tests/test_netx_ume_ne_tools.py +++ b/tests/test_netx_ume_ne_tools.py @@ -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] = [] diff --git a/tests/test_oclaw_acp_pointer_relay.py b/tests/test_oclaw_acp_pointer_relay.py index b1e3148c..9c8b96fd 100644 --- a/tests/test_oclaw_acp_pointer_relay.py +++ b/tests/test_oclaw_acp_pointer_relay.py @@ -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: diff --git a/tests/test_oclaw_agent_core.py b/tests/test_oclaw_agent_core.py index 7e3ea2c9..a7c6bee7 100644 --- a/tests/test_oclaw_agent_core.py +++ b/tests/test_oclaw_agent_core.py @@ -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: diff --git a/tests/test_oclaw_agent_core_trace.py b/tests/test_oclaw_agent_core_trace.py index ccd7e5a5..84cd887c 100644 --- a/tests/test_oclaw_agent_core_trace.py +++ b/tests/test_oclaw_agent_core_trace.py @@ -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: diff --git a/tests/test_oclaw_command_parser.py b/tests/test_oclaw_command_parser.py index 9aa20ff7..5c725b78 100644 --- a/tests/test_oclaw_command_parser.py +++ b/tests/test_oclaw_command_parser.py @@ -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: diff --git a/tests/test_oclaw_dynamic_expert.py b/tests/test_oclaw_dynamic_expert.py index 5b41dbf8..78fe26dc 100644 --- a/tests/test_oclaw_dynamic_expert.py +++ b/tests/test_oclaw_dynamic_expert.py @@ -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: diff --git a/tests/test_oclaw_gateway_optimizations.py b/tests/test_oclaw_gateway_optimizations.py index 28f18693..5bf08eba 100644 --- a/tests/test_oclaw_gateway_optimizations.py +++ b/tests/test_oclaw_gateway_optimizations.py @@ -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: diff --git a/tests/test_oclaw_gateway_trace.py b/tests/test_oclaw_gateway_trace.py index 9f927f08..24e4eb69 100644 --- a/tests/test_oclaw_gateway_trace.py +++ b/tests/test_oclaw_gateway_trace.py @@ -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( diff --git a/tests/test_oclaw_generalist_executor.py b/tests/test_oclaw_generalist_executor.py index 6c497828..52fab170 100644 --- a/tests/test_oclaw_generalist_executor.py +++ b/tests/test_oclaw_generalist_executor.py @@ -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: diff --git a/tests/test_oclaw_gmail_watcher_gates.py b/tests/test_oclaw_gmail_watcher_gates.py index bb7fc5b2..5cf04afe 100644 --- a/tests/test_oclaw_gmail_watcher_gates.py +++ b/tests/test_oclaw_gmail_watcher_gates.py @@ -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: diff --git a/tests/test_oclaw_gmail_watcher_lifecycle.py b/tests/test_oclaw_gmail_watcher_lifecycle.py index 5d32b3fb..e993e986 100644 --- a/tests/test_oclaw_gmail_watcher_lifecycle.py +++ b/tests/test_oclaw_gmail_watcher_lifecycle.py @@ -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 diff --git a/tests/test_oclaw_hooks_bundled_parity.py b/tests/test_oclaw_hooks_bundled_parity.py index 291ebc8f..c808179d 100644 --- a/tests/test_oclaw_hooks_bundled_parity.py +++ b/tests/test_oclaw_hooks_bundled_parity.py @@ -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" diff --git a/tests/test_oclaw_hooks_config_toggle_cli.py b/tests/test_oclaw_hooks_config_toggle_cli.py index ee20c535..188d5273 100644 --- a/tests/test_oclaw_hooks_config_toggle_cli.py +++ b/tests/test_oclaw_hooks_config_toggle_cli.py @@ -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")) diff --git a/tests/test_oclaw_hooks_eligibility_metadata.py b/tests/test_oclaw_hooks_eligibility_metadata.py index d08b5cc0..c4fd2989 100644 --- a/tests/test_oclaw_hooks_eligibility_metadata.py +++ b/tests/test_oclaw_hooks_eligibility_metadata.py @@ -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: diff --git a/tests/test_oclaw_hooks_runtime.py b/tests/test_oclaw_hooks_runtime.py index 8d158426..89839291 100644 --- a/tests/test_oclaw_hooks_runtime.py +++ b/tests/test_oclaw_hooks_runtime.py @@ -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" diff --git a/tests/test_oclaw_hooks_runtime_gmail_init.py b/tests/test_oclaw_hooks_runtime_gmail_init.py index e5ef39b1..45d157a5 100644 --- a/tests/test_oclaw_hooks_runtime_gmail_init.py +++ b/tests/test_oclaw_hooks_runtime_gmail_init.py @@ -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() diff --git a/tests/test_oclaw_memory_stage.py b/tests/test_oclaw_memory_stage.py index c181693a..503a36f6 100644 --- a/tests/test_oclaw_memory_stage.py +++ b/tests/test_oclaw_memory_stage.py @@ -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") diff --git a/tests/test_oclaw_operations_hooks_cmd.py b/tests/test_oclaw_operations_hooks_cmd.py index 90b2ea0f..56b11675 100644 --- a/tests/test_oclaw_operations_hooks_cmd.py +++ b/tests/test_oclaw_operations_hooks_cmd.py @@ -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()) diff --git a/tests/test_oclaw_project_context_prompt.py b/tests/test_oclaw_project_context_prompt.py index ce78674d..029eb7e0 100644 --- a/tests/test_oclaw_project_context_prompt.py +++ b/tests/test_oclaw_project_context_prompt.py @@ -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": { diff --git a/tests/test_oclaw_relay_pointer_protocol.py b/tests/test_oclaw_relay_pointer_protocol.py index b29549fd..e7415207 100644 --- a/tests/test_oclaw_relay_pointer_protocol.py +++ b/tests/test_oclaw_relay_pointer_protocol.py @@ -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: diff --git a/tests/test_oclaw_relay_pointer_security.py b/tests/test_oclaw_relay_pointer_security.py index d07fd037..f1c01795 100644 --- a/tests/test_oclaw_relay_pointer_security.py +++ b/tests/test_oclaw_relay_pointer_security.py @@ -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, diff --git a/tests/test_oclaw_role_prompt_paths.py b/tests/test_oclaw_role_prompt_paths.py index 2853c939..3ec60d68 100644 --- a/tests/test_oclaw_role_prompt_paths.py +++ b/tests/test_oclaw_role_prompt_paths.py @@ -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: diff --git a/tests/test_oclaw_router.py b/tests/test_oclaw_router.py index bb0b5063..2a958d98 100644 --- a/tests/test_oclaw_router.py +++ b/tests/test_oclaw_router.py @@ -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: diff --git a/tests/test_oclaw_skill_manifest.py b/tests/test_oclaw_skill_manifest.py index 91974d16..3a2f0aac 100644 --- a/tests/test_oclaw_skill_manifest.py +++ b/tests/test_oclaw_skill_manifest.py @@ -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: diff --git a/tests/test_oclaw_startup_workspace_resolution.py b/tests/test_oclaw_startup_workspace_resolution.py index dc38c14a..95dc1e4b 100644 --- a/tests/test_oclaw_startup_workspace_resolution.py +++ b/tests/test_oclaw_startup_workspace_resolution.py @@ -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: diff --git a/tests/test_oclaw_system_prompt.py b/tests/test_oclaw_system_prompt.py index ac5d7f40..03166fed 100644 --- a/tests/test_oclaw_system_prompt.py +++ b/tests/test_oclaw_system_prompt.py @@ -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: diff --git a/tests/test_oclaw_task_queue.py b/tests/test_oclaw_task_queue.py index 6697e73d..e3b0020b 100644 --- a/tests/test_oclaw_task_queue.py +++ b/tests/test_oclaw_task_queue.py @@ -2,7 +2,7 @@ from __future__ import annotations from pathlib import Path -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.persistence.sqlite_store import SqliteStore def test_oclaw_task_status_flow(tmp_path: Path) -> None: diff --git a/tests/test_oclaw_tool_result_guard.py b/tests/test_oclaw_tool_result_guard.py index 88a46a92..d7564dea 100644 --- a/tests/test_oclaw_tool_result_guard.py +++ b/tests/test_oclaw_tool_result_guard.py @@ -3,9 +3,9 @@ from __future__ import annotations import json from pathlib import Path -from oclaw.runtime.direct_loop import _OCLAW_TOOL_RESULT_HARD_CAP_CHARS, _build_model_context -from oclaw.platform.llm.chat_models import RuleBasedChatModel -from oclaw.platform.persistence.sqlite_store import SqliteStore +from runtime.direct_loop import _OCLAW_TOOL_RESULT_HARD_CAP_CHARS, _build_model_context +from svc.llm.chat_models import RuleBasedChatModel +from svc.persistence.sqlite_store import SqliteStore def test_oclaw_tool_result_context_guard_truncates_large_tool_message(tmp_path: Path) -> None: diff --git a/tests/test_oclaw_worker_title.py b/tests/test_oclaw_worker_title.py index 9dbbff50..8859ca6c 100644 --- a/tests/test_oclaw_worker_title.py +++ b/tests/test_oclaw_worker_title.py @@ -3,9 +3,9 @@ from __future__ import annotations import hashlib from pathlib import Path -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.types import StandardMessage -from oclaw.runtime.worker import _maybe_generate_title_on_third_round +from svc.persistence.sqlite_store import SqliteStore +from runtime.types import StandardMessage +from runtime.worker import _maybe_generate_title_on_third_round class _DummyResp: diff --git a/tests/test_openai_chat_multimodal_downgrade.py b/tests/test_openai_chat_multimodal_downgrade.py index 786fd322..95172ec5 100644 --- a/tests/test_openai_chat_multimodal_downgrade.py +++ b/tests/test_openai_chat_multimodal_downgrade.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.platform.llm.transports.openai_chat_completions import ( +from svc.llm.transports.openai_chat_completions import ( _is_text_only_gateway_error, _messages_contain_list_with_image, _should_proactively_downgrade_multimodal_messages, diff --git a/tests/test_openai_chat_multimodal_downgrade_ocr.py b/tests/test_openai_chat_multimodal_downgrade_ocr.py index eecbb1d9..cf818f38 100644 --- a/tests/test_openai_chat_multimodal_downgrade_ocr.py +++ b/tests/test_openai_chat_multimodal_downgrade_ocr.py @@ -2,7 +2,7 @@ from __future__ import annotations from unittest.mock import patch -from oclaw.platform.llm.transports.openai_chat_completions import ( +from svc.llm.transports.openai_chat_completions import ( _flatten_message_content_for_text_gateway, _normalize_messages_for_text_only_gateway, ) @@ -18,7 +18,7 @@ def test_text_only_downgrade_injects_ocr_when_vision_lane_ok(monkeypatch) -> Non _ = (images, prompt, kwargs) return {"ok": True, "text": "HELLO_FROM_PIC"} - with patch("oclaw.platform.llm.image_ocr_client.send_ocr_image_messages", fake_send): + with patch("svc.llm.image_ocr_client.send_ocr_image_messages", fake_send): content = [ {"type": "text", "text": "请看图"}, {"type": "image_url", "image_url": {"url": "data:image/png;base64,QUJD"}}, @@ -56,7 +56,7 @@ def test_normalize_messages_uses_ocr_flatten(monkeypatch) -> None: _ = (images, prompt, kwargs) return {"ok": True, "text": "X"} - with patch("oclaw.platform.llm.image_ocr_client.send_ocr_image_messages", fake_send): + with patch("svc.llm.image_ocr_client.send_ocr_image_messages", fake_send): out = _normalize_messages_for_text_only_gateway( [{"role": "user", "content": [{"type": "image_url", "image_url": {"url": "https://x/y.png"}}]}] ) diff --git a/tests/test_openai_chat_strict_tool_mode.py b/tests/test_openai_chat_strict_tool_mode.py index e82d9faf..03c1dba7 100644 --- a/tests/test_openai_chat_strict_tool_mode.py +++ b/tests/test_openai_chat_strict_tool_mode.py @@ -5,7 +5,7 @@ from __future__ import annotations import os import unittest -from oclaw.platform.llm.transports.openai_chat_completions import ( +from svc.llm.transports.openai_chat_completions import ( _deepseek_strict_tool_mode_enabled, _merge_deepseek_strict_tool_mode_extra_body, ) diff --git a/tests/test_openai_responses_normalize.py b/tests/test_openai_responses_normalize.py index d197c8ef..c4274936 100644 --- a/tests/test_openai_responses_normalize.py +++ b/tests/test_openai_responses_normalize.py @@ -3,7 +3,7 @@ from __future__ import annotations import httpx from openai import BadRequestError -from oclaw.platform.llm.transports.openai_responses import OpenAIResponsesModel, _is_input_messages_validation_error +from svc.llm.transports.openai_responses import OpenAIResponsesModel, _is_input_messages_validation_error def test_input_messages_validation_detects_body_not_str_exc() -> None: @@ -152,7 +152,7 @@ def test_normalize_agent_messages_style_input_image() -> None: def test_image_legacy_compatible_mode_uses_image_url_parts() -> None: - from oclaw.platform.llm.image_legacy_client import _openai_compatible_vision_content + from svc.llm.image_legacy_client import _openai_compatible_vision_content cc = _openai_compatible_vision_content(["data:image/jpeg;base64,SGk="], "go") assert cc[-1]["type"] == "text" diff --git a/tests/test_openai_responses_transport.py b/tests/test_openai_responses_transport.py index 28220c17..1d3afdab 100644 --- a/tests/test_openai_responses_transport.py +++ b/tests/test_openai_responses_transport.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.platform.llm.transports.openai_responses import parse_openai_responses_stream_events +from svc.llm.transports.openai_responses import parse_openai_responses_stream_events def test_openai_responses_stream_parses_text_deltas_and_final_response_tool_calls() -> None: diff --git a/tests/test_openai_tools_schema_compat.py b/tests/test_openai_tools_schema_compat.py index 2a108442..9948f1b1 100644 --- a/tests/test_openai_tools_schema_compat.py +++ b/tests/test_openai_tools_schema_compat.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.platform.llm.tool_schema import complete_openai_tools_wire_parameters +from svc.llm.tool_schema import complete_openai_tools_wire_parameters def test_complete_tools_coerces_null_function_parameters_to_min_object_schema() -> None: diff --git a/tests/test_openai_tools_shrink.py b/tests/test_openai_tools_shrink.py index fdfdf0f5..23280ea9 100644 --- a/tests/test_openai_tools_shrink.py +++ b/tests/test_openai_tools_shrink.py @@ -3,7 +3,7 @@ from __future__ import annotations import json import unittest -from oclaw.platform.llm.chat_models import shrink_openai_tools_payload_for_api, _openai_tools_json_byte_length +from svc.llm.chat_models import shrink_openai_tools_payload_for_api, _openai_tools_json_byte_length class OpenAiToolsShrinkTests(unittest.TestCase): diff --git a/tests/test_ops_cli.py b/tests/test_ops_cli.py index b3b752c9..9d787059 100644 --- a/tests/test_ops_cli.py +++ b/tests/test_ops_cli.py @@ -2,7 +2,7 @@ from __future__ import annotations from pathlib import Path -import oclaw.runtime.operations.main as ops_main +import runtime.operations.main as ops_main def test_gateway_start_uses_fastapi_only(monkeypatch) -> None: @@ -12,7 +12,7 @@ def test_gateway_start_uses_fastapi_only(monkeypatch) -> None: called["ok"] = True return 0 - monkeypatch.setattr("oclaw.interfaces.http.fastapi_app.main", fake_fastapi_main) + monkeypatch.setattr("interfaces.http.fastapi_app.main", fake_fastapi_main) rc = ops_main(["gateway", "start", "--host", "127.0.0.1", "--port", "8799"]) assert rc == 0 assert called["ok"] is True diff --git a/tests/test_ops_netx_system_inject.py b/tests/test_ops_netx_system_inject.py index 987ec4eb..3bc1902a 100644 --- a/tests/test_ops_netx_system_inject.py +++ b/tests/test_ops_netx_system_inject.py @@ -4,13 +4,13 @@ from pathlib import Path import pytest -from oclaw.platform.llm.chat_models import RuleBasedChatModel -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.direct_loop import _build_model_context +from svc.llm.chat_models import RuleBasedChatModel +from svc.persistence.sqlite_store import SqliteStore +from runtime.direct_loop import _build_model_context def test_ops_role_injects_netx_batch_anchor_into_system(tmp_path: 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 def _fake_anchor() -> dict: return { @@ -61,7 +61,7 @@ def test_non_ops_role_skips_netx_inject(tmp_path: Path, monkeypatch: pytest.Monk calls["n"] += 1 return {"ok": True, "anchor": {}} - import oclaw.runtime.tools.experts.network_ops.netx_tools as nt + import runtime.tools.experts.network_ops.netx_tools as nt monkeypatch.setattr(nt, "_resolve_ume_anchor", _spy_anchor) diff --git a/tests/test_paths_db_migration.py b/tests/test_paths_db_migration.py index e1255677..3e6d0598 100644 --- a/tests/test_paths_db_migration.py +++ b/tests/test_paths_db_migration.py @@ -5,7 +5,7 @@ from __future__ import annotations from pathlib import Path from unittest.mock import patch -import oclaw.platform.config.paths as paths_mod +import svc.config.paths as paths_mod def _legacy_dir(tmp_path: Path) -> Path: diff --git a/tests/test_plan_agent_v2_gateway_cutover_draft.py b/tests/test_plan_agent_v2_gateway_cutover_draft.py index 276b8800..e84c5a90 100644 --- a/tests/test_plan_agent_v2_gateway_cutover_draft.py +++ b/tests/test_plan_agent_v2_gateway_cutover_draft.py @@ -2,9 +2,9 @@ from __future__ import annotations from pathlib import Path -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.plan_agent_v2_gateway_cutover import maybe_handle_expert_turn_v2_draft -from oclaw.runtime.types import StandardMessage +from svc.persistence.sqlite_store import SqliteStore +from runtime.plan_agent_v2_gateway_cutover import maybe_handle_expert_turn_v2_draft +from runtime.types import StandardMessage def _msg(text: str) -> StandardMessage: diff --git a/tests/test_plan_agent_v2_gateway_dryrun.py b/tests/test_plan_agent_v2_gateway_dryrun.py index 27051bf7..35b1faef 100644 --- a/tests/test_plan_agent_v2_gateway_dryrun.py +++ b/tests/test_plan_agent_v2_gateway_dryrun.py @@ -2,14 +2,14 @@ from __future__ import annotations from pathlib import Path -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.gateway import OclawGatewayResult -from oclaw.runtime.plan_agent_v2 import ( +from svc.persistence.sqlite_store import SqliteStore +from runtime.gateway import OclawGatewayResult +from runtime.plan_agent_v2 import ( build_shadow_gateway_result, evaluate_gateway_expert_turn_shadow, legacy_gateway_result_keys, ) -from oclaw.runtime.types import StandardMessage +from runtime.types import StandardMessage def _msg(text: str) -> StandardMessage: diff --git a/tests/test_plan_agent_v2_shadow.py b/tests/test_plan_agent_v2_shadow.py index cb92a2a6..a607cadd 100644 --- a/tests/test_plan_agent_v2_shadow.py +++ b/tests/test_plan_agent_v2_shadow.py @@ -2,22 +2,22 @@ from __future__ import annotations from pathlib import Path -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.plan_agent_v2_adapter import evaluate_for_expert_mode -from oclaw.runtime.plan_agent_v2_compat import build_shadow_gateway_result, legacy_gateway_result_keys -from oclaw.runtime.plan_agent_v2_gateway_adapter import evaluate_gateway_expert_turn_shadow -from oclaw.runtime.plan_agent_v2_manager import PlanModeManagerV2 -from oclaw.runtime.plan_agent_v2_models import PLAN_MODE_PLAN, PlanAgentStateV2 -from oclaw.runtime.plan_agent_v2_prompt_injector import build_plan_mode_prefix -from oclaw.runtime.plan_agent_v2_state_store import PlanAgentStateStoreV2 -from oclaw.runtime.plan_agent_v2_switch import should_route_to_v2, v2_feature_enabled -from oclaw.runtime.plan_agent_v2_tool_specs import materialize_plan_mode_v2_tools -from oclaw.runtime.plan_agent_v2_tool_policy import filter_tools_for_mode -from oclaw.runtime.plan_agent_v2_trace import emit_plan_agent_v2_trace -from oclaw.runtime.plan_agent_v2 import should_route_to_v2 as should_route_to_v2_pkg -from oclaw.runtime.gateway import OclawGatewayResult -from oclaw.runtime.tools.base import ToolRegistry, ToolSpec -from oclaw.runtime.types import StandardMessage +from svc.persistence.sqlite_store import SqliteStore +from runtime.plan_agent_v2_adapter import evaluate_for_expert_mode +from runtime.plan_agent_v2_compat import build_shadow_gateway_result, legacy_gateway_result_keys +from runtime.plan_agent_v2_gateway_adapter import evaluate_gateway_expert_turn_shadow +from runtime.plan_agent_v2_manager import PlanModeManagerV2 +from runtime.plan_agent_v2_models import PLAN_MODE_PLAN, PlanAgentStateV2 +from runtime.plan_agent_v2_prompt_injector import build_plan_mode_prefix +from runtime.plan_agent_v2_state_store import PlanAgentStateStoreV2 +from runtime.plan_agent_v2_switch import should_route_to_v2, v2_feature_enabled +from runtime.plan_agent_v2_tool_specs import materialize_plan_mode_v2_tools +from runtime.plan_agent_v2_tool_policy import filter_tools_for_mode +from runtime.plan_agent_v2_trace import emit_plan_agent_v2_trace +from runtime.plan_agent_v2 import should_route_to_v2 as should_route_to_v2_pkg +from runtime.gateway import OclawGatewayResult +from runtime.tools.base import ToolRegistry, ToolSpec +from runtime.types import StandardMessage def _dummy_tool(name: str, read_only: bool) -> ToolSpec: @@ -429,7 +429,7 @@ def test_shadow_gateway_result_defaults_align_legacy_baseline(tmp_path: Path) -> def test_package_exports_stable_symbols() -> None: - import oclaw.runtime.plan_agent_v2 as p + import runtime.plan_agent_v2 as p required = [ "PlanAgentStateV2", diff --git a/tests/test_prompt_ci_guard.py b/tests/test_prompt_ci_guard.py index 1e1861b0..576c4688 100644 --- a/tests/test_prompt_ci_guard.py +++ b/tests/test_prompt_ci_guard.py @@ -2,7 +2,7 @@ from __future__ import annotations from pathlib import Path -from oclaw.platform.config.paths import PROJECT_ROOT +from svc.config.paths import PROJECT_ROOT _PROMPT_CRITICAL_FILES = ( @@ -13,8 +13,8 @@ _PROMPT_CRITICAL_FILES = ( "runtime/memory_stage.py", "runtime/project_context_prompt.py", "runtime/chat/agent_errors.py", - "platform/llm/image_ocr_client.py", - "platform/llm/image_legacy_client.py", + "svc/llm/image_ocr_client.py", + "svc/llm/image_legacy_client.py", "runtime/gateway.py", ) @@ -27,7 +27,7 @@ def test_prompt_critical_paths_use_prompt_templates() -> None: or "render_prompt_for_lang(" in text or "render_runtime_prompt(" in text ), ( - f"{rel} must use oclaw.runtime.prompt_templates (Markdown under runtime/workspaces/_system)" + f"{rel} must use runtime.prompt_templates (Markdown under runtime/workspaces/_system)" ) diff --git a/tests/test_prompt_hardcode_guard.py b/tests/test_prompt_hardcode_guard.py index ebbc6389..d46ea961 100644 --- a/tests/test_prompt_hardcode_guard.py +++ b/tests/test_prompt_hardcode_guard.py @@ -2,7 +2,7 @@ from __future__ import annotations from pathlib import Path -from oclaw.platform.config.paths import PROJECT_ROOT +from svc.config.paths import PROJECT_ROOT def _read(rel: str) -> str: diff --git a/tests/test_prompt_loader.py b/tests/test_prompt_loader.py index 1c2dc12b..23bdadec 100644 --- a/tests/test_prompt_loader.py +++ b/tests/test_prompt_loader.py @@ -2,7 +2,7 @@ from __future__ import annotations import pytest -from oclaw.runtime.prompt_templates import ( +from runtime.prompt_templates import ( load_prompt_doc, load_runtime_prompt_doc, render_prompt, diff --git a/tests/test_prompt_prebuild.py b/tests/test_prompt_prebuild.py index 89897126..9ed1d48c 100644 --- a/tests/test_prompt_prebuild.py +++ b/tests/test_prompt_prebuild.py @@ -2,7 +2,7 @@ from __future__ import annotations from typing import Any -from oclaw.runtime import prompt_prebuild as pp +from runtime import prompt_prebuild as pp class _DummyStore: diff --git a/tests/test_prompt_runtime_paths.py b/tests/test_prompt_runtime_paths.py index 4d609d55..c4ccc31e 100644 --- a/tests/test_prompt_runtime_paths.py +++ b/tests/test_prompt_runtime_paths.py @@ -1,8 +1,8 @@ from __future__ import annotations -from oclaw.runtime.memory_stage import render_memory_context_block -from oclaw.runtime.types import OclawMemoryContext -from oclaw.runtime.prompt_templates import render_runtime_prompt +from runtime.memory_stage import render_memory_context_block +from runtime.types import OclawMemoryContext +from runtime.prompt_templates import render_runtime_prompt def test_router_prompt_renders() -> None: diff --git a/tests/test_replay_tool_call_id.py b/tests/test_replay_tool_call_id.py index 089fb58f..3139cf07 100644 --- a/tests/test_replay_tool_call_id.py +++ b/tests/test_replay_tool_call_id.py @@ -1,9 +1,9 @@ -"""Regression tests for Oclaw-style tool_call_id replay (see src/platform/llm/tool_call_id.py).""" +"""Regression tests for Oclaw-style tool_call_id replay (see svc/llm/tool_call_id.py).""" from __future__ import annotations -from oclaw.platform.llm.replay_policy import apply_replay_policy_to_messages, resolve_replay_policy -from oclaw.platform.llm.tool_call_id import repair_orphan_tool_messages, rewrite_openai_chat_messages_tool_ids +from svc.llm.replay_policy import apply_replay_policy_to_messages, resolve_replay_policy +from svc.llm.tool_call_id import repair_orphan_tool_messages, rewrite_openai_chat_messages_tool_ids def test_rewrite_pairs_assistant_and_tool_ids() -> None: diff --git a/tests/test_runtime_prewarm_api.py b/tests/test_runtime_prewarm_api.py index 59a4e788..77fb7caa 100644 --- a/tests/test_runtime_prewarm_api.py +++ b/tests/test_runtime_prewarm_api.py @@ -3,7 +3,7 @@ from __future__ import annotations from fastapi import FastAPI from fastapi.testclient import TestClient -from oclaw.interfaces.admin import routes as routes_mod +from interfaces.admin import routes as routes_mod def test_runtime_prewarm_routes_registered_and_guarded() -> None: diff --git a/tests/test_runtime_streaming_contract.py b/tests/test_runtime_streaming_contract.py index 90bf554f..96a972cc 100644 --- a/tests/test_runtime_streaming_contract.py +++ b/tests/test_runtime_streaming_contract.py @@ -2,10 +2,10 @@ from __future__ import annotations from pathlib import Path -from oclaw.runtime.direct_loop import run_oclaw_direct_loop -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.tools.base import ToolRegistry, ToolSpec -from oclaw.platform.llm.transports.base import LLMResponse, LLMToolCall +from runtime.direct_loop import run_oclaw_direct_loop +from svc.persistence.sqlite_store import SqliteStore +from runtime.tools.base import ToolRegistry, ToolSpec +from svc.llm.transports.base import LLMResponse, LLMToolCall class _TwoChunkModel: diff --git a/tests/test_secret_migration.py b/tests/test_secret_migration.py index 86830e8b..239df27b 100644 --- a/tests/test_secret_migration.py +++ b/tests/test_secret_migration.py @@ -7,7 +7,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 SecretMigrationTests(unittest.TestCase): diff --git a/tests/test_session_auto_title.py b/tests/test_session_auto_title.py index 29f722ad..b144c463 100644 --- a/tests/test_session_auto_title.py +++ b/tests/test_session_auto_title.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.runtime.session_auto_title import AUTO_TITLE_CHAR_MAX, finalize_auto_title, should_reject_auto_title +from runtime.session_auto_title import AUTO_TITLE_CHAR_MAX, finalize_auto_title, should_reject_auto_title def test_should_reject_long_prose() -> None: diff --git a/tests/test_session_context_diagnostics.py b/tests/test_session_context_diagnostics.py index 9368ed9b..5a700b1b 100644 --- a/tests/test_session_context_diagnostics.py +++ b/tests/test_session_context_diagnostics.py @@ -1,7 +1,7 @@ from __future__ import annotations -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.chat.session_context_diagnostics import compute_session_context_stats +from svc.persistence.sqlite_store import SqliteStore +from runtime.chat.session_context_diagnostics import compute_session_context_stats def test_compute_session_context_stats_detects_empty_assistant(tmp_path) -> None: # noqa: ANN001 diff --git a/tests/test_session_delete_cascade.py b/tests/test_session_delete_cascade.py index 7d394717..4f2f20bd 100644 --- a/tests/test_session_delete_cascade.py +++ b/tests/test_session_delete_cascade.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.persistence.sqlite_store import SqliteStore def test_delete_session_cascades_chat_message_and_tool_log(tmp_path) -> None: # noqa: ANN001 diff --git a/tests/test_session_orphan_prune.py b/tests/test_session_orphan_prune.py index bd8fc4d2..79d12a11 100644 --- a/tests/test_session_orphan_prune.py +++ b/tests/test_session_orphan_prune.py @@ -7,7 +7,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 SessionOrphanPruneTests(unittest.TestCase): diff --git a/tests/test_skill_executor_trace.py b/tests/test_skill_executor_trace.py index f6cfa4cc..a73c64f7 100644 --- a/tests/test_skill_executor_trace.py +++ b/tests/test_skill_executor_trace.py @@ -2,9 +2,9 @@ from __future__ import annotations from types import SimpleNamespace -from oclaw.runtime import skill_executor as skill_executor_mod -from oclaw.runtime.skill_executor import SkillExecutionContext, SkillExecutor -from oclaw.runtime.tools.base import ToolRegistry, ToolSpec +from runtime import skill_executor as skill_executor_mod +from runtime.skill_executor import SkillExecutionContext, SkillExecutor +from runtime.tools.base import ToolRegistry, ToolSpec class _DummyStore: diff --git a/tests/test_skill_installer.py b/tests/test_skill_installer.py index 6711bc18..c4ff0453 100644 --- a/tests/test_skill_installer.py +++ b/tests/test_skill_installer.py @@ -4,7 +4,7 @@ from pathlib import Path import zipfile import subprocess -from oclaw.runtime.skill_installer import ( +from runtime.skill_installer import ( auto_install_skill_from_payload, create_skill_from_template, install_skill_from_local_dir, @@ -13,7 +13,7 @@ from oclaw.runtime.skill_installer import ( repair_skill_dependencies, set_skill_enabled, ) -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.persistence.sqlite_store import SqliteStore def test_create_list_and_disable_skill(tmp_path: Path) -> None: @@ -173,7 +173,7 @@ def test_install_skill_from_clawhub_page_url(tmp_path: Path, monkeypatch) -> Non captured["slug"] = slug return {"archiveUrl": archive.resolve().as_uri()} - monkeypatch.setattr("oclaw.runtime.tools.skills.clawhub_client.get_skill_detail", _mock_get_detail) + monkeypatch.setattr("runtime.tools.skills.clawhub_client.get_skill_detail", _mock_get_detail) out = install_skill_from_registry_archive( store=store, @@ -218,7 +218,7 @@ def test_install_local_auto_installs_python_requirements(tmp_path: Path, monkeyp calls.append([str(x) for x in cmd]) return subprocess.CompletedProcess(args=cmd, returncode=0, stdout="", stderr="") - monkeypatch.setattr("oclaw.runtime.skill_installer.subprocess.run", _mock_run) + monkeypatch.setattr("runtime.skill_installer.subprocess.run", _mock_run) out = install_skill_from_local_dir(store=store, source_dir=src, skills_root=tmp_path / "skills") assert out.ok assert any(("pip" in " ".join(c) and "-r" in c) for c in calls) @@ -238,7 +238,7 @@ def test_install_local_dependency_install_failure_returns_warning(tmp_path: Path def _mock_run(cmd, **kwargs): # noqa: ANN001,ARG001 return subprocess.CompletedProcess(args=cmd, returncode=1, stdout="", stderr="install failed") - monkeypatch.setattr("oclaw.runtime.skill_installer.subprocess.run", _mock_run) + monkeypatch.setattr("runtime.skill_installer.subprocess.run", _mock_run) out = install_skill_from_local_dir(store=store, source_dir=src, skills_root=tmp_path / "skills") assert out.ok assert out.detail.startswith("installed_with_dependency_warnings:") @@ -267,7 +267,7 @@ def test_install_local_probe_missing_imports_and_install(tmp_path: Path, monkeyp calls.append([str(x) for x in cmd]) return subprocess.CompletedProcess(args=cmd, returncode=0, stdout="", stderr="") - monkeypatch.setattr("oclaw.runtime.skill_installer.subprocess.run", _mock_run) + monkeypatch.setattr("runtime.skill_installer.subprocess.run", _mock_run) out = install_skill_from_local_dir(store=store, source_dir=src, skills_root=tmp_path / "skills") assert out.ok pip_calls = [c for c in calls if ("pip" in " ".join(c))] @@ -292,7 +292,7 @@ def test_repair_skill_dependencies_for_installed_skill(tmp_path: Path, monkeypat calls.append([str(x) for x in cmd]) return subprocess.CompletedProcess(args=cmd, returncode=0, stdout="", stderr="") - monkeypatch.setattr("oclaw.runtime.skill_installer.subprocess.run", _mock_run) + monkeypatch.setattr("runtime.skill_installer.subprocess.run", _mock_run) out = install_skill_from_local_dir(store=store, source_dir=src, skills_root=tmp_path / "skills") assert out.ok calls.clear() diff --git a/tests/test_skill_role_binding_catalog.py b/tests/test_skill_role_binding_catalog.py index ea0ae9f1..a42f271c 100644 --- a/tests/test_skill_role_binding_catalog.py +++ b/tests/test_skill_role_binding_catalog.py @@ -3,7 +3,7 @@ from __future__ import annotations import json from pathlib import Path -from oclaw.runtime.skill_role_binding import ( +from runtime.skill_role_binding import ( SKILL_ROLE_BINDING_ENABLED_SETTING, SKILL_ROLE_BINDING_KEY, normalize_skill_role_binding, @@ -12,10 +12,10 @@ from oclaw.runtime.skill_role_binding import ( skill_role_binding_enabled_env_present, skill_role_binding_enabled_stored, ) -from oclaw.runtime.skills_prompt import collect_skill_catalog_entries -from oclaw.runtime.skills_workspace_lane import skill_dir_private_lane_segment -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.tools.catalog import default_registry +from runtime.skills_prompt import collect_skill_catalog_entries +from runtime.skills_workspace_lane import skill_dir_private_lane_segment +from svc.persistence.sqlite_store import SqliteStore +from runtime.tools.catalog import default_registry def _write_skill(root: Path, name: str) -> None: diff --git a/tests/test_skill_runtime_metadata_and_tools.py b/tests/test_skill_runtime_metadata_and_tools.py index 0cccb985..eac2cec7 100644 --- a/tests/test_skill_runtime_metadata_and_tools.py +++ b/tests/test_skill_runtime_metadata_and_tools.py @@ -5,8 +5,8 @@ import tempfile import unittest from pathlib import Path -from oclaw.runtime.skills import discover_workspace_skill_manifests -from oclaw.runtime.tools.skills_runtime.materialize_skill_tools import materialize_executable_skill_tools +from runtime.skills import discover_workspace_skill_manifests +from runtime.tools.skills_runtime.materialize_skill_tools import materialize_executable_skill_tools class SkillRuntimeMetadataAndToolsTests(unittest.TestCase): diff --git a/tests/test_skill_runtime_restricted_fs_permissions.py b/tests/test_skill_runtime_restricted_fs_permissions.py index 4ad447ac..1eeaae2c 100644 --- a/tests/test_skill_runtime_restricted_fs_permissions.py +++ b/tests/test_skill_runtime_restricted_fs_permissions.py @@ -5,7 +5,7 @@ import tempfile import unittest from pathlib import Path -from oclaw.runtime.tools.skills_runtime.subprocess_exec import run_skill_runtime_entry +from runtime.tools.skills_runtime.subprocess_exec import run_skill_runtime_entry class SkillRuntimeRestrictedFsPermissionTests(unittest.TestCase): diff --git a/tests/test_skills_install_public_tool_visibility.py b/tests/test_skills_install_public_tool_visibility.py index de0b5c47..3aee1fbf 100644 --- a/tests/test_skills_install_public_tool_visibility.py +++ b/tests/test_skills_install_public_tool_visibility.py @@ -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_skill_install_public_tools_hidden_for_specialist_auto_only() -> None: diff --git a/tests/test_skills_install_tool_workspace_root.py b/tests/test_skills_install_tool_workspace_root.py index 394e2da3..c8de6023 100644 --- a/tests/test_skills_install_tool_workspace_root.py +++ b/tests/test_skills_install_tool_workspace_root.py @@ -2,7 +2,7 @@ from __future__ import annotations from pathlib import Path -from oclaw.runtime.tools.public.skills_install_tool import skill_market_install_tool, skill_registry_install_tool +from runtime.tools.public.skills_install_tool import skill_market_install_tool, skill_registry_install_tool def test_skill_registry_install_tool_forces_workspace_root(monkeypatch, tmp_path: Path) -> None: @@ -24,8 +24,8 @@ def test_skill_registry_install_tool_forces_workspace_root(monkeypatch, tmp_path return _Out() - monkeypatch.setattr("oclaw.runtime.tools.public.skills_install_tool.default_skills_root", _mock_default_root) - monkeypatch.setattr("oclaw.runtime.tools.public.skills_install_tool.install_skill_from_registry_archive", _mock_install) + monkeypatch.setattr("runtime.tools.public.skills_install_tool.default_skills_root", _mock_default_root) + monkeypatch.setattr("runtime.tools.public.skills_install_tool.install_skill_from_registry_archive", _mock_install) tool = skill_registry_install_tool() result = tool.handler({"archive_url": "https://example.com/demo.zip"}) assert bool(result.get("ok")) is True @@ -70,10 +70,10 @@ def test_skill_market_install_tool_provider_arg_overrides_setting(monkeypatch, t return _Out() - monkeypatch.setattr("oclaw.runtime.tools.public.skills_install_tool._store", _mock_store) - monkeypatch.setattr("oclaw.runtime.tools.public.skills_install_tool.default_skills_root", _mock_default_root) - monkeypatch.setattr("oclaw.runtime.tools.public.skills_install_tool.get_market_adapter", _mock_get_market_adapter) - monkeypatch.setattr("oclaw.runtime.tools.public.skills_install_tool.install_skill_from_registry_archive", _mock_install) + monkeypatch.setattr("runtime.tools.public.skills_install_tool._store", _mock_store) + monkeypatch.setattr("runtime.tools.public.skills_install_tool.default_skills_root", _mock_default_root) + monkeypatch.setattr("runtime.tools.public.skills_install_tool.get_market_adapter", _mock_get_market_adapter) + monkeypatch.setattr("runtime.tools.public.skills_install_tool.install_skill_from_registry_archive", _mock_install) tool = skill_market_install_tool() result = tool.handler({"slug": "demo", "provider": "cocoloop", "version": "latest"}) diff --git a/tests/test_skills_market_providers.py b/tests/test_skills_market_providers.py index 94ece27c..ad72d6af 100644 --- a/tests/test_skills_market_providers.py +++ b/tests/test_skills_market_providers.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.runtime import skills_market +from runtime import skills_market def test_get_market_adapter_clawhub_default() -> None: @@ -28,7 +28,7 @@ def test_cocoloop_resolve_archive_url(monkeypatch) -> None: "versions": [{"version": "1.0.0", "archiveUrl": "https://dl.example/bss/skills/demo.zip"}], } - monkeypatch.setattr("oclaw.runtime.skills_market.cocoloop_get_skill_detail", _fake_detail) + monkeypatch.setattr("runtime.skills_market.cocoloop_get_skill_detail", _fake_detail) a = skills_market.CocoloopMarketAdapter() url, ver = a.resolve_archive_url(slug="demo", version=None) assert url.endswith("demo.zip") diff --git a/tests/test_skills_prompt.py b/tests/test_skills_prompt.py index ddb5f98b..a116255f 100644 --- a/tests/test_skills_prompt.py +++ b/tests/test_skills_prompt.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.runtime.skills_prompt import format_skills_for_prompt +from runtime.skills_prompt import format_skills_for_prompt def test_format_skills_for_prompt_line_shape() -> None: diff --git a/tests/test_specialists_registry.py b/tests/test_specialists_registry.py index e7aedaa8..df0277f7 100644 --- a/tests/test_specialists_registry.py +++ b/tests/test_specialists_registry.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.runtime.agents import specialists as specialists_mod +from runtime.agents import specialists as specialists_mod def test_unknown_dynamic_specialist_defaults_to_minimum_expert_permissions(monkeypatch) -> None: diff --git a/tests/test_tool_batch_partition.py b/tests/test_tool_batch_partition.py index 908d18ad..2df5c096 100644 --- a/tests/test_tool_batch_partition.py +++ b/tests/test_tool_batch_partition.py @@ -1,8 +1,8 @@ from __future__ import annotations -from oclaw.runtime.chat.tool_runtime import partition_tool_use_batches -from oclaw.platform.llm.chat_models import LLMToolCall -from oclaw.runtime.tools.base import ToolRegistry, ToolSpec +from runtime.chat.tool_runtime import partition_tool_use_batches +from svc.llm.chat_models import LLMToolCall +from runtime.tools.base import ToolRegistry, ToolSpec def _spec(name: str, *, read_only: bool) -> ToolSpec: diff --git a/tests/test_tool_llm_truncation.py b/tests/test_tool_llm_truncation.py index 806f9676..370770a5 100644 --- a/tests/test_tool_llm_truncation.py +++ b/tests/test_tool_llm_truncation.py @@ -3,12 +3,12 @@ from __future__ import annotations import json import unittest -from oclaw.runtime.chat.tool_runtime import ( +from runtime.chat.tool_runtime import ( compact_turn_tool_messages_for_storage, tool_llm_message_max_chars, truncate_tool_result_for_llm_messages, ) -from oclaw.platform.persistence.sqlite_store import SqliteStore +from svc.persistence.sqlite_store import SqliteStore class ToolLlmTruncationTests(unittest.TestCase): diff --git a/tests/test_tool_loop_guard.py b/tests/test_tool_loop_guard.py index ae2370d0..cc6008e1 100644 --- a/tests/test_tool_loop_guard.py +++ b/tests/test_tool_loop_guard.py @@ -4,10 +4,10 @@ import base64 import json from pathlib import Path -from oclaw.runtime.chat.tool_runtime import ToolExecutionContext, ToolExecutor -from oclaw.platform.llm.chat_models import LLMToolCall -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.runtime.tools.base import ToolRegistry, ToolSpec +from runtime.chat.tool_runtime import ToolExecutionContext, ToolExecutor +from svc.llm.chat_models import LLMToolCall +from svc.persistence.sqlite_store import SqliteStore +from runtime.tools.base import ToolRegistry, ToolSpec def test_tool_loop_guard_blocks_repeated_signature(tmp_path: Path) -> None: diff --git a/tests/test_tool_pairing_messages.py b/tests/test_tool_pairing_messages.py index 3a18c3c5..5406c090 100644 --- a/tests/test_tool_pairing_messages.py +++ b/tests/test_tool_pairing_messages.py @@ -2,8 +2,8 @@ from __future__ import annotations import json -from oclaw.runtime.chat.agent_messages import build_llm_messages -from oclaw.platform.llm.chat_models import RuleBasedChatModel +from runtime.chat.agent_messages import build_llm_messages +from svc.llm.chat_models import RuleBasedChatModel class _Msg: diff --git a/tests/test_tool_runtime_attachments.py b/tests/test_tool_runtime_attachments.py index 140c0a33..56f3a7dd 100644 --- a/tests/test_tool_runtime_attachments.py +++ b/tests/test_tool_runtime_attachments.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.runtime.chat.tool_runtime import _attachments_from_tool_result +from runtime.chat.tool_runtime import _attachments_from_tool_result def test_attachments_from_tool_result_preserves_non_image_ref_types() -> None: diff --git a/tests/test_tool_wire_freeze_switch.py b/tests/test_tool_wire_freeze_switch.py index 60331666..43b67603 100644 --- a/tests/test_tool_wire_freeze_switch.py +++ b/tests/test_tool_wire_freeze_switch.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.runtime import direct_loop as dl +from runtime import direct_loop as dl class _DummyStore: diff --git a/tests/test_tool_wire_policy.py b/tests/test_tool_wire_policy.py index c4ecd169..1c598236 100644 --- a/tests/test_tool_wire_policy.py +++ b/tests/test_tool_wire_policy.py @@ -5,7 +5,7 @@ import unittest from datetime import datetime, timedelta, timezone from unittest.mock import patch -from oclaw.platform.llm.tool_wire_policy import ( +from svc.llm.tool_wire_policy import ( SETTINGS_KEY_PENALTY_STATE, migrate_legacy_penalty_store, prepare_openai_tools_for_llm_api, @@ -71,7 +71,7 @@ class ToolWirePolicyTests(unittest.TestCase): } tools = [_fn("read_file"), _fn("mcp__rank__1"), _fn("mcp__rank__2"), _fn("mcp__rank__3"), _fn("mcp__srv__x")] st = FakeToolStore(usage) - with patch("oclaw.platform.llm.tool_wire_policy._utc_now", return_value=datetime(2026, 1, 5, 12, 0, 0, tzinfo=timezone.utc)): + with patch("svc.llm.tool_wire_policy._utc_now", return_value=datetime(2026, 1, 5, 12, 0, 0, tzinfo=timezone.utc)): with patch.dict("os.environ", {"OPS_MCP_WIRE_TOP_N_FULL": "3"}, clear=False): out = prepare_openai_tools_for_llm_api( tools, @@ -94,7 +94,7 @@ class ToolWirePolicyTests(unittest.TestCase): tools = [_fn("mcp__p__a"), _fn("mcp__p__b"), _fn("mcp__p__c"), _fn("mcp__p__d")] st = FakeToolStore(usage) fixed = datetime(2026, 1, 5, 12, 0, 0, tzinfo=timezone.utc) - with patch("oclaw.platform.llm.tool_wire_policy._utc_now", return_value=fixed): + with patch("svc.llm.tool_wire_policy._utc_now", return_value=fixed): with patch.dict( "os.environ", { @@ -144,7 +144,7 @@ class ToolWirePolicyTests(unittest.TestCase): {"OPS_MCP_WIRE_STALE_HOURS": "3", "OPS_MCP_WIRE_TOP_N_FULL": "3"}, clear=False, ): - with patch("oclaw.platform.llm.tool_wire_policy._utc_now", return_value=t0): + with patch("svc.llm.tool_wire_policy._utc_now", return_value=t0): out1 = prepare_openai_tools_for_llm_api( tools, base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", @@ -157,7 +157,7 @@ class ToolWirePolicyTests(unittest.TestCase): self.assertEqual(pen["mcp__st__old"]["phase"], "active") t_late = t0 + timedelta(minutes=31) - with patch("oclaw.platform.llm.tool_wire_policy._utc_now", return_value=t_late): + with patch("svc.llm.tool_wire_policy._utc_now", return_value=t_late): out2 = prepare_openai_tools_for_llm_api( tools, base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", @@ -186,7 +186,7 @@ class ToolWirePolicyTests(unittest.TestCase): {"OPS_MCP_WIRE_STALE_HOURS": "3", "OPS_MCP_WIRE_TOP_N_FULL": "3"}, clear=False, ): - with patch("oclaw.platform.llm.tool_wire_policy._utc_now", return_value=t0): + with patch("svc.llm.tool_wire_policy._utc_now", return_value=t0): out = prepare_openai_tools_for_llm_api( tools, base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", diff --git a/tests/test_tool_wire_policy_role_scoped.py b/tests/test_tool_wire_policy_role_scoped.py index e751fa47..262112b9 100644 --- a/tests/test_tool_wire_policy_role_scoped.py +++ b/tests/test_tool_wire_policy_role_scoped.py @@ -2,8 +2,8 @@ from __future__ import annotations from pathlib import Path -from oclaw.platform.persistence.sqlite_store import SqliteStore -from oclaw.platform.llm.tool_wire_policy import prepare_openai_tools_for_llm_api +from svc.persistence.sqlite_store import SqliteStore +from svc.llm.tool_wire_policy import prepare_openai_tools_for_llm_api def test_manager_role_respects_permanent_ban_by_default(tmp_path: Path) -> None: diff --git a/tests/test_video_generation_client.py b/tests/test_video_generation_client.py index 4160aeef..8f6237c0 100644 --- a/tests/test_video_generation_client.py +++ b/tests/test_video_generation_client.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import Any from unittest.mock import MagicMock, patch -from oclaw.platform.llm.video_generation_client import ( +from svc.llm.video_generation_client import ( _effective_video_model_for_request, _i2v_first_frame_input_style, dashscope_api_root_from_base_url, @@ -57,12 +57,12 @@ def test_send_video_generation_poll_succeeds() -> None: clients.append(inst) return inst - with patch("oclaw.platform.llm.video_generation_client.httpx.Client", side_effect=_client_factory): + with patch("svc.llm.video_generation_client.httpx.Client", side_effect=_client_factory): with patch( - "oclaw.platform.llm.video_generation_client.post_with_retry", + "svc.llm.video_generation_client.post_with_retry", return_value=post_resp, ): - with patch("oclaw.platform.llm.video_generation_client.time.sleep"): + with patch("svc.llm.video_generation_client.time.sleep"): r = send_video_generation_request( prompt="cat", model="wan2.2-t2v-plus", @@ -135,8 +135,8 @@ def test_send_video_coerces_payload_model_when_t2v_plus_img(monkeypatch) -> None captured.update(p) return post_resp - with patch("oclaw.platform.llm.video_generation_client.httpx.Client", return_value=inst): - with patch("oclaw.platform.llm.video_generation_client.post_with_retry", side_effect=_capture_post): + with patch("svc.llm.video_generation_client.httpx.Client", return_value=inst): + with patch("svc.llm.video_generation_client.post_with_retry", side_effect=_capture_post): r = send_video_generation_request( prompt="motion", model="wan2.6-t2v-flash", @@ -170,8 +170,8 @@ def test_send_video_includes_img_url_in_payload() -> None: captured.update(p) return post_resp - with patch("oclaw.platform.llm.video_generation_client.httpx.Client", return_value=inst): - with patch("oclaw.platform.llm.video_generation_client.post_with_retry", side_effect=_capture_post): + with patch("svc.llm.video_generation_client.httpx.Client", return_value=inst): + with patch("svc.llm.video_generation_client.post_with_retry", side_effect=_capture_post): r = send_video_generation_request( prompt="motion", model="wan2.6-i2v-flash", @@ -210,8 +210,8 @@ def test_send_video_wan27_uses_media_first_frame(monkeypatch) -> None: return post_resp u = "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250925/wpimhv/rap.png" - with patch("oclaw.platform.llm.video_generation_client.httpx.Client", return_value=inst): - with patch("oclaw.platform.llm.video_generation_client.post_with_retry", side_effect=_capture_post): + with patch("svc.llm.video_generation_client.httpx.Client", return_value=inst): + with patch("svc.llm.video_generation_client.post_with_retry", side_effect=_capture_post): r = send_video_generation_request( prompt="你好", model="wan2.7-i2v", @@ -242,9 +242,9 @@ def test_send_immediate_succeeded_on_submit() -> None: inst = MagicMock() inst.__enter__ = lambda *_x: inst inst.__exit__ = lambda *_x: None - with patch("oclaw.platform.llm.video_generation_client.httpx.Client", return_value=inst): + with patch("svc.llm.video_generation_client.httpx.Client", return_value=inst): with patch( - "oclaw.platform.llm.video_generation_client.post_with_retry", + "svc.llm.video_generation_client.post_with_retry", return_value=post_resp, ): r = send_video_generation_request( diff --git a/tests/test_video_query_tool.py b/tests/test_video_query_tool.py index 034562ba..e3817e68 100644 --- a/tests/test_video_query_tool.py +++ b/tests/test_video_query_tool.py @@ -1,6 +1,6 @@ from __future__ import annotations -import oclaw.runtime.tools.public.query_video_attachment_tool as vq +import runtime.tools.public.query_video_attachment_tool as vq def test_normalized_video_meta_extracts_top_level_fields() -> None: diff --git a/tests/test_web_fetch_clean_tool.py b/tests/test_web_fetch_clean_tool.py index fb44a5b7..5d0f23b2 100644 --- a/tests/test_web_fetch_clean_tool.py +++ b/tests/test_web_fetch_clean_tool.py @@ -1,6 +1,6 @@ from __future__ import annotations -from oclaw.runtime.tools.public.web_fetch_clean_tool import web_fetch_clean_tool +from runtime.tools.public.web_fetch_clean_tool import web_fetch_clean_tool class _Resp: diff --git a/tests/test_web_search_fast_tool.py b/tests/test_web_search_fast_tool.py index fe494dba..fc4a0191 100644 --- a/tests/test_web_search_fast_tool.py +++ b/tests/test_web_search_fast_tool.py @@ -2,8 +2,8 @@ from __future__ import annotations import json -from oclaw.platform.config.runtime_paths import runtime_skills_root -from oclaw.runtime.tools.public.web_search_fast_tool import _ENGINE_URLS, _normalize_engine_name, web_search_fast_tool +from svc.config.runtime_paths import runtime_skills_root +from runtime.tools.public.web_search_fast_tool import _ENGINE_URLS, _normalize_engine_name, web_search_fast_tool class _Resp: diff --git a/tests/test_wecom_longconn_outbound_drain.py b/tests/test_wecom_longconn_outbound_drain.py index 3d1b127b..7b83c923 100644 --- a/tests/test_wecom_longconn_outbound_drain.py +++ b/tests/test_wecom_longconn_outbound_drain.py @@ -11,7 +11,7 @@ import pytest def test_wecom_longconn_drains_outbound_on_idle_timeout(monkeypatch: pytest.MonkeyPatch) -> None: # Import module under test. - import oclaw.interfaces.channels.wecom.longconn_runner as m + import interfaces.channels.wecom.longconn_runner as m # Build a fake websocket that raises timeout once, then exits by raising KeyboardInterrupt. class _TimeoutOnceWs: diff --git a/tests/test_weixin_ilink_api.py b/tests/test_weixin_ilink_api.py index 683af49e..e17fb9e7 100644 --- a/tests/test_weixin_ilink_api.py +++ b/tests/test_weixin_ilink_api.py @@ -4,8 +4,8 @@ import unittest from fastapi.testclient import TestClient -from oclaw.interfaces.http.fastapi_app import create_app -from oclaw.interfaces.http import weixin_ilink_api +from interfaces.http.fastapi_app import create_app +from interfaces.http import weixin_ilink_api class WeixinIlinkApiTests(unittest.TestCase): diff --git a/tests/test_whatsapp_inbound_payload_shape.py b/tests/test_whatsapp_inbound_payload_shape.py index 141e41e4..ca1be680 100644 --- a/tests/test_whatsapp_inbound_payload_shape.py +++ b/tests/test_whatsapp_inbound_payload_shape.py @@ -2,8 +2,8 @@ from __future__ import annotations from fastapi.testclient import TestClient -from oclaw.interfaces.http.fastapi_app import create_app -from oclaw.interfaces.http import fastapi_app +from interfaces.http.fastapi_app import create_app +from interfaces.http import fastapi_app def test_inbound_whatsapp_accepts_basic_payload_and_returns_replies() -> None: diff --git a/tests/test_wiki_worker_pipeline.py b/tests/test_wiki_worker_pipeline.py index cfa4516a..32a42463 100644 --- a/tests/test_wiki_worker_pipeline.py +++ b/tests/test_wiki_worker_pipeline.py @@ -3,8 +3,8 @@ from __future__ import annotations import json from pathlib import Path -from oclaw.platform.persistence.sqlite_store import OclawTask -from oclaw.runtime.workers.wiki.main import _capture_after_turn, _dedup_merge, _process_task +from svc.persistence.sqlite_store import OclawTask +from runtime.workers.wiki.main import _capture_after_turn, _dedup_merge, _process_task def _task(task_id: str = "t1") -> OclawTask: diff --git a/tests/test_workspace_path_guard.py b/tests/test_workspace_path_guard.py index ff47d0a4..837577e2 100644 --- a/tests/test_workspace_path_guard.py +++ b/tests/test_workspace_path_guard.py @@ -9,12 +9,12 @@ from unittest import mock 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 oclaw.runtime.tools.public.glob_tool import glob_tool -from oclaw.runtime.tools.public.write_file_tool import write_file_tool -from oclaw.runtime.tools.path_guard import ( +from interfaces.http.fastapi_app import create_app +from svc.config.paths import db_path +from svc.persistence.sqlite_store import SqliteStore +from runtime.tools.public.glob_tool import glob_tool +from runtime.tools.public.write_file_tool import write_file_tool +from runtime.tools.path_guard import ( access_from_env, build_workspace_path_access, clear_workspace_path_access_for_tests, diff --git a/tests/test_workspaces_experts.py b/tests/test_workspaces_experts.py index 344dfe57..f4092fb8 100644 --- a/tests/test_workspaces_experts.py +++ b/tests/test_workspaces_experts.py @@ -4,8 +4,8 @@ from pathlib import Path import pytest -from oclaw.runtime.workspaces import experts as experts_mod -from oclaw.runtime.agents.specialists import discover_specialist_ids +from runtime.workspaces import experts as experts_mod +from runtime.agents.specialists import discover_specialist_ids def _set_project_root(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None: diff --git a/tests/test_workspaces_prompt_contract.py b/tests/test_workspaces_prompt_contract.py index 2418f797..d0c5c9e4 100644 --- a/tests/test_workspaces_prompt_contract.py +++ b/tests/test_workspaces_prompt_contract.py @@ -2,7 +2,7 @@ from __future__ import annotations from pathlib import Path -from oclaw.platform.config.paths import PROJECT_ROOT +from svc.config.paths import PROJECT_ROOT def _read(path: Path) -> str: diff --git a/tests/test_ws_gateway.py b/tests/test_ws_gateway.py index 009934d3..0d48b781 100644 --- a/tests/test_ws_gateway.py +++ b/tests/test_ws_gateway.py @@ -3,9 +3,9 @@ from unittest import mock from fastapi.testclient import TestClient -from oclaw.interfaces.http.fastapi_app import create_app -from oclaw.interfaces.ws.runtime_impl import OclawWsGatewayConnection -from oclaw.runtime.gateway import OclawGatewayResult +from interfaces.http.fastapi_app import create_app +from interfaces.ws.runtime_impl import OclawWsGatewayConnection +from runtime.gateway import OclawGatewayResult def _connect_params() -> dict: @@ -30,7 +30,7 @@ class WsGatewayTests(unittest.TestCase): OclawWsGatewayConnection._stats.clear() OclawWsGatewayConnection._event_buffer_by_user.clear() self._auth_patcher = mock.patch( - "oclaw.interfaces.ws.runtime_impl.resolve_ws_auth_payload", + "interfaces.ws.runtime_impl.resolve_ws_auth_payload", return_value={"tenant_id": "t1", "user_id": "u1", "role": "operator"}, ) self._auth_patcher.start() @@ -76,7 +76,7 @@ class WsGatewayTests(unittest.TestCase): assert res["ok"] is False def test_ws_connect_rejects_without_auth(self) -> None: - with mock.patch("oclaw.interfaces.ws.runtime_impl.resolve_ws_auth_payload", return_value={}): + with mock.patch("interfaces.ws.runtime_impl.resolve_ws_auth_payload", return_value={}): with self.client.websocket_connect("/ws") as ws: ws.receive_json() bad = _connect_params() @@ -94,13 +94,13 @@ class WsGatewayTests(unittest.TestCase): assert (res.get("error") or {}).get("code") == "UNAUTHORIZED" def test_ws_origin_blocked(self) -> None: - with mock.patch("oclaw.interfaces.ws.runtime_impl.origin_is_allowed", return_value=False): + with mock.patch("interfaces.ws.runtime_impl.origin_is_allowed", return_value=False): with self.assertRaises(Exception): with self.client.websocket_connect("/ws", headers={"origin": "https://evil.example.com"}): pass def test_ws_rate_limited(self) -> None: - with mock.patch("oclaw.interfaces.ws.runtime_impl.WS_RATE_LIMIT_CONN_PER_WINDOW", 1): + with mock.patch("interfaces.ws.runtime_impl.WS_RATE_LIMIT_CONN_PER_WINDOW", 1): with self.client.websocket_connect("/ws") as ws: ws.receive_json() ws.send_json({"type": "req", "id": "c1", "method": "connect", "params": _connect_params()}) @@ -148,7 +148,7 @@ class WsGatewayTests(unittest.TestCase): interaction_mode="comprehensive", ) - with mock.patch("oclaw.runtime.gateway.OclawGateway.handle_turn", new=_fake_handle_turn): + with mock.patch("runtime.gateway.OclawGateway.handle_turn", new=_fake_handle_turn): with self.client.websocket_connect("/ws") as ws: ws.receive_json() # connect.challenge ws.send_json({"type": "req", "id": "c1", "method": "connect", "params": _connect_params()}) @@ -205,7 +205,7 @@ class WsGatewayTests(unittest.TestCase): interaction_mode="comprehensive", ) - with mock.patch("oclaw.runtime.gateway.OclawGateway.handle_turn", new=_fake_handle_turn): + with mock.patch("runtime.gateway.OclawGateway.handle_turn", new=_fake_handle_turn): with self.client.websocket_connect("/ws") as ws: ws.receive_json() ws.send_json({"type": "req", "id": "c1", "method": "connect", "params": _connect_params()}) @@ -242,7 +242,7 @@ class WsGatewayTests(unittest.TestCase): interaction_mode="comprehensive", ) - with mock.patch("oclaw.runtime.gateway.OclawGateway.handle_turn", new=_fake_handle_turn): + with mock.patch("runtime.gateway.OclawGateway.handle_turn", new=_fake_handle_turn): with self.client.websocket_connect("/ws") as ws: ws.receive_json() ws.send_json({"type": "req", "id": "c1", "method": "connect", "params": _connect_params()}) @@ -284,7 +284,7 @@ class WsGatewayTests(unittest.TestCase): interaction_mode="comprehensive", ) - with mock.patch("oclaw.runtime.gateway.OclawGateway.handle_turn", new=_fake_handle_turn): + with mock.patch("runtime.gateway.OclawGateway.handle_turn", new=_fake_handle_turn): with self.client.websocket_connect("/ws") as ws: ws.receive_json() ws.send_json({"type": "req", "id": "c1", "method": "connect", "params": _connect_params()}) @@ -354,7 +354,7 @@ class WsGatewayTests(unittest.TestCase): interaction_mode="comprehensive", ) - with mock.patch("oclaw.runtime.gateway.OclawGateway.handle_turn", new=_fake_handle_turn): + with mock.patch("runtime.gateway.OclawGateway.handle_turn", new=_fake_handle_turn): with self.client.websocket_connect("/ws") as ws: ws.receive_json() ws.send_json({"type": "req", "id": "c1", "method": "connect", "params": _connect_params()}) @@ -419,7 +419,7 @@ class WsGatewayTests(unittest.TestCase): interaction_mode="comprehensive", ) - with mock.patch("oclaw.runtime.gateway.OclawGateway.handle_turn", new=_fake_handle_turn): + with mock.patch("runtime.gateway.OclawGateway.handle_turn", new=_fake_handle_turn): with self.client.websocket_connect("/ws") as ws1: ws1.receive_json() ws1.send_json({"type": "req", "id": "c1", "method": "connect", "params": _connect_params()})