mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-29 14:16:16 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
182494f885 | ||
|
|
2b767d8cb1 |
@@ -53,7 +53,6 @@ function setup(
|
||||
}
|
||||
|
||||
describe("createCompatibleApi", () => {
|
||||
/*
|
||||
test("routes V1 archive through the legacy session update", async () => {
|
||||
const { api, requests } = setup("v1")
|
||||
await api.session.archive({ sessionID: "ses_1", directory: "/repo" })
|
||||
@@ -64,7 +63,6 @@ describe("createCompatibleApi", () => {
|
||||
expect(requests[0]!.method).toBe("PATCH")
|
||||
expect(await requests[0]!.json()).toMatchObject({ time: { archived: expect.any(Number) } })
|
||||
})
|
||||
*/
|
||||
|
||||
test("converts current prompts to the V1 prompt contract", async () => {
|
||||
const { api, requests } = setup("v1")
|
||||
@@ -147,7 +145,6 @@ describe("createCompatibleApi", () => {
|
||||
expect(detections).toBe(1)
|
||||
})
|
||||
|
||||
/*
|
||||
test("keeps V2 session actions on the current API", async () => {
|
||||
const { api, requests } = setup("v2")
|
||||
await api.session.archive({ sessionID: "ses_1" })
|
||||
@@ -155,7 +152,6 @@ describe("createCompatibleApi", () => {
|
||||
expect(new URL(requests[0]!.url).pathname).toBe("/api/session/ses_1/archive")
|
||||
expect(requests[0]!.method).toBe("POST")
|
||||
})
|
||||
*/
|
||||
|
||||
test("uses the global V1 session search endpoint", async () => {
|
||||
const { api, requests } = setup("v1")
|
||||
|
||||
@@ -27,7 +27,7 @@ type CompatibleSessionApi = Omit<
|
||||
shell: (input: SessionShellInput & LegacyPrompt) => Promise<SessionShellOutput>
|
||||
compact: (input: SessionCompactInput & { model?: LegacyPrompt["model"] }) => Promise<SessionCompactOutput>
|
||||
rename: (input: Parameters<SessionApi["rename"]>[0] & LegacyLocation) => ReturnType<SessionApi["rename"]>
|
||||
// archive: (input: Parameters<SessionApi["archive"]>[0] & LegacyLocation) => ReturnType<SessionApi["archive"]>
|
||||
archive: (input: Parameters<SessionApi["archive"]>[0] & LegacyLocation) => ReturnType<SessionApi["archive"]>
|
||||
remove: (input: Parameters<SessionApi["remove"]>[0] & LegacyLocation) => ReturnType<SessionApi["remove"]>
|
||||
}
|
||||
type CompatiblePermissionApi = Omit<ServerApi["permission"], "reply"> & {
|
||||
@@ -183,9 +183,9 @@ function createV1Api(input: CompatibleInput): CompatibleApi {
|
||||
async rename(value: Parameters<ServerApi["session"]["rename"]>[0] & LegacyLocation) {
|
||||
await legacy(value).session.update({ sessionID: value.sessionID, title: value.title })
|
||||
},
|
||||
// async archive(value: Parameters<ServerApi["session"]["archive"]>[0] & LegacyLocation) {
|
||||
// await legacy(value).session.update({ sessionID: value.sessionID, time: { archived: Date.now() } })
|
||||
// },
|
||||
async archive(value: Parameters<ServerApi["session"]["archive"]>[0] & LegacyLocation) {
|
||||
await legacy(value).session.update({ sessionID: value.sessionID, time: { archived: Date.now() } })
|
||||
},
|
||||
async remove(value: Parameters<ServerApi["session"]["remove"]>[0] & LegacyLocation) {
|
||||
await legacy(value).session.delete(value)
|
||||
},
|
||||
|
||||
@@ -152,15 +152,19 @@ export type Endpoint5_8Input = { readonly sessionID: Session.ID; readonly title:
|
||||
export type Endpoint5_8Output = void
|
||||
export type SessionRenameOperation<E = never> = (input: Endpoint5_8Input) => Effect.Effect<Endpoint5_8Output, E>
|
||||
|
||||
export type Endpoint5_9Input = {
|
||||
export type Endpoint5_9Input = { readonly sessionID: Session.ID }
|
||||
export type Endpoint5_9Output = void
|
||||
export type SessionArchiveOperation<E = never> = (input: Endpoint5_9Input) => Effect.Effect<Endpoint5_9Output, E>
|
||||
|
||||
export type Endpoint5_10Input = {
|
||||
readonly sessionID: Session.ID
|
||||
readonly directory: AbsolutePath
|
||||
readonly workspaceID?: Workspace.ID | undefined
|
||||
}
|
||||
export type Endpoint5_9Output = void
|
||||
export type SessionMoveOperation<E = never> = (input: Endpoint5_9Input) => Effect.Effect<Endpoint5_9Output, E>
|
||||
export type Endpoint5_10Output = void
|
||||
export type SessionMoveOperation<E = never> = (input: Endpoint5_10Input) => Effect.Effect<Endpoint5_10Output, E>
|
||||
|
||||
export type Endpoint5_10Input = {
|
||||
export type Endpoint5_11Input = {
|
||||
readonly sessionID: Session.ID
|
||||
readonly id?: SessionMessage.ID | undefined
|
||||
readonly text: string
|
||||
@@ -170,10 +174,10 @@ export type Endpoint5_10Input = {
|
||||
readonly delivery?: "steer" | "queue" | undefined
|
||||
readonly resume?: boolean | undefined
|
||||
}
|
||||
export type Endpoint5_10Output = SessionPending.User
|
||||
export type SessionPromptOperation<E = never> = (input: Endpoint5_10Input) => Effect.Effect<Endpoint5_10Output, E>
|
||||
export type Endpoint5_11Output = SessionPending.User
|
||||
export type SessionPromptOperation<E = never> = (input: Endpoint5_11Input) => Effect.Effect<Endpoint5_11Output, E>
|
||||
|
||||
export type Endpoint5_11Input = {
|
||||
export type Endpoint5_12Input = {
|
||||
readonly sessionID: Session.ID
|
||||
readonly id?: SessionMessage.ID | undefined
|
||||
readonly command: string
|
||||
@@ -185,19 +189,19 @@ export type Endpoint5_11Input = {
|
||||
readonly delivery?: "steer" | "queue" | undefined
|
||||
readonly resume?: boolean | undefined
|
||||
}
|
||||
export type Endpoint5_11Output = SessionPending.User
|
||||
export type SessionCommandOperation<E = never> = (input: Endpoint5_11Input) => Effect.Effect<Endpoint5_11Output, E>
|
||||
export type Endpoint5_12Output = SessionPending.User
|
||||
export type SessionCommandOperation<E = never> = (input: Endpoint5_12Input) => Effect.Effect<Endpoint5_12Output, E>
|
||||
|
||||
export type Endpoint5_12Input = {
|
||||
export type Endpoint5_13Input = {
|
||||
readonly sessionID: Session.ID
|
||||
readonly id?: SessionMessage.ID | undefined
|
||||
readonly skill: Skill.ID
|
||||
readonly resume?: boolean | undefined
|
||||
}
|
||||
export type Endpoint5_12Output = void
|
||||
export type SessionSkillOperation<E = never> = (input: Endpoint5_12Input) => Effect.Effect<Endpoint5_12Output, E>
|
||||
export type Endpoint5_13Output = void
|
||||
export type SessionSkillOperation<E = never> = (input: Endpoint5_13Input) => Effect.Effect<Endpoint5_13Output, E>
|
||||
|
||||
export type Endpoint5_13Input = {
|
||||
export type Endpoint5_14Input = {
|
||||
readonly sessionID: Session.ID
|
||||
readonly id?: SessionMessage.ID | undefined
|
||||
readonly text: string
|
||||
@@ -206,81 +210,81 @@ export type Endpoint5_13Input = {
|
||||
readonly delivery?: "steer" | "queue" | undefined
|
||||
readonly resume?: boolean | undefined
|
||||
}
|
||||
export type Endpoint5_13Output = SessionPending.Synthetic
|
||||
export type SessionSyntheticOperation<E = never> = (input: Endpoint5_13Input) => Effect.Effect<Endpoint5_13Output, E>
|
||||
export type Endpoint5_14Output = SessionPending.Synthetic
|
||||
export type SessionSyntheticOperation<E = never> = (input: Endpoint5_14Input) => Effect.Effect<Endpoint5_14Output, E>
|
||||
|
||||
export type Endpoint5_14Input = {
|
||||
export type Endpoint5_15Input = {
|
||||
readonly sessionID: Session.ID
|
||||
readonly id?: Event.ID | undefined
|
||||
readonly command: string
|
||||
}
|
||||
export type Endpoint5_14Output = void
|
||||
export type SessionShellOperation<E = never> = (input: Endpoint5_14Input) => Effect.Effect<Endpoint5_14Output, E>
|
||||
export type Endpoint5_15Output = void
|
||||
export type SessionShellOperation<E = never> = (input: Endpoint5_15Input) => Effect.Effect<Endpoint5_15Output, E>
|
||||
|
||||
export type Endpoint5_15Input = { readonly sessionID: Session.ID; readonly id?: SessionMessage.ID | undefined }
|
||||
export type Endpoint5_15Output = SessionPending.Compaction
|
||||
export type SessionCompactOperation<E = never> = (input: Endpoint5_15Input) => Effect.Effect<Endpoint5_15Output, E>
|
||||
export type Endpoint5_16Input = { readonly sessionID: Session.ID; readonly id?: SessionMessage.ID | undefined }
|
||||
export type Endpoint5_16Output = SessionPending.Compaction
|
||||
export type SessionCompactOperation<E = never> = (input: Endpoint5_16Input) => Effect.Effect<Endpoint5_16Output, E>
|
||||
|
||||
export type Endpoint5_16Input = { readonly sessionID: Session.ID }
|
||||
export type Endpoint5_16Output = void
|
||||
export type SessionWaitOperation<E = never> = (input: Endpoint5_16Input) => Effect.Effect<Endpoint5_16Output, E>
|
||||
export type Endpoint5_17Input = { readonly sessionID: Session.ID }
|
||||
export type Endpoint5_17Output = void
|
||||
export type SessionWaitOperation<E = never> = (input: Endpoint5_17Input) => Effect.Effect<Endpoint5_17Output, E>
|
||||
|
||||
export type Endpoint5_17Input = {
|
||||
export type Endpoint5_18Input = {
|
||||
readonly sessionID: Session.ID
|
||||
readonly messageID: SessionMessage.ID
|
||||
readonly files?: boolean | undefined
|
||||
}
|
||||
export type Endpoint5_17Output = Session.Revert
|
||||
export type SessionRevertStageOperation<E = never> = (input: Endpoint5_17Input) => Effect.Effect<Endpoint5_17Output, E>
|
||||
|
||||
export type Endpoint5_18Input = { readonly sessionID: Session.ID }
|
||||
export type Endpoint5_18Output = void
|
||||
export type SessionRevertClearOperation<E = never> = (input: Endpoint5_18Input) => Effect.Effect<Endpoint5_18Output, E>
|
||||
export type Endpoint5_18Output = Session.Revert
|
||||
export type SessionRevertStageOperation<E = never> = (input: Endpoint5_18Input) => Effect.Effect<Endpoint5_18Output, E>
|
||||
|
||||
export type Endpoint5_19Input = { readonly sessionID: Session.ID }
|
||||
export type Endpoint5_19Output = void
|
||||
export type SessionRevertCommitOperation<E = never> = (input: Endpoint5_19Input) => Effect.Effect<Endpoint5_19Output, E>
|
||||
export type SessionRevertClearOperation<E = never> = (input: Endpoint5_19Input) => Effect.Effect<Endpoint5_19Output, E>
|
||||
|
||||
export type Endpoint5_20Input = { readonly sessionID: Session.ID }
|
||||
export type Endpoint5_20Output = ReadonlyArray<SessionMessage.Info>
|
||||
export type SessionContextOperation<E = never> = (input: Endpoint5_20Input) => Effect.Effect<Endpoint5_20Output, E>
|
||||
export type Endpoint5_20Output = void
|
||||
export type SessionRevertCommitOperation<E = never> = (input: Endpoint5_20Input) => Effect.Effect<Endpoint5_20Output, E>
|
||||
|
||||
export type Endpoint5_21Input = { readonly sessionID: Session.ID }
|
||||
export type Endpoint5_21Output = ReadonlyArray<SessionPending.Info>
|
||||
export type SessionPendingListOperation<E = never> = (input: Endpoint5_21Input) => Effect.Effect<Endpoint5_21Output, E>
|
||||
export type Endpoint5_21Output = ReadonlyArray<SessionMessage.Info>
|
||||
export type SessionContextOperation<E = never> = (input: Endpoint5_21Input) => Effect.Effect<Endpoint5_21Output, E>
|
||||
|
||||
export type Endpoint5_22Input = { readonly sessionID: Session.ID }
|
||||
export type Endpoint5_22Output = ReadonlyArray<InstructionEntry.Info>
|
||||
export type SessionInstructionsEntryListOperation<E = never> = (
|
||||
input: Endpoint5_22Input,
|
||||
) => Effect.Effect<Endpoint5_22Output, E>
|
||||
export type Endpoint5_22Output = ReadonlyArray<SessionPending.Info>
|
||||
export type SessionPendingListOperation<E = never> = (input: Endpoint5_22Input) => Effect.Effect<Endpoint5_22Output, E>
|
||||
|
||||
export type Endpoint5_23Input = {
|
||||
export type Endpoint5_23Input = { readonly sessionID: Session.ID }
|
||||
export type Endpoint5_23Output = ReadonlyArray<InstructionEntry.Info>
|
||||
export type SessionInstructionsEntryListOperation<E = never> = (
|
||||
input: Endpoint5_23Input,
|
||||
) => Effect.Effect<Endpoint5_23Output, E>
|
||||
|
||||
export type Endpoint5_24Input = {
|
||||
readonly sessionID: Session.ID
|
||||
readonly key: InstructionEntry.Key
|
||||
readonly value: Schema.Json
|
||||
}
|
||||
export type Endpoint5_23Output = void
|
||||
export type SessionInstructionsEntryPutOperation<E = never> = (
|
||||
input: Endpoint5_23Input,
|
||||
) => Effect.Effect<Endpoint5_23Output, E>
|
||||
|
||||
export type Endpoint5_24Input = { readonly sessionID: Session.ID; readonly key: InstructionEntry.Key }
|
||||
export type Endpoint5_24Output = void
|
||||
export type SessionInstructionsEntryRemoveOperation<E = never> = (
|
||||
export type SessionInstructionsEntryPutOperation<E = never> = (
|
||||
input: Endpoint5_24Input,
|
||||
) => Effect.Effect<Endpoint5_24Output, E>
|
||||
|
||||
export type Endpoint5_25Input = { readonly sessionID: Session.ID; readonly prompt: string }
|
||||
export type Endpoint5_25Output = { readonly text: string }
|
||||
export type SessionGenerateOperation<E = never> = (input: Endpoint5_25Input) => Effect.Effect<Endpoint5_25Output, E>
|
||||
export type Endpoint5_25Input = { readonly sessionID: Session.ID; readonly key: InstructionEntry.Key }
|
||||
export type Endpoint5_25Output = void
|
||||
export type SessionInstructionsEntryRemoveOperation<E = never> = (
|
||||
input: Endpoint5_25Input,
|
||||
) => Effect.Effect<Endpoint5_25Output, E>
|
||||
|
||||
export type Endpoint5_26Input = {
|
||||
export type Endpoint5_26Input = { readonly sessionID: Session.ID; readonly prompt: string }
|
||||
export type Endpoint5_26Output = { readonly text: string }
|
||||
export type SessionGenerateOperation<E = never> = (input: Endpoint5_26Input) => Effect.Effect<Endpoint5_26Output, E>
|
||||
|
||||
export type Endpoint5_27Input = {
|
||||
readonly sessionID: Session.ID
|
||||
readonly after?: Event.Seq | undefined
|
||||
readonly follow?: boolean | undefined
|
||||
}
|
||||
export type Endpoint5_26Output =
|
||||
export type Endpoint5_27Output =
|
||||
| (
|
||||
| {
|
||||
readonly id: Event.ID
|
||||
@@ -323,6 +327,15 @@ export type Endpoint5_26Output =
|
||||
readonly location?: Location.Ref | undefined
|
||||
readonly data: { readonly sessionID: Session.ID; readonly title: string }
|
||||
}
|
||||
| {
|
||||
readonly id: Event.ID
|
||||
readonly created: DateTime.Utc
|
||||
readonly metadata?: { readonly [x: string]: unknown } | undefined
|
||||
readonly type: "session.archived"
|
||||
readonly durable: { readonly aggregateID: string; readonly seq: Event.Seq; readonly version: Event.Version }
|
||||
readonly location?: Location.Ref | undefined
|
||||
readonly data: { readonly sessionID: Session.ID }
|
||||
}
|
||||
| {
|
||||
readonly id: Event.ID
|
||||
readonly created: DateTime.Utc
|
||||
@@ -825,19 +838,19 @@ export type Endpoint5_26Output =
|
||||
}
|
||||
)
|
||||
| EventLog.Synced
|
||||
export type SessionLogOperation<E = never> = (input: Endpoint5_26Input) => Stream.Stream<Endpoint5_26Output, E>
|
||||
|
||||
export type Endpoint5_27Input = { readonly sessionID: Session.ID }
|
||||
export type Endpoint5_27Output = void
|
||||
export type SessionInterruptOperation<E = never> = (input: Endpoint5_27Input) => Effect.Effect<Endpoint5_27Output, E>
|
||||
export type SessionLogOperation<E = never> = (input: Endpoint5_27Input) => Stream.Stream<Endpoint5_27Output, E>
|
||||
|
||||
export type Endpoint5_28Input = { readonly sessionID: Session.ID }
|
||||
export type Endpoint5_28Output = void
|
||||
export type SessionBackgroundOperation<E = never> = (input: Endpoint5_28Input) => Effect.Effect<Endpoint5_28Output, E>
|
||||
export type SessionInterruptOperation<E = never> = (input: Endpoint5_28Input) => Effect.Effect<Endpoint5_28Output, E>
|
||||
|
||||
export type Endpoint5_29Input = { readonly sessionID: Session.ID; readonly messageID: SessionMessage.ID }
|
||||
export type Endpoint5_29Output = SessionMessage.Info
|
||||
export type SessionMessageOperation<E = never> = (input: Endpoint5_29Input) => Effect.Effect<Endpoint5_29Output, E>
|
||||
export type Endpoint5_29Input = { readonly sessionID: Session.ID }
|
||||
export type Endpoint5_29Output = void
|
||||
export type SessionBackgroundOperation<E = never> = (input: Endpoint5_29Input) => Effect.Effect<Endpoint5_29Output, E>
|
||||
|
||||
export type Endpoint5_30Input = { readonly sessionID: Session.ID; readonly messageID: SessionMessage.ID }
|
||||
export type Endpoint5_30Output = SessionMessage.Info
|
||||
export type SessionMessageOperation<E = never> = (input: Endpoint5_30Input) => Effect.Effect<Endpoint5_30Output, E>
|
||||
|
||||
export interface SessionApi<E = never> {
|
||||
readonly list: SessionListOperation<E>
|
||||
@@ -849,6 +862,7 @@ export interface SessionApi<E = never> {
|
||||
readonly switchAgent: SessionSwitchAgentOperation<E>
|
||||
readonly switchModel: SessionSwitchModelOperation<E>
|
||||
readonly rename: SessionRenameOperation<E>
|
||||
readonly archive: SessionArchiveOperation<E>
|
||||
readonly move: SessionMoveOperation<E>
|
||||
readonly prompt: SessionPromptOperation<E>
|
||||
readonly command: SessionCommandOperation<E>
|
||||
|
||||
@@ -76,6 +76,8 @@ import type {
|
||||
Endpoint5_28Output,
|
||||
Endpoint5_29Input,
|
||||
Endpoint5_29Output,
|
||||
Endpoint5_30Input,
|
||||
Endpoint5_30Output,
|
||||
Endpoint6_0Input,
|
||||
Endpoint6_0Output,
|
||||
Endpoint7_0Input,
|
||||
@@ -358,14 +360,19 @@ const Endpoint5_8 = (raw: RawClient["server.session"]) => (input: Endpoint5_8Inp
|
||||
|
||||
const Endpoint5_9 = (raw: RawClient["server.session"]) => (input: Endpoint5_9Input) =>
|
||||
preserveEffect<Endpoint5_9Output>()(
|
||||
raw["session.archive"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const Endpoint5_10 = (raw: RawClient["server.session"]) => (input: Endpoint5_10Input) =>
|
||||
preserveEffect<Endpoint5_10Output>()(
|
||||
raw["session.move"]({
|
||||
params: { sessionID: input["sessionID"] },
|
||||
payload: { directory: input["directory"], workspaceID: input["workspaceID"] },
|
||||
}).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const Endpoint5_10 = (raw: RawClient["server.session"]) => (input: Endpoint5_10Input) =>
|
||||
preserveEffect<Endpoint5_10Output>()(
|
||||
const Endpoint5_11 = (raw: RawClient["server.session"]) => (input: Endpoint5_11Input) =>
|
||||
preserveEffect<Endpoint5_11Output>()(
|
||||
raw["session.prompt"]({
|
||||
params: { sessionID: input["sessionID"] },
|
||||
payload: {
|
||||
@@ -383,8 +390,8 @@ const Endpoint5_10 = (raw: RawClient["server.session"]) => (input: Endpoint5_10I
|
||||
),
|
||||
)
|
||||
|
||||
const Endpoint5_11 = (raw: RawClient["server.session"]) => (input: Endpoint5_11Input) =>
|
||||
preserveEffect<Endpoint5_11Output>()(
|
||||
const Endpoint5_12 = (raw: RawClient["server.session"]) => (input: Endpoint5_12Input) =>
|
||||
preserveEffect<Endpoint5_12Output>()(
|
||||
raw["session.command"]({
|
||||
params: { sessionID: input["sessionID"] },
|
||||
payload: {
|
||||
@@ -404,16 +411,16 @@ const Endpoint5_11 = (raw: RawClient["server.session"]) => (input: Endpoint5_11I
|
||||
),
|
||||
)
|
||||
|
||||
const Endpoint5_12 = (raw: RawClient["server.session"]) => (input: Endpoint5_12Input) =>
|
||||
preserveEffect<Endpoint5_12Output>()(
|
||||
const Endpoint5_13 = (raw: RawClient["server.session"]) => (input: Endpoint5_13Input) =>
|
||||
preserveEffect<Endpoint5_13Output>()(
|
||||
raw["session.skill"]({
|
||||
params: { sessionID: input["sessionID"] },
|
||||
payload: { id: input["id"], skill: input["skill"], resume: input["resume"] },
|
||||
}).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const Endpoint5_13 = (raw: RawClient["server.session"]) => (input: Endpoint5_13Input) =>
|
||||
preserveEffect<Endpoint5_13Output>()(
|
||||
const Endpoint5_14 = (raw: RawClient["server.session"]) => (input: Endpoint5_14Input) =>
|
||||
preserveEffect<Endpoint5_14Output>()(
|
||||
raw["session.synthetic"]({
|
||||
params: { sessionID: input["sessionID"] },
|
||||
payload: {
|
||||
@@ -430,29 +437,29 @@ const Endpoint5_13 = (raw: RawClient["server.session"]) => (input: Endpoint5_13I
|
||||
),
|
||||
)
|
||||
|
||||
const Endpoint5_14 = (raw: RawClient["server.session"]) => (input: Endpoint5_14Input) =>
|
||||
preserveEffect<Endpoint5_14Output>()(
|
||||
const Endpoint5_15 = (raw: RawClient["server.session"]) => (input: Endpoint5_15Input) =>
|
||||
preserveEffect<Endpoint5_15Output>()(
|
||||
raw["session.shell"]({
|
||||
params: { sessionID: input["sessionID"] },
|
||||
payload: { id: input["id"], command: input["command"] },
|
||||
}).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const Endpoint5_15 = (raw: RawClient["server.session"]) => (input: Endpoint5_15Input) =>
|
||||
preserveEffect<Endpoint5_15Output>()(
|
||||
const Endpoint5_16 = (raw: RawClient["server.session"]) => (input: Endpoint5_16Input) =>
|
||||
preserveEffect<Endpoint5_16Output>()(
|
||||
raw["session.compact"]({ params: { sessionID: input["sessionID"] }, payload: { id: input["id"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
),
|
||||
)
|
||||
|
||||
const Endpoint5_16 = (raw: RawClient["server.session"]) => (input: Endpoint5_16Input) =>
|
||||
preserveEffect<Endpoint5_16Output>()(
|
||||
const Endpoint5_17 = (raw: RawClient["server.session"]) => (input: Endpoint5_17Input) =>
|
||||
preserveEffect<Endpoint5_17Output>()(
|
||||
raw["session.wait"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const Endpoint5_17 = (raw: RawClient["server.session"]) => (input: Endpoint5_17Input) =>
|
||||
preserveEffect<Endpoint5_17Output>()(
|
||||
const Endpoint5_18 = (raw: RawClient["server.session"]) => (input: Endpoint5_18Input) =>
|
||||
preserveEffect<Endpoint5_18Output>()(
|
||||
raw["session.revert.stage"]({
|
||||
params: { sessionID: input["sessionID"] },
|
||||
payload: { messageID: input["messageID"], files: input["files"] },
|
||||
@@ -462,27 +469,19 @@ const Endpoint5_17 = (raw: RawClient["server.session"]) => (input: Endpoint5_17I
|
||||
),
|
||||
)
|
||||
|
||||
const Endpoint5_18 = (raw: RawClient["server.session"]) => (input: Endpoint5_18Input) =>
|
||||
preserveEffect<Endpoint5_18Output>()(
|
||||
raw["session.revert.clear"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const Endpoint5_19 = (raw: RawClient["server.session"]) => (input: Endpoint5_19Input) =>
|
||||
preserveEffect<Endpoint5_19Output>()(
|
||||
raw["session.revert.commit"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError)),
|
||||
raw["session.revert.clear"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const Endpoint5_20 = (raw: RawClient["server.session"]) => (input: Endpoint5_20Input) =>
|
||||
preserveEffect<Endpoint5_20Output>()(
|
||||
raw["session.context"]({ params: { sessionID: input["sessionID"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
),
|
||||
raw["session.revert.commit"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const Endpoint5_21 = (raw: RawClient["server.session"]) => (input: Endpoint5_21Input) =>
|
||||
preserveEffect<Endpoint5_21Output>()(
|
||||
raw["session.pending.list"]({ params: { sessionID: input["sessionID"] } }).pipe(
|
||||
raw["session.context"]({ params: { sessionID: input["sessionID"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
),
|
||||
@@ -490,7 +489,7 @@ const Endpoint5_21 = (raw: RawClient["server.session"]) => (input: Endpoint5_21I
|
||||
|
||||
const Endpoint5_22 = (raw: RawClient["server.session"]) => (input: Endpoint5_22Input) =>
|
||||
preserveEffect<Endpoint5_22Output>()(
|
||||
raw["session.instructions.entry.list"]({ params: { sessionID: input["sessionID"] } }).pipe(
|
||||
raw["session.pending.list"]({ params: { sessionID: input["sessionID"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
),
|
||||
@@ -498,29 +497,37 @@ const Endpoint5_22 = (raw: RawClient["server.session"]) => (input: Endpoint5_22I
|
||||
|
||||
const Endpoint5_23 = (raw: RawClient["server.session"]) => (input: Endpoint5_23Input) =>
|
||||
preserveEffect<Endpoint5_23Output>()(
|
||||
raw["session.instructions.entry.list"]({ params: { sessionID: input["sessionID"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
),
|
||||
)
|
||||
|
||||
const Endpoint5_24 = (raw: RawClient["server.session"]) => (input: Endpoint5_24Input) =>
|
||||
preserveEffect<Endpoint5_24Output>()(
|
||||
raw["session.instructions.entry.put"]({
|
||||
params: { sessionID: input["sessionID"], key: input["key"] },
|
||||
payload: { value: input["value"] },
|
||||
}).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const Endpoint5_24 = (raw: RawClient["server.session"]) => (input: Endpoint5_24Input) =>
|
||||
preserveEffect<Endpoint5_24Output>()(
|
||||
const Endpoint5_25 = (raw: RawClient["server.session"]) => (input: Endpoint5_25Input) =>
|
||||
preserveEffect<Endpoint5_25Output>()(
|
||||
raw["session.instructions.entry.remove"]({ params: { sessionID: input["sessionID"], key: input["key"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
),
|
||||
)
|
||||
|
||||
const Endpoint5_25 = (raw: RawClient["server.session"]) => (input: Endpoint5_25Input) =>
|
||||
preserveEffect<Endpoint5_25Output>()(
|
||||
const Endpoint5_26 = (raw: RawClient["server.session"]) => (input: Endpoint5_26Input) =>
|
||||
preserveEffect<Endpoint5_26Output>()(
|
||||
raw["session.generate"]({ params: { sessionID: input["sessionID"] }, payload: { prompt: input["prompt"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
),
|
||||
)
|
||||
|
||||
const Endpoint5_26 = (raw: RawClient["server.session"]) => (input: Endpoint5_26Input) =>
|
||||
preserveStream<Endpoint5_26Output>()(
|
||||
const Endpoint5_27 = (raw: RawClient["server.session"]) => (input: Endpoint5_27Input) =>
|
||||
preserveStream<Endpoint5_27Output>()(
|
||||
Stream.unwrap(
|
||||
raw["session.log"]({
|
||||
params: { sessionID: input["sessionID"] },
|
||||
@@ -532,18 +539,18 @@ const Endpoint5_26 = (raw: RawClient["server.session"]) => (input: Endpoint5_26I
|
||||
),
|
||||
)
|
||||
|
||||
const Endpoint5_27 = (raw: RawClient["server.session"]) => (input: Endpoint5_27Input) =>
|
||||
preserveEffect<Endpoint5_27Output>()(
|
||||
raw["session.interrupt"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const Endpoint5_28 = (raw: RawClient["server.session"]) => (input: Endpoint5_28Input) =>
|
||||
preserveEffect<Endpoint5_28Output>()(
|
||||
raw["session.background"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError)),
|
||||
raw["session.interrupt"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const Endpoint5_29 = (raw: RawClient["server.session"]) => (input: Endpoint5_29Input) =>
|
||||
preserveEffect<Endpoint5_29Output>()(
|
||||
raw["session.background"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const Endpoint5_30 = (raw: RawClient["server.session"]) => (input: Endpoint5_30Input) =>
|
||||
preserveEffect<Endpoint5_30Output>()(
|
||||
raw["session.message"]({ params: { sessionID: input["sessionID"], messageID: input["messageID"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
@@ -560,23 +567,24 @@ const adaptGroup5 = (raw: RawClient["server.session"]) => ({
|
||||
switchAgent: Endpoint5_6(raw),
|
||||
switchModel: Endpoint5_7(raw),
|
||||
rename: Endpoint5_8(raw),
|
||||
move: Endpoint5_9(raw),
|
||||
prompt: Endpoint5_10(raw),
|
||||
command: Endpoint5_11(raw),
|
||||
skill: Endpoint5_12(raw),
|
||||
synthetic: Endpoint5_13(raw),
|
||||
shell: Endpoint5_14(raw),
|
||||
compact: Endpoint5_15(raw),
|
||||
wait: Endpoint5_16(raw),
|
||||
revert: { stage: Endpoint5_17(raw), clear: Endpoint5_18(raw), commit: Endpoint5_19(raw) },
|
||||
context: Endpoint5_20(raw),
|
||||
pending: { list: Endpoint5_21(raw) },
|
||||
instructions: { entry: { list: Endpoint5_22(raw), put: Endpoint5_23(raw), remove: Endpoint5_24(raw) } },
|
||||
generate: Endpoint5_25(raw),
|
||||
log: Endpoint5_26(raw),
|
||||
interrupt: Endpoint5_27(raw),
|
||||
background: Endpoint5_28(raw),
|
||||
message: Endpoint5_29(raw),
|
||||
archive: Endpoint5_9(raw),
|
||||
move: Endpoint5_10(raw),
|
||||
prompt: Endpoint5_11(raw),
|
||||
command: Endpoint5_12(raw),
|
||||
skill: Endpoint5_13(raw),
|
||||
synthetic: Endpoint5_14(raw),
|
||||
shell: Endpoint5_15(raw),
|
||||
compact: Endpoint5_16(raw),
|
||||
wait: Endpoint5_17(raw),
|
||||
revert: { stage: Endpoint5_18(raw), clear: Endpoint5_19(raw), commit: Endpoint5_20(raw) },
|
||||
context: Endpoint5_21(raw),
|
||||
pending: { list: Endpoint5_22(raw) },
|
||||
instructions: { entry: { list: Endpoint5_23(raw), put: Endpoint5_24(raw), remove: Endpoint5_25(raw) } },
|
||||
generate: Endpoint5_26(raw),
|
||||
log: Endpoint5_27(raw),
|
||||
interrupt: Endpoint5_28(raw),
|
||||
background: Endpoint5_29(raw),
|
||||
message: Endpoint5_30(raw),
|
||||
})
|
||||
|
||||
const Endpoint6_0 = (raw: RawClient["server.message"]) => (input: Endpoint6_0Input) =>
|
||||
|
||||
@@ -28,6 +28,8 @@ import type {
|
||||
SessionSwitchModelOutput,
|
||||
SessionRenameInput,
|
||||
SessionRenameOutput,
|
||||
SessionArchiveInput,
|
||||
SessionArchiveOutput,
|
||||
SessionMoveInput,
|
||||
SessionMoveOutput,
|
||||
SessionPromptInput,
|
||||
@@ -553,6 +555,17 @@ export function make(options: ClientOptions) {
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
archive: (input: SessionArchiveInput, requestOptions?: RequestOptions) =>
|
||||
request<SessionArchiveOutput>(
|
||||
{
|
||||
method: "POST",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/archive`,
|
||||
successStatus: 204,
|
||||
declaredStatuses: [404, 400, 401],
|
||||
empty: true,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
move: (input: SessionMoveInput, requestOptions?: RequestOptions) =>
|
||||
request<SessionMoveOutput>(
|
||||
{
|
||||
|
||||
@@ -611,6 +611,16 @@ export type SessionRenamed = {
|
||||
data: { sessionID: string; title: string }
|
||||
}
|
||||
|
||||
export type SessionArchived = {
|
||||
id: string
|
||||
created: number
|
||||
metadata?: { [x: string]: any }
|
||||
type: "session.archived"
|
||||
durable: { aggregateID: string; seq: number; version: 1 }
|
||||
location?: LocationRef
|
||||
data: { sessionID: string }
|
||||
}
|
||||
|
||||
export type SessionDeleted = {
|
||||
id: string
|
||||
created: number
|
||||
@@ -2159,6 +2169,7 @@ export type SessionEventDurable =
|
||||
| SessionModelSelected
|
||||
| SessionMoved
|
||||
| SessionRenamed
|
||||
| SessionArchived
|
||||
| SessionDeleted
|
||||
| SessionForked
|
||||
| SessionInputPromoted
|
||||
@@ -2253,6 +2264,7 @@ export type V2Event =
|
||||
| SessionModelSelected
|
||||
| SessionMoved
|
||||
| SessionRenamed
|
||||
| SessionArchived
|
||||
| SessionUsageUpdated
|
||||
| SessionDeleted
|
||||
| SessionForked
|
||||
@@ -2730,6 +2742,10 @@ export type SessionRenameInput = {
|
||||
|
||||
export type SessionRenameOutput = void
|
||||
|
||||
export type SessionArchiveInput = { readonly sessionID: { readonly sessionID: string }["sessionID"] }
|
||||
|
||||
export type SessionArchiveOutput = void
|
||||
|
||||
export type SessionMoveInput = {
|
||||
readonly sessionID: { readonly sessionID: string }["sessionID"]
|
||||
readonly directory: { readonly directory: string; readonly workspaceID?: string }["directory"]
|
||||
|
||||
@@ -432,6 +432,7 @@ test("session methods use the public HTTP contract", async () => {
|
||||
sessionID: "ses_test",
|
||||
model: { id: "claude", providerID: "anthropic" },
|
||||
})
|
||||
await client.session.archive({ sessionID: "ses_test" })
|
||||
const admitted = await client.session.prompt({
|
||||
sessionID: "ses_test",
|
||||
text: "Hello",
|
||||
@@ -467,6 +468,7 @@ test("session methods use the public HTTP contract", async () => {
|
||||
["POST", "http://localhost:3000/api/session"],
|
||||
["POST", "http://localhost:3000/api/session/ses_test/agent"],
|
||||
["POST", "http://localhost:3000/api/session/ses_test/model"],
|
||||
["POST", "http://localhost:3000/api/session/ses_test/archive"],
|
||||
["POST", "http://localhost:3000/api/session/ses_test/prompt"],
|
||||
["POST", "http://localhost:3000/api/session/ses_test/generate"],
|
||||
["POST", "http://localhost:3000/api/session/ses_test/synthetic"],
|
||||
|
||||
@@ -227,6 +227,7 @@ export interface Interface {
|
||||
model: Model.Ref
|
||||
}) => Effect.Effect<void, NotFoundError>
|
||||
readonly rename: (input: { sessionID: SessionSchema.ID; title: string }) => Effect.Effect<void, NotFoundError>
|
||||
readonly archive: (sessionID: SessionSchema.ID) => Effect.Effect<void, NotFoundError>
|
||||
readonly move: (input: {
|
||||
sessionID: SessionSchema.ID
|
||||
directory: AbsolutePath
|
||||
@@ -706,6 +707,11 @@ const layer = Layer.effect(
|
||||
title: input.title,
|
||||
})
|
||||
}),
|
||||
archive: Effect.fn("Session.archive")(function* (sessionID) {
|
||||
const session = yield* result.get(sessionID)
|
||||
if (session.time.archived) return
|
||||
yield* bus.publish(SessionEvent.Archived, { sessionID })
|
||||
}),
|
||||
move: Effect.fn("Session.move")(function* (input) {
|
||||
const current = yield* result.get(input.sessionID)
|
||||
const value = input.directory.trim()
|
||||
|
||||
@@ -53,7 +53,7 @@ export function fromRow(row: typeof SessionTable.$inferSelect): SessionSchema.In
|
||||
time: {
|
||||
created: DateTime.makeUnsafe(row.time_created),
|
||||
updated: DateTime.makeUnsafe(row.time_updated),
|
||||
archived: row.time_archived ? DateTime.makeUnsafe(row.time_archived) : undefined,
|
||||
archived: row.time_archived !== null ? DateTime.makeUnsafe(row.time_archived) : undefined,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -171,6 +171,7 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
|
||||
},
|
||||
"session.moved": () => Effect.void,
|
||||
"session.renamed": () => Effect.void,
|
||||
"session.archived": () => Effect.void,
|
||||
"session.deleted": () => Effect.void,
|
||||
"session.forked": () => Effect.void,
|
||||
"session.input.promoted": () => Effect.void,
|
||||
|
||||
@@ -609,6 +609,17 @@ const layer = Layer.effectDiscard(
|
||||
.run()
|
||||
.pipe(Effect.orDie),
|
||||
)
|
||||
yield* bus.project(SessionEvent.Archived, (event) =>
|
||||
db
|
||||
.update(SessionTable)
|
||||
.set({
|
||||
time_archived: DateTime.toEpochMillis(event.created),
|
||||
time_updated: DateTime.toEpochMillis(event.created),
|
||||
})
|
||||
.where(eq(SessionTable.id, event.data.sessionID))
|
||||
.run()
|
||||
.pipe(Effect.orDie),
|
||||
)
|
||||
yield* bus.project(SessionEvent.UsageRecorded, (event) => applyUsage(db, event.data.sessionID, event.data))
|
||||
yield* bus.project(SessionEvent.Forked, (event) => projectFork(db, event))
|
||||
yield* bus.project(SessionEvent.InputPromoted, (event) =>
|
||||
|
||||
@@ -660,4 +660,32 @@ describe("Session.create", () => {
|
||||
).toBe("Session.NotFoundError")
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("archives a Session through one durable event", () =>
|
||||
Effect.gen(function* () {
|
||||
const session = yield* Session.Service
|
||||
const created = yield* session.create({ location })
|
||||
|
||||
yield* session.archive(created.id)
|
||||
yield* session.archive(created.id)
|
||||
|
||||
expect((yield* session.get(created.id)).time.archived).toBeDefined()
|
||||
const events = Array.from(yield* logEvents(session, created.id).pipe(Stream.runCollect))
|
||||
expect(events.map((event) => event.type)).toContain("session.archived")
|
||||
expect(events.filter((event) => event.type === "session.archived")).toHaveLength(1)
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("rejects archiving a missing Session", () =>
|
||||
Effect.gen(function* () {
|
||||
const session = yield* Session.Service
|
||||
|
||||
expect(
|
||||
yield* session.archive(Session.ID.make("ses_missing_archive")).pipe(
|
||||
Effect.flip,
|
||||
Effect.map((error) => error._tag),
|
||||
),
|
||||
).toBe("Session.NotFoundError")
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
@@ -269,6 +269,21 @@ export const makeSessionGroup = <I extends HttpApiMiddleware.AnyId, S>(sessionLo
|
||||
}),
|
||||
),
|
||||
)
|
||||
.add(
|
||||
HttpApiEndpoint.post("session.archive", "/api/session/:sessionID/archive", {
|
||||
params: { sessionID: Session.ID },
|
||||
success: HttpApiSchema.NoContent,
|
||||
error: SessionNotFoundError,
|
||||
})
|
||||
.middleware(sessionLocationMiddleware)
|
||||
.annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "v2.session.archive",
|
||||
summary: "Archive session",
|
||||
description: "Archive a session.",
|
||||
}),
|
||||
),
|
||||
)
|
||||
.add(
|
||||
HttpApiEndpoint.post("session.move", "/api/session/:sessionID/move", {
|
||||
params: { sessionID: Session.ID },
|
||||
|
||||
@@ -86,6 +86,13 @@ export const Renamed = Event.durable({
|
||||
})
|
||||
export type Renamed = typeof Renamed.Type
|
||||
|
||||
export const Archived = Event.durable({
|
||||
type: "session.archived",
|
||||
...options,
|
||||
schema: Base,
|
||||
})
|
||||
export type Archived = typeof Archived.Type
|
||||
|
||||
export const UsageRecorded = Event.durable({
|
||||
type: "session.usage.recorded",
|
||||
...options,
|
||||
@@ -550,6 +557,7 @@ export const Definitions = Event.inventory(
|
||||
ModelSelected,
|
||||
Moved,
|
||||
Renamed,
|
||||
Archived,
|
||||
UsageUpdated,
|
||||
Deleted,
|
||||
Forked,
|
||||
|
||||
@@ -104,6 +104,7 @@ describe("public event manifest", () => {
|
||||
"session.model.selected.1",
|
||||
"session.moved.1",
|
||||
"session.renamed.1",
|
||||
"session.archived.1",
|
||||
"session.usage.recorded.1",
|
||||
"session.forked.2",
|
||||
"session.input.promoted.1",
|
||||
|
||||
@@ -201,6 +201,22 @@ export const SessionHandler = HttpApiBuilder.group(Api, "server.session", (handl
|
||||
return HttpApiSchema.NoContent.make()
|
||||
}),
|
||||
)
|
||||
.handle(
|
||||
"session.archive",
|
||||
Effect.fn(function* (ctx) {
|
||||
yield* session.archive(ctx.params.sessionID).pipe(
|
||||
Effect.catchTag("Session.NotFoundError", (error) =>
|
||||
Effect.fail(
|
||||
new SessionNotFoundError({
|
||||
sessionID: error.sessionID,
|
||||
message: `Session not found: ${error.sessionID}`,
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
return HttpApiSchema.NoContent.make()
|
||||
}),
|
||||
)
|
||||
.handle(
|
||||
"session.move",
|
||||
Effect.fn(function* (ctx) {
|
||||
|
||||
Reference in New Issue
Block a user