feat(core): add durable session fork event

This commit is contained in:
Dax Raad 2026-06-29 16:13:51 -04:00
commit b2d46ecd7e
11 changed files with 582 additions and 82 deletions

View file

@ -11,6 +11,8 @@ import type {
SessionsActiveOutput,
SessionsGetInput,
SessionsGetOutput,
SessionsForkInput,
SessionsForkOutput,
SessionsSwitchAgentInput,
SessionsSwitchAgentOutput,
SessionsSwitchModelInput,
@ -361,6 +363,18 @@ export function make(options: ClientOptions) {
},
requestOptions,
).then((value) => value.data),
fork: (input: SessionsForkInput, requestOptions?: RequestOptions) =>
request<{ readonly data: SessionsForkOutput }>(
{
method: "POST",
path: `/api/session/${encodeURIComponent(input.sessionID)}/fork`,
body: { messageID: input["messageID"] },
successStatus: 200,
declaredStatuses: [404, 400, 401],
empty: false,
},
requestOptions,
).then((value) => value.data),
switchAgent: (input: SessionsSwitchAgentInput, requestOptions?: RequestOptions) =>
request<SessionsSwitchAgentOutput>(
{

View file

@ -33,6 +33,15 @@ export type SessionNotFoundError = {
export const isSessionNotFoundError = (value: unknown): value is SessionNotFoundError =>
typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "SessionNotFoundError"
export type MessageNotFoundError = {
readonly _tag: "MessageNotFoundError"
readonly sessionID: string
readonly messageID: string
readonly message: string
}
export const isMessageNotFoundError = (value: unknown): value is MessageNotFoundError =>
typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "MessageNotFoundError"
export type ConflictError = {
readonly _tag: "ConflictError"
readonly message: string
@ -65,15 +74,6 @@ export type UnknownError = {
export const isUnknownError = (value: unknown): value is UnknownError =>
typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "UnknownError"
export type MessageNotFoundError = {
readonly _tag: "MessageNotFoundError"
readonly sessionID: string
readonly messageID: string
readonly message: string
}
export const isMessageNotFoundError = (value: unknown): value is MessageNotFoundError =>
typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "MessageNotFoundError"
export type ProviderNotFoundError = {
readonly _tag: "ProviderNotFoundError"
readonly providerID: string
@ -377,6 +377,45 @@ export type SessionsGetOutput = {
}
}["data"]
export type SessionsForkInput = {
readonly sessionID: { readonly sessionID: string }["sessionID"]
readonly messageID?: { readonly messageID?: string | undefined }["messageID"]
}
export type SessionsForkOutput = {
readonly data: {
readonly id: string
readonly parentID?: string
readonly projectID: string
readonly agent?: string
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string }
readonly cost: number
readonly tokens: {
readonly input: number
readonly output: number
readonly reasoning: number
readonly cache: { readonly read: number; readonly write: number }
}
readonly time: { readonly created: number; readonly updated: number; readonly archived?: number }
readonly title: string
readonly location: { readonly directory: string; readonly workspaceID?: string }
readonly subpath?: string
readonly revert?: {
readonly messageID: string
readonly partID?: string
readonly snapshot?: string
readonly diff?: string
readonly files?: ReadonlyArray<{
readonly path: string
readonly status: "added" | "modified" | "deleted"
readonly additions: number
readonly deletions: number
readonly patch: string
}>
}
}
}["data"]
export type SessionsSwitchAgentInput = {
readonly sessionID: { readonly sessionID: string }["sessionID"]
readonly agent: { readonly agent: string }["agent"]
@ -750,6 +789,24 @@ export type SessionsHistoryOutput = {
readonly location?: { readonly directory: string; readonly workspaceID?: string }
readonly data: { readonly timestamp: number; readonly sessionID: string; readonly title: string }
}
| {
readonly id: string
readonly metadata?: { readonly [x: string]: JsonValue }
readonly type: "session.next.forked"
readonly durable?: { readonly aggregateID: string; readonly seq: number; readonly version: number }
readonly location?: { readonly directory: string; readonly workspaceID?: string }
readonly data: {
readonly timestamp: number
readonly sessionID: string
readonly parentID: string
readonly slug: string
readonly title: string
readonly agent?: string
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string }
readonly messageID?: string
readonly copiedSeq: number
}
}
| {
readonly id: string
readonly metadata?: { readonly [x: string]: JsonValue }
@ -1216,6 +1273,24 @@ export type SessionsEventsOutput =
readonly location?: { readonly directory: string; readonly workspaceID?: string }
readonly data: { readonly timestamp: number; readonly sessionID: string; readonly title: string }
}
| {
readonly id: string
readonly metadata?: { readonly [x: string]: unknown }
readonly type: "session.next.forked"
readonly durable?: { readonly aggregateID: string; readonly seq: number; readonly version: number }
readonly location?: { readonly directory: string; readonly workspaceID?: string }
readonly data: {
readonly timestamp: number
readonly sessionID: string
readonly parentID: string
readonly slug: string
readonly title: string
readonly agent?: string
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string }
readonly messageID?: string
readonly copiedSeq: number
}
}
| {
readonly id: string
readonly metadata?: { readonly [x: string]: unknown }