feat(web): choose the agent preset on the new-session screen
The composer seat spent nearly all its life disabled: a session's composition is fixed once a turn has run. Move the choice to the new-session screen beside the workspace picker, where it still works, and let the session header report what a running session runs. The hero pick is staged rather than applied — that screen precedes the session it belongs to. It lands when a session becomes current and is still blank, which covers both the session a workspace connect creates and the blank one it reuses; riding `sessions.create` would miss the second. It is spent on first use, matching the workspace picker. Fix the durability the header field claimed but never had: `agentPreset` was declared on `SessionHeader` and dropped by the JSONL header line, the SQLite sessions row, the derived query index, and the cold list projection, so every resumed session came back composed from nothing. Add the web e2e lane that would have caught it — the one lane that mounts the shipped roster, which needed `cordis:group` in the scaffold's Loader builtins, as `mountRootInclude` already registers.
This commit is contained in:
@@ -180,6 +180,20 @@ export interface LaunchOptions {
|
||||
/** Credential reference resolved by the shipped search provider. */
|
||||
apiKeyEnv: string
|
||||
}
|
||||
/**
|
||||
* Replace the roster the scaffold mounts by default (the shipped directory
|
||||
* at `system` trust, default `standard`). Supply this only to change WHICH
|
||||
* presets a scenario sees — a writable user root, a different default —
|
||||
* never to turn the roster on: without one every session composes an agent
|
||||
* with no tools, no persona, and no token meter, which is not a shape the
|
||||
* product ever boots in. The patch lands after the default, so it wins.
|
||||
*/
|
||||
agentPresets?: {
|
||||
/** Roots to discover, in precedence order; the shipped directory is `system`. */
|
||||
roots: { path: string; trust: 'system' | 'user' }[]
|
||||
/** The preset a session that names none is composed from. */
|
||||
default: string
|
||||
}
|
||||
/** Leave the current welcome notice unacknowledged; ordinary scenarios publish it as complete before browser boot. */
|
||||
welcomeNoticePending?: boolean
|
||||
/**
|
||||
@@ -319,6 +333,9 @@ export async function launchWebScaffold(options: LaunchOptions = {}): Promise<We
|
||||
// disable+insert pair.
|
||||
{ id: 'directory-picker', disabled: true },
|
||||
{ insert: [{ id: 'directory-picker-browse', name: '@deepseek-ai/dsh-host-directory-picker-browse' }] },
|
||||
...options.agentPresets === undefined
|
||||
? []
|
||||
: [{ id: 'agent-presets', config: options.agentPresets }],
|
||||
...options.toolsMode === undefined ? [] : [{ id: 'tools', config: { mode: options.toolsMode } }],
|
||||
...options.cordisTools === true
|
||||
? [{ insert: [{ id: 'tool-cordis', name: 'cordis:tool-cordis' }] }]
|
||||
@@ -511,6 +528,8 @@ export function fixtureUserPrompts(fixtureText: string): string[] {
|
||||
* @param scaffold - the target scaffold.
|
||||
* @param fixtureText - raw recorded session.jsonl contents.
|
||||
* @param id - the seeded session id (stable for deterministic goldens).
|
||||
* @param agentPreset - the preset the recorded session was composed from,
|
||||
* for scenarios asserting what a resumed session reports running.
|
||||
* @returns the seeded id.
|
||||
*/
|
||||
/**
|
||||
@@ -534,7 +553,12 @@ export function realizeSeedFixture(scaffold: WebScaffold, fixtureText: string, i
|
||||
: realized.split(fixtureCwd).join(scaffold.workspaceCwd)
|
||||
}
|
||||
|
||||
export async function seedSession(scaffold: WebScaffold, fixtureText: string, id: string): Promise<SessionId> {
|
||||
export async function seedSession(
|
||||
scaffold: WebScaffold,
|
||||
fixtureText: string,
|
||||
id: string,
|
||||
agentPreset?: string,
|
||||
): Promise<SessionId> {
|
||||
const events = parseSessionLog(realizeSeedFixture(scaffold, fixtureText, id))
|
||||
if (events.length === 0) throw new Error('seed fixture has no events')
|
||||
const last = events[events.length - 1]!
|
||||
@@ -547,6 +571,7 @@ export async function seedSession(scaffold: WebScaffold, fixtureText: string, id
|
||||
createdAt: Date.now() - 60_000,
|
||||
cwd: scaffold.workspaceCwd,
|
||||
delegationDepth: 0,
|
||||
...agentPreset === undefined ? {} : { agentPreset },
|
||||
}
|
||||
const seeder = new Context()
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user