self-evolve-framework 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/template/rules/ponytail.mdc +98 -23
- package/template/skills/skillopt-sleep/SKILL.md +42 -0
- package/template/skills/skillopt-sleep/configs/_base_/default.yaml +103 -0
- package/template/skills/skillopt-sleep/configs/alfworld/default.yaml +29 -0
- package/template/skills/skillopt-sleep/configs/docvqa/default.yaml +28 -0
- package/template/skills/skillopt-sleep/configs/features/soft_gate.yaml +47 -0
- package/template/skills/skillopt-sleep/configs/livemathematicianbench/default.yaml +22 -0
- package/template/skills/skillopt-sleep/configs/officeqa/default.yaml +34 -0
- package/template/skills/skillopt-sleep/configs/searchqa/default.yaml +32 -0
- package/template/skills/skillopt-sleep/configs/spreadsheetbench/default.yaml +34 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/__init__.py +28 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/config.py +282 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/datasets/__init__.py +7 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/datasets/base.py +512 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/engine/__init__.py +9 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/engine/trainer.py +2379 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/__init__.py +1 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/_template/README.md +43 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/_template/config_template.yaml +55 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/_template/env_template.py +151 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/_template/loader_template.py +87 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/__init__.py +5 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/adapter.py +428 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/dataloader.py +123 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/prompts/analyst_error.md +55 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/prompts/analyst_success.md +33 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/prompts/rollout_no_history.md +8 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/prompts/rollout_with_history.md +9 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/prompts/rollout_with_memory.md +16 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/reflect.py +4 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/rollout.py +366 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/skills/initial.md +45 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/__init__.py +9 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/alfworld_envs.py +221 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/alfworld_projection.py +60 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/alfworld_prompts.py +8 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/config_tw.yaml +145 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/env_base.py +84 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/env_manager.py +139 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/memory.py +87 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/base.py +329 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/__init__.py +1 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/adapter.py +90 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/dataloader.py +61 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/evaluator.py +113 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/prompts/analyst_error.md +35 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/prompts/analyst_success.md +24 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/prompts/rollout_system.md +12 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/rollout.py +391 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/skills/initial.md +11 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/__init__.py +1 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/adapter.py +129 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/dataloader.py +308 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/evaluator.py +62 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/prompts/analyst_error.md +37 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/prompts/analyst_success.md +25 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/prompts/rollout_system.md +12 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/reflect.py +4 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/rollout.py +434 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/skills/initial.md +16 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/__init__.py +1 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/adapter.py +112 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/dataloader.py +71 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/evaluator.py +46 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/prompts/analyst_error.md +37 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/prompts/analyst_success.md +25 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/prompts/rollout_system.md +15 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/rollout.py +799 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/skills/initial.md +15 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/tool_runtime.py +552 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/__init__.py +1 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/adapter.py +96 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/dataloader.py +42 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/evaluator.py +100 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/prompts/analyst_error.md +46 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/prompts/analyst_success.md +32 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/prompts/rollout_system.md +13 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/reflect.py +4 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/rollout.py +494 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/skills/initial.md +3 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/__init__.py +5 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/adapter.py +159 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/codegen_agent.py +731 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/dataloader.py +37 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/evaluator.py +158 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/executor.py +67 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/prompts/analyst_error.md +46 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/prompts/analyst_success.md +32 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/prompts/codegen_system.md +1 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/prompts/critical_rules.md +9 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/prompts/react_system.md +21 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/react_agent.py +395 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/reflect.py +4 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/rollout.py +979 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/skills/initial.md +56 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/evaluation/__init__.py +13 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/evaluation/gate.py +148 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/gradient/__init__.py +15 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/gradient/aggregate.py +253 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/gradient/reflect.py +635 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/__init__.py +514 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/azure_openai.py +915 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/backend_config.py +185 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/claude_backend.py +371 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/codex_backend.py +666 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/codex_harness.py +1057 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/common.py +229 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/minimax_backend.py +277 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/qwen_backend.py +456 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/router.py +236 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/__init__.py +15 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/appendix.py +156 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/clip.py +109 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/lr_autonomous.py +108 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/meta_skill.py +79 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/rewrite.py +59 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/scheduler.py +127 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/select.py +4 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/skill.py +201 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/skill_aware.py +206 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/slow_update.py +396 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/update_modes.py +135 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/__init__.py +63 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_error.md +41 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_error_full_rewrite.md +32 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_error_rewrite.md +44 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_success.md +36 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_success_full_rewrite.md +30 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_success_rewrite.md +33 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/lr_autonomous.md +20 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_failure.md +30 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_failure_full_rewrite.md +28 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_failure_rewrite.md +26 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_final.md +33 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_final_full_rewrite.md +28 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_final_rewrite.md +25 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_success.md +28 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_success_full_rewrite.md +28 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_success_rewrite.md +25 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/meta_skill.md +40 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/ranking.md +20 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/ranking_rewrite.md +15 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/rewrite_skill.md +25 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/slow_update.md +60 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/scheduler/__init__.py +8 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/types.py +306 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/utils/__init__.py +4 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/utils/json_utils.py +172 -0
- package/template/skills/skillopt-sleep/scripts/framework/skillopt/utils/scoring.py +28 -0
- package/template/skills/ponytail/SKILL.md +0 -133
- package/template/skills/ponytail/scripts/hooks/claude-codex-hooks.json +0 -44
- package/template/skills/ponytail/scripts/hooks/copilot-hooks.json +0 -21
- package/template/skills/ponytail/scripts/hooks/ponytail-activate.js +0 -91
- package/template/skills/ponytail/scripts/hooks/ponytail-config.js +0 -122
- package/template/skills/ponytail/scripts/hooks/ponytail-instructions.js +0 -94
- package/template/skills/ponytail/scripts/hooks/ponytail-mode-tracker.js +0 -55
- package/template/skills/ponytail/scripts/hooks/ponytail-runtime.js +0 -68
- package/template/skills/ponytail/scripts/hooks/ponytail-statusline.ps1 +0 -21
- package/template/skills/ponytail/scripts/hooks/ponytail-statusline.sh +0 -12
- package/template/skills/ponytail/scripts/hooks/ponytail-subagent.js +0 -22
- package/template/skills/ponytail/scripts/mcp/README.md +0 -46
- package/template/skills/ponytail/scripts/mcp/index.js +0 -48
- package/template/skills/ponytail/scripts/mcp/instructions.js +0 -26
- package/template/skills/ponytail/scripts/mcp/package.json +0 -13
- package/template/skills/ponytail/scripts/mcp/test/instructions.test.js +0 -22
- package/template/skills/ponytail-audit/SKILL.md +0 -41
- package/template/skills/ponytail-debt/SKILL.md +0 -44
- package/template/skills/ponytail-gain/SKILL.md +0 -50
- package/template/skills/ponytail-help/SKILL.md +0 -69
- package/template/skills/ponytail-review/SKILL.md +0 -57
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
"""OpenAI-compatible Qwen chat backend for optimizer and target paths."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import threading
|
|
8
|
+
import time
|
|
9
|
+
import urllib.error
|
|
10
|
+
import urllib.request
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from skillopt.model.common import (
|
|
14
|
+
CompatAssistantMessage,
|
|
15
|
+
CompatToolCall,
|
|
16
|
+
CompatToolFunction,
|
|
17
|
+
TokenTracker,
|
|
18
|
+
default_model_for_backend,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class QwenChatConfig:
|
|
24
|
+
base_url: str
|
|
25
|
+
api_key: str
|
|
26
|
+
timeout_seconds: float
|
|
27
|
+
max_tokens: int
|
|
28
|
+
temperature: float | None
|
|
29
|
+
enable_thinking: bool
|
|
30
|
+
deployment: str
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _parse_bool(value: Any, default: bool = False) -> bool:
|
|
34
|
+
if value is None:
|
|
35
|
+
return default
|
|
36
|
+
return str(value).strip().lower() in {"1", "true", "yes", "on"}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _parse_optional_float(value: Any) -> float | None:
|
|
40
|
+
if value is None:
|
|
41
|
+
return None
|
|
42
|
+
raw = str(value).strip()
|
|
43
|
+
return float(raw) if raw else None
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _parse_int(value: Any, default: int) -> int:
|
|
47
|
+
if value is None:
|
|
48
|
+
return default
|
|
49
|
+
raw = str(value).strip()
|
|
50
|
+
return int(raw) if raw else default
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _role_env(role: str, key: str, default: str) -> str:
|
|
54
|
+
role_key = f"{role.upper()}_QWEN_CHAT_{key}"
|
|
55
|
+
generic_key = f"QWEN_CHAT_{key}"
|
|
56
|
+
return os.environ.get(role_key) or os.environ.get(generic_key) or default
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _initial_config(role: str) -> QwenChatConfig:
|
|
60
|
+
role_upper = role.upper()
|
|
61
|
+
deployment_env = "OPTIMIZER_DEPLOYMENT" if role == "optimizer" else "TARGET_DEPLOYMENT"
|
|
62
|
+
return QwenChatConfig(
|
|
63
|
+
base_url=_role_env(role, "BASE_URL", "http://localhost:8000/v1"),
|
|
64
|
+
api_key=_role_env(role, "API_KEY", ""),
|
|
65
|
+
timeout_seconds=float(_role_env(role, "TIMEOUT_SECONDS", "300") or 300),
|
|
66
|
+
max_tokens=_parse_int(_role_env(role, "MAX_TOKENS", "8000"), 8000),
|
|
67
|
+
temperature=_parse_optional_float(_role_env(role, "TEMPERATURE", "0.7")),
|
|
68
|
+
enable_thinking=_parse_bool(_role_env(role, "ENABLE_THINKING", "false")),
|
|
69
|
+
deployment=(
|
|
70
|
+
os.environ.get(f"{role_upper}_QWEN_CHAT_MODEL")
|
|
71
|
+
or os.environ.get("QWEN_CHAT_MODEL")
|
|
72
|
+
or os.environ.get(deployment_env)
|
|
73
|
+
or default_model_for_backend("qwen_chat")
|
|
74
|
+
),
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
OPTIMIZER_CONFIG = _initial_config("optimizer")
|
|
79
|
+
TARGET_CONFIG = _initial_config("target")
|
|
80
|
+
|
|
81
|
+
_config_lock = threading.Lock()
|
|
82
|
+
tracker = TokenTracker()
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _chat_url(config: QwenChatConfig) -> str:
|
|
86
|
+
base = config.base_url.rstrip("/")
|
|
87
|
+
if base.endswith("/chat/completions"):
|
|
88
|
+
return base
|
|
89
|
+
return f"{base}/chat/completions"
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _json_safe(value: Any) -> Any:
|
|
93
|
+
if value is None or isinstance(value, (str, int, float, bool)):
|
|
94
|
+
return value
|
|
95
|
+
if isinstance(value, list):
|
|
96
|
+
return [_json_safe(item) for item in value]
|
|
97
|
+
if isinstance(value, dict):
|
|
98
|
+
return {str(key): _json_safe(val) for key, val in value.items()}
|
|
99
|
+
model_dump = getattr(value, "model_dump", None)
|
|
100
|
+
if callable(model_dump):
|
|
101
|
+
try:
|
|
102
|
+
return model_dump(mode="json")
|
|
103
|
+
except TypeError:
|
|
104
|
+
return model_dump()
|
|
105
|
+
return str(value)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _usage_from_payload(payload: dict[str, Any]) -> dict[str, int]:
|
|
109
|
+
usage = payload.get("usage") or {}
|
|
110
|
+
prompt_tokens = int(usage.get("prompt_tokens") or usage.get("input_tokens") or 0)
|
|
111
|
+
completion_tokens = int(usage.get("completion_tokens") or usage.get("output_tokens") or 0)
|
|
112
|
+
total_tokens = int(usage.get("total_tokens") or (prompt_tokens + completion_tokens))
|
|
113
|
+
return {
|
|
114
|
+
"prompt_tokens": prompt_tokens,
|
|
115
|
+
"completion_tokens": completion_tokens,
|
|
116
|
+
"total_tokens": total_tokens,
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def _compat_message_from_payload(message: dict[str, Any], choice: dict[str, Any]) -> CompatAssistantMessage:
|
|
121
|
+
content = message.get("content") or ""
|
|
122
|
+
if not isinstance(content, str):
|
|
123
|
+
content = json.dumps(content, ensure_ascii=False)
|
|
124
|
+
tool_calls: list[CompatToolCall] = []
|
|
125
|
+
for index, tool_call in enumerate(message.get("tool_calls") or [], start=1):
|
|
126
|
+
function = tool_call.get("function") or {}
|
|
127
|
+
tool_calls.append(
|
|
128
|
+
CompatToolCall(
|
|
129
|
+
id=str(tool_call.get("id") or f"qwen_tool_{index}"),
|
|
130
|
+
type=str(tool_call.get("type") or "function"),
|
|
131
|
+
function=CompatToolFunction(
|
|
132
|
+
name=str(function.get("name") or ""),
|
|
133
|
+
arguments=str(function.get("arguments") or "{}"),
|
|
134
|
+
),
|
|
135
|
+
)
|
|
136
|
+
)
|
|
137
|
+
return CompatAssistantMessage(
|
|
138
|
+
content=content,
|
|
139
|
+
tool_calls=tool_calls,
|
|
140
|
+
metadata={
|
|
141
|
+
"finish_reason": choice.get("finish_reason"),
|
|
142
|
+
"choice0": _json_safe(choice),
|
|
143
|
+
},
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def _post_chat_completion(
|
|
148
|
+
payload: dict[str, Any],
|
|
149
|
+
timeout: float | None,
|
|
150
|
+
config: QwenChatConfig,
|
|
151
|
+
) -> dict[str, Any]:
|
|
152
|
+
headers = {"Content-Type": "application/json"}
|
|
153
|
+
if config.api_key:
|
|
154
|
+
headers["Authorization"] = f"Bearer {config.api_key}"
|
|
155
|
+
req = urllib.request.Request(
|
|
156
|
+
_chat_url(config),
|
|
157
|
+
data=json.dumps(payload, ensure_ascii=False).encode("utf-8"),
|
|
158
|
+
headers=headers,
|
|
159
|
+
method="POST",
|
|
160
|
+
)
|
|
161
|
+
try:
|
|
162
|
+
with urllib.request.urlopen(req, timeout=timeout or config.timeout_seconds) as resp:
|
|
163
|
+
raw = resp.read().decode("utf-8")
|
|
164
|
+
except urllib.error.HTTPError as e:
|
|
165
|
+
body = e.read().decode("utf-8", errors="replace")
|
|
166
|
+
raise RuntimeError(f"Qwen chat API returned HTTP {e.code}: {body}") from e
|
|
167
|
+
except urllib.error.URLError as e:
|
|
168
|
+
raise RuntimeError(f"Qwen chat API request failed: {e}") from e
|
|
169
|
+
try:
|
|
170
|
+
return json.loads(raw)
|
|
171
|
+
except json.JSONDecodeError as e:
|
|
172
|
+
raise RuntimeError(f"Qwen chat API returned non-JSON response: {raw[:1000]}") from e
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def _chat_messages_impl(
|
|
176
|
+
messages: list[dict[str, Any]],
|
|
177
|
+
max_completion_tokens: int,
|
|
178
|
+
retries: int,
|
|
179
|
+
stage: str,
|
|
180
|
+
*,
|
|
181
|
+
role: str,
|
|
182
|
+
tools: list[dict[str, Any]] | None = None,
|
|
183
|
+
tool_choice: str | dict[str, Any] | None = None,
|
|
184
|
+
return_message: bool = False,
|
|
185
|
+
deployment: str | None = None,
|
|
186
|
+
timeout: float | None = None,
|
|
187
|
+
) -> tuple[Any, dict[str, int]]:
|
|
188
|
+
config = OPTIMIZER_CONFIG if role == "optimizer" else TARGET_CONFIG
|
|
189
|
+
payload: dict[str, Any] = {
|
|
190
|
+
"model": deployment or config.deployment,
|
|
191
|
+
"messages": _json_safe(messages),
|
|
192
|
+
"max_tokens": min(max_completion_tokens, config.max_tokens),
|
|
193
|
+
}
|
|
194
|
+
if config.enable_thinking:
|
|
195
|
+
payload["chat_template_kwargs"] = {"enable_thinking": True}
|
|
196
|
+
if config.temperature is not None:
|
|
197
|
+
payload["temperature"] = config.temperature
|
|
198
|
+
if tools:
|
|
199
|
+
payload["tools"] = _json_safe(tools)
|
|
200
|
+
if tool_choice is not None:
|
|
201
|
+
payload["tool_choice"] = _json_safe(tool_choice)
|
|
202
|
+
|
|
203
|
+
last_err: Exception | None = None
|
|
204
|
+
for attempt in range(retries):
|
|
205
|
+
try:
|
|
206
|
+
data = _post_chat_completion(payload, timeout, config)
|
|
207
|
+
choices = data.get("choices") or []
|
|
208
|
+
if not choices:
|
|
209
|
+
raise RuntimeError(f"Qwen chat API returned no choices: {data}")
|
|
210
|
+
choice0 = choices[0]
|
|
211
|
+
message = choice0.get("message") or {}
|
|
212
|
+
text = message.get("content") or ""
|
|
213
|
+
if not isinstance(text, str):
|
|
214
|
+
text = json.dumps(text, ensure_ascii=False)
|
|
215
|
+
usage_info = _usage_from_payload(data)
|
|
216
|
+
tracker.record(stage, usage_info["prompt_tokens"], usage_info["completion_tokens"])
|
|
217
|
+
if return_message:
|
|
218
|
+
return _compat_message_from_payload(message, choice0), usage_info
|
|
219
|
+
return text, usage_info
|
|
220
|
+
except Exception as e: # noqa: BLE001
|
|
221
|
+
last_err = e
|
|
222
|
+
time.sleep(min(2 ** attempt, 30))
|
|
223
|
+
raise RuntimeError(f"Qwen chat call failed after {retries} retries: {last_err}")
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def configure_qwen_chat(
|
|
227
|
+
*,
|
|
228
|
+
base_url: str | None = None,
|
|
229
|
+
api_key: str | None = None,
|
|
230
|
+
temperature: float | str | None = None,
|
|
231
|
+
timeout_seconds: float | str | None = None,
|
|
232
|
+
max_tokens: int | str | None = None,
|
|
233
|
+
enable_thinking: bool | str | None = None,
|
|
234
|
+
optimizer_base_url: str | None = None,
|
|
235
|
+
optimizer_api_key: str | None = None,
|
|
236
|
+
optimizer_temperature: float | str | None = None,
|
|
237
|
+
optimizer_timeout_seconds: float | str | None = None,
|
|
238
|
+
optimizer_max_tokens: int | str | None = None,
|
|
239
|
+
optimizer_enable_thinking: bool | str | None = None,
|
|
240
|
+
target_base_url: str | None = None,
|
|
241
|
+
target_api_key: str | None = None,
|
|
242
|
+
target_temperature: float | str | None = None,
|
|
243
|
+
target_timeout_seconds: float | str | None = None,
|
|
244
|
+
target_max_tokens: int | str | None = None,
|
|
245
|
+
target_enable_thinking: bool | str | None = None,
|
|
246
|
+
) -> None:
|
|
247
|
+
with _config_lock:
|
|
248
|
+
if base_url is not None:
|
|
249
|
+
os.environ["QWEN_CHAT_BASE_URL"] = str(base_url).strip()
|
|
250
|
+
if api_key is not None:
|
|
251
|
+
os.environ["QWEN_CHAT_API_KEY"] = str(api_key).strip()
|
|
252
|
+
if temperature is not None:
|
|
253
|
+
os.environ["QWEN_CHAT_TEMPERATURE"] = str(temperature).strip()
|
|
254
|
+
if timeout_seconds is not None:
|
|
255
|
+
os.environ["QWEN_CHAT_TIMEOUT_SECONDS"] = str(timeout_seconds)
|
|
256
|
+
if max_tokens is not None:
|
|
257
|
+
os.environ["QWEN_CHAT_MAX_TOKENS"] = str(max_tokens)
|
|
258
|
+
if enable_thinking is not None:
|
|
259
|
+
os.environ["QWEN_CHAT_ENABLE_THINKING"] = (
|
|
260
|
+
"true" if _parse_bool(enable_thinking) else "false"
|
|
261
|
+
)
|
|
262
|
+
_update_config(
|
|
263
|
+
OPTIMIZER_CONFIG,
|
|
264
|
+
"optimizer",
|
|
265
|
+
base_url=optimizer_base_url if optimizer_base_url is not None else base_url,
|
|
266
|
+
api_key=optimizer_api_key if optimizer_api_key is not None else api_key,
|
|
267
|
+
temperature=(
|
|
268
|
+
optimizer_temperature
|
|
269
|
+
if optimizer_temperature is not None
|
|
270
|
+
else temperature
|
|
271
|
+
),
|
|
272
|
+
timeout_seconds=(
|
|
273
|
+
optimizer_timeout_seconds
|
|
274
|
+
if optimizer_timeout_seconds is not None
|
|
275
|
+
else timeout_seconds
|
|
276
|
+
),
|
|
277
|
+
max_tokens=optimizer_max_tokens if optimizer_max_tokens is not None else max_tokens,
|
|
278
|
+
enable_thinking=(
|
|
279
|
+
optimizer_enable_thinking
|
|
280
|
+
if optimizer_enable_thinking is not None
|
|
281
|
+
else enable_thinking
|
|
282
|
+
),
|
|
283
|
+
)
|
|
284
|
+
_update_config(
|
|
285
|
+
TARGET_CONFIG,
|
|
286
|
+
"target",
|
|
287
|
+
base_url=target_base_url if target_base_url is not None else base_url,
|
|
288
|
+
api_key=target_api_key if target_api_key is not None else api_key,
|
|
289
|
+
temperature=target_temperature if target_temperature is not None else temperature,
|
|
290
|
+
timeout_seconds=(
|
|
291
|
+
target_timeout_seconds
|
|
292
|
+
if target_timeout_seconds is not None
|
|
293
|
+
else timeout_seconds
|
|
294
|
+
),
|
|
295
|
+
max_tokens=target_max_tokens if target_max_tokens is not None else max_tokens,
|
|
296
|
+
enable_thinking=(
|
|
297
|
+
target_enable_thinking
|
|
298
|
+
if target_enable_thinking is not None
|
|
299
|
+
else enable_thinking
|
|
300
|
+
),
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def _update_config(
|
|
305
|
+
config: QwenChatConfig,
|
|
306
|
+
role: str,
|
|
307
|
+
*,
|
|
308
|
+
base_url: str | None = None,
|
|
309
|
+
api_key: str | None = None,
|
|
310
|
+
temperature: float | str | None = None,
|
|
311
|
+
timeout_seconds: float | str | None = None,
|
|
312
|
+
max_tokens: int | str | None = None,
|
|
313
|
+
enable_thinking: bool | str | None = None,
|
|
314
|
+
) -> None:
|
|
315
|
+
env_prefix = role.upper()
|
|
316
|
+
if base_url is not None:
|
|
317
|
+
config.base_url = str(base_url).strip() or config.base_url
|
|
318
|
+
os.environ[f"{env_prefix}_QWEN_CHAT_BASE_URL"] = config.base_url
|
|
319
|
+
if api_key is not None:
|
|
320
|
+
config.api_key = str(api_key).strip()
|
|
321
|
+
os.environ[f"{env_prefix}_QWEN_CHAT_API_KEY"] = config.api_key
|
|
322
|
+
if temperature is not None:
|
|
323
|
+
raw = str(temperature).strip()
|
|
324
|
+
config.temperature = float(raw) if raw else None
|
|
325
|
+
os.environ[f"{env_prefix}_QWEN_CHAT_TEMPERATURE"] = raw
|
|
326
|
+
if timeout_seconds is not None:
|
|
327
|
+
config.timeout_seconds = float(timeout_seconds)
|
|
328
|
+
os.environ[f"{env_prefix}_QWEN_CHAT_TIMEOUT_SECONDS"] = str(timeout_seconds)
|
|
329
|
+
if max_tokens is not None:
|
|
330
|
+
config.max_tokens = int(max_tokens)
|
|
331
|
+
os.environ[f"{env_prefix}_QWEN_CHAT_MAX_TOKENS"] = str(max_tokens)
|
|
332
|
+
if enable_thinking is not None:
|
|
333
|
+
config.enable_thinking = _parse_bool(enable_thinking)
|
|
334
|
+
os.environ[f"{env_prefix}_QWEN_CHAT_ENABLE_THINKING"] = (
|
|
335
|
+
"true" if config.enable_thinking else "false"
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def get_max_tokens() -> int:
|
|
340
|
+
return TARGET_CONFIG.max_tokens
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def chat_optimizer(
|
|
344
|
+
system: str,
|
|
345
|
+
user: str,
|
|
346
|
+
max_completion_tokens: int = 16384,
|
|
347
|
+
retries: int = 5,
|
|
348
|
+
stage: str = "optimizer",
|
|
349
|
+
reasoning_effort: str | None = None,
|
|
350
|
+
timeout: float | None = None,
|
|
351
|
+
) -> tuple[str, dict[str, int]]:
|
|
352
|
+
del reasoning_effort
|
|
353
|
+
messages = [{"role": "system", "content": system}, {"role": "user", "content": user}]
|
|
354
|
+
return _chat_messages_impl(
|
|
355
|
+
messages,
|
|
356
|
+
max_completion_tokens,
|
|
357
|
+
retries,
|
|
358
|
+
stage,
|
|
359
|
+
role="optimizer",
|
|
360
|
+
timeout=timeout,
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
def chat_target(
|
|
365
|
+
system: str,
|
|
366
|
+
user: str,
|
|
367
|
+
max_completion_tokens: int = 16384,
|
|
368
|
+
retries: int = 5,
|
|
369
|
+
stage: str = "target",
|
|
370
|
+
reasoning_effort: str | None = None,
|
|
371
|
+
timeout: float | None = None,
|
|
372
|
+
) -> tuple[str, dict[str, int]]:
|
|
373
|
+
del reasoning_effort
|
|
374
|
+
messages = [{"role": "system", "content": system}, {"role": "user", "content": user}]
|
|
375
|
+
return _chat_messages_impl(
|
|
376
|
+
messages,
|
|
377
|
+
max_completion_tokens,
|
|
378
|
+
retries,
|
|
379
|
+
stage,
|
|
380
|
+
role="target",
|
|
381
|
+
timeout=timeout,
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
def chat_optimizer_messages(
|
|
386
|
+
messages: list[dict[str, Any]],
|
|
387
|
+
max_completion_tokens: int = 16384,
|
|
388
|
+
retries: int = 5,
|
|
389
|
+
stage: str = "optimizer",
|
|
390
|
+
reasoning_effort: str | None = None,
|
|
391
|
+
*,
|
|
392
|
+
tools: list[dict[str, Any]] | None = None,
|
|
393
|
+
tool_choice: str | dict[str, Any] | None = None,
|
|
394
|
+
return_message: bool = False,
|
|
395
|
+
timeout: float | None = None,
|
|
396
|
+
) -> tuple[Any, dict[str, int]]:
|
|
397
|
+
del reasoning_effort
|
|
398
|
+
return _chat_messages_impl(
|
|
399
|
+
messages,
|
|
400
|
+
max_completion_tokens,
|
|
401
|
+
retries,
|
|
402
|
+
stage,
|
|
403
|
+
role="optimizer",
|
|
404
|
+
tools=tools,
|
|
405
|
+
tool_choice=tool_choice,
|
|
406
|
+
return_message=return_message,
|
|
407
|
+
timeout=timeout,
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def chat_target_messages(
|
|
412
|
+
messages: list[dict[str, Any]],
|
|
413
|
+
max_completion_tokens: int = 16384,
|
|
414
|
+
retries: int = 5,
|
|
415
|
+
stage: str = "target",
|
|
416
|
+
reasoning_effort: str | None = None,
|
|
417
|
+
*,
|
|
418
|
+
tools: list[dict[str, Any]] | None = None,
|
|
419
|
+
tool_choice: str | dict[str, Any] | None = None,
|
|
420
|
+
return_message: bool = False,
|
|
421
|
+
timeout: float | None = None,
|
|
422
|
+
) -> tuple[Any, dict[str, int]]:
|
|
423
|
+
del reasoning_effort
|
|
424
|
+
return _chat_messages_impl(
|
|
425
|
+
messages,
|
|
426
|
+
max_completion_tokens,
|
|
427
|
+
retries,
|
|
428
|
+
stage,
|
|
429
|
+
role="target",
|
|
430
|
+
tools=tools,
|
|
431
|
+
tool_choice=tool_choice,
|
|
432
|
+
return_message=return_message,
|
|
433
|
+
timeout=timeout,
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
def get_token_summary() -> dict[str, dict[str, int]]:
|
|
438
|
+
return tracker.summary()
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
def reset_token_tracker() -> None:
|
|
442
|
+
tracker.reset()
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
def set_reasoning_effort(effort: str | None) -> None:
|
|
446
|
+
del effort
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
def set_target_deployment(deployment: str) -> None:
|
|
450
|
+
TARGET_CONFIG.deployment = deployment or default_model_for_backend("qwen_chat")
|
|
451
|
+
os.environ["TARGET_DEPLOYMENT"] = TARGET_CONFIG.deployment
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
def set_optimizer_deployment(deployment: str) -> None:
|
|
455
|
+
OPTIMIZER_CONFIG.deployment = deployment or default_model_for_backend("qwen_chat")
|
|
456
|
+
os.environ["OPTIMIZER_DEPLOYMENT"] = OPTIMIZER_CONFIG.deployment
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"""Runtime backend router for ReflACT model calls."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from . import azure_openai, claude_backend, codex_backend
|
|
8
|
+
from .common import normalize_backend_name
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
_ACTIVE_BACKEND = normalize_backend_name(
|
|
12
|
+
os.environ.get("REFLACT_MODEL_BACKEND", "azure_openai")
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _backend_module(name: str):
|
|
17
|
+
if name == "azure_openai":
|
|
18
|
+
return azure_openai
|
|
19
|
+
if name == "codex":
|
|
20
|
+
return codex_backend
|
|
21
|
+
if name == "claude":
|
|
22
|
+
return claude_backend
|
|
23
|
+
raise ValueError(f"Unknown backend: {name!r}")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _all_backend_modules() -> list[Any]:
|
|
27
|
+
return [azure_openai, codex_backend, claude_backend]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def set_backend(name: str | None) -> str:
|
|
31
|
+
"""Select the active model backend for subsequent calls."""
|
|
32
|
+
global _ACTIVE_BACKEND
|
|
33
|
+
normalized = normalize_backend_name(name)
|
|
34
|
+
if normalized not in {"azure_openai", "codex", "claude"}:
|
|
35
|
+
valid = ", ".join(sorted({"azure_openai", "codex", "claude"}))
|
|
36
|
+
raise ValueError(f"Unknown backend {name!r}. Expected one of: {valid}")
|
|
37
|
+
_ACTIVE_BACKEND = normalized
|
|
38
|
+
os.environ["REFLACT_MODEL_BACKEND"] = normalized
|
|
39
|
+
return _ACTIVE_BACKEND
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def get_backend_name() -> str:
|
|
43
|
+
return _ACTIVE_BACKEND
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def chat_optimizer(
|
|
47
|
+
system: str,
|
|
48
|
+
user: str,
|
|
49
|
+
max_completion_tokens: int = 16384,
|
|
50
|
+
retries: int = 5,
|
|
51
|
+
stage: str = "optimizer",
|
|
52
|
+
timeout: int | None = None,
|
|
53
|
+
) -> tuple[str, dict[str, int]]:
|
|
54
|
+
return _backend_module(_ACTIVE_BACKEND).chat_optimizer(
|
|
55
|
+
system=system,
|
|
56
|
+
user=user,
|
|
57
|
+
max_completion_tokens=max_completion_tokens,
|
|
58
|
+
retries=retries,
|
|
59
|
+
stage=stage,
|
|
60
|
+
timeout=timeout,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def chat_target(
|
|
65
|
+
system: str,
|
|
66
|
+
user: str,
|
|
67
|
+
max_completion_tokens: int = 16384,
|
|
68
|
+
retries: int = 5,
|
|
69
|
+
stage: str = "target",
|
|
70
|
+
timeout: int | None = None,
|
|
71
|
+
) -> tuple[str, dict[str, int]]:
|
|
72
|
+
return _backend_module(_ACTIVE_BACKEND).chat_target(
|
|
73
|
+
system=system,
|
|
74
|
+
user=user,
|
|
75
|
+
max_completion_tokens=max_completion_tokens,
|
|
76
|
+
retries=retries,
|
|
77
|
+
stage=stage,
|
|
78
|
+
timeout=timeout,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def chat_with_deployment(
|
|
83
|
+
deployment: str,
|
|
84
|
+
system: str,
|
|
85
|
+
user: str,
|
|
86
|
+
max_completion_tokens: int = 16384,
|
|
87
|
+
retries: int = 5,
|
|
88
|
+
stage: str = "custom",
|
|
89
|
+
timeout: int | None = None,
|
|
90
|
+
) -> tuple[str, dict[str, int]]:
|
|
91
|
+
return _backend_module(_ACTIVE_BACKEND).chat_with_deployment(
|
|
92
|
+
deployment=deployment,
|
|
93
|
+
system=system,
|
|
94
|
+
user=user,
|
|
95
|
+
max_completion_tokens=max_completion_tokens,
|
|
96
|
+
retries=retries,
|
|
97
|
+
stage=stage,
|
|
98
|
+
timeout=timeout,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def chat_optimizer_messages(
|
|
103
|
+
messages: list[dict[str, Any]],
|
|
104
|
+
max_completion_tokens: int = 16384,
|
|
105
|
+
retries: int = 5,
|
|
106
|
+
stage: str = "optimizer",
|
|
107
|
+
*,
|
|
108
|
+
tools: list[dict[str, Any]] | None = None,
|
|
109
|
+
tool_choice: str | dict[str, Any] | None = None,
|
|
110
|
+
return_message: bool = False,
|
|
111
|
+
timeout: int | None = None,
|
|
112
|
+
) -> tuple[Any, dict[str, int]]:
|
|
113
|
+
return _backend_module(_ACTIVE_BACKEND).chat_optimizer_messages(
|
|
114
|
+
messages=messages,
|
|
115
|
+
max_completion_tokens=max_completion_tokens,
|
|
116
|
+
retries=retries,
|
|
117
|
+
stage=stage,
|
|
118
|
+
tools=tools,
|
|
119
|
+
tool_choice=tool_choice,
|
|
120
|
+
return_message=return_message,
|
|
121
|
+
timeout=timeout,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def chat_target_messages(
|
|
126
|
+
messages: list[dict[str, Any]],
|
|
127
|
+
max_completion_tokens: int = 16384,
|
|
128
|
+
retries: int = 5,
|
|
129
|
+
stage: str = "target",
|
|
130
|
+
*,
|
|
131
|
+
tools: list[dict[str, Any]] | None = None,
|
|
132
|
+
tool_choice: str | dict[str, Any] | None = None,
|
|
133
|
+
return_message: bool = False,
|
|
134
|
+
timeout: int | None = None,
|
|
135
|
+
) -> tuple[Any, dict[str, int]]:
|
|
136
|
+
return _backend_module(_ACTIVE_BACKEND).chat_target_messages(
|
|
137
|
+
messages=messages,
|
|
138
|
+
max_completion_tokens=max_completion_tokens,
|
|
139
|
+
retries=retries,
|
|
140
|
+
stage=stage,
|
|
141
|
+
tools=tools,
|
|
142
|
+
tool_choice=tool_choice,
|
|
143
|
+
return_message=return_message,
|
|
144
|
+
timeout=timeout,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def chat_messages_with_deployment(
|
|
149
|
+
deployment: str,
|
|
150
|
+
messages: list[dict[str, Any]],
|
|
151
|
+
max_completion_tokens: int = 16384,
|
|
152
|
+
retries: int = 5,
|
|
153
|
+
stage: str = "custom",
|
|
154
|
+
*,
|
|
155
|
+
tools: list[dict[str, Any]] | None = None,
|
|
156
|
+
tool_choice: str | dict[str, Any] | None = None,
|
|
157
|
+
return_message: bool = False,
|
|
158
|
+
timeout: int | None = None,
|
|
159
|
+
) -> tuple[Any, dict[str, int]]:
|
|
160
|
+
return _backend_module(_ACTIVE_BACKEND).chat_messages_with_deployment(
|
|
161
|
+
deployment=deployment,
|
|
162
|
+
messages=messages,
|
|
163
|
+
max_completion_tokens=max_completion_tokens,
|
|
164
|
+
retries=retries,
|
|
165
|
+
stage=stage,
|
|
166
|
+
tools=tools,
|
|
167
|
+
tool_choice=tool_choice,
|
|
168
|
+
return_message=return_message,
|
|
169
|
+
timeout=timeout,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def get_token_summary() -> dict[str, dict[str, int]]:
|
|
174
|
+
return _backend_module(_ACTIVE_BACKEND).get_token_summary()
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def reset_token_tracker() -> None:
|
|
178
|
+
_backend_module(_ACTIVE_BACKEND).reset_token_tracker()
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def set_reasoning_effort(effort: str | None) -> None:
|
|
182
|
+
for module in _all_backend_modules():
|
|
183
|
+
module.set_reasoning_effort(effort)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def set_target_deployment(deployment: str) -> None:
|
|
187
|
+
for module in _all_backend_modules():
|
|
188
|
+
module.set_target_deployment(deployment)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def set_optimizer_deployment(deployment: str) -> None:
|
|
192
|
+
for module in _all_backend_modules():
|
|
193
|
+
module.set_optimizer_deployment(deployment)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def configure_azure_openai(
|
|
197
|
+
*,
|
|
198
|
+
endpoint: str | None = None,
|
|
199
|
+
api_version: str | None = None,
|
|
200
|
+
api_key: str | None = None,
|
|
201
|
+
auth_mode: str | None = None,
|
|
202
|
+
ad_scope: str | None = None,
|
|
203
|
+
managed_identity_client_id: str | None = None,
|
|
204
|
+
optimizer_endpoint: str | None = None,
|
|
205
|
+
optimizer_api_version: str | None = None,
|
|
206
|
+
optimizer_api_key: str | None = None,
|
|
207
|
+
optimizer_auth_mode: str | None = None,
|
|
208
|
+
optimizer_ad_scope: str | None = None,
|
|
209
|
+
optimizer_managed_identity_client_id: str | None = None,
|
|
210
|
+
target_endpoint: str | None = None,
|
|
211
|
+
target_api_version: str | None = None,
|
|
212
|
+
target_api_key: str | None = None,
|
|
213
|
+
target_auth_mode: str | None = None,
|
|
214
|
+
target_ad_scope: str | None = None,
|
|
215
|
+
target_managed_identity_client_id: str | None = None,
|
|
216
|
+
) -> None:
|
|
217
|
+
azure_openai.configure_azure_openai(
|
|
218
|
+
endpoint=endpoint,
|
|
219
|
+
api_version=api_version,
|
|
220
|
+
api_key=api_key,
|
|
221
|
+
auth_mode=auth_mode,
|
|
222
|
+
ad_scope=ad_scope,
|
|
223
|
+
managed_identity_client_id=managed_identity_client_id,
|
|
224
|
+
optimizer_endpoint=optimizer_endpoint,
|
|
225
|
+
optimizer_api_version=optimizer_api_version,
|
|
226
|
+
optimizer_api_key=optimizer_api_key,
|
|
227
|
+
optimizer_auth_mode=optimizer_auth_mode,
|
|
228
|
+
optimizer_ad_scope=optimizer_ad_scope,
|
|
229
|
+
optimizer_managed_identity_client_id=optimizer_managed_identity_client_id,
|
|
230
|
+
target_endpoint=target_endpoint,
|
|
231
|
+
target_api_version=target_api_version,
|
|
232
|
+
target_api_key=target_api_key,
|
|
233
|
+
target_auth_mode=target_auth_mode,
|
|
234
|
+
target_ad_scope=target_ad_scope,
|
|
235
|
+
target_managed_identity_client_id=target_managed_identity_client_id,
|
|
236
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""SkillOpt Optimizer -- skill update operations.
|
|
2
|
+
|
|
3
|
+
Analogous to the optimizer in neural network training: applies the computed
|
|
4
|
+
"gradient" (patches) to the current skill document to produce an updated
|
|
5
|
+
candidate skill.
|
|
6
|
+
|
|
7
|
+
Modules
|
|
8
|
+
-------
|
|
9
|
+
- skill: edit application (optimizer.step() / parameter update)
|
|
10
|
+
- clip: edit ranking and selection (gradient clipping)
|
|
11
|
+
- slow_update: longitudinal comparison and guidance (EMA / regularization)
|
|
12
|
+
- meta_skill: cross-epoch memory for optimizer context
|
|
13
|
+
"""
|
|
14
|
+
from skillopt.optimizer.skill import apply_edit, apply_patch # noqa: F401
|
|
15
|
+
from skillopt.optimizer.clip import rank_and_select # noqa: F401
|