| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511 |
- import { Schema } from "effect"
- import { ProviderMetadata, ToolContent } from "@opencode-ai/llm"
- import { EventV2 } from "../event"
- import { ModelV2 } from "../model"
- import { NonNegativeInt } from "../schema"
- import { V2Schema } from "../v2-schema"
- import { FileAttachment, Prompt } from "./prompt"
- import { SessionSchema } from "./schema"
- import { Location } from "../location"
- import { RelativePath } from "../schema"
- import { SessionMessageID } from "./message-id"
- export { FileAttachment }
- export const Source = Schema.Struct({
- start: NonNegativeInt,
- end: NonNegativeInt,
- text: Schema.String,
- }).annotate({
- identifier: "session.next.event.source",
- })
- export type Source = typeof Source.Type
- const Base = {
- timestamp: V2Schema.DateTimeUtcFromMillis,
- sessionID: SessionSchema.ID,
- }
- const options = {
- durable: {
- aggregate: "sessionID",
- version: 1,
- },
- } as const
- const stepSettlementOptions = {
- durable: {
- aggregate: "sessionID",
- version: 2,
- },
- } as const
- export const UnknownError = Schema.Struct({
- type: Schema.Literal("unknown"),
- message: Schema.String,
- }).annotate({
- identifier: "Session.Error.Unknown",
- })
- export type UnknownError = typeof UnknownError.Type
- export const AgentSwitched = EventV2.define({
- type: "session.next.agent.switched",
- ...options,
- schema: {
- ...Base,
- messageID: SessionMessageID.ID,
- agent: Schema.String,
- },
- })
- export type AgentSwitched = typeof AgentSwitched.Type
- export const ModelSwitched = EventV2.define({
- type: "session.next.model.switched",
- ...options,
- schema: {
- ...Base,
- messageID: SessionMessageID.ID,
- model: ModelV2.Ref,
- },
- })
- export type ModelSwitched = typeof ModelSwitched.Type
- export const Moved = EventV2.define({
- type: "session.next.moved",
- ...options,
- schema: {
- ...Base,
- location: Location.Ref,
- subdirectory: RelativePath.pipe(Schema.optional),
- },
- })
- export type Moved = typeof Moved.Type
- export const Prompted = EventV2.define({
- type: "session.next.prompted",
- ...options,
- schema: {
- ...Base,
- messageID: SessionMessageID.ID,
- prompt: Prompt,
- delivery: Schema.Literals(["steer", "queue"]),
- },
- })
- export type Prompted = typeof Prompted.Type
- export namespace PromptLifecycle {
- export const Admitted = EventV2.define({
- type: "session.next.prompt.admitted",
- ...options,
- schema: {
- ...Base,
- messageID: SessionMessageID.ID,
- prompt: Prompt,
- delivery: Schema.Literals(["steer", "queue"]),
- },
- })
- export type Admitted = typeof Admitted.Type
- export const Promoted = EventV2.define({
- type: "session.next.prompt.promoted",
- ...options,
- schema: {
- ...Base,
- messageID: SessionMessageID.ID,
- prompt: Prompt,
- timeCreated: V2Schema.DateTimeUtcFromMillis,
- },
- })
- export type Promoted = typeof Promoted.Type
- }
- export const InterruptRequested = EventV2.define({
- type: "session.next.interrupt.requested",
- ...options,
- schema: Base,
- })
- export type InterruptRequested = typeof InterruptRequested.Type
- export const ContextUpdated = EventV2.define({
- type: "session.next.context.updated",
- ...options,
- schema: {
- ...Base,
- messageID: SessionMessageID.ID,
- text: Schema.String,
- },
- })
- export type ContextUpdated = typeof ContextUpdated.Type
- export const Synthetic = EventV2.define({
- type: "session.next.synthetic",
- ...options,
- schema: {
- ...Base,
- messageID: SessionMessageID.ID,
- text: Schema.String,
- },
- })
- export type Synthetic = typeof Synthetic.Type
- export namespace Shell {
- export const Started = EventV2.define({
- type: "session.next.shell.started",
- ...options,
- schema: {
- ...Base,
- messageID: SessionMessageID.ID,
- callID: Schema.String,
- command: Schema.String,
- },
- })
- export type Started = typeof Started.Type
- export const Ended = EventV2.define({
- type: "session.next.shell.ended",
- ...options,
- schema: {
- ...Base,
- callID: Schema.String,
- output: Schema.String,
- },
- })
- export type Ended = typeof Ended.Type
- }
- export namespace Step {
- export const Started = EventV2.define({
- type: "session.next.step.started",
- ...options,
- schema: {
- ...Base,
- assistantMessageID: SessionMessageID.ID,
- agent: Schema.String,
- model: ModelV2.Ref,
- snapshot: Schema.String.pipe(Schema.optional),
- },
- })
- export type Started = typeof Started.Type
- export const Ended = EventV2.define({
- type: "session.next.step.ended",
- ...stepSettlementOptions,
- schema: {
- ...Base,
- assistantMessageID: SessionMessageID.ID,
- finish: Schema.String,
- cost: Schema.Finite,
- tokens: Schema.Struct({
- input: Schema.Finite,
- output: Schema.Finite,
- reasoning: Schema.Finite,
- cache: Schema.Struct({
- read: Schema.Finite,
- write: Schema.Finite,
- }),
- }),
- snapshot: Schema.String.pipe(Schema.optional),
- },
- })
- export type Ended = typeof Ended.Type
- export const Failed = EventV2.define({
- type: "session.next.step.failed",
- ...stepSettlementOptions,
- schema: {
- ...Base,
- assistantMessageID: SessionMessageID.ID,
- error: UnknownError,
- },
- })
- export type Failed = typeof Failed.Type
- }
- export namespace Text {
- export const Started = EventV2.define({
- type: "session.next.text.started",
- ...options,
- schema: {
- ...Base,
- assistantMessageID: SessionMessageID.ID,
- textID: Schema.String,
- },
- })
- export type Started = typeof Started.Type
- // Stream fragments are live-only; Text.Ended is the replayable full-value boundary.
- export const Delta = EventV2.define({
- type: "session.next.text.delta",
- schema: {
- ...Base,
- assistantMessageID: SessionMessageID.ID,
- textID: Schema.String,
- delta: Schema.String,
- },
- })
- export type Delta = typeof Delta.Type
- export const Ended = EventV2.define({
- type: "session.next.text.ended",
- ...options,
- schema: {
- ...Base,
- assistantMessageID: SessionMessageID.ID,
- textID: Schema.String,
- text: Schema.String,
- },
- })
- export type Ended = typeof Ended.Type
- }
- export namespace Reasoning {
- export const Started = EventV2.define({
- type: "session.next.reasoning.started",
- ...options,
- schema: {
- ...Base,
- assistantMessageID: SessionMessageID.ID,
- reasoningID: Schema.String,
- providerMetadata: ProviderMetadata.pipe(Schema.optional),
- },
- })
- export type Started = typeof Started.Type
- // Stream fragments are live-only; Reasoning.Ended is the replayable full-value boundary.
- export const Delta = EventV2.define({
- type: "session.next.reasoning.delta",
- schema: {
- ...Base,
- assistantMessageID: SessionMessageID.ID,
- reasoningID: Schema.String,
- delta: Schema.String,
- },
- })
- export type Delta = typeof Delta.Type
- export const Ended = EventV2.define({
- type: "session.next.reasoning.ended",
- ...options,
- schema: {
- ...Base,
- assistantMessageID: SessionMessageID.ID,
- reasoningID: Schema.String,
- text: Schema.String,
- providerMetadata: ProviderMetadata.pipe(Schema.optional),
- },
- })
- export type Ended = typeof Ended.Type
- }
- export namespace Tool {
- const ToolBase = {
- ...Base,
- assistantMessageID: SessionMessageID.ID,
- callID: Schema.String,
- }
- export namespace Input {
- export const Started = EventV2.define({
- type: "session.next.tool.input.started",
- ...options,
- schema: {
- ...ToolBase,
- name: Schema.String,
- },
- })
- export type Started = typeof Started.Type
- // Stream fragments are live-only; Input.Ended is the replayable raw-input boundary.
- export const Delta = EventV2.define({
- type: "session.next.tool.input.delta",
- schema: {
- ...ToolBase,
- delta: Schema.String,
- },
- })
- export type Delta = typeof Delta.Type
- export const Ended = EventV2.define({
- type: "session.next.tool.input.ended",
- ...options,
- schema: {
- ...ToolBase,
- text: Schema.String,
- },
- })
- export type Ended = typeof Ended.Type
- }
- export const Called = EventV2.define({
- type: "session.next.tool.called",
- ...options,
- schema: {
- ...ToolBase,
- tool: Schema.String,
- input: Schema.Record(Schema.String, Schema.Unknown),
- provider: Schema.Struct({
- executed: Schema.Boolean,
- metadata: ProviderMetadata.pipe(Schema.optional),
- }),
- },
- })
- export type Called = typeof Called.Type
- /**
- * Replayable bounded running-tool state. Tools should checkpoint semantic
- * transitions or at a bounded cadence, not persist every stdout/stderr chunk.
- */
- export const Progress = EventV2.define({
- type: "session.next.tool.progress",
- ...options,
- schema: {
- ...ToolBase,
- structured: Schema.Record(Schema.String, Schema.Any),
- content: Schema.Array(ToolContent),
- },
- })
- export type Progress = typeof Progress.Type
- export const Success = EventV2.define({
- type: "session.next.tool.success",
- ...options,
- schema: {
- ...ToolBase,
- structured: Schema.Record(Schema.String, Schema.Any),
- content: Schema.Array(ToolContent),
- outputPaths: Schema.Array(Schema.String).pipe(Schema.optional),
- result: Schema.Unknown.pipe(Schema.optional),
- provider: Schema.Struct({
- executed: Schema.Boolean,
- metadata: ProviderMetadata.pipe(Schema.optional),
- }),
- },
- })
- export type Success = typeof Success.Type
- export const Failed = EventV2.define({
- type: "session.next.tool.failed",
- ...options,
- schema: {
- ...ToolBase,
- error: UnknownError,
- result: Schema.Unknown.pipe(Schema.optional),
- provider: Schema.Struct({
- executed: Schema.Boolean,
- metadata: ProviderMetadata.pipe(Schema.optional),
- }),
- },
- })
- export type Failed = typeof Failed.Type
- }
- export const RetryError = Schema.Struct({
- message: Schema.String,
- statusCode: Schema.Finite.pipe(Schema.optional),
- isRetryable: Schema.Boolean,
- responseHeaders: Schema.Record(Schema.String, Schema.String).pipe(Schema.optional),
- responseBody: Schema.String.pipe(Schema.optional),
- metadata: Schema.Record(Schema.String, Schema.String).pipe(Schema.optional),
- }).annotate({
- identifier: "session.next.retry_error",
- })
- export type RetryError = typeof RetryError.Type
- export const Retried = EventV2.define({
- type: "session.next.retried",
- ...options,
- schema: {
- ...Base,
- attempt: Schema.Finite,
- error: RetryError,
- },
- })
- export type Retried = typeof Retried.Type
- export namespace Compaction {
- export const Started = EventV2.define({
- type: "session.next.compaction.started",
- ...options,
- schema: {
- ...Base,
- messageID: SessionMessageID.ID,
- reason: Schema.Union([Schema.Literal("auto"), Schema.Literal("manual")]),
- },
- })
- export type Started = typeof Started.Type
- export const Delta = EventV2.define({
- type: "session.next.compaction.delta",
- schema: {
- ...Base,
- messageID: SessionMessageID.ID,
- text: Schema.String,
- },
- })
- export type Delta = typeof Delta.Type
- // Retain the unpublished v1 decoder so stored beta events remain replayable.
- export const EndedV1 = EventV2.define({
- type: "session.next.compaction.ended",
- ...options,
- schema: {
- ...Base,
- text: Schema.String,
- include: Schema.String.pipe(Schema.optional),
- },
- })
- export const Ended = EventV2.define({
- type: "session.next.compaction.ended",
- durable: { aggregate: "sessionID", version: 2 },
- schema: {
- ...Base,
- messageID: SessionMessageID.ID,
- reason: Started.data.fields.reason,
- text: Schema.String,
- recent: Schema.String,
- },
- })
- export type Ended = typeof Ended.Type
- }
- const DurableDefinitions = [
- AgentSwitched,
- ModelSwitched,
- Moved,
- Prompted,
- PromptLifecycle.Admitted,
- PromptLifecycle.Promoted,
- InterruptRequested,
- ContextUpdated,
- Synthetic,
- Shell.Started,
- Shell.Ended,
- Step.Started,
- Step.Ended,
- Step.Failed,
- Text.Started,
- Text.Ended,
- Tool.Input.Started,
- Tool.Input.Ended,
- Tool.Called,
- Tool.Progress,
- Tool.Success,
- Tool.Failed,
- Reasoning.Started,
- Reasoning.Ended,
- Retried,
- Compaction.Started,
- Compaction.Ended,
- ] as const
- const EphemeralDefinitions = [Text.Delta, Tool.Input.Delta, Reasoning.Delta, Compaction.Delta] as const
- export const Durable = Schema.Union(DurableDefinitions, { mode: "oneOf" }).pipe(Schema.toTaggedUnion("type"))
- export type DurableEvent = typeof Durable.Type
- export const All = Schema.Union([...DurableDefinitions, ...EphemeralDefinitions], { mode: "oneOf" }).pipe(
- Schema.toTaggedUnion("type"),
- )
- export type Event = typeof All.Type
- export type Type = Event["type"]
- export * as SessionEvent from "./event"
|