Files
wehub-resource-sync 4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

81 lines
2.4 KiB
Python

"""Lifecycle and execution orchestration for the Pi coding tool.
These are the stages ``PiCodingTool.run`` drives, kept as small free functions so
the tool class stays a thin agent-facing contract:
- :func:`ensure_enabled` — opt-in gate (``PI_CODING_ENABLED``).
- :func:`ensure_cli_ready` — Pi binary installed and authenticated.
- :func:`execute` — run the polled Pi process (``integrations/pi`` client).
- :func:`to_output` — shape a stable result dict (with ``error_kind``).
- :func:`error_output` — the same dict shape for an early/expected failure.
"""
from __future__ import annotations
from typing import Any, Final
from integrations.pi import (
PiCodingResult,
is_pi_coding_enabled,
run_pi_coding_task,
verify_pi_coding,
)
from tools.pi_coding_tool.errors import (
ERR_CLI_UNAVAILABLE,
ERR_DISABLED,
ERR_EXECUTION,
ERR_TIMEOUT,
PiCodingError,
)
from tools.pi_coding_tool.validation import ResolvedRequest
#: Evidence source tag stamped on every result dict.
SOURCE: Final = "knowledge"
_DISABLED_MESSAGE = (
"Pi coding tool is disabled. Set PI_CODING_ENABLED=1 (and install/authenticate "
"the Pi CLI) to enable it."
)
def ensure_enabled() -> None:
if not is_pi_coding_enabled():
raise PiCodingError(ERR_DISABLED, _DISABLED_MESSAGE)
def ensure_cli_ready() -> None:
available, detail = verify_pi_coding()
if not available:
raise PiCodingError(ERR_CLI_UNAVAILABLE, f"Pi CLI is not ready: {detail}")
def execute(request: ResolvedRequest) -> PiCodingResult:
return run_pi_coding_task(
request.task,
workspace=request.workspace,
model=request.model,
timeout_sec=request.timeout_sec,
)
def to_output(result: PiCodingResult) -> dict[str, Any]:
error_kind: str | None = None
if not result.success:
error_kind = ERR_TIMEOUT if result.timed_out else ERR_EXECUTION
return {
"source": SOURCE,
"success": result.success,
"error_kind": error_kind,
"summary": result.summary,
"changed_files": result.changed_files,
"diff": result.diff,
"diff_truncated": result.diff_truncated,
"returncode": result.returncode,
"timed_out": result.timed_out,
"error": result.error,
}
def error_output(kind: str, message: str) -> dict[str, Any]:
return {"source": SOURCE, "success": False, "error_kind": kind, "error": message}