export * as SessionMessage from "./session-message.js" import { Schema } from "effect" import { optional } from "./schema.js" import { ToolContent } from "./llm.js" import { Model } from "./model.js" import { Prompt } from "./prompt.js" import { DateTimeUtcFromMillis, PositiveInt, RelativePath, statics } from "./schema.js" import { ascending } from "./identifier.js" import { Event } from "./event.js" import { Shell as ShellSchema } from "./shell.js" import { FinishReason } from "./llm.js" import { SessionError } from "./session-error.js" import { Agent } from "./agent.js" import { Skill as SkillSchema } from "./skill.js" import { Money } from "./money.js" import { Snapshot } from "./snapshot.js" import { TokenUsage } from "./token-usage.js" export const ID = Schema.String.check(Schema.isStartsWith("msg_")).pipe( Schema.brand("Session.Message.ID"), statics((schema) => ({ create: () => schema.make("msg_" + ascending()), fromEvent: (eventID: Event.ID) => schema.make(eventID.replace(/^evt_/, "msg_")), })), ) export type ID = typeof ID.Type const Base = { id: ID, metadata: Schema.Record(Schema.String, Schema.Unknown).pipe(optional), time: Schema.Struct({ created: DateTimeUtcFromMillis }), } export const ProviderState = Schema.Record(Schema.String, Schema.Unknown).annotate({ identifier: "Session.Message.ProviderState", }) export type ProviderState = typeof ProviderState.Type export interface AgentSelected extends Schema.Schema.Type {} export const AgentSelected = Schema.Struct({ ...Base, type: Schema.tag("agent-switched"), agent: Agent.ID, }).annotate({ identifier: "Session.Message.AgentSelected" }) export interface ModelSelected extends Schema.Schema.Type {} export const ModelSelected = Schema.Struct({ ...Base, type: Schema.tag("model-switched"), model: Model.Ref, previous: Model.Ref.pipe(optional), }).annotate({ identifier: "Session.Message.ModelSelected" }) export interface User extends Schema.Schema.Type {} export const User = Schema.Struct({ ...Base, text: Prompt.fields.text, files: Prompt.fields.files, agents: Prompt.fields.agents, type: Schema.tag("user"), }).annotate({ identifier: "Session.Message.User" }) export interface Synthetic extends Schema.Schema.Type {} export const Synthetic = Schema.Struct({ ...Base, text: Schema.String, description: Schema.String.pipe(optional), type: Schema.tag("synthetic"), }).annotate({ identifier: "Session.Message.Synthetic" }) export interface System extends Schema.Schema.Type {} export const System = Schema.Struct({ ...Base, type: Schema.tag("system"), text: Schema.String, }).annotate({ identifier: "Session.Message.System" }) export interface Skill extends Schema.Schema.Type {} export const Skill = Schema.Struct({ ...Base, type: Schema.tag("skill"), skill: SkillSchema.ID, name: SkillSchema.Name, text: Schema.String, }).annotate({ identifier: "Session.Message.Skill" }) export interface Shell extends Schema.Schema.Type {} export const Shell = Schema.Struct({ ...Base, type: Schema.tag("shell"), shellID: ShellSchema.ID, command: Schema.String, status: ShellSchema.Status, exit: Schema.Number.pipe(optional), output: ShellSchema.Output.pipe(optional), time: Schema.Struct({ created: DateTimeUtcFromMillis, completed: DateTimeUtcFromMillis.pipe(optional), }), }).annotate({ identifier: "Session.Message.Shell" }) export interface ToolStateStreaming extends Schema.Schema.Type {} export const ToolStateStreaming = Schema.Struct({ status: Schema.tag("streaming"), input: Schema.String, }).annotate({ identifier: "Session.Message.ToolState.Streaming" }) export interface ToolStateRunning extends Schema.Schema.Type {} export const ToolStateRunning = Schema.Struct({ status: Schema.tag("running"), input: Schema.Record(Schema.String, Schema.Unknown), structured: Schema.Record(Schema.String, Schema.Unknown), content: ToolContent.pipe(Schema.Array), }).annotate({ identifier: "Session.Message.ToolState.Running" }) export interface ToolStateCompleted extends Schema.Schema.Type {} export const ToolStateCompleted = Schema.Struct({ status: Schema.tag("completed"), input: Schema.Record(Schema.String, Schema.Unknown), content: ToolContent.pipe(Schema.Array), structured: Schema.Record(Schema.String, Schema.Unknown), result: Schema.Unknown.pipe(optional), }).annotate({ identifier: "Session.Message.ToolState.Completed" }) export interface ToolStateError extends Schema.Schema.Type {} export const ToolStateError = Schema.Struct({ status: Schema.tag("error"), input: Schema.Record(Schema.String, Schema.Unknown), content: ToolContent.pipe(Schema.Array), structured: Schema.Record(Schema.String, Schema.Unknown), error: SessionError.Error, result: Schema.Unknown.pipe(optional), }).annotate({ identifier: "Session.Message.ToolState.Error" }) export const ToolState = Schema.Union([ToolStateStreaming, ToolStateRunning, ToolStateCompleted, ToolStateError]).pipe( Schema.toTaggedUnion("status"), ) export type ToolState = ToolStateStreaming | ToolStateRunning | ToolStateCompleted | ToolStateError export interface AssistantTool extends Schema.Schema.Type {} export const AssistantTool = Schema.Struct({ type: Schema.tag("tool"), id: Schema.String, name: Schema.String, executed: Schema.Boolean.pipe(optional), providerState: ProviderState.pipe(optional), providerResultState: ProviderState.pipe(optional), state: ToolState, time: Schema.Struct({ created: DateTimeUtcFromMillis, ran: DateTimeUtcFromMillis.pipe(optional), completed: DateTimeUtcFromMillis.pipe(optional), }), }).annotate({ identifier: "Session.Message.Assistant.Tool" }) export interface AssistantText extends Schema.Schema.Type {} export const AssistantText = Schema.Struct({ type: Schema.tag("text"), text: Schema.String, }).annotate({ identifier: "Session.Message.Assistant.Text" }) export interface AssistantReasoning extends Schema.Schema.Type {} export const AssistantReasoning = Schema.Struct({ type: Schema.tag("reasoning"), text: Schema.String, state: ProviderState.pipe(optional), time: Schema.Struct({ created: DateTimeUtcFromMillis, completed: DateTimeUtcFromMillis.pipe(optional), }).pipe(optional), }).annotate({ identifier: "Session.Message.Assistant.Reasoning" }) export const AssistantContent = Schema.Union([AssistantText, AssistantReasoning, AssistantTool]).pipe( Schema.toTaggedUnion("type"), ) export type AssistantContent = AssistantText | AssistantReasoning | AssistantTool export interface AssistantRetry extends Schema.Schema.Type {} export const AssistantRetry = Schema.Struct({ attempt: PositiveInt, at: DateTimeUtcFromMillis, error: SessionError.Error, }).annotate({ identifier: "Session.Message.Assistant.Retry" }) export interface Assistant extends Schema.Schema.Type {} export const Assistant = Schema.Struct({ ...Base, type: Schema.tag("assistant"), agent: Agent.ID, model: Model.Ref, content: AssistantContent.pipe(Schema.Array), snapshot: Schema.Struct({ start: Snapshot.ID.pipe(optional), end: Snapshot.ID.pipe(optional), files: Schema.Array(RelativePath).pipe(optional), }).pipe(optional), finish: FinishReason.pipe(optional), cost: Money.USD.pipe(optional), tokens: TokenUsage.Info.pipe(optional), error: SessionError.Error.pipe(optional), retry: AssistantRetry.pipe(optional), time: Schema.Struct({ created: DateTimeUtcFromMillis, completed: DateTimeUtcFromMillis.pipe(optional), }), }).annotate({ identifier: "Session.Message.Assistant" }) const CompactionBase = { type: Schema.tag("compaction"), ...Base } export interface CompactionRunning extends Schema.Schema.Type {} export const CompactionRunning = Schema.Struct({ ...CompactionBase, status: Schema.tag("running"), reason: Schema.Literals(["auto", "manual"]), summary: Schema.String, recent: Schema.String, }).annotate({ identifier: "Session.Message.Compaction.Running" }) export interface CompactionCompleted extends Schema.Schema.Type {} export const CompactionCompleted = Schema.Struct({ ...CompactionBase, status: Schema.tag("completed"), reason: Schema.Literals(["auto", "manual"]), summary: Schema.String, recent: Schema.String, }).annotate({ identifier: "Session.Message.Compaction.Completed" }) export interface CompactionFailed extends Schema.Schema.Type {} export const CompactionFailed = Schema.Struct({ ...CompactionBase, status: Schema.tag("failed"), reason: Schema.Literals(["auto", "manual"]), error: SessionError.Error, }).annotate({ identifier: "Session.Message.Compaction.Failed" }) export const Compaction = Schema.Union([CompactionRunning, CompactionCompleted, CompactionFailed]).pipe( Schema.toTaggedUnion("status"), Schema.annotate({ identifier: "Session.Message.Compaction" }), ) export type Compaction = CompactionRunning | CompactionCompleted | CompactionFailed export const Info = Schema.Union([ AgentSelected, ModelSelected, User, Synthetic, System, Skill, Shell, Assistant, Compaction, ]) .pipe(Schema.toTaggedUnion("type")) .annotate({ identifier: "Session.Message.Info" }) export type Info = AgentSelected | ModelSelected | User | Synthetic | System | Skill | Shell | Assistant | Compaction export type Type = Info["type"]