mirror of
https://github.com/microsoft/SkillOpt.git
synced 2026-07-06 07:32:34 +08:00
186 lines
7.7 KiB
Python
186 lines
7.7 KiB
Python
"""Runtime backend configuration for optimizer/target model calls."""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
|
|
from skillopt.model.common import default_model_for_backend, normalize_backend_name
|
|
|
|
|
|
def _parse_bool(value: str | None, default: bool) -> bool:
|
|
if value is None:
|
|
return default
|
|
return str(value).strip().lower() in {"1", "true", "yes", "on"}
|
|
|
|
|
|
OPTIMIZER_BACKEND = normalize_backend_name(os.environ.get("OPTIMIZER_BACKEND", "openai_chat"))
|
|
TARGET_BACKEND = normalize_backend_name(os.environ.get("TARGET_BACKEND", "openai_chat"))
|
|
|
|
CODEX_EXEC_PATH = os.environ.get("CODEX_EXEC_PATH", "codex")
|
|
CODEX_EXEC_SANDBOX = os.environ.get("CODEX_EXEC_SANDBOX", "workspace-write")
|
|
CODEX_EXEC_PROFILE = os.environ.get("CODEX_EXEC_PROFILE", "")
|
|
CODEX_EXEC_FULL_AUTO = _parse_bool(os.environ.get("CODEX_EXEC_FULL_AUTO"), True)
|
|
CODEX_EXEC_REASONING_EFFORT = os.environ.get("CODEX_EXEC_REASONING_EFFORT", "none")
|
|
CODEX_EXEC_USE_SDK = os.environ.get("CODEX_EXEC_USE_SDK", "auto")
|
|
CODEX_EXEC_NETWORK_ACCESS = _parse_bool(os.environ.get("CODEX_EXEC_NETWORK_ACCESS"), False)
|
|
CODEX_EXEC_WEB_SEARCH = _parse_bool(os.environ.get("CODEX_EXEC_WEB_SEARCH"), False)
|
|
CODEX_EXEC_APPROVAL_POLICY = os.environ.get("CODEX_EXEC_APPROVAL_POLICY", "never")
|
|
CLAUDE_CODE_EXEC_PATH = os.environ.get("CLAUDE_CODE_EXEC_PATH", "claude")
|
|
CLAUDE_CODE_EXEC_PROFILE = os.environ.get("CLAUDE_CODE_EXEC_PROFILE", "")
|
|
CLAUDE_CODE_EXEC_USE_SDK = os.environ.get("CLAUDE_CODE_EXEC_USE_SDK", "auto")
|
|
CLAUDE_CODE_EXEC_EFFORT = os.environ.get("CLAUDE_CODE_EXEC_EFFORT", "medium")
|
|
|
|
|
|
def _parse_int(value: str | None, default: int) -> int:
|
|
if value is None:
|
|
return default
|
|
try:
|
|
return int(str(value).strip())
|
|
except ValueError:
|
|
return default
|
|
|
|
|
|
EXEC_EMPTY_RESPONSE_RETRIES = max(0, _parse_int(os.environ.get("EXEC_EMPTY_RESPONSE_RETRIES"), 1))
|
|
CLAUDE_CODE_EXEC_MAX_THINKING_TOKENS = max(
|
|
0,
|
|
_parse_int(os.environ.get("CLAUDE_CODE_EXEC_MAX_THINKING_TOKENS"), 16384),
|
|
)
|
|
|
|
|
|
def set_optimizer_backend(backend: str) -> None:
|
|
global OPTIMIZER_BACKEND
|
|
OPTIMIZER_BACKEND = normalize_backend_name(backend or "openai_chat")
|
|
if OPTIMIZER_BACKEND not in {"openai_chat", "claude_chat", "qwen_chat", "minimax_chat"}:
|
|
raise ValueError(
|
|
f"Unsupported optimizer backend: {OPTIMIZER_BACKEND!r}. "
|
|
"Supported values are 'openai_chat', 'claude_chat', 'qwen_chat', and 'minimax_chat'."
|
|
)
|
|
os.environ["OPTIMIZER_BACKEND"] = OPTIMIZER_BACKEND
|
|
|
|
|
|
def get_optimizer_backend() -> str:
|
|
return OPTIMIZER_BACKEND
|
|
|
|
|
|
def set_target_backend(backend: str) -> None:
|
|
global TARGET_BACKEND
|
|
TARGET_BACKEND = normalize_backend_name(backend or "openai_chat")
|
|
if TARGET_BACKEND not in {"openai_chat", "claude_chat", "qwen_chat", "minimax_chat", "codex_exec", "claude_code_exec"}:
|
|
raise ValueError(
|
|
f"Unsupported target backend: {TARGET_BACKEND!r}. "
|
|
"Supported values are 'openai_chat', 'claude_chat', 'qwen_chat', 'minimax_chat', 'codex_exec', and 'claude_code_exec'."
|
|
)
|
|
os.environ["TARGET_BACKEND"] = TARGET_BACKEND
|
|
|
|
|
|
def get_target_backend() -> str:
|
|
return TARGET_BACKEND
|
|
|
|
|
|
def is_target_exec_backend() -> bool:
|
|
return TARGET_BACKEND in {"codex_exec", "claude_code_exec"}
|
|
|
|
|
|
def is_optimizer_chat_backend() -> bool:
|
|
return OPTIMIZER_BACKEND in {"openai_chat", "claude_chat", "qwen_chat", "minimax_chat"}
|
|
|
|
|
|
def is_target_chat_backend() -> bool:
|
|
return TARGET_BACKEND in {"openai_chat", "claude_chat", "qwen_chat", "minimax_chat"}
|
|
|
|
|
|
def configure_codex_exec(
|
|
*,
|
|
path: str | None = None,
|
|
sandbox: str | None = None,
|
|
profile: str | None = None,
|
|
full_auto: bool | None = None,
|
|
reasoning_effort: str | None = None,
|
|
use_sdk: str | None = None,
|
|
network_access: bool | None = None,
|
|
web_search: bool | None = None,
|
|
approval_policy: str | None = None,
|
|
) -> None:
|
|
global CODEX_EXEC_PATH, CODEX_EXEC_SANDBOX, CODEX_EXEC_PROFILE, CODEX_EXEC_FULL_AUTO, CODEX_EXEC_REASONING_EFFORT, CODEX_EXEC_USE_SDK, CODEX_EXEC_NETWORK_ACCESS, CODEX_EXEC_WEB_SEARCH, CODEX_EXEC_APPROVAL_POLICY
|
|
if path is not None:
|
|
CODEX_EXEC_PATH = str(path).strip() or "codex"
|
|
os.environ["CODEX_EXEC_PATH"] = CODEX_EXEC_PATH
|
|
if sandbox is not None:
|
|
CODEX_EXEC_SANDBOX = str(sandbox).strip() or "workspace-write"
|
|
os.environ["CODEX_EXEC_SANDBOX"] = CODEX_EXEC_SANDBOX
|
|
if profile is not None:
|
|
CODEX_EXEC_PROFILE = str(profile).strip()
|
|
os.environ["CODEX_EXEC_PROFILE"] = CODEX_EXEC_PROFILE
|
|
if full_auto is not None:
|
|
CODEX_EXEC_FULL_AUTO = bool(full_auto)
|
|
os.environ["CODEX_EXEC_FULL_AUTO"] = "true" if CODEX_EXEC_FULL_AUTO else "false"
|
|
if reasoning_effort is not None:
|
|
CODEX_EXEC_REASONING_EFFORT = str(reasoning_effort).strip() or "none"
|
|
os.environ["CODEX_EXEC_REASONING_EFFORT"] = CODEX_EXEC_REASONING_EFFORT
|
|
if use_sdk is not None:
|
|
CODEX_EXEC_USE_SDK = str(use_sdk).strip().lower() or "auto"
|
|
os.environ["CODEX_EXEC_USE_SDK"] = CODEX_EXEC_USE_SDK
|
|
if network_access is not None:
|
|
CODEX_EXEC_NETWORK_ACCESS = bool(network_access)
|
|
os.environ["CODEX_EXEC_NETWORK_ACCESS"] = "true" if CODEX_EXEC_NETWORK_ACCESS else "false"
|
|
if web_search is not None:
|
|
CODEX_EXEC_WEB_SEARCH = bool(web_search)
|
|
os.environ["CODEX_EXEC_WEB_SEARCH"] = "true" if CODEX_EXEC_WEB_SEARCH else "false"
|
|
if approval_policy is not None:
|
|
CODEX_EXEC_APPROVAL_POLICY = str(approval_policy).strip() or "never"
|
|
os.environ["CODEX_EXEC_APPROVAL_POLICY"] = CODEX_EXEC_APPROVAL_POLICY
|
|
|
|
|
|
def get_codex_exec_config() -> dict[str, str | bool | int]:
|
|
return {
|
|
"path": CODEX_EXEC_PATH,
|
|
"sandbox": CODEX_EXEC_SANDBOX,
|
|
"profile": CODEX_EXEC_PROFILE,
|
|
"full_auto": CODEX_EXEC_FULL_AUTO,
|
|
"reasoning_effort": CODEX_EXEC_REASONING_EFFORT,
|
|
"use_sdk": CODEX_EXEC_USE_SDK,
|
|
"network_access": CODEX_EXEC_NETWORK_ACCESS,
|
|
"web_search": CODEX_EXEC_WEB_SEARCH,
|
|
"approval_policy": CODEX_EXEC_APPROVAL_POLICY,
|
|
"empty_response_retries": EXEC_EMPTY_RESPONSE_RETRIES,
|
|
}
|
|
|
|
|
|
def configure_claude_code_exec(
|
|
*,
|
|
path: str | None = None,
|
|
profile: str | None = None,
|
|
use_sdk: str | None = None,
|
|
effort: str | None = None,
|
|
max_thinking_tokens: int | str | None = None,
|
|
) -> None:
|
|
global CLAUDE_CODE_EXEC_PATH, CLAUDE_CODE_EXEC_PROFILE, CLAUDE_CODE_EXEC_USE_SDK, CLAUDE_CODE_EXEC_EFFORT, CLAUDE_CODE_EXEC_MAX_THINKING_TOKENS
|
|
if path is not None:
|
|
CLAUDE_CODE_EXEC_PATH = str(path).strip() or "claude"
|
|
os.environ["CLAUDE_CODE_EXEC_PATH"] = CLAUDE_CODE_EXEC_PATH
|
|
if profile is not None:
|
|
CLAUDE_CODE_EXEC_PROFILE = str(profile).strip()
|
|
os.environ["CLAUDE_CODE_EXEC_PROFILE"] = CLAUDE_CODE_EXEC_PROFILE
|
|
if use_sdk is not None:
|
|
CLAUDE_CODE_EXEC_USE_SDK = str(use_sdk).strip().lower() or "auto"
|
|
os.environ["CLAUDE_CODE_EXEC_USE_SDK"] = CLAUDE_CODE_EXEC_USE_SDK
|
|
if effort is not None:
|
|
CLAUDE_CODE_EXEC_EFFORT = str(effort).strip().lower() or "medium"
|
|
os.environ["CLAUDE_CODE_EXEC_EFFORT"] = CLAUDE_CODE_EXEC_EFFORT
|
|
if max_thinking_tokens is not None:
|
|
CLAUDE_CODE_EXEC_MAX_THINKING_TOKENS = max(
|
|
0,
|
|
_parse_int(str(max_thinking_tokens), 16384),
|
|
)
|
|
os.environ["CLAUDE_CODE_EXEC_MAX_THINKING_TOKENS"] = str(CLAUDE_CODE_EXEC_MAX_THINKING_TOKENS)
|
|
|
|
|
|
def get_claude_code_exec_config() -> dict[str, str | int]:
|
|
return {
|
|
"path": CLAUDE_CODE_EXEC_PATH,
|
|
"profile": CLAUDE_CODE_EXEC_PROFILE,
|
|
"use_sdk": CLAUDE_CODE_EXEC_USE_SDK,
|
|
"effort": CLAUDE_CODE_EXEC_EFFORT,
|
|
"max_thinking_tokens": CLAUDE_CODE_EXEC_MAX_THINKING_TOKENS,
|
|
"empty_response_retries": EXEC_EMPTY_RESPONSE_RETRIES,
|
|
}
|