Merge remote-tracking branch 'origin/master' into xtr/identified-immutable-messages

# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-24-separate-context-injection-from-turn-execution.i18n.yaml
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/core.i18n.yaml
#	docs/core-data-structures/session.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/persistence-catalog.md
#	packages/core/session/README.i18n.yaml
#	packages/session-title/session-title/tests/persistence.spec.ts
This commit is contained in:
_Kerman
2026-07-28 15:45:53 +08:00
174 changed files with 1994 additions and 1274 deletions

View File

@@ -4,6 +4,12 @@ import { createUserMessage, CallId , createMessage } from '@deepseek-ai/dsh-llm'
import SessionStore, { Session, SessionForkError, SessionId } from '@deepseek-ai/dsh-session'
import type { SessionEvent, TurnEndReason } from '@deepseek-ai/dsh-session'
declare module '@deepseek-ai/dsh-session' {
interface SessionEventMap {
'test/log-only': { value: string }
}
}
async function setup(): Promise<{ ctx: Context; sessions: SessionStore }> {
const ctx = new Context()
await ctx.plugin(SessionStore)
@@ -83,6 +89,21 @@ describe('SessionStore.fork', () => {
})
})
it('includes stable log-only events appended after a closed turn', async () => {
const { ctx, sessions } = await setup()
const source = ctx.sessions.create(SessionId('log-only-parent'))
appendClosedTurn(source, 1, 'hello')
source.append('test/log-only', { value: 'after execution' })
const child = sessions.fork(source, undefined, SessionId('log-only-child'))
expect(child.events).toEqual(source.events)
expect(child.events.at(-1)).toMatchObject({
type: 'test/log-only',
data: { value: 'after execution' },
})
})
it('forks from an earlier turn boundary even when the source currently has an open tail', async () => {
const { ctx, sessions } = await setup()
const source = ctx.sessions.create(SessionId('parent'), { meta: { cwd: '/workspace' } })
@@ -241,7 +262,7 @@ describe('SessionStore.fork', () => {
const boundary = build(source)
expect(() => sessions.fork(source, boundary))
.toThrow(new SessionForkError(`fork boundary ${boundary} in session "open-${lastType}" must be turn/end, got ${lastType}`, 'OPEN_TURN'))
.toThrow(new SessionForkError(`fork boundary ${boundary} in session "open-${lastType}" ends inside open turn 1`, 'OPEN_TURN'))
}
})