From ef2220c6f111e5e92e19861699a8ab4e40932687 Mon Sep 17 00:00:00 2001 From: jay23606 <4602056+jay23606@users.noreply.github.com> Date: Sun, 11 Oct 2026 22:55:54 -0400 Subject: [PATCH 1/2] test: cover default expert OCTOP_HOME root --- tests/unit/agents/test_default_agent.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/unit/agents/test_default_agent.py b/tests/unit/agents/test_default_agent.py index d56c17622..bc5b26060 100644 --- a/tests/unit/agents/test_default_agent.py +++ b/tests/unit/agents/test_default_agent.py @@ -87,6 +87,15 @@ async def test_bootstrap_main_uses_fs_root_backend(catalog: ExpertCatalog) -> No assert spec.config["backend"]["root_dir"] == host_fs_tree_root() +def test_default_backend_uses_configured_octop_home(monkeypatch, tmp_path: Path) -> None: + octop_home = tmp_path / "octop-home" + monkeypatch.setenv("OCTOP_HOME", str(octop_home)) + + backend = default_home_local_backend() + + assert backend["root_dir"] == str(octop_home) + + async def test_bootstrap_respects_policy_root_dir(catalog: ExpertCatalog, tmp_path: Path) -> None: registry = MagicMock() registry.get_row.return_value = None From 7e7e0c77244d5a60fd59e8b0bf17c3f1745d50bc Mon Sep 17 00:00:00 2001 From: jay23606 <4602056+jay23606@users.noreply.github.com> Date: Sun, 11 Oct 2026 22:57:34 -0400 Subject: [PATCH 2/2] fix: honor OCTOP_HOME for default expert root --- CHANGELOG.md | 12 ++++++++++++ src/octop/infra/agents/experts/default_agent.py | 12 +++++++++--- tests/unit/agents/test_default_agent.py | 5 ++++- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed6e23968..0d2aa3f52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,18 @@ - 定时任务推送的会话在投递时就有标题,不必等用户再发一条消息 - Docker 使用 PostgreSQL 等外部数据库时,容器重启不再重复执行初始化导致 `UniqueViolation` 崩溃:`octop init` 成功后写入数据卷初始化标记(`~/.octop/.initialized`),重启直接启动;`octop init` 对已有管理员改为幂等跳过(#1866) - 更新提示仅对拥有「应用更新」权限的用户显示:非管理员不再看到 PWA「新版本已就绪」横幅,且关闭后同一标签页会话内不再重复弹出 +- Windows 上设置 `OCTOP_HOME` 到其他磁盘时,首次创建的默认专家现在使用该目录作为后端根目录;未设置时仍使用主机文件系统根目录,用户的工作区根目录策略仍优先。 +- 修复便携版程序内升级重复解析已有依赖导致超时的问题;随包提供 uv,独立启动脚本将升级安装到实际加载的 packages 目录。未带 uv 的旧包先下载应用 wheel,确认已有依赖满足新版约束后才离线安装,避免依赖不兼容时提前覆盖应用;下载和本地安装各有 90 秒预算,依赖不满足或安装后 CLI 校验失败时再完整安装依赖,跨镜像回退共用从首次完整安装开始的 900 秒计时窗口。升级校验读取实际加载的代码版本并忽略导入时的额外输出,避免 pip 遗留 dist-info 或包无法加载造成误判;同版本和旧版本在安装前拒绝(#1562)。 +- Ask / Plan 模式下输入栏「+」菜单的选择面板过矮(模型、知识库一次只看得见一条),改为按视口可用高度封顶(目标 400px,且不低于左侧菜单);右侧比左侧矮时上对齐、更高时下对齐向上长;连接器/技能/专家/子智能体数量角标与知识库一样跟在文字后;模型列表现在可搜索 +- 飞牛原生 start 被中途杀掉时立刻退出,不再继续就绪轮询 +- 飞牛 Docker / 本地版清单版本与 pyproject 对齐为 1.0.2b6 +- Docker 首次启动:未设置或不合格的 `OCTOP_DEFAULT_PASSWORD` 不再静默生成随机管理员,改为写入向导口令并走设置向导 +- 云端协同:心跳检测半开连接、禁止自连/重复对端、每用户连接上限;对端回合与隧道请求不再堵住收包循环 +- 自定义 OpenAI 兼容供应商默认关闭流式用量,避免华为 MindIE 等网关因 `stream_options` 返回 422 +- 桌面端下载走本机 Downloads,外链与连接器授权改用系统浏览器 +- Plan 模式把 `plans/*.md` 写回专家工作区,避免 POSIX 默认后端落到容器根目录 `/plans` +- 对话失败与工具错误写入可检索的服务端日志;聊天里可一键关闭实时 Token 后重试 +- 英文界面残留中文文案:浏览器 AI 助手对话消息、技能录制与回放提示、PWA 安装引导、MBTI 人格标签、侧边栏更新徽标 ## [1.0.2b8] - 2026-10-14 diff --git a/src/octop/infra/agents/experts/default_agent.py b/src/octop/infra/agents/experts/default_agent.py index f26f3e676..1075a85cf 100644 --- a/src/octop/infra/agents/experts/default_agent.py +++ b/src/octop/infra/agents/experts/default_agent.py @@ -7,6 +7,7 @@ from __future__ import annotations import logging +import os from typing import Any from octop.infra.agents.experts.catalog import ExpertCatalog, build_create_spec_from_expert @@ -17,6 +18,7 @@ ) from octop.infra.utils.host_dirs import host_fs_tree_root from octop.infra.utils.locale import normalize_locale +from octop.infra.utils.paths import PathLayout logger = logging.getLogger(__name__) @@ -25,12 +27,16 @@ def default_home_local_backend(*, root_dir: str | None = None) -> dict[str, Any]: - """Same local backend as the dashboard create-from-expert default. + """Local backend for the default expert created during setup or invite. - Defaults to host filesystem root; pass *root_dir* when a user + Defaults to the configured Octop home when ``OCTOP_HOME`` is set, or + the host filesystem root otherwise. Pass *root_dir* when a user ``workspace_root_dir`` policy applies. """ - resolved = (root_dir or "").strip() or host_fs_tree_root() + configured_home = os.environ.get("OCTOP_HOME", "").strip() + resolved = (root_dir or "").strip() + if not resolved: + resolved = str(PathLayout.from_env().root) if configured_home else host_fs_tree_root() return { "type": "local_shell", "root_dir": resolved, diff --git a/tests/unit/agents/test_default_agent.py b/tests/unit/agents/test_default_agent.py index bc5b26060..672ab1be1 100644 --- a/tests/unit/agents/test_default_agent.py +++ b/tests/unit/agents/test_default_agent.py @@ -96,11 +96,14 @@ def test_default_backend_uses_configured_octop_home(monkeypatch, tmp_path: Path) assert backend["root_dir"] == str(octop_home) -async def test_bootstrap_respects_policy_root_dir(catalog: ExpertCatalog, tmp_path: Path) -> None: +async def test_bootstrap_respects_policy_root_dir( + catalog: ExpertCatalog, monkeypatch, tmp_path: Path +) -> None: registry = MagicMock() registry.get_row.return_value = None registry.list_agents.return_value = [] registry.create = AsyncMock(return_value=object()) + monkeypatch.setenv("OCTOP_HOME", str(tmp_path / "octop-home")) jail = (tmp_path / "jail").resolve().as_posix() await bootstrap_default_agent(