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

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

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

View file

@ -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

View file

@ -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

View file

@ -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``."""

View file

@ -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 <port>`.
2. Start backend using `python -m runtime.operations gateway start --host 127.0.0.1 --port <port>`.
3. Open `http://127.0.0.1:<port>/chat` in the desktop window.
Logs are written under:

View file

@ -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,

View file

@ -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`

View file

@ -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).

View file

@ -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.

View file

@ -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/<role>/` (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/<role>/` (e.g. `ROLE_SYSTEM.md`). Load via `runtime.prompt_templates`.
- Business code must inject variables only; no long inline prompt strings.
## Template Contract

View file

@ -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`)。

View file

@ -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:

View file

@ -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:

View file

@ -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,

View file

@ -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)

View file

@ -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"

View file

@ -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:

View file

@ -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):

View file

@ -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]:

View file

@ -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:

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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"]

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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]

View file

@ -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

View file

@ -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,

View file

@ -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)

View file

@ -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(

View file

@ -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

View file

@ -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(

View file

@ -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__)

View file

@ -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()

View file

@ -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(

View file

@ -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:

View file

@ -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__ = []

View file

@ -1 +0,0 @@
# oclaw.platform.llm package

View file

@ -1 +0,0 @@
# oclaw.platform.llm.transports package

View file

@ -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] = {}

View file

@ -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 {}

View file

@ -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",

View file

@ -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:

View file

@ -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")

View file

@ -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(

View file

@ -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

View file

@ -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

View file

@ -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()

View file

@ -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:

View file

@ -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"<think>\s*(.*?)\s*</think>\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``

View file

@ -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,

View file

@ -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")

View file

@ -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,

View file

@ -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"]

View file

@ -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,

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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

View file

@ -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"

View file

@ -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)"

View file

@ -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"]

View file

@ -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),

View file

@ -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

View file

@ -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:

View file

@ -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"]

View file

@ -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"

View file

@ -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:

View file

@ -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")

View file

@ -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`).

View file

@ -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:

View file

@ -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)

View file

@ -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]:

View file

@ -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:

View file

@ -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 {}))

View file

@ -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(

View file

@ -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.")

View file

@ -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()

View file

@ -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,"

View file

@ -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()

View file

@ -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

View file

@ -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

View file

@ -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:

View file

@ -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] = {

View file

@ -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)

View file

@ -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"

View file

@ -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:

View file

@ -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:

View file

@ -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:

View file

@ -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:

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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
}

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