Merge remote-tracking branch 'origin/master' into codex/session-title

# Conflicts:
#	docs/architecture.md
#	docs/config-catalog.md
#	docs/event-producer-consumer.md
#	docs/module-graph.md
#	examples/acp-agent/tests/snapshots/advanced-toolchain/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/bash-spill/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/both-mode-turn/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/cancel-tool-calls/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/cancel/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/code-mode-turn/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/code-mode-workspace-context/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/error-finish/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/fs-edit/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/fs-policy-reject/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/fs-read-window/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/fs-read/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/fs-terminal-card/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/fs-write-overwrite/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/fs-write/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-posttool-block/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-posttool-context/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-pretool-ask/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-pretool-deny/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-promptsubmit-context/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-stop-continue/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-posttool-block/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-posttool-context/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-pretool-block/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-promptsubmit-context/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-stop-continue/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/model-switching/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/multi-turn/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/parallel-tool-calls/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/repeat-tool-guard/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/skill-load/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/subagent-fork/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/subagent-mixed/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/subagent-multi/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/subagent-spawn/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/text-turn/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/todo-plan/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/tool-call-turn/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/workflow-run/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/workspace-context/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/workspace-edit/stdout.expected.jsonl
#	examples/headless-agent/tests/headless.snapshot.ts
#	packages/examples/README.md
#	packages/examples/agent-spine-demo/README.md
#	packages/examples/agent-spine-demo/package.json
#	packages/ui/README.md
#	packages/ui/acp/README.md
This commit is contained in:
Tianyi Cui
2026-07-21 02:13:10 +08:00
273 changed files with 13033 additions and 314 deletions

View File

@@ -1,6 +1,6 @@
/**
* Default executor-less, UI-less agent spine. It bundles the common services,
* background-task registry and controls, concrete loop, local skill and
* background-task registry and controls, optional persisted goals, concrete loop, local skill and
* workspace-context providers, and model-facing bash/skill consumers;
* deployments still choose the LLM adapter, bash executor, and presentation.
* The plugin intentionally exposes named exports only because Loader default
@@ -19,6 +19,9 @@ import ToolRegistry, { type Config as ToolsConfig } from '@deepseek-ai/dsh-tools
import SkillService, { type Config as SkillRegistryConfig } from '@deepseek-ai/dsh-skill'
import * as SkillLocal from '@deepseek-ai/dsh-skill-local'
import AgentRegistry from '@deepseek-ai/dsh-agent'
import GoalService, { type Config as GoalDomainConfig } from '@deepseek-ai/dsh-goal'
import * as goalSession from '@deepseek-ai/dsh-goal-session'
import * as toolGoal from '@deepseek-ai/dsh-tool-goal'
import TaskService from '@deepseek-ai/dsh-tasks'
import * as invariants from '@deepseek-ai/dsh-invariants'
import * as toolBash from '@deepseek-ai/dsh-tool-bash'
@@ -43,6 +46,14 @@ export interface SkillConfig {
tool?: toolSkill.Config
}
/** Persisted goal domain, model-tool policy, and same-session driver config. */
export interface GoalConfig {
/** Goal-domain creation defaults. */
domain?: GoalDomainConfig
/** Model-facing goal-tool authority policy. */
tool?: toolGoal.Config
}
/**
* Bundle config: each field forwarded verbatim to the child that owns it —
* `agents` to the agent loop (an app that pre-creates no agents, like the ACP
@@ -51,8 +62,10 @@ export interface SkillConfig {
* order), the `tools` object to the tool registry (its presentation `mode`),
* `dshHome` to bash environment and local skill discovery, `skills` to the
* skill registry/local provider/tool consumer, `workspaceContext` to the
* workspace-context loader, and `toolBash`/`toolTasks` to the model-facing tool
* plugins this bundle owns. Owner schemas supply defaults for optional input;
* workspace-context loader, `llmRetry` to the bounded request-recovery policy,
* and `toolBash`/`toolTasks` to the model-facing tool plugins this bundle owns.
* `goals` opts into and configures the persisted goal
* domain plus its model tool and same-session driver. Owner schemas supply defaults for optional input;
* workspace context instead requires an explicit byte budget or `false` because
* it changes model-visible input. Producer opt-in stays producer-local:
* `toolBash` configures bash only; independently composed producers keep their
@@ -79,6 +92,8 @@ export interface Config {
toolBash?: toolBash.Config
/** Generic background-task controls; set false to keep the task service without model-facing task tools. */
toolTasks?: toolTasks.Config | false
/** Opt-in persisted same-session goal stack; set false or omit to leave it unmounted. */
goals?: GoalConfig | false
/** Bounded transient model-request retry policy. */
llmRetry?: llmRetry.Config
}
@@ -97,6 +112,12 @@ export const ToolBashConfigSchema: z<toolBash.Config> = toolBash.Config
/** The task-control-tool config schema exported for app packages that forward `toolTasks`. */
export const ToolTasksConfigSchema: z<toolTasks.Config> = toolTasks.Config
/** The persisted-goal config schema exported for app packages that opt in. */
export const GoalConfigSchema: z<GoalConfig> = z.object({
domain: GoalService.Config,
tool: toolGoal.Config,
})
/** The bounded LLM retry schema exported for app packages that forward `llmRetry`. */
export const LlmRetryConfigSchema: z<llmRetry.Config> = llmRetry.Config
@@ -111,8 +132,9 @@ export const Config = z.intersect([
workspaceContext: z.union([z.const(false), workspaceContext.Config]).required(),
toolBash: ToolBashConfigSchema,
toolTasks: z.union([z.const(false), ToolTasksConfigSchema]),
goals: z.union([z.const(false), GoalConfigSchema]),
llmRetry: LlmRetryConfigSchema,
}) as unknown as z<Pick<Config, 'tools' | 'dshHome' | 'skills' | 'workspaceContext' | 'toolBash' | 'toolTasks' | 'llmRetry'>>,
}) as unknown as z<Pick<Config, 'tools' | 'dshHome' | 'skills' | 'workspaceContext' | 'toolBash' | 'toolTasks' | 'goals' | 'llmRetry'>>,
]) as unknown as z<Config>
/**
@@ -131,6 +153,7 @@ export function pickSpineConfig(config: Omit<Config, 'agents'>): Omit<Config, 'a
...config.skills !== undefined ? { skills: config.skills } : {},
...config.toolBash !== undefined ? { toolBash: config.toolBash } : {},
...config.toolTasks !== undefined ? { toolTasks: config.toolTasks } : {},
...config.goals !== undefined ? { goals: config.goals } : {},
...config.llmRetry !== undefined ? { llmRetry: config.llmRetry } : {},
}
}
@@ -174,6 +197,11 @@ export function apply(ctx: Context, config: Config): void {
}
ctx.plugin(AgentRegistry)
ctx.plugin(llmRetry, config.llmRetry ?? {})
if (config.goals !== undefined && config.goals !== false) {
ctx.plugin(GoalService, config.goals.domain ?? {})
ctx.plugin(toolGoal, config.goals.tool ?? {})
ctx.plugin(goalSession)
}
ctx.plugin(TaskService)
ctx.plugin(invariants)
ctx.plugin(toolBash, Object.assign({}, config.toolBash, { dshHome }))