feat(session): define explicit fork boundaries

This commit is contained in:
Dax Raad 2026-07-29 09:49:35 -04:00
commit fc11ed3838
29 changed files with 821 additions and 386 deletions

View file

@ -22,6 +22,7 @@ import { Snapshot } from "./snapshot.js"
import { TokenUsage } from "./token-usage.js"
import { SessionPending } from "./session-pending.js"
import { Project } from "./project.js"
import { SessionFork } from "./session-fork.js"
export { FileAttachment }
@ -127,8 +128,8 @@ export const Forked = Event.durable({
schema: {
...Base,
parentID: SessionID,
parentSeq: Schema.Int.check(Schema.isGreaterThanOrEqualTo(-1)),
from: SessionMessage.ID.pipe(optional),
boundary: SessionFork.Boundary,
instructions: Instruction.Values.pipe(optional),
},
})
export type Forked = typeof Forked.Type

View file

@ -0,0 +1,16 @@
export * as SessionFork from "./session-fork.js"
import { Schema } from "effect"
import { SessionMessage } from "./session-message.js"
export const Boundary = Schema.Union([
Schema.Struct({ type: Schema.Literal("before"), messageID: SessionMessage.ID }),
Schema.Struct({ type: Schema.Literal("through"), messageID: SessionMessage.ID }),
]).annotate({ identifier: "Session.ForkBoundary" })
export type Boundary = typeof Boundary.Type
export const RequestBoundary = Schema.Union([
Schema.Struct({ type: Schema.Literal("before"), messageID: SessionMessage.ID }),
Schema.Struct({ type: Schema.Literal("through") }),
]).annotate({ identifier: "Session.ForkRequestBoundary" })
export type RequestBoundary = typeof RequestBoundary.Type

View file

@ -8,10 +8,10 @@ import { Project } from "./project.js"
import { DateTimeUtcFromMillis, optional, RelativePath } from "./schema.js"
import { SessionEvent } from "./session-event.js"
import { SessionID } from "./session-id.js"
import { SessionMessage } from "./session-message.js"
import { Money } from "./money.js"
import { TokenUsage } from "./token-usage.js"
import { Revert } from "./session-revert.js"
import { SessionFork } from "./session-fork.js"
export const ID = SessionID
export type ID = SessionID
@ -19,6 +19,10 @@ export type ID = SessionID
export const Event = SessionEvent
export { Revert }
export const ForkBoundary = SessionFork.Boundary
export type ForkBoundary = SessionFork.Boundary
export const ForkRequestBoundary = SessionFork.RequestBoundary
export type ForkRequestBoundary = SessionFork.RequestBoundary
export interface Info extends Schema.Schema.Type<typeof Info> {}
export const Info = Schema.Struct({
@ -26,8 +30,7 @@ export const Info = Schema.Struct({
parentID: ID.pipe(optional),
fork: Schema.Struct({
sessionID: ID,
/** Messages before this exclusive boundary are copied into the fork. */
messageID: SessionMessage.ID.pipe(optional),
boundary: ForkBoundary,
}).pipe(optional),
projectID: Project.ID,
agent: Agent.ID.pipe(optional),