feat(tui): lazy-create the session on first use with the v2 engine - #2458
feat(tui): lazy-create the session on first use with the v2 engine#2458liruifengv wants to merge 7 commits into
Conversation
Start the interactive TUI session-less under the v2 engine and create the session on first use (message, bash input, or a session-requiring slash command) instead of at startup. Skills and plugin commands are resolved from the workspace/app-global catalogs without a session, and the footer shows config defaults (model, permission, plan mode, thinking effort, context cap) until the session exists.
|
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d3755653bd
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…king Concurrent first-use triggers (double Enter, a slash command right after a prompt) both observed `session === undefined` and created their own session, letting the later setSession close the first one mid-dispatch. Share an in-flight creation promise instead. A session-only thinking choice (model picker Alt+S) made before the first session exists only updated appState, so the lazy-created session fell back to the engine default while the footer showed the chosen effort. Carry it as a first-session thinking override and clear it on creation.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 79fe2a18cb
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
The v2 engine applies config.defaultPlanMode at session create time (sessionLifecycleService), so passing the pre-filled appState.planMode as the create override entered plan mode twice and threw 'Already in plan mode' on the first message. Pass only the explicit CLI --plan intent for session-less v2 creation; the config default stays footer-only.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cd52d72a04
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…ings session-less A bash command submitted while the first prompt is still being lazy-created shared the in-flight creation promise but resumed past handleUserInput's busy check, running runShellCommand concurrently with the prompt. Re-check streamingPhase after the await and queue instead. /settings is a local settings entry point: opening it must not require or create a session, so it no longer triggers lazy creation; its session-requiring sub-items keep their own errors.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2e21d4cfa3
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…ins session-free A skill/plugin or idle-only slash command submitted while the first prompt was still being lazy-created shared the in-flight creation promise but resumed past the availability check resolved before the await, running concurrently with the prompt's turn. Re-check the busy gate after the shared await in the skill, plugin-command and builtin dispatch paths. /plugins is app-global on the v2 engine, so a session-less startup no longer creates a session (or fails with LLM-not-set) just to manage plugins: the harness now exposes the global plugin API and the command routes through it until a session exists.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c5e87a1ccd
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
The bare and `list` forms already tolerate a missing session, but the blanket lazy-create gate forced a session (or failed with LLM-not-set) before they could run. Only the path-adding form needs a live session, so it now lazy-creates inside the handler instead of in the dispatch preflight.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c7392b65bf
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| let session = host.session; | ||
|
|
||
| if (input.length === 0 || input.toLowerCase() === 'list') { | ||
| const additionalDirs = session?.summary?.additionalDirs ?? []; |
There was a problem hiding this comment.
Use pending dirs when listing before lazy session
When v2 starts session-less and startupInput.additionalDirs is already populated, host.session is still undefined but appState.additionalDirs contains the directories that will be passed into the lazy-created session. This read-only branch only looks at session?.summary, so /add-dir or /add-dir list incorrectly reports that no additional directories are configured until some other action creates the session; fall back to the app state when there is no active session.
Useful? React with 👍 / 👎.
| async function reloadPlugins(host: SlashCommandHost): Promise<void> { | ||
| const summary = await host.requireSession().reloadPlugins(); | ||
| const summary = await (await resolvePluginApi(host)).reloadPlugins(); | ||
| const line = `Reload: +${summary.added.length} -${summary.removed.length}` + | ||
| (summary.errors.length > 0 ? ` (${summary.errors.length} errors)` : ''); | ||
| host.showStatus(line); |
There was a problem hiding this comment.
Refresh plugin slash commands after global reloads
When /plugins reload runs before the first v2 session exists, this now reloads the app-global plugin service, but the TUI's pluginCommandMap is still the snapshot fetched at startup and is not rebuilt here. Any newly added or enabled plugin slash command continues to be parsed as a normal prompt until a session is created or the TUI restarts, so the sessionless reload path does not actually apply command changes in the current UI.
Useful? React with 👍 / 👎.
Related Issue
No linked issue — this is part of the ongoing agent-core-v2 engine rollout for the interactive TUI.
Problem
The TUI eagerly creates a session at startup (
KimiTUI.initcallsharness.createSessioneven when the user has not sent anything yet). Under the v2 engine this is unnecessary: a workspace handler can exist without a session, the main agent is only materialized on first use, and skills live on the workspace rather than the session. Eager creation also means the session appears in the picker / persisted session store before the user has done anything.What changed
With the v2 engine (
KIMI_CODE_EXPERIMENTAL_FLAG), the TUI now starts session-less and creates the session on first use:--session/--continueresume and the--session ""picker behave as before. The footer shows the config defaults the engine would apply atcreateSessiontime (model,defaultPermissionMode,defaultPlanMode, thinking effort, context cap) so nothing goes blank while waiting./plan/yolo/auto/compact/goal/permission/settings/undo/web/fork/export-*/init/btw/swarm/add-dir/plugins/mcp/usage/status/title) and skill/plugin commands all lazy-create the session via a sharedensureSession()path./login,/model,/logout,/provider,/reload,/copy,/themeand other session-independent commands never trigger creation;activateModelAfterLoginno longer creates a session after login/model switch.refreshSkillCommandsfalls back toharness.listWorkspaceSkills(workDir)when no session exists (plugin skills are missing from that list until the session is created and refreshed). Plugin commands are already app-global under v2, so a newKimiHarness.listPluginCommands()exposes them session-less (the base RPC returns an empty list for v1).--agent/--agent-file: the startup agent binding is carried inappStateand applied to the first lazy-created session, instead of being lost when session creation moves out ofinit()./plugins: fixed a latent unhandled-rejection when the command runs without an active session (its internalrequireSessionthrow was dispatched viavoid).Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.