Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7b50bdedb4 | |||
| 4be660c73b | |||
| 2fb949754f | |||
| 3cb81aebe5 | |||
| 4e980858ea | |||
| 61aaa250c4 | |||
| cb87a172c1 | |||
| 92544483d8 | |||
| fb6770a69d | |||
| 3497c2dfe9 | |||
| 36ddebf770 | |||
| 5cd941a503 | |||
| d47287911f | |||
| 39ab49c9e5 |
@@ -1 +1,5 @@
|
||||
["client-error.ts", "client.ts", "index.ts"]
|
||||
[
|
||||
"client-error.ts",
|
||||
"client.ts",
|
||||
"index.ts"
|
||||
]
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
["client-error.ts", "client.ts", "index.ts", "types.ts"]
|
||||
[
|
||||
"client-error.ts",
|
||||
"client.ts",
|
||||
"index.ts",
|
||||
"types.ts"
|
||||
]
|
||||
|
||||
@@ -152,8 +152,8 @@ export type SessionsListOutput = {
|
||||
readonly id: string
|
||||
readonly parentID?: string
|
||||
readonly projectID: string
|
||||
readonly agent?: string | null
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string | null } | null
|
||||
readonly agent?: string
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string }
|
||||
readonly cost: number
|
||||
readonly tokens: {
|
||||
readonly input: number
|
||||
@@ -161,23 +161,23 @@ export type SessionsListOutput = {
|
||||
readonly reasoning: number
|
||||
readonly cache: { readonly read: number; readonly write: number }
|
||||
}
|
||||
readonly time: { readonly created: number; readonly updated: number; readonly archived?: number | null }
|
||||
readonly time: { readonly created: number; readonly updated: number; readonly archived?: number }
|
||||
readonly title: string
|
||||
readonly location: { readonly directory: string; readonly workspaceID?: string | null | null }
|
||||
readonly subpath?: string | null
|
||||
readonly location: { readonly directory: string; readonly workspaceID?: string }
|
||||
readonly subpath?: string
|
||||
readonly revert?: {
|
||||
readonly messageID: string
|
||||
readonly partID?: string | null
|
||||
readonly snapshot?: string | null
|
||||
readonly diff?: string | null
|
||||
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
|
||||
}> | null
|
||||
} | null
|
||||
}>
|
||||
}
|
||||
}>
|
||||
readonly cursor: { readonly previous?: string | null; readonly next?: string | null }
|
||||
}
|
||||
@@ -186,26 +186,26 @@ export type SessionsCreateInput = {
|
||||
readonly id?: {
|
||||
readonly id?: string | null
|
||||
readonly agent?: string | null
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string | null } | null
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string | null | null } | null
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string } | null
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string } | null
|
||||
}["id"]
|
||||
readonly agent?: {
|
||||
readonly id?: string | null
|
||||
readonly agent?: string | null
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string | null } | null
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string | null | null } | null
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string } | null
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string } | null
|
||||
}["agent"]
|
||||
readonly model?: {
|
||||
readonly id?: string | null
|
||||
readonly agent?: string | null
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string | null } | null
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string | null | null } | null
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string } | null
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string } | null
|
||||
}["model"]
|
||||
readonly location?: {
|
||||
readonly id?: string | null
|
||||
readonly agent?: string | null
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string | null } | null
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string | null | null } | null
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string } | null
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string } | null
|
||||
}["location"]
|
||||
}
|
||||
|
||||
@@ -214,8 +214,8 @@ export type SessionsCreateOutput = {
|
||||
readonly id: string
|
||||
readonly parentID?: string
|
||||
readonly projectID: string
|
||||
readonly agent?: string | null
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string | null } | null
|
||||
readonly agent?: string
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string }
|
||||
readonly cost: number
|
||||
readonly tokens: {
|
||||
readonly input: number
|
||||
@@ -223,23 +223,23 @@ export type SessionsCreateOutput = {
|
||||
readonly reasoning: number
|
||||
readonly cache: { readonly read: number; readonly write: number }
|
||||
}
|
||||
readonly time: { readonly created: number; readonly updated: number; readonly archived?: number | null }
|
||||
readonly time: { readonly created: number; readonly updated: number; readonly archived?: number }
|
||||
readonly title: string
|
||||
readonly location: { readonly directory: string; readonly workspaceID?: string | null | null }
|
||||
readonly subpath?: string | null
|
||||
readonly location: { readonly directory: string; readonly workspaceID?: string }
|
||||
readonly subpath?: string
|
||||
readonly revert?: {
|
||||
readonly messageID: string
|
||||
readonly partID?: string | null
|
||||
readonly snapshot?: string | null
|
||||
readonly diff?: string | null
|
||||
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
|
||||
}> | null
|
||||
} | null
|
||||
}>
|
||||
}
|
||||
}
|
||||
}["data"]
|
||||
|
||||
@@ -250,8 +250,8 @@ export type SessionsGetOutput = {
|
||||
readonly id: string
|
||||
readonly parentID?: string
|
||||
readonly projectID: string
|
||||
readonly agent?: string | null
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string | null } | null
|
||||
readonly agent?: string
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string }
|
||||
readonly cost: number
|
||||
readonly tokens: {
|
||||
readonly input: number
|
||||
@@ -259,23 +259,23 @@ export type SessionsGetOutput = {
|
||||
readonly reasoning: number
|
||||
readonly cache: { readonly read: number; readonly write: number }
|
||||
}
|
||||
readonly time: { readonly created: number; readonly updated: number; readonly archived?: number | null }
|
||||
readonly time: { readonly created: number; readonly updated: number; readonly archived?: number }
|
||||
readonly title: string
|
||||
readonly location: { readonly directory: string; readonly workspaceID?: string | null | null }
|
||||
readonly subpath?: string | null
|
||||
readonly location: { readonly directory: string; readonly workspaceID?: string }
|
||||
readonly subpath?: string
|
||||
readonly revert?: {
|
||||
readonly messageID: string
|
||||
readonly partID?: string | null
|
||||
readonly snapshot?: string | null
|
||||
readonly diff?: string | null
|
||||
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
|
||||
}> | null
|
||||
} | null
|
||||
}>
|
||||
}
|
||||
}
|
||||
}["data"]
|
||||
|
||||
@@ -289,7 +289,7 @@ export type SessionsSwitchAgentOutput = void
|
||||
export type SessionsSwitchModelInput = {
|
||||
readonly sessionID: { readonly sessionID: string }["sessionID"]
|
||||
readonly model: {
|
||||
readonly model: { readonly id: string; readonly providerID: string; readonly variant?: string | undefined }
|
||||
readonly model: { readonly id: string; readonly providerID: string; readonly variant?: string }
|
||||
}["model"]
|
||||
}
|
||||
|
||||
@@ -298,96 +298,80 @@ export type SessionsSwitchModelOutput = void
|
||||
export type SessionsPromptInput = {
|
||||
readonly sessionID: { readonly sessionID: string }["sessionID"]
|
||||
readonly id?: {
|
||||
readonly id?: string | undefined
|
||||
readonly id?: string | null
|
||||
readonly prompt: {
|
||||
readonly text: string
|
||||
readonly files?:
|
||||
| ReadonlyArray<{
|
||||
readonly uri: string
|
||||
readonly mime: string
|
||||
readonly name?: string | undefined
|
||||
readonly description?: string | undefined
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string } | undefined
|
||||
}>
|
||||
| undefined
|
||||
readonly agents?:
|
||||
| ReadonlyArray<{
|
||||
readonly name: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string } | undefined
|
||||
}>
|
||||
| undefined
|
||||
readonly files?: ReadonlyArray<{
|
||||
readonly uri: string
|
||||
readonly mime: string
|
||||
readonly name?: string
|
||||
readonly description?: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string }
|
||||
}>
|
||||
readonly agents?: ReadonlyArray<{
|
||||
readonly name: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string }
|
||||
}>
|
||||
}
|
||||
readonly delivery?: "steer" | "queue" | undefined
|
||||
readonly resume?: boolean | undefined
|
||||
readonly delivery?: "steer" | "queue" | null
|
||||
readonly resume?: boolean | null
|
||||
}["id"]
|
||||
readonly prompt: {
|
||||
readonly id?: string | undefined
|
||||
readonly id?: string | null
|
||||
readonly prompt: {
|
||||
readonly text: string
|
||||
readonly files?:
|
||||
| ReadonlyArray<{
|
||||
readonly uri: string
|
||||
readonly mime: string
|
||||
readonly name?: string | undefined
|
||||
readonly description?: string | undefined
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string } | undefined
|
||||
}>
|
||||
| undefined
|
||||
readonly agents?:
|
||||
| ReadonlyArray<{
|
||||
readonly name: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string } | undefined
|
||||
}>
|
||||
| undefined
|
||||
readonly files?: ReadonlyArray<{
|
||||
readonly uri: string
|
||||
readonly mime: string
|
||||
readonly name?: string
|
||||
readonly description?: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string }
|
||||
}>
|
||||
readonly agents?: ReadonlyArray<{
|
||||
readonly name: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string }
|
||||
}>
|
||||
}
|
||||
readonly delivery?: "steer" | "queue" | undefined
|
||||
readonly resume?: boolean | undefined
|
||||
readonly delivery?: "steer" | "queue" | null
|
||||
readonly resume?: boolean | null
|
||||
}["prompt"]
|
||||
readonly delivery?: {
|
||||
readonly id?: string | undefined
|
||||
readonly id?: string | null
|
||||
readonly prompt: {
|
||||
readonly text: string
|
||||
readonly files?:
|
||||
| ReadonlyArray<{
|
||||
readonly uri: string
|
||||
readonly mime: string
|
||||
readonly name?: string | undefined
|
||||
readonly description?: string | undefined
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string } | undefined
|
||||
}>
|
||||
| undefined
|
||||
readonly agents?:
|
||||
| ReadonlyArray<{
|
||||
readonly name: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string } | undefined
|
||||
}>
|
||||
| undefined
|
||||
readonly files?: ReadonlyArray<{
|
||||
readonly uri: string
|
||||
readonly mime: string
|
||||
readonly name?: string
|
||||
readonly description?: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string }
|
||||
}>
|
||||
readonly agents?: ReadonlyArray<{
|
||||
readonly name: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string }
|
||||
}>
|
||||
}
|
||||
readonly delivery?: "steer" | "queue" | undefined
|
||||
readonly resume?: boolean | undefined
|
||||
readonly delivery?: "steer" | "queue" | null
|
||||
readonly resume?: boolean | null
|
||||
}["delivery"]
|
||||
readonly resume?: {
|
||||
readonly id?: string | undefined
|
||||
readonly id?: string | null
|
||||
readonly prompt: {
|
||||
readonly text: string
|
||||
readonly files?:
|
||||
| ReadonlyArray<{
|
||||
readonly uri: string
|
||||
readonly mime: string
|
||||
readonly name?: string | undefined
|
||||
readonly description?: string | undefined
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string } | undefined
|
||||
}>
|
||||
| undefined
|
||||
readonly agents?:
|
||||
| ReadonlyArray<{
|
||||
readonly name: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string } | undefined
|
||||
}>
|
||||
| undefined
|
||||
readonly files?: ReadonlyArray<{
|
||||
readonly uri: string
|
||||
readonly mime: string
|
||||
readonly name?: string
|
||||
readonly description?: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string }
|
||||
}>
|
||||
readonly agents?: ReadonlyArray<{
|
||||
readonly name: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string }
|
||||
}>
|
||||
}
|
||||
readonly delivery?: "steer" | "queue" | undefined
|
||||
readonly resume?: boolean | undefined
|
||||
readonly delivery?: "steer" | "queue" | null
|
||||
readonly resume?: boolean | null
|
||||
}["resume"]
|
||||
}
|
||||
|
||||
@@ -401,18 +385,18 @@ export type SessionsPromptOutput = {
|
||||
readonly files?: ReadonlyArray<{
|
||||
readonly uri: string
|
||||
readonly mime: string
|
||||
readonly name?: string | null
|
||||
readonly description?: string | null
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string } | null
|
||||
}> | null
|
||||
readonly name?: string
|
||||
readonly description?: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string }
|
||||
}>
|
||||
readonly agents?: ReadonlyArray<{
|
||||
readonly name: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string } | null
|
||||
}> | null
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string }
|
||||
}>
|
||||
}
|
||||
readonly delivery: "steer" | "queue"
|
||||
readonly timeCreated: number
|
||||
readonly promotedSeq?: number | null
|
||||
readonly promotedSeq?: number
|
||||
}
|
||||
}["data"]
|
||||
|
||||
@@ -433,18 +417,16 @@ export type SessionsStageInput = {
|
||||
export type SessionsStageOutput = {
|
||||
readonly data: {
|
||||
readonly messageID: string
|
||||
readonly partID?: string | undefined
|
||||
readonly snapshot?: string | undefined
|
||||
readonly diff?: string | undefined
|
||||
readonly files?:
|
||||
| ReadonlyArray<{
|
||||
readonly path: string
|
||||
readonly status: "added" | "modified" | "deleted"
|
||||
readonly additions: number
|
||||
readonly deletions: number
|
||||
readonly patch: string
|
||||
}>
|
||||
| undefined
|
||||
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"]
|
||||
|
||||
@@ -462,39 +444,39 @@ export type SessionsContextOutput = {
|
||||
readonly data: ReadonlyArray<
|
||||
| {
|
||||
readonly id: string
|
||||
readonly metadata?: { readonly [x: string]: JsonValue } | null
|
||||
readonly metadata?: { readonly [x: string]: JsonValue }
|
||||
readonly time: { readonly created: number }
|
||||
readonly type: "agent-switched"
|
||||
readonly agent: string
|
||||
}
|
||||
| {
|
||||
readonly id: string
|
||||
readonly metadata?: { readonly [x: string]: JsonValue } | null
|
||||
readonly metadata?: { readonly [x: string]: JsonValue }
|
||||
readonly time: { readonly created: number }
|
||||
readonly type: "model-switched"
|
||||
readonly model: { readonly id: string; readonly providerID: string; readonly variant?: string | null }
|
||||
readonly model: { readonly id: string; readonly providerID: string; readonly variant?: string }
|
||||
}
|
||||
| {
|
||||
readonly id: string
|
||||
readonly metadata?: { readonly [x: string]: JsonValue } | null
|
||||
readonly metadata?: { readonly [x: string]: JsonValue }
|
||||
readonly time: { readonly created: number }
|
||||
readonly text: string
|
||||
readonly files?: ReadonlyArray<{
|
||||
readonly uri: string
|
||||
readonly mime: string
|
||||
readonly name?: string | null
|
||||
readonly description?: string | null
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string } | null
|
||||
}> | null
|
||||
readonly name?: string
|
||||
readonly description?: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string }
|
||||
}>
|
||||
readonly agents?: ReadonlyArray<{
|
||||
readonly name: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string } | null
|
||||
}> | null
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string }
|
||||
}>
|
||||
readonly type: "user"
|
||||
}
|
||||
| {
|
||||
readonly id: string
|
||||
readonly metadata?: { readonly [x: string]: JsonValue } | null
|
||||
readonly metadata?: { readonly [x: string]: JsonValue }
|
||||
readonly time: { readonly created: number }
|
||||
readonly sessionID: string
|
||||
readonly text: string
|
||||
@@ -502,15 +484,15 @@ export type SessionsContextOutput = {
|
||||
}
|
||||
| {
|
||||
readonly id: string
|
||||
readonly metadata?: { readonly [x: string]: JsonValue } | null
|
||||
readonly metadata?: { readonly [x: string]: JsonValue }
|
||||
readonly time: { readonly created: number }
|
||||
readonly type: "system"
|
||||
readonly text: string
|
||||
}
|
||||
| {
|
||||
readonly id: string
|
||||
readonly metadata?: { readonly [x: string]: JsonValue } | null
|
||||
readonly time: { readonly created: number; readonly completed?: number | null }
|
||||
readonly metadata?: { readonly [x: string]: JsonValue }
|
||||
readonly time: { readonly created: number; readonly completed?: number }
|
||||
readonly type: "shell"
|
||||
readonly callID: string
|
||||
readonly command: string
|
||||
@@ -518,18 +500,18 @@ export type SessionsContextOutput = {
|
||||
}
|
||||
| {
|
||||
readonly id: string
|
||||
readonly metadata?: { readonly [x: string]: JsonValue } | null
|
||||
readonly time: { readonly created: number; readonly completed?: number | null }
|
||||
readonly metadata?: { readonly [x: string]: JsonValue }
|
||||
readonly time: { readonly created: number; readonly completed?: number }
|
||||
readonly type: "assistant"
|
||||
readonly agent: string
|
||||
readonly model: { readonly id: string; readonly providerID: string; readonly variant?: string | null }
|
||||
readonly model: { readonly id: string; readonly providerID: string; readonly variant?: string }
|
||||
readonly content: ReadonlyArray<
|
||||
| { readonly type: "text"; readonly id: string; readonly text: string }
|
||||
| {
|
||||
readonly type: "reasoning"
|
||||
readonly id: string
|
||||
readonly text: string
|
||||
readonly providerMetadata?: { readonly [x: string]: { readonly [x: string]: JsonValue } } | null
|
||||
readonly providerMetadata?: { readonly [x: string]: { readonly [x: string]: JsonValue } }
|
||||
}
|
||||
| {
|
||||
readonly type: "tool"
|
||||
@@ -537,23 +519,18 @@ export type SessionsContextOutput = {
|
||||
readonly name: string
|
||||
readonly provider?: {
|
||||
readonly executed: boolean
|
||||
readonly metadata?: { readonly [x: string]: { readonly [x: string]: JsonValue } } | null
|
||||
readonly resultMetadata?: { readonly [x: string]: { readonly [x: string]: JsonValue } } | null
|
||||
} | null
|
||||
readonly metadata?: { readonly [x: string]: { readonly [x: string]: JsonValue } }
|
||||
readonly resultMetadata?: { readonly [x: string]: { readonly [x: string]: JsonValue } }
|
||||
}
|
||||
readonly state:
|
||||
| { readonly status: "pending"; readonly input: string }
|
||||
| {
|
||||
readonly status: "running"
|
||||
readonly input: { readonly [x: string]: JsonValue }
|
||||
readonly structured: { readonly [x: string]: any }
|
||||
readonly structured: { readonly [x: string]: JsonValue }
|
||||
readonly content: ReadonlyArray<
|
||||
| { readonly type: "text"; readonly text: string }
|
||||
| {
|
||||
readonly type: "file"
|
||||
readonly uri: string
|
||||
readonly mime: string
|
||||
readonly name?: string | null
|
||||
}
|
||||
| { readonly type: "file"; readonly uri: string; readonly mime: string; readonly name?: string }
|
||||
>
|
||||
}
|
||||
| {
|
||||
@@ -562,61 +539,47 @@ export type SessionsContextOutput = {
|
||||
readonly attachments?: ReadonlyArray<{
|
||||
readonly uri: string
|
||||
readonly mime: string
|
||||
readonly name?: string | null
|
||||
readonly description?: string | null
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string } | null
|
||||
}> | null
|
||||
readonly name?: string
|
||||
readonly description?: string
|
||||
readonly source?: { readonly start: number; readonly end: number; readonly text: string }
|
||||
}>
|
||||
readonly content: ReadonlyArray<
|
||||
| { readonly type: "text"; readonly text: string }
|
||||
| {
|
||||
readonly type: "file"
|
||||
readonly uri: string
|
||||
readonly mime: string
|
||||
readonly name?: string | null
|
||||
}
|
||||
| { readonly type: "file"; readonly uri: string; readonly mime: string; readonly name?: string }
|
||||
>
|
||||
readonly outputPaths?: ReadonlyArray<string> | null
|
||||
readonly structured: { readonly [x: string]: any }
|
||||
readonly result?: JsonValue | null
|
||||
readonly outputPaths?: ReadonlyArray<string>
|
||||
readonly structured: { readonly [x: string]: JsonValue }
|
||||
readonly result?: JsonValue
|
||||
}
|
||||
| {
|
||||
readonly status: "error"
|
||||
readonly input: { readonly [x: string]: JsonValue }
|
||||
readonly content: ReadonlyArray<
|
||||
| { readonly type: "text"; readonly text: string }
|
||||
| {
|
||||
readonly type: "file"
|
||||
readonly uri: string
|
||||
readonly mime: string
|
||||
readonly name?: string | null
|
||||
}
|
||||
| { readonly type: "file"; readonly uri: string; readonly mime: string; readonly name?: string }
|
||||
>
|
||||
readonly structured: { readonly [x: string]: any }
|
||||
readonly structured: { readonly [x: string]: JsonValue }
|
||||
readonly error: { readonly type: "unknown"; readonly message: string }
|
||||
readonly result?: JsonValue | null
|
||||
readonly result?: JsonValue
|
||||
}
|
||||
readonly time: {
|
||||
readonly created: number
|
||||
readonly ran?: number | null
|
||||
readonly completed?: number | null
|
||||
readonly pruned?: number | null
|
||||
readonly ran?: number
|
||||
readonly completed?: number
|
||||
readonly pruned?: number
|
||||
}
|
||||
}
|
||||
>
|
||||
readonly snapshot?: {
|
||||
readonly start?: string | null
|
||||
readonly end?: string | null
|
||||
readonly files?: ReadonlyArray<string> | null
|
||||
} | null
|
||||
readonly finish?: string | null
|
||||
readonly cost?: number | null
|
||||
readonly snapshot?: { readonly start?: string; readonly end?: string; readonly files?: ReadonlyArray<string> }
|
||||
readonly finish?: string
|
||||
readonly cost?: number
|
||||
readonly tokens?: {
|
||||
readonly input: number
|
||||
readonly output: number
|
||||
readonly reasoning: number
|
||||
readonly cache: { readonly read: number; readonly write: number }
|
||||
} | null
|
||||
readonly error?: { readonly type: "unknown"; readonly message: string } | null
|
||||
}
|
||||
readonly error?: { readonly type: "unknown"; readonly message: string }
|
||||
}
|
||||
| {
|
||||
readonly type: "compaction"
|
||||
@@ -624,7 +587,7 @@ export type SessionsContextOutput = {
|
||||
readonly summary: string
|
||||
readonly recent: string
|
||||
readonly id: string
|
||||
readonly metadata?: { readonly [x: string]: JsonValue } | null
|
||||
readonly metadata?: { readonly [x: string]: JsonValue }
|
||||
readonly time: { readonly created: number }
|
||||
}
|
||||
>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
export * as PluginV2 from "./plugin"
|
||||
|
||||
import { Context, Deferred, Effect, Exit, Layer, Scope } from "effect"
|
||||
import type { Plugin } from "@opencode-ai/plugin/v2/effect"
|
||||
import { PluginEvent, PluginID } from "@opencode-ai/schema/plugin"
|
||||
import { Plugin } from "@opencode-ai/schema/plugin"
|
||||
import { AgentV2 } from "./agent"
|
||||
import { AISDK } from "./aisdk"
|
||||
import { Catalog } from "./catalog"
|
||||
@@ -15,13 +14,14 @@ import { Reference } from "./reference"
|
||||
import { SkillV2 } from "./skill"
|
||||
import { State } from "./state"
|
||||
|
||||
export const ID = PluginID
|
||||
export type ID = typeof ID.Type
|
||||
type PluginRuntime = import("@opencode-ai/plugin/v2/effect").Plugin
|
||||
|
||||
export const Event = PluginEvent
|
||||
export const ID = Plugin.ID
|
||||
export type ID = typeof ID.Type
|
||||
export const Event = Plugin.Event
|
||||
|
||||
export interface Interface {
|
||||
readonly add: (id: ID, effect: Plugin["effect"]) => Effect.Effect<void>
|
||||
readonly add: (id: ID, effect: PluginRuntime["effect"]) => Effect.Effect<void>
|
||||
readonly remove: (id: ID) => Effect.Effect<void>
|
||||
readonly wait: (id: ID) => Effect.Effect<void>
|
||||
}
|
||||
@@ -38,9 +38,9 @@ export const layer = Layer.effect(
|
||||
const loading = new Set<ID>()
|
||||
const waiters = new Map<ID, Set<Deferred.Deferred<void>>>()
|
||||
const failures = new Map<ID, Exit.Exit<void, never>>()
|
||||
let host: Parameters<Plugin["effect"]>[0]
|
||||
let host: Parameters<PluginRuntime["effect"]>[0]
|
||||
|
||||
const add = Effect.fn("Plugin.add")(function* (id: ID, effect: Plugin["effect"]) {
|
||||
const add = Effect.fn("Plugin.add")(function* (id: ID, effect: PluginRuntime["effect"]) {
|
||||
if (loading.has(id)) return yield* Effect.die(`Plugin load cycle detected for ${id}`)
|
||||
|
||||
yield* locks.withLock(id)(
|
||||
|
||||
@@ -13,7 +13,7 @@ import { Slug } from "../util/slug"
|
||||
import { EventV2 } from "../event"
|
||||
import { Database } from "../database/database"
|
||||
import { Location } from "../location"
|
||||
import { ProjectDirectoriesEvent } from "@opencode-ai/schema/project-directories"
|
||||
import { Event } from "@opencode-ai/schema/project-directories"
|
||||
import { ProjectCopy } from "@opencode-ai/schema/project-copy"
|
||||
|
||||
export const StrategyID = ProjectCopy.StrategyID
|
||||
@@ -96,7 +96,7 @@ export interface Strategy {
|
||||
readonly list: (directory: AbsolutePath) => Effect.Effect<ListEntry[], Git.WorktreeError | DirectoryUnavailableError>
|
||||
}
|
||||
|
||||
export const Event = ProjectDirectoriesEvent
|
||||
export { Event }
|
||||
|
||||
export interface Interface {
|
||||
readonly register: (strategy: Strategy) => Effect.Effect<void, DuplicateStrategyError>
|
||||
|
||||
@@ -4,7 +4,7 @@ import { and, asc, desc, eq, isNotNull, isNull, ne, or } from "drizzle-orm"
|
||||
import { Context, Effect, Layer, Schema } from "effect"
|
||||
import { Database } from "../database/database"
|
||||
import { LayerNode } from "../effect/layer-node"
|
||||
import { AbsolutePath, optionalOmitUndefined } from "../schema"
|
||||
import { AbsolutePath, optional } from "../schema"
|
||||
import { ProjectSchema } from "./schema"
|
||||
import { ProjectDirectoryTable } from "./sql"
|
||||
import type { EffectDrizzleSqlite } from "@opencode-ai/effect-drizzle-sqlite"
|
||||
@@ -39,7 +39,7 @@ export type ListInput = typeof ListInput.Type
|
||||
export const ListOutput = Schema.Array(
|
||||
Schema.Struct({
|
||||
directory: AbsolutePath,
|
||||
strategy: optionalOmitUndefined(Schema.String),
|
||||
strategy: optional(Schema.String),
|
||||
}),
|
||||
).annotate({ identifier: "Project.Directories" })
|
||||
export type ListOutput = typeof ListOutput.Type
|
||||
|
||||
@@ -2,7 +2,7 @@ export * as Pty from "./pty"
|
||||
|
||||
import type { Disp, Proc } from "#pty"
|
||||
import { Context, Effect, Layer, Schema, Types } from "effect"
|
||||
import { PtyEvent, PtyInfo, Pty } from "@opencode-ai/schema/pty"
|
||||
import { Pty } from "@opencode-ai/schema/pty"
|
||||
import { Config } from "./config"
|
||||
import { EventV2 } from "./event"
|
||||
import { Location } from "./location"
|
||||
@@ -35,8 +35,7 @@ type Active = {
|
||||
listeners: Disp[]
|
||||
}
|
||||
|
||||
export const Info = PtyInfo
|
||||
|
||||
export const Info = Pty.Info
|
||||
export type Info = Types.DeepMutable<typeof Info.Type>
|
||||
|
||||
export const CreateInput = Pty.CreateInput
|
||||
@@ -47,6 +46,8 @@ export const UpdateInput = Pty.UpdateInput
|
||||
|
||||
export type UpdateInput = Types.DeepMutable<typeof UpdateInput.Type>
|
||||
|
||||
export const Event = Pty.Event
|
||||
|
||||
export type AttachInput = {
|
||||
// Absolute output cursor to replay from. -1 tails from the current end; omitted replays the full retained buffer.
|
||||
readonly cursor?: number
|
||||
@@ -75,8 +76,6 @@ export class ExitedError extends Schema.TaggedErrorClass<ExitedError>()("Pty.Exi
|
||||
ptyID: PtyID,
|
||||
}) {}
|
||||
|
||||
export const Event = PtyEvent
|
||||
|
||||
export interface Interface {
|
||||
readonly list: () => Effect.Effect<Info[]>
|
||||
readonly get: (id: PtyID) => Effect.Effect<Info, NotFoundError>
|
||||
|
||||
@@ -3,20 +3,20 @@ import {
|
||||
AbsolutePath,
|
||||
DateTimeUtcFromMillis,
|
||||
NonNegativeInt,
|
||||
optionalOmitUndefined,
|
||||
optional,
|
||||
PositiveInt,
|
||||
RelativePath,
|
||||
withStatics,
|
||||
statics,
|
||||
} from "@opencode-ai/schema/schema"
|
||||
|
||||
export {
|
||||
AbsolutePath,
|
||||
DateTimeUtcFromMillis,
|
||||
NonNegativeInt,
|
||||
optionalOmitUndefined,
|
||||
optional,
|
||||
PositiveInt,
|
||||
RelativePath,
|
||||
withStatics,
|
||||
statics,
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,7 +9,7 @@ import { ContextSnapshotDecodeError } from "./error"
|
||||
import { SessionEvent } from "./event"
|
||||
import { SessionHistory } from "./history"
|
||||
import { SessionInput } from "./input"
|
||||
import { SessionMessageID } from "./message-id"
|
||||
import { SessionMessage } from "./message"
|
||||
import { SessionSchema } from "./schema"
|
||||
import { SessionContextEpochTable } from "./sql"
|
||||
|
||||
@@ -71,7 +71,7 @@ const prepareOnce = Effect.fnUntraced(function* (
|
||||
|
||||
yield* events.publish(
|
||||
SessionEvent.ContextUpdated,
|
||||
{ sessionID, messageID: SessionMessageID.ID.create(), timestamp: yield* DateTime.now, text: result.text },
|
||||
{ sessionID, messageID: SessionMessage.ID.create(), timestamp: yield* DateTime.now, text: result.text },
|
||||
{ commit: () => advance(db, sessionID, result.snapshot).pipe(Effect.orDie) },
|
||||
)
|
||||
return { baseline: stored.baseline, baselineSeq: stored.baseline_seq }
|
||||
|
||||
@@ -8,7 +8,7 @@ import { AbsolutePath, RelativePath } from "../schema"
|
||||
import { WorkspaceV2 } from "../workspace"
|
||||
import { SessionSchema } from "./schema"
|
||||
import { SessionTable } from "./sql"
|
||||
import { SessionMessageID } from "./message-id"
|
||||
import { SessionMessage } from "./message"
|
||||
import { Snapshot } from "../snapshot"
|
||||
|
||||
export function fromRow(row: typeof SessionTable.$inferSelect): SessionSchema.Info {
|
||||
@@ -40,7 +40,7 @@ export function fromRow(row: typeof SessionTable.$inferSelect): SessionSchema.In
|
||||
workspaceID: row.workspace_id ? WorkspaceV2.ID.make(row.workspace_id) : undefined,
|
||||
}),
|
||||
subpath: row.path ? RelativePath.make(row.path) : undefined,
|
||||
revert: row.revert ? { ...row.revert, messageID: SessionMessageID.ID.make(row.revert.messageID) } : undefined,
|
||||
revert: row.revert ? { ...row.revert, messageID: SessionMessage.ID.make(row.revert.messageID) } : undefined,
|
||||
time: {
|
||||
created: DateTime.makeUnsafe(row.time_created),
|
||||
updated: DateTime.makeUnsafe(row.time_updated),
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
export * as SessionMessageID from "./message-id"
|
||||
export { ID } from "@opencode-ai/schema/session-message-id"
|
||||
@@ -15,7 +15,6 @@ import { WorkspaceV2 } from "../workspace"
|
||||
import { SessionContextEpoch } from "./context-epoch"
|
||||
import { MessageTable, PartTable, SessionInputTable, SessionMessageTable, SessionTable } from "./sql"
|
||||
import type { DeepMutable } from "../schema"
|
||||
import { SessionMessageID } from "./message-id"
|
||||
|
||||
type DatabaseService = Database.Interface["db"]
|
||||
|
||||
@@ -67,7 +66,7 @@ function sessionRow(info: SessionV1.SessionInfo): typeof SessionTable.$inferInse
|
||||
tokens_reasoning: (info.tokens ?? { reasoning: 0 }).reasoning,
|
||||
tokens_cache_read: (info.tokens ?? { cache: { read: 0 } }).cache.read,
|
||||
tokens_cache_write: (info.tokens ?? { cache: { write: 0 } }).cache.write,
|
||||
revert: info.revert ? { ...info.revert, messageID: SessionMessageID.ID.make(info.revert.messageID) } : null,
|
||||
revert: info.revert ? { ...info.revert, messageID: SessionMessage.ID.make(info.revert.messageID) } : null,
|
||||
permission: info.permission ? [...info.permission] : undefined,
|
||||
time_created: info.time.created,
|
||||
time_updated: info.time.updated,
|
||||
|
||||
@@ -14,6 +14,7 @@ import { Timestamps } from "../database/schema.sql"
|
||||
import type { SystemContext } from "../system-context/index"
|
||||
import { AgentV2 } from "../agent"
|
||||
import type { Revert } from "@opencode-ai/schema/revert"
|
||||
import type { SessionTodo } from "@opencode-ai/schema/session-todo"
|
||||
|
||||
type SessionMessageData = Omit<(typeof SessionMessage.Message)["Encoded"], "type" | "id">
|
||||
type V1MessageData = Omit<SessionV1.Info, "id" | "sessionID">
|
||||
@@ -105,8 +106,8 @@ export const TodoTable = sqliteTable(
|
||||
.notNull()
|
||||
.references(() => SessionTable.id, { onDelete: "cascade" }),
|
||||
content: text().notNull(),
|
||||
status: text().notNull(),
|
||||
priority: text().notNull(),
|
||||
status: text().$type<SessionTodo.Info["status"]>().notNull(),
|
||||
priority: text().$type<SessionTodo.Info["priority"]>().notNull(),
|
||||
position: integer().notNull(),
|
||||
...Timestamps,
|
||||
},
|
||||
|
||||
@@ -2,15 +2,14 @@ export * as SessionTodo from "./todo"
|
||||
|
||||
import { asc, eq } from "drizzle-orm"
|
||||
import { Context, Effect, Layer } from "effect"
|
||||
import { SessionTodo, SessionTodoInfo } from "@opencode-ai/schema/session-todo"
|
||||
import { SessionTodo } from "@opencode-ai/schema/session-todo"
|
||||
import { Database } from "../database/database"
|
||||
import { EventV2 } from "../event"
|
||||
import { SessionSchema } from "./schema"
|
||||
import { TodoTable } from "./sql"
|
||||
|
||||
export const Info = SessionTodoInfo
|
||||
export const Info = SessionTodo.Info
|
||||
export type Info = typeof Info.Type
|
||||
|
||||
export const Event = SessionTodo.Event
|
||||
|
||||
export interface Interface {
|
||||
|
||||
@@ -9,6 +9,8 @@ import { Model } from "@opencode-ai/schema/model"
|
||||
import { AgentAttachment, FileAttachment, Prompt, Source } from "@opencode-ai/schema/prompt"
|
||||
import { Provider } from "@opencode-ai/schema/provider"
|
||||
import { Project } from "@opencode-ai/schema/project"
|
||||
import { ProjectDirectories } from "@opencode-ai/schema/project-directories"
|
||||
import { PermissionV1 } from "@opencode-ai/schema/permission-v1"
|
||||
import { Session } from "@opencode-ai/schema/session"
|
||||
import { SessionInput } from "@opencode-ai/schema/session-input"
|
||||
import { SessionMessage } from "@opencode-ai/schema/session-message"
|
||||
@@ -20,10 +22,14 @@ import { FileSystem } from "@opencode-ai/schema/filesystem"
|
||||
import { Integration } from "@opencode-ai/schema/integration"
|
||||
import { LLM } from "@opencode-ai/schema/llm"
|
||||
import { Permission } from "@opencode-ai/schema/permission"
|
||||
import { Plugin } from "@opencode-ai/schema/plugin"
|
||||
import { Pty } from "@opencode-ai/schema/pty"
|
||||
import { Reference } from "@opencode-ai/schema/reference"
|
||||
import { SessionTodo } from "@opencode-ai/schema/session-todo"
|
||||
import { Skill } from "@opencode-ai/schema/skill"
|
||||
import { AbsolutePath, DateTimeUtcFromMillis } from "@opencode-ai/schema/schema"
|
||||
import { AbsolutePath, DateTimeUtcFromMillis, optional, statics } from "@opencode-ai/schema/schema"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { PluginV2 } from "@opencode-ai/core/plugin"
|
||||
|
||||
test("Core reuses the canonical shared schemas", async () => {
|
||||
const [
|
||||
@@ -35,13 +41,18 @@ test("Core reuses the canonical shared schemas", async () => {
|
||||
coreLocation,
|
||||
coreLLM,
|
||||
corePermission,
|
||||
corePermissionV1,
|
||||
coreProjectCopy,
|
||||
corePty,
|
||||
coreProject,
|
||||
coreReference,
|
||||
coreSessionInput,
|
||||
coreSessionMessage,
|
||||
coreSessionTodo,
|
||||
corePrompt,
|
||||
coreSkill,
|
||||
coreV2Schema,
|
||||
coreSchema,
|
||||
coreWorkspace,
|
||||
] = await Promise.all([
|
||||
import("@opencode-ai/core/command"),
|
||||
@@ -52,13 +63,18 @@ test("Core reuses the canonical shared schemas", async () => {
|
||||
import("@opencode-ai/core/location"),
|
||||
import("@opencode-ai/llm"),
|
||||
import("@opencode-ai/core/permission"),
|
||||
import("@opencode-ai/core/v1/permission"),
|
||||
import("@opencode-ai/core/project/copy"),
|
||||
import("@opencode-ai/core/pty"),
|
||||
import("@opencode-ai/core/project/schema"),
|
||||
import("@opencode-ai/core/reference"),
|
||||
import("@opencode-ai/core/session/input"),
|
||||
import("@opencode-ai/core/session/message"),
|
||||
import("@opencode-ai/core/session/todo"),
|
||||
import("@opencode-ai/core/session/prompt"),
|
||||
import("@opencode-ai/core/skill"),
|
||||
import("@opencode-ai/core/v2-schema"),
|
||||
import("@opencode-ai/core/schema"),
|
||||
import("@opencode-ai/core/workspace"),
|
||||
])
|
||||
|
||||
@@ -111,6 +127,12 @@ test("Core reuses the canonical shared schemas", async () => {
|
||||
[corePermission.Effect, Permission.Effect],
|
||||
[corePermission.Rule, Permission.Rule],
|
||||
[corePermission.Ruleset, Permission.Ruleset],
|
||||
[corePermissionV1.Event, PermissionV1.Event],
|
||||
[coreProjectCopy.Event, ProjectDirectories.Event],
|
||||
[PluginV2.ID, Plugin.ID],
|
||||
[PluginV2.Event, Plugin.Event],
|
||||
[corePty.Info, Pty.Info],
|
||||
[corePty.Event, Pty.Event],
|
||||
[coreProject.ID, Project.ID],
|
||||
[coreReference.LocalSource, Reference.LocalSource],
|
||||
[coreReference.GitSource, Reference.GitSource],
|
||||
@@ -140,6 +162,8 @@ test("Core reuses the canonical shared schemas", async () => {
|
||||
[coreSessionMessage.Assistant, SessionMessage.Assistant],
|
||||
[coreSessionMessage.Compaction, SessionMessage.Compaction],
|
||||
[coreSessionMessage.Message, SessionMessage.Message],
|
||||
[coreSessionTodo.Info, SessionTodo.Info],
|
||||
[coreSessionTodo.Event, SessionTodo.Event],
|
||||
[corePrompt.Source, Source],
|
||||
[corePrompt.FileAttachment, FileAttachment],
|
||||
[corePrompt.AgentAttachment, AgentAttachment],
|
||||
@@ -150,6 +174,8 @@ test("Core reuses the canonical shared schemas", async () => {
|
||||
[coreSkill.Source, Skill.Source],
|
||||
[coreSkill.Info, Skill.Info],
|
||||
[coreV2Schema.DateTimeUtcFromMillis, DateTimeUtcFromMillis],
|
||||
[coreSchema.optional, optional],
|
||||
[coreSchema.statics, statics],
|
||||
[coreWorkspace.ID, Workspace.ID],
|
||||
]
|
||||
for (const [core, shared] of schemas) expect(core).toBe(shared)
|
||||
|
||||
@@ -77,7 +77,9 @@ describe("TodoWriteTool", () => {
|
||||
yield* setup
|
||||
const registry = yield* ToolRegistry.Service
|
||||
const service = yield* SessionTodo.Service
|
||||
const todoList = [{ content: "Implement slice", status: "in_progress", priority: "high" }]
|
||||
const todoList: ReadonlyArray<SessionTodo.Info> = [
|
||||
{ content: "Implement slice", status: "in_progress", priority: "high" },
|
||||
]
|
||||
|
||||
expect((yield* toolDefinitions(registry)).map((tool) => tool.name)).toEqual([TodoWriteTool.name])
|
||||
expect(yield* settleTool(registry, call(todoList))).toEqual({
|
||||
|
||||
@@ -6,9 +6,8 @@ import { Deferred, Effect, Layer, Context } from "effect"
|
||||
import os from "os"
|
||||
import { PermissionV1 } from "@opencode-ai/core/v1/permission"
|
||||
import { EventV2Bridge } from "@/event-v2-bridge"
|
||||
import { PermissionV1Event } from "@opencode-ai/schema/permission-v1"
|
||||
|
||||
export const Event = PermissionV1Event
|
||||
export const Event = PermissionV1.Event
|
||||
|
||||
export interface Interface {
|
||||
readonly ask: (input: PermissionV1.AskInput) => Effect.Effect<void, PermissionV1.Error>
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { AuthOAuthResult, Hooks } from "@opencode-ai/plugin"
|
||||
import { serviceUse } from "@opencode-ai/core/effect/service-use"
|
||||
import { Auth } from "@/auth"
|
||||
import { InstanceState } from "@/effect/instance-state"
|
||||
import { optionalOmitUndefined } from "@opencode-ai/core/schema"
|
||||
import { optional } from "@opencode-ai/core/schema"
|
||||
import { Plugin } from "../plugin"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { Array as Arr, Effect, Layer, Record, Result, Context, Schema } from "effect"
|
||||
@@ -18,14 +18,14 @@ const TextPrompt = Schema.Struct({
|
||||
type: Schema.Literal("text"),
|
||||
key: Schema.String,
|
||||
message: Schema.String,
|
||||
placeholder: optionalOmitUndefined(Schema.String),
|
||||
when: optionalOmitUndefined(When),
|
||||
placeholder: optional(Schema.String),
|
||||
when: optional(When),
|
||||
})
|
||||
|
||||
const SelectOption = Schema.Struct({
|
||||
label: Schema.String,
|
||||
value: Schema.String,
|
||||
hint: optionalOmitUndefined(Schema.String),
|
||||
hint: optional(Schema.String),
|
||||
})
|
||||
|
||||
const SelectPrompt = Schema.Struct({
|
||||
@@ -33,7 +33,7 @@ const SelectPrompt = Schema.Struct({
|
||||
key: Schema.String,
|
||||
message: Schema.String,
|
||||
options: Schema.Array(SelectOption),
|
||||
when: optionalOmitUndefined(When),
|
||||
when: optional(When),
|
||||
})
|
||||
|
||||
const Prompt = Schema.Union([TextPrompt, SelectPrompt])
|
||||
@@ -41,7 +41,7 @@ const Prompt = Schema.Union([TextPrompt, SelectPrompt])
|
||||
export class Method extends Schema.Class<Method>("ProviderAuthMethod")({
|
||||
type: Schema.Literals(["oauth", "api"]),
|
||||
label: Schema.String,
|
||||
prompts: optionalOmitUndefined(Schema.Array(Prompt)),
|
||||
prompts: optional(Schema.Array(Prompt)),
|
||||
}) {}
|
||||
|
||||
export const Methods = Schema.Record(Schema.String, Schema.Array(Method))
|
||||
|
||||
@@ -24,7 +24,7 @@ import { InstanceState } from "@/effect/instance-state"
|
||||
import { EffectPromise } from "@/effect/promise"
|
||||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||
import { isRecord } from "@/util/record"
|
||||
import { optionalOmitUndefined } from "@opencode-ai/core/schema"
|
||||
import { optional } from "@opencode-ai/core/schema"
|
||||
import { ProviderTransform } from "./transform"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
@@ -999,8 +999,8 @@ const ProviderCost = Schema.Struct({
|
||||
input: Schema.Finite,
|
||||
output: Schema.Finite,
|
||||
cache: ProviderCacheCost,
|
||||
tiers: optionalOmitUndefined(Schema.Array(ProviderCostTier)),
|
||||
experimentalOver200K: optionalOmitUndefined(
|
||||
tiers: optional(Schema.Array(ProviderCostTier)),
|
||||
experimentalOver200K: optional(
|
||||
Schema.Struct({
|
||||
input: Schema.Finite,
|
||||
output: Schema.Finite,
|
||||
@@ -1011,7 +1011,7 @@ const ProviderCost = Schema.Struct({
|
||||
|
||||
const ProviderLimit = Schema.Struct({
|
||||
context: Schema.Finite,
|
||||
input: optionalOmitUndefined(Schema.Finite),
|
||||
input: optional(Schema.Finite),
|
||||
output: Schema.Finite,
|
||||
})
|
||||
|
||||
@@ -1020,7 +1020,7 @@ export const Model = Schema.Struct({
|
||||
providerID: ProviderV2.ID,
|
||||
api: ProviderApiInfo,
|
||||
name: Schema.String,
|
||||
family: optionalOmitUndefined(Schema.String),
|
||||
family: optional(Schema.String),
|
||||
capabilities: ProviderCapabilities,
|
||||
cost: ProviderCost,
|
||||
limit: ProviderLimit,
|
||||
@@ -1028,7 +1028,7 @@ export const Model = Schema.Struct({
|
||||
options: Schema.Record(Schema.String, Schema.Any),
|
||||
headers: Schema.Record(Schema.String, Schema.String),
|
||||
release_date: Schema.String,
|
||||
variants: optionalOmitUndefined(Schema.Record(Schema.String, Schema.Record(Schema.String, Schema.Any))),
|
||||
variants: optional(Schema.Record(Schema.String, Schema.Record(Schema.String, Schema.Any))),
|
||||
}).annotate({ identifier: "Model" })
|
||||
export type Model = Types.DeepMutable<Schema.Schema.Type<typeof Model>>
|
||||
|
||||
@@ -1037,7 +1037,7 @@ export const Info = Schema.Struct({
|
||||
name: Schema.String,
|
||||
source: Schema.Literals(["env", "config", "custom", "api"]),
|
||||
env: Schema.Array(Schema.String),
|
||||
key: optionalOmitUndefined(Schema.String),
|
||||
key: optional(Schema.String),
|
||||
options: Schema.Record(Schema.String, Schema.Any),
|
||||
models: Schema.Record(Schema.String, Model),
|
||||
}).annotate({ identifier: "Provider" })
|
||||
|
||||
@@ -2,14 +2,14 @@ import { Schema } from "effect"
|
||||
|
||||
import { Identifier } from "@/id/id"
|
||||
import { SessionV2 } from "@opencode-ai/core/session"
|
||||
import { withStatics } from "@opencode-ai/core/schema"
|
||||
import { statics } from "@opencode-ai/core/schema"
|
||||
|
||||
export const SessionID = SessionV2.ID
|
||||
export type SessionID = Schema.Schema.Type<typeof SessionID>
|
||||
|
||||
export const MessageID = Schema.String.check(Schema.isStartsWith("msg")).pipe(
|
||||
Schema.brand("MessageID"),
|
||||
withStatics((s) => ({
|
||||
statics((s) => ({
|
||||
ascending: (id?: string) => s.make(Identifier.ascending("message", id)),
|
||||
})),
|
||||
)
|
||||
@@ -18,7 +18,7 @@ export type MessageID = Schema.Schema.Type<typeof MessageID>
|
||||
|
||||
export const PartID = Schema.String.check(Schema.isStartsWith("prt")).pipe(
|
||||
Schema.brand("PartID"),
|
||||
withStatics((s) => ({
|
||||
statics((s) => ({
|
||||
ascending: (id?: string) => s.make(Identifier.ascending("part", id)),
|
||||
})),
|
||||
)
|
||||
|
||||
@@ -39,11 +39,11 @@ import { SessionID, MessageID, PartID } from "./schema"
|
||||
import type { Provider } from "@/provider/provider"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Effect, Layer, Option, Context, Schema, Types } from "effect"
|
||||
import { NonNegativeInt, optionalOmitUndefined } from "@opencode-ai/core/schema"
|
||||
import { NonNegativeInt, optional } from "@opencode-ai/core/schema"
|
||||
import { RuntimeFlags } from "@/effect/runtime-flags"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
import { SessionMessageID } from "@opencode-ai/schema/session-message-id"
|
||||
import { SessionMessage } from "@opencode-ai/schema/session-message"
|
||||
|
||||
const runtime = makeRuntime(Database.Service, Database.defaultLayer)
|
||||
|
||||
@@ -146,7 +146,7 @@ export function toRow(info: Info) {
|
||||
tokens_cache_write: (info.tokens ?? EmptyTokens).cache.write,
|
||||
revert: info.revert
|
||||
? {
|
||||
messageID: SessionMessageID.ID.make(info.revert.messageID),
|
||||
messageID: SessionMessage.ID.make(info.revert.messageID),
|
||||
partID: info.revert.partID,
|
||||
snapshot: info.revert.snapshot,
|
||||
diff: info.revert.diff,
|
||||
@@ -178,7 +178,7 @@ const Summary = Schema.Struct({
|
||||
additions: Schema.Finite,
|
||||
deletions: Schema.Finite,
|
||||
files: Schema.Finite,
|
||||
diffs: optionalOmitUndefined(Schema.Array(Snapshot.FileDiff)),
|
||||
diffs: optional(Schema.Array(Snapshot.FileDiff)),
|
||||
})
|
||||
|
||||
const Tokens = Schema.Struct({
|
||||
@@ -204,21 +204,21 @@ export const ArchivedTimestamp = Schema.Finite
|
||||
const Time = Schema.Struct({
|
||||
created: NonNegativeInt,
|
||||
updated: NonNegativeInt,
|
||||
compacting: optionalOmitUndefined(NonNegativeInt),
|
||||
archived: optionalOmitUndefined(ArchivedTimestamp),
|
||||
compacting: optional(NonNegativeInt),
|
||||
archived: optional(ArchivedTimestamp),
|
||||
})
|
||||
|
||||
const Revert = Schema.Struct({
|
||||
messageID: MessageID,
|
||||
partID: optionalOmitUndefined(PartID),
|
||||
snapshot: optionalOmitUndefined(Schema.String),
|
||||
diff: optionalOmitUndefined(Schema.String),
|
||||
partID: optional(PartID),
|
||||
snapshot: optional(Schema.String),
|
||||
diff: optional(Schema.String),
|
||||
})
|
||||
|
||||
const Model = Schema.Struct({
|
||||
id: ModelV2.ID,
|
||||
providerID: ProviderV2.ID,
|
||||
variant: optionalOmitUndefined(Schema.String),
|
||||
variant: optional(Schema.String),
|
||||
})
|
||||
|
||||
export const Metadata = Schema.Record(Schema.String, Schema.Any)
|
||||
@@ -227,28 +227,28 @@ export const Info = Schema.Struct({
|
||||
id: SessionID,
|
||||
slug: Schema.String,
|
||||
projectID: ProjectV2.ID,
|
||||
workspaceID: optionalOmitUndefined(WorkspaceV2.ID),
|
||||
workspaceID: optional(WorkspaceV2.ID),
|
||||
directory: Schema.String,
|
||||
path: optionalOmitUndefined(Schema.String),
|
||||
parentID: optionalOmitUndefined(SessionID),
|
||||
summary: optionalOmitUndefined(Summary),
|
||||
cost: optionalOmitUndefined(Schema.Finite),
|
||||
tokens: optionalOmitUndefined(Tokens),
|
||||
share: optionalOmitUndefined(Share),
|
||||
path: optional(Schema.String),
|
||||
parentID: optional(SessionID),
|
||||
summary: optional(Summary),
|
||||
cost: optional(Schema.Finite),
|
||||
tokens: optional(Tokens),
|
||||
share: optional(Share),
|
||||
title: Schema.String,
|
||||
agent: optionalOmitUndefined(Schema.String),
|
||||
model: optionalOmitUndefined(Model),
|
||||
agent: optional(Schema.String),
|
||||
model: optional(Model),
|
||||
version: Schema.String,
|
||||
metadata: optionalOmitUndefined(Metadata),
|
||||
metadata: optional(Metadata),
|
||||
time: Time,
|
||||
permission: optionalOmitUndefined(PermissionV1.Ruleset),
|
||||
revert: optionalOmitUndefined(Revert),
|
||||
permission: optional(PermissionV1.Ruleset),
|
||||
revert: optional(Revert),
|
||||
}).annotate({ identifier: "Session" })
|
||||
export type Info = Types.DeepMutable<Schema.Schema.Type<typeof Info>>
|
||||
|
||||
export const ProjectInfo = Schema.Struct({
|
||||
id: ProjectV2.ID,
|
||||
name: optionalOmitUndefined(Schema.String),
|
||||
name: optional(Schema.String),
|
||||
worktree: Schema.String,
|
||||
}).annotate({ identifier: "ProjectSummary" })
|
||||
export type ProjectInfo = Types.DeepMutable<Schema.Schema.Type<typeof ProjectInfo>>
|
||||
|
||||
@@ -14,7 +14,7 @@ export type Info = SessionTodo.Info
|
||||
export const Event = SessionTodo.Event
|
||||
|
||||
export interface Interface {
|
||||
readonly update: (input: { sessionID: SessionID; todos: Info[] }) => Effect.Effect<void>
|
||||
readonly update: (input: { sessionID: SessionID; todos: ReadonlyArray<Info> }) => Effect.Effect<void>
|
||||
readonly get: (sessionID: SessionID) => Effect.Effect<Info[]>
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ export const layer = Layer.effect(
|
||||
const events = yield* EventV2Bridge.Service
|
||||
const { db } = yield* Database.Service
|
||||
|
||||
const update = Effect.fn("Todo.update")(function* (input: { sessionID: SessionID; todos: Info[] }) {
|
||||
const update = Effect.fn("Todo.update")(function* (input: { sessionID: SessionID; todos: ReadonlyArray<Info> }) {
|
||||
yield* db
|
||||
.transaction((tx) =>
|
||||
Effect.gen(function* () {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Schema } from "effect"
|
||||
|
||||
import { Identifier } from "@/id/id"
|
||||
import { withStatics } from "@opencode-ai/core/schema"
|
||||
import { statics } from "@opencode-ai/core/schema"
|
||||
|
||||
export const EventID = Schema.String.check(Schema.isStartsWith("evt")).pipe(
|
||||
Schema.brand("EventID"),
|
||||
withStatics((s) => ({
|
||||
statics((s) => ({
|
||||
ascending: (id?: string) => s.make(Identifier.ascending("event", id)),
|
||||
})),
|
||||
)
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { Schema } from "effect"
|
||||
|
||||
import { Identifier } from "@/id/id"
|
||||
import { withStatics } from "@opencode-ai/core/schema"
|
||||
import { statics } from "@opencode-ai/core/schema"
|
||||
|
||||
const toolIdSchema = Schema.String.check(Schema.isStartsWith("tool")).pipe(Schema.brand("ToolID"))
|
||||
|
||||
export type ToolID = typeof toolIdSchema.Type
|
||||
|
||||
export const ToolID = toolIdSchema.pipe(
|
||||
withStatics((schema: typeof toolIdSchema) => ({
|
||||
statics((schema: typeof toolIdSchema) => ({
|
||||
ascending: (id?: string) => schema.make(Identifier.ascending("tool", id)),
|
||||
})),
|
||||
)
|
||||
|
||||
@@ -3,19 +3,8 @@ import * as Tool from "./tool"
|
||||
import DESCRIPTION_WRITE from "./todowrite.txt"
|
||||
import { Todo } from "../session/todo"
|
||||
|
||||
// Todo.Info is still a zod schema (session/todo.ts). Inline the field shape
|
||||
// here rather than referencing its `.shape` — the LLM-visible JSON Schema is
|
||||
// identical, and it removes the last zod dependency from this tool.
|
||||
const TodoItem = Schema.Struct({
|
||||
content: Schema.String.annotate({ description: "Brief description of the task" }),
|
||||
status: Schema.String.annotate({
|
||||
description: "Current status of the task: pending, in_progress, completed, cancelled",
|
||||
}),
|
||||
priority: Schema.String.annotate({ description: "Priority level of the task: high, medium, low" }),
|
||||
})
|
||||
|
||||
export const Parameters = Schema.Struct({
|
||||
todos: Schema.mutable(Schema.Array(TodoItem)).annotate({ description: "The updated todo list" }),
|
||||
todos: Schema.mutable(Schema.Array(Todo.Info)).annotate({ description: "The updated todo list" }),
|
||||
})
|
||||
|
||||
type Metadata = {
|
||||
|
||||
@@ -1170,7 +1170,7 @@ const scenarios: Scenario[] = [
|
||||
.seeded((ctx) =>
|
||||
Effect.gen(function* () {
|
||||
const session = yield* ctx.session({ title: "Todo session" })
|
||||
const todos = [{ content: "cover session todo", status: "pending", priority: "high" }]
|
||||
const todos = [{ content: "cover session todo", status: "pending" as const, priority: "high" as const }]
|
||||
yield* ctx.todos(session.id, todos)
|
||||
return { session, todos }
|
||||
}),
|
||||
|
||||
@@ -119,5 +119,9 @@ export type Result =
|
||||
| { status: "skip"; scenario: TodoScenario }
|
||||
|
||||
export type SessionInfo = { id: SessionID; title: string; parentID?: SessionID }
|
||||
export type TodoInfo = { content: string; status: string; priority: string }
|
||||
export type TodoInfo = {
|
||||
content: string
|
||||
status: "pending" | "in_progress" | "completed" | "cancelled"
|
||||
priority: "high" | "medium" | "low"
|
||||
}
|
||||
export type MessageSeed = { info: SessionV1.User; part: SessionV1.TextPart }
|
||||
|
||||
@@ -256,7 +256,7 @@ describe("Todo.Info", () => {
|
||||
const decode = decodeUnknown(Todo.Info)
|
||||
|
||||
test("three-field round-trip", () => {
|
||||
const input = { content: "do a thing", status: "pending", priority: "high" }
|
||||
const input = Todo.Info.make({ content: "do a thing", status: "pending", priority: "high" })
|
||||
expect(decode(input)).toEqual(input)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import type { AgentV2Info } from "@opencode-ai/sdk/v2/types"
|
||||
import type { ReadonlyDeep } from "../options.js"
|
||||
import type { Hooks } from "./registration.js"
|
||||
|
||||
export interface AgentDraft {
|
||||
list(): readonly AgentV2Info[]
|
||||
get(id: string): AgentV2Info | undefined
|
||||
list(): readonly ReadonlyDeep<AgentV2Info>[]
|
||||
get(id: string): ReadonlyDeep<AgentV2Info> | undefined
|
||||
default(id: string | undefined): void
|
||||
update(id: string, update: (agent: AgentV2Info) => void): void
|
||||
remove(id: string): void
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import type { LanguageModelV3 } from "@ai-sdk/provider"
|
||||
import type { ModelV2Info } from "@opencode-ai/sdk/v2/types"
|
||||
import type { ReadonlyDeep } from "../options.js"
|
||||
import type { Hooks } from "./registration.js"
|
||||
|
||||
export type AISDKHooks = Hooks<{
|
||||
sdk: {
|
||||
readonly model: ModelV2Info
|
||||
readonly model: ReadonlyDeep<ModelV2Info>
|
||||
readonly package: string
|
||||
readonly options: Record<string, any>
|
||||
sdk?: any
|
||||
}
|
||||
language: {
|
||||
readonly model: ModelV2Info
|
||||
readonly model: ReadonlyDeep<ModelV2Info>
|
||||
readonly sdk: any
|
||||
readonly options: Record<string, any>
|
||||
language?: LanguageModelV3
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import type { ModelV2Info, ProviderV2Info } from "@opencode-ai/sdk/v2/types"
|
||||
import type { ReadonlyDeep } from "../options.js"
|
||||
import type { Hooks } from "./registration.js"
|
||||
|
||||
export interface CatalogProviderRecord {
|
||||
readonly provider: ProviderV2Info
|
||||
readonly models: ReadonlyMap<string, ModelV2Info>
|
||||
readonly provider: ReadonlyDeep<ProviderV2Info>
|
||||
readonly models: ReadonlyMap<string, ReadonlyDeep<ModelV2Info>>
|
||||
}
|
||||
|
||||
export interface CatalogDraft {
|
||||
@@ -14,7 +15,7 @@ export interface CatalogDraft {
|
||||
remove(providerID: string): void
|
||||
}
|
||||
readonly model: {
|
||||
get(providerID: string, modelID: string): ModelV2Info | undefined
|
||||
get(providerID: string, modelID: string): ReadonlyDeep<ModelV2Info> | undefined
|
||||
update(providerID: string, modelID: string, update: (model: ModelV2Info) => void): void
|
||||
remove(providerID: string, modelID: string): void
|
||||
readonly default: {
|
||||
|
||||
@@ -11,6 +11,7 @@ import type {
|
||||
} from "@opencode-ai/sdk/v2/types"
|
||||
import type { Effect, Scope } from "effect"
|
||||
import type { Hooks } from "./registration.js"
|
||||
import type { ReadonlyDeep } from "../options.js"
|
||||
|
||||
export type IntegrationOAuthAuthorization = {
|
||||
readonly url: string
|
||||
@@ -44,12 +45,12 @@ export type IntegrationMethodRegistration =
|
||||
}
|
||||
|
||||
export interface IntegrationDraft {
|
||||
list(): readonly IntegrationRef[]
|
||||
get(id: string): IntegrationRef | undefined
|
||||
list(): readonly ReadonlyDeep<IntegrationRef>[]
|
||||
get(id: string): ReadonlyDeep<IntegrationRef> | undefined
|
||||
update(id: string, update: (integration: IntegrationRef) => void): void
|
||||
remove(id: string): void
|
||||
readonly method: {
|
||||
list(integrationID: string): readonly IntegrationMethod[]
|
||||
list(integrationID: string): readonly ReadonlyDeep<IntegrationMethod>[]
|
||||
update(input: IntegrationMethodRegistration): void
|
||||
remove(integrationID: string, method: IntegrationMethod): void
|
||||
}
|
||||
|
||||
@@ -1 +1,11 @@
|
||||
export type PluginOptions = Readonly<Record<string, any>>
|
||||
|
||||
export type ReadonlyDeep<T> = T extends (...args: any[]) => any
|
||||
? T
|
||||
: T extends ReadonlyMap<infer K, infer V>
|
||||
? ReadonlyMap<ReadonlyDeep<K>, ReadonlyDeep<V>>
|
||||
: T extends readonly (infer U)[]
|
||||
? readonly ReadonlyDeep<U>[]
|
||||
: T extends object
|
||||
? { readonly [K in keyof T]: ReadonlyDeep<T[K]> }
|
||||
: T
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import type { LanguageModelV3 } from "@ai-sdk/provider"
|
||||
import type { ModelV2Info } from "@opencode-ai/sdk/v2/types"
|
||||
import type { ReadonlyDeep } from "../options.js"
|
||||
import type { Hooks } from "./registration.js"
|
||||
|
||||
export type AISDKHooks = Hooks<{
|
||||
sdk: {
|
||||
readonly model: ModelV2Info
|
||||
readonly model: ReadonlyDeep<ModelV2Info>
|
||||
readonly package: string
|
||||
readonly options: Record<string, any>
|
||||
sdk?: any
|
||||
}
|
||||
language: {
|
||||
readonly model: ModelV2Info
|
||||
readonly model: ReadonlyDeep<ModelV2Info>
|
||||
readonly sdk: any
|
||||
readonly options: Record<string, any>
|
||||
language?: LanguageModelV3
|
||||
|
||||
@@ -3,7 +3,7 @@ import { SessionInput } from "@opencode-ai/schema/session-input"
|
||||
import { Prompt } from "@opencode-ai/schema/prompt"
|
||||
import { Session } from "@opencode-ai/schema/session"
|
||||
import { Project } from "@opencode-ai/schema/project"
|
||||
import { AbsolutePath, PositiveInt, RelativePath, withStatics } from "@opencode-ai/schema/schema"
|
||||
import { AbsolutePath, PositiveInt, RelativePath, statics } from "@opencode-ai/schema/schema"
|
||||
import { Workspace } from "@opencode-ai/schema/workspace"
|
||||
import { Context, Encoding, Result, Schema, Struct } from "effect"
|
||||
import { HttpApiEndpoint, HttpApiGroup, HttpApiMiddleware, HttpApiSchema, OpenApi } from "effect/unstable/httpapi"
|
||||
@@ -62,7 +62,7 @@ const decodeSessionsCursor = Schema.decodeUnknownEffect(SessionsCursorJson)
|
||||
|
||||
export const SessionsCursor = Schema.String.pipe(
|
||||
Schema.brand("SessionsCursor"),
|
||||
withStatics((schema) => {
|
||||
statics((schema) => {
|
||||
const make = schema.make.bind(schema)
|
||||
return {
|
||||
make: (input: typeof SessionsCursorInput.Type) => make(Encoding.encodeBase64Url(encodeSessionsCursor(input))),
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
# Schema Package Guide
|
||||
|
||||
`@opencode-ai/schema` owns browser-safe wire and storage contracts shared by protocol, server, core, and generated SDKs. Keep runtime behavior, service layers, side effects, and host-local implementation details in the domain package that owns them.
|
||||
|
||||
## Package Boundary
|
||||
|
||||
- Preserve the dependency direction: `@opencode-ai/schema <- @opencode-ai/protocol <- @opencode-ai/server`.
|
||||
- Schema values should be serializable contract definitions, not service implementations or runtime registries.
|
||||
- A domain may keep a minimal public wire contract here when SDK generation needs it, but do not move the broader runtime model into Schema just because an event is public. `plugin.added` is the current example: Schema may own the minimum browser-safe event payload, while plugin runtime behavior stays outside Schema.
|
||||
- The root barrel exports canonical current domain contracts. Specialized event modules, manifests, infrastructure modules, and V1 contracts use direct entrypoints instead of becoming first-class root exports.
|
||||
|
||||
## Current Versus V1
|
||||
|
||||
- Current contracts are unversioned: use names like `Session`, `Permission`, `Question`, and identifiers like `Permission.Request`.
|
||||
- Legacy contracts retained for active compatibility, persistence, or migration are explicitly `V1`: use names like `SessionV1`, `PermissionV1`, and identifiers like `PermissionV1.Request`.
|
||||
- Do not preserve `V2` as the permanent name for the replacement architecture. Remove `V2` from current namespaces, brands, and identifiers as the contracts are normalized.
|
||||
- Retained V1 contracts should live under a dedicated `src/v1/` subtree once the V1 isolation PR runs. New/current code must not depend on that subtree.
|
||||
- V1 coexistence is temporary. Keep compatibility entrypoints only where migration requires them, and delete the V1 subtree when the legacy runtime is retired.
|
||||
- `@opencode-ai/protocol` and `@opencode-ai/sdk-next` are current `/api/...` surfaces.
|
||||
|
||||
## Events
|
||||
|
||||
- Classify event definitions by protocol role before adding them to a public manifest: `current`, `shared transitional`, or `V1-only`.
|
||||
- Being emitted by V1 is not enough to include an event in Protocol or SDK Next.
|
||||
- Keep clearly V1-only events, such as `message.updated` and `message.part.*`, out of the current Protocol/SDK Next event surface unless a current-client requirement is documented.
|
||||
- Keep compatibility events available only to the existing App/TUI/CLI compatibility surface while they are still needed.
|
||||
- Preserve a single canonical event definition. Do not duplicate definitions for generation convenience.
|
||||
|
||||
## Module Shape
|
||||
|
||||
- Use one canonical exported value for each contract. Avoid bridge aliases such as `PluginID`, `PluginEvent`, `PtyInfo`, `PtyEvent`, and `SessionTodoInfo`.
|
||||
- Prefer importing the schema module namespace and reading canonical members, for example `Plugin.ID` or `SessionTodo.Info`.
|
||||
- Core may compose Schema contracts with runtime behavior into a deliberate domain facade, but the facade must re-export the exact canonical Schema value. Do not create a second schema identity.
|
||||
- Use flat top-level exports plus the package's existing namespace projection pattern, for example `export * as SessionMessage from "./session-message"`.
|
||||
- Keep standalone ID modules only when they prevent real cycles or heavy dependency edges. Inline one-off IDs into their owning contract module when no cycle exists.
|
||||
|
||||
## Naming
|
||||
|
||||
- Exported schema values and namespace objects use `PascalCase`.
|
||||
- Schema-building functions and combinators use `camelCase`.
|
||||
- The package's static-method combinator is `statics(...)`.
|
||||
- Keep descriptive schema value names such as `PositiveInt`, `NonNegativeInt`, `AbsolutePath`, `RelativePath`, and `DateTimeUtcFromMillis`.
|
||||
|
||||
## Optional Fields And Defaults
|
||||
|
||||
- Use the package `optional(...)` helper for optional object properties, including nested structs and event payloads, so encoded objects omit `undefined` keys.
|
||||
- Use raw `Schema.optional(...)` only when preserving `undefined` as an explicitly encoded property is intentional and documented.
|
||||
- External convenience defaults are normally decode-only with `Schema.withDecodingDefault(...)`.
|
||||
- Add constructor defaults only when the domain value itself requires construction-time normalization.
|
||||
|
||||
## Public Types
|
||||
|
||||
- Public `Schema.Struct` records use same-name interfaces:
|
||||
|
||||
```ts
|
||||
export interface Info extends Schema.Schema.Type<typeof Info> {}
|
||||
export const Info = Schema.Struct({ ... })
|
||||
```
|
||||
|
||||
- Use type aliases for unions, scalars, arrays, branded scalar types, and event payload helper types.
|
||||
- Closed documented string sets use `Schema.Literals(...)`. If arbitrary strings are valid, document the field as arbitrary rather than listing a closed set.
|
||||
|
||||
## Mutability
|
||||
|
||||
- Public Schema contracts are readonly by default.
|
||||
- Do not use `Schema.mutable(...)` in public contracts for runtime convenience.
|
||||
- Runtime code that needs mutation should opt in at the boundary with `Types.DeepMutable`, a purpose-built draft type, or another explicit mutable API.
|
||||
|
||||
## Unknown Values
|
||||
|
||||
- Current public contracts avoid `Schema.Any`.
|
||||
- Use `Schema.Json` for values that must be JSON-serializable.
|
||||
- Use `Schema.Unknown` for genuinely opaque values that require consumer-side narrowing.
|
||||
- Keep `Schema.Any` only at an explicitly unsafe compatibility boundary with a documented reason.
|
||||
|
||||
## IDs And Identifiers
|
||||
|
||||
- Current ID constructors expose `create()`.
|
||||
- Directional constructors such as `ascending()` or `descending()` remain only where ordering semantics are part of the public contract or compatibility requires the old method.
|
||||
- New generated ID schemas must validate exactly the prefix they emit, including the underscore.
|
||||
- Do not tighten legacy loose ID validators without an explicit compatibility and migration decision; existing callers and tests may rely on accepted non-canonical IDs.
|
||||
- Reusable exported public schemas get stable, domain-qualified identifiers such as `Model.Ref` or `Agent.Color`.
|
||||
- Public schema identifiers and brands must be unique and stable. Private one-use nested schemas may remain anonymous.
|
||||
|
||||
## Tests For Contract Changes
|
||||
|
||||
- Add focused tests when changing contract behavior or generated surface.
|
||||
- Cover optional properties omitting `undefined`, no accidental current-contract `Schema.Any`, stable and unique public identifiers, exact facade/schema identity, and current Protocol manifests excluding V1-only events.
|
||||
@@ -1,10 +1,11 @@
|
||||
export * as Agent from "./agent"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { Model } from "./model"
|
||||
import { Permission } from "./permission"
|
||||
import { Provider } from "./provider"
|
||||
import { PositiveInt, withStatics } from "./schema"
|
||||
import { PositiveInt, statics } from "./schema"
|
||||
|
||||
export const ID = Schema.String.pipe(Schema.brand("AgentV2.ID"))
|
||||
export type ID = typeof ID.Type
|
||||
@@ -12,25 +13,25 @@ export type ID = typeof ID.Type
|
||||
export const Color = Schema.Union([
|
||||
Schema.String.check(Schema.isPattern(/^#[0-9a-fA-F]{6}$/)),
|
||||
Schema.Literals(["primary", "secondary", "accent", "success", "warning", "error", "info"]),
|
||||
])
|
||||
]).annotate({ identifier: "Agent.Color" })
|
||||
export type Color = typeof Color.Type
|
||||
|
||||
export interface Info extends Schema.Schema.Type<typeof Info> {}
|
||||
export const Info = Schema.Struct({
|
||||
id: ID,
|
||||
model: Model.Ref.pipe(Schema.optional),
|
||||
model: Model.Ref.pipe(optional),
|
||||
request: Provider.Request,
|
||||
system: Schema.String.pipe(Schema.optional),
|
||||
description: Schema.String.pipe(Schema.optional),
|
||||
system: Schema.String.pipe(optional),
|
||||
description: Schema.String.pipe(optional),
|
||||
mode: Schema.Literals(["subagent", "primary", "all"]),
|
||||
hidden: Schema.Boolean,
|
||||
color: Color.pipe(Schema.optional),
|
||||
steps: PositiveInt.pipe(Schema.optional),
|
||||
color: Color.pipe(optional),
|
||||
steps: PositiveInt.pipe(optional),
|
||||
permissions: Permission.Ruleset,
|
||||
})
|
||||
.annotate({ identifier: "AgentV2.Info" })
|
||||
.pipe(
|
||||
withStatics((schema) => ({
|
||||
statics((schema) => ({
|
||||
empty: (id: ID) =>
|
||||
schema.make({ id, request: { headers: {}, body: {} }, mode: "all", hidden: false, permissions: [] }),
|
||||
})),
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
export * as Command from "./command"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { Model } from "./model"
|
||||
|
||||
export interface Info extends Schema.Schema.Type<typeof Info> {}
|
||||
export const Info = Schema.Struct({
|
||||
name: Schema.String,
|
||||
template: Schema.String,
|
||||
description: Schema.String.pipe(Schema.optional),
|
||||
agent: Schema.String.pipe(Schema.optional),
|
||||
model: Model.Ref.pipe(Schema.optional),
|
||||
subtask: Schema.Boolean.pipe(Schema.optional),
|
||||
description: Schema.String.pipe(optional),
|
||||
agent: Schema.String.pipe(optional),
|
||||
model: Model.Ref.pipe(optional),
|
||||
subtask: Schema.Boolean.pipe(optional),
|
||||
}).annotate({ identifier: "CommandV2.Info" })
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
export * as Credential from "./credential"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { IntegrationMethodID } from "./integration-id"
|
||||
import { ascending } from "./identifier"
|
||||
import { NonNegativeInt, withStatics } from "./schema"
|
||||
import { NonNegativeInt, statics } from "./schema"
|
||||
|
||||
export const ID = Schema.String.pipe(
|
||||
Schema.brand("Credential.ID"),
|
||||
withStatics((schema) => ({ create: () => schema.make("cred_" + ascending()) })),
|
||||
statics((schema) => ({ create: () => schema.make("cred_" + ascending()) })),
|
||||
)
|
||||
export type ID = typeof ID.Type
|
||||
|
||||
@@ -18,14 +19,14 @@ export const OAuth = Schema.Struct({
|
||||
refresh: Schema.String,
|
||||
access: Schema.String,
|
||||
expires: NonNegativeInt,
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
metadata: optional(Schema.Record(Schema.String, Schema.Unknown)),
|
||||
}).annotate({ identifier: "Credential.OAuth" })
|
||||
|
||||
export interface Key extends Schema.Schema.Type<typeof Key> {}
|
||||
export const Key = Schema.Struct({
|
||||
type: Schema.Literal("key"),
|
||||
key: Schema.String,
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
metadata: optional(Schema.Record(Schema.String, Schema.Unknown)),
|
||||
}).annotate({ identifier: "Credential.Key" })
|
||||
|
||||
export const Value = Schema.Union([OAuth, Key])
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
export * as Event from "./event"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { ascending } from "./identifier"
|
||||
import { Location } from "./location"
|
||||
import { withStatics } from "./schema"
|
||||
import { statics } from "./schema"
|
||||
|
||||
export const ID = Schema.String.check(Schema.isStartsWith("evt_")).pipe(
|
||||
Schema.brand("Event.ID"),
|
||||
withStatics((schema) => ({ create: () => schema.make("evt_" + ascending()) })),
|
||||
statics((schema) => ({ create: () => schema.make("evt_" + ascending()) })),
|
||||
)
|
||||
export type ID = typeof ID.Type
|
||||
|
||||
@@ -53,12 +54,10 @@ export function define<
|
||||
return Object.assign(
|
||||
Schema.Struct({
|
||||
id: ID,
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)),
|
||||
metadata: optional(Schema.Record(Schema.String, Schema.Unknown)),
|
||||
type: Schema.Literal(input.type),
|
||||
durable: Schema.optional(
|
||||
Schema.Struct({ aggregateID: Schema.String, seq: Schema.Number, version: Schema.Number }),
|
||||
),
|
||||
location: Schema.optional(Location.Ref),
|
||||
durable: optional(Schema.Struct({ aggregateID: Schema.String, seq: Schema.Number, version: Schema.Number })),
|
||||
location: optional(Location.Ref),
|
||||
data,
|
||||
}).annotate({ identifier: input.type }),
|
||||
{
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
export * as FileDiff from "./file-diff"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
|
||||
export const Info = Schema.Struct({
|
||||
file: Schema.optional(Schema.String),
|
||||
patch: Schema.optional(Schema.String),
|
||||
file: optional(Schema.String),
|
||||
patch: optional(Schema.String),
|
||||
additions: Schema.Finite,
|
||||
deletions: Schema.Finite,
|
||||
status: Schema.optional(Schema.Literals(["added", "deleted", "modified"])),
|
||||
status: optional(Schema.Literals(["added", "deleted", "modified"])),
|
||||
}).annotate({ identifier: "SnapshotFileDiff" })
|
||||
export type Info = typeof Info.Type
|
||||
export interface Info extends Schema.Schema.Type<typeof Info> {}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export * as FileSystem from "./filesystem"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { define, inventory } from "./event"
|
||||
import { NonNegativeInt, PositiveInt, RelativePath } from "./schema"
|
||||
|
||||
@@ -21,7 +22,7 @@ export const Submatch = Schema.Struct({
|
||||
text: Schema.String,
|
||||
start: NonNegativeInt,
|
||||
end: NonNegativeInt,
|
||||
})
|
||||
}).annotate({ identifier: "FileSystem.Submatch" })
|
||||
|
||||
export interface Match extends Schema.Schema.Type<typeof Match> {}
|
||||
export const Match = Schema.Struct({
|
||||
@@ -34,6 +35,6 @@ export const Match = Schema.Struct({
|
||||
|
||||
export class FindInput extends Schema.Class<FindInput>("FileSystem.FindInput")({
|
||||
query: Schema.String,
|
||||
type: Schema.Literals(["file", "directory"]).pipe(Schema.optional),
|
||||
limit: PositiveInt.pipe(Schema.optional),
|
||||
type: Schema.Literals(["file", "directory"]).pipe(optional),
|
||||
limit: PositiveInt.pipe(optional),
|
||||
}) {}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
export * as Integration from "./integration"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { define, inventory } from "./event"
|
||||
import { Connection } from "./connection"
|
||||
import { ascending } from "./identifier"
|
||||
import { withStatics } from "./schema"
|
||||
import { statics } from "./schema"
|
||||
import { IntegrationID, IntegrationMethodID } from "./integration-id"
|
||||
|
||||
export const ID = IntegrationID
|
||||
@@ -25,8 +26,8 @@ export const TextPrompt = Schema.Struct({
|
||||
type: Schema.Literal("text"),
|
||||
key: Schema.String,
|
||||
message: Schema.String,
|
||||
placeholder: Schema.optional(Schema.String),
|
||||
when: Schema.optional(When),
|
||||
placeholder: optional(Schema.String),
|
||||
when: optional(When),
|
||||
}).annotate({ identifier: "Integration.TextPrompt" })
|
||||
|
||||
export interface SelectPrompt extends Schema.Schema.Type<typeof SelectPrompt> {}
|
||||
@@ -34,16 +35,14 @@ export const SelectPrompt = Schema.Struct({
|
||||
type: Schema.Literal("select"),
|
||||
key: Schema.String,
|
||||
message: Schema.String,
|
||||
options: Schema.mutable(
|
||||
Schema.Array(
|
||||
Schema.Struct({
|
||||
label: Schema.String,
|
||||
value: Schema.String,
|
||||
hint: Schema.optional(Schema.String),
|
||||
}),
|
||||
),
|
||||
options: Schema.Array(
|
||||
Schema.Struct({
|
||||
label: Schema.String,
|
||||
value: Schema.String,
|
||||
hint: optional(Schema.String),
|
||||
}),
|
||||
),
|
||||
when: Schema.optional(When),
|
||||
when: optional(When),
|
||||
}).annotate({ identifier: "Integration.SelectPrompt" })
|
||||
|
||||
export const Prompt = Schema.Union([TextPrompt, SelectPrompt]).pipe(Schema.toTaggedUnion("type"))
|
||||
@@ -54,19 +53,19 @@ export const OAuthMethod = Schema.Struct({
|
||||
id: MethodID,
|
||||
type: Schema.Literal("oauth"),
|
||||
label: Schema.String,
|
||||
prompts: Schema.optional(Schema.mutable(Schema.Array(Prompt))),
|
||||
prompts: optional(Schema.Array(Prompt)),
|
||||
}).annotate({ identifier: "Integration.OAuthMethod" })
|
||||
|
||||
export interface KeyMethod extends Schema.Schema.Type<typeof KeyMethod> {}
|
||||
export const KeyMethod = Schema.Struct({
|
||||
type: Schema.Literal("key"),
|
||||
label: Schema.optional(Schema.String),
|
||||
label: optional(Schema.String),
|
||||
}).annotate({ identifier: "Integration.KeyMethod" })
|
||||
|
||||
export interface EnvMethod extends Schema.Schema.Type<typeof EnvMethod> {}
|
||||
export const EnvMethod = Schema.Struct({
|
||||
type: Schema.Literal("env"),
|
||||
names: Schema.mutable(Schema.Array(Schema.String)),
|
||||
names: Schema.Array(Schema.String),
|
||||
}).annotate({ identifier: "Integration.EnvMethod" })
|
||||
|
||||
export const Method = Schema.Union([OAuthMethod, KeyMethod, EnvMethod])
|
||||
@@ -96,13 +95,13 @@ export const Ref = Schema.Struct({
|
||||
export class Info extends Schema.Class<Info>("Integration.Info")({
|
||||
id: ID,
|
||||
name: Schema.String,
|
||||
methods: Schema.mutable(Schema.Array(Method)),
|
||||
connections: Schema.mutable(Schema.Array(Connection.Info)),
|
||||
methods: Schema.Array(Method),
|
||||
connections: Schema.Array(Connection.Info),
|
||||
}) {}
|
||||
|
||||
export const AttemptID = Schema.String.pipe(
|
||||
Schema.brand("Integration.AttemptID"),
|
||||
withStatics((schema) => ({ create: () => schema.make("con_" + ascending()) })),
|
||||
statics((schema) => ({ create: () => schema.make("con_" + ascending()) })),
|
||||
)
|
||||
export type AttemptID = typeof AttemptID.Type
|
||||
|
||||
@@ -124,5 +123,7 @@ export const AttemptStatus = Schema.Union([
|
||||
Schema.Struct({ status: Schema.Literal("complete"), time: AttemptTime }),
|
||||
Schema.Struct({ status: Schema.Literal("failed"), message: Schema.String, time: AttemptTime }),
|
||||
Schema.Struct({ status: Schema.Literal("expired"), time: AttemptTime }),
|
||||
]).pipe(Schema.toTaggedUnion("status"))
|
||||
])
|
||||
.pipe(Schema.toTaggedUnion("status"))
|
||||
.annotate({ identifier: "Integration.AttemptStatus" })
|
||||
export type AttemptStatus = typeof AttemptStatus.Type
|
||||
|
||||
@@ -1,18 +1 @@
|
||||
export * as LegacyEvent from "./legacy-event"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { define, inventory } from "./event"
|
||||
import { SessionID } from "./session-id"
|
||||
import { SessionV1 } from "./session-v1"
|
||||
|
||||
export const CommandExecuted = define({
|
||||
type: "command.executed",
|
||||
schema: {
|
||||
name: Schema.String,
|
||||
sessionID: SessionID,
|
||||
arguments: Schema.String,
|
||||
messageID: SessionV1.MessageID,
|
||||
},
|
||||
})
|
||||
|
||||
export const Definitions = inventory(CommandExecuted)
|
||||
export * from "./v1/legacy-event"
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
export * as LLM from "./llm"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
|
||||
export const ProviderMetadata = Schema.Record(Schema.String, Schema.Record(Schema.String, Schema.Unknown))
|
||||
export const ProviderMetadata = Schema.Record(Schema.String, Schema.Record(Schema.String, Schema.Unknown)).annotate({
|
||||
identifier: "LLM.ProviderMetadata",
|
||||
})
|
||||
export type ProviderMetadata = Schema.Schema.Type<typeof ProviderMetadata>
|
||||
|
||||
export interface ToolTextContent extends Schema.Schema.Type<typeof ToolTextContent> {}
|
||||
@@ -16,8 +19,10 @@ export const ToolFileContent = Schema.Struct({
|
||||
type: Schema.Literal("file"),
|
||||
uri: Schema.String,
|
||||
mime: Schema.String,
|
||||
name: Schema.optional(Schema.String),
|
||||
name: optional(Schema.String),
|
||||
}).annotate({ identifier: "Tool.FileContent" })
|
||||
|
||||
export const ToolContent = Schema.Union([ToolTextContent, ToolFileContent]).pipe(Schema.toTaggedUnion("type"))
|
||||
export const ToolContent = Schema.Union([ToolTextContent, ToolFileContent])
|
||||
.pipe(Schema.toTaggedUnion("type"))
|
||||
.annotate({ identifier: "LLM.ToolContent" })
|
||||
export type ToolContent = Schema.Schema.Type<typeof ToolContent>
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
export * as Location from "./location"
|
||||
|
||||
import { Effect, Schema } from "effect"
|
||||
import { AbsolutePath, optionalOmitUndefined } from "./schema"
|
||||
import { Schema } from "effect"
|
||||
import { AbsolutePath, optional } from "./schema"
|
||||
import { ProjectID } from "./project-id"
|
||||
import { WorkspaceID } from "./workspace-id"
|
||||
|
||||
export interface Ref extends Schema.Schema.Type<typeof Ref> {}
|
||||
export const Ref = Schema.Struct({
|
||||
directory: AbsolutePath,
|
||||
workspaceID: Schema.optional(WorkspaceID).pipe(
|
||||
Schema.withDecodingDefault(Effect.succeed(undefined)),
|
||||
Schema.withConstructorDefault(Effect.succeed(undefined)),
|
||||
),
|
||||
workspaceID: optional(WorkspaceID),
|
||||
}).annotate({ identifier: "Location.Ref" })
|
||||
|
||||
export class Info extends Schema.Class<Info>("Location.Info")({
|
||||
directory: AbsolutePath,
|
||||
workspaceID: optionalOmitUndefined(WorkspaceID),
|
||||
workspaceID: optional(WorkspaceID),
|
||||
project: Schema.Struct({
|
||||
id: ProjectID,
|
||||
directory: AbsolutePath,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
export * as Model from "./model"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { Provider } from "./provider"
|
||||
import { withStatics } from "./schema"
|
||||
import { statics } from "./schema"
|
||||
|
||||
export const ID = Schema.String.pipe(Schema.brand("ModelV2.ID"))
|
||||
export type ID = typeof ID.Type
|
||||
@@ -13,9 +14,9 @@ export type VariantID = typeof VariantID.Type
|
||||
export const Ref = Schema.Struct({
|
||||
id: ID,
|
||||
providerID: Provider.ID,
|
||||
variant: VariantID.pipe(Schema.optional),
|
||||
})
|
||||
export type Ref = typeof Ref.Type
|
||||
variant: VariantID.pipe(optional),
|
||||
}).annotate({ identifier: "Model.Ref" })
|
||||
export interface Ref extends Schema.Schema.Type<typeof Ref> {}
|
||||
|
||||
export const Family = Schema.String.pipe(Schema.brand("Family"))
|
||||
export type Family = typeof Family.Type
|
||||
@@ -23,23 +24,23 @@ export type Family = typeof Family.Type
|
||||
export interface Capabilities extends Schema.Schema.Type<typeof Capabilities> {}
|
||||
export const Capabilities = Schema.Struct({
|
||||
tools: Schema.Boolean,
|
||||
input: Schema.String.pipe(Schema.Array, Schema.mutable),
|
||||
output: Schema.String.pipe(Schema.Array, Schema.mutable),
|
||||
})
|
||||
input: Schema.Array(Schema.String),
|
||||
output: Schema.Array(Schema.String),
|
||||
}).annotate({ identifier: "Model.Capabilities" })
|
||||
|
||||
export interface Cost extends Schema.Schema.Type<typeof Cost> {}
|
||||
export const Cost = Schema.Struct({
|
||||
tier: Schema.Struct({
|
||||
type: Schema.Literal("context"),
|
||||
size: Schema.Int,
|
||||
}).pipe(Schema.optional),
|
||||
}).pipe(optional),
|
||||
input: Schema.Finite,
|
||||
output: Schema.Finite,
|
||||
cache: Schema.Struct({
|
||||
read: Schema.Finite,
|
||||
write: Schema.Finite,
|
||||
}),
|
||||
})
|
||||
}).annotate({ identifier: "Model.Cost" })
|
||||
|
||||
export const Api = Schema.Union([
|
||||
Schema.Struct({
|
||||
@@ -50,40 +51,42 @@ export const Api = Schema.Union([
|
||||
id: ID,
|
||||
...Provider.Native.fields,
|
||||
}),
|
||||
]).pipe(Schema.toTaggedUnion("type"))
|
||||
])
|
||||
.pipe(Schema.toTaggedUnion("type"))
|
||||
.annotate({ identifier: "Model.Api" })
|
||||
export type Api = typeof Api.Type
|
||||
|
||||
export interface Info extends Schema.Schema.Type<typeof Info> {}
|
||||
export const Info = Schema.Struct({
|
||||
id: ID,
|
||||
providerID: Provider.ID,
|
||||
family: Family.pipe(Schema.optional),
|
||||
family: Family.pipe(optional),
|
||||
name: Schema.String,
|
||||
api: Api,
|
||||
capabilities: Capabilities,
|
||||
request: Schema.Struct({
|
||||
...Provider.Request.fields,
|
||||
variant: Schema.String.pipe(Schema.optional),
|
||||
variant: Schema.String.pipe(optional),
|
||||
}),
|
||||
variants: Schema.Struct({
|
||||
id: VariantID,
|
||||
...Provider.Request.fields,
|
||||
}).pipe(Schema.Array, Schema.mutable),
|
||||
}).pipe(Schema.Array),
|
||||
time: Schema.Struct({
|
||||
released: Schema.Finite,
|
||||
}),
|
||||
cost: Cost.pipe(Schema.Array, Schema.mutable),
|
||||
cost: Schema.Array(Cost),
|
||||
status: Schema.Literals(["alpha", "beta", "deprecated", "active"]),
|
||||
enabled: Schema.Boolean,
|
||||
limit: Schema.Struct({
|
||||
context: Schema.Int,
|
||||
input: Schema.Int.pipe(Schema.optional),
|
||||
input: Schema.Int.pipe(optional),
|
||||
output: Schema.Int,
|
||||
}),
|
||||
})
|
||||
.annotate({ identifier: "ModelV2.Info" })
|
||||
.pipe(
|
||||
withStatics((schema) => ({
|
||||
statics((schema) => ({
|
||||
empty: (providerID: Provider.ID, modelID: ID) =>
|
||||
schema.make({
|
||||
id: modelID,
|
||||
|
||||
@@ -3,11 +3,11 @@ export * as PermissionSaved from "./permission-saved"
|
||||
import { Schema } from "effect"
|
||||
import { ascending } from "./identifier"
|
||||
import { ProjectID } from "./project-id"
|
||||
import { withStatics } from "./schema"
|
||||
import { statics } from "./schema"
|
||||
|
||||
export const ID = Schema.String.pipe(
|
||||
Schema.brand("PermissionSaved.ID"),
|
||||
withStatics((schema) => ({ create: () => schema.make("psv_" + ascending()) })),
|
||||
statics((schema) => ({ create: () => schema.make("psv_" + ascending()) })),
|
||||
)
|
||||
export type ID = typeof ID.Type
|
||||
|
||||
@@ -17,4 +17,4 @@ export const Info = Schema.Struct({
|
||||
action: Schema.String,
|
||||
resource: Schema.String,
|
||||
}).annotate({ identifier: "PermissionSaved.Info" })
|
||||
export type Info = typeof Info.Type
|
||||
export interface Info extends Schema.Schema.Type<typeof Info> {}
|
||||
|
||||
@@ -1,67 +1 @@
|
||||
export * as PermissionV1 from "./permission-v1"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { define, inventory } from "./event"
|
||||
import { ascending } from "./identifier"
|
||||
import { Project } from "./project"
|
||||
import { withStatics } from "./schema"
|
||||
import { SessionID } from "./session-id"
|
||||
|
||||
export const ID = Schema.String.check(Schema.isStartsWith("per")).pipe(
|
||||
Schema.brand("PermissionID"),
|
||||
withStatics((schema) => ({ ascending: (id?: string) => schema.make(id ?? "per_" + ascending()) })),
|
||||
)
|
||||
export type ID = typeof ID.Type
|
||||
|
||||
export const Action = Schema.Literals(["allow", "deny", "ask"]).annotate({ identifier: "PermissionAction" })
|
||||
export type Action = typeof Action.Type
|
||||
|
||||
export const Rule = Schema.Struct({ permission: Schema.String, pattern: Schema.String, action: Action }).annotate({
|
||||
identifier: "PermissionRule",
|
||||
})
|
||||
export type Rule = typeof Rule.Type
|
||||
|
||||
export const Ruleset = Schema.Array(Rule).annotate({ identifier: "PermissionRuleset" })
|
||||
export type Ruleset = typeof Ruleset.Type
|
||||
|
||||
export const Request = Schema.Struct({
|
||||
id: ID,
|
||||
sessionID: SessionID,
|
||||
permission: Schema.String,
|
||||
patterns: Schema.Array(Schema.String),
|
||||
metadata: Schema.Record(Schema.String, Schema.Unknown),
|
||||
always: Schema.Array(Schema.String),
|
||||
tool: Schema.optional(Schema.Struct({ messageID: Schema.String, callID: Schema.String })),
|
||||
}).annotate({ identifier: "PermissionRequest" })
|
||||
export type Request = typeof Request.Type
|
||||
|
||||
export const Reply = Schema.Literals(["once", "always", "reject"])
|
||||
export type Reply = typeof Reply.Type
|
||||
|
||||
export const ReplyBody = Schema.Struct({ reply: Reply, message: Schema.optional(Schema.String) }).annotate({
|
||||
identifier: "PermissionReplyBody",
|
||||
})
|
||||
export type ReplyBody = typeof ReplyBody.Type
|
||||
|
||||
export const Approval = Schema.Struct({ projectID: Project.ID, patterns: Schema.Array(Schema.String) }).annotate({
|
||||
identifier: "PermissionApproval",
|
||||
})
|
||||
export type Approval = typeof Approval.Type
|
||||
|
||||
export const AskInput = Schema.Struct({ ...Request.fields, id: Schema.optional(ID), ruleset: Ruleset }).annotate({
|
||||
identifier: "PermissionAskInput",
|
||||
})
|
||||
export type AskInput = typeof AskInput.Type
|
||||
|
||||
export const ReplyInput = Schema.Struct({ requestID: ID, ...ReplyBody.fields }).annotate({
|
||||
identifier: "PermissionReplyInput",
|
||||
})
|
||||
export type ReplyInput = typeof ReplyInput.Type
|
||||
|
||||
const Asked = define({ type: "permission.asked", schema: Request.fields })
|
||||
const Replied = define({
|
||||
type: "permission.replied",
|
||||
schema: { sessionID: SessionID, requestID: ID, reply: Reply },
|
||||
})
|
||||
export const Event = { Asked, Replied, Definitions: inventory(Asked, Replied) }
|
||||
export const PermissionV1Event = Event
|
||||
export * from "./v1/permission"
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
export * as Permission from "./permission"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { define, inventory } from "./event"
|
||||
import { ascending } from "./identifier"
|
||||
import { SessionID } from "./session-id"
|
||||
import { withStatics } from "./schema"
|
||||
import { statics } from "./schema"
|
||||
|
||||
export const ID = Schema.String.check(Schema.isStartsWith("per")).pipe(
|
||||
Schema.brand("PermissionV2.ID"),
|
||||
withStatics((schema) => ({ create: (id?: string) => schema.make(id ?? "per_" + ascending()) })),
|
||||
statics((schema) => ({ create: (id?: string) => schema.make(id ?? "per_" + ascending()) })),
|
||||
)
|
||||
export type ID = typeof ID.Type
|
||||
|
||||
@@ -25,16 +26,16 @@ const RequestFields = {
|
||||
sessionID: SessionID,
|
||||
action: Schema.String,
|
||||
resources: Schema.Array(Schema.String),
|
||||
save: Schema.Array(Schema.String).pipe(Schema.optional),
|
||||
metadata: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
|
||||
source: Source.pipe(Schema.optional),
|
||||
save: Schema.Array(Schema.String).pipe(optional),
|
||||
metadata: Schema.Record(Schema.String, Schema.Unknown).pipe(optional),
|
||||
source: Source.pipe(optional),
|
||||
}
|
||||
|
||||
export const Request = Schema.Struct({
|
||||
id: ID,
|
||||
...RequestFields,
|
||||
}).annotate({ identifier: "PermissionV2.Request" })
|
||||
export type Request = typeof Request.Type
|
||||
export interface Request extends Schema.Schema.Type<typeof Request> {}
|
||||
|
||||
export const Reply = Schema.Literals(["once", "always", "reject"]).annotate({ identifier: "PermissionV2.Reply" })
|
||||
export type Reply = typeof Reply.Type
|
||||
@@ -60,5 +61,5 @@ export const Rule = Schema.Struct({
|
||||
effect: Effect,
|
||||
}).annotate({ identifier: "PermissionV2.Rule" })
|
||||
|
||||
export const Ruleset = Schema.mutable(Schema.Array(Rule)).annotate({ identifier: "PermissionV2.Ruleset" })
|
||||
export const Ruleset = Schema.Array(Rule).annotate({ identifier: "PermissionV2.Ruleset" })
|
||||
export type Ruleset = typeof Ruleset.Type
|
||||
|
||||
@@ -5,11 +5,9 @@ import { define, inventory } from "./event"
|
||||
|
||||
export const ID = Schema.String.pipe(Schema.brand("Plugin.ID"))
|
||||
export type ID = typeof ID.Type
|
||||
export const PluginID = ID
|
||||
|
||||
const Added = define({
|
||||
type: "plugin.added",
|
||||
schema: { id: ID },
|
||||
})
|
||||
export const Event = { Added, Definitions: inventory(Added) }
|
||||
export const PluginEvent = Event
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export * as ProjectCopy from "./project-copy"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { ProjectID } from "./project-id"
|
||||
import { AbsolutePath } from "./schema"
|
||||
|
||||
@@ -12,18 +13,18 @@ export const CreateInput = Schema.Struct({
|
||||
strategy: StrategyID,
|
||||
sourceDirectory: AbsolutePath,
|
||||
directory: AbsolutePath,
|
||||
name: Schema.optional(Schema.String),
|
||||
name: optional(Schema.String),
|
||||
}).annotate({ identifier: "ProjectCopy.CreateInput" })
|
||||
export type CreateInput = typeof CreateInput.Type
|
||||
export interface CreateInput extends Schema.Schema.Type<typeof CreateInput> {}
|
||||
|
||||
export const RemoveInput = Schema.Struct({
|
||||
projectID: ProjectID,
|
||||
directory: AbsolutePath,
|
||||
force: Schema.Boolean,
|
||||
}).annotate({ identifier: "ProjectCopy.RemoveInput" })
|
||||
export type RemoveInput = typeof RemoveInput.Type
|
||||
export interface RemoveInput extends Schema.Schema.Type<typeof RemoveInput> {}
|
||||
|
||||
export const Copy = Schema.Struct({
|
||||
directory: AbsolutePath,
|
||||
}).annotate({ identifier: "ProjectCopy.Copy" })
|
||||
export type Copy = typeof Copy.Type
|
||||
export interface Copy extends Schema.Schema.Type<typeof Copy> {}
|
||||
|
||||
@@ -8,4 +8,3 @@ const Updated = define({
|
||||
schema: { projectID: Project.ID },
|
||||
})
|
||||
export const Event = { Updated, Definitions: inventory(Updated) }
|
||||
export const ProjectDirectoriesEvent = Event
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Schema } from "effect"
|
||||
import { withStatics } from "./schema"
|
||||
import { statics } from "./schema"
|
||||
|
||||
export const ProjectID = Schema.String.pipe(
|
||||
Schema.brand("Project.ID"),
|
||||
withStatics((schema) => ({ global: schema.make("global") })),
|
||||
statics((schema) => ({ global: schema.make("global") })),
|
||||
)
|
||||
export type ProjectID = typeof ProjectID.Type
|
||||
|
||||
@@ -2,40 +2,43 @@ export * as Project from "./project"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { define, inventory } from "./event"
|
||||
import { NonNegativeInt, optionalOmitUndefined } from "./schema"
|
||||
import { NonNegativeInt, optional } from "./schema"
|
||||
import { ProjectID } from "./project-id"
|
||||
|
||||
export const ID = ProjectID
|
||||
export type ID = typeof ID.Type
|
||||
|
||||
export const Vcs = Schema.Literal("git")
|
||||
export const Vcs = Schema.Literal("git").annotate({ identifier: "Project.Vcs" })
|
||||
export const Icon = Schema.Struct({
|
||||
url: optionalOmitUndefined(Schema.String),
|
||||
override: optionalOmitUndefined(Schema.String),
|
||||
color: optionalOmitUndefined(Schema.String),
|
||||
})
|
||||
url: optional(Schema.String),
|
||||
override: optional(Schema.String),
|
||||
color: optional(Schema.String),
|
||||
}).annotate({ identifier: "Project.Icon" })
|
||||
export interface Icon extends Schema.Schema.Type<typeof Icon> {}
|
||||
export const Commands = Schema.Struct({
|
||||
start: optionalOmitUndefined(
|
||||
start: optional(
|
||||
Schema.String.annotate({ description: "Startup script to run when creating a new workspace (worktree)" }),
|
||||
),
|
||||
})
|
||||
}).annotate({ identifier: "Project.Commands" })
|
||||
export interface Commands extends Schema.Schema.Type<typeof Commands> {}
|
||||
export const Time = Schema.Struct({
|
||||
created: NonNegativeInt,
|
||||
updated: NonNegativeInt,
|
||||
initialized: optionalOmitUndefined(NonNegativeInt),
|
||||
})
|
||||
initialized: optional(NonNegativeInt),
|
||||
}).annotate({ identifier: "Project.Time" })
|
||||
export interface Time extends Schema.Schema.Type<typeof Time> {}
|
||||
|
||||
export const Info = Schema.Struct({
|
||||
id: ID,
|
||||
worktree: Schema.String,
|
||||
vcs: optionalOmitUndefined(Vcs),
|
||||
name: optionalOmitUndefined(Schema.String),
|
||||
icon: optionalOmitUndefined(Icon),
|
||||
commands: optionalOmitUndefined(Commands),
|
||||
vcs: optional(Vcs),
|
||||
name: optional(Schema.String),
|
||||
icon: optional(Icon),
|
||||
commands: optional(Commands),
|
||||
time: Time,
|
||||
sandboxes: Schema.Array(Schema.String),
|
||||
}).annotate({ identifier: "Project" })
|
||||
export type Info = typeof Info.Type
|
||||
export interface Info extends Schema.Schema.Type<typeof Info> {}
|
||||
|
||||
const Updated = define({ type: "project.updated", schema: Info.fields })
|
||||
export const Event = { Updated, Definitions: inventory(Updated) }
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Schema } from "effect"
|
||||
import { withStatics } from "./schema"
|
||||
import { optional } from "./schema"
|
||||
import { statics } from "./schema"
|
||||
|
||||
export interface Source extends Schema.Schema.Type<typeof Source> {}
|
||||
export const Source = Schema.Struct({
|
||||
@@ -12,13 +13,13 @@ export interface FileAttachment extends Schema.Schema.Type<typeof FileAttachment
|
||||
export const FileAttachment = Schema.Struct({
|
||||
uri: Schema.String,
|
||||
mime: Schema.String,
|
||||
name: Schema.String.pipe(Schema.optional),
|
||||
description: Schema.String.pipe(Schema.optional),
|
||||
source: Source.pipe(Schema.optional),
|
||||
name: Schema.String.pipe(optional),
|
||||
description: Schema.String.pipe(optional),
|
||||
source: Source.pipe(optional),
|
||||
})
|
||||
.annotate({ identifier: "Prompt.FileAttachment" })
|
||||
.pipe(
|
||||
withStatics((schema) => ({
|
||||
statics((schema) => ({
|
||||
create: (input: FileAttachment) =>
|
||||
schema.make({
|
||||
uri: input.uri,
|
||||
@@ -33,18 +34,18 @@ export const FileAttachment = Schema.Struct({
|
||||
export interface AgentAttachment extends Schema.Schema.Type<typeof AgentAttachment> {}
|
||||
export const AgentAttachment = Schema.Struct({
|
||||
name: Schema.String,
|
||||
source: Source.pipe(Schema.optional),
|
||||
source: Source.pipe(optional),
|
||||
}).annotate({ identifier: "Prompt.AgentAttachment" })
|
||||
|
||||
export interface Prompt extends Schema.Schema.Type<typeof Prompt> {}
|
||||
export const Prompt = Schema.Struct({
|
||||
text: Schema.String,
|
||||
files: Schema.Array(FileAttachment).pipe(Schema.optional),
|
||||
agents: Schema.Array(AgentAttachment).pipe(Schema.optional),
|
||||
files: Schema.Array(FileAttachment).pipe(optional),
|
||||
agents: Schema.Array(AgentAttachment).pipe(optional),
|
||||
})
|
||||
.annotate({ identifier: "Prompt" })
|
||||
.pipe(
|
||||
withStatics((schema) => ({
|
||||
statics((schema) => ({
|
||||
equivalence: Schema.toEquivalence(schema),
|
||||
fromUserMessage: (input: Pick<Prompt, "text" | "files" | "agents">) =>
|
||||
schema.make({
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
export * as Provider from "./provider"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { Integration } from "./integration"
|
||||
import { withStatics } from "./schema"
|
||||
import { statics } from "./schema"
|
||||
|
||||
export const ID = Schema.String.pipe(
|
||||
Schema.brand("ProviderV2.ID"),
|
||||
withStatics((schema) => ({
|
||||
statics((schema) => ({
|
||||
opencode: schema.make("opencode"),
|
||||
anthropic: schema.make("anthropic"),
|
||||
openai: schema.make("openai"),
|
||||
@@ -26,38 +27,40 @@ export interface AISDK extends Schema.Schema.Type<typeof AISDK> {}
|
||||
export const AISDK = Schema.Struct({
|
||||
type: Schema.Literal("aisdk"),
|
||||
package: Schema.String,
|
||||
url: Schema.String.pipe(Schema.optional),
|
||||
settings: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
|
||||
})
|
||||
url: Schema.String.pipe(optional),
|
||||
settings: Schema.Record(Schema.String, Schema.Unknown).pipe(optional),
|
||||
}).annotate({ identifier: "Provider.AISDK" })
|
||||
|
||||
export interface Native extends Schema.Schema.Type<typeof Native> {}
|
||||
export const Native = Schema.Struct({
|
||||
type: Schema.Literal("native"),
|
||||
url: Schema.String.pipe(Schema.optional),
|
||||
url: Schema.String.pipe(optional),
|
||||
settings: Schema.Record(Schema.String, Schema.Unknown),
|
||||
})
|
||||
}).annotate({ identifier: "Provider.Native" })
|
||||
|
||||
export const Api = Schema.Union([AISDK, Native]).pipe(Schema.toTaggedUnion("type"))
|
||||
export const Api = Schema.Union([AISDK, Native])
|
||||
.pipe(Schema.toTaggedUnion("type"))
|
||||
.annotate({ identifier: "Provider.Api" })
|
||||
export type Api = typeof Api.Type
|
||||
|
||||
export interface Request extends Schema.Schema.Type<typeof Request> {}
|
||||
export const Request = Schema.Struct({
|
||||
headers: Schema.Record(Schema.String, Schema.String),
|
||||
body: Schema.Record(Schema.String, Schema.Any),
|
||||
})
|
||||
body: Schema.Record(Schema.String, Schema.Json),
|
||||
}).annotate({ identifier: "Provider.Request" })
|
||||
|
||||
export interface Info extends Schema.Schema.Type<typeof Info> {}
|
||||
export const Info = Schema.Struct({
|
||||
id: ID,
|
||||
integrationID: Integration.ID.pipe(Schema.optional),
|
||||
integrationID: Integration.ID.pipe(optional),
|
||||
name: Schema.String,
|
||||
disabled: Schema.Boolean.pipe(Schema.optional),
|
||||
disabled: Schema.Boolean.pipe(optional),
|
||||
api: Api,
|
||||
request: Request,
|
||||
})
|
||||
.annotate({ identifier: "ProviderV2.Info" })
|
||||
.pipe(
|
||||
withStatics((schema) => ({
|
||||
statics((schema) => ({
|
||||
empty: (id: ID) =>
|
||||
schema.make({
|
||||
id,
|
||||
|
||||
@@ -6,4 +6,5 @@ import { PositiveInt } from "./schema"
|
||||
export const ConnectToken = Schema.Struct({
|
||||
ticket: Schema.String,
|
||||
expires_in: PositiveInt,
|
||||
})
|
||||
}).annotate({ identifier: "PtyTicket.ConnectToken" })
|
||||
export interface ConnectToken extends Schema.Schema.Type<typeof ConnectToken> {}
|
||||
|
||||
+20
-17
@@ -1,17 +1,21 @@
|
||||
export * as Pty from "./pty"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { define, inventory } from "./event"
|
||||
import { ascending } from "./identifier"
|
||||
import { NonNegativeInt, PositiveInt } from "./schema"
|
||||
import { withStatics } from "./schema"
|
||||
import { NonNegativeInt, PositiveInt, statics } from "./schema"
|
||||
|
||||
const IDSchema = Schema.String.check(Schema.isStartsWith("pty")).pipe(Schema.brand("PtyID"))
|
||||
|
||||
export const ID = IDSchema.pipe(
|
||||
withStatics((schema: typeof IDSchema) => ({
|
||||
ascending: (id?: string) => schema.make(id ?? "pty_" + ascending()),
|
||||
})),
|
||||
statics((schema: typeof IDSchema) => {
|
||||
const create = () => schema.make("pty_" + ascending())
|
||||
return {
|
||||
create,
|
||||
ascending: (id?: string) => (id === undefined ? create() : schema.make(id)),
|
||||
}
|
||||
}),
|
||||
)
|
||||
export type ID = typeof ID.Type
|
||||
|
||||
@@ -23,33 +27,32 @@ export const Info = Schema.Struct({
|
||||
cwd: Schema.String,
|
||||
status: Schema.Literals(["running", "exited"]),
|
||||
pid: NonNegativeInt,
|
||||
exitCode: Schema.optional(NonNegativeInt),
|
||||
exitCode: optional(NonNegativeInt),
|
||||
}).annotate({ identifier: "Pty" })
|
||||
export const PtyInfo = Info
|
||||
export interface Info extends Schema.Schema.Type<typeof Info> {}
|
||||
|
||||
const Created = define({ type: "pty.created", schema: { info: Info } })
|
||||
const Updated = define({ type: "pty.updated", schema: { info: Info } })
|
||||
const Exited = define({ type: "pty.exited", schema: { id: ID, exitCode: NonNegativeInt } })
|
||||
const Deleted = define({ type: "pty.deleted", schema: { id: ID } })
|
||||
export const Event = { Created, Updated, Exited, Deleted, Definitions: inventory(Created, Updated, Exited, Deleted) }
|
||||
export const PtyEvent = Event
|
||||
|
||||
export const CreateInput = Schema.Struct({
|
||||
command: Schema.optional(Schema.String),
|
||||
args: Schema.optional(Schema.Array(Schema.String)),
|
||||
cwd: Schema.optional(Schema.String),
|
||||
title: Schema.optional(Schema.String),
|
||||
env: Schema.optional(Schema.Record(Schema.String, Schema.String)),
|
||||
command: optional(Schema.String),
|
||||
args: optional(Schema.Array(Schema.String)),
|
||||
cwd: optional(Schema.String),
|
||||
title: optional(Schema.String),
|
||||
env: optional(Schema.Record(Schema.String, Schema.String)),
|
||||
})
|
||||
export type CreateInput = typeof CreateInput.Type
|
||||
export interface CreateInput extends Schema.Schema.Type<typeof CreateInput> {}
|
||||
|
||||
export const UpdateInput = Schema.Struct({
|
||||
title: Schema.optional(Schema.String),
|
||||
size: Schema.optional(
|
||||
title: optional(Schema.String),
|
||||
size: optional(
|
||||
Schema.Struct({
|
||||
rows: PositiveInt,
|
||||
cols: PositiveInt,
|
||||
}),
|
||||
),
|
||||
})
|
||||
export type UpdateInput = typeof UpdateInput.Type
|
||||
export interface UpdateInput extends Schema.Schema.Type<typeof UpdateInput> {}
|
||||
|
||||
@@ -1,66 +1 @@
|
||||
export * as QuestionV1 from "./question-v1"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { define, inventory } from "./event"
|
||||
import { ascending } from "./identifier"
|
||||
import { withStatics } from "./schema"
|
||||
import { SessionID } from "./session-id"
|
||||
import { SessionV1 } from "./session-v1"
|
||||
|
||||
export const ID = Schema.String.check(Schema.isStartsWith("que")).pipe(
|
||||
Schema.brand("QuestionID"),
|
||||
withStatics((schema) => ({ ascending: (id?: string) => schema.make(id ?? "que_" + ascending()) })),
|
||||
)
|
||||
|
||||
export const Option = Schema.Struct({
|
||||
label: Schema.String.annotate({ description: "Display text (1-5 words, concise)" }),
|
||||
description: Schema.String.annotate({ description: "Explanation of choice" }),
|
||||
}).annotate({ identifier: "QuestionOption" })
|
||||
|
||||
const base = {
|
||||
question: Schema.String.annotate({ description: "Complete question" }),
|
||||
header: Schema.String.annotate({ description: "Very short label (max 30 chars)" }),
|
||||
options: Schema.Array(Option).annotate({ description: "Available choices" }),
|
||||
multiple: Schema.optional(Schema.Boolean).annotate({ description: "Allow selecting multiple choices" }),
|
||||
}
|
||||
|
||||
export const Info = Schema.Struct({
|
||||
...base,
|
||||
custom: Schema.optional(Schema.Boolean).annotate({ description: "Allow typing a custom answer (default: true)" }),
|
||||
}).annotate({ identifier: "QuestionInfo" })
|
||||
export const Prompt = Schema.Struct(base).annotate({ identifier: "QuestionPrompt" })
|
||||
export const Tool = Schema.Struct({ messageID: SessionV1.MessageID, callID: Schema.String }).annotate({
|
||||
identifier: "QuestionTool",
|
||||
})
|
||||
export const Request = Schema.Struct({
|
||||
id: ID,
|
||||
sessionID: SessionID,
|
||||
questions: Schema.Array(Info).annotate({ description: "Questions to ask" }),
|
||||
tool: Schema.optional(Tool),
|
||||
}).annotate({ identifier: "QuestionRequest" })
|
||||
export const Answer = Schema.Array(Schema.String).annotate({ identifier: "QuestionAnswer" })
|
||||
export const Reply = Schema.Struct({
|
||||
answers: Schema.Array(Answer).annotate({
|
||||
description: "User answers in order of questions (each answer is an array of selected labels)",
|
||||
}),
|
||||
}).annotate({ identifier: "QuestionReply" })
|
||||
export const Replied = Schema.Struct({
|
||||
sessionID: SessionID,
|
||||
requestID: ID,
|
||||
answers: Schema.Array(Answer),
|
||||
}).annotate({
|
||||
identifier: "QuestionReplied",
|
||||
})
|
||||
export const Rejected = Schema.Struct({ sessionID: SessionID, requestID: ID }).annotate({
|
||||
identifier: "QuestionRejected",
|
||||
})
|
||||
|
||||
const Asked = define({ type: "question.asked", schema: Request.fields })
|
||||
const RepliedEvent = define({ type: "question.replied", schema: Replied.fields })
|
||||
const RejectedEvent = define({ type: "question.rejected", schema: Rejected.fields })
|
||||
export const Event = {
|
||||
Asked,
|
||||
Replied: RepliedEvent,
|
||||
Rejected: RejectedEvent,
|
||||
Definitions: inventory(Asked, RepliedEvent, RejectedEvent),
|
||||
}
|
||||
export * from "./v1/question"
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
export * as Question from "./question"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { define, inventory } from "./event"
|
||||
import { ascending } from "./identifier"
|
||||
import { SessionID } from "./session-id"
|
||||
import { withStatics } from "./schema"
|
||||
import { statics } from "./schema"
|
||||
|
||||
export const ID = Schema.String.check(Schema.isStartsWith("que")).pipe(
|
||||
Schema.brand("QuestionV2.ID"),
|
||||
withStatics((schema) => ({ ascending: (id?: string) => schema.make(id ?? "que_" + ascending()) })),
|
||||
statics((schema) => {
|
||||
const create = () => schema.make("que_" + ascending())
|
||||
return {
|
||||
create,
|
||||
ascending: (id?: string) => (id === undefined ? create() : schema.make(id)),
|
||||
}
|
||||
}),
|
||||
)
|
||||
export type ID = typeof ID.Type
|
||||
|
||||
@@ -16,39 +23,39 @@ export const Option = Schema.Struct({
|
||||
label: Schema.String.annotate({ description: "Display text (1-5 words, concise)" }),
|
||||
description: Schema.String.annotate({ description: "Explanation of choice" }),
|
||||
}).annotate({ identifier: "QuestionV2.Option" })
|
||||
export type Option = typeof Option.Type
|
||||
export interface Option extends Schema.Schema.Type<typeof Option> {}
|
||||
|
||||
const base = {
|
||||
question: Schema.String.annotate({ description: "Complete question" }),
|
||||
header: Schema.String.annotate({ description: "Very short label (max 30 chars)" }),
|
||||
options: Schema.Array(Option).annotate({ description: "Available choices" }),
|
||||
multiple: Schema.Boolean.pipe(Schema.optional).annotate({ description: "Allow selecting multiple choices" }),
|
||||
multiple: Schema.Boolean.pipe(optional).annotate({ description: "Allow selecting multiple choices" }),
|
||||
}
|
||||
|
||||
export const Info = Schema.Struct({
|
||||
...base,
|
||||
custom: Schema.Boolean.pipe(Schema.optional).annotate({
|
||||
custom: Schema.Boolean.pipe(optional).annotate({
|
||||
description: "Allow typing a custom answer (default: true)",
|
||||
}),
|
||||
}).annotate({ identifier: "QuestionV2.Info" })
|
||||
export type Info = typeof Info.Type
|
||||
export interface Info extends Schema.Schema.Type<typeof Info> {}
|
||||
|
||||
export const Prompt = Schema.Struct(base).annotate({ identifier: "QuestionV2.Prompt" })
|
||||
export type Prompt = typeof Prompt.Type
|
||||
export interface Prompt extends Schema.Schema.Type<typeof Prompt> {}
|
||||
|
||||
export const Tool = Schema.Struct({
|
||||
messageID: Schema.String,
|
||||
callID: Schema.String,
|
||||
}).annotate({ identifier: "QuestionV2.Tool" })
|
||||
export type Tool = typeof Tool.Type
|
||||
export interface Tool extends Schema.Schema.Type<typeof Tool> {}
|
||||
|
||||
export const Request = Schema.Struct({
|
||||
id: ID,
|
||||
sessionID: SessionID,
|
||||
questions: Schema.Array(Info).annotate({ description: "Questions to ask" }),
|
||||
tool: Tool.pipe(Schema.optional),
|
||||
tool: Tool.pipe(optional),
|
||||
}).annotate({ identifier: "QuestionV2.Request" })
|
||||
export type Request = typeof Request.Type
|
||||
export interface Request extends Schema.Schema.Type<typeof Request> {}
|
||||
|
||||
export const Answer = Schema.Array(Schema.String).annotate({ identifier: "QuestionV2.Answer" })
|
||||
export type Answer = typeof Answer.Type
|
||||
@@ -58,7 +65,7 @@ export const Reply = Schema.Struct({
|
||||
description: "User answers in order of questions (each answer is an array of selected labels)",
|
||||
}),
|
||||
}).annotate({ identifier: "QuestionV2.Reply" })
|
||||
export type Reply = typeof Reply.Type
|
||||
export interface Reply extends Schema.Schema.Type<typeof Reply> {}
|
||||
|
||||
const Asked = define({ type: "question.v2.asked", schema: Request.fields })
|
||||
const Replied = define({
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export * as Reference from "./reference"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { define, inventory } from "./event"
|
||||
import { AbsolutePath } from "./schema"
|
||||
|
||||
@@ -11,26 +12,28 @@ export interface LocalSource extends Schema.Schema.Type<typeof LocalSource> {}
|
||||
export const LocalSource = Schema.Struct({
|
||||
type: Schema.Literal("local"),
|
||||
path: AbsolutePath,
|
||||
description: Schema.String.pipe(Schema.optional),
|
||||
hidden: Schema.Boolean.pipe(Schema.optional),
|
||||
description: Schema.String.pipe(optional),
|
||||
hidden: Schema.Boolean.pipe(optional),
|
||||
}).annotate({ identifier: "Reference.LocalSource" })
|
||||
|
||||
export interface GitSource extends Schema.Schema.Type<typeof GitSource> {}
|
||||
export const GitSource = Schema.Struct({
|
||||
type: Schema.Literal("git"),
|
||||
repository: Schema.String,
|
||||
branch: Schema.String.pipe(Schema.optional),
|
||||
description: Schema.String.pipe(Schema.optional),
|
||||
hidden: Schema.Boolean.pipe(Schema.optional),
|
||||
branch: Schema.String.pipe(optional),
|
||||
description: Schema.String.pipe(optional),
|
||||
hidden: Schema.Boolean.pipe(optional),
|
||||
}).annotate({ identifier: "Reference.GitSource" })
|
||||
|
||||
export const Source = Schema.Union([LocalSource, GitSource]).pipe(Schema.toTaggedUnion("type"))
|
||||
export const Source = Schema.Union([LocalSource, GitSource])
|
||||
.pipe(Schema.toTaggedUnion("type"))
|
||||
.annotate({ identifier: "Reference.Source" })
|
||||
export type Source = typeof Source.Type
|
||||
|
||||
export class Info extends Schema.Class<Info>("Reference.Info")({
|
||||
name: Schema.String,
|
||||
path: AbsolutePath,
|
||||
description: Schema.String.pipe(Schema.optional),
|
||||
hidden: Schema.Boolean.pipe(Schema.optional),
|
||||
description: Schema.String.pipe(optional),
|
||||
hidden: Schema.Boolean.pipe(optional),
|
||||
source: Source,
|
||||
}) {}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
export * as Revert from "./revert"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { NonNegativeInt, RelativePath } from "./schema"
|
||||
import { SessionMessageID } from "./session-message-id"
|
||||
import { SessionMessage } from "./session-message"
|
||||
|
||||
export const FileDiff = Schema.Struct({
|
||||
path: RelativePath,
|
||||
@@ -11,13 +12,13 @@ export const FileDiff = Schema.Struct({
|
||||
deletions: NonNegativeInt,
|
||||
patch: Schema.String,
|
||||
}).annotate({ identifier: "File.Diff" })
|
||||
export type FileDiff = typeof FileDiff.Type
|
||||
export interface FileDiff extends Schema.Schema.Type<typeof FileDiff> {}
|
||||
|
||||
export const State = Schema.Struct({
|
||||
messageID: SessionMessageID.ID,
|
||||
partID: Schema.String.pipe(Schema.optional),
|
||||
snapshot: Schema.String.pipe(Schema.optional),
|
||||
diff: Schema.String.pipe(Schema.optional),
|
||||
files: Schema.Array(FileDiff).pipe(Schema.optional),
|
||||
})
|
||||
export type State = typeof State.Type
|
||||
messageID: SessionMessage.ID,
|
||||
partID: Schema.String.pipe(optional),
|
||||
snapshot: Schema.String.pipe(optional),
|
||||
diff: Schema.String.pipe(optional),
|
||||
files: Schema.Array(FileDiff).pipe(optional),
|
||||
}).annotate({ identifier: "Revert.State" })
|
||||
export interface State extends Schema.Schema.Type<typeof State> {}
|
||||
|
||||
@@ -9,7 +9,7 @@ export type RelativePath = typeof RelativePath.Type
|
||||
export const AbsolutePath = Schema.String.pipe(Schema.brand("AbsolutePath"))
|
||||
export type AbsolutePath = typeof AbsolutePath.Type
|
||||
|
||||
export const optionalOmitUndefined = <S extends Schema.Top>(schema: S) =>
|
||||
export const optional = <S extends Schema.Top>(schema: S) =>
|
||||
Schema.optionalKey(schema).pipe(
|
||||
Schema.decodeTo(Schema.optional(schema), {
|
||||
decode: SchemaGetter.passthrough({ strict: false }),
|
||||
@@ -17,7 +17,7 @@ export const optionalOmitUndefined = <S extends Schema.Top>(schema: S) =>
|
||||
}),
|
||||
)
|
||||
|
||||
export const withStatics =
|
||||
export const statics =
|
||||
<S extends object, M extends Record<string, unknown>>(methods: (schema: S) => M) =>
|
||||
(schema: S): S & M =>
|
||||
Object.assign(schema, methods(schema))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export * as SessionEvent from "./session-event"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { Event } from "./event"
|
||||
import { ProviderMetadata, ToolContent } from "./llm"
|
||||
import { Delivery } from "./session-delivery"
|
||||
@@ -9,7 +10,6 @@ import { DateTimeUtcFromMillis, NonNegativeInt, RelativePath } from "./schema"
|
||||
import { FileAttachment, Prompt } from "./prompt"
|
||||
import { SessionID } from "./session-id"
|
||||
import { Location } from "./location"
|
||||
import { SessionMessageID } from "./session-message-id"
|
||||
import { SessionMessage } from "./session-message"
|
||||
import { Revert } from "./revert"
|
||||
|
||||
@@ -22,7 +22,7 @@ export const Source = Schema.Struct({
|
||||
}).annotate({
|
||||
identifier: "session.next.event.source",
|
||||
})
|
||||
export type Source = typeof Source.Type
|
||||
export interface Source extends Schema.Schema.Type<typeof Source> {}
|
||||
|
||||
const Base = {
|
||||
timestamp: DateTimeUtcFromMillis,
|
||||
@@ -30,7 +30,7 @@ const Base = {
|
||||
}
|
||||
const PromptFields = {
|
||||
...Base,
|
||||
messageID: SessionMessageID.ID,
|
||||
messageID: SessionMessage.ID,
|
||||
prompt: Prompt,
|
||||
delivery: Delivery,
|
||||
}
|
||||
@@ -56,7 +56,7 @@ export const AgentSwitched = Event.define({
|
||||
...options,
|
||||
schema: {
|
||||
...Base,
|
||||
messageID: SessionMessageID.ID,
|
||||
messageID: SessionMessage.ID,
|
||||
agent: Schema.String,
|
||||
},
|
||||
})
|
||||
@@ -67,7 +67,7 @@ export const ModelSwitched = Event.define({
|
||||
...options,
|
||||
schema: {
|
||||
...Base,
|
||||
messageID: SessionMessageID.ID,
|
||||
messageID: SessionMessage.ID,
|
||||
model: Model.Ref,
|
||||
},
|
||||
})
|
||||
@@ -79,7 +79,7 @@ export const Moved = Event.define({
|
||||
schema: {
|
||||
...Base,
|
||||
location: Location.Ref,
|
||||
subdirectory: RelativePath.pipe(Schema.optional),
|
||||
subdirectory: RelativePath.pipe(optional),
|
||||
},
|
||||
})
|
||||
export type Moved = typeof Moved.Type
|
||||
@@ -103,7 +103,7 @@ export const ContextUpdated = Event.define({
|
||||
...options,
|
||||
schema: {
|
||||
...Base,
|
||||
messageID: SessionMessageID.ID,
|
||||
messageID: SessionMessage.ID,
|
||||
text: Schema.String,
|
||||
},
|
||||
})
|
||||
@@ -114,7 +114,7 @@ export const Synthetic = Event.define({
|
||||
...options,
|
||||
schema: {
|
||||
...Base,
|
||||
messageID: SessionMessageID.ID,
|
||||
messageID: SessionMessage.ID,
|
||||
text: Schema.String,
|
||||
},
|
||||
})
|
||||
@@ -126,7 +126,7 @@ export namespace Shell {
|
||||
...options,
|
||||
schema: {
|
||||
...Base,
|
||||
messageID: SessionMessageID.ID,
|
||||
messageID: SessionMessage.ID,
|
||||
callID: Schema.String,
|
||||
command: Schema.String,
|
||||
},
|
||||
@@ -151,10 +151,10 @@ export namespace Step {
|
||||
...options,
|
||||
schema: {
|
||||
...Base,
|
||||
assistantMessageID: SessionMessageID.ID,
|
||||
assistantMessageID: SessionMessage.ID,
|
||||
agent: Schema.String,
|
||||
model: Model.Ref,
|
||||
snapshot: Schema.String.pipe(Schema.optional),
|
||||
snapshot: Schema.String.pipe(optional),
|
||||
},
|
||||
})
|
||||
export type Started = typeof Started.Type
|
||||
@@ -164,7 +164,7 @@ export namespace Step {
|
||||
...stepSettlementOptions,
|
||||
schema: {
|
||||
...Base,
|
||||
assistantMessageID: SessionMessageID.ID,
|
||||
assistantMessageID: SessionMessage.ID,
|
||||
finish: Schema.String,
|
||||
cost: Schema.Finite,
|
||||
tokens: Schema.Struct({
|
||||
@@ -176,8 +176,8 @@ export namespace Step {
|
||||
write: Schema.Finite,
|
||||
}),
|
||||
}),
|
||||
snapshot: Schema.String.pipe(Schema.optional),
|
||||
files: Schema.Array(RelativePath).pipe(Schema.optional),
|
||||
snapshot: Schema.String.pipe(optional),
|
||||
files: Schema.Array(RelativePath).pipe(optional),
|
||||
},
|
||||
})
|
||||
export type Ended = typeof Ended.Type
|
||||
@@ -187,7 +187,7 @@ export namespace Step {
|
||||
...stepSettlementOptions,
|
||||
schema: {
|
||||
...Base,
|
||||
assistantMessageID: SessionMessageID.ID,
|
||||
assistantMessageID: SessionMessage.ID,
|
||||
error: UnknownError,
|
||||
},
|
||||
})
|
||||
@@ -200,7 +200,7 @@ export namespace Text {
|
||||
...options,
|
||||
schema: {
|
||||
...Base,
|
||||
assistantMessageID: SessionMessageID.ID,
|
||||
assistantMessageID: SessionMessage.ID,
|
||||
textID: Schema.String,
|
||||
},
|
||||
})
|
||||
@@ -211,7 +211,7 @@ export namespace Text {
|
||||
type: "session.next.text.delta",
|
||||
schema: {
|
||||
...Base,
|
||||
assistantMessageID: SessionMessageID.ID,
|
||||
assistantMessageID: SessionMessage.ID,
|
||||
textID: Schema.String,
|
||||
delta: Schema.String,
|
||||
},
|
||||
@@ -223,7 +223,7 @@ export namespace Text {
|
||||
...options,
|
||||
schema: {
|
||||
...Base,
|
||||
assistantMessageID: SessionMessageID.ID,
|
||||
assistantMessageID: SessionMessage.ID,
|
||||
textID: Schema.String,
|
||||
text: Schema.String,
|
||||
},
|
||||
@@ -237,9 +237,9 @@ export namespace Reasoning {
|
||||
...options,
|
||||
schema: {
|
||||
...Base,
|
||||
assistantMessageID: SessionMessageID.ID,
|
||||
assistantMessageID: SessionMessage.ID,
|
||||
reasoningID: Schema.String,
|
||||
providerMetadata: ProviderMetadata.pipe(Schema.optional),
|
||||
providerMetadata: ProviderMetadata.pipe(optional),
|
||||
},
|
||||
})
|
||||
export type Started = typeof Started.Type
|
||||
@@ -249,7 +249,7 @@ export namespace Reasoning {
|
||||
type: "session.next.reasoning.delta",
|
||||
schema: {
|
||||
...Base,
|
||||
assistantMessageID: SessionMessageID.ID,
|
||||
assistantMessageID: SessionMessage.ID,
|
||||
reasoningID: Schema.String,
|
||||
delta: Schema.String,
|
||||
},
|
||||
@@ -261,10 +261,10 @@ export namespace Reasoning {
|
||||
...options,
|
||||
schema: {
|
||||
...Base,
|
||||
assistantMessageID: SessionMessageID.ID,
|
||||
assistantMessageID: SessionMessage.ID,
|
||||
reasoningID: Schema.String,
|
||||
text: Schema.String,
|
||||
providerMetadata: ProviderMetadata.pipe(Schema.optional),
|
||||
providerMetadata: ProviderMetadata.pipe(optional),
|
||||
},
|
||||
})
|
||||
export type Ended = typeof Ended.Type
|
||||
@@ -273,7 +273,7 @@ export namespace Reasoning {
|
||||
export namespace Tool {
|
||||
const ToolBase = {
|
||||
...Base,
|
||||
assistantMessageID: SessionMessageID.ID,
|
||||
assistantMessageID: SessionMessage.ID,
|
||||
callID: Schema.String,
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ export namespace Tool {
|
||||
input: Schema.Record(Schema.String, Schema.Unknown),
|
||||
provider: Schema.Struct({
|
||||
executed: Schema.Boolean,
|
||||
metadata: ProviderMetadata.pipe(Schema.optional),
|
||||
metadata: ProviderMetadata.pipe(optional),
|
||||
}),
|
||||
},
|
||||
})
|
||||
@@ -333,7 +333,7 @@ export namespace Tool {
|
||||
...options,
|
||||
schema: {
|
||||
...ToolBase,
|
||||
structured: Schema.Record(Schema.String, Schema.Any),
|
||||
structured: Schema.Record(Schema.String, Schema.Unknown),
|
||||
content: Schema.Array(ToolContent),
|
||||
},
|
||||
})
|
||||
@@ -344,13 +344,13 @@ export namespace Tool {
|
||||
...options,
|
||||
schema: {
|
||||
...ToolBase,
|
||||
structured: Schema.Record(Schema.String, Schema.Any),
|
||||
structured: Schema.Record(Schema.String, Schema.Unknown),
|
||||
content: Schema.Array(ToolContent),
|
||||
outputPaths: Schema.Array(Schema.String).pipe(Schema.optional),
|
||||
result: Schema.Unknown.pipe(Schema.optional),
|
||||
outputPaths: Schema.Array(Schema.String).pipe(optional),
|
||||
result: Schema.Unknown.pipe(optional),
|
||||
provider: Schema.Struct({
|
||||
executed: Schema.Boolean,
|
||||
metadata: ProviderMetadata.pipe(Schema.optional),
|
||||
metadata: ProviderMetadata.pipe(optional),
|
||||
}),
|
||||
},
|
||||
})
|
||||
@@ -362,10 +362,10 @@ export namespace Tool {
|
||||
schema: {
|
||||
...ToolBase,
|
||||
error: UnknownError,
|
||||
result: Schema.Unknown.pipe(Schema.optional),
|
||||
result: Schema.Unknown.pipe(optional),
|
||||
provider: Schema.Struct({
|
||||
executed: Schema.Boolean,
|
||||
metadata: ProviderMetadata.pipe(Schema.optional),
|
||||
metadata: ProviderMetadata.pipe(optional),
|
||||
}),
|
||||
},
|
||||
})
|
||||
@@ -374,15 +374,15 @@ export namespace Tool {
|
||||
|
||||
export const RetryError = Schema.Struct({
|
||||
message: Schema.String,
|
||||
statusCode: Schema.Finite.pipe(Schema.optional),
|
||||
statusCode: Schema.Finite.pipe(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),
|
||||
responseHeaders: Schema.Record(Schema.String, Schema.String).pipe(optional),
|
||||
responseBody: Schema.String.pipe(optional),
|
||||
metadata: Schema.Record(Schema.String, Schema.String).pipe(optional),
|
||||
}).annotate({
|
||||
identifier: "session.next.retry_error",
|
||||
})
|
||||
export type RetryError = typeof RetryError.Type
|
||||
export interface RetryError extends Schema.Schema.Type<typeof RetryError> {}
|
||||
|
||||
export const Retried = Event.define({
|
||||
type: "session.next.retried",
|
||||
@@ -401,7 +401,7 @@ export namespace Compaction {
|
||||
...options,
|
||||
schema: {
|
||||
...Base,
|
||||
messageID: SessionMessageID.ID,
|
||||
messageID: SessionMessage.ID,
|
||||
reason: Schema.Union([Schema.Literal("auto"), Schema.Literal("manual")]),
|
||||
},
|
||||
})
|
||||
@@ -411,7 +411,7 @@ export namespace Compaction {
|
||||
type: "session.next.compaction.delta",
|
||||
schema: {
|
||||
...Base,
|
||||
messageID: SessionMessageID.ID,
|
||||
messageID: SessionMessage.ID,
|
||||
text: Schema.String,
|
||||
},
|
||||
})
|
||||
@@ -422,7 +422,7 @@ export namespace Compaction {
|
||||
...options,
|
||||
schema: {
|
||||
...Base,
|
||||
messageID: SessionMessageID.ID,
|
||||
messageID: SessionMessage.ID,
|
||||
reason: Started.data.fields.reason,
|
||||
text: Schema.String,
|
||||
recent: Schema.String,
|
||||
@@ -441,7 +441,7 @@ export namespace RevertEvent {
|
||||
export const Committed = Event.define({
|
||||
type: "session.next.revert.committed",
|
||||
...options,
|
||||
schema: { ...Base, messageID: SessionMessageID.ID },
|
||||
schema: { ...Base, messageID: SessionMessage.ID },
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Schema } from "effect"
|
||||
import { descending } from "./identifier"
|
||||
import { withStatics } from "./schema"
|
||||
import { statics } from "./schema"
|
||||
|
||||
export const SessionID = Schema.String.check(Schema.isStartsWith("ses")).pipe(
|
||||
Schema.brand("SessionID"),
|
||||
withStatics((schema) => {
|
||||
statics((schema) => {
|
||||
const create = () => schema.make("ses_" + descending())
|
||||
return {
|
||||
create,
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
export * as SessionInput from "./session-input"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { Prompt } from "./prompt"
|
||||
import { DateTimeUtcFromMillis, NonNegativeInt } from "./schema"
|
||||
import { SessionDelivery } from "./session-delivery"
|
||||
import { SessionID } from "./session-id"
|
||||
import { SessionMessageID } from "./session-message-id"
|
||||
import { SessionMessage } from "./session-message"
|
||||
|
||||
export const Delivery = SessionDelivery.Delivery
|
||||
export type Delivery = SessionDelivery.Delivery
|
||||
@@ -13,10 +14,10 @@ export type Delivery = SessionDelivery.Delivery
|
||||
export interface Admitted extends Schema.Schema.Type<typeof Admitted> {}
|
||||
export const Admitted = Schema.Struct({
|
||||
admittedSeq: NonNegativeInt,
|
||||
id: SessionMessageID.ID,
|
||||
id: SessionMessage.ID,
|
||||
sessionID: SessionID,
|
||||
prompt: Prompt,
|
||||
delivery: Delivery,
|
||||
timeCreated: DateTimeUtcFromMillis,
|
||||
promotedSeq: NonNegativeInt.pipe(Schema.optional),
|
||||
promotedSeq: NonNegativeInt.pipe(optional),
|
||||
}).annotate({ identifier: "SessionInput.Admitted" })
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
export * as SessionMessageID from "./session-message-id"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { ascending } from "./identifier"
|
||||
import { withStatics } from "./schema"
|
||||
|
||||
export const ID = Schema.String.check(Schema.isStartsWith("msg_")).pipe(
|
||||
Schema.brand("Session.Message.ID"),
|
||||
withStatics((schema) => ({ create: () => schema.make("msg_" + ascending()) })),
|
||||
)
|
||||
export type ID = typeof ID.Type
|
||||
@@ -1,15 +1,19 @@
|
||||
export * as SessionMessage from "./session-message"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { ProviderMetadata, ToolContent } from "./llm"
|
||||
import { Model } from "./model"
|
||||
import { FileAttachment, Prompt } from "./prompt"
|
||||
import { DateTimeUtcFromMillis, RelativePath } from "./schema"
|
||||
import { DateTimeUtcFromMillis, RelativePath, statics } from "./schema"
|
||||
import { SessionID } from "./session-id"
|
||||
import { SessionMessageID } from "./session-message-id"
|
||||
import { ascending } from "./identifier"
|
||||
|
||||
export const ID = SessionMessageID.ID
|
||||
export type ID = SessionMessageID.ID
|
||||
export const ID = Schema.String.check(Schema.isStartsWith("msg_")).pipe(
|
||||
Schema.brand("Session.Message.ID"),
|
||||
statics((schema) => ({ create: () => schema.make("msg_" + ascending()) })),
|
||||
)
|
||||
export type ID = typeof ID.Type
|
||||
|
||||
export interface UnknownError extends Schema.Schema.Type<typeof UnknownError> {}
|
||||
export const UnknownError = Schema.Struct({
|
||||
@@ -19,7 +23,7 @@ export const UnknownError = Schema.Struct({
|
||||
|
||||
const Base = {
|
||||
id: ID,
|
||||
metadata: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
|
||||
metadata: Schema.Record(Schema.String, Schema.Unknown).pipe(optional),
|
||||
time: Schema.Struct({ created: DateTimeUtcFromMillis }),
|
||||
}
|
||||
|
||||
@@ -70,7 +74,7 @@ export const Shell = Schema.Struct({
|
||||
output: Schema.String,
|
||||
time: Schema.Struct({
|
||||
created: DateTimeUtcFromMillis,
|
||||
completed: DateTimeUtcFromMillis.pipe(Schema.optional),
|
||||
completed: DateTimeUtcFromMillis.pipe(optional),
|
||||
}),
|
||||
}).annotate({ identifier: "Session.Message.Shell" })
|
||||
|
||||
@@ -84,7 +88,7 @@ export interface ToolStateRunning extends Schema.Schema.Type<typeof ToolStateRun
|
||||
export const ToolStateRunning = Schema.Struct({
|
||||
status: Schema.Literal("running"),
|
||||
input: Schema.Record(Schema.String, Schema.Unknown),
|
||||
structured: Schema.Record(Schema.String, Schema.Any),
|
||||
structured: Schema.Record(Schema.String, Schema.Unknown),
|
||||
content: ToolContent.pipe(Schema.Array),
|
||||
}).annotate({ identifier: "Session.Message.ToolState.Running" })
|
||||
|
||||
@@ -92,11 +96,11 @@ export interface ToolStateCompleted extends Schema.Schema.Type<typeof ToolStateC
|
||||
export const ToolStateCompleted = Schema.Struct({
|
||||
status: Schema.Literal("completed"),
|
||||
input: Schema.Record(Schema.String, Schema.Unknown),
|
||||
attachments: FileAttachment.pipe(Schema.Array, Schema.optional),
|
||||
attachments: FileAttachment.pipe(Schema.Array, optional),
|
||||
content: ToolContent.pipe(Schema.Array),
|
||||
outputPaths: Schema.Array(Schema.String).pipe(Schema.optional),
|
||||
structured: Schema.Record(Schema.String, Schema.Any),
|
||||
result: Schema.Unknown.pipe(Schema.optional),
|
||||
outputPaths: Schema.Array(Schema.String).pipe(optional),
|
||||
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<typeof ToolStateError> {}
|
||||
@@ -104,9 +108,9 @@ export const ToolStateError = Schema.Struct({
|
||||
status: Schema.Literal("error"),
|
||||
input: Schema.Record(Schema.String, Schema.Unknown),
|
||||
content: ToolContent.pipe(Schema.Array),
|
||||
structured: Schema.Record(Schema.String, Schema.Any),
|
||||
structured: Schema.Record(Schema.String, Schema.Unknown),
|
||||
error: UnknownError,
|
||||
result: Schema.Unknown.pipe(Schema.optional),
|
||||
result: Schema.Unknown.pipe(optional),
|
||||
}).annotate({ identifier: "Session.Message.ToolState.Error" })
|
||||
|
||||
export const ToolState = Schema.Union([ToolStatePending, ToolStateRunning, ToolStateCompleted, ToolStateError]).pipe(
|
||||
@@ -121,15 +125,15 @@ export const AssistantTool = Schema.Struct({
|
||||
name: Schema.String,
|
||||
provider: Schema.Struct({
|
||||
executed: Schema.Boolean,
|
||||
metadata: ProviderMetadata.pipe(Schema.optional),
|
||||
resultMetadata: ProviderMetadata.pipe(Schema.optional),
|
||||
}).pipe(Schema.optional),
|
||||
metadata: ProviderMetadata.pipe(optional),
|
||||
resultMetadata: ProviderMetadata.pipe(optional),
|
||||
}).pipe(optional),
|
||||
state: ToolState,
|
||||
time: Schema.Struct({
|
||||
created: DateTimeUtcFromMillis,
|
||||
ran: DateTimeUtcFromMillis.pipe(Schema.optional),
|
||||
completed: DateTimeUtcFromMillis.pipe(Schema.optional),
|
||||
pruned: DateTimeUtcFromMillis.pipe(Schema.optional),
|
||||
ran: DateTimeUtcFromMillis.pipe(optional),
|
||||
completed: DateTimeUtcFromMillis.pipe(optional),
|
||||
pruned: DateTimeUtcFromMillis.pipe(optional),
|
||||
}),
|
||||
}).annotate({ identifier: "Session.Message.Assistant.Tool" })
|
||||
|
||||
@@ -145,7 +149,7 @@ export const AssistantReasoning = Schema.Struct({
|
||||
type: Schema.Literal("reasoning"),
|
||||
id: Schema.String,
|
||||
text: Schema.String,
|
||||
providerMetadata: ProviderMetadata.pipe(Schema.optional),
|
||||
providerMetadata: ProviderMetadata.pipe(optional),
|
||||
}).annotate({ identifier: "Session.Message.Assistant.Reasoning" })
|
||||
|
||||
export const AssistantContent = Schema.Union([AssistantText, AssistantReasoning, AssistantTool]).pipe(
|
||||
@@ -161,22 +165,22 @@ export const Assistant = Schema.Struct({
|
||||
model: Model.Ref,
|
||||
content: AssistantContent.pipe(Schema.Array),
|
||||
snapshot: Schema.Struct({
|
||||
start: Schema.String.pipe(Schema.optional),
|
||||
end: Schema.String.pipe(Schema.optional),
|
||||
files: Schema.Array(RelativePath).pipe(Schema.optional),
|
||||
}).pipe(Schema.optional),
|
||||
finish: Schema.String.pipe(Schema.optional),
|
||||
cost: Schema.Finite.pipe(Schema.optional),
|
||||
start: Schema.String.pipe(optional),
|
||||
end: Schema.String.pipe(optional),
|
||||
files: Schema.Array(RelativePath).pipe(optional),
|
||||
}).pipe(optional),
|
||||
finish: Schema.String.pipe(optional),
|
||||
cost: Schema.Finite.pipe(optional),
|
||||
tokens: Schema.Struct({
|
||||
input: Schema.Finite,
|
||||
output: Schema.Finite,
|
||||
reasoning: Schema.Finite,
|
||||
cache: Schema.Struct({ read: Schema.Finite, write: Schema.Finite }),
|
||||
}).pipe(Schema.optional),
|
||||
error: UnknownError.pipe(Schema.optional),
|
||||
}).pipe(optional),
|
||||
error: UnknownError.pipe(optional),
|
||||
time: Schema.Struct({
|
||||
created: DateTimeUtcFromMillis,
|
||||
completed: DateTimeUtcFromMillis.pipe(Schema.optional),
|
||||
completed: DateTimeUtcFromMillis.pipe(optional),
|
||||
}),
|
||||
}).annotate({ identifier: "Session.Message.Assistant" })
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export * as SessionStatusEvent from "./session-status-event"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { Event } from "./event"
|
||||
import { NonNegativeInt } from "./schema"
|
||||
import { SessionID } from "./session-id"
|
||||
@@ -13,14 +14,14 @@ export const Info = Schema.Union([
|
||||
type: Schema.Literal("retry"),
|
||||
attempt: NonNegativeInt,
|
||||
message: Schema.String,
|
||||
action: Schema.optional(
|
||||
action: optional(
|
||||
Schema.Struct({
|
||||
reason: Schema.String,
|
||||
provider: Schema.String,
|
||||
title: Schema.String,
|
||||
message: Schema.String,
|
||||
label: Schema.String,
|
||||
link: Schema.optional(Schema.String),
|
||||
link: optional(Schema.String),
|
||||
}),
|
||||
),
|
||||
next: NonNegativeInt,
|
||||
|
||||
@@ -6,13 +6,14 @@ import { SessionID } from "./session-id"
|
||||
|
||||
export const Info = Schema.Struct({
|
||||
content: Schema.String.annotate({ description: "Brief description of the task" }),
|
||||
status: Schema.String.annotate({
|
||||
status: Schema.Literals(["pending", "in_progress", "completed", "cancelled"]).annotate({
|
||||
description: "Current status of the task: pending, in_progress, completed, cancelled",
|
||||
}),
|
||||
priority: Schema.String.annotate({ description: "Priority level of the task: high, medium, low" }),
|
||||
priority: Schema.Literals(["high", "medium", "low"]).annotate({
|
||||
description: "Priority level of the task: high, medium, low",
|
||||
}),
|
||||
}).annotate({ identifier: "Todo" })
|
||||
export type Info = typeof Info.Type
|
||||
export const SessionTodoInfo = Info
|
||||
export interface Info extends Schema.Schema.Type<typeof Info> {}
|
||||
|
||||
const Updated = define({
|
||||
type: "todo.updated",
|
||||
|
||||
@@ -1,676 +1 @@
|
||||
export * as SessionV1 from "./session-v1"
|
||||
|
||||
import { Effect, Schema, Types } from "effect"
|
||||
import { define, inventory } from "./event"
|
||||
import { FileDiff } from "./file-diff"
|
||||
import { PermissionV1 } from "./permission-v1"
|
||||
import { Project } from "./project"
|
||||
import { Provider } from "./provider"
|
||||
import { Model } from "./model"
|
||||
import { NonNegativeInt, optionalOmitUndefined, withStatics } from "./schema"
|
||||
import { ascending } from "./identifier"
|
||||
import { SessionID } from "./session-id"
|
||||
import { WorkspaceID } from "./workspace-id"
|
||||
|
||||
const Timestamp = Schema.Finite.check(Schema.isGreaterThanOrEqualTo(0))
|
||||
|
||||
export const MessageID = Schema.String.check(Schema.isStartsWith("msg")).pipe(
|
||||
Schema.brand("MessageID"),
|
||||
withStatics((schema) => ({ ascending: (id?: string) => schema.make(id ?? "msg_" + ascending()) })),
|
||||
)
|
||||
export type MessageID = typeof MessageID.Type
|
||||
|
||||
export const PartID = Schema.String.check(Schema.isStartsWith("prt")).pipe(
|
||||
Schema.brand("PartID"),
|
||||
withStatics((schema) => ({ ascending: (id?: string) => schema.make(id ?? "prt_" + ascending()) })),
|
||||
)
|
||||
export type PartID = typeof PartID.Type
|
||||
|
||||
const namedError = <Name extends string, Fields extends Schema.Struct.Fields>(name: Name, fields: Fields) => {
|
||||
const schema = Schema.Struct({ name: Schema.Literal(name), data: Schema.Struct(fields) }).annotate({
|
||||
identifier: name,
|
||||
})
|
||||
return { Schema: schema, EffectSchema: schema }
|
||||
}
|
||||
|
||||
export const OutputLengthError = namedError("MessageOutputLengthError", {})
|
||||
|
||||
export const AuthError = namedError("ProviderAuthError", {
|
||||
providerID: Schema.String,
|
||||
message: Schema.String,
|
||||
})
|
||||
|
||||
export const AbortedError = namedError("MessageAbortedError", { message: Schema.String })
|
||||
export const StructuredOutputError = namedError("StructuredOutputError", {
|
||||
message: Schema.String,
|
||||
retries: NonNegativeInt,
|
||||
})
|
||||
export const APIError = namedError("APIError", {
|
||||
message: Schema.String,
|
||||
statusCode: Schema.optional(NonNegativeInt),
|
||||
isRetryable: Schema.Boolean,
|
||||
responseHeaders: Schema.optional(Schema.Record(Schema.String, Schema.String)),
|
||||
responseBody: Schema.optional(Schema.String),
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.String)),
|
||||
})
|
||||
export type APIError = Schema.Schema.Type<typeof APIError.Schema>
|
||||
export const ContextOverflowError = namedError("ContextOverflowError", {
|
||||
message: Schema.String,
|
||||
responseBody: Schema.optional(Schema.String),
|
||||
})
|
||||
export const ContentFilterError = namedError("ContentFilterError", {
|
||||
message: Schema.String,
|
||||
})
|
||||
|
||||
export class OutputFormatText extends Schema.Class<OutputFormatText>("OutputFormatText")({
|
||||
type: Schema.Literal("text"),
|
||||
}) {}
|
||||
|
||||
export class OutputFormatJsonSchema extends Schema.Class<OutputFormatJsonSchema>("OutputFormatJsonSchema")({
|
||||
type: Schema.Literal("json_schema"),
|
||||
schema: Schema.Record(Schema.String, Schema.Any).annotate({ identifier: "JSONSchema" }),
|
||||
retryCount: NonNegativeInt.pipe(Schema.optional, Schema.withDecodingDefault(Effect.succeed(2))),
|
||||
}) {}
|
||||
|
||||
export const Format = Schema.Union([OutputFormatText, OutputFormatJsonSchema]).annotate({
|
||||
discriminator: "type",
|
||||
identifier: "OutputFormat",
|
||||
})
|
||||
export type OutputFormat = Schema.Schema.Type<typeof Format>
|
||||
|
||||
const partBase = {
|
||||
id: PartID,
|
||||
sessionID: SessionID,
|
||||
messageID: MessageID,
|
||||
}
|
||||
|
||||
export const SnapshotPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("snapshot"),
|
||||
snapshot: Schema.String,
|
||||
}).annotate({ identifier: "SnapshotPart" })
|
||||
export type SnapshotPart = Types.DeepMutable<Schema.Schema.Type<typeof SnapshotPart>>
|
||||
|
||||
export const PatchPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("patch"),
|
||||
hash: Schema.String,
|
||||
files: Schema.Array(Schema.String),
|
||||
}).annotate({ identifier: "PatchPart" })
|
||||
export type PatchPart = Types.DeepMutable<Schema.Schema.Type<typeof PatchPart>>
|
||||
|
||||
export const TextPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("text"),
|
||||
text: Schema.String,
|
||||
synthetic: Schema.optional(Schema.Boolean),
|
||||
ignored: Schema.optional(Schema.Boolean),
|
||||
time: Schema.optional(
|
||||
Schema.Struct({
|
||||
start: NonNegativeInt,
|
||||
end: Schema.optional(NonNegativeInt),
|
||||
}),
|
||||
),
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
}).annotate({ identifier: "TextPart" })
|
||||
export type TextPart = Types.DeepMutable<Schema.Schema.Type<typeof TextPart>>
|
||||
|
||||
export const ReasoningPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("reasoning"),
|
||||
text: Schema.String,
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
time: Schema.Struct({
|
||||
start: NonNegativeInt,
|
||||
end: Schema.optional(NonNegativeInt),
|
||||
}),
|
||||
}).annotate({ identifier: "ReasoningPart" })
|
||||
export type ReasoningPart = Types.DeepMutable<Schema.Schema.Type<typeof ReasoningPart>>
|
||||
|
||||
const filePartSourceBase = {
|
||||
text: Schema.Struct({
|
||||
value: Schema.String,
|
||||
start: Schema.Finite,
|
||||
end: Schema.Finite,
|
||||
}).annotate({ identifier: "FilePartSourceText" }),
|
||||
}
|
||||
|
||||
export const Range = Schema.Struct({
|
||||
start: Schema.Struct({ line: NonNegativeInt, character: NonNegativeInt }),
|
||||
end: Schema.Struct({ line: NonNegativeInt, character: NonNegativeInt }),
|
||||
}).annotate({ identifier: "Range" })
|
||||
export type Range = typeof Range.Type
|
||||
|
||||
export const FileSource = Schema.Struct({
|
||||
...filePartSourceBase,
|
||||
type: Schema.Literal("file"),
|
||||
path: Schema.String,
|
||||
}).annotate({ identifier: "FileSource" })
|
||||
|
||||
export const SymbolSource = Schema.Struct({
|
||||
...filePartSourceBase,
|
||||
type: Schema.Literal("symbol"),
|
||||
path: Schema.String,
|
||||
range: Range,
|
||||
name: Schema.String,
|
||||
kind: NonNegativeInt,
|
||||
}).annotate({ identifier: "SymbolSource" })
|
||||
|
||||
export const ResourceSource = Schema.Struct({
|
||||
...filePartSourceBase,
|
||||
type: Schema.Literal("resource"),
|
||||
clientName: Schema.String,
|
||||
uri: Schema.String,
|
||||
}).annotate({ identifier: "ResourceSource" })
|
||||
|
||||
export const FilePartSource = Schema.Union([FileSource, SymbolSource, ResourceSource]).annotate({
|
||||
discriminator: "type",
|
||||
identifier: "FilePartSource",
|
||||
})
|
||||
|
||||
export const FilePart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("file"),
|
||||
mime: Schema.String,
|
||||
filename: Schema.optional(Schema.String),
|
||||
url: Schema.String,
|
||||
source: Schema.optional(FilePartSource),
|
||||
}).annotate({ identifier: "FilePart" })
|
||||
export type FilePart = Types.DeepMutable<Schema.Schema.Type<typeof FilePart>>
|
||||
|
||||
export const AgentPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("agent"),
|
||||
name: Schema.String,
|
||||
source: Schema.optional(
|
||||
Schema.Struct({
|
||||
value: Schema.String,
|
||||
start: NonNegativeInt,
|
||||
end: NonNegativeInt,
|
||||
}),
|
||||
),
|
||||
}).annotate({ identifier: "AgentPart" })
|
||||
export type AgentPart = Types.DeepMutable<Schema.Schema.Type<typeof AgentPart>>
|
||||
|
||||
export const CompactionPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("compaction"),
|
||||
auto: Schema.Boolean,
|
||||
overflow: Schema.optional(Schema.Boolean),
|
||||
tail_start_id: Schema.optional(MessageID),
|
||||
}).annotate({ identifier: "CompactionPart" })
|
||||
export type CompactionPart = Types.DeepMutable<Schema.Schema.Type<typeof CompactionPart>>
|
||||
|
||||
export const SubtaskPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("subtask"),
|
||||
prompt: Schema.String,
|
||||
description: Schema.String,
|
||||
agent: Schema.String,
|
||||
model: Schema.optional(
|
||||
Schema.Struct({
|
||||
providerID: Provider.ID,
|
||||
modelID: Model.ID,
|
||||
}),
|
||||
),
|
||||
command: Schema.optional(Schema.String),
|
||||
}).annotate({ identifier: "SubtaskPart" })
|
||||
export type SubtaskPart = Types.DeepMutable<Schema.Schema.Type<typeof SubtaskPart>>
|
||||
|
||||
export const RetryPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("retry"),
|
||||
attempt: NonNegativeInt,
|
||||
error: APIError.EffectSchema,
|
||||
time: Schema.Struct({
|
||||
created: NonNegativeInt,
|
||||
}),
|
||||
}).annotate({ identifier: "RetryPart" })
|
||||
export type RetryPart = Omit<Types.DeepMutable<Schema.Schema.Type<typeof RetryPart>>, "error"> & {
|
||||
error: APIError
|
||||
}
|
||||
|
||||
export const StepStartPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("step-start"),
|
||||
snapshot: Schema.optional(Schema.String),
|
||||
}).annotate({ identifier: "StepStartPart" })
|
||||
export type StepStartPart = Types.DeepMutable<Schema.Schema.Type<typeof StepStartPart>>
|
||||
|
||||
export const StepFinishPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("step-finish"),
|
||||
reason: Schema.String,
|
||||
snapshot: Schema.optional(Schema.String),
|
||||
cost: Schema.Finite,
|
||||
tokens: Schema.Struct({
|
||||
total: Schema.optional(Schema.Finite),
|
||||
input: Schema.Finite,
|
||||
output: Schema.Finite,
|
||||
reasoning: Schema.Finite,
|
||||
cache: Schema.Struct({
|
||||
read: Schema.Finite,
|
||||
write: Schema.Finite,
|
||||
}),
|
||||
}),
|
||||
}).annotate({ identifier: "StepFinishPart" })
|
||||
export type StepFinishPart = Types.DeepMutable<Schema.Schema.Type<typeof StepFinishPart>>
|
||||
|
||||
export const ToolStatePending = Schema.Struct({
|
||||
status: Schema.Literal("pending"),
|
||||
input: Schema.Record(Schema.String, Schema.Any),
|
||||
raw: Schema.String,
|
||||
}).annotate({ identifier: "ToolStatePending" })
|
||||
export type ToolStatePending = Types.DeepMutable<Schema.Schema.Type<typeof ToolStatePending>>
|
||||
|
||||
export const ToolStateRunning = Schema.Struct({
|
||||
status: Schema.Literal("running"),
|
||||
input: Schema.Record(Schema.String, Schema.Any),
|
||||
title: Schema.optional(Schema.String),
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
time: Schema.Struct({
|
||||
start: NonNegativeInt,
|
||||
}),
|
||||
}).annotate({ identifier: "ToolStateRunning" })
|
||||
export type ToolStateRunning = Types.DeepMutable<Schema.Schema.Type<typeof ToolStateRunning>>
|
||||
|
||||
export const ToolStateCompleted = Schema.Struct({
|
||||
status: Schema.Literal("completed"),
|
||||
input: Schema.Record(Schema.String, Schema.Any),
|
||||
output: Schema.String,
|
||||
title: Schema.String,
|
||||
metadata: Schema.Record(Schema.String, Schema.Any),
|
||||
time: Schema.Struct({
|
||||
start: NonNegativeInt,
|
||||
end: NonNegativeInt,
|
||||
compacted: Schema.optional(NonNegativeInt),
|
||||
}),
|
||||
attachments: Schema.optional(Schema.Array(FilePart)),
|
||||
}).annotate({ identifier: "ToolStateCompleted" })
|
||||
export type ToolStateCompleted = Types.DeepMutable<Schema.Schema.Type<typeof ToolStateCompleted>>
|
||||
|
||||
export const ToolStateError = Schema.Struct({
|
||||
status: Schema.Literal("error"),
|
||||
input: Schema.Record(Schema.String, Schema.Any),
|
||||
error: Schema.String,
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
time: Schema.Struct({
|
||||
start: NonNegativeInt,
|
||||
end: NonNegativeInt,
|
||||
}),
|
||||
}).annotate({ identifier: "ToolStateError" })
|
||||
export type ToolStateError = Types.DeepMutable<Schema.Schema.Type<typeof ToolStateError>>
|
||||
|
||||
export const ToolState = Schema.Union([
|
||||
ToolStatePending,
|
||||
ToolStateRunning,
|
||||
ToolStateCompleted,
|
||||
ToolStateError,
|
||||
]).annotate({
|
||||
discriminator: "status",
|
||||
identifier: "ToolState",
|
||||
})
|
||||
export type ToolState = ToolStatePending | ToolStateRunning | ToolStateCompleted | ToolStateError
|
||||
|
||||
export const ToolPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("tool"),
|
||||
callID: Schema.String,
|
||||
tool: Schema.String,
|
||||
state: ToolState,
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
}).annotate({ identifier: "ToolPart" })
|
||||
export type ToolPart = Omit<Types.DeepMutable<Schema.Schema.Type<typeof ToolPart>>, "state"> & {
|
||||
state: ToolState
|
||||
}
|
||||
|
||||
const messageBase = {
|
||||
id: MessageID,
|
||||
sessionID: partBase.sessionID,
|
||||
}
|
||||
|
||||
export const User = Schema.Struct({
|
||||
...messageBase,
|
||||
role: Schema.Literal("user"),
|
||||
time: Schema.Struct({
|
||||
created: Timestamp,
|
||||
}),
|
||||
format: Schema.optional(Format),
|
||||
summary: Schema.optional(
|
||||
Schema.Struct({
|
||||
title: Schema.optional(Schema.String),
|
||||
body: Schema.optional(Schema.String),
|
||||
diffs: Schema.Array(FileDiff.Info),
|
||||
}),
|
||||
),
|
||||
agent: Schema.String,
|
||||
model: Schema.Struct({
|
||||
providerID: Provider.ID,
|
||||
modelID: Model.ID,
|
||||
variant: Schema.optional(Schema.String),
|
||||
}),
|
||||
system: Schema.optional(Schema.String),
|
||||
tools: Schema.optional(Schema.Record(Schema.String, Schema.Boolean)),
|
||||
}).annotate({ identifier: "UserMessage" })
|
||||
export type User = Types.DeepMutable<Schema.Schema.Type<typeof User>>
|
||||
|
||||
export const Part = Schema.Union([
|
||||
TextPart,
|
||||
SubtaskPart,
|
||||
ReasoningPart,
|
||||
FilePart,
|
||||
ToolPart,
|
||||
StepStartPart,
|
||||
StepFinishPart,
|
||||
SnapshotPart,
|
||||
PatchPart,
|
||||
AgentPart,
|
||||
RetryPart,
|
||||
CompactionPart,
|
||||
]).annotate({ discriminator: "type", identifier: "Part" })
|
||||
export type Part =
|
||||
| TextPart
|
||||
| SubtaskPart
|
||||
| ReasoningPart
|
||||
| FilePart
|
||||
| ToolPart
|
||||
| StepStartPart
|
||||
| StepFinishPart
|
||||
| SnapshotPart
|
||||
| PatchPart
|
||||
| AgentPart
|
||||
| RetryPart
|
||||
| CompactionPart
|
||||
|
||||
const AssistantErrorSchema = Schema.Union([
|
||||
AuthError.EffectSchema,
|
||||
namedError("UnknownError", { message: Schema.String, ref: Schema.optional(Schema.String) }).EffectSchema,
|
||||
OutputLengthError.EffectSchema,
|
||||
AbortedError.EffectSchema,
|
||||
StructuredOutputError.EffectSchema,
|
||||
ContextOverflowError.EffectSchema,
|
||||
ContentFilterError.EffectSchema,
|
||||
APIError.EffectSchema,
|
||||
]).annotate({ discriminator: "name" })
|
||||
type AssistantError = Schema.Schema.Type<typeof AssistantErrorSchema>
|
||||
|
||||
export const TextPartInput = Schema.Struct({
|
||||
id: Schema.optional(PartID),
|
||||
type: Schema.Literal("text"),
|
||||
text: Schema.String,
|
||||
synthetic: Schema.optional(Schema.Boolean),
|
||||
ignored: Schema.optional(Schema.Boolean),
|
||||
time: Schema.optional(
|
||||
Schema.Struct({
|
||||
start: NonNegativeInt,
|
||||
end: Schema.optional(NonNegativeInt),
|
||||
}),
|
||||
),
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
}).annotate({ identifier: "TextPartInput" })
|
||||
export type TextPartInput = Types.DeepMutable<Schema.Schema.Type<typeof TextPartInput>>
|
||||
|
||||
export const FilePartInput = Schema.Struct({
|
||||
id: Schema.optional(PartID),
|
||||
type: Schema.Literal("file"),
|
||||
mime: Schema.String,
|
||||
filename: Schema.optional(Schema.String),
|
||||
url: Schema.String,
|
||||
source: Schema.optional(FilePartSource),
|
||||
}).annotate({ identifier: "FilePartInput" })
|
||||
export type FilePartInput = Types.DeepMutable<Schema.Schema.Type<typeof FilePartInput>>
|
||||
|
||||
export const AgentPartInput = Schema.Struct({
|
||||
id: Schema.optional(PartID),
|
||||
type: Schema.Literal("agent"),
|
||||
name: Schema.String,
|
||||
source: Schema.optional(
|
||||
Schema.Struct({
|
||||
value: Schema.String,
|
||||
start: NonNegativeInt,
|
||||
end: NonNegativeInt,
|
||||
}),
|
||||
),
|
||||
}).annotate({ identifier: "AgentPartInput" })
|
||||
export type AgentPartInput = Types.DeepMutable<Schema.Schema.Type<typeof AgentPartInput>>
|
||||
|
||||
export const SubtaskPartInput = Schema.Struct({
|
||||
id: Schema.optional(PartID),
|
||||
type: Schema.Literal("subtask"),
|
||||
prompt: Schema.String,
|
||||
description: Schema.String,
|
||||
agent: Schema.String,
|
||||
model: Schema.optional(
|
||||
Schema.Struct({
|
||||
providerID: Provider.ID,
|
||||
modelID: Model.ID,
|
||||
}),
|
||||
),
|
||||
command: Schema.optional(Schema.String),
|
||||
}).annotate({ identifier: "SubtaskPartInput" })
|
||||
export type SubtaskPartInput = Types.DeepMutable<Schema.Schema.Type<typeof SubtaskPartInput>>
|
||||
|
||||
export const Assistant = Schema.Struct({
|
||||
...messageBase,
|
||||
role: Schema.Literal("assistant"),
|
||||
time: Schema.Struct({
|
||||
created: NonNegativeInt,
|
||||
completed: Schema.optional(NonNegativeInt),
|
||||
}),
|
||||
error: Schema.optional(AssistantErrorSchema),
|
||||
parentID: MessageID,
|
||||
modelID: Model.ID,
|
||||
providerID: Provider.ID,
|
||||
mode: Schema.String,
|
||||
agent: Schema.String,
|
||||
path: Schema.Struct({
|
||||
cwd: Schema.String,
|
||||
root: Schema.String,
|
||||
}),
|
||||
summary: Schema.optional(Schema.Boolean),
|
||||
cost: Schema.Finite,
|
||||
tokens: Schema.Struct({
|
||||
total: Schema.optional(Schema.Finite),
|
||||
input: Schema.Finite,
|
||||
output: Schema.Finite,
|
||||
reasoning: Schema.Finite,
|
||||
cache: Schema.Struct({
|
||||
read: Schema.Finite,
|
||||
write: Schema.Finite,
|
||||
}),
|
||||
}),
|
||||
structured: Schema.optional(Schema.Any),
|
||||
variant: Schema.optional(Schema.String),
|
||||
finish: Schema.optional(Schema.String),
|
||||
}).annotate({ identifier: "AssistantMessage" })
|
||||
export type Assistant = Omit<Types.DeepMutable<Schema.Schema.Type<typeof Assistant>>, "error"> & {
|
||||
error?: AssistantError
|
||||
}
|
||||
|
||||
export const Info = Schema.Union([User, Assistant]).annotate({ discriminator: "role", identifier: "Message" })
|
||||
export type Info = User | Assistant
|
||||
|
||||
export const WithParts = Schema.Struct({
|
||||
info: Info,
|
||||
parts: Schema.Array(Part),
|
||||
})
|
||||
export type WithParts = {
|
||||
info: Info
|
||||
parts: Part[]
|
||||
}
|
||||
|
||||
const options = {
|
||||
durable: {
|
||||
aggregate: "sessionID",
|
||||
version: 1,
|
||||
},
|
||||
} as const
|
||||
|
||||
const SessionSummary = Schema.Struct({
|
||||
additions: Schema.Finite,
|
||||
deletions: Schema.Finite,
|
||||
files: Schema.Finite,
|
||||
diffs: optionalOmitUndefined(Schema.Array(FileDiff.Info)),
|
||||
})
|
||||
|
||||
const SessionTokens = Schema.Struct({
|
||||
input: Schema.Finite,
|
||||
output: Schema.Finite,
|
||||
reasoning: Schema.Finite,
|
||||
cache: Schema.Struct({
|
||||
read: Schema.Finite,
|
||||
write: Schema.Finite,
|
||||
}),
|
||||
})
|
||||
|
||||
const SessionShare = Schema.Struct({
|
||||
url: Schema.String,
|
||||
})
|
||||
|
||||
const SessionRevert = Schema.Struct({
|
||||
messageID: MessageID,
|
||||
partID: optionalOmitUndefined(PartID),
|
||||
snapshot: optionalOmitUndefined(Schema.String),
|
||||
diff: optionalOmitUndefined(Schema.String),
|
||||
})
|
||||
|
||||
const SessionModel = Schema.Struct({
|
||||
id: Model.ID,
|
||||
providerID: Provider.ID,
|
||||
variant: optionalOmitUndefined(Schema.String),
|
||||
})
|
||||
|
||||
export const SessionInfo = Schema.Struct({
|
||||
id: SessionID,
|
||||
slug: Schema.String,
|
||||
projectID: Project.ID,
|
||||
workspaceID: optionalOmitUndefined(WorkspaceID),
|
||||
directory: Schema.String,
|
||||
path: optionalOmitUndefined(Schema.String),
|
||||
parentID: optionalOmitUndefined(SessionID),
|
||||
summary: optionalOmitUndefined(SessionSummary),
|
||||
cost: optionalOmitUndefined(Schema.Finite),
|
||||
tokens: optionalOmitUndefined(SessionTokens),
|
||||
share: optionalOmitUndefined(SessionShare),
|
||||
title: Schema.String,
|
||||
agent: optionalOmitUndefined(Schema.String),
|
||||
model: optionalOmitUndefined(SessionModel),
|
||||
version: Schema.String,
|
||||
metadata: optionalOmitUndefined(Schema.Record(Schema.String, Schema.Any)),
|
||||
time: Schema.Struct({
|
||||
created: NonNegativeInt,
|
||||
updated: NonNegativeInt,
|
||||
compacting: optionalOmitUndefined(NonNegativeInt),
|
||||
archived: optionalOmitUndefined(Schema.Finite),
|
||||
}),
|
||||
permission: optionalOmitUndefined(PermissionV1.Ruleset),
|
||||
revert: optionalOmitUndefined(SessionRevert),
|
||||
}).annotate({ identifier: "Session" })
|
||||
export type SessionInfo = typeof SessionInfo.Type
|
||||
|
||||
const events = {
|
||||
Created: define({
|
||||
type: "session.created",
|
||||
...options,
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
info: SessionInfo,
|
||||
},
|
||||
}),
|
||||
Updated: define({
|
||||
type: "session.updated",
|
||||
...options,
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
info: SessionInfo,
|
||||
},
|
||||
}),
|
||||
Deleted: define({
|
||||
type: "session.deleted",
|
||||
...options,
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
info: SessionInfo,
|
||||
},
|
||||
}),
|
||||
MessageUpdated: define({
|
||||
type: "message.updated",
|
||||
...options,
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
info: Info,
|
||||
},
|
||||
}),
|
||||
MessageRemoved: define({
|
||||
type: "message.removed",
|
||||
...options,
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
messageID: MessageID,
|
||||
},
|
||||
}),
|
||||
PartUpdated: define({
|
||||
type: "message.part.updated",
|
||||
...options,
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
part: Part,
|
||||
time: Schema.Finite,
|
||||
},
|
||||
}),
|
||||
PartRemoved: define({
|
||||
type: "message.part.removed",
|
||||
...options,
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
messageID: MessageID,
|
||||
partID: PartID,
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
export const PartDelta = define({
|
||||
type: "message.part.delta",
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
messageID: MessageID,
|
||||
partID: PartID,
|
||||
field: Schema.String,
|
||||
delta: Schema.String,
|
||||
},
|
||||
})
|
||||
|
||||
export const Diff = define({
|
||||
type: "session.diff",
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
diff: Schema.Array(FileDiff.Info),
|
||||
},
|
||||
})
|
||||
|
||||
export const Error = define({
|
||||
type: "session.error",
|
||||
schema: {
|
||||
sessionID: Schema.optional(SessionID),
|
||||
error: Assistant.fields.error,
|
||||
},
|
||||
})
|
||||
|
||||
export const Event = {
|
||||
...events,
|
||||
PartDelta,
|
||||
Diff,
|
||||
Error,
|
||||
Definitions: inventory(
|
||||
events.Created,
|
||||
events.Updated,
|
||||
events.Deleted,
|
||||
events.MessageUpdated,
|
||||
events.MessageRemoved,
|
||||
events.PartUpdated,
|
||||
events.PartRemoved,
|
||||
PartDelta,
|
||||
Diff,
|
||||
Error,
|
||||
),
|
||||
}
|
||||
export * from "./v1/session"
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Agent } from "./agent"
|
||||
import { Location } from "./location"
|
||||
import { Model } from "./model"
|
||||
import { Project } from "./project"
|
||||
import { DateTimeUtcFromMillis, optionalOmitUndefined, RelativePath } from "./schema"
|
||||
import { DateTimeUtcFromMillis, optional, RelativePath } from "./schema"
|
||||
import { SessionEvent } from "./session-event"
|
||||
import { SessionID } from "./session-id"
|
||||
import { Revert } from "./revert"
|
||||
@@ -18,10 +18,10 @@ export const Event = SessionEvent
|
||||
export interface Info extends Schema.Schema.Type<typeof Info> {}
|
||||
export const Info = Schema.Struct({
|
||||
id: ID,
|
||||
parentID: ID.pipe(optionalOmitUndefined),
|
||||
parentID: ID.pipe(optional),
|
||||
projectID: Project.ID,
|
||||
agent: Agent.ID.pipe(Schema.optional),
|
||||
model: Model.Ref.pipe(Schema.optional),
|
||||
agent: Agent.ID.pipe(optional),
|
||||
model: Model.Ref.pipe(optional),
|
||||
cost: Schema.Finite,
|
||||
tokens: Schema.Struct({
|
||||
input: Schema.Finite,
|
||||
@@ -35,17 +35,17 @@ export const Info = Schema.Struct({
|
||||
time: Schema.Struct({
|
||||
created: DateTimeUtcFromMillis,
|
||||
updated: DateTimeUtcFromMillis,
|
||||
archived: DateTimeUtcFromMillis.pipe(Schema.optional),
|
||||
archived: DateTimeUtcFromMillis.pipe(optional),
|
||||
}),
|
||||
title: Schema.String,
|
||||
location: Location.Ref,
|
||||
subpath: RelativePath.pipe(Schema.optional),
|
||||
revert: Revert.State.pipe(Schema.optional),
|
||||
subpath: RelativePath.pipe(optional),
|
||||
revert: Revert.State.pipe(optional),
|
||||
}).annotate({ identifier: "SessionV2.Info" })
|
||||
|
||||
export const ListAnchor = Schema.Struct({
|
||||
id: ID,
|
||||
time: Schema.Finite,
|
||||
direction: Schema.Literals(["previous", "next"]),
|
||||
})
|
||||
export type ListAnchor = typeof ListAnchor.Type
|
||||
}).annotate({ identifier: "Session.ListAnchor" })
|
||||
export interface ListAnchor extends Schema.Schema.Type<typeof ListAnchor> {}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export * as Skill from "./skill"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { AbsolutePath } from "./schema"
|
||||
|
||||
export interface DirectorySource extends Schema.Schema.Type<typeof DirectorySource> {}
|
||||
@@ -18,8 +19,8 @@ export const UrlSource = Schema.Struct({
|
||||
export interface Info extends Schema.Schema.Type<typeof Info> {}
|
||||
export const Info = Schema.Struct({
|
||||
name: Schema.String,
|
||||
description: Schema.String.pipe(Schema.optional),
|
||||
slash: Schema.Boolean.pipe(Schema.optional),
|
||||
description: Schema.String.pipe(optional),
|
||||
slash: Schema.Boolean.pipe(optional),
|
||||
location: AbsolutePath,
|
||||
content: Schema.String,
|
||||
}).annotate({ identifier: "SkillV2.Info" })
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export * as TuiEvent from "./tui-event"
|
||||
|
||||
import { Effect, Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { Event } from "./event"
|
||||
import { PositiveInt } from "./schema"
|
||||
import { SessionID } from "./session-id"
|
||||
@@ -39,7 +40,7 @@ export const CommandExecute = Event.define({
|
||||
export const ToastShow = Event.define({
|
||||
type: "tui.toast.show",
|
||||
schema: {
|
||||
title: Schema.optional(Schema.String),
|
||||
title: optional(Schema.String),
|
||||
message: Schema.String,
|
||||
variant: Schema.Literals(["info", "success", "warning", "error"]),
|
||||
duration: PositiveInt.pipe(Schema.withDecodingDefault(Effect.succeed(DEFAULT_TOAST_DURATION))).annotate({
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
export * as LegacyEvent from "./legacy-event"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { define, inventory } from "../event"
|
||||
import { SessionID } from "../session-id"
|
||||
import { SessionV1 } from "./session"
|
||||
|
||||
export const CommandExecuted = define({
|
||||
type: "command.executed",
|
||||
schema: {
|
||||
name: Schema.String,
|
||||
sessionID: SessionID,
|
||||
arguments: Schema.String,
|
||||
messageID: SessionV1.MessageID,
|
||||
},
|
||||
})
|
||||
|
||||
export const Definitions = inventory(CommandExecuted)
|
||||
@@ -0,0 +1,66 @@
|
||||
export * as PermissionV1 from "./permission"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { define, inventory } from "../event"
|
||||
import { ascending } from "../identifier"
|
||||
import { Project } from "../project"
|
||||
import { statics } from "../schema"
|
||||
import { SessionID } from "../session-id"
|
||||
|
||||
export const ID = Schema.String.check(Schema.isStartsWith("per")).pipe(
|
||||
Schema.brand("PermissionID"),
|
||||
statics((schema) => ({ ascending: (id?: string) => schema.make(id ?? "per_" + ascending()) })),
|
||||
)
|
||||
export type ID = typeof ID.Type
|
||||
|
||||
export const Action = Schema.Literals(["allow", "deny", "ask"]).annotate({ identifier: "PermissionAction" })
|
||||
export type Action = typeof Action.Type
|
||||
|
||||
export const Rule = Schema.Struct({ permission: Schema.String, pattern: Schema.String, action: Action }).annotate({
|
||||
identifier: "PermissionRule",
|
||||
})
|
||||
export type Rule = typeof Rule.Type
|
||||
|
||||
export const Ruleset = Schema.Array(Rule).annotate({ identifier: "PermissionRuleset" })
|
||||
export type Ruleset = typeof Ruleset.Type
|
||||
|
||||
export const Request = Schema.Struct({
|
||||
id: ID,
|
||||
sessionID: SessionID,
|
||||
permission: Schema.String,
|
||||
patterns: Schema.Array(Schema.String),
|
||||
metadata: Schema.Record(Schema.String, Schema.Unknown),
|
||||
always: Schema.Array(Schema.String),
|
||||
tool: Schema.optional(Schema.Struct({ messageID: Schema.String, callID: Schema.String })),
|
||||
}).annotate({ identifier: "PermissionRequest" })
|
||||
export type Request = typeof Request.Type
|
||||
|
||||
export const Reply = Schema.Literals(["once", "always", "reject"])
|
||||
export type Reply = typeof Reply.Type
|
||||
|
||||
export const ReplyBody = Schema.Struct({ reply: Reply, message: Schema.optional(Schema.String) }).annotate({
|
||||
identifier: "PermissionReplyBody",
|
||||
})
|
||||
export type ReplyBody = typeof ReplyBody.Type
|
||||
|
||||
export const Approval = Schema.Struct({ projectID: Project.ID, patterns: Schema.Array(Schema.String) }).annotate({
|
||||
identifier: "PermissionApproval",
|
||||
})
|
||||
export type Approval = typeof Approval.Type
|
||||
|
||||
export const AskInput = Schema.Struct({ ...Request.fields, id: Schema.optional(ID), ruleset: Ruleset }).annotate({
|
||||
identifier: "PermissionAskInput",
|
||||
})
|
||||
export type AskInput = typeof AskInput.Type
|
||||
|
||||
export const ReplyInput = Schema.Struct({ requestID: ID, ...ReplyBody.fields }).annotate({
|
||||
identifier: "PermissionReplyInput",
|
||||
})
|
||||
export type ReplyInput = typeof ReplyInput.Type
|
||||
|
||||
const Asked = define({ type: "permission.asked", schema: Request.fields })
|
||||
const Replied = define({
|
||||
type: "permission.replied",
|
||||
schema: { sessionID: SessionID, requestID: ID, reply: Reply },
|
||||
})
|
||||
export const Event = { Asked, Replied, Definitions: inventory(Asked, Replied) }
|
||||
@@ -0,0 +1,66 @@
|
||||
export * as QuestionV1 from "./question"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { define, inventory } from "../event"
|
||||
import { ascending } from "../identifier"
|
||||
import { statics } from "../schema"
|
||||
import { SessionID } from "../session-id"
|
||||
import { SessionV1 } from "./session"
|
||||
|
||||
export const ID = Schema.String.check(Schema.isStartsWith("que")).pipe(
|
||||
Schema.brand("QuestionID"),
|
||||
statics((schema) => ({ ascending: (id?: string) => schema.make(id ?? "que_" + ascending()) })),
|
||||
)
|
||||
|
||||
export const Option = Schema.Struct({
|
||||
label: Schema.String.annotate({ description: "Display text (1-5 words, concise)" }),
|
||||
description: Schema.String.annotate({ description: "Explanation of choice" }),
|
||||
}).annotate({ identifier: "QuestionOption" })
|
||||
|
||||
const base = {
|
||||
question: Schema.String.annotate({ description: "Complete question" }),
|
||||
header: Schema.String.annotate({ description: "Very short label (max 30 chars)" }),
|
||||
options: Schema.Array(Option).annotate({ description: "Available choices" }),
|
||||
multiple: Schema.optional(Schema.Boolean).annotate({ description: "Allow selecting multiple choices" }),
|
||||
}
|
||||
|
||||
export const Info = Schema.Struct({
|
||||
...base,
|
||||
custom: Schema.optional(Schema.Boolean).annotate({ description: "Allow typing a custom answer (default: true)" }),
|
||||
}).annotate({ identifier: "QuestionInfo" })
|
||||
export const Prompt = Schema.Struct(base).annotate({ identifier: "QuestionPrompt" })
|
||||
export const Tool = Schema.Struct({ messageID: SessionV1.MessageID, callID: Schema.String }).annotate({
|
||||
identifier: "QuestionTool",
|
||||
})
|
||||
export const Request = Schema.Struct({
|
||||
id: ID,
|
||||
sessionID: SessionID,
|
||||
questions: Schema.Array(Info).annotate({ description: "Questions to ask" }),
|
||||
tool: Schema.optional(Tool),
|
||||
}).annotate({ identifier: "QuestionRequest" })
|
||||
export const Answer = Schema.Array(Schema.String).annotate({ identifier: "QuestionAnswer" })
|
||||
export const Reply = Schema.Struct({
|
||||
answers: Schema.Array(Answer).annotate({
|
||||
description: "User answers in order of questions (each answer is an array of selected labels)",
|
||||
}),
|
||||
}).annotate({ identifier: "QuestionReply" })
|
||||
export const Replied = Schema.Struct({
|
||||
sessionID: SessionID,
|
||||
requestID: ID,
|
||||
answers: Schema.Array(Answer),
|
||||
}).annotate({
|
||||
identifier: "QuestionReplied",
|
||||
})
|
||||
export const Rejected = Schema.Struct({ sessionID: SessionID, requestID: ID }).annotate({
|
||||
identifier: "QuestionRejected",
|
||||
})
|
||||
|
||||
const Asked = define({ type: "question.asked", schema: Request.fields })
|
||||
const RepliedEvent = define({ type: "question.replied", schema: Replied.fields })
|
||||
const RejectedEvent = define({ type: "question.rejected", schema: Rejected.fields })
|
||||
export const Event = {
|
||||
Asked,
|
||||
Replied: RepliedEvent,
|
||||
Rejected: RejectedEvent,
|
||||
Definitions: inventory(Asked, RepliedEvent, RejectedEvent),
|
||||
}
|
||||
@@ -0,0 +1,676 @@
|
||||
export * as SessionV1 from "./session"
|
||||
|
||||
import { Effect, Schema, Types } from "effect"
|
||||
import { define, inventory } from "../event"
|
||||
import { FileDiff } from "../file-diff"
|
||||
import { Project } from "../project"
|
||||
import { Provider } from "../provider"
|
||||
import { Model } from "../model"
|
||||
import { NonNegativeInt, optional, statics } from "../schema"
|
||||
import { ascending } from "../identifier"
|
||||
import { SessionID } from "../session-id"
|
||||
import { WorkspaceID } from "../workspace-id"
|
||||
import { PermissionV1 } from "./permission"
|
||||
|
||||
const Timestamp = Schema.Finite.check(Schema.isGreaterThanOrEqualTo(0))
|
||||
|
||||
export const MessageID = Schema.String.check(Schema.isStartsWith("msg")).pipe(
|
||||
Schema.brand("MessageID"),
|
||||
statics((schema) => ({ ascending: (id?: string) => schema.make(id ?? "msg_" + ascending()) })),
|
||||
)
|
||||
export type MessageID = typeof MessageID.Type
|
||||
|
||||
export const PartID = Schema.String.check(Schema.isStartsWith("prt")).pipe(
|
||||
Schema.brand("PartID"),
|
||||
statics((schema) => ({ ascending: (id?: string) => schema.make(id ?? "prt_" + ascending()) })),
|
||||
)
|
||||
export type PartID = typeof PartID.Type
|
||||
|
||||
const namedError = <Name extends string, Fields extends Schema.Struct.Fields>(name: Name, fields: Fields) => {
|
||||
const schema = Schema.Struct({ name: Schema.Literal(name), data: Schema.Struct(fields) }).annotate({
|
||||
identifier: name,
|
||||
})
|
||||
return { Schema: schema, EffectSchema: schema }
|
||||
}
|
||||
|
||||
export const OutputLengthError = namedError("MessageOutputLengthError", {})
|
||||
|
||||
export const AuthError = namedError("ProviderAuthError", {
|
||||
providerID: Schema.String,
|
||||
message: Schema.String,
|
||||
})
|
||||
|
||||
export const AbortedError = namedError("MessageAbortedError", { message: Schema.String })
|
||||
export const StructuredOutputError = namedError("StructuredOutputError", {
|
||||
message: Schema.String,
|
||||
retries: NonNegativeInt,
|
||||
})
|
||||
export const APIError = namedError("APIError", {
|
||||
message: Schema.String,
|
||||
statusCode: Schema.optional(NonNegativeInt),
|
||||
isRetryable: Schema.Boolean,
|
||||
responseHeaders: Schema.optional(Schema.Record(Schema.String, Schema.String)),
|
||||
responseBody: Schema.optional(Schema.String),
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.String)),
|
||||
})
|
||||
export type APIError = Schema.Schema.Type<typeof APIError.Schema>
|
||||
export const ContextOverflowError = namedError("ContextOverflowError", {
|
||||
message: Schema.String,
|
||||
responseBody: Schema.optional(Schema.String),
|
||||
})
|
||||
export const ContentFilterError = namedError("ContentFilterError", {
|
||||
message: Schema.String,
|
||||
})
|
||||
|
||||
export class OutputFormatText extends Schema.Class<OutputFormatText>("OutputFormatText")({
|
||||
type: Schema.Literal("text"),
|
||||
}) {}
|
||||
|
||||
export class OutputFormatJsonSchema extends Schema.Class<OutputFormatJsonSchema>("OutputFormatJsonSchema")({
|
||||
type: Schema.Literal("json_schema"),
|
||||
schema: Schema.Record(Schema.String, Schema.Any).annotate({ identifier: "JSONSchema" }),
|
||||
retryCount: NonNegativeInt.pipe(Schema.optional, Schema.withDecodingDefault(Effect.succeed(2))),
|
||||
}) {}
|
||||
|
||||
export const Format = Schema.Union([OutputFormatText, OutputFormatJsonSchema]).annotate({
|
||||
discriminator: "type",
|
||||
identifier: "OutputFormat",
|
||||
})
|
||||
export type OutputFormat = Schema.Schema.Type<typeof Format>
|
||||
|
||||
const partBase = {
|
||||
id: PartID,
|
||||
sessionID: SessionID,
|
||||
messageID: MessageID,
|
||||
}
|
||||
|
||||
export const SnapshotPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("snapshot"),
|
||||
snapshot: Schema.String,
|
||||
}).annotate({ identifier: "SnapshotPart" })
|
||||
export type SnapshotPart = Types.DeepMutable<Schema.Schema.Type<typeof SnapshotPart>>
|
||||
|
||||
export const PatchPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("patch"),
|
||||
hash: Schema.String,
|
||||
files: Schema.Array(Schema.String),
|
||||
}).annotate({ identifier: "PatchPart" })
|
||||
export type PatchPart = Types.DeepMutable<Schema.Schema.Type<typeof PatchPart>>
|
||||
|
||||
export const TextPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("text"),
|
||||
text: Schema.String,
|
||||
synthetic: Schema.optional(Schema.Boolean),
|
||||
ignored: Schema.optional(Schema.Boolean),
|
||||
time: Schema.optional(
|
||||
Schema.Struct({
|
||||
start: NonNegativeInt,
|
||||
end: Schema.optional(NonNegativeInt),
|
||||
}),
|
||||
),
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
}).annotate({ identifier: "TextPart" })
|
||||
export type TextPart = Types.DeepMutable<Schema.Schema.Type<typeof TextPart>>
|
||||
|
||||
export const ReasoningPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("reasoning"),
|
||||
text: Schema.String,
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
time: Schema.Struct({
|
||||
start: NonNegativeInt,
|
||||
end: Schema.optional(NonNegativeInt),
|
||||
}),
|
||||
}).annotate({ identifier: "ReasoningPart" })
|
||||
export type ReasoningPart = Types.DeepMutable<Schema.Schema.Type<typeof ReasoningPart>>
|
||||
|
||||
const filePartSourceBase = {
|
||||
text: Schema.Struct({
|
||||
value: Schema.String,
|
||||
start: Schema.Finite,
|
||||
end: Schema.Finite,
|
||||
}).annotate({ identifier: "FilePartSourceText" }),
|
||||
}
|
||||
|
||||
export const Range = Schema.Struct({
|
||||
start: Schema.Struct({ line: NonNegativeInt, character: NonNegativeInt }),
|
||||
end: Schema.Struct({ line: NonNegativeInt, character: NonNegativeInt }),
|
||||
}).annotate({ identifier: "Range" })
|
||||
export type Range = typeof Range.Type
|
||||
|
||||
export const FileSource = Schema.Struct({
|
||||
...filePartSourceBase,
|
||||
type: Schema.Literal("file"),
|
||||
path: Schema.String,
|
||||
}).annotate({ identifier: "FileSource" })
|
||||
|
||||
export const SymbolSource = Schema.Struct({
|
||||
...filePartSourceBase,
|
||||
type: Schema.Literal("symbol"),
|
||||
path: Schema.String,
|
||||
range: Range,
|
||||
name: Schema.String,
|
||||
kind: NonNegativeInt,
|
||||
}).annotate({ identifier: "SymbolSource" })
|
||||
|
||||
export const ResourceSource = Schema.Struct({
|
||||
...filePartSourceBase,
|
||||
type: Schema.Literal("resource"),
|
||||
clientName: Schema.String,
|
||||
uri: Schema.String,
|
||||
}).annotate({ identifier: "ResourceSource" })
|
||||
|
||||
export const FilePartSource = Schema.Union([FileSource, SymbolSource, ResourceSource]).annotate({
|
||||
discriminator: "type",
|
||||
identifier: "FilePartSource",
|
||||
})
|
||||
|
||||
export const FilePart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("file"),
|
||||
mime: Schema.String,
|
||||
filename: Schema.optional(Schema.String),
|
||||
url: Schema.String,
|
||||
source: Schema.optional(FilePartSource),
|
||||
}).annotate({ identifier: "FilePart" })
|
||||
export type FilePart = Types.DeepMutable<Schema.Schema.Type<typeof FilePart>>
|
||||
|
||||
export const AgentPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("agent"),
|
||||
name: Schema.String,
|
||||
source: Schema.optional(
|
||||
Schema.Struct({
|
||||
value: Schema.String,
|
||||
start: NonNegativeInt,
|
||||
end: NonNegativeInt,
|
||||
}),
|
||||
),
|
||||
}).annotate({ identifier: "AgentPart" })
|
||||
export type AgentPart = Types.DeepMutable<Schema.Schema.Type<typeof AgentPart>>
|
||||
|
||||
export const CompactionPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("compaction"),
|
||||
auto: Schema.Boolean,
|
||||
overflow: Schema.optional(Schema.Boolean),
|
||||
tail_start_id: Schema.optional(MessageID),
|
||||
}).annotate({ identifier: "CompactionPart" })
|
||||
export type CompactionPart = Types.DeepMutable<Schema.Schema.Type<typeof CompactionPart>>
|
||||
|
||||
export const SubtaskPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("subtask"),
|
||||
prompt: Schema.String,
|
||||
description: Schema.String,
|
||||
agent: Schema.String,
|
||||
model: Schema.optional(
|
||||
Schema.Struct({
|
||||
providerID: Provider.ID,
|
||||
modelID: Model.ID,
|
||||
}),
|
||||
),
|
||||
command: Schema.optional(Schema.String),
|
||||
}).annotate({ identifier: "SubtaskPart" })
|
||||
export type SubtaskPart = Types.DeepMutable<Schema.Schema.Type<typeof SubtaskPart>>
|
||||
|
||||
export const RetryPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("retry"),
|
||||
attempt: NonNegativeInt,
|
||||
error: APIError.EffectSchema,
|
||||
time: Schema.Struct({
|
||||
created: NonNegativeInt,
|
||||
}),
|
||||
}).annotate({ identifier: "RetryPart" })
|
||||
export type RetryPart = Omit<Types.DeepMutable<Schema.Schema.Type<typeof RetryPart>>, "error"> & {
|
||||
error: APIError
|
||||
}
|
||||
|
||||
export const StepStartPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("step-start"),
|
||||
snapshot: Schema.optional(Schema.String),
|
||||
}).annotate({ identifier: "StepStartPart" })
|
||||
export type StepStartPart = Types.DeepMutable<Schema.Schema.Type<typeof StepStartPart>>
|
||||
|
||||
export const StepFinishPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("step-finish"),
|
||||
reason: Schema.String,
|
||||
snapshot: Schema.optional(Schema.String),
|
||||
cost: Schema.Finite,
|
||||
tokens: Schema.Struct({
|
||||
total: Schema.optional(Schema.Finite),
|
||||
input: Schema.Finite,
|
||||
output: Schema.Finite,
|
||||
reasoning: Schema.Finite,
|
||||
cache: Schema.Struct({
|
||||
read: Schema.Finite,
|
||||
write: Schema.Finite,
|
||||
}),
|
||||
}),
|
||||
}).annotate({ identifier: "StepFinishPart" })
|
||||
export type StepFinishPart = Types.DeepMutable<Schema.Schema.Type<typeof StepFinishPart>>
|
||||
|
||||
export const ToolStatePending = Schema.Struct({
|
||||
status: Schema.Literal("pending"),
|
||||
input: Schema.Record(Schema.String, Schema.Any),
|
||||
raw: Schema.String,
|
||||
}).annotate({ identifier: "ToolStatePending" })
|
||||
export type ToolStatePending = Types.DeepMutable<Schema.Schema.Type<typeof ToolStatePending>>
|
||||
|
||||
export const ToolStateRunning = Schema.Struct({
|
||||
status: Schema.Literal("running"),
|
||||
input: Schema.Record(Schema.String, Schema.Any),
|
||||
title: Schema.optional(Schema.String),
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
time: Schema.Struct({
|
||||
start: NonNegativeInt,
|
||||
}),
|
||||
}).annotate({ identifier: "ToolStateRunning" })
|
||||
export type ToolStateRunning = Types.DeepMutable<Schema.Schema.Type<typeof ToolStateRunning>>
|
||||
|
||||
export const ToolStateCompleted = Schema.Struct({
|
||||
status: Schema.Literal("completed"),
|
||||
input: Schema.Record(Schema.String, Schema.Any),
|
||||
output: Schema.String,
|
||||
title: Schema.String,
|
||||
metadata: Schema.Record(Schema.String, Schema.Any),
|
||||
time: Schema.Struct({
|
||||
start: NonNegativeInt,
|
||||
end: NonNegativeInt,
|
||||
compacted: Schema.optional(NonNegativeInt),
|
||||
}),
|
||||
attachments: Schema.optional(Schema.Array(FilePart)),
|
||||
}).annotate({ identifier: "ToolStateCompleted" })
|
||||
export type ToolStateCompleted = Types.DeepMutable<Schema.Schema.Type<typeof ToolStateCompleted>>
|
||||
|
||||
export const ToolStateError = Schema.Struct({
|
||||
status: Schema.Literal("error"),
|
||||
input: Schema.Record(Schema.String, Schema.Any),
|
||||
error: Schema.String,
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
time: Schema.Struct({
|
||||
start: NonNegativeInt,
|
||||
end: NonNegativeInt,
|
||||
}),
|
||||
}).annotate({ identifier: "ToolStateError" })
|
||||
export type ToolStateError = Types.DeepMutable<Schema.Schema.Type<typeof ToolStateError>>
|
||||
|
||||
export const ToolState = Schema.Union([
|
||||
ToolStatePending,
|
||||
ToolStateRunning,
|
||||
ToolStateCompleted,
|
||||
ToolStateError,
|
||||
]).annotate({
|
||||
discriminator: "status",
|
||||
identifier: "ToolState",
|
||||
})
|
||||
export type ToolState = ToolStatePending | ToolStateRunning | ToolStateCompleted | ToolStateError
|
||||
|
||||
export const ToolPart = Schema.Struct({
|
||||
...partBase,
|
||||
type: Schema.Literal("tool"),
|
||||
callID: Schema.String,
|
||||
tool: Schema.String,
|
||||
state: ToolState,
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
}).annotate({ identifier: "ToolPart" })
|
||||
export type ToolPart = Omit<Types.DeepMutable<Schema.Schema.Type<typeof ToolPart>>, "state"> & {
|
||||
state: ToolState
|
||||
}
|
||||
|
||||
const messageBase = {
|
||||
id: MessageID,
|
||||
sessionID: partBase.sessionID,
|
||||
}
|
||||
|
||||
export const User = Schema.Struct({
|
||||
...messageBase,
|
||||
role: Schema.Literal("user"),
|
||||
time: Schema.Struct({
|
||||
created: Timestamp,
|
||||
}),
|
||||
format: Schema.optional(Format),
|
||||
summary: Schema.optional(
|
||||
Schema.Struct({
|
||||
title: Schema.optional(Schema.String),
|
||||
body: Schema.optional(Schema.String),
|
||||
diffs: Schema.Array(FileDiff.Info),
|
||||
}),
|
||||
),
|
||||
agent: Schema.String,
|
||||
model: Schema.Struct({
|
||||
providerID: Provider.ID,
|
||||
modelID: Model.ID,
|
||||
variant: Schema.optional(Schema.String),
|
||||
}),
|
||||
system: Schema.optional(Schema.String),
|
||||
tools: Schema.optional(Schema.Record(Schema.String, Schema.Boolean)),
|
||||
}).annotate({ identifier: "UserMessage" })
|
||||
export type User = Types.DeepMutable<Schema.Schema.Type<typeof User>>
|
||||
|
||||
export const Part = Schema.Union([
|
||||
TextPart,
|
||||
SubtaskPart,
|
||||
ReasoningPart,
|
||||
FilePart,
|
||||
ToolPart,
|
||||
StepStartPart,
|
||||
StepFinishPart,
|
||||
SnapshotPart,
|
||||
PatchPart,
|
||||
AgentPart,
|
||||
RetryPart,
|
||||
CompactionPart,
|
||||
]).annotate({ discriminator: "type", identifier: "Part" })
|
||||
export type Part =
|
||||
| TextPart
|
||||
| SubtaskPart
|
||||
| ReasoningPart
|
||||
| FilePart
|
||||
| ToolPart
|
||||
| StepStartPart
|
||||
| StepFinishPart
|
||||
| SnapshotPart
|
||||
| PatchPart
|
||||
| AgentPart
|
||||
| RetryPart
|
||||
| CompactionPart
|
||||
|
||||
const AssistantErrorSchema = Schema.Union([
|
||||
AuthError.EffectSchema,
|
||||
namedError("UnknownError", { message: Schema.String, ref: Schema.optional(Schema.String) }).EffectSchema,
|
||||
OutputLengthError.EffectSchema,
|
||||
AbortedError.EffectSchema,
|
||||
StructuredOutputError.EffectSchema,
|
||||
ContextOverflowError.EffectSchema,
|
||||
ContentFilterError.EffectSchema,
|
||||
APIError.EffectSchema,
|
||||
]).annotate({ discriminator: "name" })
|
||||
type AssistantError = Schema.Schema.Type<typeof AssistantErrorSchema>
|
||||
|
||||
export const TextPartInput = Schema.Struct({
|
||||
id: Schema.optional(PartID),
|
||||
type: Schema.Literal("text"),
|
||||
text: Schema.String,
|
||||
synthetic: Schema.optional(Schema.Boolean),
|
||||
ignored: Schema.optional(Schema.Boolean),
|
||||
time: Schema.optional(
|
||||
Schema.Struct({
|
||||
start: NonNegativeInt,
|
||||
end: Schema.optional(NonNegativeInt),
|
||||
}),
|
||||
),
|
||||
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
}).annotate({ identifier: "TextPartInput" })
|
||||
export type TextPartInput = Types.DeepMutable<Schema.Schema.Type<typeof TextPartInput>>
|
||||
|
||||
export const FilePartInput = Schema.Struct({
|
||||
id: Schema.optional(PartID),
|
||||
type: Schema.Literal("file"),
|
||||
mime: Schema.String,
|
||||
filename: Schema.optional(Schema.String),
|
||||
url: Schema.String,
|
||||
source: Schema.optional(FilePartSource),
|
||||
}).annotate({ identifier: "FilePartInput" })
|
||||
export type FilePartInput = Types.DeepMutable<Schema.Schema.Type<typeof FilePartInput>>
|
||||
|
||||
export const AgentPartInput = Schema.Struct({
|
||||
id: Schema.optional(PartID),
|
||||
type: Schema.Literal("agent"),
|
||||
name: Schema.String,
|
||||
source: Schema.optional(
|
||||
Schema.Struct({
|
||||
value: Schema.String,
|
||||
start: NonNegativeInt,
|
||||
end: NonNegativeInt,
|
||||
}),
|
||||
),
|
||||
}).annotate({ identifier: "AgentPartInput" })
|
||||
export type AgentPartInput = Types.DeepMutable<Schema.Schema.Type<typeof AgentPartInput>>
|
||||
|
||||
export const SubtaskPartInput = Schema.Struct({
|
||||
id: Schema.optional(PartID),
|
||||
type: Schema.Literal("subtask"),
|
||||
prompt: Schema.String,
|
||||
description: Schema.String,
|
||||
agent: Schema.String,
|
||||
model: Schema.optional(
|
||||
Schema.Struct({
|
||||
providerID: Provider.ID,
|
||||
modelID: Model.ID,
|
||||
}),
|
||||
),
|
||||
command: Schema.optional(Schema.String),
|
||||
}).annotate({ identifier: "SubtaskPartInput" })
|
||||
export type SubtaskPartInput = Types.DeepMutable<Schema.Schema.Type<typeof SubtaskPartInput>>
|
||||
|
||||
export const Assistant = Schema.Struct({
|
||||
...messageBase,
|
||||
role: Schema.Literal("assistant"),
|
||||
time: Schema.Struct({
|
||||
created: NonNegativeInt,
|
||||
completed: Schema.optional(NonNegativeInt),
|
||||
}),
|
||||
error: Schema.optional(AssistantErrorSchema),
|
||||
parentID: MessageID,
|
||||
modelID: Model.ID,
|
||||
providerID: Provider.ID,
|
||||
mode: Schema.String,
|
||||
agent: Schema.String,
|
||||
path: Schema.Struct({
|
||||
cwd: Schema.String,
|
||||
root: Schema.String,
|
||||
}),
|
||||
summary: Schema.optional(Schema.Boolean),
|
||||
cost: Schema.Finite,
|
||||
tokens: Schema.Struct({
|
||||
total: Schema.optional(Schema.Finite),
|
||||
input: Schema.Finite,
|
||||
output: Schema.Finite,
|
||||
reasoning: Schema.Finite,
|
||||
cache: Schema.Struct({
|
||||
read: Schema.Finite,
|
||||
write: Schema.Finite,
|
||||
}),
|
||||
}),
|
||||
structured: Schema.optional(Schema.Any),
|
||||
variant: Schema.optional(Schema.String),
|
||||
finish: Schema.optional(Schema.String),
|
||||
}).annotate({ identifier: "AssistantMessage" })
|
||||
export type Assistant = Omit<Types.DeepMutable<Schema.Schema.Type<typeof Assistant>>, "error"> & {
|
||||
error?: AssistantError
|
||||
}
|
||||
|
||||
export const Info = Schema.Union([User, Assistant]).annotate({ discriminator: "role", identifier: "Message" })
|
||||
export type Info = User | Assistant
|
||||
|
||||
export const WithParts = Schema.Struct({
|
||||
info: Info,
|
||||
parts: Schema.Array(Part),
|
||||
})
|
||||
export type WithParts = {
|
||||
info: Info
|
||||
parts: Part[]
|
||||
}
|
||||
|
||||
const options = {
|
||||
durable: {
|
||||
aggregate: "sessionID",
|
||||
version: 1,
|
||||
},
|
||||
} as const
|
||||
|
||||
const SessionSummary = Schema.Struct({
|
||||
additions: Schema.Finite,
|
||||
deletions: Schema.Finite,
|
||||
files: Schema.Finite,
|
||||
diffs: optional(Schema.Array(FileDiff.Info)),
|
||||
})
|
||||
|
||||
const SessionTokens = Schema.Struct({
|
||||
input: Schema.Finite,
|
||||
output: Schema.Finite,
|
||||
reasoning: Schema.Finite,
|
||||
cache: Schema.Struct({
|
||||
read: Schema.Finite,
|
||||
write: Schema.Finite,
|
||||
}),
|
||||
})
|
||||
|
||||
const SessionShare = Schema.Struct({
|
||||
url: Schema.String,
|
||||
})
|
||||
|
||||
const SessionRevert = Schema.Struct({
|
||||
messageID: MessageID,
|
||||
partID: optional(PartID),
|
||||
snapshot: optional(Schema.String),
|
||||
diff: optional(Schema.String),
|
||||
})
|
||||
|
||||
const SessionModel = Schema.Struct({
|
||||
id: Model.ID,
|
||||
providerID: Provider.ID,
|
||||
variant: optional(Schema.String),
|
||||
})
|
||||
|
||||
export const SessionInfo = Schema.Struct({
|
||||
id: SessionID,
|
||||
slug: Schema.String,
|
||||
projectID: Project.ID,
|
||||
workspaceID: optional(WorkspaceID),
|
||||
directory: Schema.String,
|
||||
path: optional(Schema.String),
|
||||
parentID: optional(SessionID),
|
||||
summary: optional(SessionSummary),
|
||||
cost: optional(Schema.Finite),
|
||||
tokens: optional(SessionTokens),
|
||||
share: optional(SessionShare),
|
||||
title: Schema.String,
|
||||
agent: optional(Schema.String),
|
||||
model: optional(SessionModel),
|
||||
version: Schema.String,
|
||||
metadata: optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
time: Schema.Struct({
|
||||
created: NonNegativeInt,
|
||||
updated: NonNegativeInt,
|
||||
compacting: optional(NonNegativeInt),
|
||||
archived: optional(Schema.Finite),
|
||||
}),
|
||||
permission: optional(PermissionV1.Ruleset),
|
||||
revert: optional(SessionRevert),
|
||||
}).annotate({ identifier: "Session" })
|
||||
export type SessionInfo = typeof SessionInfo.Type
|
||||
|
||||
const events = {
|
||||
Created: define({
|
||||
type: "session.created",
|
||||
...options,
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
info: SessionInfo,
|
||||
},
|
||||
}),
|
||||
Updated: define({
|
||||
type: "session.updated",
|
||||
...options,
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
info: SessionInfo,
|
||||
},
|
||||
}),
|
||||
Deleted: define({
|
||||
type: "session.deleted",
|
||||
...options,
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
info: SessionInfo,
|
||||
},
|
||||
}),
|
||||
MessageUpdated: define({
|
||||
type: "message.updated",
|
||||
...options,
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
info: Info,
|
||||
},
|
||||
}),
|
||||
MessageRemoved: define({
|
||||
type: "message.removed",
|
||||
...options,
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
messageID: MessageID,
|
||||
},
|
||||
}),
|
||||
PartUpdated: define({
|
||||
type: "message.part.updated",
|
||||
...options,
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
part: Part,
|
||||
time: Schema.Finite,
|
||||
},
|
||||
}),
|
||||
PartRemoved: define({
|
||||
type: "message.part.removed",
|
||||
...options,
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
messageID: MessageID,
|
||||
partID: PartID,
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
export const PartDelta = define({
|
||||
type: "message.part.delta",
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
messageID: MessageID,
|
||||
partID: PartID,
|
||||
field: Schema.String,
|
||||
delta: Schema.String,
|
||||
},
|
||||
})
|
||||
|
||||
export const Diff = define({
|
||||
type: "session.diff",
|
||||
schema: {
|
||||
sessionID: SessionID,
|
||||
diff: Schema.Array(FileDiff.Info),
|
||||
},
|
||||
})
|
||||
|
||||
export const Error = define({
|
||||
type: "session.error",
|
||||
schema: {
|
||||
sessionID: Schema.optional(SessionID),
|
||||
error: Assistant.fields.error,
|
||||
},
|
||||
})
|
||||
|
||||
export const Event = {
|
||||
...events,
|
||||
PartDelta,
|
||||
Diff,
|
||||
Error,
|
||||
Definitions: inventory(
|
||||
events.Created,
|
||||
events.Updated,
|
||||
events.Deleted,
|
||||
events.MessageUpdated,
|
||||
events.MessageRemoved,
|
||||
events.PartUpdated,
|
||||
events.PartRemoved,
|
||||
PartDelta,
|
||||
Diff,
|
||||
Error,
|
||||
),
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
export * as VcsEvent from "./vcs-event"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { Event } from "./event"
|
||||
|
||||
export const BranchUpdated = Event.define({
|
||||
type: "vcs.branch.updated",
|
||||
schema: {
|
||||
branch: Schema.optional(Schema.String),
|
||||
branch: optional(Schema.String),
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ import { WorkspaceID } from "./workspace-id"
|
||||
export const ConnectionStatus = Schema.Struct({
|
||||
workspaceID: WorkspaceID,
|
||||
status: Schema.Literals(["connected", "connecting", "disconnected", "error"]),
|
||||
})
|
||||
export type ConnectionStatus = typeof ConnectionStatus.Type
|
||||
}).annotate({ identifier: "WorkspaceEvent.ConnectionStatus" })
|
||||
export interface ConnectionStatus extends Schema.Schema.Type<typeof ConnectionStatus> {}
|
||||
|
||||
export const Ready = Event.define({
|
||||
type: "workspace.ready",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Schema } from "effect"
|
||||
import { ascending } from "./identifier"
|
||||
import { withStatics } from "./schema"
|
||||
import { statics } from "./schema"
|
||||
|
||||
export const WorkspaceID = Schema.String.check(Schema.isStartsWith("wrk")).pipe(
|
||||
Schema.brand("WorkspaceV2.ID"),
|
||||
withStatics((schema) => {
|
||||
statics((schema) => {
|
||||
const create = () => schema.make("wrk_" + ascending())
|
||||
return {
|
||||
ascending: (id?: string) => {
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
export * as WorktreeEvent from "./worktree-event"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema"
|
||||
import { Event } from "./event"
|
||||
|
||||
export const Ready = Event.define({
|
||||
type: "worktree.ready",
|
||||
schema: {
|
||||
name: Schema.String,
|
||||
branch: Schema.optional(Schema.String),
|
||||
branch: optional(Schema.String),
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { Schema } from "effect"
|
||||
import { Agent } from "../src/agent"
|
||||
import { FileSystem } from "../src/filesystem"
|
||||
import { Model } from "../src/model"
|
||||
import { Project } from "../src/project"
|
||||
import { Pty } from "../src/pty"
|
||||
import { Question } from "../src/question"
|
||||
import { Session } from "../src/session"
|
||||
import { SessionEvent } from "../src/session-event"
|
||||
import { SessionTodo } from "../src/session-todo"
|
||||
import { optional } from "../src/schema"
|
||||
|
||||
describe("contract hygiene", () => {
|
||||
test("optional properties omit undefined while encoding", () => {
|
||||
const Value = Schema.Struct({ value: optional(Schema.String) })
|
||||
expect(Schema.encodeSync(Value)({ value: undefined })).toEqual({})
|
||||
})
|
||||
|
||||
test("todo status and priority are closed sets", () => {
|
||||
const decode = Schema.decodeUnknownSync(SessionTodo.Info)
|
||||
expect(decode({ content: "ship", status: "pending", priority: "high" })).toEqual({
|
||||
content: "ship",
|
||||
status: "pending",
|
||||
priority: "high",
|
||||
})
|
||||
expect(() => decode({ content: "ship", status: "waiting", priority: "high" })).toThrow()
|
||||
expect(() => decode({ content: "ship", status: "pending", priority: "urgent" })).toThrow()
|
||||
})
|
||||
|
||||
test("current ID constructors expose create", () => {
|
||||
expect(Question.ID.create()).toStartWith("que_")
|
||||
expect(Pty.ID.create()).toStartWith("pty_")
|
||||
})
|
||||
|
||||
test("reusable public identifiers are stable and unique", () => {
|
||||
const identifiers = [
|
||||
Agent.Color,
|
||||
FileSystem.Submatch,
|
||||
Model.Ref,
|
||||
Model.Capabilities,
|
||||
Model.Cost,
|
||||
Model.Api,
|
||||
Project.Icon,
|
||||
Project.Commands,
|
||||
Project.Time,
|
||||
Project.Info,
|
||||
Pty.Info,
|
||||
Session.ListAnchor,
|
||||
].map((schema) => schema.ast.annotations?.identifier)
|
||||
|
||||
expect(identifiers.every((identifier) => typeof identifier === "string")).toBe(true)
|
||||
expect(new Set(identifiers).size).toBe(identifiers.length)
|
||||
})
|
||||
|
||||
test("current source avoids Any and mutable contract wrappers", async () => {
|
||||
const files = [...new Bun.Glob("*.ts").scanSync(new URL("../src", import.meta.url).pathname)].filter(
|
||||
(file) => !file.endsWith("-v1.ts"),
|
||||
)
|
||||
const source = await Promise.all(
|
||||
files.map((file) => Bun.file(new URL(`../src/${file}`, import.meta.url)).text()),
|
||||
).then((values) => values.join("\n"))
|
||||
|
||||
expect(source).not.toContain("Schema.Any")
|
||||
expect(source).not.toContain("Schema.mutable")
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,28 @@
|
||||
import { expect, test } from "bun:test"
|
||||
import { LegacyEvent } from "../src/legacy-event"
|
||||
import { PermissionV1 } from "../src/permission-v1"
|
||||
import { QuestionV1 } from "../src/question-v1"
|
||||
import { SessionV1 } from "../src/session-v1"
|
||||
import { LegacyEvent as IsolatedLegacyEvent } from "../src/v1/legacy-event"
|
||||
import { PermissionV1 as IsolatedPermissionV1 } from "../src/v1/permission"
|
||||
import { QuestionV1 as IsolatedQuestionV1 } from "../src/v1/question"
|
||||
import { SessionV1 as IsolatedSessionV1 } from "../src/v1/session"
|
||||
|
||||
test("compatibility entrypoints preserve isolated V1 schema identity", () => {
|
||||
expect(LegacyEvent).toBe(IsolatedLegacyEvent)
|
||||
expect(PermissionV1).toBe(IsolatedPermissionV1)
|
||||
expect(QuestionV1).toBe(IsolatedQuestionV1)
|
||||
expect(SessionV1).toBe(IsolatedSessionV1)
|
||||
})
|
||||
|
||||
test("current source does not import the V1 subtree directly", async () => {
|
||||
const allowed = new Set(["legacy-event.ts", "permission-v1.ts", "question-v1.ts", "session-v1.ts"])
|
||||
const files = [...new Bun.Glob("*.ts").scanSync(new URL("../src", import.meta.url).pathname)].filter(
|
||||
(file) => !allowed.has(file),
|
||||
)
|
||||
const directImports = await Promise.all(
|
||||
files.map(async (file) => ({ file, source: await Bun.file(new URL(`../src/${file}`, import.meta.url)).text() })),
|
||||
).then((values) => values.filter((value) => value.source.includes('from "./v1/')))
|
||||
|
||||
expect(directImports).toEqual([])
|
||||
})
|
||||
@@ -111,6 +111,7 @@ import type {
|
||||
McpRemoteConfig,
|
||||
McpStatusErrors,
|
||||
McpStatusResponses,
|
||||
ModelRef,
|
||||
MoveSessionDestination,
|
||||
OutputFormat,
|
||||
Part as Part2,
|
||||
@@ -128,10 +129,12 @@ import type {
|
||||
PermissionRespondResponses,
|
||||
PermissionRuleset,
|
||||
PermissionV2Reply,
|
||||
ProjectCommands,
|
||||
ProjectCurrentErrors,
|
||||
ProjectCurrentResponses,
|
||||
ProjectDirectoriesErrors,
|
||||
ProjectDirectoriesResponses,
|
||||
ProjectIcon,
|
||||
ProjectInitGitErrors,
|
||||
ProjectInitGitResponses,
|
||||
ProjectListErrors,
|
||||
@@ -2611,17 +2614,8 @@ export class Project extends HeyApiClient {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
name?: string
|
||||
icon?: {
|
||||
url?: string
|
||||
override?: string
|
||||
color?: string
|
||||
}
|
||||
commands?: {
|
||||
/**
|
||||
* Startup script to run when creating a new workspace (worktree)
|
||||
*/
|
||||
start?: string
|
||||
}
|
||||
icon?: ProjectIcon
|
||||
commands?: ProjectCommands
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
@@ -5379,11 +5373,7 @@ export class Session3 extends HeyApiClient {
|
||||
parameters?: {
|
||||
id?: string
|
||||
agent?: string
|
||||
model?: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
model?: ModelRef
|
||||
location?: LocationRef
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
@@ -5479,11 +5469,7 @@ export class Session3 extends HeyApiClient {
|
||||
public switchModel<ThrowOnError extends boolean = false>(
|
||||
parameters: {
|
||||
sessionID: string
|
||||
model?: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
model?: ModelRef
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
|
||||
@@ -663,11 +663,11 @@ export type Todo = {
|
||||
/**
|
||||
* Current status of the task: pending, in_progress, completed, cancelled
|
||||
*/
|
||||
status: string
|
||||
status: "pending" | "in_progress" | "completed" | "cancelled"
|
||||
/**
|
||||
* Priority level of the task: high, medium, low
|
||||
*/
|
||||
priority: string
|
||||
priority: "high" | "medium" | "low"
|
||||
}
|
||||
|
||||
export type SessionStatus =
|
||||
@@ -835,11 +835,7 @@ export type GlobalEvent = {
|
||||
timestamp: number
|
||||
sessionID: string
|
||||
messageID: string
|
||||
model: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
model: ModelRef
|
||||
}
|
||||
}
|
||||
| {
|
||||
@@ -923,11 +919,7 @@ export type GlobalEvent = {
|
||||
sessionID: string
|
||||
assistantMessageID: string
|
||||
agent: string
|
||||
model: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
model: ModelRef
|
||||
snapshot?: string
|
||||
}
|
||||
}
|
||||
@@ -1003,11 +995,7 @@ export type GlobalEvent = {
|
||||
sessionID: string
|
||||
assistantMessageID: string
|
||||
reasoningID: string
|
||||
providerMetadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
providerMetadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
| {
|
||||
@@ -1030,11 +1018,7 @@ export type GlobalEvent = {
|
||||
assistantMessageID: string
|
||||
reasoningID: string
|
||||
text: string
|
||||
providerMetadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
providerMetadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
| {
|
||||
@@ -1084,11 +1068,7 @@ export type GlobalEvent = {
|
||||
}
|
||||
provider: {
|
||||
executed: boolean
|
||||
metadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
metadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1103,7 +1083,7 @@ export type GlobalEvent = {
|
||||
structured: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
content: Array<ToolTextContent | ToolFileContent>
|
||||
content: Array<LlmToolContent>
|
||||
}
|
||||
}
|
||||
| {
|
||||
@@ -1117,16 +1097,12 @@ export type GlobalEvent = {
|
||||
structured: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
content: Array<ToolTextContent | ToolFileContent>
|
||||
content: Array<LlmToolContent>
|
||||
outputPaths?: Array<string>
|
||||
result?: unknown
|
||||
provider: {
|
||||
executed: boolean
|
||||
metadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
metadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1142,11 +1118,7 @@ export type GlobalEvent = {
|
||||
result?: unknown
|
||||
provider: {
|
||||
executed: boolean
|
||||
metadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
metadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1198,13 +1170,7 @@ export type GlobalEvent = {
|
||||
properties: {
|
||||
timestamp: number
|
||||
sessionID: string
|
||||
revert: {
|
||||
messageID: string
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
files?: Array<FileDiff>
|
||||
}
|
||||
revert: RevertState
|
||||
}
|
||||
}
|
||||
| {
|
||||
@@ -1516,24 +1482,11 @@ export type GlobalEvent = {
|
||||
properties: {
|
||||
id: string
|
||||
worktree: string
|
||||
vcs?: "git"
|
||||
vcs?: ProjectVcs
|
||||
name?: string
|
||||
icon?: {
|
||||
url?: string
|
||||
override?: string
|
||||
color?: string
|
||||
}
|
||||
commands?: {
|
||||
/**
|
||||
* Startup script to run when creating a new workspace (worktree)
|
||||
*/
|
||||
start?: string
|
||||
}
|
||||
time: {
|
||||
created: number
|
||||
updated: number
|
||||
initialized?: number
|
||||
}
|
||||
icon?: ProjectIcon
|
||||
commands?: ProjectCommands
|
||||
time: ProjectTime
|
||||
sandboxes: Array<string>
|
||||
}
|
||||
}
|
||||
@@ -2466,24 +2419,11 @@ export type McpServerNotFoundError = {
|
||||
export type Project = {
|
||||
id: string
|
||||
worktree: string
|
||||
vcs?: "git"
|
||||
vcs?: ProjectVcs
|
||||
name?: string
|
||||
icon?: {
|
||||
url?: string
|
||||
override?: string
|
||||
color?: string
|
||||
}
|
||||
commands?: {
|
||||
/**
|
||||
* Startup script to run when creating a new workspace (worktree)
|
||||
*/
|
||||
start?: string
|
||||
}
|
||||
time: {
|
||||
created: number
|
||||
updated: number
|
||||
initialized?: number
|
||||
}
|
||||
icon?: ProjectIcon
|
||||
commands?: ProjectCommands
|
||||
time: ProjectTime
|
||||
sandboxes: Array<string>
|
||||
}
|
||||
|
||||
@@ -2976,6 +2916,12 @@ export type MoveSessionDestination = {
|
||||
directory: string
|
||||
}
|
||||
|
||||
export type ModelRef = {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
|
||||
export type LocationRef = {
|
||||
directory: string
|
||||
workspaceID?: string
|
||||
@@ -3005,6 +2951,12 @@ export type SessionErrorUnknown = {
|
||||
message: string
|
||||
}
|
||||
|
||||
export type LlmProviderMetadata = {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
|
||||
export type ToolTextContent = {
|
||||
type: "text"
|
||||
text: string
|
||||
@@ -3017,6 +2969,8 @@ export type ToolFileContent = {
|
||||
name?: string
|
||||
}
|
||||
|
||||
export type LlmToolContent = ToolTextContent | ToolFileContent
|
||||
|
||||
export type SessionNextRetryError = {
|
||||
message: string
|
||||
statusCode?: number
|
||||
@@ -3038,6 +2992,14 @@ export type FileDiff = {
|
||||
patch: string
|
||||
}
|
||||
|
||||
export type RevertState = {
|
||||
messageID: string
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
files?: Array<FileDiff>
|
||||
}
|
||||
|
||||
export type PermissionV2Source = {
|
||||
type: "tool"
|
||||
messageID: string
|
||||
@@ -3081,6 +3043,27 @@ export type QuestionV2Tool = {
|
||||
|
||||
export type QuestionV2Answer = Array<string>
|
||||
|
||||
export type ProjectVcs = "git"
|
||||
|
||||
export type ProjectIcon = {
|
||||
url?: string
|
||||
override?: string
|
||||
color?: string
|
||||
}
|
||||
|
||||
export type ProjectCommands = {
|
||||
/**
|
||||
* Startup script to run when creating a new workspace (worktree)
|
||||
*/
|
||||
start?: string
|
||||
}
|
||||
|
||||
export type ProjectTime = {
|
||||
created: number
|
||||
updated: number
|
||||
initialized?: number
|
||||
}
|
||||
|
||||
export type EventServerInstanceDisposed = {
|
||||
id: string
|
||||
type: "server.instance.disposed"
|
||||
@@ -3225,11 +3208,7 @@ export type SyncEventSessionNextModelSwitched = {
|
||||
timestamp: number
|
||||
sessionID: string
|
||||
messageID: string
|
||||
model: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
model: ModelRef
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3369,11 +3348,7 @@ export type SyncEventSessionNextStepStarted = {
|
||||
sessionID: string
|
||||
assistantMessageID: string
|
||||
agent: string
|
||||
model: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
model: ModelRef
|
||||
snapshot?: string
|
||||
}
|
||||
}
|
||||
@@ -3473,11 +3448,7 @@ export type SyncEventSessionNextReasoningStarted = {
|
||||
sessionID: string
|
||||
assistantMessageID: string
|
||||
reasoningID: string
|
||||
providerMetadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
providerMetadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3496,11 +3467,7 @@ export type SyncEventSessionNextReasoningEnded = {
|
||||
assistantMessageID: string
|
||||
reasoningID: string
|
||||
text: string
|
||||
providerMetadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
providerMetadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3560,11 +3527,7 @@ export type SyncEventSessionNextToolCalled = {
|
||||
}
|
||||
provider: {
|
||||
executed: boolean
|
||||
metadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
metadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3586,7 +3549,7 @@ export type SyncEventSessionNextToolProgress = {
|
||||
structured: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
content: Array<ToolTextContent | ToolFileContent>
|
||||
content: Array<LlmToolContent>
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3607,16 +3570,12 @@ export type SyncEventSessionNextToolSuccess = {
|
||||
structured: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
content: Array<ToolTextContent | ToolFileContent>
|
||||
content: Array<LlmToolContent>
|
||||
outputPaths?: Array<string>
|
||||
result?: unknown
|
||||
provider: {
|
||||
executed: boolean
|
||||
metadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
metadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3639,11 +3598,7 @@ export type SyncEventSessionNextToolFailed = {
|
||||
result?: unknown
|
||||
provider: {
|
||||
executed: boolean
|
||||
metadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
metadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3713,13 +3668,7 @@ export type SyncEventSessionNextRevertStaged = {
|
||||
data: {
|
||||
timestamp: number
|
||||
sessionID: string
|
||||
revert: {
|
||||
messageID: string
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
files?: Array<FileDiff>
|
||||
}
|
||||
revert: RevertState
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3781,6 +3730,16 @@ export type ProjectDirectories = Array<{
|
||||
strategy?: string
|
||||
}>
|
||||
|
||||
export type PtyTicketConnectToken = {
|
||||
ticket: string
|
||||
expires_in: number
|
||||
}
|
||||
|
||||
export type WorkspaceEventConnectionStatus = {
|
||||
workspaceID: string
|
||||
status: "connected" | "connecting" | "disconnected" | "error"
|
||||
}
|
||||
|
||||
export type LocationInfo = {
|
||||
directory: string
|
||||
workspaceID?: string
|
||||
@@ -3790,6 +3749,17 @@ export type LocationInfo = {
|
||||
}
|
||||
}
|
||||
|
||||
export type ProviderRequest = {
|
||||
headers: {
|
||||
[key: string]: string
|
||||
}
|
||||
body: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
|
||||
export type AgentColor = string | "primary" | "secondary" | "accent" | "success" | "warning" | "error" | "info"
|
||||
|
||||
export type PermissionV2Effect = "allow" | "deny" | "ask"
|
||||
|
||||
export type PermissionV2Rule = {
|
||||
@@ -3802,24 +3772,13 @@ export type PermissionV2Ruleset = Array<PermissionV2Rule>
|
||||
|
||||
export type AgentV2Info = {
|
||||
id: string
|
||||
model?: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
request: {
|
||||
headers: {
|
||||
[key: string]: string
|
||||
}
|
||||
body: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
model?: ModelRef
|
||||
request: ProviderRequest
|
||||
system?: string
|
||||
description?: string
|
||||
mode: "subagent" | "primary" | "all"
|
||||
hidden: boolean
|
||||
color?: string | "primary" | "secondary" | "accent" | "success" | "warning" | "error" | "info"
|
||||
color?: AgentColor
|
||||
steps?: number
|
||||
permissions: PermissionV2Ruleset
|
||||
}
|
||||
@@ -3829,11 +3788,7 @@ export type SessionV2Info = {
|
||||
parentID?: string
|
||||
projectID: string
|
||||
agent?: string
|
||||
model?: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
model?: ModelRef
|
||||
cost: number
|
||||
tokens: {
|
||||
input: number
|
||||
@@ -3852,13 +3807,7 @@ export type SessionV2Info = {
|
||||
title: string
|
||||
location: LocationRef
|
||||
subpath?: string
|
||||
revert?: {
|
||||
messageID: string
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
files?: Array<FileDiff>
|
||||
}
|
||||
revert?: RevertState
|
||||
}
|
||||
|
||||
export type SessionInputAdmitted = {
|
||||
@@ -3892,11 +3841,7 @@ export type SessionMessageModelSwitched = {
|
||||
created: number
|
||||
}
|
||||
type: "model-switched"
|
||||
model: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
model: ModelRef
|
||||
}
|
||||
|
||||
export type SessionMessageUser = {
|
||||
@@ -3963,11 +3908,7 @@ export type SessionMessageAssistantReasoning = {
|
||||
type: "reasoning"
|
||||
id: string
|
||||
text: string
|
||||
providerMetadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
providerMetadata?: LlmProviderMetadata
|
||||
}
|
||||
|
||||
export type SessionMessageToolStatePending = {
|
||||
@@ -3983,7 +3924,7 @@ export type SessionMessageToolStateRunning = {
|
||||
structured: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
content: Array<ToolTextContent | ToolFileContent>
|
||||
content: Array<LlmToolContent>
|
||||
}
|
||||
|
||||
export type SessionMessageToolStateCompleted = {
|
||||
@@ -3992,7 +3933,7 @@ export type SessionMessageToolStateCompleted = {
|
||||
[key: string]: unknown
|
||||
}
|
||||
attachments?: Array<PromptFileAttachment>
|
||||
content: Array<ToolTextContent | ToolFileContent>
|
||||
content: Array<LlmToolContent>
|
||||
outputPaths?: Array<string>
|
||||
structured: {
|
||||
[key: string]: unknown
|
||||
@@ -4005,7 +3946,7 @@ export type SessionMessageToolStateError = {
|
||||
input: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
content: Array<ToolTextContent | ToolFileContent>
|
||||
content: Array<LlmToolContent>
|
||||
structured: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
@@ -4019,16 +3960,8 @@ export type SessionMessageAssistantTool = {
|
||||
name: string
|
||||
provider?: {
|
||||
executed: boolean
|
||||
metadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
resultMetadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
metadata?: LlmProviderMetadata
|
||||
resultMetadata?: LlmProviderMetadata
|
||||
}
|
||||
state:
|
||||
| SessionMessageToolStatePending
|
||||
@@ -4054,11 +3987,7 @@ export type SessionMessageAssistant = {
|
||||
}
|
||||
type: "assistant"
|
||||
agent: string
|
||||
model: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
model: ModelRef
|
||||
content: Array<SessionMessageAssistantText | SessionMessageAssistantReasoning | SessionMessageAssistantTool>
|
||||
snapshot?: {
|
||||
start?: string
|
||||
@@ -4103,34 +4032,51 @@ export type SessionMessage =
|
||||
| SessionMessageAssistant
|
||||
| SessionMessageCompaction
|
||||
|
||||
export type ModelApi =
|
||||
| {
|
||||
id: string
|
||||
type: "aisdk"
|
||||
package: string
|
||||
url?: string
|
||||
settings?: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
| {
|
||||
id: string
|
||||
type: "native"
|
||||
url?: string
|
||||
settings: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
|
||||
export type ModelCapabilities = {
|
||||
tools: boolean
|
||||
input: Array<string>
|
||||
output: Array<string>
|
||||
}
|
||||
|
||||
export type ModelCost = {
|
||||
tier?: {
|
||||
type: "context"
|
||||
size: number
|
||||
}
|
||||
input: number
|
||||
output: number
|
||||
cache: {
|
||||
read: number
|
||||
write: number
|
||||
}
|
||||
}
|
||||
|
||||
export type ModelV2Info = {
|
||||
id: string
|
||||
providerID: string
|
||||
family?: string
|
||||
name: string
|
||||
api:
|
||||
| {
|
||||
id: string
|
||||
type: "aisdk"
|
||||
package: string
|
||||
url?: string
|
||||
settings?: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
| {
|
||||
id: string
|
||||
type: "native"
|
||||
url?: string
|
||||
settings: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
capabilities: {
|
||||
tools: boolean
|
||||
input: Array<string>
|
||||
output: Array<string>
|
||||
}
|
||||
api: ModelApi
|
||||
capabilities: ModelCapabilities
|
||||
request: {
|
||||
headers: {
|
||||
[key: string]: string
|
||||
@@ -4152,18 +4098,7 @@ export type ModelV2Info = {
|
||||
time: {
|
||||
released: number
|
||||
}
|
||||
cost: Array<{
|
||||
tier?: {
|
||||
type: "context"
|
||||
size: number
|
||||
}
|
||||
input: number
|
||||
output: number
|
||||
cache: {
|
||||
read: number
|
||||
write: number
|
||||
}
|
||||
}>
|
||||
cost: Array<ModelCost>
|
||||
status: "alpha" | "beta" | "deprecated" | "active"
|
||||
enabled: boolean
|
||||
limit: {
|
||||
@@ -4173,35 +4108,32 @@ export type ModelV2Info = {
|
||||
}
|
||||
}
|
||||
|
||||
export type ProviderAisdk = {
|
||||
type: "aisdk"
|
||||
package: string
|
||||
url?: string
|
||||
settings?: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
|
||||
export type ProviderNative = {
|
||||
type: "native"
|
||||
url?: string
|
||||
settings: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
|
||||
export type ProviderApi = ProviderAisdk | ProviderNative
|
||||
|
||||
export type ProviderV2Info = {
|
||||
id: string
|
||||
integrationID?: string
|
||||
name: string
|
||||
disabled?: boolean
|
||||
api:
|
||||
| {
|
||||
type: "aisdk"
|
||||
package: string
|
||||
url?: string
|
||||
settings?: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
| {
|
||||
type: "native"
|
||||
url?: string
|
||||
settings: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
request: {
|
||||
headers: {
|
||||
[key: string]: string
|
||||
}
|
||||
body: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
api: ProviderApi
|
||||
request: ProviderRequest
|
||||
}
|
||||
|
||||
export type IntegrationWhen = {
|
||||
@@ -4278,6 +4210,37 @@ export type IntegrationAttempt = {
|
||||
}
|
||||
}
|
||||
|
||||
export type IntegrationAttemptStatus =
|
||||
| {
|
||||
status: "pending"
|
||||
time: {
|
||||
created: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
expires: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
}
|
||||
}
|
||||
| {
|
||||
status: "complete"
|
||||
time: {
|
||||
created: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
expires: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
}
|
||||
}
|
||||
| {
|
||||
status: "failed"
|
||||
message: string
|
||||
time: {
|
||||
created: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
expires: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
}
|
||||
}
|
||||
| {
|
||||
status: "expired"
|
||||
time: {
|
||||
created: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
expires: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
}
|
||||
}
|
||||
|
||||
export type PermissionV2Request = {
|
||||
id: string
|
||||
sessionID: string
|
||||
@@ -4307,11 +4270,7 @@ export type CommandV2Info = {
|
||||
template: string
|
||||
description?: string
|
||||
agent?: string
|
||||
model?: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
model?: ModelRef
|
||||
subtask?: boolean
|
||||
}
|
||||
|
||||
@@ -4555,11 +4514,7 @@ export type V2EventSessionNextModelSwitched = {
|
||||
timestamp: number
|
||||
sessionID: string
|
||||
messageID: string
|
||||
model: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
model: ModelRef
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4723,11 +4678,7 @@ export type V2EventSessionNextStepStarted = {
|
||||
sessionID: string
|
||||
assistantMessageID: string
|
||||
agent: string
|
||||
model: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
model: ModelRef
|
||||
snapshot?: string
|
||||
}
|
||||
}
|
||||
@@ -4863,11 +4814,7 @@ export type V2EventSessionNextReasoningStarted = {
|
||||
sessionID: string
|
||||
assistantMessageID: string
|
||||
reasoningID: string
|
||||
providerMetadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
providerMetadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4910,11 +4857,7 @@ export type V2EventSessionNextReasoningEnded = {
|
||||
assistantMessageID: string
|
||||
reasoningID: string
|
||||
text: string
|
||||
providerMetadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
providerMetadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5004,11 +4947,7 @@ export type V2EventSessionNextToolCalled = {
|
||||
}
|
||||
provider: {
|
||||
executed: boolean
|
||||
metadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
metadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5033,7 +4972,7 @@ export type V2EventSessionNextToolProgress = {
|
||||
structured: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
content: Array<ToolTextContent | ToolFileContent>
|
||||
content: Array<LlmToolContent>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5057,16 +4996,12 @@ export type V2EventSessionNextToolSuccess = {
|
||||
structured: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
content: Array<ToolTextContent | ToolFileContent>
|
||||
content: Array<LlmToolContent>
|
||||
outputPaths?: Array<string>
|
||||
result?: unknown
|
||||
provider: {
|
||||
executed: boolean
|
||||
metadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
metadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5092,11 +5027,7 @@ export type V2EventSessionNextToolFailed = {
|
||||
result?: unknown
|
||||
provider: {
|
||||
executed: boolean
|
||||
metadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
metadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5198,13 +5129,7 @@ export type V2EventSessionNextRevertStaged = {
|
||||
data: {
|
||||
timestamp: number
|
||||
sessionID: string
|
||||
revert: {
|
||||
messageID: string
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
files?: Array<FileDiff>
|
||||
}
|
||||
revert: RevertState
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5846,24 +5771,11 @@ export type V2EventProjectUpdated = {
|
||||
data: {
|
||||
id: string
|
||||
worktree: string
|
||||
vcs?: "git"
|
||||
vcs?: ProjectVcs
|
||||
name?: string
|
||||
icon?: {
|
||||
url?: string
|
||||
override?: string
|
||||
color?: string
|
||||
}
|
||||
commands?: {
|
||||
/**
|
||||
* Startup script to run when creating a new workspace (worktree)
|
||||
*/
|
||||
start?: string
|
||||
}
|
||||
time: {
|
||||
created: number
|
||||
updated: number
|
||||
initialized?: number
|
||||
}
|
||||
icon?: ProjectIcon
|
||||
commands?: ProjectCommands
|
||||
time: ProjectTime
|
||||
sandboxes: Array<string>
|
||||
}
|
||||
}
|
||||
@@ -6150,12 +6062,14 @@ export type ReferenceGitSource = {
|
||||
hidden?: boolean
|
||||
}
|
||||
|
||||
export type ReferenceSource = ReferenceLocalSource | ReferenceGitSource
|
||||
|
||||
export type ReferenceInfo = {
|
||||
name: string
|
||||
path: string
|
||||
description?: string
|
||||
hidden?: boolean
|
||||
source: ReferenceLocalSource | ReferenceGitSource
|
||||
source: ReferenceSource
|
||||
}
|
||||
|
||||
export type ProjectCopyCopy = {
|
||||
@@ -6277,11 +6191,7 @@ export type EventSessionNextModelSwitched = {
|
||||
timestamp: number
|
||||
sessionID: string
|
||||
messageID: string
|
||||
model: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
model: ModelRef
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6373,11 +6283,7 @@ export type EventSessionNextStepStarted = {
|
||||
sessionID: string
|
||||
assistantMessageID: string
|
||||
agent: string
|
||||
model: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
model: ModelRef
|
||||
snapshot?: string
|
||||
}
|
||||
}
|
||||
@@ -6459,11 +6365,7 @@ export type EventSessionNextReasoningStarted = {
|
||||
sessionID: string
|
||||
assistantMessageID: string
|
||||
reasoningID: string
|
||||
providerMetadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
providerMetadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6488,11 +6390,7 @@ export type EventSessionNextReasoningEnded = {
|
||||
assistantMessageID: string
|
||||
reasoningID: string
|
||||
text: string
|
||||
providerMetadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
providerMetadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6546,11 +6444,7 @@ export type EventSessionNextToolCalled = {
|
||||
}
|
||||
provider: {
|
||||
executed: boolean
|
||||
metadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
metadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6566,7 +6460,7 @@ export type EventSessionNextToolProgress = {
|
||||
structured: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
content: Array<ToolTextContent | ToolFileContent>
|
||||
content: Array<LlmToolContent>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6581,16 +6475,12 @@ export type EventSessionNextToolSuccess = {
|
||||
structured: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
content: Array<ToolTextContent | ToolFileContent>
|
||||
content: Array<LlmToolContent>
|
||||
outputPaths?: Array<string>
|
||||
result?: unknown
|
||||
provider: {
|
||||
executed: boolean
|
||||
metadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
metadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6607,11 +6497,7 @@ export type EventSessionNextToolFailed = {
|
||||
result?: unknown
|
||||
provider: {
|
||||
executed: boolean
|
||||
metadata?: {
|
||||
[key: string]: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
metadata?: LlmProviderMetadata
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6668,13 +6554,7 @@ export type EventSessionNextRevertStaged = {
|
||||
properties: {
|
||||
timestamp: number
|
||||
sessionID: string
|
||||
revert: {
|
||||
messageID: string
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
files?: Array<FileDiff>
|
||||
}
|
||||
revert: RevertState
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6964,24 +6844,11 @@ export type EventProjectUpdated = {
|
||||
properties: {
|
||||
id: string
|
||||
worktree: string
|
||||
vcs?: "git"
|
||||
vcs?: ProjectVcs
|
||||
name?: string
|
||||
icon?: {
|
||||
url?: string
|
||||
override?: string
|
||||
color?: string
|
||||
}
|
||||
commands?: {
|
||||
/**
|
||||
* Startup script to run when creating a new workspace (worktree)
|
||||
*/
|
||||
start?: string
|
||||
}
|
||||
time: {
|
||||
created: number
|
||||
updated: number
|
||||
initialized?: number
|
||||
}
|
||||
icon?: ProjectIcon
|
||||
commands?: ProjectCommands
|
||||
time: ProjectTime
|
||||
sandboxes: Array<string>
|
||||
}
|
||||
}
|
||||
@@ -8847,17 +8714,8 @@ export type ProjectInitGitResponse = ProjectInitGitResponses[keyof ProjectInitGi
|
||||
export type ProjectUpdateData = {
|
||||
body?: {
|
||||
name?: string
|
||||
icon?: {
|
||||
url?: string
|
||||
override?: string
|
||||
color?: string
|
||||
}
|
||||
commands?: {
|
||||
/**
|
||||
* Startup script to run when creating a new workspace (worktree)
|
||||
*/
|
||||
start?: string
|
||||
}
|
||||
icon?: ProjectIcon
|
||||
commands?: ProjectCommands
|
||||
}
|
||||
path: {
|
||||
projectID: string
|
||||
@@ -9194,10 +9052,7 @@ export type PtyConnectTokenResponses = {
|
||||
/**
|
||||
* WebSocket connect token
|
||||
*/
|
||||
200: {
|
||||
ticket: string
|
||||
expires_in: number
|
||||
}
|
||||
200: PtyTicketConnectToken
|
||||
}
|
||||
|
||||
export type PtyConnectTokenResponse = PtyConnectTokenResponses[keyof PtyConnectTokenResponses]
|
||||
@@ -11222,10 +11077,7 @@ export type ExperimentalWorkspaceStatusResponses = {
|
||||
/**
|
||||
* Workspace status
|
||||
*/
|
||||
200: Array<{
|
||||
workspaceID: string
|
||||
status: "connected" | "connecting" | "disconnected" | "error"
|
||||
}>
|
||||
200: Array<WorkspaceEventConnectionStatus>
|
||||
}
|
||||
|
||||
export type ExperimentalWorkspaceStatusResponse =
|
||||
@@ -11447,11 +11299,7 @@ export type V2SessionCreateData = {
|
||||
body: {
|
||||
id?: string
|
||||
agent?: string
|
||||
model?: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
model?: ModelRef
|
||||
location?: LocationRef
|
||||
}
|
||||
path?: never
|
||||
@@ -11559,11 +11407,7 @@ export type V2SessionSwitchAgentResponse = V2SessionSwitchAgentResponses[keyof V
|
||||
|
||||
export type V2SessionSwitchModelData = {
|
||||
body: {
|
||||
model: {
|
||||
id: string
|
||||
providerID: string
|
||||
variant?: string
|
||||
}
|
||||
model: ModelRef
|
||||
}
|
||||
path: {
|
||||
sessionID: string
|
||||
@@ -11760,13 +11604,7 @@ export type V2SessionRevertStageResponses = {
|
||||
* Success
|
||||
*/
|
||||
200: {
|
||||
data: {
|
||||
messageID: string
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
files?: Array<FileDiff>
|
||||
}
|
||||
data: RevertState
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12293,36 +12131,7 @@ export type V2IntegrationAttemptStatusResponses = {
|
||||
*/
|
||||
200: {
|
||||
location: LocationInfo
|
||||
data:
|
||||
| {
|
||||
status: "pending"
|
||||
time: {
|
||||
created: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
expires: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
}
|
||||
}
|
||||
| {
|
||||
status: "complete"
|
||||
time: {
|
||||
created: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
expires: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
}
|
||||
}
|
||||
| {
|
||||
status: "failed"
|
||||
message: string
|
||||
time: {
|
||||
created: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
expires: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
}
|
||||
}
|
||||
| {
|
||||
status: "expired"
|
||||
time: {
|
||||
created: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
expires: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
}
|
||||
}
|
||||
data: IntegrationAttemptStatus
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13091,10 +12900,7 @@ export type V2PtyConnectTokenResponses = {
|
||||
*/
|
||||
200: {
|
||||
location: LocationInfo
|
||||
data: {
|
||||
ticket: string
|
||||
expires_in: number
|
||||
}
|
||||
data: PtyTicketConnectToken
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ Use Effect schemas as the public contract:
|
||||
- branded schemas for ids
|
||||
- `Schema.Class` or `Schema.Struct` for domain data
|
||||
- `Schema.TaggedErrorClass` for expected errors
|
||||
- existing core helpers like `DeepMutable`, `withStatics`, and integer schemas where appropriate
|
||||
- existing core helpers like `DeepMutable`, `statics`, and integer schemas where appropriate
|
||||
|
||||
Prefer `Info` objects as the stored domain records. Add static `empty(...)` constructors when update APIs need to create records on first mutation.
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
```ts
|
||||
export const ID = Schema.String.pipe(
|
||||
Schema.brand("ProviderV2.ID"),
|
||||
withStatics((schema) => ({
|
||||
statics((schema) => ({
|
||||
opencode: schema.make("opencode"),
|
||||
anthropic: schema.make("anthropic"),
|
||||
openai: schema.make("openai"),
|
||||
|
||||
Reference in New Issue
Block a user