fix: stabilize session fork duplicate-id errors
This commit is contained in:
@@ -8,7 +8,7 @@ Session fork service (`ctx.sessionFork`) for creating seeded child sessions from
|
||||
|
||||
| Method | Purpose |
|
||||
|---|---|
|
||||
| `snapshot(source)` | Resolve a live `Session | SessionId`, reject non-boundary logs, and return a deep-cloned seed plus `parentSession` / `seedLength` metadata. |
|
||||
| `snapshot(source)` | Resolve a live `Session \| SessionId`, reject non-boundary logs, and return a deep-cloned seed plus `parentSession` / `seedLength` metadata. |
|
||||
| `fork({ source, sessionId? })` | Create a live child session from `snapshot(source)`, using the caller-supplied child id or the session store's generated id. |
|
||||
|
||||
## Boundary Rule
|
||||
|
||||
@@ -95,10 +95,10 @@ export class SessionForkService extends Service {
|
||||
* `ctx.agents.create` instead.
|
||||
*/
|
||||
fork(options: ForkSessionOptions): Session {
|
||||
const snapshot = this.snapshot(options.source)
|
||||
if (options.sessionId !== undefined && this.ctx.sessions.get(options.sessionId) !== undefined) {
|
||||
throw new SessionForkError(`session "${options.sessionId}" already exists`, 'SESSION_ALREADY_EXISTS')
|
||||
}
|
||||
const snapshot = this.snapshot(options.source)
|
||||
return this.ctx.sessions.create(options.sessionId, {
|
||||
seed: snapshot.seed,
|
||||
meta: snapshot.meta,
|
||||
|
||||
@@ -203,6 +203,16 @@ describe('SessionForkService', () => {
|
||||
.toThrow(new SessionForkError('session "child" already exists', 'SESSION_ALREADY_EXISTS'))
|
||||
})
|
||||
|
||||
it('rejects a duplicate child session id before validating the source boundary', async () => {
|
||||
const { ctx, fork } = await setup()
|
||||
const source = ctx.sessions.create(SessionId('open-parent'))
|
||||
source.append('turn/start', { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } })
|
||||
ctx.sessions.create(SessionId('child'))
|
||||
|
||||
expect(() => fork.fork({ source, sessionId: SessionId('child') }))
|
||||
.toThrow(new SessionForkError('session "child" already exists', 'SESSION_ALREADY_EXISTS'))
|
||||
})
|
||||
|
||||
it('persists a forked child seed through the existing session write path', async () => {
|
||||
const root = await tempRoot()
|
||||
const ctx = new Context()
|
||||
|
||||
Reference in New Issue
Block a user