Skip to content

fix(runtime-host): import external sessions without a configured default model - #4227

Open
liuxiaocs7 wants to merge 1 commit into
apache:mainfrom
liuxiaocs7:liuxiaocs7/import
Open

fix(runtime-host): import external sessions without a configured default model#4227
liuxiaocs7 wants to merge 1 commit into
apache:mainfrom
liuxiaocs7:liuxiaocs7/import

Conversation

@liuxiaocs7

Copy link
Copy Markdown
Member

Summary

External-session import (Settings → 活动 → 导入任务) failed for every conversation with the generic banner "该对话无法转换或保存", regardless of size or source.

Root cause: resolveExternalSessionImportTarget resolved the imported task's model with a hardcoded { kind: 'default' } target, so it threw "No default Session model is configured" whenever the workspace had no default set — a legitimate state for a self-configured profile that still has usable connections (a default is only auto-set during onboarding bootstrap). The throw happened before the source was read, so it failed every import; at the IPC boundary it became a RuntimeHostOperationError the renderer redacted down to the generic fallback banner.

This resolves the import model by preferring the configured default but falling back to the first ready connection+model in the catalog, reusing the existing explicit-target readiness path (resolveExecutionConnection + authorizeConnectionModel) so disabled / retired / credential-less / non-chat candidates are skipped. Behavior is unchanged when a default is set and ready.

It also makes import errors actionable: because Electron strips the error code before the renderer sees it, Desktop Main now maps the intact Host operation code to typed IPC reasons (no_model, source_unreadable) so the page shows a specific banner instead of the redacted fallback. This also gives the oversized-rollout (> 64 MB) failure an honest "too large" message rather than the same generic text.

Fixes#4226

Verification

Ran locally (from the worktree):

  • runtime-host — 53/53 pass (session-catalog-coordinator.test.ts, external-session-coordinator.test.ts), including 4 new cases: fallback when no default is set; skip an unready default and use the next ready connection; clean failure when no connection is usable; and the previously-uncovered resolveTarget-throws → importFailure branch. The 3 new coordinator tests fail without the fix.
  • desktop main — 23/23 pass (import-tasks-settings-page.test.ts, runtime-host-external-sessions-ipc-main.test.ts), including 5 new cases: the code→reason mapping (no_model, source_unreadable, and rethrow for an unmapped code), and the two new banners rendered by the page.
  • tsc (typecheck) clean for @maka/core, @maka/runtime-host, @maka/ui, and desktop build:main.
  • biome check clean on all changed files.

Not run: the full-repo npm run build / npm run typecheck and knip. (This environment has a pre-existing, unrelated @maka/runtime type error — HttpsProxyAgent is not generic — that predates and is untouched by this change.)

User-visible change: the import error banner. New copy — zh importFailedNoModel: "没有可用的模型连接,无法为导入的任务选择模型。请先在设置 › 服务商中配置并启用一个模型后再导入。"; importFailedSourceUnreadable: "无法读取或转换该对话,它可能过大或已损坏。请检查来源后重试。" (English equivalents added). No layout change, so no screenshot; the two banners are asserted by the page test.

Root cause

See #4226 for the full trace. The redacted banner (generalizedErrorMessageChineseimportFailedFallback) hid the real error, so the failure was undiagnosable from the UI — the typed-reason mapping above is the durable fix for that.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Code (claude-opus-4.8) diagnosed the root cause against real local data, implemented the fix and tests, and drafted this PR. The commit carries a Generated-by trailer.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@github-actionsgithub-actionsBot added the effort/L Under 1000 readable lines label Aug 29, 2026
…ult model
External-session import resolved its task's model with a hardcoded
`{ kind: 'default' }` target, so it threw "No default Session model is
configured" whenever the workspace had no default set — a legitimate state for
a self-configured profile with otherwise-usable connections. The throw happened
before the source was read, so every import failed, surfaced as the generic
"该对话无法转换或保存" banner.
Split model resolution by caller intent:
- `resolveExternalSessionImportTarget` (import, an explicit user action) prefers
the default but falls back to the first ready connection+model.
- `resolveDefaultCreateTarget` (autonomous WorkHub/scheduled/root create) keeps
the strict, fail-closed default — there is no user in the loop to pick one, and
WorkHub's "配置默认模型" startup banner depends on that throw. This is the path
the WorkHub coordination E2E exercises.
Give import failures stable, code-based classification: publish dedicated
`model_unavailable` and `source_unreadable` operation error codes (compatibility
epoch 68 -> 69), so Desktop Main maps them to typed IPC reasons by code rather
than by the redacted error message. An unsupported adapter (`invalid_request`)
is no longer mislabeled as a too-large/corrupt source, and the oversized-rollout
(> 64 MB) failure gets an honest "too large" banner.
Refs apache#4226
Generated-by: Claude (claude-opus-4.8)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/LUnder 1000 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

External-session import fails for every conversation when no default model is configured

1 participant

@liuxiaocs7