Compare commits

...
Author SHA1 Message Date
Dax Raad 81d81e6334 fix sdk generation for date time schemas 2026-04-24 18:25:25 -04:00
Dax Raad 459af775e8 fix session event typechecks and shell cwd 2026-04-24 18:19:59 -04:00
8 changed files with 929 additions and 468 deletions
+18 -11
View File
@@ -1,6 +1,8 @@
export * as ConfigPermission from "./permission"
import { Schema, SchemaGetter } from "effect"
import z from "zod"
import { zod } from "@/util/effect-zod"
import { ZodOverride } from "@/util/effect-zod"
import { withStatics } from "@/util/schema"
export const Action = Schema.Literals(["ask", "allow", "deny"])
@@ -18,17 +20,9 @@ export const Rule = Schema.Union([Action, Object])
.pipe(withStatics((s) => ({ zod: zod(s) })))
export type Rule = Schema.Schema.Type<typeof Rule>
// Known permission keys get explicit types — most are full Rule (either a
// single Action or a per-pattern object), but a handful of tools take no
// sub-target patterns and are Action-only. Unknown keys fall through the
// Record rest signature as Rule.
//
// StructWithRest canonicalises key order on decode (known first, then rest),
// which used to require the `__originalKeys` preprocess hack because
// `Permission.fromConfig` depended on the user's insertion order. That
// dependency is gone — `fromConfig` now sorts top-level keys so wildcard
// permissions come before specifics, making the final precedence
// order-independent.
// Known permission keys get explicit types in the Effect schema for generated
// docs/types. Runtime config parsing uses `InfoZod` below so user key order is
// preserved for permission precedence.
const InputObject = Schema.StructWithRest(
Schema.Struct({
read: Schema.optional(Rule),
@@ -60,6 +54,18 @@ const InputSchema = Schema.Union([Action, InputObject])
const normalizeInput = (input: Schema.Schema.Type<typeof InputSchema>): Schema.Schema.Type<typeof InputObject> =>
typeof input === "string" ? { "*": input } : input
const ACTION_ONLY = new Set(["todowrite", "question", "webfetch", "websearch", "codesearch", "doom_loop"])
const InfoZod = z
.union([zod(Action), z.record(z.string(), z.union([zod(Action), z.record(z.string(), zod(Action))]))])
.transform(normalizeInput)
.superRefine((input, ctx) => {
for (const [key, value] of globalThis.Object.entries(input)) {
if (!ACTION_ONLY.has(key) || typeof value === "string") continue
ctx.addIssue({ code: "custom", message: `${key} must be a permission action`, path: [key] })
}
})
export const Info = InputSchema.pipe(
Schema.decodeTo(InputObject, {
decode: SchemaGetter.transform(normalizeInput),
@@ -70,6 +76,7 @@ export const Info = InputSchema.pipe(
}),
)
.annotate({ identifier: "PermissionConfig" })
.annotate({ [ZodOverride]: InfoZod })
.pipe(
// Walker already emits the decodeTo transform into the derived zod (see
// `encoded()` in effect-zod.ts), so just expose that directly.
@@ -2,6 +2,7 @@ import { NotFoundError, eq, and } from "../storage"
import { SyncEvent } from "@/sync"
import * as Session from "./session"
import { MessageV2 } from "./message-v2"
import "../v2/session-event"
import { SessionTable, MessageTable, PartTable } from "./session.sql"
import { Log } from "../util"
+3 -3
View File
@@ -795,7 +795,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
"-l",
"-c",
`
__oc_cwd=$PWD
__oc_cwd=$OPENCODE_CWD
[[ -f ~/.zshenv ]] && source ~/.zshenv >/dev/null 2>&1 || true
[[ -f "\${ZDOTDIR:-$HOME}/.zshrc" ]] && source "\${ZDOTDIR:-$HOME}/.zshrc" >/dev/null 2>&1 || true
cd "$__oc_cwd"
@@ -808,7 +808,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
"-l",
"-c",
`
__oc_cwd=$PWD
__oc_cwd=$OPENCODE_CWD
shopt -s expand_aliases
[[ -f ~/.bashrc ]] && source ~/.bashrc >/dev/null 2>&1 || true
cd "$__oc_cwd"
@@ -833,7 +833,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
const cmd = ChildProcess.make(sh, args, {
cwd,
extendEnv: true,
env: { ...shellEnv.env, TERM: "dumb" },
env: { ...shellEnv.env, OPENCODE_CWD: cwd, TERM: "dumb" },
stdin: "ignore",
forceKillAfter: "3 seconds",
})
+1
View File
@@ -8,6 +8,7 @@ export const SessionID = Schema.String.annotate({ [ZodOverride]: Identifier.sche
Schema.brand("SessionID"),
withStatics((s) => ({
descending: (id?: string) => s.make(Identifier.descending("session", id)),
empty: () => s.make("ses_empty"),
zod: zod(s),
})),
)
+2
View File
@@ -360,6 +360,8 @@ function array(ast: SchemaAST.Arrays): z.ZodTypeAny {
}
function decl(ast: SchemaAST.Declaration): z.ZodTypeAny {
const typeConstructor = (ast.annotations as { typeConstructor?: { _tag?: string } }).typeConstructor
if (typeConstructor?._tag === "effect/DateTime.Utc") return z.string().datetime()
if (ast.typeParameters.length !== 1) return fail(ast)
return walk(ast.typeParameters[0])
}
+215 -375
View File
@@ -1,127 +1,132 @@
import { Identifier } from "@/id/id"
import { withStatics } from "@/util/schema"
import * as DateTime from "effect/DateTime"
import { Schema } from "effect"
import { SyncEvent } from "@/sync"
import { SessionID } from "@/session/schema"
import * as DateTime from "effect/DateTime"
export namespace SessionEvent {
export const ID = Schema.String.pipe(
Schema.brand("Session.Event.ID"),
withStatics((s) => ({
create: () => s.make(Identifier.create("evt", "ascending")),
})),
)
export type ID = Schema.Schema.Type<typeof ID>
type Stamp = Schema.Schema.Type<typeof Schema.DateTimeUtc>
type BaseInput = {
id?: ID
metadata?: Record<string, unknown>
timestamp?: Stamp
export const ID = Schema.String.pipe(
Schema.brand("Session.Event.ID"),
withStatics((s) => ({
create: () => s.make(Identifier.create("evt", "ascending")),
})),
)
export type ID = Schema.Schema.Type<typeof ID>
type Stamp = Schema.Schema.Type<typeof Schema.DateTimeUtc>
type BaseInput = {
id?: ID
sessionID: SessionID
metadata?: Record<string, unknown>
timestamp?: Stamp
}
function defineEvent<Self>(identifier: string) {
return <const Type extends string, Fields extends Schema.Struct.Fields>(input: {
type: Type
schema: Fields
version?: number
}) => {
const RawEvent = Schema.Class<Self>(identifier)({
id: ID,
sessionID: SessionID,
metadata: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
timestamp: Schema.DateTimeUtc,
type: Schema.Literal(input.type),
...input.schema,
})
const Event = RawEvent as Exclude<typeof RawEvent, string>
const Sync = SyncEvent.define({
type: input.type,
version: input.version ?? 1,
aggregate: "sessionID",
schema: Event,
})
return Object.assign(Event, {
Sync,
create(value: BaseInput & Record<string, unknown>) {
return new (Event as unknown as new (value: Record<string, unknown>) => Self)({
...value,
id: value.id ?? ID.create(),
sessionID: value.sessionID,
timestamp: value.timestamp ?? DateTime.makeUnsafe(Date.now()),
type: input.type,
})
},
})
}
}
const Base = {
id: ID,
metadata: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
timestamp: Schema.DateTimeUtc,
export class Source extends Schema.Class<Source>("Session.Event.Source")({
start: Schema.Number,
end: Schema.Number,
text: Schema.String,
}) {}
export class FileAttachment extends Schema.Class<FileAttachment>("Session.Event.FileAttachment")({
uri: Schema.String,
mime: Schema.String,
name: Schema.String.pipe(Schema.optional),
description: Schema.String.pipe(Schema.optional),
source: Source.pipe(Schema.optional),
}) {
static create(input: FileAttachment) {
return new FileAttachment({
uri: input.uri,
mime: input.mime,
name: input.name,
description: input.description,
source: input.source,
})
}
}
export class Source extends Schema.Class<Source>("Session.Event.Source")({
start: Schema.Number,
end: Schema.Number,
text: Schema.String,
}) {}
export class AgentAttachment extends Schema.Class<AgentAttachment>("Session.Event.AgentAttachment")({
name: Schema.String,
source: Source.pipe(Schema.optional),
}) {}
export class FileAttachment extends Schema.Class<FileAttachment>("Session.Event.FileAttachment")({
uri: Schema.String,
mime: Schema.String,
name: Schema.String.pipe(Schema.optional),
description: Schema.String.pipe(Schema.optional),
source: Source.pipe(Schema.optional),
}) {
static create(input: FileAttachment) {
return new FileAttachment({
uri: input.uri,
mime: input.mime,
name: input.name,
description: input.description,
source: input.source,
})
}
}
export class RetryError extends Schema.Class<RetryError>("Session.Event.Retry.Error")({
message: Schema.String,
statusCode: Schema.Number.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),
}) {}
export class AgentAttachment extends Schema.Class<AgentAttachment>("Session.Event.AgentAttachment")({
name: Schema.String,
source: Source.pipe(Schema.optional),
}) {}
export class RetryError extends Schema.Class<RetryError>("Session.Event.Retry.Error")({
message: Schema.String,
statusCode: Schema.Number.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),
}) {}
export class Prompt extends Schema.Class<Prompt>("Session.Event.Prompt")({
...Base,
type: Schema.Literal("prompt"),
export class Prompt extends defineEvent<Prompt>("Session.Event.Prompt")({
type: "prompt",
schema: {
text: Schema.String,
files: Schema.Array(FileAttachment).pipe(Schema.optional),
agents: Schema.Array(AgentAttachment).pipe(Schema.optional),
}) {
static create(input: BaseInput & { text: string; files?: FileAttachment[]; agents?: AgentAttachment[] }) {
return new Prompt({
id: input.id ?? ID.create(),
type: "prompt",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
text: input.text,
files: input.files,
agents: input.agents,
})
}
}
},
}) {}
export class Synthetic extends Schema.Class<Synthetic>("Session.Event.Synthetic")({
...Base,
type: Schema.Literal("synthetic"),
export class Synthetic extends defineEvent<Synthetic>("Session.Event.Synthetic")({
type: "synthetic",
schema: {
text: Schema.String,
}) {
static create(input: BaseInput & { text: string }) {
return new Synthetic({
id: input.id ?? ID.create(),
type: "synthetic",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
text: input.text,
})
}
}
},
}) {}
export namespace Step {
export class Started extends Schema.Class<Started>("Session.Event.Step.Started")({
...Base,
type: Schema.Literal("step.started"),
export namespace Step {
export class Started extends defineEvent<Started>("Session.Event.Step.Started")({
type: "step.started",
schema: {
model: Schema.Struct({
id: Schema.String,
providerID: Schema.String,
variant: Schema.String.pipe(Schema.optional),
}),
}) {
static create(input: BaseInput & { model: { id: string; providerID: string; variant?: string } }) {
return new Started({
id: input.id ?? ID.create(),
type: "step.started",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
model: input.model,
})
}
}
},
}) {}
export class Ended extends Schema.Class<Ended>("Session.Event.Step.Ended")({
...Base,
type: Schema.Literal("step.ended"),
export class Ended extends defineEvent<Ended>("Session.Event.Step.Ended")({
type: "step.ended",
schema: {
reason: Schema.String,
cost: Schema.Number,
tokens: Schema.Struct({
@@ -133,177 +138,82 @@ export namespace SessionEvent {
write: Schema.Number,
}),
}),
}) {
static create(input: BaseInput & { reason: string; cost: number; tokens: Ended["tokens"] }) {
return new Ended({
id: input.id ?? ID.create(),
type: "step.ended",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
reason: input.reason,
cost: input.cost,
tokens: input.tokens,
})
}
}
}
},
}) {}
}
export namespace Text {
export class Started extends Schema.Class<Started>("Session.Event.Text.Started")({
...Base,
type: Schema.Literal("text.started"),
}) {
static create(input: BaseInput = {}) {
return new Started({
id: input.id ?? ID.create(),
type: "text.started",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
})
}
}
export namespace Text {
export class Started extends defineEvent<Started>("Session.Event.Text.Started")({
type: "text.started",
schema: {},
}) {}
export class Delta extends Schema.Class<Delta>("Session.Event.Text.Delta")({
...Base,
type: Schema.Literal("text.delta"),
export class Delta extends defineEvent<Delta>("Session.Event.Text.Delta")({
type: "text.delta",
schema: {
delta: Schema.String,
}) {
static create(input: BaseInput & { delta: string }) {
return new Delta({
id: input.id ?? ID.create(),
type: "text.delta",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
delta: input.delta,
})
}
}
},
}) {}
export class Ended extends Schema.Class<Ended>("Session.Event.Text.Ended")({
...Base,
type: Schema.Literal("text.ended"),
export class Ended extends defineEvent<Ended>("Session.Event.Text.Ended")({
type: "text.ended",
schema: {
text: Schema.String,
}) {
static create(input: BaseInput & { text: string }) {
return new Ended({
id: input.id ?? ID.create(),
type: "text.ended",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
text: input.text,
})
}
}
}
},
}) {}
}
export namespace Reasoning {
export class Started extends Schema.Class<Started>("Session.Event.Reasoning.Started")({
...Base,
type: Schema.Literal("reasoning.started"),
}) {
static create(input: BaseInput = {}) {
return new Started({
id: input.id ?? ID.create(),
type: "reasoning.started",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
})
}
}
export namespace Reasoning {
export class Started extends defineEvent<Started>("Session.Event.Reasoning.Started")({
type: "reasoning.started",
schema: {},
}) {}
export class Delta extends Schema.Class<Delta>("Session.Event.Reasoning.Delta")({
...Base,
type: Schema.Literal("reasoning.delta"),
export class Delta extends defineEvent<Delta>("Session.Event.Reasoning.Delta")({
type: "reasoning.delta",
schema: {
delta: Schema.String,
}) {
static create(input: BaseInput & { delta: string }) {
return new Delta({
id: input.id ?? ID.create(),
type: "reasoning.delta",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
delta: input.delta,
})
}
}
},
}) {}
export class Ended extends Schema.Class<Ended>("Session.Event.Reasoning.Ended")({
...Base,
type: Schema.Literal("reasoning.ended"),
export class Ended extends defineEvent<Ended>("Session.Event.Reasoning.Ended")({
type: "reasoning.ended",
schema: {
text: Schema.String,
}) {
static create(input: BaseInput & { text: string }) {
return new Ended({
id: input.id ?? ID.create(),
type: "reasoning.ended",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
text: input.text,
})
}
}
}
},
}) {}
}
export namespace Tool {
export namespace Input {
export class Started extends Schema.Class<Started>("Session.Event.Tool.Input.Started")({
...Base,
export namespace Tool {
export namespace Input {
export class Started extends defineEvent<Started>("Session.Event.Tool.Input.Started")({
type: "tool.input.started",
schema: {
callID: Schema.String,
name: Schema.String,
type: Schema.Literal("tool.input.started"),
}) {
static create(input: BaseInput & { callID: string; name: string }) {
return new Started({
id: input.id ?? ID.create(),
type: "tool.input.started",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
callID: input.callID,
name: input.name,
})
}
}
},
}) {}
export class Delta extends Schema.Class<Delta>("Session.Event.Tool.Input.Delta")({
...Base,
export class Delta extends defineEvent<Delta>("Session.Event.Tool.Input.Delta")({
type: "tool.input.delta",
schema: {
callID: Schema.String,
type: Schema.Literal("tool.input.delta"),
delta: Schema.String,
}) {
static create(input: BaseInput & { callID: string; delta: string }) {
return new Delta({
id: input.id ?? ID.create(),
type: "tool.input.delta",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
callID: input.callID,
delta: input.delta,
})
}
}
},
}) {}
export class Ended extends Schema.Class<Ended>("Session.Event.Tool.Input.Ended")({
...Base,
export class Ended extends defineEvent<Ended>("Session.Event.Tool.Input.Ended")({
type: "tool.input.ended",
schema: {
callID: Schema.String,
type: Schema.Literal("tool.input.ended"),
text: Schema.String,
}) {
static create(input: BaseInput & { callID: string; text: string }) {
return new Ended({
id: input.id ?? ID.create(),
type: "tool.input.ended",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
callID: input.callID,
text: input.text,
})
}
}
}
},
}) {}
}
export class Called extends Schema.Class<Called>("Session.Event.Tool.Called")({
...Base,
type: Schema.Literal("tool.called"),
export class Called extends defineEvent<Called>("Session.Event.Tool.Called")({
type: "tool.called",
schema: {
callID: Schema.String,
tool: Schema.String,
input: Schema.Record(Schema.String, Schema.Unknown),
@@ -311,31 +221,12 @@ export namespace SessionEvent {
executed: Schema.Boolean,
metadata: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
}),
}) {
static create(
input: BaseInput & {
callID: string
tool: string
input: Record<string, unknown>
provider: Called["provider"]
},
) {
return new Called({
id: input.id ?? ID.create(),
type: "tool.called",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
callID: input.callID,
tool: input.tool,
input: input.input,
provider: input.provider,
})
}
}
},
}) {}
export class Success extends Schema.Class<Success>("Session.Event.Tool.Success")({
...Base,
type: Schema.Literal("tool.success"),
export class Success extends defineEvent<Success>("Session.Event.Tool.Success")({
type: "tool.success",
schema: {
callID: Schema.String,
title: Schema.String,
output: Schema.String.pipe(Schema.optional),
@@ -344,115 +235,64 @@ export namespace SessionEvent {
executed: Schema.Boolean,
metadata: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
}),
}) {
static create(
input: BaseInput & {
callID: string
title: string
output?: string
attachments?: FileAttachment[]
provider: Success["provider"]
},
) {
return new Success({
id: input.id ?? ID.create(),
type: "tool.success",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
callID: input.callID,
title: input.title,
output: input.output,
attachments: input.attachments,
provider: input.provider,
})
}
}
},
}) {}
export class Error extends Schema.Class<Error>("Session.Event.Tool.Error")({
...Base,
type: Schema.Literal("tool.error"),
export class Error extends defineEvent<Error>("Session.Event.Tool.Error")({
type: "tool.error",
schema: {
callID: Schema.String,
error: Schema.String,
provider: Schema.Struct({
executed: Schema.Boolean,
metadata: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
}),
}) {
static create(input: BaseInput & { callID: string; error: string; provider: Error["provider"] }) {
return new Error({
id: input.id ?? ID.create(),
type: "tool.error",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
callID: input.callID,
error: input.error,
provider: input.provider,
})
}
}
}
},
}) {}
}
export class Retried extends Schema.Class<Retried>("Session.Event.Retried")({
...Base,
type: Schema.Literal("retried"),
export class Retried extends defineEvent<Retried>("Session.Event.Retried")({
type: "retried",
schema: {
attempt: Schema.Number,
error: RetryError,
}) {
static create(input: BaseInput & { attempt: number; error: RetryError }) {
return new Retried({
id: input.id ?? ID.create(),
type: "retried",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
attempt: input.attempt,
error: input.error,
})
}
}
},
}) {}
export class Compacted extends Schema.Class<Compacted>("Session.Event.Compated")({
...Base,
type: Schema.Literal("compacted"),
export class Compacted extends defineEvent<Compacted>("Session.Event.Compacted")({
type: "compacted",
schema: {
auto: Schema.Boolean,
overflow: Schema.Boolean.pipe(Schema.optional),
}) {
static create(input: BaseInput & { auto: boolean; overflow?: boolean }) {
return new Compacted({
id: input.id ?? ID.create(),
type: "compacted",
timestamp: input.timestamp ?? DateTime.makeUnsafe(Date.now()),
metadata: input.metadata,
auto: input.auto,
overflow: input.overflow,
})
}
}
},
}) {}
export const Event = Schema.Union(
[
Prompt,
Synthetic,
Step.Started,
Step.Ended,
Text.Started,
Text.Delta,
Text.Ended,
Tool.Input.Started,
Tool.Input.Delta,
Tool.Input.Ended,
Tool.Called,
Tool.Success,
Tool.Error,
Reasoning.Started,
Reasoning.Delta,
Reasoning.Ended,
Retried,
Compacted,
],
{
mode: "oneOf",
},
).pipe(Schema.toTaggedUnion("type"))
export type Event = Schema.Schema.Type<typeof Event>
export type Type = Event["type"]
}
export const Event = Schema.Union(
[
Prompt,
Synthetic,
Step.Started,
Step.Ended,
Text.Started,
Text.Delta,
Text.Ended,
Tool.Input.Started,
Tool.Input.Delta,
Tool.Input.Ended,
Tool.Called,
Tool.Success,
Tool.Error,
Reasoning.Started,
Reasoning.Delta,
Reasoning.Ended,
Retried,
Compacted,
],
{
mode: "oneOf",
},
).pipe(Schema.toTaggedUnion("type"))
export type Event = Schema.Schema.Type<typeof Event>
export type Type = Event["type"]
export * as SessionEvent from "./session-event"
@@ -4,8 +4,10 @@ import * as FastCheck from "effect/testing/FastCheck"
import { SessionEntry } from "../../src/v2/session-entry"
import { SessionEntryStepper } from "../../src/v2/session-entry-stepper"
import { SessionEvent } from "../../src/v2/session-event"
import { SessionID } from "../../src/session/schema"
const time = (n: number) => DateTime.makeUnsafe(n)
const sessionID = SessionID.empty()
const word = FastCheck.string({ minLength: 1, maxLength: 8 })
const text = FastCheck.string({ maxLength: 16 })
@@ -147,24 +149,34 @@ describe("session-entry-stepper", () => {
const store = adapterStore()
store.committed.push(assistant())
SessionEntryStepper.stepWith(adapterFor(store), SessionEvent.Prompt.create({ text: "hello", timestamp: time(1) }))
SessionEntryStepper.stepWith(adapterFor(store), SessionEvent.Reasoning.Started.create({ timestamp: time(2) }))
SessionEntryStepper.stepWith(
adapterFor(store),
SessionEvent.Reasoning.Delta.create({ delta: "thinking", timestamp: time(3) }),
SessionEvent.Prompt.create({ sessionID, text: "hello", timestamp: time(1) }),
)
SessionEntryStepper.stepWith(
adapterFor(store),
SessionEvent.Reasoning.Ended.create({ text: "thought", timestamp: time(4) }),
SessionEvent.Reasoning.Started.create({ sessionID, timestamp: time(2) }),
)
SessionEntryStepper.stepWith(adapterFor(store), SessionEvent.Text.Started.create({ timestamp: time(5) }))
SessionEntryStepper.stepWith(
adapterFor(store),
SessionEvent.Text.Delta.create({ delta: "world", timestamp: time(6) }),
SessionEvent.Reasoning.Delta.create({ sessionID, delta: "thinking", timestamp: time(3) }),
)
SessionEntryStepper.stepWith(
adapterFor(store),
SessionEvent.Reasoning.Ended.create({ sessionID, text: "thought", timestamp: time(4) }),
)
SessionEntryStepper.stepWith(
adapterFor(store),
SessionEvent.Text.Started.create({ sessionID, timestamp: time(5) }),
)
SessionEntryStepper.stepWith(
adapterFor(store),
SessionEvent.Text.Delta.create({ sessionID, delta: "world", timestamp: time(6) }),
)
SessionEntryStepper.stepWith(
adapterFor(store),
SessionEvent.Step.Ended.create({
sessionID,
reason: "stop",
cost: 1,
tokens: {
@@ -199,15 +211,12 @@ describe("session-entry-stepper", () => {
SessionEntryStepper.stepWith(
adapterFor(store),
SessionEvent.Retried.create({
attempt: 1,
error: retryError("rate limited"),
timestamp: time(1),
}),
SessionEvent.Retried.create({ sessionID, attempt: 1, error: retryError("rate limited"), timestamp: time(1) }),
)
SessionEntryStepper.stepWith(
adapterFor(store),
SessionEvent.Retried.create({
sessionID,
attempt: 2,
error: retryError("provider overloaded"),
timestamp: time(2),
@@ -253,9 +262,11 @@ describe("session-entry-stepper", () => {
const state = memoryState()
const adapter = SessionEntryStepper.memory(state)
const committed = SessionEntry.User.fromEvent(
SessionEvent.Prompt.create({ text: "committed", timestamp: time(1) }),
SessionEvent.Prompt.create({ sessionID, text: "committed", timestamp: time(1) }),
)
const pending = SessionEntry.User.fromEvent(
SessionEvent.Prompt.create({ sessionID, text: "pending", timestamp: time(2) }),
)
const pending = SessionEntry.User.fromEvent(SessionEvent.Prompt.create({ text: "pending", timestamp: time(2) }))
adapter.appendEntry(committed)
adapter.appendPending(pending)
@@ -269,15 +280,15 @@ describe("session-entry-stepper", () => {
SessionEntryStepper.stepWith(
SessionEntryStepper.memory(state),
SessionEvent.Reasoning.Started.create({ timestamp: time(1) }),
SessionEvent.Reasoning.Started.create({ sessionID, timestamp: time(1) }),
)
SessionEntryStepper.stepWith(
SessionEntryStepper.memory(state),
SessionEvent.Reasoning.Delta.create({ delta: "draft", timestamp: time(2) }),
SessionEvent.Reasoning.Delta.create({ sessionID, delta: "draft", timestamp: time(2) }),
)
SessionEntryStepper.stepWith(
SessionEntryStepper.memory(state),
SessionEvent.Reasoning.Ended.create({ text: "final", timestamp: time(3) }),
SessionEvent.Reasoning.Ended.create({ sessionID, text: "final", timestamp: time(3) }),
)
expect(reasons(state)).toEqual([{ type: "reasoning", text: "final" }])
@@ -288,11 +299,7 @@ describe("session-entry-stepper", () => {
SessionEntryStepper.stepWith(
SessionEntryStepper.memory(state),
SessionEvent.Retried.create({
attempt: 1,
error: retryError("rate limited"),
timestamp: time(1),
}),
SessionEvent.Retried.create({ sessionID, attempt: 1, error: retryError("rate limited"), timestamp: time(1) }),
)
expect(retriesOf(state)).toEqual([retry(1, "rate limited", 1)])
@@ -306,7 +313,7 @@ describe("session-entry-stepper", () => {
FastCheck.property(word, (body) => {
const next = SessionEntryStepper.step(
memoryState(),
SessionEvent.Prompt.create({ text: body, timestamp: time(1) }),
SessionEvent.Prompt.create({ sessionID, text: body, timestamp: time(1) }),
)
expect(next.entries).toHaveLength(1)
expect(next.entries[0]?.type).toBe("user")
@@ -322,7 +329,7 @@ describe("session-entry-stepper", () => {
FastCheck.property(word, (body) => {
const next = SessionEntryStepper.step(
active(),
SessionEvent.Prompt.create({ text: body, timestamp: time(1) }),
SessionEvent.Prompt.create({ sessionID, text: body, timestamp: time(1) }),
)
expect(next.pending).toHaveLength(1)
expect(next.pending[0]?.type).toBe("user")
@@ -340,9 +347,9 @@ describe("session-entry-stepper", () => {
(state, part, i) =>
SessionEntryStepper.step(
state,
SessionEvent.Text.Delta.create({ delta: part, timestamp: time(i + 2) }),
SessionEvent.Text.Delta.create({ sessionID, delta: part, timestamp: time(i + 2) }),
),
SessionEntryStepper.step(active(), SessionEvent.Text.Started.create({ timestamp: time(1) })),
SessionEntryStepper.step(active(), SessionEvent.Text.Started.create({ sessionID, timestamp: time(1) })),
)
expect(texts_of(next)).toEqual([
@@ -361,10 +368,12 @@ describe("session-entry-stepper", () => {
FastCheck.property(texts, texts, (a, b) => {
const next = run(
[
SessionEvent.Text.Started.create({ timestamp: time(1) }),
...a.map((x, i) => SessionEvent.Text.Delta.create({ delta: x, timestamp: time(i + 2) })),
SessionEvent.Text.Started.create({ timestamp: time(a.length + 2) }),
...b.map((x, i) => SessionEvent.Text.Delta.create({ delta: x, timestamp: time(i + a.length + 3) })),
SessionEvent.Text.Started.create({ sessionID, timestamp: time(1) }),
...a.map((x, i) => SessionEvent.Text.Delta.create({ sessionID, delta: x, timestamp: time(i + 2) })),
SessionEvent.Text.Started.create({ sessionID, timestamp: time(a.length + 2) }),
...b.map((x, i) =>
SessionEvent.Text.Delta.create({ sessionID, delta: x, timestamp: time(i + a.length + 3) }),
),
],
active(),
)
@@ -383,9 +392,11 @@ describe("session-entry-stepper", () => {
FastCheck.property(texts, text, (parts, end) => {
const next = run(
[
SessionEvent.Reasoning.Started.create({ timestamp: time(1) }),
...parts.map((x, i) => SessionEvent.Reasoning.Delta.create({ delta: x, timestamp: time(i + 2) })),
SessionEvent.Reasoning.Ended.create({ text: end, timestamp: time(parts.length + 2) }),
SessionEvent.Reasoning.Started.create({ sessionID, timestamp: time(1) }),
...parts.map((x, i) =>
SessionEvent.Reasoning.Delta.create({ sessionID, delta: x, timestamp: time(i + 2) }),
),
SessionEvent.Reasoning.Ended.create({ sessionID, text: end, timestamp: time(parts.length + 2) }),
],
active(),
)
@@ -414,11 +425,12 @@ describe("session-entry-stepper", () => {
(callID, title, input, output, metadata, attachments, parts) => {
const next = run(
[
SessionEvent.Tool.Input.Started.create({ callID, name: "bash", timestamp: time(1) }),
SessionEvent.Tool.Input.Started.create({ sessionID, callID, name: "bash", timestamp: time(1) }),
...parts.map((x, i) =>
SessionEvent.Tool.Input.Delta.create({ callID, delta: x, timestamp: time(i + 2) }),
SessionEvent.Tool.Input.Delta.create({ sessionID, callID, delta: x, timestamp: time(i + 2) }),
),
SessionEvent.Tool.Called.create({
sessionID,
callID,
tool: "bash",
input,
@@ -426,6 +438,7 @@ describe("session-entry-stepper", () => {
timestamp: time(parts.length + 2),
}),
SessionEvent.Tool.Success.create({
sessionID,
callID,
title,
output,
@@ -459,8 +472,9 @@ describe("session-entry-stepper", () => {
FastCheck.property(word, dict, word, maybe(dict), (callID, input, error, metadata) => {
const next = run(
[
SessionEvent.Tool.Input.Started.create({ callID, name: "bash", timestamp: time(1) }),
SessionEvent.Tool.Input.Started.create({ sessionID, callID, name: "bash", timestamp: time(1) }),
SessionEvent.Tool.Called.create({
sessionID,
callID,
tool: "bash",
input,
@@ -468,6 +482,7 @@ describe("session-entry-stepper", () => {
timestamp: time(2),
}),
SessionEvent.Tool.Error.create({
sessionID,
callID,
error,
metadata,
@@ -496,8 +511,9 @@ describe("session-entry-stepper", () => {
FastCheck.property(word, word, (callID, title) => {
const next = run(
[
SessionEvent.Tool.Input.Started.create({ callID, name: "bash", timestamp: time(1) }),
SessionEvent.Tool.Input.Started.create({ sessionID, callID, name: "bash", timestamp: time(1) }),
SessionEvent.Tool.Success.create({
sessionID,
callID,
title,
provider: { executed: true },
@@ -520,6 +536,7 @@ describe("session-entry-stepper", () => {
FastCheck.assert(
FastCheck.property(FastCheck.integer({ min: 1, max: 1000 }), (n) => {
const event = SessionEvent.Step.Ended.create({
sessionID,
reason: "stop",
cost: 1,
tokens: {
@@ -552,7 +569,10 @@ describe("session-entry-stepper", () => {
FastCheck.assert(
FastCheck.property(word, (body) => {
const old = memoryState()
const next = SessionEntryStepper.step(old, SessionEvent.Prompt.create({ text: body, timestamp: time(1) }))
const next = SessionEntryStepper.step(
old,
SessionEvent.Prompt.create({ sessionID, text: body, timestamp: time(1) }),
)
expect(old).not.toBe(next)
expect(old.entries).toHaveLength(0)
expect(next.entries).toHaveLength(1)
@@ -565,7 +585,10 @@ describe("session-entry-stepper", () => {
FastCheck.assert(
FastCheck.property(word, (body) => {
const old = active()
const next = SessionEntryStepper.step(old, SessionEvent.Prompt.create({ text: body, timestamp: time(1) }))
const next = SessionEntryStepper.step(
old,
SessionEvent.Prompt.create({ sessionID, text: body, timestamp: time(1) }),
)
expect(old).not.toBe(next)
expect(old.pending).toHaveLength(0)
expect(next.pending).toHaveLength(1)
@@ -579,15 +602,17 @@ describe("session-entry-stepper", () => {
FastCheck.property(texts, (parts) => {
const next = run([
SessionEvent.Step.Started.create({
sessionID,
model: {
id: "model",
providerID: "provider",
},
timestamp: time(1),
}),
SessionEvent.Text.Started.create({ timestamp: time(2) }),
...parts.map((x, i) => SessionEvent.Text.Delta.create({ delta: x, timestamp: time(i + 3) })),
SessionEvent.Text.Started.create({ sessionID, timestamp: time(2) }),
...parts.map((x, i) => SessionEvent.Text.Delta.create({ sessionID, delta: x, timestamp: time(i + 3) })),
SessionEvent.Step.Ended.create({
sessionID,
reason: "stop",
cost: 1,
tokens: {
@@ -623,17 +648,19 @@ describe("session-entry-stepper", () => {
FastCheck.assert(
FastCheck.property(word, texts, (body, parts) => {
const next = run([
SessionEvent.Prompt.create({ text: body, timestamp: time(0) }),
SessionEvent.Prompt.create({ sessionID, text: body, timestamp: time(0) }),
SessionEvent.Step.Started.create({
sessionID,
model: {
id: "model",
providerID: "provider",
},
timestamp: time(1),
}),
SessionEvent.Text.Started.create({ timestamp: time(2) }),
...parts.map((x, i) => SessionEvent.Text.Delta.create({ delta: x, timestamp: time(i + 3) })),
SessionEvent.Text.Started.create({ sessionID, timestamp: time(2) }),
...parts.map((x, i) => SessionEvent.Text.Delta.create({ sessionID, delta: x, timestamp: time(i + 3) })),
SessionEvent.Step.Ended.create({
sessionID,
reason: "stop",
cost: 1,
tokens: {
@@ -680,19 +707,28 @@ describe("session-entry-stepper", () => {
(body, reason, end, input, title, output, metadata, attachments) => {
const callID = "call"
const next = run([
SessionEvent.Prompt.create({ text: body, timestamp: time(0) }),
SessionEvent.Prompt.create({ sessionID, text: body, timestamp: time(0) }),
SessionEvent.Step.Started.create({
sessionID,
model: {
id: "model",
providerID: "provider",
},
timestamp: time(1),
}),
SessionEvent.Reasoning.Started.create({ timestamp: time(2) }),
...reason.map((x, i) => SessionEvent.Reasoning.Delta.create({ delta: x, timestamp: time(i + 3) })),
SessionEvent.Reasoning.Ended.create({ text: end, timestamp: time(reason.length + 3) }),
SessionEvent.Tool.Input.Started.create({ callID, name: "bash", timestamp: time(reason.length + 4) }),
SessionEvent.Reasoning.Started.create({ sessionID, timestamp: time(2) }),
...reason.map((x, i) =>
SessionEvent.Reasoning.Delta.create({ sessionID, delta: x, timestamp: time(i + 3) }),
),
SessionEvent.Reasoning.Ended.create({ sessionID, text: end, timestamp: time(reason.length + 3) }),
SessionEvent.Tool.Input.Started.create({
sessionID,
callID,
name: "bash",
timestamp: time(reason.length + 4),
}),
SessionEvent.Tool.Called.create({
sessionID,
callID,
tool: "bash",
input,
@@ -700,6 +736,7 @@ describe("session-entry-stepper", () => {
timestamp: time(reason.length + 5),
}),
SessionEvent.Tool.Success.create({
sessionID,
callID,
title,
output,
@@ -709,6 +746,7 @@ describe("session-entry-stepper", () => {
timestamp: time(reason.length + 6),
}),
SessionEvent.Step.Ended.create({
sessionID,
reason: "stop",
cost: 1,
tokens: {
@@ -747,6 +785,7 @@ describe("session-entry-stepper", () => {
const next = run(
[
SessionEvent.Step.Started.create({
sessionID,
model: {
id: "model",
providerID: "provider",
@@ -771,8 +810,9 @@ describe("session-entry-stepper", () => {
FastCheck.property(dict, dict, word, word, (a, b, title, error) => {
const next = run(
[
SessionEvent.Tool.Input.Started.create({ callID: "a", name: "bash", timestamp: time(1) }),
SessionEvent.Tool.Input.Started.create({ sessionID, callID: "a", name: "bash", timestamp: time(1) }),
SessionEvent.Tool.Called.create({
sessionID,
callID: "a",
tool: "bash",
input: a,
@@ -780,14 +820,16 @@ describe("session-entry-stepper", () => {
timestamp: time(2),
}),
SessionEvent.Tool.Success.create({
sessionID,
callID: "a",
title,
output: "done",
provider: { executed: true },
timestamp: time(3),
}),
SessionEvent.Tool.Input.Started.create({ callID: "b", name: "grep", timestamp: time(4) }),
SessionEvent.Tool.Input.Started.create({ sessionID, callID: "b", name: "grep", timestamp: time(4) }),
SessionEvent.Tool.Called.create({
sessionID,
callID: "b",
tool: "bash",
input: b,
@@ -795,6 +837,7 @@ describe("session-entry-stepper", () => {
timestamp: time(5),
}),
SessionEvent.Tool.Error.create({
sessionID,
callID: "b",
error,
provider: { executed: true },
@@ -827,11 +870,12 @@ describe("session-entry-stepper", () => {
FastCheck.property(dict, dict, word, word, text, text, (a, b, titleA, titleB, deltaA, deltaB) => {
const next = run(
[
SessionEvent.Tool.Input.Started.create({ callID: "a", name: "bash", timestamp: time(1) }),
SessionEvent.Tool.Input.Started.create({ callID: "b", name: "grep", timestamp: time(2) }),
SessionEvent.Tool.Input.Delta.create({ callID: "a", delta: deltaA, timestamp: time(3) }),
SessionEvent.Tool.Input.Delta.create({ callID: "b", delta: deltaB, timestamp: time(4) }),
SessionEvent.Tool.Input.Started.create({ sessionID, callID: "a", name: "bash", timestamp: time(1) }),
SessionEvent.Tool.Input.Started.create({ sessionID, callID: "b", name: "grep", timestamp: time(2) }),
SessionEvent.Tool.Input.Delta.create({ sessionID, callID: "a", delta: deltaA, timestamp: time(3) }),
SessionEvent.Tool.Input.Delta.create({ sessionID, callID: "b", delta: deltaB, timestamp: time(4) }),
SessionEvent.Tool.Called.create({
sessionID,
callID: "a",
tool: "bash",
input: a,
@@ -839,6 +883,7 @@ describe("session-entry-stepper", () => {
timestamp: time(5),
}),
SessionEvent.Tool.Called.create({
sessionID,
callID: "b",
tool: "grep",
input: b,
@@ -846,6 +891,7 @@ describe("session-entry-stepper", () => {
timestamp: time(6),
}),
SessionEvent.Tool.Success.create({
sessionID,
callID: "a",
title: titleA,
output: "done-a",
@@ -853,6 +899,7 @@ describe("session-entry-stepper", () => {
timestamp: time(7),
}),
SessionEvent.Tool.Success.create({
sessionID,
callID: "b",
title: titleB,
output: "done-b",
@@ -884,7 +931,7 @@ describe("session-entry-stepper", () => {
FastCheck.property(word, (body) => {
const next = SessionEntryStepper.step(
memoryState(),
SessionEvent.Synthetic.create({ text: body, timestamp: time(1) }),
SessionEvent.Synthetic.create({ sessionID, text: body, timestamp: time(1) }),
)
expect(next.entries).toHaveLength(1)
expect(next.entries[0]?.type).toBe("synthetic")
@@ -900,7 +947,7 @@ describe("session-entry-stepper", () => {
FastCheck.property(FastCheck.boolean(), maybe(FastCheck.boolean()), (auto, overflow) => {
const next = SessionEntryStepper.step(
memoryState(),
SessionEvent.Compacted.create({ auto, overflow, timestamp: time(1) }),
SessionEvent.Compacted.create({ sessionID, auto, overflow, timestamp: time(1) }),
)
expect(next.entries).toHaveLength(1)
expect(next.entries[0]?.type).toBe("compaction")
+586 -23
View File
@@ -987,6 +987,371 @@ export type EventSessionDeleted = {
}
}
export type SessionEventSource = {
start: number
end: number
text: string
}
export type SessionEventFileAttachment = {
uri: string
mime: string
name?: string
description?: string
source?: SessionEventSource
}
export type SessionEventAgentAttachment = {
name: string
source?: SessionEventSource
}
export type SessionEventPrompt = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "prompt"
text: string
files?: Array<SessionEventFileAttachment>
agents?: Array<SessionEventAgentAttachment>
}
export type EventPrompt = {
type: "prompt"
properties: SessionEventPrompt
}
export type SessionEventSynthetic = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "synthetic"
text: string
}
export type EventSynthetic = {
type: "synthetic"
properties: SessionEventSynthetic
}
export type SessionEventStepStarted = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "step.started"
model: {
id: string
providerID: string
variant?: string
}
}
export type EventStepStarted = {
type: "step.started"
properties: SessionEventStepStarted
}
export type SessionEventStepEnded = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "step.ended"
reason: string
cost: number
tokens: {
input: number
output: number
reasoning: number
cache: {
read: number
write: number
}
}
}
export type EventStepEnded = {
type: "step.ended"
properties: SessionEventStepEnded
}
export type SessionEventTextStarted = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "text.started"
}
export type EventTextStarted = {
type: "text.started"
properties: SessionEventTextStarted
}
export type SessionEventTextDelta = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "text.delta"
delta: string
}
export type EventTextDelta = {
type: "text.delta"
properties: SessionEventTextDelta
}
export type SessionEventTextEnded = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "text.ended"
text: string
}
export type EventTextEnded = {
type: "text.ended"
properties: SessionEventTextEnded
}
export type SessionEventReasoningStarted = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "reasoning.started"
}
export type EventReasoningStarted = {
type: "reasoning.started"
properties: SessionEventReasoningStarted
}
export type SessionEventReasoningDelta = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "reasoning.delta"
delta: string
}
export type EventReasoningDelta = {
type: "reasoning.delta"
properties: SessionEventReasoningDelta
}
export type SessionEventReasoningEnded = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "reasoning.ended"
text: string
}
export type EventReasoningEnded = {
type: "reasoning.ended"
properties: SessionEventReasoningEnded
}
export type SessionEventToolInputStarted = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "tool.input.started"
callID: string
name: string
}
export type EventToolInputStarted = {
type: "tool.input.started"
properties: SessionEventToolInputStarted
}
export type SessionEventToolInputDelta = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "tool.input.delta"
callID: string
delta: string
}
export type EventToolInputDelta = {
type: "tool.input.delta"
properties: SessionEventToolInputDelta
}
export type SessionEventToolInputEnded = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "tool.input.ended"
callID: string
text: string
}
export type EventToolInputEnded = {
type: "tool.input.ended"
properties: SessionEventToolInputEnded
}
export type SessionEventToolCalled = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "tool.called"
callID: string
tool: string
input: {
[key: string]: unknown
}
provider: {
executed: boolean
metadata?: {
[key: string]: unknown
}
}
}
export type EventToolCalled = {
type: "tool.called"
properties: SessionEventToolCalled
}
export type SessionEventToolSuccess = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "tool.success"
callID: string
title: string
output?: string
attachments?: Array<SessionEventFileAttachment>
provider: {
executed: boolean
metadata?: {
[key: string]: unknown
}
}
}
export type EventToolSuccess = {
type: "tool.success"
properties: SessionEventToolSuccess
}
export type SessionEventToolError = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "tool.error"
callID: string
error: string
provider: {
executed: boolean
metadata?: {
[key: string]: unknown
}
}
}
export type EventToolError = {
type: "tool.error"
properties: SessionEventToolError
}
export type SessionEventRetryError = {
message: string
statusCode?: number
isRetryable: boolean
responseHeaders?: {
[key: string]: string
}
responseBody?: string
metadata?: {
[key: string]: string
}
}
export type SessionEventRetried = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "retried"
attempt: number
error: SessionEventRetryError
}
export type EventRetried = {
type: "retried"
properties: SessionEventRetried
}
export type SessionEventCompacted = {
id: string
sessionID: string
metadata?: {
[key: string]: unknown
}
timestamp: string
type: "compacted"
auto: boolean
overflow?: boolean
}
export type EventCompacted = {
type: "compacted"
properties: SessionEventCompacted
}
export type SyncEventMessageUpdated = {
type: "sync"
name: "message.updated.1"
@@ -1104,6 +1469,168 @@ export type SyncEventSessionDeleted = {
}
}
export type SyncEventPrompt = {
type: "sync"
name: "prompt.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventPrompt
}
export type SyncEventSynthetic = {
type: "sync"
name: "synthetic.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventSynthetic
}
export type SyncEventStepStarted = {
type: "sync"
name: "step.started.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventStepStarted
}
export type SyncEventStepEnded = {
type: "sync"
name: "step.ended.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventStepEnded
}
export type SyncEventTextStarted = {
type: "sync"
name: "text.started.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventTextStarted
}
export type SyncEventTextDelta = {
type: "sync"
name: "text.delta.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventTextDelta
}
export type SyncEventTextEnded = {
type: "sync"
name: "text.ended.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventTextEnded
}
export type SyncEventReasoningStarted = {
type: "sync"
name: "reasoning.started.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventReasoningStarted
}
export type SyncEventReasoningDelta = {
type: "sync"
name: "reasoning.delta.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventReasoningDelta
}
export type SyncEventReasoningEnded = {
type: "sync"
name: "reasoning.ended.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventReasoningEnded
}
export type SyncEventToolInputStarted = {
type: "sync"
name: "tool.input.started.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventToolInputStarted
}
export type SyncEventToolInputDelta = {
type: "sync"
name: "tool.input.delta.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventToolInputDelta
}
export type SyncEventToolInputEnded = {
type: "sync"
name: "tool.input.ended.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventToolInputEnded
}
export type SyncEventToolCalled = {
type: "sync"
name: "tool.called.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventToolCalled
}
export type SyncEventToolSuccess = {
type: "sync"
name: "tool.success.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventToolSuccess
}
export type SyncEventToolError = {
type: "sync"
name: "tool.error.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventToolError
}
export type SyncEventRetried = {
type: "sync"
name: "retried.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventRetried
}
export type SyncEventCompacted = {
type: "sync"
name: "compacted.1"
id: string
seq: number
aggregateID: "sessionID"
data: SessionEventCompacted
}
export type GlobalEvent = {
directory: string
project?: string
@@ -1156,6 +1683,24 @@ export type GlobalEvent = {
| EventSessionCreated
| EventSessionUpdated
| EventSessionDeleted
| EventPrompt
| EventSynthetic
| EventStepStarted
| EventStepEnded
| EventTextStarted
| EventTextDelta
| EventTextEnded
| EventReasoningStarted
| EventReasoningDelta
| EventReasoningEnded
| EventToolInputStarted
| EventToolInputDelta
| EventToolInputEnded
| EventToolCalled
| EventToolSuccess
| EventToolError
| EventRetried
| EventCompacted
| SyncEventMessageUpdated
| SyncEventMessageRemoved
| SyncEventMessagePartUpdated
@@ -1163,6 +1708,24 @@ export type GlobalEvent = {
| SyncEventSessionCreated
| SyncEventSessionUpdated
| SyncEventSessionDeleted
| SyncEventPrompt
| SyncEventSynthetic
| SyncEventStepStarted
| SyncEventStepEnded
| SyncEventTextStarted
| SyncEventTextDelta
| SyncEventTextEnded
| SyncEventReasoningStarted
| SyncEventReasoningDelta
| SyncEventReasoningEnded
| SyncEventToolInputStarted
| SyncEventToolInputDelta
| SyncEventToolInputEnded
| SyncEventToolCalled
| SyncEventToolSuccess
| SyncEventToolError
| SyncEventRetried
| SyncEventCompacted
}
/**
@@ -1198,32 +1761,14 @@ export type ServerConfig = {
export type PermissionActionConfig = "ask" | "allow" | "deny"
export type PermissionObjectConfig = {
[key: string]: PermissionActionConfig
}
export type PermissionRuleConfig = PermissionActionConfig | PermissionObjectConfig
export type PermissionConfig =
| PermissionActionConfig
| {
read?: PermissionRuleConfig
edit?: PermissionRuleConfig
glob?: PermissionRuleConfig
grep?: PermissionRuleConfig
list?: PermissionRuleConfig
bash?: PermissionRuleConfig
task?: PermissionRuleConfig
external_directory?: PermissionRuleConfig
todowrite?: PermissionActionConfig
question?: PermissionActionConfig
webfetch?: PermissionActionConfig
websearch?: PermissionActionConfig
codesearch?: PermissionActionConfig
lsp?: PermissionRuleConfig
doom_loop?: PermissionActionConfig
skill?: PermissionRuleConfig
[key: string]: PermissionRuleConfig | PermissionActionConfig | undefined
[key: string]:
| PermissionActionConfig
| {
[key: string]: PermissionActionConfig
}
}
export type AgentConfig = {
@@ -2082,6 +2627,24 @@ export type Event =
| EventSessionCreated
| EventSessionUpdated
| EventSessionDeleted
| EventPrompt
| EventSynthetic
| EventStepStarted
| EventStepEnded
| EventTextStarted
| EventTextDelta
| EventTextEnded
| EventReasoningStarted
| EventReasoningDelta
| EventReasoningEnded
| EventToolInputStarted
| EventToolInputDelta
| EventToolInputEnded
| EventToolCalled
| EventToolSuccess
| EventToolError
| EventRetried
| EventCompacted
export type McpStatusConnected = {
status: "connected"