fix(goal): close human command surface gaps
This commit is contained in:
@@ -12,7 +12,7 @@ A terminal chat always wants the same cluster, so the package owns it rather tha
|
||||
|---|---|
|
||||
| `@deepseek-ai/dsh-agent-spine-demo` | the spine, pre-creating a `main` agent from this app's provider/model pair with `process.cwd()` as the fresh session cwd and carrying its `persona` |
|
||||
| `@deepseek-ai/dsh-commands` | the human-command registry consumed by the TUI front door and optional command plugins |
|
||||
| `@deepseek-ai/dsh-command-goal` | the direct `/goal` producer; the app enables the spine's persisted-goal stack with it |
|
||||
| `@deepseek-ai/dsh-command-goal` | the direct `/goal` producer mounted only for the TUI front door; readline retains the model-mediated goal path |
|
||||
| `@deepseek-ai/dsh-session-persistence-jsonl` | durable JSONL session log under `persistenceRoot` |
|
||||
| `@deepseek-ai/dsh-user-interaction` | the human question/answer seam used by confirmation tools |
|
||||
| `@deepseek-ai/dsh-tool-ask-user` | the model-facing `ask_user_question` tool |
|
||||
@@ -38,7 +38,7 @@ The leaf `cordis.yml` supplies only the **swappable backends** — an LLM adapte
|
||||
| `skills` | owner defaults | registry-cache, local-provider, and model-facing skill-tool config, routed through `dsh-agent-spine-demo` |
|
||||
| `toolBash` | owner defaults | model-facing bash config routed through `dsh-agent-spine-demo`, including bash's producer-local `enableRunInBackground` |
|
||||
| `toolTasks` | owner defaults | generic `task_output` wait bounds routed through `dsh-agent-spine-demo` |
|
||||
| `goals` | owner defaults | persisted goal-domain and model-tool config; `false` removes the goal stack and `/goal` producer |
|
||||
| `goals` | owner defaults | persisted goal-domain and model-tool config; `false` removes the goal stack and the TUI `/goal` producer |
|
||||
| `persistenceRoot` | `./.sessions` | the JSONL backend's root directory |
|
||||
| `welcome` | `ready.` | terminal banner / TUI subtitle |
|
||||
| `ui` | `{ mode: 'auto' }` | terminal mode (`auto` / `readline` / `tui`) and nested TUI presentation config |
|
||||
|
||||
@@ -101,7 +101,7 @@ export interface Config {
|
||||
toolBash?: NonNullable<agentCore.Config['toolBash']>
|
||||
/** Generic background-task controls forwarded through agent-core; set false to omit their tool surface. */
|
||||
toolTasks?: NonNullable<agentCore.Config['toolTasks']>
|
||||
/** Persisted same-session goals; owner defaults enable them, or false disables the stack and command. */
|
||||
/** Persisted same-session goals; owner defaults enable them, or false disables the stack and TUI command. */
|
||||
goals?: agentCore.GoalConfig | false
|
||||
/**
|
||||
* If set, the pre-created agent RESUMES this persisted session id instead of
|
||||
@@ -152,7 +152,7 @@ export function composeTerminalApp(ctx: Context, config: Config, isTTY: boolean)
|
||||
const goals = config.goals ?? {}
|
||||
if (mode === 'readline') ctx.plugin(ConsoleExporter)
|
||||
ctx.plugin(CommandService)
|
||||
if (goals !== false) ctx.plugin(commandGoal)
|
||||
if (mode === 'tui' && goals !== false) ctx.plugin(commandGoal)
|
||||
ctx.plugin(SessionPersistenceJsonl, { root: config.persistenceRoot ?? DEFAULT_PERSISTENCE_ROOT })
|
||||
ctx.plugin(UserInteractionService)
|
||||
if (mode === 'tui') {
|
||||
|
||||
@@ -118,17 +118,25 @@ describe('dsh-stdio-demo app', () => {
|
||||
|
||||
calls.length = 0
|
||||
stdioAgent.composeTerminalApp(ctx, {
|
||||
provider: 'mock', model: 'mock', workspaceContext: false, goals: false, ui: { mode: 'readline' },
|
||||
provider: 'mock', model: 'mock', workspaceContext: false, goals: false, ui: { mode: 'tui' },
|
||||
}, true)
|
||||
expect(calls.map(call => call.name)).toContain('ui-tui')
|
||||
expect(calls.map(call => call.name)).not.toContain('command-goal')
|
||||
expect(calls.find(call => call.name === 'agent-spine-demo')?.config).toMatchObject({ goals: false })
|
||||
|
||||
calls.length = 0
|
||||
stdioAgent.composeTerminalApp(ctx, {
|
||||
provider: 'mock', model: 'mock', workspaceContext: false, ui: { mode: 'readline' },
|
||||
}, false)
|
||||
expect(calls.map(call => call.name)).toContain('ui-stdio')
|
||||
expect(calls.map(call => call.name)).toContain('ConsoleExporter')
|
||||
expect(calls.map(call => call.name)).not.toContain('ui-tui')
|
||||
expect(calls.map(call => call.name)).not.toContain('command-goal')
|
||||
expect(calls.find(call => call.name === 'agent-spine-demo')?.config).toMatchObject({ goals: false })
|
||||
expect(calls.find(call => call.name === 'agent-spine-demo')?.config).toMatchObject({ goals: {} })
|
||||
})
|
||||
|
||||
it('composes the spine + front-door cluster and pre-creates the main agent', async () => {
|
||||
const ctx = await mount({ provider: 'mock', model: 'mock', persona: 'hi', persistenceRoot: '/tmp/dsh-stdio-demo-spec', skills: await isolatedSkillsConfig(), workspaceContext: false })
|
||||
const ctx = await mount({ provider: 'mock', model: 'mock', persona: 'hi', persistenceRoot: '/tmp/dsh-stdio-demo-spec', skills: await isolatedSkillsConfig(), workspaceContext: false, ui: { mode: 'readline' } })
|
||||
// The spine services (brought up by the agent-spine-demo bundle) are all present.
|
||||
expect(ctx.get('agents')).toBeDefined()
|
||||
expect(ctx.get('agentLoop')).toBeDefined()
|
||||
@@ -145,7 +153,7 @@ describe('dsh-stdio-demo app', () => {
|
||||
expect(agent?.id).toBe(agent?.session.id)
|
||||
expect(agent?.id).toMatch(/^main-session-/)
|
||||
expect(agent?.session.header.cwd).toBe(process.cwd())
|
||||
expect(ctx.commands.find(agent!, 'tui', 'goal')).toBeDefined()
|
||||
expect(ctx.commands.find(agent!, 'tui', 'goal')).toBeUndefined()
|
||||
await ctx.fiber.dispose()
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user