From 87bc3bd14ac69cb73fff760acb1dd858c0ea32b2 Mon Sep 17 00:00:00 2001 From: yiqi-017 <22300246009@m.fudan.edu.cn> Date: Fri, 19 Jun 2026 00:26:11 +0800 Subject: [PATCH] feat(conductor): follow desktop-selected model live + build on test_yiqi Conductor and its subagents always used the first model (llm_no=0) because GenericAgent() defaults to index 0 and conductor never switched. Read ui.llmNo from ~/.ga_desktop_settings.json and apply it before each conductor task (live follow) and on every subagent spawn, so the conductor uses whatever model the user picked in the desktop UI. Also enable the three desktop package workflows on the test_yiqi branch and add frontends/conductor.py to their path filters so conductor changes trigger a build. --- .../linux-desktop-release-package.yml | 2 ++ .../macos-desktop-release-package.yml | 2 ++ .../windows-desktop-release-package.yml | 2 ++ frontends/conductor.py | 28 +++++++++++++++++++ 4 files changed, 34 insertions(+) diff --git a/.github/workflows/linux-desktop-release-package.yml b/.github/workflows/linux-desktop-release-package.yml index 34ec77ab..3e89567e 100644 --- a/.github/workflows/linux-desktop-release-package.yml +++ b/.github/workflows/linux-desktop-release-package.yml @@ -4,10 +4,12 @@ name: Build Linux Desktop Release Package push: branches: - test + - test_yiqi paths: - ".github/workflows/linux-desktop-release-package.yml" - "desktop_release/scripts/linux/install_linux.sh" - "frontends/desktop/**" + - "frontends/conductor.py" workflow_dispatch: inputs: upload_release: diff --git a/.github/workflows/macos-desktop-release-package.yml b/.github/workflows/macos-desktop-release-package.yml index ae4c5dc0..8678f67e 100644 --- a/.github/workflows/macos-desktop-release-package.yml +++ b/.github/workflows/macos-desktop-release-package.yml @@ -4,10 +4,12 @@ name: Build macOS Desktop Portable Package push: branches: - test + - test_yiqi paths: - ".github/workflows/macos-desktop-release-package.yml" - "desktop_release/scripts/macos/install_macos.sh" - "frontends/desktop/**" + - "frontends/conductor.py" workflow_dispatch: inputs: upload_release: diff --git a/.github/workflows/windows-desktop-release-package.yml b/.github/workflows/windows-desktop-release-package.yml index b262db2d..09b4b2f3 100644 --- a/.github/workflows/windows-desktop-release-package.yml +++ b/.github/workflows/windows-desktop-release-package.yml @@ -4,10 +4,12 @@ name: Build Windows Desktop Portable Package push: branches: - test + - test_yiqi paths: - ".github/workflows/windows-desktop-release-package.yml" - "desktop_release/scripts/windows/install_windows.ps1" - "frontends/desktop/**" + - "frontends/conductor.py" workflow_dispatch: inputs: upload_release: diff --git a/frontends/conductor.py b/frontends/conductor.py index c3dd6834..7b8b6899 100644 --- a/frontends/conductor.py +++ b/frontends/conductor.py @@ -18,6 +18,30 @@ PORT = 8900 HTML_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "conductor.html") +def _desktop_llm_no() -> Optional[int]: + """Read the model index the user picked in the desktop UI. + Persisted by the bridge at ~/.ga_desktop_settings.json under ui.llmNo. + Returns None when unavailable, so callers keep the agent's default model.""" + try: + from pathlib import Path + doc = json.loads((Path.home() / ".ga_desktop_settings.json").read_text(encoding="utf-8")) + no = (doc.get("ui") or {}).get("llmNo") + return int(no) if no is not None else None + except Exception: + return None + + +def _apply_desktop_model(agent: "GenericAgent") -> None: + """Switch a freshly built agent to the desktop-selected model (if any).""" + no = _desktop_llm_no() + if no is None: + return + try: + agent.next_llm(int(no)) + except Exception as e: + print(f"[conductor] failed to apply desktop model #{no}: {e}", file=sys.stderr) + + @asynccontextmanager async def lifespan(app: FastAPI): # 服务启动(事件循环已就绪):捕获 loop 供工作线程跨线程推 WS 广播,并起主agent @@ -197,6 +221,7 @@ class SubagentPool: agent.inc_out = True agent.verbose = False agent.no_print = True + _apply_desktop_model(agent) th = start_agent_runner(agent, f"subagent-{sid}") state = SubAgentState(id=sid, agent=agent, prompt=prompt, status="running", thread=th) with self.lock: self.subagents[sid] = state @@ -346,6 +371,9 @@ API: {base};先requests,GET /readme查用法,GET /chat读未读对话,GE break try: prompt = self._build_prompt(events) + # Follow the desktop-selected model live: re-read before each task + # so switching models in the UI takes effect without restarting. + _apply_desktop_model(self.agent) dq = self.agent.put_task(prompt, source="conductor") self._drain(dq, events) except Exception as e: print(f"Conductor error: {e}")