Merge remote-tracking branch 'origin/master' into codex/skill-system

# Conflicts:
#	docs/event-producer-consumer.md
#	docs/module-graph.md
#	docs/rfc/README.md
#	packages/core/agent-core/package.json
#	packages/core/agent-core/src/index.ts
#	packages/core/agent-loop/README.md
#	packages/core/agent-loop/src/index.ts
#	packages/ui/acp-agent/src/index.ts
#	packages/ui/acp-agent/tests/acp-agent.spec.ts
#	packages/ui/stdio-agent/README.md
#	packages/ui/stdio-agent/src/index.ts
#	packages/ui/stdio-agent/tests/stdio-agent.spec.ts
This commit is contained in:
Yichen Jiang
2026-07-06 10:09:26 +08:00
205 changed files with 2738 additions and 1268 deletions

View File

@@ -54,7 +54,7 @@ async function withIsolatedSkillHomes<T>(run: () => Promise<T>): Promise<T> {
describe('dsh-acp-agent composition', () => {
it('brings up the spine + persistence + the ACP bridge', async () => {
const ctx = await mount({ model: 'mock', systemPrompt: 'hi', persistenceRoot: '/tmp/dsh-acp-agent-test', skills: await isolatedSkillsConfig() })
const ctx = await mount({ model: 'mock', persona: 'hi', persistenceRoot: '/tmp/dsh-acp-agent-test', skills: await isolatedSkillsConfig() })
expect(ctx.get('agents')).toBeDefined()
expect(ctx.get('sessions')).toBeDefined()
expect(ctx.get('sessionPersistence')).toBeDefined()
@@ -70,7 +70,8 @@ describe('dsh-acp-agent composition', () => {
// `ctx.plugin`, which validates+defaults the config first) with no
// persistenceRoot, so the runtime fallback is the one that fires.
const ctx = new Context()
acpAgent.apply(ctx, { model: 'mock', systemPrompt: 'hi', skills: await isolatedSkillsConfig() })
// No persona: covers the omitted-persona forwarding branch too.
acpAgent.apply(ctx, { model: 'mock', skills: await isolatedSkillsConfig() })
await new Promise(resolve => setTimeout(resolve, 50))
expect(ctx.get('sessionPersistence')).toBeDefined()
await ctx.fiber.dispose()
@@ -79,7 +80,7 @@ describe('dsh-acp-agent composition', () => {
it('uses default skill config when apply is called directly without skills', async () => {
await withIsolatedSkillHomes(async () => {
const ctx = new Context()
acpAgent.apply(ctx, { model: 'mock', systemPrompt: 'hi' })
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([
@@ -91,7 +92,7 @@ describe('dsh-acp-agent composition', () => {
})
it('forwards skill config into agent-core', async () => {
const ctx = await mount({ model: 'mock', systemPrompt: 'hi', skills: await isolatedSkillsConfig() })
const ctx = await mount({ model: 'mock', persona: 'hi', skills: await isolatedSkillsConfig() })
expect(await ctx.skills.list()).toEqual([])
await ctx.fiber.dispose()
})

View File

@@ -99,7 +99,7 @@ async function makeConsumer(): Promise<string> {
' name: \'@deepseek-ai/dsh-acp-agent\'',
' config:',
' model: deepseek-v4-flash',
' systemPrompt: \'test agent\'',
' persona: \'test agent\'',
'',
].join('\n'))
return dir

View File

@@ -54,7 +54,7 @@ const CORDIS_YML = `
name: '@deepseek-ai/dsh-acp-agent'
config:
model: deepseek-v4-flash
systemPrompt: 'You are a test agent.'
persona: 'You are a test agent.'
`
interface Spawned {