refactor: split skill providers

This commit is contained in:
Yichen Jiang
2026-07-08 15:50:38 +08:00
parent 5fd647012e
commit f453ba77a2
77 changed files with 1673 additions and 1334 deletions

View File

@@ -1,6 +1,6 @@
# @deepseek-ai/dsh-acp-agent
The **ACP server app**: a Cordis app plugin that composes the providerless agent spine ([`@deepseek-ai/dsh-agent-core`](../../core/agent-core/README.md)) with the front-door cluster an [Agent Client Protocol](../acp/README.md) server needs, and a `bin` that boots a leaf `cordis.yml` speaking ACP JSON-RPC on stdio.
The **ACP server app**: a Cordis app plugin that composes the default agent spine ([`@deepseek-ai/dsh-agent-core`](../../core/agent-core/README.md)) with the front-door cluster an [Agent Client Protocol](../acp/README.md) server needs, and a `bin` that boots a leaf `cordis.yml` speaking ACP JSON-RPC on stdio.
It is the structured counterpart to [`@deepseek-ai/dsh-stdio-agent`](../stdio-agent/README.md): both consume the same spine, but this one bakes in the OPPOSITE front-door cluster.

View File

@@ -1,5 +1,5 @@
/**
* The ACP server app: the providerless agent spine ({@link
* The ACP server app: the default agent spine ({@link
* @deepseek-ai/dsh-agent-core}) plus the coupled front-door cluster an ACP
* server needs — JSONL session persistence and the {@link @deepseek-ai/dsh-acp}
* bridge, and DELIBERATELY NOTHING that writes to stdout.
@@ -52,7 +52,7 @@ export interface Config {
persona?: string
/** Directory the JSONL session backend writes under. Defaults to `./.sessions`. */
persistenceRoot?: string
/** Skill discovery config forwarded to the shared agent-core spine. */
/** Skill registry/local-provider config forwarded to the shared agent-core spine. */
skills?: agentCore.SkillConfig
}

View File

@@ -27,7 +27,7 @@ async function mount(config: acpAgent.Config): Promise<Context> {
async function isolatedSkillsConfig(): Promise<NonNullable<acpAgent.Config['skills']>> {
const home = await mkdtemp(join(tmpdir(), 'dsh-acp-agent-skills-'))
return { dshHome: join(home, '.dsh'), agentsHome: join(home, '.agents'), installSystemSkills: false }
return { local: { dshHome: join(home, '.dsh'), agentsHome: join(home, '.agents') } }
}
async function withIsolatedSkillHomes<T>(run: () => Promise<T>): Promise<T> {
@@ -83,10 +83,7 @@ describe('dsh-acp-agent composition', () => {
acpAgent.apply(ctx, { model: 'mock' })
await new Promise(resolve => setTimeout(resolve, 50))
expect(ctx.skills).toBeDefined()
expect((await ctx.skills.list()).map(skill => skill.name)).toEqual(expect.arrayContaining([
'dsh-plugin-creator',
'dsh-skill-creator',
]))
expect(await ctx.skills.list()).toEqual([])
await ctx.fiber.dispose()
})
})

View File

@@ -1,6 +1,6 @@
# @deepseek-ai/dsh-stdio-agent
The **terminal stdio chat app**: a Cordis app plugin that composes the providerless agent spine ([`@deepseek-ai/dsh-agent-core`](../../core/agent-core/README.md)) with the front-door cluster a terminal chat needs, and a `bin` that boots a leaf `cordis.yml`.
The **terminal stdio chat app**: a Cordis app plugin that composes the default agent spine ([`@deepseek-ai/dsh-agent-core`](../../core/agent-core/README.md)) with the front-door cluster a terminal chat needs, and a `bin` that boots a leaf `cordis.yml`.
It is the readline counterpart to [`@deepseek-ai/dsh-acp-agent`](../acp-agent/README.md): both consume the same spine, but each bakes in the OPPOSITE front-door cluster.

View File

@@ -1,5 +1,5 @@
/**
* The stdio chat app: the providerless agent spine ({@link
* The stdio chat app: the default agent spine ({@link
* @deepseek-ai/dsh-agent-core}) plus the coupled front-door cluster a terminal
* chat needs — a console logger, the readline UI (the in-package `stdio-chat`
* module), JSONL session
@@ -67,7 +67,7 @@ export interface Config {
persistenceRoot?: string
/** stdin-chat banner printed once on start. Defaults to `'ready.'`. */
welcome?: string
/** Skill discovery config forwarded to the shared agent-core spine. */
/** Skill registry/local-provider config forwarded to the shared agent-core spine. */
skills?: agentCore.SkillConfig
/**
* If set, the `main` agent RESUMES this persisted session id instead of

View File

@@ -34,7 +34,7 @@ async function mount(config: stdioAgent.Config): Promise<Context> {
async function isolatedSkillsConfig(): Promise<NonNullable<stdioAgent.Config['skills']>> {
const home = await mkdtemp(join(tmpdir(), 'dsh-stdio-agent-skills-'))
return { dshHome: join(home, '.dsh'), agentsHome: join(home, '.agents'), installSystemSkills: false }
return { local: { dshHome: join(home, '.dsh'), agentsHome: join(home, '.agents') } }
}
async function withIsolatedSkillHomes<T>(run: () => Promise<T>): Promise<T> {
@@ -93,10 +93,7 @@ describe('dsh-stdio-agent app', () => {
stdioAgent.apply(ctx, { model: 'mock' })
await new Promise(resolve => setTimeout(resolve, 80))
expect(ctx.skills).toBeDefined()
expect((await ctx.skills.list()).map(skill => skill.name)).toEqual(expect.arrayContaining([
'dsh-plugin-creator',
'dsh-skill-creator',
]))
expect(await ctx.skills.list()).toEqual([])
await ctx.fiber.dispose()
})
})