diff --git a/.env.example b/.env.example index 12e534d..67272f1 100644 --- a/.env.example +++ b/.env.example @@ -7,7 +7,7 @@ OPENAI_MODEL=mimo-v2.6-flash # 单次模型 HTTP 请求超时(秒) OPENAI_TIMEOUT_SECONDS=300 # 可选的后台步骤截图摘要单次超时,独立于上面的主模型请求超时。 -ARTEMIS_STEP_SUMMARIZER_TIMEOUT_SECONDS=25 +ARTEMIS_STEP_SUMMARIZER_TIMEOUT_SECONDS=120 # 失败后最多重试 5 次,由 Artemis 统一管理,SDK 不叠加重试。 OPENAI_MAX_RETRIES=5 OPENAI_RETRY_INTERVAL_SECONDS=10 diff --git a/apps/showcase_ui/package-lock.json b/apps/showcase_ui/package-lock.json index 63d9745..9011e43 100644 --- a/apps/showcase_ui/package-lock.json +++ b/apps/showcase_ui/package-lock.json @@ -1,12 +1,12 @@ { "name": "artemis-showcase-ui", - "version": "1.2.2", + "version": "1.2.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "artemis-showcase-ui", - "version": "1.2.2", + "version": "1.2.3", "dependencies": { "@angular/cdk": "^22.1.5", "@angular/common": "^22.1.4", diff --git a/apps/showcase_ui/package.json b/apps/showcase_ui/package.json index 9fb0446..cd55115 100644 --- a/apps/showcase_ui/package.json +++ b/apps/showcase_ui/package.json @@ -1,6 +1,6 @@ { "name": "artemis-showcase-ui", - "version": "1.2.2", + "version": "1.2.3", "scripts": { "ng": "ng", "start": "ng serve --proxy-config proxy.conf.json", diff --git a/artemis/agents/flash/summarizer.py b/artemis/agents/flash/summarizer.py index 36fb2c6..9b1626d 100644 --- a/artemis/agents/flash/summarizer.py +++ b/artemis/agents/flash/summarizer.py @@ -152,7 +152,7 @@ class VisualStepSummarizer(StepMemoryService): ctx: ArtemisContext, model_name: str | None = None, retry_limit: int = 3, - timeout_seconds: float = 25.0, + timeout_seconds: float = 120.0, *, max_concurrency: int = 1, flush_timeout_s: float = 30.0, @@ -161,7 +161,9 @@ class VisualStepSummarizer(StepMemoryService): ctx, max_concurrency=max_concurrency, retry_limit=retry_limit, - flush_timeout_s=flush_timeout_s, + # A pending request must be allowed to reach its own timeout when + # the task finishes; otherwise the shorter flush cancels it first. + flush_timeout_s=max(flush_timeout_s, timeout_seconds + 1.0), ) self._timeout_seconds = timeout_seconds diff --git a/artemis/config/agent.py b/artemis/config/agent.py index aa943b6..9cec72a 100644 --- a/artemis/config/agent.py +++ b/artemis/config/agent.py @@ -371,7 +371,7 @@ class StepSummarizerConfig(BaseModel): description="Lightweight model used for background step state summarization.", ) timeout_seconds: float = Field( - default=25.0, + default=120.0, gt=0, description="Timeout for one optional background visual-summary model request.", ) diff --git a/artemis/memory/__init__.py b/artemis/memory/__init__.py index 5b005df..e044baf 100644 --- a/artemis/memory/__init__.py +++ b/artemis/memory/__init__.py @@ -58,6 +58,7 @@ def ensure_step_memory(ctx): "retry_limit": cfg.memory.runtime.retry_limit, "max_concurrency": cfg.memory.runtime.max_concurrency, "flush_timeout_s": cfg.memory.runtime.flush_timeout_s, + "timeout_seconds": cfg.flash.step_summarizer.timeout_seconds, } except Exception as exc: logger.debug( diff --git a/artemis/resources/config/artemis.jsonc b/artemis/resources/config/artemis.jsonc index e20a9f6..2a876f2 100644 --- a/artemis/resources/config/artemis.jsonc +++ b/artemis/resources/config/artemis.jsonc @@ -33,7 +33,7 @@ "step_summarizer": { "enabled": "${env:ARTEMIS_STEP_SUMMARIZER_ENABLED:-true}", "model": "${env:OPENAI_MODEL:-mimo-v2.6-flash}", - "timeout_seconds": "${env:ARTEMIS_STEP_SUMMARIZER_TIMEOUT_SECONDS:-25}", + "timeout_seconds": "${env:ARTEMIS_STEP_SUMMARIZER_TIMEOUT_SECONDS:-120}", "prune_history_xml": true } }, diff --git a/config/artemis.jsonc b/config/artemis.jsonc index e20a9f6..2a876f2 100644 --- a/config/artemis.jsonc +++ b/config/artemis.jsonc @@ -33,7 +33,7 @@ "step_summarizer": { "enabled": "${env:ARTEMIS_STEP_SUMMARIZER_ENABLED:-true}", "model": "${env:OPENAI_MODEL:-mimo-v2.6-flash}", - "timeout_seconds": "${env:ARTEMIS_STEP_SUMMARIZER_TIMEOUT_SECONDS:-25}", + "timeout_seconds": "${env:ARTEMIS_STEP_SUMMARIZER_TIMEOUT_SECONDS:-120}", "prune_history_xml": true } }, diff --git a/docs/releases/1.2.3.md b/docs/releases/1.2.3.md new file mode 100644 index 0000000..8d85d11 --- /dev/null +++ b/docs/releases/1.2.3.md @@ -0,0 +1,13 @@ +# ARTEMIS-Eapil 1.2.3 + +## 更新 + +- 视觉步骤摘要的单次模型请求默认超时从 25 秒延长至 120 秒;任务收尾不会再在 30 秒时提前取消仍在进行的摘要。可通过 `ARTEMIS_STEP_SUMMARIZER_TIMEOUT_SECONDS` 调整。 +- Pro 与 Flash 共用的步骤摘要服务现在都会读取该超时配置。 +- 本版本还包含尚未发布的 Responses 消息与视频导出修复,以及设备观察稳定性改进。 + +## 安装 + +下载 `artemis-eapil-1.2.3-source.zip`,解压后运行 `start.bat`,国内网络使用 `start-cn.bat`。附件包含可继续更新的 Git 仓库。已有安装可按原方式运行启动脚本更新;升级后重启 ARTEMIS 服务,并重新加载 MCP。 + +验证:Python 默认测试 2207 项通过、2 项跳过、8 项按标记排除;Ruff、质量基线、核心类型检查、前端 149 项测试及构建均通过。 diff --git a/pyproject.toml b/pyproject.toml index 3eedc4e..f63f135 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ [project] name = "artemis" -version = "1.2.2" +version = "1.2.3" description = "Autonomous AI Assistant for Mobile Automation" authors = [ diff --git a/tests/unit/agents/test_flash_step_summarizer.py b/tests/unit/agents/test_flash_step_summarizer.py index 55086ff..5945457 100644 --- a/tests/unit/agents/test_flash_step_summarizer.py +++ b/tests/unit/agents/test_flash_step_summarizer.py @@ -51,6 +51,8 @@ def _user_role_prompt(messages): async def test_summarizer_dispatch_and_caching(mock_context): """Verify non-blocking dispatch and summary generation.""" summarizer = VisualStepSummarizer(mock_context) + assert summarizer._timeout_seconds == 120.0 + assert summarizer._flush_timeout_s > summarizer._timeout_seconds mock_llm_response = AIMessage( content="[Step 1 State: Tapped 'Login' button. Home view opened.]" diff --git a/tests/unit/test_memory_config.py b/tests/unit/test_memory_config.py index eb6e357..d737688 100644 --- a/tests/unit/test_memory_config.py +++ b/tests/unit/test_memory_config.py @@ -16,11 +16,12 @@ import pytest -from artemis.config import AgentGlobalConfig +from artemis.config import AgentGlobalConfig, load_agent_config def test_memory_defaults(): cfg = AgentGlobalConfig.model_validate({}) + assert cfg.flash.step_summarizer.timeout_seconds == 120.0 # 2 per the 2026-09-01 on-device baseline (serial queue at 1 pushed # summary-ready P90 past the scrub-edge grace window). assert cfg.memory.runtime.max_concurrency == 2 @@ -41,6 +42,14 @@ def test_memory_defaults(): assert cfg.memory.transcript.hard_ratio == 0.9 +def test_visual_summary_timeout_config(monkeypatch): + monkeypatch.delenv("ARTEMIS_STEP_SUMMARIZER_TIMEOUT_SECONDS", raising=False) + assert load_agent_config().flash.step_summarizer.timeout_seconds == 120.0 + + monkeypatch.setenv("ARTEMIS_STEP_SUMMARIZER_TIMEOUT_SECONDS", "75") + assert load_agent_config().flash.step_summarizer.timeout_seconds == 75.0 + + def test_transcript_ratio_ladder_is_validated(): """start <= soft <= hard, all within [0, 1]: the defaults pass, a crossed pair is rejected with a clear message.""" diff --git a/uv.lock b/uv.lock index 8da39f8..3c5414b 100644 --- a/uv.lock +++ b/uv.lock @@ -206,7 +206,7 @@ wheels = [ [[package]] name = "artemis" -version = "1.2.2" +version = "1.2.3" source = { editable = "." } dependencies = [ { name = "adbutils" },