feat(host-runtime,llm-replay): keyless llm seam + replay pacing/consumption handle

BootHostOptions.llm: 'deepseek' | false — false mounts no adapter, boots
keyless, and leaves the llm capability seam open for the embedder to fill
on RunningHost.ctx (now the third sanctioned ctx use, JSDoc + README
amended); an unfilled seam fails loud with NO_ADAPTER at the first stream.

dsh-llm-replay grows two additive surfaces for the web browser e2e lane:
paceMs (validated per-chunk delay so a real transport shows incremental
delivery; abort during a pace wait cancels promptly) and a ReplayHandle
return — dispose() plus assertConsumed(), the teardown check that every
recorded script bound and drained, converting silent fixture underruns
into diagnostics. Existing callers updated; config catalog regenerated.
This commit is contained in:
Tianyi Cui
2026-07-24 19:08:10 +08:00
parent fd6713b496
commit 9ef0193dd5
8 files changed
+201 -18

No files matched your search

+10 -1
View File
@@ -65,6 +65,15 @@ export interface BootHostOptions {
persistenceRoot: string
/** Workspace-instruction byte budget/config, or false to disable AGENTS.md/CLAUDE.md loading. */
workspaceContext: workspaceContext.Config | false
/**
* LLM adapter selection: `'deepseek'` (default) mounts the DeepSeek adapter
* (requires an API key at load), `false` mounts no adapter and leaves the
* `llm` capability seam open for the embedder to fill on the returned ctx
* (e.g. the keyless web e2e harness installing a replay backend). With
* `false` and nothing filled, the first stream fails loud with NO_ADAPTER —
* the earliest resolvable point for an open capability seam.
*/
llm?: 'deepseek' | false
/** Default provider route for created/resumed agents (defaults to 'deepseek', the only adapter bootHost registers). */
provider?: string
/** Default model id (defaults to 'deepseek-v4-flash', matching the demos). */
@@ -129,7 +138,7 @@ export async function bootHost(options: BootHostOptions): Promise<HostHandle> {
await ctx.plugin(AgentRegistry)
await ctx.plugin(TaskService)
await ctx.plugin(AgentLoop, { agents: [] })
await ctx.plugin(LlmDeepSeek, {})
if (options.llm !== false) await ctx.plugin(LlmDeepSeek, {})
await ctx.plugin(SessionPersistenceJsonl, { root: options.persistenceRoot })
await ctx.plugin(LocalBashExecutor, {})
// Tool suite mirroring the demo:repl composition (repl-agent/cordis.yml +
+6 -3
View File
@@ -34,9 +34,12 @@ export interface RunningHost {
/**
* Root context — a formal seam, not an escape hatch: (1) the mount point for
* protocol front-door plugins (`dsh acp` = startHost() → ctx.plugin(uiAcp, config));
* (2) headless session-event subscription. Discipline: consuming clients must
* not bypass `api` through ctx; shells must not ctx.plugin to alter the
* assembly (mounting a front door is the shell's own shape, not an assembly change).
* (2) headless session-event subscription; (3) filling a capability seam the
* boot options deliberately left open (`llm: false` → the embedder installs
* its own LLM backend, e.g. keyless replay). Discipline: consuming clients
* must not bypass `api` through ctx; shells must not ctx.plugin to alter the
* assembly (mounting a front door or filling an explicitly-open seam is the
* shell's own shape, not an assembly change).
*/
ctx: Context
/** Single shutdown exit (ctx.fiber.dispose()). Idempotent: a second call returns the same promise. */