Merge remote-tracking branch 'origin/master' into worktree/session-reference

# Conflicts:
#	.agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.md
#	docs/config-catalog.md
#	docs/cordis-catalog/services.md
#	docs/event-producer-consumer.md
#	docs/module-graph.md
#	packages/compact/compact-basic/src/region.ts
#	packages/compact/compact/README.md
#	packages/compact/compact/tests/compact.spec.ts
#	packages/examples/acp-demo/package.json
#	packages/ui/tui/README.md
#	packages/ui/tui/package.json
#	packages/ui/tui/src/index.ts
#	packages/ui/tui/tests/harness.ts
#	packages/ui/tui/tests/tui.spec.ts
This commit is contained in:
Yichen Jiang
2026-07-21 21:10:42 +08:00
629 changed files with 21135 additions and 3315 deletions

View File

@@ -15,6 +15,7 @@ import type { SessionEvent, SessionId } from '@deepseek-ai/dsh-session'
import type { Agent, AgentOptions } from './types.ts'
export * from './types.ts'
export * from './llm-target.ts'
export { agentEvents, assembleContextFor } from './dispatch.ts'
export type { AgentEventDispatch, AgentSubjectEvent } from './dispatch.ts'

View File

@@ -0,0 +1,35 @@
/** Package-owned agent lifecycle invariants. @module @deepseek-ai/dsh-agent/invariant */
import type { Context } from 'cordis'
import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants'
import type { Agent, AgentStatus } from '@deepseek-ai/dsh-agent'
const PACKAGE_NAME = '@deepseek-ai/dsh-agent'
/** Cordis companion plugin name. */
export const name = 'agent-invariant'
/** Services required before the companion can register. */
export const inject = ['invariants']
/** Install the agent contribution into its child registration fiber. */
const install: InvariantInstaller = (ctx, fail) => {
const lastStatus = new WeakMap<Agent, AgentStatus>()
ctx.on('agent/status', (agent, status) => {
const previous = lastStatus.get(agent)
if (previous === status) {
fail(`agent/status repeated ${status} (no-op transition)`)
}
if (previous === 'disposed') {
fail(`agent/status left terminal state disposed → ${status}`)
}
lastStatus.set(agent, status)
}, { global: true })
}
/**
* Register the agent invariant companion.
* @param ctx - Cordis context carrying the invariant service.
* @returns the installed registration's disposer after setup succeeds.
*/
export const apply = (ctx: Context): Promise<() => void> =>
Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install))

View File

@@ -0,0 +1,66 @@
/**
* Agent-scoped provider/model target snapshot shared by interactive front doors.
* @module @deepseek-ai/dsh-agent/llm-target
*/
import type { Context } from 'cordis'
import type { LlmCallConfig } from '@deepseek-ai/dsh-llm'
/** Complete provider/model route selected for one live agent. */
export interface AgentLlmTarget {
/** Registered provider route. */
provider: string
/** Provider-owned model id. */
model: string
}
/** Mutable selection plus the target captured for the current step. */
export interface AgentLlmTargetRef {
/** Target selected for the next step that enters prompt assembly. */
current: AgentLlmTarget | undefined
/** Target captured when the current step entered prompt assembly. */
assembled: AgentLlmTarget | undefined
}
/**
* Couple one mutable target to agent-scoped prompt assembly and request routing.
* Prompt assembly snapshots the selected pair before delegating, then applies
* both prompt variables and request config to that snapshot so a concurrent
* switch takes effect on a later step instead of splitting the two surfaces.
*
* @param agentCtx - The target agent's scoped context.
* @param target - Mutable selection owned by the calling front door.
* @returns Disposer for both scoped waterfall listeners.
*/
export function installAgentLlmTarget(agentCtx: Context, target: AgentLlmTargetRef): () => void {
const disposeAssembly = agentCtx.on('system-prompt/assemble', async (_assembly, _context, next) => {
const selected = target.current
const assembled = await next()
target.assembled = selected
if (selected === undefined) return assembled
return {
...assembled,
variables: {
...assembled.variables,
provider: selected.provider,
model: selected.model,
},
}
})
const disposeRequest = agentCtx.on(
'agent/request',
async (_agent, _turn, _step, _config, next): Promise<LlmCallConfig> => {
const resolved = await next()
const selected = target.assembled
return selected === undefined ? resolved : {
...resolved,
provider: selected.provider,
model: selected.model,
}
},
)
return () => {
disposeAssembly()
disposeRequest()
}
}