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 - name: Install dependencies
run: python -m pip install -r requirements.txt ruff mypy run: python -m pip install -r requirements.txt ruff mypy
- name: Lint changed architecture modules - 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 - 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 - name: Run tests
run: python -m pytest -q oclaw/tests run: python -m pytest -q tests
- name: Offline eval sanity - 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 - `gateway/`: method handlers and protocol bridging
- `application/`: use-cases and orchestration services - `application/`: use-cases and orchestration services
- `infrastructure/`: runtime-facing integrations/adapters - `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 - `tools/`: tool registry, MCP adapters, public/system tools
- `skills/`: installable skills and runtime manifests - `skills/`: installable skills and runtime manifests

View file

@ -1,5 +1 @@
"""Oclaw v2 package root. """Repository marker (optional). Imports use top-level ``svc``, ``runtime``, ``interfaces``."""
All production code in this repository lives under this package root.
"""

View file

@ -24,7 +24,7 @@ npm run dev
The app will: The app will:
1. Pick an available local port (default prefers `8787`). 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. 3. Open `http://127.0.0.1:<port>/chat` in the desktop window.
Logs are written under: Logs are written under:

View file

@ -253,7 +253,7 @@ async function startBackendProcess() {
AIA_DESKTOP_MODE: "1", 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, { backendProc = spawn(pythonBin, args, {
cwd: APP_ROOT, cwd: APP_ROOT,
env, env,
@ -343,7 +343,7 @@ async function startChannelProcess() {
try { try {
const cleanupRes = await runPythonInline( const cleanupRes = await runPythonInline(
pythonBin, 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 }, { AIA_DATA_DIR: DATA_ROOT },
); );
if (!cleanupRes.ok) { if (!cleanupRes.ok) {
@ -359,7 +359,7 @@ async function startChannelProcess() {
AIA_DATA_DIR: DATA_ROOT, AIA_DATA_DIR: DATA_ROOT,
AIA_DESKTOP_MODE: "1", 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; channelStopping = false;
channelProc = spawn(pythonBin, args, { channelProc = spawn(pythonBin, args, {
cwd: APP_ROOT, cwd: APP_ROOT,

View file

@ -506,7 +506,7 @@
- 生效:`oclaw/app_server/fastapi_main.py`, `oclaw/runtime/operations/main.py` - 生效:`oclaw/app_server/fastapi_main.py`, `oclaw/runtime/operations/main.py`
- `OCLAW_UVICORN_WS_MAX_SIZE` - `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 对 WebSocket 单帧的字节上限**(与 hello 里 `maxPayload` 应对齐)。uvicorn 自带默认约 **16MB**;两张高清图经 base64 塞进一条 `chat.send` 常超过 16MB,服务端直接断连,浏览器侧表现为 **`ws_closed`** / 请求失败
- 说明:若用命令行 `uvicorn ...` 启动而未走 `fastapi_app.main()`,需自行加 `--ws-max-size` 或设置本变量(取决于你的启动入口是否读取) - 说明:若用命令行 `uvicorn ...` 启动而未走 `fastapi_app.main()`,需自行加 `--ws-max-size` 或设置本变量(取决于你的启动入口是否读取)
- 生效:`oclaw/interfaces/http/fastapi_app.py` - 生效:`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 ## Import graph checks
- [x] `rg "src\.app_server\."` has no runtime/code matches (tests excluded or updated). - [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] CLI/runtime startup paths import from `interfaces.*` only.
- [x] WebSocket entrypoint imports resolve through `oclaw.interfaces.ws.*`. - [x] WebSocket entrypoint imports resolve through `interfaces.ws.*`.
## Behavior parity checks ## Behavior parity checks
- [x] HTTP gateway smoke tests pass (`/health`, `/inbound`, `/gateway/method`, `/ws` handshake). - [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 ## Runtime notes
- Gateway HTTP method adapter: `POST /gateway/method` - Gateway HTTP method adapter: `POST /gateway/method`
- WS dispatch first resolves method handlers from shared dispatcher. - WS dispatch first resolves method handlers from shared dispatcher.
- Inbound payload use-case entrypoint: `oclaw.runtime.application.gateway.process_inbound_payload_usecase` - Inbound payload use-case entrypoint: `runtime.application.gateway.process_inbound_payload_usecase`
- HTTP app entrypoint moved to: `oclaw.interfaces.http.fastapi_app` - HTTP app entrypoint moved to: `interfaces.http.fastapi_app`
- WS entrypoint moved to: `oclaw.interfaces.ws.entrypoint` - WS entrypoint moved to: `interfaces.ws.entrypoint`
- WS runtime bridge path: `oclaw.interfaces.ws.runtime` - WS runtime bridge path: `interfaces.ws.runtime`
- WS runtime implementation seam: - WS runtime implementation seam:
- `oclaw/interfaces/ws/runtime_impl.py` - `oclaw/interfaces/ws/runtime_impl.py`
- `runtime.py` points to this module as stable import surface. - `runtime.py` points to this module as stable import surface.

View file

@ -1,7 +1,7 @@
# Prompt Style Guide # Prompt Style Guide
## Goal ## 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. - Business code must inject variables only; no long inline prompt strings.
## Template Contract ## Template Contract

View file

@ -11,7 +11,7 @@
## 1. 统一入口(只保留最新) ## 1. 统一入口(只保留最新)
所有运维命令统一通过 `scripts/`,不要再使用 `python -m oclaw.runtime.operations ...` 或历史 `.bat` 方式。 所有运维命令统一通过 `scripts/`,不要再使用 `python -m runtime.operations ...` 或历史 `.bat` 方式。
补充:工具脚本也统一放在 `scripts/`(例如 `seed_mcp_registry.py`、`ws_probe.py`)。 补充:工具脚本也统一放在 `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 import APIRouter, Body, File, Header, HTTPException, Query, UploadFile
from fastapi.responses import Response, StreamingResponse from fastapi.responses import Response, StreamingResponse
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
from oclaw.runtime.agents.specialists import specialist_ids from runtime.agents.specialists import specialist_ids
from oclaw.runtime.agents.factory import build_gateway_executor from runtime.agents.factory import build_gateway_executor
from oclaw.runtime.chat.agent import GenerationInterrupted from runtime.chat.agent import GenerationInterrupted
from oclaw.platform.config.paths import db_path from svc.config.paths import db_path
from oclaw.platform.files.attachment_assets import AttachmentAssetStore from svc.files.attachment_assets import AttachmentAssetStore
from oclaw.platform.files.file_attachments import ( from svc.files.file_attachments import (
DEFAULT_TABULAR_CELL_CHARS, DEFAULT_TABULAR_CELL_CHARS,
DEFAULT_TABULAR_COLUMNS, DEFAULT_TABULAR_COLUMNS,
DEFAULT_MAX_EXCEL_SHEETS, DEFAULT_MAX_EXCEL_SHEETS,
DEFAULT_TABULAR_ROWS_READ, DEFAULT_TABULAR_ROWS_READ,
clear_attachment_limits_cache, clear_attachment_limits_cache,
) )
from oclaw.interfaces.ws.common import normalize_ws_attachments from interfaces.ws.common import normalize_ws_attachments
from oclaw.platform.files.session_export import export_session_json, export_session_markdown from svc.files.session_export import export_session_json, export_session_markdown
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
from oclaw.runtime.gateway import OclawGateway from runtime.gateway import OclawGateway
from oclaw.runtime.plan_agent_v2.switch import v2_feature_enabled from runtime.plan_agent_v2.switch import v2_feature_enabled
from oclaw.runtime.types import StandardMessage, normalize_interaction_mode, normalize_requested_specialist from 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 runtime.chat.history_tool_result_compact import compact_tool_results_in_session_history
def _oclaw_config_path() -> Path: def _oclaw_config_path() -> Path:

View file

@ -3,8 +3,8 @@ from __future__ import annotations
from typing import Any from typing import Any
from oclaw.runtime.tools.base import ToolRegistry, ToolSpec from runtime.tools.base import ToolRegistry, ToolSpec
from oclaw.runtime.tools.tool_validation import validate_tool_arguments from runtime.tools.tool_validation import validate_tool_arguments
def parse_mcp_bound_tool_name(full_name: str) -> tuple[str, str] | None: 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 import APIRouter, Body, Header, HTTPException, Query
from fastapi.responses import Response from fastapi.responses import Response
from oclaw.runtime.agents.factory import DEFAULT_OLLAMA_BASE_URL, DEFAULT_OLLAMA_MODEL from runtime.agents.factory import DEFAULT_OLLAMA_BASE_URL, DEFAULT_OLLAMA_MODEL
from oclaw.runtime.agents.specialists import ( from runtime.agents.specialists import (
AGENT_PROFILE_BINDINGS_KEY, AGENT_PROFILE_BINDINGS_KEY,
agent_role_ids, agent_role_ids,
dump_agent_profile_bindings, dump_agent_profile_bindings,
parse_agent_profile_bindings, parse_agent_profile_bindings,
) )
from oclaw.platform.config.paths import db_path from svc.config.paths import db_path
from oclaw.runtime.orchestration.evaluation import eval_summary from runtime.orchestration.evaluation import eval_summary
from oclaw.platform.persistence.sqlite_store import ( from svc.persistence.sqlite_store import (
LLM_BUILTIN_OLLAMA_PROFILE_ID, LLM_BUILTIN_OLLAMA_PROFILE_ID,
SqliteStore, SqliteStore,
active_llm_profile_setting_key, active_llm_profile_setting_key,

View file

@ -16,12 +16,12 @@ from fastapi import APIRouter, Body, Header, Query
from fastapi import HTTPException from fastapi import HTTPException
from fastapi.responses import HTMLResponse from fastapi.responses import HTMLResponse
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
from oclaw.runtime.agents.factory import build_gateway_executor from runtime.agents.factory import build_gateway_executor
from oclaw.runtime.gateway import OclawGateway from runtime.gateway import OclawGateway
from oclaw.runtime.types import StandardMessage, normalize_interaction_mode, normalize_requested_specialist from runtime.types import StandardMessage, normalize_interaction_mode, normalize_requested_specialist
from oclaw.runtime.operations.providers.registry import build_channel_registry from runtime.operations.providers.registry import build_channel_registry
from oclaw.runtime.operations.runtime import ( from runtime.operations.runtime import (
cleanup_service_processes_by_pid, cleanup_service_processes_by_pid,
detect_orphan_service_processes, detect_orphan_service_processes,
is_pid_running, is_pid_running,
@ -29,37 +29,37 @@ from oclaw.runtime.operations.runtime import (
list_service_process_pids, list_service_process_pids,
status_services, status_services,
) )
from oclaw.runtime.operations.stack import cmd_stack_down, cmd_stack_status, cmd_stack_up from 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 runtime.orchestration.vector_store import read_vector_memory_runtime
from oclaw.platform.config.paths import PROJECT_ROOT, db_path from svc.config.paths import PROJECT_ROOT, db_path
from oclaw.platform.config.passwords import load_expected_password from svc.config.passwords import load_expected_password
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
from oclaw.runtime.agents.specialists import discover_specialist_ids, parse_agent_profile_bindings from runtime.agents.specialists import discover_specialist_ids, parse_agent_profile_bindings
from oclaw.runtime.tools.mcp.installer import ( from runtime.tools.mcp.installer import (
_safe_server_id, _safe_server_id,
detect_local_dependencies, detect_local_dependencies,
install_mcp_server, install_mcp_server,
preflight_mcp_server, preflight_mcp_server,
uninstall_mcp_server, uninstall_mcp_server,
) )
from oclaw.runtime.tools.mcp.market import search_mcp_market, trending_mcp_market from runtime.tools.mcp.market import search_mcp_market, trending_mcp_market
from oclaw.runtime.tools.mcp.manifest import McpServerManifest from runtime.tools.mcp.manifest import McpServerManifest
from oclaw.runtime.operations.mcp_registry_export import ( from runtime.operations.mcp_registry_export import (
build_mcp_install_export_document, build_mcp_install_export_document,
mcp_migrated_json_path, mcp_migrated_json_path,
persist_mcp_migrated_file, persist_mcp_migrated_file,
) )
from oclaw.runtime.tools.mcp.filesystem_argv import build_mcp_process_command from runtime.tools.mcp.filesystem_argv import build_mcp_process_command
from oclaw.runtime.tools.mcp.registry import McpRegistry from runtime.tools.mcp.registry import McpRegistry
from oclaw.runtime.tools.mcp.runtime import McpProcessRuntime from runtime.tools.mcp.runtime import McpProcessRuntime
from oclaw.interfaces.admin.mcp_e2e_probe import build_mcp_e2e_probe_plans from interfaces.admin.mcp_e2e_probe import build_mcp_e2e_probe_plans
from oclaw.runtime.tools.catalog import default_registry from runtime.tools.catalog import default_registry
from oclaw.runtime.chat.tool_runtime import ToolExecutionContext, ToolExecutor from runtime.chat.tool_runtime import ToolExecutionContext, ToolExecutor
from oclaw.platform.llm.chat_models import LLMToolCall from svc.llm.chat_models import LLMToolCall
from oclaw.runtime.agent_core_attempt import ALL_ATTEMPT_ERROR_CODES from 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 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 runtime.prompt_prebuild import run_runtime_prewarm, runtime_prewarm_prompts_snapshot, runtime_prewarm_status
from oclaw.runtime.workspaces.experts import ( from runtime.workspaces.experts import (
create_expert, create_expert,
delete_expert, delete_expert,
list_experts, list_experts,
@ -446,8 +446,8 @@ def build_admin_router() -> APIRouter:
ctx = _resolve_auth(store, authorization) ctx = _resolve_auth(store, authorization)
_require_permission(ctx, "admin:tenant:write") _require_permission(ctx, "admin:tenant:write")
from oclaw.runtime.tools.expert_registry import clear_expert_tool_cache from runtime.tools.expert_registry import clear_expert_tool_cache
from oclaw.runtime.tools.public_registry import clear_public_tool_cache from runtime.tools.public_registry import clear_public_tool_cache
clear_public_tool_cache() clear_public_tool_cache()
clear_expert_tool_cache() clear_expert_tool_cache()
@ -504,7 +504,7 @@ def build_admin_router() -> APIRouter:
store = SqliteStore(db_path()) store = SqliteStore(db_path())
ctx = _resolve_auth(store, authorization) ctx = _resolve_auth(store, authorization)
_require_permission(ctx, "admin:tenant:write") _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() r = str(role or "").strip().lower()
available_roles = _ordered_roles() available_roles = _ordered_roles()
@ -543,8 +543,8 @@ def build_admin_router() -> APIRouter:
ctx = _resolve_auth(store, authorization) ctx = _resolve_auth(store, authorization)
_require_permission(ctx, "admin:tenant:write") _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 svc.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 runtime.tools.exposure_plan import build_internal_tool_specs, build_llm_tools_plan
roles = _ordered_roles() roles = _ordered_roles()
items: list[dict[str, Any]] = [] items: list[dict[str, Any]] = []
@ -607,7 +607,7 @@ def build_admin_router() -> APIRouter:
store = SqliteStore(db_path()) store = SqliteStore(db_path())
ctx = _resolve_auth(store, authorization) ctx = _resolve_auth(store, authorization)
_require_permission(ctx, "admin:tenant:write") _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() r = str(role or "").strip().lower()
available_roles = _ordered_roles() available_roles = _ordered_roles()
@ -2295,7 +2295,7 @@ def build_admin_router() -> APIRouter:
store = SqliteStore(db_path()) store = SqliteStore(db_path())
ctx = _resolve_auth(store, authorization) ctx = _resolve_auth(store, authorization)
_require_permission(ctx, "admin:tenant:write") _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) 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), payload: dict[str, Any] | None = Body(default=None),
authorization: str | None = Header(default=None), authorization: str | None = Header(default=None),
) -> dict[str, Any]: ) -> 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 {} payload = payload or {}
store = SqliteStore(db_path()) store = SqliteStore(db_path())
@ -2356,7 +2356,7 @@ def build_admin_router() -> APIRouter:
payload: dict[str, Any] | None = Body(default=None), payload: dict[str, Any] | None = Body(default=None),
authorization: str | None = Header(default=None), authorization: str | None = Header(default=None),
) -> dict[str, Any]: ) -> 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 {} payload = payload or {}
store = SqliteStore(db_path()) store = SqliteStore(db_path())
@ -2396,7 +2396,7 @@ def build_admin_router() -> APIRouter:
role: str | None = Query(default=None), role: str | None = Query(default=None),
authorization: str | None = Header(default=None), authorization: str | None = Header(default=None),
) -> dict[str, Any]: ) -> 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()) store = SqliteStore(db_path())
ctx = _resolve_auth(store, authorization) ctx = _resolve_auth(store, authorization)
@ -2433,7 +2433,7 @@ def build_admin_router() -> APIRouter:
payload: dict[str, Any] | None = Body(default=None), payload: dict[str, Any] | None = Body(default=None),
authorization: str | None = Header(default=None), authorization: str | None = Header(default=None),
) -> dict[str, Any]: ) -> 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,
SETTINGS_KEY_TOOL_POLICIES_BY_ROLE, SETTINGS_KEY_TOOL_POLICIES_BY_ROLE,
load_tool_policies_dict_for_role, load_tool_policies_dict_for_role,
@ -2504,7 +2504,7 @@ def build_admin_router() -> APIRouter:
payload: dict[str, Any] | None = Body(default=None), payload: dict[str, Any] | None = Body(default=None),
authorization: str | None = Header(default=None), authorization: str | None = Header(default=None),
) -> dict[str, Any]: ) -> 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,
SETTINGS_KEY_TOOL_POLICIES_BY_ROLE, SETTINGS_KEY_TOOL_POLICIES_BY_ROLE,
load_tool_policies_dict_for_role, load_tool_policies_dict_for_role,
@ -3604,8 +3604,8 @@ def build_admin_router() -> APIRouter:
if tenant_id: if tenant_id:
_require_tenant_scope(ctx, tenant_id) _require_tenant_scope(ctx, tenant_id)
user_id = str(payload.get("user_id") or "").strip() or None user_id = str(payload.get("user_id") or "").strip() or None
from oclaw.platform.embeddings.embedding_client import build_default_embedding_client from svc.embeddings.embedding_client import build_default_embedding_client
from oclaw.runtime.orchestration.vector_store import build_vector_store, MemoryVectorItem from runtime.orchestration.vector_store import build_vector_store, MemoryVectorItem
client = build_default_embedding_client() client = build_default_embedding_client()
vector = build_vector_store(store) vector = build_vector_store(store)
@ -4114,9 +4114,9 @@ def build_admin_router() -> APIRouter:
"offset": int(off), "offset": int(off),
} }
from oclaw.interfaces.admin.chat_api import include_chat_routes from interfaces.admin.chat_api import include_chat_routes
from oclaw.interfaces.admin.models_api import include_model_mgmt_routes from interfaces.admin.models_api import include_model_mgmt_routes
from oclaw.interfaces.admin.skills_api import include_skill_routes from interfaces.admin.skills_api import include_skill_routes
include_chat_routes(router, resolve_auth=_resolve_auth) include_chat_routes(router, resolve_auth=_resolve_auth)
include_model_mgmt_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 fastapi import APIRouter, Body, Header, HTTPException
from oclaw.runtime.agents.factory import build_gateway_executor from runtime.agents.factory import build_gateway_executor
from oclaw.runtime.skill_installer import ( from runtime.skill_installer import (
auto_install_skill_from_payload, auto_install_skill_from_payload,
create_skill_from_template, create_skill_from_template,
create_workspace_skill, create_workspace_skill,
@ -19,7 +19,7 @@ from oclaw.runtime.skill_installer import (
set_skill_enabled, set_skill_enabled,
uninstall_skill, uninstall_skill,
) )
from oclaw.runtime.skill_role_binding import ( from runtime.skill_role_binding import (
SKILL_ROLE_BINDING_ENABLED_SETTING, SKILL_ROLE_BINDING_ENABLED_SETTING,
SKILL_ROLE_BINDING_KEY, SKILL_ROLE_BINDING_KEY,
SKILL_ROLE_BINDING_MANAGER_INHERIT_SETTING, 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_env_present,
skill_role_binding_enabled_stored, skill_role_binding_enabled_stored,
) )
from oclaw.runtime.skills_prompt import collect_skill_catalog_entries from runtime.skills_prompt import collect_skill_catalog_entries
from oclaw.runtime.skills import _allowed_tool_names_after_wire_policy, discover_workspace_skill_manifests from 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 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 runtime.tools.skills_runtime.subprocess_exec import run_skill_runtime_entry
from oclaw.platform.config.paths import db_path from svc.config.paths import db_path
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
_SKILL_MARKET_PROVIDER_KEY = "AIA_SKILL_MARKET_PROVIDER" _SKILL_MARKET_PROVIDER_KEY = "AIA_SKILL_MARKET_PROVIDER"

View file

@ -11,11 +11,11 @@ from collections import deque
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
from oclaw.runtime.application.gateway import process_inbound_payload_usecase from runtime.application.gateway import process_inbound_payload_usecase
from oclaw.interfaces.channels.wecom.normalize import normalize_wecom_event, normalize_wecom_event_batch from interfaces.channels.wecom.normalize import normalize_wecom_event, normalize_wecom_event_batch
from oclaw.platform.config.paths import db_path from svc.config.paths import db_path
from oclaw.platform.integrations.wecom_client import WeComClient from svc.integrations.wecom_client import WeComClient
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
def _safe_json(obj: Any) -> str: def _safe_json(obj: Any) -> str:

View file

@ -2,7 +2,7 @@ from __future__ import annotations
from typing import Any from typing import Any
from oclaw.interfaces.channels.base import ChannelAdapter, InboundMessage, OutboundMessage from interfaces.channels.base import ChannelAdapter, InboundMessage, OutboundMessage
class WeComAdapter(ChannelAdapter): class WeComAdapter(ChannelAdapter):

View file

@ -2,9 +2,9 @@ from __future__ import annotations
from typing import Any from typing import Any
from oclaw.runtime.skill_installer import install_skill_from_registry_archive from 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 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.tools.skills.clawhub_client import search_skills as clawhub_search_skills
def build_common_gateway_context(*, store: Any) -> dict[str, Any]: def build_common_gateway_context(*, store: Any) -> dict[str, Any]:

View file

@ -1,12 +1,12 @@
from __future__ import annotations from __future__ import annotations
from oclaw.interfaces.gateway.server_methods.agent import agent_handlers from interfaces.gateway.server_methods.agent import agent_handlers
from oclaw.interfaces.gateway.server_methods.chat import chat_handlers from interfaces.gateway.server_methods.chat import chat_handlers
from oclaw.interfaces.gateway.server_methods.commands import commands_handlers from interfaces.gateway.server_methods.commands import commands_handlers
from oclaw.interfaces.gateway.server_methods.connect import connect_handlers from interfaces.gateway.server_methods.connect import connect_handlers
from oclaw.interfaces.gateway.server_methods.sessions import sessions_handlers from interfaces.gateway.server_methods.sessions import sessions_handlers
from oclaw.interfaces.gateway.server_methods.skills import skills_handlers from interfaces.gateway.server_methods.skills import skills_handlers
from oclaw.interfaces.gateway.server_methods.shared_types import GatewayRequestHandlers from interfaces.gateway.server_methods.shared_types import GatewayRequestHandlers
def build_gateway_method_handlers() -> GatewayRequestHandlers: def build_gateway_method_handlers() -> GatewayRequestHandlers:

View file

@ -2,8 +2,8 @@ from __future__ import annotations
from typing import Any from typing import Any
from oclaw.platform.config.paths import db_path from svc.config.paths import db_path
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
from .context_builder import build_common_gateway_context from .context_builder import build_common_gateway_context
from .dispatcher import build_gateway_method_handlers from .dispatcher import build_gateway_method_handlers

View file

@ -8,8 +8,8 @@ from types import ModuleType
from typing import Any, Iterable from typing import Any, Iterable
from types import SimpleNamespace from types import SimpleNamespace
from oclaw.platform.config.runtime_paths import runtime_extensions_root from svc.config.runtime_paths import runtime_extensions_root
from oclaw.runtime.extensions.plugin_api import PluginEntry from runtime.extensions.plugin_api import PluginEntry
def _sanitize_module_name(value: str) -> str: def _sanitize_module_name(value: str) -> str:

View file

@ -2,7 +2,7 @@ from __future__ import annotations
from typing import Any 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 .shared_types import GatewayRequestHandlers
from .validation import error_shape from .validation import error_shape

View file

@ -1,6 +1,6 @@
"""Compatibility bridge to the new oclaw dispatcher.""" """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"] __all__ = ["build_gateway_method_handlers", "method_names"]

View file

@ -4,7 +4,7 @@ import importlib.util
from pathlib import Path from pathlib import Path
from typing import Any, Callable 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 .shared_types import GatewayRequestHandlers
from .validation import error_shape from .validation import error_shape

View file

@ -2,7 +2,7 @@ from __future__ import annotations
from typing import Any 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 .shared_types import GatewayRequestHandlers
from .telegram_send_normalize import normalize_transport_target_for_channel from .telegram_send_normalize import normalize_transport_target_for_channel

View file

@ -3,14 +3,14 @@ from __future__ import annotations
import json import json
from typing import Any from typing import Any
from oclaw.runtime.skill_installer import ( from runtime.skill_installer import (
create_skill_from_template, create_skill_from_template,
install_skill_from_local_dir, install_skill_from_local_dir,
install_skill_from_registry_archive, install_skill_from_registry_archive,
list_skills_with_status, list_skills_with_status,
set_skill_enabled, 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 .shared_types import GatewayRequestHandlers
from .validation import error_shape from .validation import error_shape

View file

@ -2,7 +2,7 @@ from __future__ import annotations
from typing import Any from typing import Any
from oclaw.runtime.extensions.telegram import ( from runtime.extensions.telegram import (
normalize_telegram_messaging_target, normalize_telegram_messaging_target,
parse_telegram_reply_to_message_id, parse_telegram_reply_to_message_id,
parse_telegram_target, parse_telegram_target,

View file

@ -4,7 +4,7 @@ from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from typing import Any, Callable 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 from .python_extensions_loader import build_python_extensions_registry
GatewayHandler = Callable[..., Any] GatewayHandler = Callable[..., Any]

View file

@ -3,8 +3,8 @@ from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, Callable from typing import Any, Callable
from oclaw.runtime.agents.agent_scope import resolve_agent_workspace_dir, resolve_default_agent_id from 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.subagent_registry import init_subagent_registry
from .server_plugins import GatewayPluginLoadResult, load_gateway_plugins from .server_plugins import GatewayPluginLoadResult, load_gateway_plugins

View file

@ -1,6 +1,6 @@
from __future__ import annotations 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() load_system_env()
@ -17,24 +17,24 @@ from fastapi import Request
from fastapi.responses import HTMLResponse from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from oclaw.runtime.application.gateway import process_inbound_payload_usecase from runtime.application.gateway import process_inbound_payload_usecase
from oclaw.interfaces.gateway.http_adapter import dispatch_gateway_http_method from interfaces.gateway.http_adapter import dispatch_gateway_http_method
from oclaw.interfaces.ws import ws_gateway_loop from interfaces.ws import ws_gateway_loop
from oclaw.interfaces.ws.common import MAX_PAYLOAD_BYTES from interfaces.ws.common import MAX_PAYLOAD_BYTES
from oclaw.interfaces.admin.routes import admin_static_dir, build_admin_router from 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 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 interfaces.gateway.server_startup_plugins import prepare_gateway_plugin_bootstrap
from oclaw.runtime.hooks_runtime import ( from runtime.hooks_runtime import (
initialize_hooks_runtime, initialize_hooks_runtime,
resolve_runtime_config, resolve_runtime_config,
trigger_hook_event, trigger_hook_event,
) )
from oclaw.runtime.skills import skill_runtime_diagnostics from runtime.skills import skill_runtime_diagnostics
from oclaw.runtime.prompt_prebuild import run_runtime_prewarm from runtime.prompt_prebuild import run_runtime_prewarm
from oclaw.platform.config.paths import PROJECT_ROOT, db_path from svc.config.paths import PROJECT_ROOT, db_path
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
from oclaw.interfaces.http.weixin_ilink_api import router as weixin_ilink_router from interfaces.http.weixin_ilink_api import router as weixin_ilink_router
from oclaw.runtime.workspaces.experts import warm_expert_workspace_cache from runtime.workspaces.experts import warm_expert_workspace_cache
def _resolve_startup_workspace_dir(cfg: dict[str, Any]) -> str: 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 = int(MAX_PAYLOAD_BYTES)
ws_max_size = max(1024, min(int(ws_max_size), 200_000_000)) ws_max_size = max(1024, min(int(ws_max_size), 200_000_000))
uvicorn.run( uvicorn.run(
"oclaw.interfaces.http.fastapi_app:create_app", "interfaces.http.fastapi_app:create_app",
host=host, host=host,
port=port, port=port,
reload=False, 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]: def _process_inbound_payload_usecase(payload: dict[str, Any]) -> dict[str, Any]:
# Lazy import to avoid circular imports during FastAPI app bootstrap. # 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) return process_inbound_payload_usecase(payload)

View file

@ -4,8 +4,8 @@ import hashlib
import os import os
from typing import Any from typing import Any
from oclaw.platform.config.paths import db_path from svc.config.paths import db_path
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
def build_hello_ok_payload( def build_hello_ok_payload(

View file

@ -5,7 +5,7 @@ import os
import time import time
from typing import Any 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 PROTOCOL_VERSION = 3
MAX_PAYLOAD_BYTES = 26_214_400 MAX_PAYLOAD_BYTES = 26_214_400

View file

@ -6,7 +6,7 @@ from typing import Any
from starlette.websockets import WebSocketDisconnect 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( async def recv_frame(

View file

@ -11,9 +11,9 @@ import threading
from fastapi import WebSocket from fastapi import WebSocket
from oclaw.interfaces.gateway.dispatcher import build_gateway_method_handlers, method_names from 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 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.ws.common import (
MAX_BUFFERED_BYTES, MAX_BUFFERED_BYTES,
MAX_PAYLOAD_BYTES, MAX_PAYLOAD_BYTES,
PREAUTH_HANDSHAKE_TIMEOUT_MS, PREAUTH_HANDSHAKE_TIMEOUT_MS,
@ -31,19 +31,19 @@ from oclaw.interfaces.ws.common import (
now_ms as _now_ms, now_ms as _now_ms,
origin_is_allowed, origin_is_allowed,
) )
from oclaw.interfaces.ws.events import ( from interfaces.ws.events import (
emit_agent_event as emit_agent_event_impl, emit_agent_event as emit_agent_event_impl,
emit_chat_event as emit_chat_event_impl, emit_chat_event as emit_chat_event_impl,
send_event as send_event_impl, send_event as send_event_impl,
send_res as send_res_impl, send_res as send_res_impl,
) )
from oclaw.interfaces.ws.runtime_dispatch import dispatch_connected as dispatch_connected_impl from 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 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 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 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 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 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 runtime.relay_pointer import validate_relay_share_envelope
_LOG = logging.getLogger(__name__) _LOG = logging.getLogger(__name__)

View file

@ -6,7 +6,7 @@ from typing import Any
from jsonschema import Draft202012Validator 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() _SCHEMA_DIR = ws_protocol_schemas_root()

View file

@ -4,9 +4,9 @@ import asyncio
import uuid import uuid
from typing import Any, Callable from typing import Any, Callable
from oclaw.platform.config.paths import db_path from svc.config.paths import db_path
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
from oclaw.interfaces.gateway.context_builder import build_common_gateway_context from interfaces.gateway.context_builder import build_common_gateway_context
def build_gateway_context( def build_gateway_context(

View file

@ -7,11 +7,11 @@ import uuid
from datetime import datetime from datetime import datetime
from typing import Any, Callable from typing import Any, Callable
from oclaw.runtime.agents.factory import build_gateway_executor from runtime.agents.factory import build_gateway_executor
from oclaw.runtime.gateway import OclawGateway from runtime.gateway import OclawGateway
from oclaw.runtime.types import StandardMessage from runtime.types import StandardMessage
from oclaw.platform.config.paths import db_path from svc.config.paths import db_path
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
def _persisted_chat_attachments_nonempty(raw: Any) -> bool: 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 pathlib import Path
from typing import Any 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_LOCK = threading.Lock()
_ROLE_CONTEXT_CACHE: dict[tuple[str, tuple[Any, ...], tuple[tuple[str, str], ...]], str] = {} _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 dataclasses import dataclass
from typing import Any, Callable, Optional from typing import Any, Callable, Optional
from oclaw.runtime.chat.turn_types import TurnRunOutcome from runtime.chat.turn_types import TurnRunOutcome
from oclaw.runtime.direct_loop import run_direct_loop from runtime.direct_loop import run_direct_loop
from oclaw.runtime.memory_stage import after_turn_memory from runtime.memory_stage import after_turn_memory
from oclaw.runtime.types import AttemptState, OclawMemoryContext, StandardMessage from runtime.types import AttemptState, OclawMemoryContext, StandardMessage
from oclaw.runtime.orchestration.trace import new_span_id from runtime.orchestration.trace import new_span_id
def _workspace_owner_session_id_from_msg(msg: StandardMessage) -> str | None: def _workspace_owner_session_id_from_msg(msg: StandardMessage) -> str | None:
md = msg.metadata if isinstance(msg.metadata, dict) else {} md = msg.metadata if isinstance(msg.metadata, dict) else {}

View file

@ -4,12 +4,12 @@ import uuid
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, Callable, Optional from typing import Any, Callable, Optional
from oclaw.runtime.chat.turn_types import TurnRunOutcome from runtime.chat.turn_types import TurnRunOutcome
from oclaw.runtime.agent_core_attempt import ALL_ATTEMPT_ERROR_CODES from runtime.agent_core_attempt import ALL_ATTEMPT_ERROR_CODES
from oclaw.runtime.agent_core_attempt import AttemptRunnerInput, run_attempt from runtime.agent_core_attempt import AttemptRunnerInput, run_attempt
from oclaw.runtime.memory_stage import compact_memory_context from runtime.memory_stage import compact_memory_context
from oclaw.runtime.types import AttemptState, OclawMemoryContext, RunState, StandardMessage from runtime.types import AttemptState, OclawMemoryContext, RunState, StandardMessage
from oclaw.runtime.orchestration.trace import new_span_id from runtime.orchestration.trace import new_span_id
_AGENT_CORE_OC_STAGE: dict[str, str] = { _AGENT_CORE_OC_STAGE: dict[str, str] = {
"run_started": "run_start", "run_started": "run_start",

View file

@ -5,10 +5,10 @@ from __future__ import annotations
import os import os
from typing import Any 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 oclaw.runtime.agents.network_ops_agent import NetworkOpsAgent from runtime.agents.network_ops_agent import NetworkOpsAgent
from oclaw.runtime.agents.specialist_agent import SpecialistProfile from runtime.agents.specialist_agent import SpecialistProfile
from oclaw.runtime.agents.specialists import ( from runtime.agents.specialists import (
AGENT_PROFILE_BINDINGS_KEY, AGENT_PROFILE_BINDINGS_KEY,
normalize_specialist_id, normalize_specialist_id,
agent_role_ids, agent_role_ids,
@ -20,21 +20,21 @@ from oclaw.runtime.agents.specialists import (
expert_name_for_specialist, expert_name_for_specialist,
parse_agent_profile_bindings, parse_agent_profile_bindings,
) )
from oclaw.runtime.chat.agent import Agent from runtime.chat.agent import Agent
from oclaw.runtime.orchestration.inventory import inventory_snapshot from runtime.orchestration.inventory import inventory_snapshot
from oclaw.runtime.orchestration.memory import upsert_knowledge_chunks from runtime.orchestration.memory import upsert_knowledge_chunks
from oclaw.platform.llm.chat_models import GoogleGeminiChatModel, OpenAIChatModel, RuleBasedChatModel, StaticTextChatModel from svc.llm.chat_models import GoogleGeminiChatModel, OpenAIChatModel, RuleBasedChatModel, StaticTextChatModel
from oclaw.platform.llm.transports.anthropic_messages import AnthropicMessagesModel from svc.llm.transports.anthropic_messages import AnthropicMessagesModel
from oclaw.platform.llm.transports.openai_responses import OpenAIResponsesModel from svc.llm.transports.openai_responses import OpenAIResponsesModel
from oclaw.platform.persistence.sqlite_store import ( from svc.persistence.sqlite_store import (
SqliteStore, SqliteStore,
active_llm_profile_setting_key, active_llm_profile_setting_key,
agent_profile_bindings_setting_key, agent_profile_bindings_setting_key,
is_administrator_model_pool, is_administrator_model_pool,
) )
from oclaw.runtime.prompt_templates import render_prompt from runtime.prompt_templates import render_prompt
from oclaw.runtime.tools.catalog import default_registry from runtime.tools.catalog import default_registry
from oclaw.runtime.tools.plugin_loader import sync_plugin_metadata from runtime.tools.plugin_loader import sync_plugin_metadata
def _openai_missing_key_user_message(lang: str) -> str: def _openai_missing_key_user_message(lang: str) -> str:

View file

@ -2,10 +2,10 @@ from __future__ import annotations
from typing import Any from typing import Any
from oclaw.runtime.chat.agent import Agent from runtime.chat.agent import Agent
from oclaw.runtime.agent_context import build_role_system_context from runtime.agent_context import build_role_system_context
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
from oclaw.runtime.tools import default_registry from runtime.tools import default_registry
# Ops 专家走与 specialists 相同的工作区框架:runtime/workspaces/ops/{SOUL,ROLE_SYSTEM}.md # Ops 专家走与 specialists 相同的工作区框架:runtime/workspaces/ops/{SOUL,ROLE_SYSTEM}.md
NETWORK_SYSTEM_PROMPT_ZH = build_role_system_context("ops") 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 dataclasses import dataclass, field
from typing import Any, Optional from typing import Any, Optional
from oclaw.runtime.chat.agent import Agent from runtime.chat.agent import Agent
from oclaw.runtime.chat.agent import GenerationInterrupted from runtime.chat.agent import GenerationInterrupted
from oclaw.runtime.agents.network_ops_agent import NetworkOpsAgent from runtime.agents.network_ops_agent import NetworkOpsAgent
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
from oclaw.platform.llm.image_legacy_client import ( from svc.llm.image_legacy_client import (
IMAGE_SPECIALIST_DEFAULT_PROMPT_ZH, IMAGE_SPECIALIST_DEFAULT_PROMPT_ZH,
collect_legacy_lane_images_from_attachments, collect_legacy_lane_images_from_attachments,
collect_legacy_lane_images_with_session_fallback, collect_legacy_lane_images_with_session_fallback,
@ -21,19 +21,19 @@ from oclaw.platform.llm.image_legacy_client import (
legacy_image_turn_bundle, legacy_image_turn_bundle,
send_legacy_image_messages, send_legacy_image_messages,
) )
from oclaw.platform.llm.video_generation_client import ( from svc.llm.video_generation_client import (
VIDEO_SPECIALIST_DEFAULT_PROMPT_ZH, VIDEO_SPECIALIST_DEFAULT_PROMPT_ZH,
legacy_video_assistant_body_with_placeholder, legacy_video_assistant_body_with_placeholder,
legacy_video_turn_bundle, legacy_video_turn_bundle,
send_video_generation_request, send_video_generation_request,
) )
from oclaw.runtime.tools import default_registry from runtime.tools import default_registry
from oclaw.runtime.agents.specialists import expert_name_for_specialist from runtime.agents.specialists import expert_name_for_specialist
from oclaw.runtime.chat.turn_types import TurnRunOutcome from runtime.chat.turn_types import TurnRunOutcome
from oclaw.runtime.relay_pointer import build_manifest_from_attachment_refs from runtime.relay_pointer import build_manifest_from_attachment_refs
from oclaw.runtime.types import RelayShareEnvelope from runtime.types import RelayShareEnvelope
from oclaw.runtime.orchestration.protocol import ( from runtime.orchestration.protocol import (
AgentTask, AgentTask,
PlanStep, PlanStep,
SpecialistDelivery, SpecialistDelivery,
@ -361,8 +361,8 @@ class SpecialistAgentRunner:
path_policy_tenant_id=_path_tenant, path_policy_tenant_id=_path_tenant,
path_policy_user_id=_path_user, path_policy_user_id=_path_user,
) )
from oclaw.runtime.gateway import OclawGateway from runtime.gateway import OclawGateway
from oclaw.runtime.types import StandardMessage from runtime.types import StandardMessage
gw = OclawGateway(store=self.store) gw = OclawGateway(store=self.store)
msg = StandardMessage( msg = StandardMessage(

View file

@ -4,8 +4,8 @@ from dataclasses import dataclass
import json import json
from typing import Any from typing import Any
from oclaw.runtime.agent_context import build_role_system_context from runtime.agent_context import build_role_system_context
from oclaw.runtime.workspaces.experts import specialist_registry_snapshot from runtime.workspaces.experts import specialist_registry_snapshot
SpecialistId = str SpecialistId = str

View file

@ -4,9 +4,9 @@ import hashlib
import re import re
from typing import Any from typing import Any
from oclaw.interfaces.channels.base import InboundMessage, OutboundMessage from interfaces.channels.base import InboundMessage, OutboundMessage
from oclaw.interfaces.channels.wecom.wecom_bridge import WeComAdapter from interfaces.channels.wecom.wecom_bridge import WeComAdapter
from oclaw.runtime.types import normalize_interaction_mode, normalize_requested_specialist from runtime.types import normalize_interaction_mode, normalize_requested_specialist
_CHANNEL_DISPATCH_INTERACTION_KEY_PREFIX = "channel.dispatch.interaction_mode." _CHANNEL_DISPATCH_INTERACTION_KEY_PREFIX = "channel.dispatch.interaction_mode."
_CHANNEL_DISPATCH_SPECIALIST_KEY_PREFIX = "channel.dispatch.specialist." _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: 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( return build_gateway_executor(
store, store,
@ -71,8 +71,8 @@ def _handle_productivity_commands(*, text: str, tenant_id: str, user_id: str) ->
if t in ("帮助", "菜单", "help", "/help"): if t in ("帮助", "菜单", "help", "/help"):
return _menu_text() return _menu_text()
from oclaw.platform.config.paths import db_path from svc.config.paths import db_path
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
store = SqliteStore(db_path()) store = SqliteStore(db_path())
@ -114,7 +114,7 @@ def _handle_productivity_commands(*, text: str, tenant_id: str, user_id: str) ->
content = t[len("加知识 ") :].strip() content = t[len("加知识 ") :].strip()
if not content: if not content:
return "知识内容不能为空。示例:加知识 办公室WiFi密码是12345678" 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}) res = kb_add_tool().handler({"tenant_id": tenant_id, "user_id": user_id, "text": content})
if not res.get("ok"): 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() q = t[len("查知识 ") :].strip()
if not q: if not q:
return "请提供关键词。示例:查知识 WiFi 密码" 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}) res = kb_search_tool().handler({"tenant_id": tenant_id, "query": q, "limit": 5})
if not res.get("ok"): 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") user = store.get_user_by_username(tenant_id=tenant_id, username="administrator")
if not user: if not user:
try: try:
from oclaw.platform.config.passwords import load_expected_password from svc.config.passwords import load_expected_password
except Exception: except Exception:
load_expected_password = None # type: ignore load_expected_password = None # type: ignore
pwd = load_expected_password(store) if callable(load_expected_password) else None 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: 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.""" """For wechat/weixin sidecar, prefer a local file path for media send."""
try: try:
from oclaw.platform.files.attachment_assets import AttachmentAssetStore from svc.files.attachment_assets import AttachmentAssetStore
except Exception: except Exception:
return return
if not isinstance(reply, dict): if not isinstance(reply, dict):
@ -421,7 +421,7 @@ def _maybe_expand_reply_attachments_for_channel(reply: dict[str, Any]) -> None:
try: try:
import base64 import base64
from oclaw.platform.files.attachment_assets import AttachmentAssetStore from svc.files.attachment_assets import AttachmentAssetStore
except Exception: except Exception:
return return
ast = AttachmentAssetStore() 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]: 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() apply_gateway_mcp_env_to_os()
channel_name = str(payload.get("channel") or "wecom").strip().lower() 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: else:
adapter = None adapter = None
inbound = _parse_generic_inbound(channel_name, payload) inbound = _parse_generic_inbound(channel_name, payload)
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
from oclaw.platform.config.paths import db_path from svc.config.paths import db_path
store = SqliteStore(db_path()) store = SqliteStore(db_path())
if channel_name == "wecom": if channel_name == "wecom":
@ -567,8 +567,8 @@ def process_inbound_payload(payload: dict[str, Any]) -> dict[str, Any]:
if not ident: if not ident:
reply = "账号初始化失败,请检查 administrator/tenant 配置。" reply = "账号初始化失败,请检查 administrator/tenant 配置。"
if ident: if ident:
from oclaw.runtime.orchestration.policy import ActionPolicyContext, PolicyEngine from runtime.orchestration.policy import ActionPolicyContext, PolicyEngine
from oclaw.runtime.orchestration.security import has_explicit_confirmation_token from runtime.orchestration.security import has_explicit_confirmation_token
tenant_id = str(ident.get("tenant_id") or "") tenant_id = str(ident.get("tenant_id") or "")
user_id = str(ident.get("user_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() user_text = (inbound.text or "").strip()
if user_text: if user_text:
try: try:
from oclaw.runtime.gateway import OclawGateway from runtime.gateway import OclawGateway
from oclaw.runtime.types import StandardMessage from runtime.types import StandardMessage
interaction_mode, selected_specialist = _resolve_channel_dispatch( interaction_mode, selected_specialist = _resolve_channel_dispatch(
store, channel=inbound.channel, account=account store, channel=inbound.channel, account=account

View file

@ -9,9 +9,9 @@ from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, Optional from typing import Any, Optional
from oclaw.runtime.tools.base import ToolRegistry from runtime.tools.base import ToolRegistry
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
from oclaw.platform.llm.chat_models import ( from svc.llm.chat_models import (
ChatModel, ChatModel,
LLMResponse, LLMResponse,
LLMToolCall, LLMToolCall,
@ -22,8 +22,8 @@ from oclaw.platform.llm.chat_models import (
build_default_model, build_default_model,
gemini_openai_compat_client, gemini_openai_compat_client,
) )
from oclaw.runtime.prompt_templates import render_prompt_for_lang from runtime.prompt_templates import render_prompt_for_lang
from oclaw.runtime.tools.tool_validation import validate_tool_arguments from runtime.tools.tool_validation import validate_tool_arguments
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -81,13 +81,13 @@ class Agent:
def _format_ollama_failure_banner(self, exc: BaseException) -> str: def _format_ollama_failure_banner(self, exc: BaseException) -> str:
# Backward compat wrapper; implementation lives in `src.chat.agent_errors`. # 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) return format_ollama_failure_banner(lang=self.lang, exc=exc)
def _format_openai_transport_error(self, exc: BaseException) -> str: def _format_openai_transport_error(self, exc: BaseException) -> str:
# Backward compat wrapper; implementation lives in `src.chat.agent_errors`. # 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) return format_openai_transport_error(lang=self.lang, exc=exc)
@ -197,8 +197,8 @@ class Agent:
interaction_mode: str | None = None, interaction_mode: str | None = None,
selected_specialist: str | None = None, selected_specialist: str | None = None,
) -> str: ) -> str:
from oclaw.runtime.gateway import OclawGateway from runtime.gateway import OclawGateway
from oclaw.runtime.types import StandardMessage from runtime.types import StandardMessage
tenant_id = str(path_policy_tenant_id or "").strip() tenant_id = str(path_policy_tenant_id or "").strip()
user_id = str(path_policy_user_id or "").strip() user_id = str(path_policy_user_id or "").strip()
@ -256,7 +256,7 @@ class Agent:
return str(res.reply_text or "") return str(res.reply_text or "")
def _build_llm_messages(self, session_id: str) -> list[dict[str, Any]]: 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) 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() 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 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: def format_ollama_failure_banner(*, lang: str, exc: BaseException) -> str:

View file

@ -13,12 +13,12 @@ import os
import re import re
from typing import Any from typing import Any
from oclaw.platform.llm.chat_models import _normalize_image_b64_payload, gemini_openai_compat_client, ChatModel from svc.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 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 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 runtime.prompt_templates import render_prompt
from oclaw.platform.files.attachment_assets import attachment_id_to_data_url from svc.files.attachment_assets import attachment_id_to_data_url
from oclaw.runtime.relay_pointer import parse_pointer_uri from runtime.relay_pointer import parse_pointer_uri
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
_THINK_BLOCK_RE = re.compile(r"<think>\s*(.*?)\s*</think>\s*", flags=re.IGNORECASE | re.DOTALL) _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 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 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). 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`` 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 dataclasses import dataclass
from typing import Any from typing import Any
from oclaw.runtime.chat.media_redact import redact_embedded_image_blobs from runtime.chat.media_redact import redact_embedded_image_blobs
from oclaw.runtime.direct_loop import ( from runtime.direct_loop import (
_OCLAW_TOOL_RESULT_HARD_CAP_CHARS, _OCLAW_TOOL_RESULT_HARD_CAP_CHARS,
_image_tool_result_replay_cap_chars, _image_tool_result_replay_cap_chars,
_video_tool_result_replay_cap_chars, _video_tool_result_replay_cap_chars,

View file

@ -7,7 +7,7 @@ from __future__ import annotations
import base64 import base64
import os import os
from typing import Any 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"}) _IMAGE_CONTENT_TYPES = frozenset({"image", "input_image"})
_BASE64_PAYLOAD_KEYS = ("data", "image_base64", "base64", "content_base64", "body_base64") _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 dataclasses import dataclass
from typing import Any, Callable, Optional from typing import Any, Callable, Optional
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
from oclaw.runtime.tools.base import ToolRegistry from runtime.tools.base import ToolRegistry
from oclaw.platform.llm.chat_models import LLMToolCall from svc.llm.chat_models import LLMToolCall
from oclaw.runtime.tools.tool_validation import validate_tool_arguments from runtime.tools.tool_validation import validate_tool_arguments
from oclaw.runtime.chat.media_redact import ingest_embedded_image_blobs_as_refs from runtime.chat.media_redact import ingest_embedded_image_blobs_as_refs
from oclaw.runtime.tools.path_guard import ( from runtime.tools.path_guard import (
workspace_path_access_scope, workspace_path_access_scope,
workspace_write_namespace_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__) logger = logging.getLogger(__name__)
_tool_exec_log = logging.getLogger("oclaw.tool_exec") _tool_exec_log = logging.getLogger("oclaw.tool_exec")
@ -628,7 +628,7 @@ class ToolExecutor:
if not ctx.trace_id: if not ctx.trace_id:
return return
try: try:
from oclaw.runtime.orchestration.trace import new_span_id from runtime.orchestration.trace import new_span_id
ctx.store.add_trace_event( ctx.store.add_trace_event(
session_id=ctx.session_id, session_id=ctx.session_id,

View file

@ -1,8 +1,8 @@
from __future__ import annotations from __future__ import annotations
from oclaw.runtime.agent_core_run import AgentCoreRunInput, run_agent_core from runtime.agent_core_run import AgentCoreRunInput, run_agent_core
from oclaw.runtime.direct_loop import run_direct_loop from runtime.direct_loop import run_direct_loop
from oclaw.runtime.memory_stage import build_memory_context from runtime.memory_stage import build_memory_context
__all__ = ["AgentCoreRunInput", "run_agent_core", "run_direct_loop", "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 types import SimpleNamespace
from typing import Any, Callable, Optional from typing import Any, Callable, Optional
from oclaw.runtime.chat.agent_messages import build_llm_messages, get_last_build_llm_messages_stats from 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 runtime.chat.media_redact import redact_embedded_image_blobs
from oclaw.runtime.chat.tool_runtime import ToolExecutionConfig from runtime.chat.tool_runtime import ToolExecutionConfig
from oclaw.runtime.chat.turn_types import TurnRunOutcome from runtime.chat.turn_types import TurnRunOutcome
from oclaw.runtime.skill_executor import SkillExecutionContext, SkillExecutor from runtime.skill_executor import SkillExecutionContext, SkillExecutor
from oclaw.runtime.skills import build_skill_manifest from runtime.skills import build_skill_manifest
from oclaw.platform.llm.chat_models import ChatModel from svc.llm.chat_models import ChatModel
from oclaw.runtime.system_prompt import build_oclaw_executor_system_prompt from runtime.system_prompt import build_oclaw_executor_system_prompt
from oclaw.runtime.types import OclawMemoryContext from runtime.types import OclawMemoryContext
from oclaw.runtime.orchestration.trace import new_span_id from runtime.orchestration.trace import new_span_id
from oclaw.runtime.tools.base import ToolRegistry from runtime.tools.base import ToolRegistry
from oclaw.runtime.hooks_runtime import trigger_hook_event from 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 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.tools.experts.network_ops.netx_tools import ops_netx_system_context_extension
_OCLAW_TOOL_RESULT_HARD_CAP_CHARS = 24_000 _OCLAW_TOOL_RESULT_HARD_CAP_CHARS = 24_000
_OCLAW_ATTACHMENT_TEXT_REPLAY_CAP_CHARS = 4_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] raw_llm_tools = [s.as_openai_tool() for s in skill_specs]
else: else:
raw_llm_tools = tools.as_openai_tools() 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( plan = build_llm_tools_plan(
store=store, store=store,
@ -1136,7 +1136,7 @@ def _maybe_image_specialist_legacy_gateway_turn(
) -> TurnRunOutcome | None: ) -> TurnRunOutcome | None:
"""When the UI selects **image** specialist, skip Responses/chat-model transports. """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``. (``/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``. 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": if str(skill_binding_role or "").strip().lower() != "image":
return None return None
from oclaw.platform.llm.image_legacy_client import ( from svc.llm.image_legacy_client import (
IMAGE_SPECIALIST_DEFAULT_PROMPT_ZH, IMAGE_SPECIALIST_DEFAULT_PROMPT_ZH,
collect_legacy_lane_images_with_session_fallback, collect_legacy_lane_images_with_session_fallback,
legacy_image_assistant_body_with_placeholder, legacy_image_assistant_body_with_placeholder,
@ -1241,7 +1241,7 @@ def _maybe_video_specialist_legacy_gateway_turn(
) -> TurnRunOutcome | None: ) -> TurnRunOutcome | None:
"""When the UI selects **video** specialist, skip Responses/chat-model transports. """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**; 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``. 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": if str(skill_binding_role or "").strip().lower() != "video":
return None return None
from oclaw.platform.llm.image_legacy_client import collect_legacy_lane_images_with_session_fallback from svc.llm.image_legacy_client import collect_legacy_lane_images_with_session_fallback
from oclaw.platform.llm.video_generation_client import ( from svc.llm.video_generation_client import (
VIDEO_SPECIALIST_DEFAULT_PROMPT_ZH, VIDEO_SPECIALIST_DEFAULT_PROMPT_ZH,
legacy_video_assistant_body_with_placeholder, legacy_video_assistant_body_with_placeholder,
legacy_video_turn_bundle, legacy_video_turn_bundle,

View file

@ -15,7 +15,7 @@ import re
import uuid import uuid
from typing import Any 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). # Official DeepSeek-V4 DSML token uses FULLWIDTH VERTICAL LINE (U+FF5C).
_DSML_PIPE = "\uFF5C" _DSML_PIPE = "\uFF5C"

View file

@ -1,7 +1,7 @@
from __future__ import annotations from __future__ import annotations
from .api import build_anthropic_provider 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" PLUGIN_ID = "anthropic"

View file

@ -1,7 +1,7 @@
from __future__ import annotations from __future__ import annotations
from .api import build_deepseek_provider 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" PROVIDER_ID = "deepseek"

View file

@ -1,6 +1,6 @@
from __future__ import annotations 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 from .api import list_runtime_image_generation_providers

View file

@ -1,7 +1,7 @@
from __future__ import annotations from __future__ import annotations
from .api import build_kimi_coding_provider 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" PLUGIN_ID = "kimi"

View file

@ -1,6 +1,6 @@
from __future__ import annotations 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_ID = "memory-core"
PLUGIN_NAME = "Memory (Core)" PLUGIN_NAME = "Memory (Core)"

View file

@ -1,6 +1,6 @@
from __future__ import annotations 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"] __all__ = ["PluginEntry", "define_plugin_entry"]

View file

@ -3,7 +3,7 @@ from __future__ import annotations
import html import html
import re 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 = ( PROMPT_INJECTION_PATTERNS = (
re.compile(r"ignore (all|any|previous|above|prior) instructions", re.I), re.compile(r"ignore (all|any|previous|above|prior) instructions", re.I),

View file

@ -1,6 +1,6 @@
from __future__ import annotations 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 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_image_generation_provider,
build_openai_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: def register_openai_plugin(api) -> None:

View file

@ -1,5 +1,5 @@
from __future__ import annotations 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"] __all__ = ["PluginApi", "PluginEntry", "PluginLogger", "PluginRuntime", "define_plugin_entry"]

View file

@ -1,7 +1,7 @@
from __future__ import annotations from __future__ import annotations
from .api import QWEN_BASE_URL, build_qwen_provider 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" PROVIDER_ID = "qwen"

View file

@ -1,7 +1,7 @@
from __future__ import annotations from __future__ import annotations
from .api import telegram_plugin 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: def register_telegram_channel(api) -> None:

View file

@ -10,39 +10,39 @@ from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from typing import Any, Callable, Optional from typing import Any, Callable, Optional
from oclaw.runtime.agents.factory import build_ephemeral_executor from runtime.agents.factory import build_ephemeral_executor
from oclaw.runtime.hooks.eligibility_from_metadata import hook_eligibility_from_message_metadata from runtime.hooks.eligibility_from_metadata import hook_eligibility_from_message_metadata
from oclaw.runtime.hooks_runtime import ( from runtime.hooks_runtime import (
get_active_hooks_config, get_active_hooks_config,
initialize_hooks_runtime, initialize_hooks_runtime,
trigger_hook_event, trigger_hook_event,
) )
from oclaw.runtime.relay_pointer import summarize_relay_ttl from runtime.relay_pointer import summarize_relay_ttl
from oclaw.runtime.skills import build_skill_manifest from runtime.skills import build_skill_manifest
from oclaw.runtime.prompt_prebuild import get_manager_prompt_prebuild from runtime.prompt_prebuild import get_manager_prompt_prebuild
from oclaw.runtime.types import ( from runtime.types import (
OclawSessionContext, OclawSessionContext,
StandardMessage, StandardMessage,
normalize_interaction_mode, normalize_interaction_mode,
normalize_requested_specialist, normalize_requested_specialist,
) )
from oclaw.platform.config.paths import PROJECT_ROOT from svc.config.paths import PROJECT_ROOT
from oclaw.runtime.prompt_templates import render_prompt from runtime.prompt_templates import render_prompt
from oclaw.runtime.command_parser import parse_internal_command from runtime.command_parser import parse_internal_command
from oclaw.runtime.core.agent_execution import AgentCoreRunInput, build_memory_context, run_agent_core from runtime.core.agent_execution import AgentCoreRunInput, build_memory_context, run_agent_core
from oclaw.runtime.router import decide_route from runtime.router import decide_route
from oclaw.runtime.worker import ensure_worker_started from runtime.worker import ensure_worker_started
from oclaw.runtime.orchestration.trace import new_span_id, new_trace_id from runtime.orchestration.trace import new_span_id, new_trace_id
from oclaw.runtime.chat.tool_runtime import compact_turn_tool_messages_for_storage from 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 runtime.chat.model_path_audit import ensure_no_tool_or_embedded_image_payload
from oclaw.runtime.session_auto_title import ( from runtime.session_auto_title import (
AUTO_TITLE_SYSTEM_PROMPT_EN, AUTO_TITLE_SYSTEM_PROMPT_EN,
AUTO_TITLE_SYSTEM_PROMPT_ZH, AUTO_TITLE_SYSTEM_PROMPT_ZH,
finalize_auto_title, finalize_auto_title,
) )
from oclaw.runtime.tools.base import ToolRegistry from runtime.tools.base import ToolRegistry
from oclaw.runtime.tools.public.local_sdk import local_adapter_startup_self_check from runtime.tools.public.local_sdk import local_adapter_startup_self_check
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -953,8 +953,8 @@ class OclawGateway:
system_prompt_override = "" system_prompt_override = ""
tools_override = None tools_override = None
if interaction_mode == "expert": if interaction_mode == "expert":
from oclaw.runtime.plan_agent_v2.gateway_adapter import evaluate_gateway_expert_turn_shadow from 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.tool_specs import DEFAULT_SESSION_KEY, materialize_plan_mode_v2_tools
execution_mode = str(base_metadata.get("execution_mode") or "agent").strip().lower() execution_mode = str(base_metadata.get("execution_mode") or "agent").strip().lower()
if execution_mode not in {"agent", "plan"}: if execution_mode not in {"agent", "plan"}:
@ -1022,7 +1022,7 @@ class OclawGateway:
except Exception: except Exception:
plan_mode = "" plan_mode = ""
if plan_mode == "plan": 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): if isinstance(tools_override, ToolRegistry):
filtered = filter_tools_for_mode(registry=tools_override, mode="plan") 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 #### Quick check
```bash ```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`. 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 | | package.json `openclaw.hooks` / `oclaw.hooks` | Done |
| plugin hook dirs (`.codex-plugin` + `hooks`) | Done | | plugin hook dirs (`.codex-plugin` + `hooks`) | Done |
| legacy `hooks.internal.handlers` | 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 | | `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) | | 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. | | 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`) ### Operations CLI (from parent of this repo on `sys.path`, see `tests/conftest.py`)
```bash ```bash
python -m oclaw.runtime.operations hooks list python -m runtime.operations hooks list
python -m oclaw.runtime.operations hooks list --eligible --verbose python -m runtime.operations hooks list --eligible --verbose
python -m oclaw.runtime.operations hooks check --json python -m runtime.operations hooks check --json
python -m oclaw.runtime.operations hooks info session-memory --workspace /path/to/workspace python -m 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 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 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 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 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`). 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: if str(OCLAW_DIR) not in sys.path:
sys.path.insert(0, str(OCLAW_DIR)) sys.path.insert(0, str(OCLAW_DIR))
from oclaw.runtime.hooks.internal_hooks import create_hook_event, trigger_hook # noqa: E402 from 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.loader import load_internal_hooks # noqa: E402
def main() -> int: def main() -> int:

View file

@ -122,8 +122,8 @@ def handle(event: Any) -> None:
# Fetch recent messages from sqlite. # Fetch recent messages from sqlite.
try: try:
_ensure_repo_imports() _ensure_repo_imports()
from oclaw.platform.config.paths import db_path # type: ignore from svc.config.paths import db_path # type: ignore
from oclaw.platform.persistence.sqlite_store import SqliteStore # type: ignore from svc.persistence.sqlite_store import SqliteStore # type: ignore
store = SqliteStore(db_path()) store = SqliteStore(db_path())
msgs = store.get_messages(session_id=session_id, limit=max_msgs_n) 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 pathlib import Path
from typing import Any 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]: 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 pathlib import Path
from typing import Any 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: def resolve_hooks_config_storage_path() -> Path:

View file

@ -9,10 +9,10 @@ from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
from oclaw.runtime.hooks.hook_types import HookEligibilityContext from runtime.hooks.hook_types import HookEligibilityContext
from oclaw.runtime.hooks.merge_skill_hook_dirs import merge_skill_hook_extra_dirs_into_config from runtime.hooks.merge_skill_hook_dirs import merge_skill_hook_extra_dirs_into_config
from oclaw.platform.config.paths import PROJECT_ROOT from svc.config.paths import PROJECT_ROOT
from oclaw.platform.config.runtime_paths import runtime_hooks_bundled_root from svc.config.runtime_paths import runtime_hooks_bundled_root
@dataclass @dataclass
@ -42,7 +42,7 @@ class _GmailWatcherLogAdapter:
def _maybe_start_gmail_watcher_with_logs(resolved_cfg: dict[str, Any]) -> None: 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.""" """After hooks load: parity hook for OpenClaw gateway post-attach Gmail lifecycle."""
try: 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()) start_gmail_watcher_with_logs(cfg=resolved_cfg, log=_GmailWatcherLogAdapter())
except Exception: except Exception:
@ -128,7 +128,7 @@ def initialize_hooks_runtime(
return int(_STATE.loaded_count or 0) return int(_STATE.loaded_count or 0)
try: try:
oclaw_dir = _ensure_oclaw_path() 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() bundled_dir = runtime_hooks_bundled_root()
resolved_cfg = merge_skill_hook_extra_dirs_into_config(dict(cfg or resolve_runtime_config() or {})) 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 pathlib import Path
from typing import Any from typing import Any
from oclaw.runtime.types import OclawMemoryContext from runtime.types import OclawMemoryContext
from oclaw.runtime.orchestration.memory import semantic_retrieve, session_memory_digest from runtime.orchestration.memory import semantic_retrieve, session_memory_digest
from oclaw.runtime.prompt_templates import render_runtime_prompt from runtime.prompt_templates import render_runtime_prompt
_SPECIALIST_FLAGS_SETTING_KEY = "AIA_CHAT_SPECIALIST_FLAGS_JSON" _SPECIALIST_FLAGS_SETTING_KEY = "AIA_CHAT_SPECIALIST_FLAGS_JSON"
@ -145,8 +145,8 @@ def after_turn_memory(
assistant_text=assistant_text, assistant_text=assistant_text,
) )
try: try:
from oclaw.runtime.orchestration.memory import maybe_write_turn_memory from runtime.orchestration.memory import maybe_write_turn_memory
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
if isinstance(store, SqliteStore): if isinstance(store, SqliteStore):
maybe_write_turn_memory( maybe_write_turn_memory(

View file

@ -19,21 +19,21 @@ _DEPREC_UPDATE = (
" • If you use the OpenClaw app: use `openclaw plugins update`.\n" " • If you use the OpenClaw app: use `openclaw plugins update`.\n"
) )
from oclaw.platform.config.runtime_paths import runtime_hooks_bundled_root from svc.config.runtime_paths import runtime_hooks_bundled_root
from oclaw.runtime.hooks.config import should_include_hook from runtime.hooks.config import should_include_hook
from oclaw.runtime.hooks.frontmatter import resolve_hook_key from runtime.hooks.frontmatter import resolve_hook_key
from oclaw.runtime.hooks.hooks_status import build_workspace_hook_status from runtime.hooks.hooks_status import build_workspace_hook_status
from oclaw.runtime.hooks.hook_types import HookEntry from runtime.hooks.hook_types import HookEntry
from oclaw.runtime.hooks.merge_skill_hook_dirs import merge_skill_hook_extra_dirs_into_config from runtime.hooks.merge_skill_hook_dirs import merge_skill_hook_extra_dirs_into_config
from oclaw.runtime.hooks.user_config_hooks import ( from runtime.hooks.user_config_hooks import (
apply_hook_entry_enabled, apply_hook_entry_enabled,
load_storage_config_document, load_storage_config_document,
resolve_hooks_config_storage_path, resolve_hooks_config_storage_path,
save_storage_config_document, save_storage_config_document,
) )
from oclaw.runtime.hooks.workspace import load_workspace_hook_entries from runtime.hooks.workspace import load_workspace_hook_entries
from oclaw.runtime.hooks_runtime import resolve_runtime_config from runtime.hooks_runtime import resolve_runtime_config
from oclaw.runtime.tools.path_guard import workspace_root from runtime.tools.path_guard import workspace_root
def _resolve_cli_workspace(ns: argparse.Namespace) -> str: def _resolve_cli_workspace(ns: argparse.Namespace) -> str:
@ -196,7 +196,7 @@ def _cmd_hooks_info(args: argparse.Namespace) -> int:
if args.json: if args.json:
print(json.dumps({"error": "not_found", "hook": name}, indent=2)) print(json.dumps({"error": "not_found", "hook": name}, indent=2))
else: 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 return 1
if args.json: if args.json:
print(json.dumps(row, indent=2, default=str)) 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() name = str(getattr(args, "name", "") or "").strip()
entry = find_hook_entry_for_name(ws, name, config=None) entry = find_hook_entry_for_name(ws, name, config=None)
if entry is 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 return 1
if entry.hook.source == "oclaw-plugin": if entry.hook.source == "oclaw-plugin":
print("Plugin-managed hooks cannot be enabled via this CLI; enable or configure the plugin instead.") 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 os
import sys import sys
from oclaw.runtime.operations.hooks_cmd import register_hooks_parser from runtime.operations.hooks_cmd import register_hooks_parser
from oclaw.runtime.operations.memory import register_memory_parser from runtime.operations.memory import register_memory_parser
from oclaw.runtime.operations.providers.registry import build_channel_registry from runtime.operations.providers.registry import build_channel_registry
from oclaw.runtime.operations.stack import register_stack_parser from runtime.operations.stack import register_stack_parser
def _cmd_gateway_start(args: argparse.Namespace) -> int: 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 os.environ["AIA_ASSISTANT_GATEWAY_HOST"] = args.host
if args.port is not None: if args.port is not None:
os.environ["AIA_ASSISTANT_GATEWAY_PORT"] = str(args.port) 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() 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() return fastapi_main()
def _build_parser() -> argparse.ArgumentParser: 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) root_sub = p.add_subparsers(dest="root_cmd", required=True)
registry = build_channel_registry() registry = build_channel_registry()

View file

@ -5,7 +5,7 @@ from __future__ import annotations
import os import os
from pathlib import Path 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 = ( _DEFAULT_ALLOWLIST = (
"BRAVE_API_KEY,GOOGLE_OAUTH_CREDENTIALS,GOOGLE_CALENDAR_MCP_TOKEN_PATH," "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 pathlib import Path
from typing import Any from typing import Any
from oclaw.platform.config.paths import PROJECT_ROOT from svc.config.paths import PROJECT_ROOT
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
from oclaw.runtime.tools.mcp.registry import McpRegistry from runtime.tools.mcp.registry import McpRegistry
_EXPORT_FILENAME = "mcp_registry_migrated.json" _EXPORT_FILENAME = "mcp_registry_migrated.json"
_LOCAL_DIR = (PROJECT_ROOT / "_local").resolve() _LOCAL_DIR = (PROJECT_ROOT / "_local").resolve()

View file

@ -6,9 +6,9 @@ import secrets
import sys import sys
from argparse import _SubParsersAction from argparse import _SubParsersAction
from oclaw.interfaces.channels.wecom.longconn_runner import run_forever as run_wecom_longconn from interfaces.channels.wecom.longconn_runner import run_forever as run_wecom_longconn
from oclaw.platform.config.paths import db_path from svc.config.paths import db_path
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
from .base import ChannelProvider from .base import ChannelProvider
@ -101,7 +101,7 @@ class WecomProvider(ChannelProvider):
return run_wecom_longconn() return run_wecom_longconn()
def _cmd_status(self, _args: argparse.Namespace) -> int: 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() return status_main()
@ -150,7 +150,7 @@ class WecomProvider(ChannelProvider):
return 0 return 0
def _cmd_smoke(self, args: argparse.Namespace) -> int: 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 old = sys.argv
try: try:
@ -206,6 +206,6 @@ class WecomProvider(ChannelProvider):
print("ok=1") print("ok=1")
print("mode=bot_api") print("mode=bot_api")
print(f"bot_id={args.bot_id}") 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 return 0

View file

@ -9,7 +9,7 @@ from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
from oclaw.platform.config.paths import db_path from svc.config.paths import db_path
def _runtime_file() -> Path: def _runtime_file() -> Path:
@ -76,13 +76,13 @@ def _python_bin() -> str:
def _service_signature(name: str) -> str | None: def _service_signature(name: str) -> str | None:
n = str(name or "").strip().lower() n = str(name or "").strip().lower()
if n == "gateway": if n == "gateway":
return "-m oclaw.runtime.operations gateway start" return "-m runtime.operations gateway start"
if n == "ui": if n == "ui":
return "-m oclaw.runtime.operations ui start" return "-m runtime.operations ui start"
if n.startswith("channel:"): if n.startswith("channel:"):
ch = n.split(":", 1)[1].strip() ch = n.split(":", 1)[1].strip()
if ch: if ch:
return f"-m oclaw.runtime.operations channel {ch} start" return f"-m runtime.operations channel {ch} start"
return None return None

View file

@ -3,8 +3,8 @@ from __future__ import annotations
import secrets import secrets
import sys import sys
from oclaw.platform.config.paths import db_path from svc.config.paths import db_path
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
def main() -> int: def main() -> int:

View file

@ -2,7 +2,7 @@ from __future__ import annotations
from pathlib import Path 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] = { _PS1_FORWARDERS: dict[str, str] = {

View file

@ -11,9 +11,9 @@ from pathlib import Path
ROOT = Path(__file__).resolve().parents[1] ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT)) sys.path.insert(0, str(ROOT))
from oclaw.platform.config.paths import db_path # noqa: E402 from svc.config.paths import db_path # noqa: E402
from oclaw.platform.persistence.sqlite_store import SqliteStore # noqa: E402 from svc.persistence.sqlite_store import SqliteStore # noqa: E402
from oclaw.runtime.tools.mcp.installer import McpServerManifest, _safe_server_id, install_mcp_server # 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) # (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] ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT)) sys.path.insert(0, str(ROOT))
from oclaw.platform.config.paths import db_path # noqa: E402 from svc.config.paths import db_path # noqa: E402
from oclaw.platform.persistence.sqlite_store import SqliteStore # noqa: E402 from svc.persistence.sqlite_store import SqliteStore # noqa: E402
from oclaw.runtime.tools.mcp.installer import McpServerManifest, install_mcp_server # noqa: E402 from runtime.tools.mcp.installer import McpServerManifest, install_mcp_server # noqa: E402
from oclaw.runtime.tools.mcp.runtime import McpProcessRuntime # noqa: E402 from runtime.tools.mcp.runtime import McpProcessRuntime # noqa: E402
_BINDING_KEY = "mcp_specialist_server_binding" _BINDING_KEY = "mcp_specialist_server_binding"

View file

@ -13,10 +13,10 @@ from pathlib import Path
ROOT = Path(__file__).resolve().parents[1] ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT)) sys.path.insert(0, str(ROOT))
from oclaw.platform.config.paths import db_path # noqa: E402 from svc.config.paths import db_path # noqa: E402
from oclaw.platform.persistence.sqlite_store import SqliteStore # noqa: E402 from svc.persistence.sqlite_store import SqliteStore # noqa: E402
from oclaw.runtime.tools.mcp.installer import McpServerManifest, install_mcp_server # noqa: E402 from runtime.tools.mcp.installer import McpServerManifest, install_mcp_server # noqa: E402
from oclaw.runtime.tools.mcp.runtime import McpProcessRuntime # noqa: E402 from runtime.tools.mcp.runtime import McpProcessRuntime # noqa: E402
def _sync_tools(store: SqliteStore, server_id: str) -> bool: 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 # Same bootstrap as gateway: ``interfaces/http/fastapi_app.py`` calls ``load_system_env()`` so
# ``oclaw/_local/system.env`` is merged before reading ``OPENAI_*``. # ``oclaw/_local/system.env`` is merged before reading ``OPENAI_*``.
try: try:
from oclaw.platform.config.bootstrap_env import load_system_env from svc.config.bootstrap_env import load_system_env
load_system_env() load_system_env()
except ImportError: except ImportError:

View file

@ -15,9 +15,9 @@ from pathlib import Path
ROOT = Path(__file__).resolve().parents[1] ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT)) sys.path.insert(0, str(ROOT))
from oclaw.platform.config.paths import PROJECT_ROOT, db_path # noqa: E402 from svc.config.paths import PROJECT_ROOT, db_path # noqa: E402
from oclaw.platform.persistence.sqlite_store import SqliteStore # noqa: E402 from svc.persistence.sqlite_store import SqliteStore # noqa: E402
from oclaw.runtime.tools.mcp.installer import McpServerManifest, _safe_server_id, install_mcp_server # noqa: E402 from runtime.tools.mcp.installer import McpServerManifest, _safe_server_id, install_mcp_server # noqa: E402
def _subst_repo(path_str: str) -> str: def _subst_repo(path_str: str) -> str:

View file

@ -2,8 +2,8 @@ from __future__ import annotations
import sys import sys
from oclaw.platform.config.paths import db_path from svc.config.paths import db_path
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
def _to_bool(v: str) -> str: def _to_bool(v: str) -> str:

View file

@ -2,8 +2,8 @@ from __future__ import annotations
import sys import sys
from oclaw.platform.config.paths import db_path from svc.config.paths import db_path
from oclaw.platform.persistence.sqlite_store import SqliteStore from svc.persistence.sqlite_store import SqliteStore
def main() -> int: def main() -> int:

View file

@ -43,9 +43,8 @@ if (-not $repoRoot) {
# Fallback: old relative layout assumption # Fallback: old relative layout assumption
$repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) $repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
} }
$repoParent = Split-Path -Parent $repoRoot
Set-Location $repoRoot Set-Location $repoRoot
$env:PYTHONPATH = $repoParent $env:PYTHONPATH = $repoRoot
$env:PYTHONSAFEPATH = "1" $env:PYTHONSAFEPATH = "1"
$env:AIA_WORKSPACE_ROOT = $repoRoot $env:AIA_WORKSPACE_ROOT = $repoRoot
$env:OPS_WORKSPACE_ROOT = $repoRoot $env:OPS_WORKSPACE_ROOT = $repoRoot

View file

@ -8,7 +8,6 @@
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
$repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) $repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
$repoParent = Split-Path -Parent $repoRoot
$desktopDir = Join-Path $repoRoot "desktop" $desktopDir = Join-Path $repoRoot "desktop"
$runDir = Join-Path $PSScriptRoot ".run" $runDir = Join-Path $PSScriptRoot ".run"
New-Item -ItemType Directory -Force -Path $runDir | Out-Null New-Item -ItemType Directory -Force -Path $runDir | Out-Null
@ -22,7 +21,7 @@ if (-not (Test-Path $desktopDir)) {
} }
Set-Location $desktopDir Set-Location $desktopDir
$env:PYTHONPATH = $repoParent $env:PYTHONPATH = $repoRoot
$env:PYTHONSAFEPATH = "1" $env:PYTHONSAFEPATH = "1"
$env:AIA_WORKSPACE_ROOT = $repoRoot $env:AIA_WORKSPACE_ROOT = $repoRoot
$env:OPS_WORKSPACE_ROOT = $repoRoot $env:OPS_WORKSPACE_ROOT = $repoRoot

View file

@ -39,7 +39,6 @@ if (-not $repoRoot) {
# Fallback: old relative layout assumption # Fallback: old relative layout assumption
$repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) $repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
} }
$repoParent = Split-Path -Parent $repoRoot
Set-Location $repoRoot Set-Location $repoRoot
$runDir = Join-Path $PSScriptRoot ".run" $runDir = Join-Path $PSScriptRoot ".run"
@ -49,7 +48,8 @@ $pidFile = Join-Path $runDir "gateway.pid"
Write-Step "Project root: $repoRoot" Write-Step "Project root: $repoRoot"
Write-Step "Working directory: $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:PYTHONSAFEPATH = "1"
$env:AIA_WORKSPACE_ROOT = $repoRoot $env:AIA_WORKSPACE_ROOT = $repoRoot
$env:OPS_WORKSPACE_ROOT = $repoRoot $env:OPS_WORKSPACE_ROOT = $repoRoot
@ -95,7 +95,7 @@ if ($WithWikiWorker) {
if ($Background) { if ($Background) {
Write-Step "Starting gateway in 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 Set-Content -Path $pidFile -Value "$($p.Id)" -Encoding ascii
Write-Host "gateway.pid = $pidFile" -ForegroundColor DarkGray Write-Host "gateway.pid = $pidFile" -ForegroundColor DarkGray
Write-Host "PID = $($p.Id)" -ForegroundColor Green Write-Host "PID = $($p.Id)" -ForegroundColor Green
@ -103,7 +103,7 @@ if ($Background) {
} }
Write-Step "Starting gateway (foreground)" 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 # Fallback: old relative layout assumption
$repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) $repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
} }
$repoParent = Split-Path -Parent $repoRoot
Set-Location $repoRoot Set-Location $repoRoot
Write-Step "Project root: $repoRoot" Write-Step "Project root: $repoRoot"
Write-Step "Working directory: $repoRoot" Write-Step "Working directory: $repoRoot"
$env:PYTHONPATH = $repoParent $env:PYTHONPATH = $repoRoot
$env:PYTHONSAFEPATH = "1" $env:PYTHONSAFEPATH = "1"
$env:AIA_WORKSPACE_ROOT = $repoRoot $env:AIA_WORKSPACE_ROOT = $repoRoot
$env:OPS_WORKSPACE_ROOT = $repoRoot $env:OPS_WORKSPACE_ROOT = $repoRoot
@ -72,21 +71,21 @@ if (-not $SkipInstall) {
if (-not $SkipConfigHint) { if (-not $SkipConfigHint) {
Write-Step "Current WeCom status" Write-Step "Current WeCom status"
try { try {
& $pythonExe -m oclaw.runtime.operations channel wecom status & $pythonExe -m runtime.operations channel wecom status
} catch { } catch {
Write-Host "[WARN] Unable to read WeCom status yet." -ForegroundColor Yellow Write-Host "[WARN] Unable to read WeCom status yet." -ForegroundColor Yellow
} }
Write-Host "" Write-Host ""
Write-Host "If WeCom is not configured yet, run this first:" -ForegroundColor Yellow 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-Host ""
} }
Write-Step "Stopping previous stack (safe if not running)" 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" Write-Step "Starting stack: python -m runtime.operations stack up --channel $Channel"
& $pythonExe -m oclaw.runtime.operations stack up --channel $Channel & $pythonExe -m runtime.operations stack up --channel $Channel
Write-Host "" Write-Host ""
Write-Host "Started successfully." -ForegroundColor Green 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 "Chat: http://127.0.0.1:8787/chat"
Write-Host "" Write-Host ""
Write-Host "Useful commands:" Write-Host "Useful commands:"
Write-Host " python -m oclaw.runtime.operations stack status" Write-Host " python -m runtime.operations stack status"
Write-Host " python -m oclaw.runtime.operations stack down" Write-Host " python -m runtime.operations stack down"

View file

@ -10,7 +10,6 @@ function Resolve-RepoRoot {
} }
$repoRoot = Resolve-RepoRoot $repoRoot = Resolve-RepoRoot
$repoParent = Split-Path -Parent $repoRoot
$runDir = Join-Path $PSScriptRoot ".run" $runDir = Join-Path $PSScriptRoot ".run"
$null = New-Item -ItemType Directory -Force -Path $runDir -ErrorAction SilentlyContinue $null = New-Item -ItemType Directory -Force -Path $runDir -ErrorAction SilentlyContinue
$pidFile = Join-Path $runDir "wiki_worker.pid" $pidFile = Join-Path $runDir "wiki_worker.pid"
@ -30,7 +29,7 @@ function Test-IsWikiWorkerPid([int]$procId) {
try { try {
$wmi = Get-CimInstance Win32_Process -Filter "ProcessId = $procId" -ErrorAction Stop $wmi = Get-CimInstance Win32_Process -Filter "ProcessId = $procId" -ErrorAction Stop
$cmd = [string]($wmi.CommandLine) $cmd = [string]($wmi.CommandLine)
return $cmd -like "*oclaw.runtime.workers.wiki.main*" return $cmd -like "*runtime.workers.wiki.main*"
} catch { } catch {
return $false return $false
} }
@ -46,14 +45,14 @@ if (Test-Path $venvPython) {
} }
$pythonExe = "python" $pythonExe = "python"
} }
$env:PYTHONPATH = $repoParent $env:PYTHONPATH = $repoRoot
$env:PYTHONSAFEPATH = "1" $env:PYTHONSAFEPATH = "1"
$env:AIA_WORKSPACE_ROOT = $repoRoot $env:AIA_WORKSPACE_ROOT = $repoRoot
$env:OPS_WORKSPACE_ROOT = $repoRoot $env:OPS_WORKSPACE_ROOT = $repoRoot
$env:OCLAW_WORKSPACE = $repoRoot $env:OCLAW_WORKSPACE = $repoRoot
if (-not $Background) { if (-not $Background) {
& $pythonExe -m oclaw.runtime.workers.wiki.main & $pythonExe -m runtime.workers.wiki.main
exit 0 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 Set-Content -Path $pidFile -Value $p.Id -Encoding ascii
Write-Host "[ok] started wiki worker pid=$($p.Id) out=$outLog err=$errLog" 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)) $repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
$repoParent = Split-Path -Parent $repoRoot
Set-Location $repoRoot Set-Location $repoRoot
$env:PYTHONPATH = $repoParent $env:PYTHONPATH = $repoRoot
$env:PYTHONSAFEPATH = "1" $env:PYTHONSAFEPATH = "1"
$env:AIA_WORKSPACE_ROOT = $repoRoot $env:AIA_WORKSPACE_ROOT = $repoRoot
$env:OPS_WORKSPACE_ROOT = $repoRoot $env:OPS_WORKSPACE_ROOT = $repoRoot
@ -23,11 +22,11 @@ if (Test-Path $venvPython) {
Write-Step "Project root: $repoRoot" Write-Step "Project root: $repoRoot"
Write-Step "Working directory: $repoRoot" Write-Step "Working directory: $repoRoot"
Write-Step "Stack status" Write-Step "Stack status"
& $pythonExe -m oclaw.runtime.operations stack status & $pythonExe -m runtime.operations stack status
Write-Host "" Write-Host ""
Write-Step "WeCom status" Write-Step "WeCom status"
& $pythonExe -m oclaw.runtime.operations channel wecom status & $pythonExe -m runtime.operations channel wecom status
Write-Host "" Write-Host ""
Write-Host "Admin: http://127.0.0.1:8787/admin" Write-Host "Admin: http://127.0.0.1:8787/admin"

View file

@ -30,9 +30,8 @@ if (-not $repoRoot) {
# Fallback: old relative layout assumption # Fallback: old relative layout assumption
$repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) $repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
} }
$repoParent = Split-Path -Parent $repoRoot
Set-Location $repoRoot Set-Location $repoRoot
$env:PYTHONPATH = $repoParent $env:PYTHONPATH = $repoRoot
$env:PYTHONSAFEPATH = "1" $env:PYTHONSAFEPATH = "1"
$env:AIA_WORKSPACE_ROOT = $repoRoot $env:AIA_WORKSPACE_ROOT = $repoRoot
$env:OPS_WORKSPACE_ROOT = $repoRoot $env:OPS_WORKSPACE_ROOT = $repoRoot
@ -50,7 +49,7 @@ Write-Step "Working directory: $repoRoot"
Write-Step "Stopping stack services..." Write-Step "Stopping stack services..."
try { try {
& $pythonExe -m oclaw.runtime.operations stack down & $pythonExe -m runtime.operations stack down
Write-Host "Stack stopped." -ForegroundColor Green Write-Host "Stack stopped." -ForegroundColor Green
} catch { } catch {
Write-Host "[WARN] stack down failed: $($_.Exception.Message)" -ForegroundColor Yellow Write-Host "[WARN] stack down failed: $($_.Exception.Message)" -ForegroundColor Yellow
@ -61,7 +60,7 @@ try {
Write-Step "Current status" Write-Step "Current status"
try { try {
& $pythonExe -m oclaw.runtime.operations stack status & $pythonExe -m runtime.operations stack status
} catch { } catch {
Write-Host "[WARN] Unable to read status after stop." -ForegroundColor Yellow 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