feat: unify model selection and complete favorite settings
This commit is contained in:
1 parent
a4a5430922
commit
50638d4130
24 files changed
+347
-90
No files matched your search
@@ -8,8 +8,10 @@ from artemis.config.settings import settings
|
||||
def execution_config(item: dict) -> dict:
|
||||
agent = load_agent_config()
|
||||
model = parse_llm_config().operator
|
||||
overrides = item.get("runtime_overrides") or {}
|
||||
profile = overrides.get("profile") or item.get("profile") or "flash"
|
||||
options = {
|
||||
"profile": item.get("profile") or "flash",
|
||||
"profile": profile,
|
||||
"model": model.model,
|
||||
"reasoning_effort": model.reasoning_effort or "default",
|
||||
"request_timeout_seconds": model.timeout,
|
||||
@@ -20,7 +22,7 @@ def execution_config(item: dict) -> dict:
|
||||
"analyze_video": agent.video_analyzer.enable_ledger,
|
||||
"timeout_seconds": settings.ARTEMIS_TASK_TIMEOUT_SECONDS,
|
||||
"verification_level": verification_level_for_checker(agent.checker),
|
||||
"explorer_mode": agent.explorer.resolve(profile=item.get("profile") or "flash"),
|
||||
"explorer_mode": agent.explorer.resolve(profile=profile),
|
||||
"observation_timeout_seconds": settings.ARTEMIS_OBSERVATION_TIMEOUT_SECONDS,
|
||||
"observation_max_attempts": settings.ARTEMIS_OBSERVATION_MAX_ATTEMPTS,
|
||||
"device_command_timeout_seconds": settings.ARTEMIS_DEVICE_COMMAND_TIMEOUT_SECONDS,
|
||||
@@ -30,7 +32,6 @@ def execution_config(item: dict) -> dict:
|
||||
for key in ("device_serial", "verification_level", "explorer_mode", "locked_app_package"):
|
||||
if item.get(key) is not None:
|
||||
options[key] = item[key]
|
||||
overrides = item.get("runtime_overrides") or {}
|
||||
options["recording"] = {**options["recording"], **(overrides.get("recording") or {})}
|
||||
options.update({k: v for k, v in overrides.items() if k != "recording" and v is not None})
|
||||
return {
|
||||
|
||||
@@ -58,12 +58,70 @@ class FavoriteService:
|
||||
value = self.store.get("favorite", identifier(key))
|
||||
if value is None:
|
||||
raise KeyError("收藏不存在")
|
||||
if value.get("config_version") != 1:
|
||||
# Complete legacy snapshots once and preserve their list position.
|
||||
# Re-read under the write lock so a concurrent edit cannot be lost.
|
||||
with self.store.connection() as conn:
|
||||
conn.execute("BEGIN IMMEDIATE")
|
||||
row = conn.execute(
|
||||
"SELECT payload FROM automation_records WHERE kind='favorite' AND id=?", (key,)
|
||||
).fetchone()
|
||||
if row is None:
|
||||
raise KeyError("收藏不存在")
|
||||
value = self._complete(json.loads(row[0]))
|
||||
conn.execute(
|
||||
"UPDATE automation_records SET payload=? WHERE kind='favorite' AND id=?",
|
||||
(json.dumps(value, ensure_ascii=False), key),
|
||||
)
|
||||
conn.commit()
|
||||
return value
|
||||
|
||||
def list(self) -> list[dict]:
|
||||
return [
|
||||
self.get(item["id"]) if item.get("config_version") != 1 else item
|
||||
for item in self.store.records("favorite", 10000)
|
||||
]
|
||||
|
||||
def _complete(self, favorite: dict) -> dict:
|
||||
result = deepcopy(favorite)
|
||||
if result.get("config_version") == 1:
|
||||
return result
|
||||
snapshot = result["snapshot"]
|
||||
if result["kind"] == "batch":
|
||||
for case in snapshot["cases"]:
|
||||
case["task_config"] = execution_config(
|
||||
{
|
||||
"profile": snapshot.get("profile"),
|
||||
"device_serial": snapshot.get("device_serial"),
|
||||
"runtime_overrides": {
|
||||
"timeout_seconds": snapshot.get("timeout_seconds"),
|
||||
**(case.get("task_config") or {}),
|
||||
},
|
||||
}
|
||||
)["runtime_overrides"]
|
||||
elif result["kind"] == "exploration":
|
||||
config = ExplorationConfig.model_validate(snapshot.get("config") or {}).model_dump()
|
||||
snapshot["config"] = config
|
||||
snapshot["task_config"] = execution_config(
|
||||
{
|
||||
"runtime_overrides": {
|
||||
**(snapshot.get("task_config") or {}),
|
||||
**{
|
||||
key: config[key]
|
||||
for key in ("model", "reasoning_effort", "timeout_seconds")
|
||||
},
|
||||
}
|
||||
}
|
||||
)["runtime_overrides"]
|
||||
else:
|
||||
snapshot.update(execution_config(snapshot))
|
||||
result["config_version"] = 1
|
||||
return result
|
||||
|
||||
def _task(self, session_id: str, *, fallback: dict | None = None) -> tuple[dict, list[str]]:
|
||||
job = self.store.job(session_id) or {}
|
||||
if snapshot := job.get("execution_config"):
|
||||
return deepcopy(snapshot), []
|
||||
return execution_config(snapshot), []
|
||||
row = SessionRepository(self.store.path).get_session_by_id(session_id) or {}
|
||||
submission = job.get("submission") or fallback or {}
|
||||
options = {
|
||||
@@ -140,8 +198,8 @@ class FavoriteService:
|
||||
def create(self, value: FavoriteCreate) -> dict:
|
||||
token = f"{value.source_kind}:{value.source_id}:{value.version or ''}"
|
||||
key = hashlib.sha256(token.encode()).hexdigest()[:32]
|
||||
if existing := self.store.get("favorite", key):
|
||||
return existing
|
||||
if self.store.get("favorite", key):
|
||||
return self.get(key)
|
||||
snapshot, missing, kind, version = {}, [], value.source_kind, None
|
||||
source_id = value.source_id
|
||||
repo = ExplorationStore(self.store)
|
||||
@@ -254,10 +312,10 @@ class FavoriteService:
|
||||
}
|
||||
if not favorite["name"]:
|
||||
raise ValueError("收藏名称不能为空")
|
||||
return self.store.put("favorite", key, favorite)
|
||||
return self.store.put("favorite", key, self._complete(favorite))
|
||||
|
||||
def updated(self, favorite: dict, value: FavoriteUpdate) -> dict:
|
||||
result = deepcopy(favorite)
|
||||
result = self._complete(favorite)
|
||||
if value.name is not None:
|
||||
if not value.name.strip():
|
||||
raise ValueError("收藏名称不能为空")
|
||||
|
||||
@@ -80,11 +80,9 @@ def get_model_settings() -> dict:
|
||||
"tool_fallback_no_progress_attempts": settings.ARTEMIS_TOOL_FALLBACK_MAX_NO_PROGRESS_ATTEMPTS,
|
||||
"reasoning_effort": settings.OPENAI_REASONING_EFFORT,
|
||||
"model_presets": [
|
||||
"gpt-6-luna",
|
||||
"gpt-6.1-sol",
|
||||
"gpt-6-astra",
|
||||
"gpt-5.6-luna",
|
||||
"gpt-6-luna",
|
||||
"mimo-v2.6-flash",
|
||||
"mimo-v2.6-pro",
|
||||
],
|
||||
"env_path": str(get_env_file()),
|
||||
|
||||
@@ -103,7 +103,7 @@ def template() -> bytes:
|
||||
json.dumps(
|
||||
{
|
||||
"profile": "pro",
|
||||
"model": "mimo-v2.6-flash",
|
||||
"model": "gpt-6-luna",
|
||||
"reasoning_effort": "high",
|
||||
"verification_level": "final",
|
||||
"record_video": True,
|
||||
|
||||
Reference in new issue
Block a user