mirror of
https://gitee.com/zhangsken/opencode.git
synced 2026-10-16 10:30:01 +08:00
refactor(protocol): normalize session resources
This commit is contained in:
+27
-27
@@ -111,7 +111,7 @@ Review endpoints in document order. For each endpoint, select one disposition an
|
||||
|---|---|---|---|---|---|
|
||||
| [x] 025 | `GET` | `/api/integration` | `integration.list` | Keep | Full integration inventory is consumed by authentication and integration-selection clients. |
|
||||
| [x] 026 | `GET` | `/api/integration/{integrationID}` | `integration.get` | Change | Missing integration now returns typed `404` instead of optional data. |
|
||||
| [ ] 027 | `POST` | `/api/experimental/integration/wellknown` | `experimental.integration.wellknown.add` | | |
|
||||
| [x] | `POST` | `/api/experimental/integration/wellknown` | `experimental.integration.wellknown.add` | Experimental-only | Retained outside the stable API commitment. |
|
||||
| [ ] 028 | `POST` | `/api/integration/{integrationID}/connect/key` | `integration.connect.key` | | |
|
||||
| [ ] 029 | `POST` | `/api/integration/{integrationID}/connect/oauth` | `integration.oauth.connect` | | |
|
||||
| [ ] 030 | `GET` | `/api/integration/{integrationID}/connect/oauth/{attemptID}` | `integration.oauth.status` | | |
|
||||
@@ -175,19 +175,19 @@ Review endpoints in document order. For each endpoint, select one disposition an
|
||||
|
||||
| Done | Method | Path | Operation ID | Decision | Notes |
|
||||
|---|---|---|---|---|---|
|
||||
| [ ] 070 | `POST` | `/api/session/import` | `session.import` | | |
|
||||
| [ ] 071 | `GET` | `/api/session/{sessionID}/export` | `session.export` | | |
|
||||
| [ ] 072 | `POST` | `/api/session/{sessionID}/revert/stage` | `session.revert.stage` | | |
|
||||
| [ ] 073 | `POST` | `/api/session/{sessionID}/revert/clear` | `session.revert.clear` | | |
|
||||
| [ ] 074 | `POST` | `/api/session/{sessionID}/revert/commit` | `session.revert.commit` | | |
|
||||
| [ ] 075 | `GET` | `/api/session/{sessionID}/context` | `session.context` | | |
|
||||
| [ ] 076 | `GET` | `/api/session/{sessionID}/diff` | `session.diff` | | |
|
||||
| [ ] 077 | `GET` | `/api/session/{sessionID}/instructions/entries` | `session.instructions.entry.list` | | |
|
||||
| [ ] 078 | `PUT` | `/api/session/{sessionID}/instructions/entries/{key}` | `session.instructions.entry.put` | | |
|
||||
| [ ] 079 | `DELETE` | `/api/session/{sessionID}/instructions/entries/{key}` | `session.instructions.entry.remove` | | |
|
||||
| [ ] 080 | `GET` | `/api/experimental/session/{sessionID}/log` | `session.log` | | |
|
||||
| [ ] 081 | `GET` | `/api/session/{sessionID}/message/{messageID}` | `session.message` | | |
|
||||
| [ ] 082 | `GET` | `/api/session/{sessionID}/message` | `message.list` | | |
|
||||
| [x] 070 | `POST` | `/api/experimental/session/import` | `experimental.session.import` | Experimental-only | Existing projected transcript import contract retained outside the stable API. |
|
||||
| [x] 071 | `GET` | `/api/experimental/session/{sessionID}/export` | `experimental.session.export` | Experimental-only | Existing projected transcript export contract retained outside the stable API. |
|
||||
| [x] 072 | `POST` | `/api/session/{sessionID}/revert/stage` | `session.revert.stage` | Keep | Existing staged history and optional file restoration behavior retained. |
|
||||
| [x] 073 | `DELETE` | `/api/session/{sessionID}/revert` | `session.revert.clear` | Change | Clearing staged revert now deletes the session revert resource. |
|
||||
| [x] 074 | `POST` | `/api/session/{sessionID}/revert/commit` | `session.revert.commit` | Keep | Explicit staged-revert commit action retained. |
|
||||
| [x] 075 | `GET` | `/api/session/{sessionID}/context` | `session.context` | Keep | Active model-context projection retained. |
|
||||
| [x] 076 | `GET` | `/api/session/{sessionID}/diff` | `session.diff` | Keep | Turn-range structured diff contract retained. |
|
||||
| [x] 077 | `GET` | `/api/experimental/session/{sessionID}/instructions/entries` | `experimental.session.instructions.entry.list` | Experimental-only | API-managed durable context entries retained outside the stable API. |
|
||||
| [x] 078 | `PUT` | `/api/experimental/session/{sessionID}/instructions/entries/{key}` | `experimental.session.instructions.entry.put` | Experimental-only | API-managed durable context entries retained outside the stable API. |
|
||||
| [x] 079 | `DELETE` | `/api/experimental/session/{sessionID}/instructions/entries/{key}` | `experimental.session.instructions.entry.remove` | Experimental-only | API-managed durable context entries retained outside the stable API. |
|
||||
| [x] | `GET` | `/api/experimental/session/{sessionID}/log` | `session.log` | Experimental-only | Retained outside the stable API commitment. |
|
||||
| [x] 081 | `GET` | `/api/session/{sessionID}/message/{messageID}` | `session.message.get` | Change | Normalized specific-message operation ID. |
|
||||
| [x] 082 | `GET` | `/api/session/{sessionID}/message` | `session.message.list` | Change | Normalized session-scoped message-list operation ID. |
|
||||
|
||||
## Group 7: Inbox, permissions, and forms
|
||||
|
||||
@@ -195,7 +195,7 @@ Review endpoints in document order. For each endpoint, select one disposition an
|
||||
|
||||
| Done | Method | Path | Operation ID | Decision | Notes |
|
||||
|---|---|---|---|---|---|
|
||||
| [ ] 083 | `GET` | `/api/session/{sessionID}/inbox` | `session.inbox.list` | | |
|
||||
| [x] 083 | `GET` | `/api/session/{sessionID}/inbox` | `session.inbox.list` | Change | Inbox timestamps now use the standard nested `time.created` shape. |
|
||||
| [ ] 084 | `DELETE` | `/api/session/{sessionID}/inbox/{inboxID}` | `session.inbox.cancel` | | |
|
||||
| [ ] 085 | `POST` | `/api/session/{sessionID}/inbox/{inboxID}/steer` | `session.inbox.steer` | | |
|
||||
| [ ] 086 | `POST` | `/api/session/{sessionID}/inbox/{inboxID}/queue` | `session.inbox.queue` | | |
|
||||
@@ -247,17 +247,17 @@ Review endpoints in document order. For each endpoint, select one disposition an
|
||||
| [ ] 118 | `DELETE` | `/api/pty/{ptyID}` | `pty.remove` | | |
|
||||
| [ ] 119 | `POST` | `/api/pty/{ptyID}/connect-token` | `pty.connect.token` | | |
|
||||
| [ ] 120 | `GET` | `/api/pty/{ptyID}/connect` | `pty.connect` | | |
|
||||
| [ ] 121 | `GET` | `/api/experimental/session/{sessionID}/terminal/read` | `server.experimental.persistentPty.read` | | |
|
||||
| [ ] 122 | `GET` | `/api/experimental/session/{sessionID}/terminal` | `server.experimental.persistentPty.list` | | |
|
||||
| [ ] 123 | `POST` | `/api/experimental/session/{sessionID}/terminal` | `server.experimental.persistentPty.create` | | |
|
||||
| [ ] 124 | `POST` | `/api/experimental/persistent-pty/shutdown` | `server.experimental.persistentPty.shutdown` | | |
|
||||
| [ ] 125 | `POST` | `/api/experimental/persistent-pty/handoff` | `server.experimental.persistentPty.handoff` | | |
|
||||
| [ ] 126 | `GET` | `/api/experimental/persistent-pty/{ptyID}` | `server.experimental.persistentPty.get` | | |
|
||||
| [ ] 127 | `PUT` | `/api/experimental/persistent-pty/{ptyID}` | `server.experimental.persistentPty.update` | | |
|
||||
| [ ] 128 | `DELETE` | `/api/experimental/persistent-pty/{ptyID}` | `server.experimental.persistentPty.remove` | | |
|
||||
| [ ] 129 | `GET` | `/api/experimental/persistent-pty/{ptyID}/snapshot` | `server.experimental.persistentPty.snapshot` | | |
|
||||
| [ ] 130 | `POST` | `/api/experimental/persistent-pty/{ptyID}/connect-token` | `server.experimental.persistentPty.connectToken` | | |
|
||||
| [ ] 131 | `GET` | `/api/experimental/persistent-pty/{ptyID}/connect` | `persistentPty.connect` | | |
|
||||
| [x] | `GET` | `/api/experimental/session/{sessionID}/terminal/read` | `server.experimental.persistentPty.read` | Experimental-only | Retained outside the stable API commitment. |
|
||||
| [x] | `GET` | `/api/experimental/session/{sessionID}/terminal` | `server.experimental.persistentPty.list` | Experimental-only | Retained outside the stable API commitment. |
|
||||
| [x] | `POST` | `/api/experimental/session/{sessionID}/terminal` | `server.experimental.persistentPty.create` | Experimental-only | Retained outside the stable API commitment. |
|
||||
| [x] | `POST` | `/api/experimental/persistent-pty/shutdown` | `server.experimental.persistentPty.shutdown` | Experimental-only | Retained outside the stable API commitment. |
|
||||
| [x] | `POST` | `/api/experimental/persistent-pty/handoff` | `server.experimental.persistentPty.handoff` | Experimental-only | Retained outside the stable API commitment. |
|
||||
| [x] | `GET` | `/api/experimental/persistent-pty/{ptyID}` | `server.experimental.persistentPty.get` | Experimental-only | Retained outside the stable API commitment. |
|
||||
| [x] | `PUT` | `/api/experimental/persistent-pty/{ptyID}` | `server.experimental.persistentPty.update` | Experimental-only | Retained outside the stable API commitment. |
|
||||
| [x] | `DELETE` | `/api/experimental/persistent-pty/{ptyID}` | `server.experimental.persistentPty.remove` | Experimental-only | Retained outside the stable API commitment. |
|
||||
| [x] | `GET` | `/api/experimental/persistent-pty/{ptyID}/snapshot` | `server.experimental.persistentPty.snapshot` | Experimental-only | Retained outside the stable API commitment. |
|
||||
| [x] | `POST` | `/api/experimental/persistent-pty/{ptyID}/connect-token` | `server.experimental.persistentPty.connectToken` | Experimental-only | Retained outside the stable API commitment. |
|
||||
| [x] | `GET` | `/api/experimental/persistent-pty/{ptyID}/connect` | `persistentPty.connect` | Experimental-only | Retained outside the stable API commitment. |
|
||||
| [ ] 132 | `GET` | `/api/shell` | `shell.list` | | |
|
||||
| [ ] 133 | `POST` | `/api/shell` | `shell.create` | | |
|
||||
| [ ] 134 | `GET` | `/api/shell/{id}` | `shell.get` | | |
|
||||
@@ -276,4 +276,4 @@ Review endpoints in document order. For each endpoint, select one disposition an
|
||||
| [ ] 140 | `GET` | `/api/event` | `event.subscribe` | | |
|
||||
| [ ] 141 | `GET` | `/api/debug/location` | `debug.location.list` | | |
|
||||
| [ ] 142 | `DELETE` | `/api/debug/location` | `debug.location.evict` | | |
|
||||
| [ ] 143 | `GET` | `/api/experimental/migration/v1` | `experimental.migration.v1.status` | | |
|
||||
| [x] | `GET` | `/api/experimental/migration/v1` | `experimental.migration.v1.status` | Experimental-only | Retained outside the stable API commitment. |
|
||||
|
||||
@@ -12,7 +12,7 @@ const server = `http://${process.env.PLAYWRIGHT_SERVER_HOST ?? "127.0.0.1"}:${pr
|
||||
type InboxRow = {
|
||||
id: string
|
||||
sessionID: string
|
||||
timeCreated: number
|
||||
time: { created: number }
|
||||
type: "user"
|
||||
payload: { text: string; metadata?: Record<string, unknown> }
|
||||
delivery: "steer" | "queue"
|
||||
@@ -22,7 +22,7 @@ function createQueueMock(seed: string[], messages: SessionMessageInfo[] = []) {
|
||||
const rows: InboxRow[] = seed.map((text, index) => ({
|
||||
id: `inb_seed_${index + 1}`,
|
||||
sessionID,
|
||||
timeCreated: 1700000000000 + index,
|
||||
time: { created: 1700000000000 + index },
|
||||
type: "user",
|
||||
payload: { text },
|
||||
delivery: "queue",
|
||||
@@ -59,7 +59,7 @@ function createQueueMock(seed: string[], messages: SessionMessageInfo[] = []) {
|
||||
const row: InboxRow = {
|
||||
id: typeof input.body.id === "string" ? input.body.id : `inb_mock_${sequence}`,
|
||||
sessionID: input.sessionID,
|
||||
timeCreated: Date.now(),
|
||||
time: { created: Date.now() },
|
||||
type: "user",
|
||||
payload: {
|
||||
text: typeof input.body.text === "string" ? input.body.text : "",
|
||||
|
||||
@@ -254,7 +254,7 @@ const Group = HttpApiGroup.make("mock")
|
||||
}),
|
||||
)
|
||||
.add(
|
||||
HttpApiEndpoint.post("sessionRevertClear", "/api/session/:sessionID/revert/clear", {
|
||||
HttpApiEndpoint.delete("sessionRevertClear", "/api/session/:sessionID/revert", {
|
||||
params: SessionParams,
|
||||
success: NoContent,
|
||||
}),
|
||||
|
||||
@@ -437,7 +437,7 @@ function mockHandlers(config: MockServerConfig, state: { cursors: Map<string, st
|
||||
data: {
|
||||
id: typeof body.id === "string" ? body.id : `inb_mock_${Date.now()}`,
|
||||
sessionID: ctx.params.sessionID,
|
||||
timeCreated: Date.now(),
|
||||
time: { created: Date.now() },
|
||||
type: "user",
|
||||
payload: {
|
||||
text: typeof body.text === "string" ? body.text : "",
|
||||
|
||||
@@ -6,7 +6,7 @@ const queued = [
|
||||
{
|
||||
id: "msg_original",
|
||||
sessionID: "ses_1",
|
||||
timeCreated: 1,
|
||||
time: { created: 1 },
|
||||
type: "user",
|
||||
delivery: "queue",
|
||||
payload: { text: "original" },
|
||||
@@ -14,7 +14,7 @@ const queued = [
|
||||
{
|
||||
id: "msg_replacement",
|
||||
sessionID: "ses_1",
|
||||
timeCreated: 2,
|
||||
time: { created: 2 },
|
||||
type: "user",
|
||||
delivery: "queue",
|
||||
payload: { text: "edited" },
|
||||
|
||||
@@ -70,7 +70,7 @@ export function createSessionRevert(input: {
|
||||
.map((item) => item.id)
|
||||
void server.api.session.inbox
|
||||
.list({ sessionID })
|
||||
.then((rows) => rows.filter((row) => row.type === "user" && row.timeCreated <= cutoff).map((row) => row.id))
|
||||
.then((rows) => rows.filter((row) => row.type === "user" && row.time.created <= cutoff).map((row) => row.id))
|
||||
.catch(() => [])
|
||||
.then((authoritative) => {
|
||||
new Set([...local, ...authoritative]).forEach(
|
||||
|
||||
@@ -23,7 +23,7 @@ describe("visibleTimelineMessages", () => {
|
||||
const steer = {
|
||||
id: "msg_3",
|
||||
sessionID: "ses_1",
|
||||
timeCreated: 3,
|
||||
time: { created: 3 },
|
||||
type: "user",
|
||||
delivery: "steer",
|
||||
payload: { text: "queued" },
|
||||
@@ -135,7 +135,7 @@ describe("visibleTimelineMessages", () => {
|
||||
{
|
||||
id: "msg_3",
|
||||
sessionID: "ses_1",
|
||||
timeCreated: 3,
|
||||
time: { created: 3 },
|
||||
type: "user",
|
||||
delivery: "queue",
|
||||
payload: { text: "queued" },
|
||||
|
||||
@@ -369,7 +369,7 @@ export async function streamTurn(input: {
|
||||
}
|
||||
const assistant = assistantMessageID
|
||||
? await input.client.session
|
||||
.message({ sessionID: input.sessionID, messageID: assistantMessageID })
|
||||
.message.get({ sessionID: input.sessionID, messageID: assistantMessageID })
|
||||
.catch(() => undefined)
|
||||
: undefined
|
||||
return response(
|
||||
|
||||
@@ -39,7 +39,7 @@ export default Runtime.handler(
|
||||
}),
|
||||
)
|
||||
const response = yield* Effect.promise(() =>
|
||||
fetch(new URL("/api/session/import", server.endpoint.url), {
|
||||
fetch(new URL("/api/experimental/session/import", server.endpoint.url), {
|
||||
method: "POST",
|
||||
headers: { ...Service.headers(server.endpoint), "content-type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
|
||||
@@ -62,7 +62,7 @@ test("export is raw by default and supports explicit sanitization", async () =>
|
||||
const url = new URL(request.url)
|
||||
if (url.pathname === "/api/status") return status()
|
||||
if (url.pathname === `/api/session/${info.id}`) return Response.json({ data: info })
|
||||
if (url.pathname === `/api/session/${info.id}/export`) {
|
||||
if (url.pathname === `/api/experimental/session/${info.id}/export`) {
|
||||
sanitization.push(url.searchParams.get("sanitize") ?? "")
|
||||
return Response.json({ data: url.searchParams.get("sanitize") === "true" ? sanitizedTransfer : transfer })
|
||||
}
|
||||
@@ -128,7 +128,7 @@ test("export reports a missing session without a stack trace", async () => {
|
||||
fetch(request) {
|
||||
const url = new URL(request.url)
|
||||
if (url.pathname === "/api/status") return status()
|
||||
if (url.pathname === `/api/session/${sessionID}/export`) {
|
||||
if (url.pathname === `/api/experimental/session/${sessionID}/export`) {
|
||||
return Response.json(
|
||||
{ _tag: "SessionNotFoundError", sessionID, message: `Session not found: ${sessionID}` },
|
||||
{ status: 404 },
|
||||
@@ -165,7 +165,7 @@ test("import validates a file and sends it to the resolved location", async () =
|
||||
project: { id: "global", directory: root, canonical: root },
|
||||
})
|
||||
}
|
||||
if (url.pathname === "/api/session/import") {
|
||||
if (url.pathname === "/api/experimental/session/import") {
|
||||
imported = await request.json()
|
||||
return Response.json({ data: { ...info, location: { directory: root } } })
|
||||
}
|
||||
@@ -208,7 +208,7 @@ test("import reports an existing session without a stack trace", async () => {
|
||||
project: { id: "global", directory: root, canonical: root },
|
||||
})
|
||||
}
|
||||
if (url.pathname === "/api/session/import") return new Response("Conflict", { status: 409 })
|
||||
if (url.pathname === "/api/experimental/session/import") return new Response("Conflict", { status: 409 })
|
||||
return new Response("Not found", { status: 404 })
|
||||
},
|
||||
})
|
||||
|
||||
@@ -265,7 +265,7 @@ async function run(input: {
|
||||
values.push(...input.turn(messageID))
|
||||
wake?.()
|
||||
wake = undefined
|
||||
return ok({ id: messageID, sessionID: "ses_1", timeCreated: 1 }) as never
|
||||
return ok({ id: messageID, sessionID: "ses_1", time: { created: 1 } }) as never
|
||||
})
|
||||
await runNonInteractivePrompt({
|
||||
client: sdk,
|
||||
|
||||
@@ -1319,9 +1319,11 @@ export type SessionBackgroundOperation<E = never> = (
|
||||
input: SessionBackgroundInput,
|
||||
) => Effect.Effect<SessionBackgroundOutput, E>
|
||||
|
||||
export type SessionMessageInput = { readonly sessionID: Session.ID; readonly messageID: SessionMessage.ID }
|
||||
export type SessionMessageOutput = SessionMessage.Info
|
||||
export type SessionMessageOperation<E = never> = (input: SessionMessageInput) => Effect.Effect<SessionMessageOutput, E>
|
||||
export type SessionMessageGetInput = { readonly sessionID: Session.ID; readonly messageID: SessionMessage.ID }
|
||||
export type SessionMessageGetOutput = SessionMessage.Info
|
||||
export type SessionMessageGetOperation<E = never> = (
|
||||
input: SessionMessageGetInput,
|
||||
) => Effect.Effect<SessionMessageGetOutput, E>
|
||||
|
||||
export type SessionEnvironmentInput = {
|
||||
readonly sessionID: Session.ID
|
||||
@@ -1381,7 +1383,7 @@ export interface SessionApi<E = never> {
|
||||
readonly log: SessionLogOperation<E>
|
||||
readonly interrupt: SessionInterruptOperation<E>
|
||||
readonly background: SessionBackgroundOperation<E>
|
||||
readonly message: SessionMessageOperation<E>
|
||||
readonly message: { readonly get: SessionMessageGetOperation<E> }
|
||||
readonly environment: SessionEnvironmentOperation<E>
|
||||
readonly view: SessionViewOperation<E>
|
||||
}
|
||||
|
||||
@@ -89,8 +89,8 @@ import type {
|
||||
SessionInterruptOutput,
|
||||
SessionBackgroundInput,
|
||||
SessionBackgroundOutput,
|
||||
SessionMessageInput,
|
||||
SessionMessageOutput,
|
||||
SessionMessageGetInput,
|
||||
SessionMessageGetOutput,
|
||||
SessionEnvironmentInput,
|
||||
SessionEnvironmentOutput,
|
||||
SessionViewInput,
|
||||
@@ -678,8 +678,8 @@ const EndpointSessionBackground = (raw: RawClient["server.session"]) => (input:
|
||||
raw["session.background"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const EndpointSessionMessage = (raw: RawClient["server.session"]) => (input: SessionMessageInput) =>
|
||||
preserveEffect<SessionMessageOutput>()(
|
||||
const EndpointSessionMessageGet = (raw: RawClient["server.session"]) => (input: SessionMessageGetInput) =>
|
||||
preserveEffect<SessionMessageGetOutput>()(
|
||||
raw["session.message"]({ params: { sessionID: input["sessionID"], messageID: input["messageID"] } }).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
@@ -746,7 +746,7 @@ const adaptGroupSession = (raw: RawClient["server.session"]) => ({
|
||||
log: EndpointSessionLog(raw),
|
||||
interrupt: EndpointSessionInterrupt(raw),
|
||||
background: EndpointSessionBackground(raw),
|
||||
message: EndpointSessionMessage(raw),
|
||||
message: { get: EndpointSessionMessageGet(raw) },
|
||||
environment: EndpointSessionEnvironment(raw),
|
||||
view: EndpointSessionView(raw),
|
||||
})
|
||||
|
||||
@@ -83,8 +83,8 @@ import type {
|
||||
SessionInterruptOutput,
|
||||
SessionBackgroundInput,
|
||||
SessionBackgroundOutput,
|
||||
SessionMessageInput,
|
||||
SessionMessageOutput,
|
||||
SessionMessageGetInput,
|
||||
SessionMessageGetOutput,
|
||||
SessionEnvironmentInput,
|
||||
SessionEnvironmentOutput,
|
||||
SessionViewInput,
|
||||
@@ -555,7 +555,7 @@ export function make(options: ClientOptions) {
|
||||
request<{ readonly data: SessionImportOutput }>(
|
||||
{
|
||||
method: "POST",
|
||||
path: `/api/session/import`,
|
||||
path: `/api/experimental/session/import`,
|
||||
body: { info: input["info"], messages: input["messages"], location: input["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [400, 401, 404, 409],
|
||||
@@ -567,7 +567,7 @@ export function make(options: ClientOptions) {
|
||||
request<{ readonly data: SessionExportOutput }>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/export`,
|
||||
path: `/api/experimental/session/${encodeURIComponent(input.sessionID)}/export`,
|
||||
query: { sanitize: input["sanitize"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [400, 401, 404, 500],
|
||||
@@ -790,8 +790,8 @@ export function make(options: ClientOptions) {
|
||||
clear: (input: SessionRevertClearInput, requestOptions?: RequestOptions) =>
|
||||
request<SessionRevertClearOutput>(
|
||||
{
|
||||
method: "POST",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/revert/clear`,
|
||||
method: "DELETE",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/revert`,
|
||||
successStatus: 204,
|
||||
declaredStatuses: [400, 401, 404, 409, 500],
|
||||
empty: true,
|
||||
@@ -885,7 +885,7 @@ export function make(options: ClientOptions) {
|
||||
request<{ readonly data: SessionInstructionsEntryListOutput }>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/instructions/entries`,
|
||||
path: `/api/experimental/session/${encodeURIComponent(input.sessionID)}/instructions/entries`,
|
||||
successStatus: 200,
|
||||
declaredStatuses: [400, 401, 404],
|
||||
empty: false,
|
||||
@@ -896,7 +896,7 @@ export function make(options: ClientOptions) {
|
||||
request<SessionInstructionsEntryPutOutput>(
|
||||
{
|
||||
method: "PUT",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/instructions/entries/${encodeURIComponent(input.key)}`,
|
||||
path: `/api/experimental/session/${encodeURIComponent(input.sessionID)}/instructions/entries/${encodeURIComponent(input.key)}`,
|
||||
body: { value: input["value"] },
|
||||
successStatus: 204,
|
||||
declaredStatuses: [400, 401, 404, 413],
|
||||
@@ -908,7 +908,7 @@ export function make(options: ClientOptions) {
|
||||
request<SessionInstructionsEntryRemoveOutput>(
|
||||
{
|
||||
method: "DELETE",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/instructions/entries/${encodeURIComponent(input.key)}`,
|
||||
path: `/api/experimental/session/${encodeURIComponent(input.sessionID)}/instructions/entries/${encodeURIComponent(input.key)}`,
|
||||
successStatus: 204,
|
||||
declaredStatuses: [400, 401, 404],
|
||||
empty: true,
|
||||
@@ -964,17 +964,19 @@ export function make(options: ClientOptions) {
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
message: (input: SessionMessageInput, requestOptions?: RequestOptions) =>
|
||||
request<{ readonly data: SessionMessageOutput }>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/message/${encodeURIComponent(input.messageID)}`,
|
||||
successStatus: 200,
|
||||
declaredStatuses: [400, 401, 404],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
).then((value) => value.data),
|
||||
message: {
|
||||
get: (input: SessionMessageGetInput, requestOptions?: RequestOptions) =>
|
||||
request<{ readonly data: SessionMessageGetOutput }>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/message/${encodeURIComponent(input.messageID)}`,
|
||||
successStatus: 200,
|
||||
declaredStatuses: [400, 401, 404],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
).then((value) => value.data),
|
||||
},
|
||||
environment: (input: SessionEnvironmentInput, requestOptions?: RequestOptions) =>
|
||||
request<SessionEnvironmentOutput>(
|
||||
{
|
||||
|
||||
@@ -529,7 +529,7 @@ export type SessionProviderContext = { version: 1; provenance: SessionProviderCo
|
||||
export type SessionInboxSynthetic = {
|
||||
id: string
|
||||
sessionID: string
|
||||
timeCreated: number
|
||||
time: { created: number }
|
||||
type: "synthetic"
|
||||
payload: SessionInboxSyntheticPayload
|
||||
delivery: SessionInboxDelivery
|
||||
@@ -538,7 +538,7 @@ export type SessionInboxSynthetic = {
|
||||
export type SessionInboxCompaction = {
|
||||
id: string
|
||||
sessionID: string
|
||||
timeCreated: number
|
||||
time: { created: number }
|
||||
type: "compaction"
|
||||
payload: SessionInboxCompactionPayload
|
||||
delivery: SessionInboxDelivery
|
||||
@@ -1629,7 +1629,7 @@ export type VcsInfo = { branch: VcsBranch }
|
||||
export type SessionInboxMove = {
|
||||
id: string
|
||||
sessionID: string
|
||||
timeCreated: number
|
||||
time: { created: number }
|
||||
type: "move"
|
||||
delivery: SessionInboxDelivery
|
||||
payload: SessionInboxMovePayload
|
||||
@@ -2107,7 +2107,7 @@ export type ConfigEntry =
|
||||
export type SessionInboxUser = {
|
||||
id: string
|
||||
sessionID: string
|
||||
timeCreated: number
|
||||
time: { created: number }
|
||||
type: "user"
|
||||
payload: SessionInboxUserPayload
|
||||
delivery: SessionInboxDelivery
|
||||
@@ -4390,12 +4390,12 @@ export type SessionBackgroundInput = { readonly sessionID: { readonly sessionID:
|
||||
|
||||
export type SessionBackgroundOutput = void
|
||||
|
||||
export type SessionMessageInput = {
|
||||
export type SessionMessageGetInput = {
|
||||
readonly sessionID: { readonly sessionID: string; readonly messageID: string }["sessionID"]
|
||||
readonly messageID: { readonly sessionID: string; readonly messageID: string }["messageID"]
|
||||
}
|
||||
|
||||
export type SessionMessageOutput = { data: SessionMessageInfo }["data"]
|
||||
export type SessionMessageGetOutput = { data: SessionMessageInfo }["data"]
|
||||
|
||||
export type SessionEnvironmentInput = {
|
||||
readonly sessionID: { readonly sessionID: string }["sessionID"]
|
||||
|
||||
@@ -389,8 +389,8 @@ export function createData(config: CreateDataInput) {
|
||||
message.update(item.sessionID, (draft, index) => {
|
||||
const row =
|
||||
item.type === "user"
|
||||
? { id: item.id, type: "user" as const, ...item.payload, time: { created: item.timeCreated } }
|
||||
: { id: item.id, type: "synthetic" as const, ...item.payload, time: { created: item.timeCreated } }
|
||||
? { id: item.id, type: "user" as const, ...item.payload, time: { created: item.time.created } }
|
||||
: { id: item.id, type: "synthetic" as const, ...item.payload, time: { created: item.time.created } }
|
||||
const position = index.get(item.id)
|
||||
if (position === undefined) return message.append(draft, index, row)
|
||||
draft[position] = row
|
||||
@@ -671,7 +671,7 @@ export function createData(config: CreateDataInput) {
|
||||
})
|
||||
refresh(() =>
|
||||
api()
|
||||
.session.message({ sessionID: event.data.sessionID, messageID: messageIDFromEvent(event.id) })
|
||||
.session.message.get({ sessionID: event.data.sessionID, messageID: messageIDFromEvent(event.id) })
|
||||
.then((item) => {
|
||||
message.update(event.data.sessionID, (draft, index) => {
|
||||
const position = index.get(item.id)
|
||||
@@ -772,7 +772,7 @@ export function createData(config: CreateDataInput) {
|
||||
admitLocal({
|
||||
id: event.data.inboxID,
|
||||
sessionID: event.data.sessionID,
|
||||
timeCreated: event.created,
|
||||
time: { created: event.created },
|
||||
...event.data.item,
|
||||
})
|
||||
if (event.data.item.type === "compaction") {
|
||||
@@ -1469,7 +1469,7 @@ export function createData(config: CreateDataInput) {
|
||||
admitLocal({
|
||||
id,
|
||||
sessionID: input.sessionID,
|
||||
timeCreated: Date.now(),
|
||||
time: { created: Date.now() },
|
||||
type: "compaction",
|
||||
delivery: "steer",
|
||||
payload: {},
|
||||
@@ -1520,7 +1520,7 @@ export function createData(config: CreateDataInput) {
|
||||
admitLocal({
|
||||
id,
|
||||
sessionID: request.sessionID,
|
||||
timeCreated: Date.now(),
|
||||
time: { created: Date.now() },
|
||||
type: "user",
|
||||
delivery: request.delivery ?? "steer",
|
||||
// Files and skills stay off the optimistic row: their durable
|
||||
|
||||
@@ -99,17 +99,17 @@ test("session instructions methods use the public HTTP contract", async () => {
|
||||
expect(requests).toEqual([
|
||||
{
|
||||
method: "GET",
|
||||
url: "http://localhost:3000/api/session/ses_test/instructions/entries",
|
||||
url: "http://localhost:3000/api/experimental/session/ses_test/instructions/entries",
|
||||
body: undefined,
|
||||
},
|
||||
{
|
||||
method: "PUT",
|
||||
url: "http://localhost:3000/api/session/ses_test/instructions/entries/review-notes",
|
||||
url: "http://localhost:3000/api/experimental/session/ses_test/instructions/entries/review-notes",
|
||||
body: { value: { text: "Check the diff", priority: 1 } },
|
||||
},
|
||||
{
|
||||
method: "DELETE",
|
||||
url: "http://localhost:3000/api/session/ses_test/instructions/entries/review-notes",
|
||||
url: "http://localhost:3000/api/experimental/session/ses_test/instructions/entries/review-notes",
|
||||
body: undefined,
|
||||
},
|
||||
])
|
||||
@@ -257,7 +257,7 @@ test("session methods retain decoded Effect inputs and outputs", async () => {
|
||||
.log({ sessionID: Session.ID.make("ses_test"), after: Event.Seq.make(0) })
|
||||
.pipe(Stream.runCollect)
|
||||
const interrupted = yield* client.session.interrupt({ sessionID: Session.ID.make("ses_test") })
|
||||
const message = yield* client.session.message({
|
||||
const message = yield* client.session.message.get({
|
||||
sessionID: Session.ID.make("ses_test"),
|
||||
messageID: SessionMessage.ID.make("msg_model"),
|
||||
})
|
||||
@@ -276,7 +276,7 @@ test("session methods retain decoded Effect inputs and outputs", async () => {
|
||||
expect(result.created.id).toBe("ses_test")
|
||||
expect(Object.getPrototypeOf(result.admitted)).toBe(Object.prototype)
|
||||
expect(Object.getPrototypeOf(result.admitted.payload)).toBe(Object.prototype)
|
||||
expect(DateTime.toEpochMillis(result.admitted.timeCreated)).toBe(1_717_171_717_000)
|
||||
expect(DateTime.toEpochMillis(result.admitted.time.created)).toBe(1_717_171_717_000)
|
||||
expect(result.context).toEqual([])
|
||||
expect(logQueries[0]).toEqual({ after: "0" })
|
||||
expect(requests).toContainEqual({ method: "POST", url: "http://localhost:3000/api/session/ses_test/view" })
|
||||
@@ -336,7 +336,7 @@ const admission = {
|
||||
type: "user",
|
||||
payload: { text: "Hello" },
|
||||
delivery: "steer",
|
||||
timeCreated: 1_717_171_717_000,
|
||||
time: { created: 1_717_171_717_000 },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -347,7 +347,7 @@ const compactionAdmission = {
|
||||
delivery: "queue",
|
||||
id: "msg_compaction",
|
||||
sessionID: "ses_test",
|
||||
timeCreated: 1_717_171_717_000,
|
||||
time: { created: 1_717_171_717_000 },
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -487,17 +487,17 @@ test("session instructions methods use the public HTTP contract", async () => {
|
||||
expect(requests).toEqual([
|
||||
{
|
||||
method: "GET",
|
||||
url: "http://localhost:3000/api/session/ses_test/instructions/entries",
|
||||
url: "http://localhost:3000/api/experimental/session/ses_test/instructions/entries",
|
||||
body: undefined,
|
||||
},
|
||||
{
|
||||
method: "PUT",
|
||||
url: "http://localhost:3000/api/session/ses_test/instructions/entries/review-notes",
|
||||
url: "http://localhost:3000/api/experimental/session/ses_test/instructions/entries/review-notes",
|
||||
body: { value: { text: "Check the diff", priority: 1 } },
|
||||
},
|
||||
{
|
||||
method: "DELETE",
|
||||
url: "http://localhost:3000/api/session/ses_test/instructions/entries/review-notes",
|
||||
url: "http://localhost:3000/api/experimental/session/ses_test/instructions/entries/review-notes",
|
||||
body: undefined,
|
||||
},
|
||||
])
|
||||
@@ -509,7 +509,7 @@ test("session.inbox.list uses the public HTTP contract", async () => {
|
||||
{
|
||||
id: "msg_pending",
|
||||
sessionID: "ses_test",
|
||||
timeCreated: 1_717_171_717_000,
|
||||
time: { created: 1_717_171_717_000 },
|
||||
type: "user",
|
||||
payload: { text: "Fix the failing tests" },
|
||||
delivery: "steer",
|
||||
@@ -859,7 +859,7 @@ test("session methods use the public HTTP contract", async () => {
|
||||
const log = []
|
||||
for await (const item of client.session.log({ sessionID: "ses_test", after: 0 })) log.push(item)
|
||||
const interrupted = await client.session.interrupt({ sessionID: "ses_test", continue: true })
|
||||
const message = await client.session.message({ sessionID: "ses_test", messageID: "msg_model" })
|
||||
const message = await client.session.message.get({ sessionID: "ses_test", messageID: "msg_model" })
|
||||
|
||||
expect(page.cursor.next).toBe("next")
|
||||
expect(page.data[0].time).toMatchObject({ idle: 1_717_171_717_002, viewed: 1_717_171_717_001 })
|
||||
@@ -969,7 +969,7 @@ const admission = {
|
||||
type: "user",
|
||||
data: { text: "Hello" },
|
||||
delivery: "steer",
|
||||
timeCreated: 1_717_171_717_000,
|
||||
time: { created: 1_717_171_717_000 },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -980,7 +980,7 @@ const syntheticAdmission = {
|
||||
type: "synthetic",
|
||||
data: { text: "Completed" },
|
||||
delivery: "queue",
|
||||
timeCreated: 1_717_171_717_000,
|
||||
time: { created: 1_717_171_717_000 },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -989,7 +989,7 @@ const compactionAdmission = {
|
||||
type: "compaction",
|
||||
id: "msg_compaction",
|
||||
sessionID: "ses_test",
|
||||
timeCreated: 1_717_171_717_000,
|
||||
time: { created: 1_717_171_717_000 },
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -348,7 +348,7 @@ const event = { id: "evt_compact", created: 10, durable: { aggregateID: sessionI
|
||||
const item = (id: string, timeCreated = 10): SessionInboxCompaction => ({
|
||||
id,
|
||||
sessionID,
|
||||
timeCreated,
|
||||
time: { created: timeCreated },
|
||||
type: "compaction",
|
||||
delivery: "steer",
|
||||
payload: {},
|
||||
|
||||
@@ -142,7 +142,7 @@ function fixture(read?: (url: URL) => Promise<Response | void>) {
|
||||
type: "user",
|
||||
delivery: "steer",
|
||||
payload: { text: "pending" },
|
||||
timeCreated: 1,
|
||||
time: { created: 1 },
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
@@ -77,7 +77,7 @@ const fromRow = (row: typeof SessionInboxTable.$inferSelect): Info => {
|
||||
const base = {
|
||||
id: SessionMessage.ID.make(row.id),
|
||||
sessionID: SessionSchema.ID.make(row.session_id),
|
||||
timeCreated: DateTime.makeUnsafe(row.time_created),
|
||||
time: { created: DateTime.makeUnsafe(row.time_created) },
|
||||
}
|
||||
if (row.type === "compaction")
|
||||
return Compaction.make({
|
||||
@@ -126,7 +126,7 @@ const promotedFromMessage = Effect.fn("SessionInbox.promotedFromMessage")(functi
|
||||
if (row.session_id !== sessionID || (row.type !== "user" && row.type !== "synthetic"))
|
||||
return yield* new LifecycleConflict({ id })
|
||||
const message = decodeMessage({ ...row.data, id: row.id, type: row.type })
|
||||
const base = { id, sessionID, timeCreated: message.time.created, delivery }
|
||||
const base = { id, sessionID, time: { created: message.time.created }, delivery }
|
||||
if (message.type === "user")
|
||||
return User.make({
|
||||
...base,
|
||||
@@ -184,7 +184,7 @@ export const make = Effect.fn("SessionInbox.make")(function* () {
|
||||
Info.make({
|
||||
id: request.id,
|
||||
sessionID: request.sessionID,
|
||||
timeCreated: DateTime.makeUnsafe(event.created),
|
||||
time: { created: DateTime.makeUnsafe(event.created) },
|
||||
...request.item,
|
||||
}),
|
||||
),
|
||||
|
||||
@@ -107,7 +107,7 @@ describe("ConfigCommandPlugin.Plugin", () => {
|
||||
return SessionInbox.User.make({
|
||||
id: SessionMessage.ID.make("msg_test"),
|
||||
sessionID: input.sessionID,
|
||||
timeCreated: DateTime.makeUnsafe(0),
|
||||
time: { created: DateTime.makeUnsafe(0) },
|
||||
type: "user",
|
||||
payload: { text: input.text },
|
||||
delivery: input.delivery ?? "steer",
|
||||
@@ -178,7 +178,7 @@ Review files`,
|
||||
return SessionInbox.User.make({
|
||||
id: SessionMessage.ID.make("msg_test"),
|
||||
sessionID: input.sessionID,
|
||||
timeCreated: DateTime.makeUnsafe(0),
|
||||
time: { created: DateTime.makeUnsafe(0) },
|
||||
type: "user",
|
||||
payload: { text: input.text },
|
||||
delivery: input.delivery ?? "steer",
|
||||
|
||||
@@ -55,7 +55,7 @@ describe("CommandPlugin.Plugin", () => {
|
||||
return SessionInbox.User.make({
|
||||
id: SessionMessage.ID.make("msg_test"),
|
||||
sessionID: input.sessionID,
|
||||
timeCreated: DateTime.makeUnsafe(0),
|
||||
time: { created: DateTime.makeUnsafe(0) },
|
||||
type: "user",
|
||||
payload: { text: input.text },
|
||||
delivery: input.delivery ?? "steer",
|
||||
|
||||
@@ -96,7 +96,7 @@ const run = Effect.fnUntraced(function* (events: ReadonlyArray<SessionEvent.Agen
|
||||
SessionInbox.Synthetic.make({
|
||||
id: SessionMessage.ID.make("msg_plan_test"),
|
||||
sessionID,
|
||||
timeCreated: DateTime.makeUnsafe(0),
|
||||
time: { created: DateTime.makeUnsafe(0) },
|
||||
type: "synthetic",
|
||||
payload: { text: input.text },
|
||||
delivery: "steer",
|
||||
|
||||
@@ -1064,10 +1064,10 @@
|
||||
"summary": "Get session statistics"
|
||||
}
|
||||
},
|
||||
"/api/session/import": {
|
||||
"/api/experimental/session/import": {
|
||||
"post": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.import",
|
||||
"operationId": "experimental.session.import",
|
||||
"parameters": [],
|
||||
"security": [],
|
||||
"responses": {
|
||||
@@ -1166,10 +1166,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/session/{sessionID}/export": {
|
||||
"/api/experimental/session/{sessionID}/export": {
|
||||
"get": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.export",
|
||||
"operationId": "experimental.session.export",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -2804,8 +2804,8 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/session/{sessionID}/revert/clear": {
|
||||
"post": {
|
||||
"/api/session/{sessionID}/revert": {
|
||||
"delete": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.revert.clear",
|
||||
"parameters": [
|
||||
@@ -3478,10 +3478,10 @@
|
||||
"summary": "Queue steered item"
|
||||
}
|
||||
},
|
||||
"/api/session/{sessionID}/instructions/entries": {
|
||||
"/api/experimental/session/{sessionID}/instructions/entries": {
|
||||
"get": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.instructions.entry.list",
|
||||
"operationId": "experimental.session.instructions.entry.list",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -3557,10 +3557,10 @@
|
||||
"summary": "List instruction entries"
|
||||
}
|
||||
},
|
||||
"/api/session/{sessionID}/instructions/entries/{key}": {
|
||||
"/api/experimental/session/{sessionID}/instructions/entries/{key}": {
|
||||
"put": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.instructions.entry.put",
|
||||
"operationId": "experimental.session.instructions.entry.put",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -3653,7 +3653,7 @@
|
||||
},
|
||||
"delete": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.instructions.entry.remove",
|
||||
"operationId": "experimental.session.instructions.entry.remove",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -4140,7 +4140,7 @@
|
||||
"/api/session/{sessionID}/message/{messageID}": {
|
||||
"get": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.message",
|
||||
"operationId": "session.message.get",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -4372,7 +4372,7 @@
|
||||
"/api/session/{sessionID}/message": {
|
||||
"get": {
|
||||
"tags": ["session"],
|
||||
"operationId": "message.list",
|
||||
"operationId": "session.message.list",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -17006,8 +17006,15 @@
|
||||
"type": "string",
|
||||
"pattern": "^ses"
|
||||
},
|
||||
"timeCreated": {
|
||||
"type": "number"
|
||||
"time": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["created"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -17020,7 +17027,7 @@
|
||||
"$ref": "#/components/schemas/Session.Inbox.Delivery"
|
||||
}
|
||||
},
|
||||
"required": ["id", "sessionID", "timeCreated", "type", "payload", "delivery"],
|
||||
"required": ["id", "sessionID", "time", "type", "payload", "delivery"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Session.Inbox.CompactionPayload": {
|
||||
@@ -17064,8 +17071,15 @@
|
||||
"type": "string",
|
||||
"pattern": "^ses"
|
||||
},
|
||||
"timeCreated": {
|
||||
"type": "number"
|
||||
"time": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["created"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -17078,7 +17092,7 @@
|
||||
"$ref": "#/components/schemas/Session.Inbox.MovePayload"
|
||||
}
|
||||
},
|
||||
"required": ["id", "sessionID", "timeCreated", "type", "delivery", "payload"],
|
||||
"required": ["id", "sessionID", "time", "type", "delivery", "payload"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Session.Inbox.MovePayload": {
|
||||
@@ -17108,8 +17122,15 @@
|
||||
"type": "string",
|
||||
"pattern": "^ses"
|
||||
},
|
||||
"timeCreated": {
|
||||
"type": "number"
|
||||
"time": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["created"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -17122,7 +17143,7 @@
|
||||
"$ref": "#/components/schemas/Session.Inbox.Delivery"
|
||||
}
|
||||
},
|
||||
"required": ["id", "sessionID", "timeCreated", "type", "payload", "delivery"],
|
||||
"required": ["id", "sessionID", "time", "type", "payload", "delivery"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Session.Inbox.SyntheticPayload": {
|
||||
@@ -17152,8 +17173,15 @@
|
||||
"type": "string",
|
||||
"pattern": "^ses"
|
||||
},
|
||||
"timeCreated": {
|
||||
"type": "number"
|
||||
"time": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["created"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -17166,7 +17194,7 @@
|
||||
"$ref": "#/components/schemas/Session.Inbox.Delivery"
|
||||
}
|
||||
},
|
||||
"required": ["id", "sessionID", "timeCreated", "type", "payload", "delivery"],
|
||||
"required": ["id", "sessionID", "time", "type", "payload", "delivery"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Session.Inbox.UserPayload": {
|
||||
|
||||
@@ -78,7 +78,7 @@ export const MessageGroup = HttpApiGroup.make("server.message")
|
||||
error: [InvalidCursorError, SessionNotFoundError, UnknownError],
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "message.list",
|
||||
identifier: "session.message.list",
|
||||
summary: "Get session messages",
|
||||
description:
|
||||
"Retrieve projected messages for a session, optionally filtered by type. Items keep the requested order across pages; use cursor.next or cursor.previous to move through the ordered timeline, passing the same type filter on each page.",
|
||||
|
||||
@@ -221,7 +221,7 @@ export const makeSessionGroup = <I extends HttpApiMiddleware.AnyId, S>(sessionLo
|
||||
),
|
||||
)
|
||||
.add(
|
||||
HttpApiEndpoint.post("session.import", "/api/session/import", {
|
||||
HttpApiEndpoint.post("session.import", "/api/experimental/session/import", {
|
||||
payload: Schema.Struct({
|
||||
...PublicSessionTransfer.fields,
|
||||
location: Location.PublicRef.pipe(Schema.optional),
|
||||
@@ -230,7 +230,7 @@ export const makeSessionGroup = <I extends HttpApiMiddleware.AnyId, S>(sessionLo
|
||||
error: [ConflictError, SessionNotFoundError],
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "session.import",
|
||||
identifier: "experimental.session.import",
|
||||
summary: "Import session",
|
||||
description:
|
||||
"Import a projected session transcript at the requested location. If parentID is supplied, the parent session must already exist; import parents before children.",
|
||||
@@ -238,14 +238,14 @@ export const makeSessionGroup = <I extends HttpApiMiddleware.AnyId, S>(sessionLo
|
||||
),
|
||||
)
|
||||
.add(
|
||||
HttpApiEndpoint.get("session.export", "/api/session/:sessionID/export", {
|
||||
HttpApiEndpoint.get("session.export", "/api/experimental/session/:sessionID/export", {
|
||||
params: { sessionID: Session.ID },
|
||||
query: Schema.Struct({ sanitize: BooleanFromString.pipe(Schema.optional) }),
|
||||
success: Schema.Struct({ data: PublicSessionTransfer }),
|
||||
error: [SessionNotFoundError, UnknownError],
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "session.export",
|
||||
identifier: "experimental.session.export",
|
||||
summary: "Export session",
|
||||
description: "Export a complete projected session transcript.",
|
||||
}),
|
||||
@@ -524,7 +524,7 @@ export const makeSessionGroup = <I extends HttpApiMiddleware.AnyId, S>(sessionLo
|
||||
),
|
||||
)
|
||||
.add(
|
||||
HttpApiEndpoint.post("session.revert.clear", "/api/session/:sessionID/revert/clear", {
|
||||
HttpApiEndpoint.delete("session.revert.clear", "/api/session/:sessionID/revert", {
|
||||
params: { sessionID: Session.ID },
|
||||
success: HttpApiSchema.NoContent,
|
||||
error: [SessionNotFoundError, SessionBusyError, UnknownError],
|
||||
@@ -635,31 +635,39 @@ export const makeSessionGroup = <I extends HttpApiMiddleware.AnyId, S>(sessionLo
|
||||
),
|
||||
)
|
||||
.add(
|
||||
HttpApiEndpoint.get("session.instructions.entry.list", "/api/session/:sessionID/instructions/entries", {
|
||||
params: { sessionID: Session.ID },
|
||||
success: Schema.Struct({ data: Schema.Array(InstructionEntry.Info) }),
|
||||
error: SessionNotFoundError,
|
||||
})
|
||||
HttpApiEndpoint.get(
|
||||
"session.instructions.entry.list",
|
||||
"/api/experimental/session/:sessionID/instructions/entries",
|
||||
{
|
||||
params: { sessionID: Session.ID },
|
||||
success: Schema.Struct({ data: Schema.Array(InstructionEntry.Info) }),
|
||||
error: SessionNotFoundError,
|
||||
},
|
||||
)
|
||||
.middleware(sessionLocationMiddleware)
|
||||
.annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "session.instructions.entry.list",
|
||||
identifier: "experimental.session.instructions.entry.list",
|
||||
summary: "List instruction entries",
|
||||
description: "List API-managed instruction entries attached to the session.",
|
||||
}),
|
||||
),
|
||||
)
|
||||
.add(
|
||||
HttpApiEndpoint.put("session.instructions.entry.put", "/api/session/:sessionID/instructions/entries/:key", {
|
||||
params: { sessionID: Session.ID, key: InstructionEntry.Key },
|
||||
payload: Schema.Struct({ value: Schema.Json }),
|
||||
success: HttpApiSchema.NoContent,
|
||||
error: [SessionNotFoundError, InstructionEntry.ValueTooLargeError],
|
||||
})
|
||||
HttpApiEndpoint.put(
|
||||
"session.instructions.entry.put",
|
||||
"/api/experimental/session/:sessionID/instructions/entries/:key",
|
||||
{
|
||||
params: { sessionID: Session.ID, key: InstructionEntry.Key },
|
||||
payload: Schema.Struct({ value: Schema.Json }),
|
||||
success: HttpApiSchema.NoContent,
|
||||
error: [SessionNotFoundError, InstructionEntry.ValueTooLargeError],
|
||||
},
|
||||
)
|
||||
.middleware(sessionLocationMiddleware)
|
||||
.annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "session.instructions.entry.put",
|
||||
identifier: "experimental.session.instructions.entry.put",
|
||||
summary: "Put instruction entry",
|
||||
description:
|
||||
"Attach or replace one durable instruction entry. Changes announce as updates at the next step boundary.",
|
||||
@@ -667,15 +675,19 @@ export const makeSessionGroup = <I extends HttpApiMiddleware.AnyId, S>(sessionLo
|
||||
),
|
||||
)
|
||||
.add(
|
||||
HttpApiEndpoint.delete("session.instructions.entry.remove", "/api/session/:sessionID/instructions/entries/:key", {
|
||||
params: { sessionID: Session.ID, key: InstructionEntry.Key },
|
||||
success: HttpApiSchema.NoContent,
|
||||
error: SessionNotFoundError,
|
||||
})
|
||||
HttpApiEndpoint.delete(
|
||||
"session.instructions.entry.remove",
|
||||
"/api/experimental/session/:sessionID/instructions/entries/:key",
|
||||
{
|
||||
params: { sessionID: Session.ID, key: InstructionEntry.Key },
|
||||
success: HttpApiSchema.NoContent,
|
||||
error: SessionNotFoundError,
|
||||
},
|
||||
)
|
||||
.middleware(sessionLocationMiddleware)
|
||||
.annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "session.instructions.entry.remove",
|
||||
identifier: "experimental.session.instructions.entry.remove",
|
||||
summary: "Remove instruction entry",
|
||||
description:
|
||||
"Remove one instruction entry; the removal is announced to the model at the next step boundary.",
|
||||
@@ -764,7 +776,7 @@ export const makeSessionGroup = <I extends HttpApiMiddleware.AnyId, S>(sessionLo
|
||||
error: [SessionNotFoundError, MessageNotFoundError],
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "session.message",
|
||||
identifier: "session.message.get",
|
||||
summary: "Get session message",
|
||||
description: "Retrieve one projected message owned by the Session.",
|
||||
}),
|
||||
|
||||
@@ -52,7 +52,7 @@ export type Item = typeof Item.Type
|
||||
const Enqueued = {
|
||||
id: SessionMessage.ID,
|
||||
sessionID: SessionID,
|
||||
timeCreated: DateTimeUtcFromMillis,
|
||||
time: Schema.Struct({ created: DateTimeUtcFromMillis }),
|
||||
}
|
||||
|
||||
export interface User extends Schema.Schema.Type<typeof User> {}
|
||||
|
||||
@@ -98,7 +98,7 @@ describe("contract hygiene", () => {
|
||||
admittedSeq: 3,
|
||||
id: "msg_pending",
|
||||
sessionID: "ses_pending",
|
||||
timeCreated: 1,
|
||||
time: { created: 1 },
|
||||
type: "user",
|
||||
payload: { text: "hello" },
|
||||
delivery: "steer",
|
||||
@@ -107,7 +107,7 @@ describe("contract hygiene", () => {
|
||||
).toEqual({
|
||||
id: "msg_pending",
|
||||
sessionID: "ses_pending",
|
||||
timeCreated: 1,
|
||||
time: { created: 1 },
|
||||
type: "user",
|
||||
payload: { text: "hello" },
|
||||
delivery: "steer",
|
||||
@@ -213,7 +213,7 @@ describe("contract hygiene", () => {
|
||||
|
||||
test("all session inbox item types accept both delivery modes", () => {
|
||||
const decode = Schema.decodeUnknownSync(SessionInbox.Info)
|
||||
const base = { id: "msg_inbox", sessionID: "ses_inbox", timeCreated: 1 }
|
||||
const base = { id: "msg_inbox", sessionID: "ses_inbox", time: { created: 1 } }
|
||||
const move = {
|
||||
location: { directory: "/project" },
|
||||
projectID: "global",
|
||||
|
||||
@@ -148,7 +148,7 @@ it.live(
|
||||
const modelMessage = Option.fromNullishOr(context.find((message) => message.type === "model-switched")).pipe(
|
||||
Option.getOrThrow,
|
||||
)
|
||||
const message = yield* opencode.sessions.message({ sessionID: id, messageID: modelMessage.id })
|
||||
const message = yield* opencode.sessions.message.get({ sessionID: id, messageID: modelMessage.id })
|
||||
yield* opencode.sessions.interrupt({ sessionID: id })
|
||||
const other = yield* opencode.sessions.create({ location: location(fixture) })
|
||||
const missingSessionID = fixture.sdk.Session.ID.create()
|
||||
@@ -156,14 +156,14 @@ it.live(
|
||||
[
|
||||
opencode.sessions.log({ sessionID: missingSessionID }).pipe(Stream.runHead, Effect.flip),
|
||||
opencode.sessions.interrupt({ sessionID: missingSessionID }).pipe(Effect.flip),
|
||||
opencode.sessions.message({ sessionID: missingSessionID, messageID: modelMessage.id }).pipe(Effect.flip),
|
||||
opencode.sessions.message.get({ sessionID: missingSessionID, messageID: modelMessage.id }).pipe(Effect.flip),
|
||||
opencode.sessions.instructions.entry.list({ sessionID: missingSessionID }).pipe(Effect.flip),
|
||||
opencode.sessions.inbox.list({ sessionID: missingSessionID }).pipe(Effect.flip),
|
||||
],
|
||||
{ concurrency: "unbounded" },
|
||||
)
|
||||
const missingMessage = yield* Effect.flip(
|
||||
opencode.sessions.message({
|
||||
opencode.sessions.message.get({
|
||||
sessionID: other.id,
|
||||
messageID: modelMessage.id,
|
||||
}),
|
||||
|
||||
@@ -34,7 +34,7 @@ it.live("preserves imported parentID through HTTP import, read, and parent filte
|
||||
const parent = Schema.decodeUnknownSync(SessionResponse)(yield* request("/api/session", { title: "Parent" }))
|
||||
const id = Session.ID.create()
|
||||
const imported = Schema.decodeUnknownSync(SessionResponse)(
|
||||
yield* request("/api/session/import", {
|
||||
yield* request("/api/experimental/session/import", {
|
||||
info: { ...parent.data, id, parentID: parent.data.id, title: "Imported child" },
|
||||
messages: [],
|
||||
}),
|
||||
@@ -58,7 +58,7 @@ it.live("preserves imported parentID through HTTP import, read, and parent filte
|
||||
const id = Session.ID.create()
|
||||
const parentID = parent === "self" ? id : Session.ID.create()
|
||||
const error = yield* request(
|
||||
"/api/session/import",
|
||||
"/api/experimental/session/import",
|
||||
{ info: { ...template.data, id, parentID }, messages: [] },
|
||||
404,
|
||||
)
|
||||
|
||||
@@ -469,7 +469,7 @@ export function createSubagentTracker(input: SubagentTrackerInput): SubagentTrac
|
||||
for (let offset = 0; offset < messageIDs.length; offset += FAMILY_DISCOVERY_CONCURRENCY) {
|
||||
const batch = messageIDs.slice(offset, offset + FAMILY_DISCOVERY_CONCURRENCY)
|
||||
const messages = await Promise.allSettled(
|
||||
batch.map((messageID) => sdk.session.message({ sessionID: child.sessionID, messageID }, { signal })),
|
||||
batch.map((messageID) => sdk.session.message.get({ sessionID: child.sessionID, messageID }, { signal })),
|
||||
)
|
||||
if (!blockerCurrent(child, epoch, signal)) return permissions
|
||||
if (
|
||||
|
||||
@@ -926,7 +926,7 @@ export async function createSessionTransport(input: StreamInput): Promise<Sessio
|
||||
]
|
||||
const messages = await Promise.allSettled(
|
||||
messageIDs.map((messageID) =>
|
||||
client.session.message({ sessionID: input.sessionID, messageID }, { signal: attempt.signal }),
|
||||
client.session.message.get({ sessionID: input.sessionID, messageID }, { signal: attempt.signal }),
|
||||
),
|
||||
)
|
||||
if (!current(attempt)) return permissions
|
||||
@@ -1034,7 +1034,7 @@ export async function createSessionTransport(input: StreamInput): Promise<Sessio
|
||||
mergePending({
|
||||
id: event.data.inboxID,
|
||||
sessionID: event.data.sessionID,
|
||||
timeCreated: event.created,
|
||||
time: { created: event.created },
|
||||
...event.data.item,
|
||||
})
|
||||
return
|
||||
|
||||
@@ -1669,7 +1669,7 @@ test("restores queued compaction from durable pending input", async () => {
|
||||
{
|
||||
id: "message-compaction-queued",
|
||||
sessionID,
|
||||
timeCreated: 1,
|
||||
time: { created: 1 },
|
||||
type: "compaction" as const,
|
||||
payload: {},
|
||||
delivery: "queue" as const,
|
||||
@@ -1677,7 +1677,7 @@ test("restores queued compaction from durable pending input", async () => {
|
||||
{
|
||||
id: "message-compaction-later",
|
||||
sessionID,
|
||||
timeCreated: 2,
|
||||
time: { created: 2 },
|
||||
type: "compaction" as const,
|
||||
payload: {},
|
||||
delivery: "queue" as const,
|
||||
@@ -2921,7 +2921,7 @@ test("renders admitted prompts immediately and tracks them until promoted", asyn
|
||||
{
|
||||
id: messageID,
|
||||
sessionID,
|
||||
timeCreated: 0,
|
||||
time: { created: 0 },
|
||||
type: "user",
|
||||
payload: { text: "hello" },
|
||||
delivery: "steer",
|
||||
@@ -3275,7 +3275,7 @@ test("admits prompts optimistically and reconciles with the durable echo", async
|
||||
{
|
||||
id: messageID,
|
||||
sessionID,
|
||||
timeCreated: 5,
|
||||
time: { created: 5 },
|
||||
type: "user",
|
||||
payload: { text: "hello", files: [echoFile] },
|
||||
delivery: "steer",
|
||||
@@ -3303,7 +3303,7 @@ test("hydrates durable pending prompts into the visible transcript", async () =>
|
||||
const item = {
|
||||
id: "msg_pending_1",
|
||||
sessionID,
|
||||
timeCreated: 5,
|
||||
time: { created: 5 },
|
||||
type: "user" as const,
|
||||
payload: { text: "waiting" },
|
||||
delivery: "steer" as const,
|
||||
@@ -3357,7 +3357,7 @@ test("keeps the row when the response lands before the echo", async () => {
|
||||
const admission = {
|
||||
id: messageID,
|
||||
sessionID,
|
||||
timeCreated: 1,
|
||||
time: { created: 1 },
|
||||
type: "user",
|
||||
payload: { text: "hello" },
|
||||
delivery: "steer",
|
||||
@@ -3464,7 +3464,7 @@ test("a retry under the same client-minted ID cannot duplicate rows", async () =
|
||||
const admission = {
|
||||
id: messageID,
|
||||
sessionID,
|
||||
timeCreated: 1,
|
||||
time: { created: 1 },
|
||||
type: "user",
|
||||
payload: { text: "hello" },
|
||||
delivery: "steer",
|
||||
|
||||
@@ -150,7 +150,7 @@ test.each(["first", "second"])(
|
||||
id: (await request.json()).id,
|
||||
sessionID,
|
||||
type: "compaction",
|
||||
timeCreated: 10,
|
||||
time: { created: 10 },
|
||||
payload: {},
|
||||
delivery: "steer",
|
||||
},
|
||||
@@ -169,7 +169,7 @@ test.each(["first", "second"])(
|
||||
id: body.id,
|
||||
sessionID,
|
||||
type: "user",
|
||||
timeCreated: 10,
|
||||
time: { created: 10 },
|
||||
payload: { text: body.text },
|
||||
delivery: "steer",
|
||||
},
|
||||
|
||||
@@ -91,7 +91,7 @@ function promptAdmission(input: Parameters<OpenCodeClient["session"]["prompt"]>[
|
||||
metadata: input.metadata,
|
||||
},
|
||||
delivery: input.delivery ?? ("steer" as const),
|
||||
timeCreated: 2,
|
||||
time: { created: 2 },
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ function sdk(input: {
|
||||
spyOn(client.session, "active").mockImplementation(() => ok(input.active?.() ?? {}))
|
||||
spyOn(client.session.inbox, "list").mockImplementation((request) => ok(input.pending?.[request.sessionID] ?? []))
|
||||
spyOn(client.session, "wait").mockImplementation(() => input.wait?.() ?? ok(undefined))
|
||||
spyOn(client.session, "message").mockImplementation((request) => {
|
||||
spyOn(client.session.message, "get").mockImplementation((request) => {
|
||||
const message = input.messages?.[request.sessionID]?.find((item) => item.id === request.messageID)
|
||||
return message ? (ok(message) as never) : Promise.reject(new Error(`message not found: ${request.messageID}`))
|
||||
})
|
||||
@@ -327,7 +327,7 @@ describe("V2 mini transport", () => {
|
||||
type: "user",
|
||||
payload: { text: "look [Image 1]", files },
|
||||
delivery: "steer",
|
||||
timeCreated: 1,
|
||||
time: { created: 1 },
|
||||
} satisfies SessionInboxInfo
|
||||
const prompt = spyOn(client.session, "prompt").mockImplementation(() => {
|
||||
requested.resolve()
|
||||
@@ -843,7 +843,7 @@ describe("V2 mini transport", () => {
|
||||
})
|
||||
const releaseSource = defer<void>()
|
||||
let sourceLookups = 0
|
||||
spyOn(client.session, "message").mockImplementation(async () => {
|
||||
spyOn(client.session.message, "get").mockImplementation(async () => {
|
||||
sourceLookups++
|
||||
if (sourceLookups === 1) throw new Error("source temporarily unavailable")
|
||||
await releaseSource.promise
|
||||
@@ -1079,7 +1079,7 @@ describe("V2 mini transport", () => {
|
||||
{
|
||||
id: "msg_queued",
|
||||
sessionID: "ses_1",
|
||||
timeCreated: 1,
|
||||
time: { created: 1 },
|
||||
type: "user",
|
||||
payload: {
|
||||
text: "follow up",
|
||||
@@ -1094,7 +1094,7 @@ describe("V2 mini transport", () => {
|
||||
{
|
||||
id: "msg_cancelled",
|
||||
sessionID: "ses_1",
|
||||
timeCreated: 2,
|
||||
time: { created: 2 },
|
||||
type: "user",
|
||||
payload: { text: "remove me", files: [image] },
|
||||
delivery,
|
||||
@@ -3449,7 +3449,7 @@ describe("V2 mini transport", () => {
|
||||
type: "user" as const,
|
||||
payload: { text: input.text },
|
||||
delivery: "steer" as const,
|
||||
timeCreated: 2,
|
||||
time: { created: 2 },
|
||||
})
|
||||
})
|
||||
|
||||
@@ -4049,7 +4049,7 @@ describe("V2 mini transport", () => {
|
||||
type: "user",
|
||||
payload: { text: "", files: [image] },
|
||||
delivery: "queue",
|
||||
timeCreated: 3,
|
||||
time: { created: 3 },
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
+53
-25
@@ -1064,10 +1064,10 @@
|
||||
"summary": "Get session statistics"
|
||||
}
|
||||
},
|
||||
"/api/session/import": {
|
||||
"/api/experimental/session/import": {
|
||||
"post": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.import",
|
||||
"operationId": "experimental.session.import",
|
||||
"parameters": [],
|
||||
"security": [],
|
||||
"responses": {
|
||||
@@ -1166,10 +1166,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/session/{sessionID}/export": {
|
||||
"/api/experimental/session/{sessionID}/export": {
|
||||
"get": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.export",
|
||||
"operationId": "experimental.session.export",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -2804,8 +2804,8 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/session/{sessionID}/revert/clear": {
|
||||
"post": {
|
||||
"/api/session/{sessionID}/revert": {
|
||||
"delete": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.revert.clear",
|
||||
"parameters": [
|
||||
@@ -3478,10 +3478,10 @@
|
||||
"summary": "Queue steered item"
|
||||
}
|
||||
},
|
||||
"/api/session/{sessionID}/instructions/entries": {
|
||||
"/api/experimental/session/{sessionID}/instructions/entries": {
|
||||
"get": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.instructions.entry.list",
|
||||
"operationId": "experimental.session.instructions.entry.list",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -3557,10 +3557,10 @@
|
||||
"summary": "List instruction entries"
|
||||
}
|
||||
},
|
||||
"/api/session/{sessionID}/instructions/entries/{key}": {
|
||||
"/api/experimental/session/{sessionID}/instructions/entries/{key}": {
|
||||
"put": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.instructions.entry.put",
|
||||
"operationId": "experimental.session.instructions.entry.put",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -3653,7 +3653,7 @@
|
||||
},
|
||||
"delete": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.instructions.entry.remove",
|
||||
"operationId": "experimental.session.instructions.entry.remove",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -4140,7 +4140,7 @@
|
||||
"/api/session/{sessionID}/message/{messageID}": {
|
||||
"get": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.message",
|
||||
"operationId": "session.message.get",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -4372,7 +4372,7 @@
|
||||
"/api/session/{sessionID}/message": {
|
||||
"get": {
|
||||
"tags": ["session"],
|
||||
"operationId": "message.list",
|
||||
"operationId": "session.message.list",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -17006,8 +17006,15 @@
|
||||
"type": "string",
|
||||
"pattern": "^ses"
|
||||
},
|
||||
"timeCreated": {
|
||||
"type": "number"
|
||||
"time": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["created"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -17020,7 +17027,7 @@
|
||||
"$ref": "#/components/schemas/Session.Inbox.Delivery"
|
||||
}
|
||||
},
|
||||
"required": ["id", "sessionID", "timeCreated", "type", "payload", "delivery"],
|
||||
"required": ["id", "sessionID", "time", "type", "payload", "delivery"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Session.Inbox.CompactionPayload": {
|
||||
@@ -17064,8 +17071,15 @@
|
||||
"type": "string",
|
||||
"pattern": "^ses"
|
||||
},
|
||||
"timeCreated": {
|
||||
"type": "number"
|
||||
"time": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["created"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -17078,7 +17092,7 @@
|
||||
"$ref": "#/components/schemas/Session.Inbox.MovePayload"
|
||||
}
|
||||
},
|
||||
"required": ["id", "sessionID", "timeCreated", "type", "delivery", "payload"],
|
||||
"required": ["id", "sessionID", "time", "type", "delivery", "payload"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Session.Inbox.MovePayload": {
|
||||
@@ -17108,8 +17122,15 @@
|
||||
"type": "string",
|
||||
"pattern": "^ses"
|
||||
},
|
||||
"timeCreated": {
|
||||
"type": "number"
|
||||
"time": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["created"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -17122,7 +17143,7 @@
|
||||
"$ref": "#/components/schemas/Session.Inbox.Delivery"
|
||||
}
|
||||
},
|
||||
"required": ["id", "sessionID", "timeCreated", "type", "payload", "delivery"],
|
||||
"required": ["id", "sessionID", "time", "type", "payload", "delivery"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Session.Inbox.SyntheticPayload": {
|
||||
@@ -17152,8 +17173,15 @@
|
||||
"type": "string",
|
||||
"pattern": "^ses"
|
||||
},
|
||||
"timeCreated": {
|
||||
"type": "number"
|
||||
"time": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["created"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -17166,7 +17194,7 @@
|
||||
"$ref": "#/components/schemas/Session.Inbox.Delivery"
|
||||
}
|
||||
},
|
||||
"required": ["id", "sessionID", "timeCreated", "type", "payload", "delivery"],
|
||||
"required": ["id", "sessionID", "time", "type", "payload", "delivery"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Session.Inbox.UserPayload": {
|
||||
|
||||
@@ -1064,10 +1064,10 @@
|
||||
"summary": "Get session statistics"
|
||||
}
|
||||
},
|
||||
"/api/session/import": {
|
||||
"/api/experimental/session/import": {
|
||||
"post": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.import",
|
||||
"operationId": "experimental.session.import",
|
||||
"parameters": [],
|
||||
"security": [],
|
||||
"responses": {
|
||||
@@ -1166,10 +1166,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/session/{sessionID}/export": {
|
||||
"/api/experimental/session/{sessionID}/export": {
|
||||
"get": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.export",
|
||||
"operationId": "experimental.session.export",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -2804,8 +2804,8 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/session/{sessionID}/revert/clear": {
|
||||
"post": {
|
||||
"/api/session/{sessionID}/revert": {
|
||||
"delete": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.revert.clear",
|
||||
"parameters": [
|
||||
@@ -3478,10 +3478,10 @@
|
||||
"summary": "Queue steered item"
|
||||
}
|
||||
},
|
||||
"/api/session/{sessionID}/instructions/entries": {
|
||||
"/api/experimental/session/{sessionID}/instructions/entries": {
|
||||
"get": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.instructions.entry.list",
|
||||
"operationId": "experimental.session.instructions.entry.list",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -3557,10 +3557,10 @@
|
||||
"summary": "List instruction entries"
|
||||
}
|
||||
},
|
||||
"/api/session/{sessionID}/instructions/entries/{key}": {
|
||||
"/api/experimental/session/{sessionID}/instructions/entries/{key}": {
|
||||
"put": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.instructions.entry.put",
|
||||
"operationId": "experimental.session.instructions.entry.put",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -3653,7 +3653,7 @@
|
||||
},
|
||||
"delete": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.instructions.entry.remove",
|
||||
"operationId": "experimental.session.instructions.entry.remove",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -4140,7 +4140,7 @@
|
||||
"/api/session/{sessionID}/message/{messageID}": {
|
||||
"get": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.message",
|
||||
"operationId": "session.message.get",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -4372,7 +4372,7 @@
|
||||
"/api/session/{sessionID}/message": {
|
||||
"get": {
|
||||
"tags": ["session"],
|
||||
"operationId": "message.list",
|
||||
"operationId": "session.message.list",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
@@ -17006,8 +17006,15 @@
|
||||
"type": "string",
|
||||
"pattern": "^ses"
|
||||
},
|
||||
"timeCreated": {
|
||||
"type": "number"
|
||||
"time": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["created"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -17020,7 +17027,7 @@
|
||||
"$ref": "#/components/schemas/Session.Inbox.Delivery"
|
||||
}
|
||||
},
|
||||
"required": ["id", "sessionID", "timeCreated", "type", "payload", "delivery"],
|
||||
"required": ["id", "sessionID", "time", "type", "payload", "delivery"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Session.Inbox.CompactionPayload": {
|
||||
@@ -17064,8 +17071,15 @@
|
||||
"type": "string",
|
||||
"pattern": "^ses"
|
||||
},
|
||||
"timeCreated": {
|
||||
"type": "number"
|
||||
"time": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["created"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -17078,7 +17092,7 @@
|
||||
"$ref": "#/components/schemas/Session.Inbox.MovePayload"
|
||||
}
|
||||
},
|
||||
"required": ["id", "sessionID", "timeCreated", "type", "delivery", "payload"],
|
||||
"required": ["id", "sessionID", "time", "type", "delivery", "payload"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Session.Inbox.MovePayload": {
|
||||
@@ -17108,8 +17122,15 @@
|
||||
"type": "string",
|
||||
"pattern": "^ses"
|
||||
},
|
||||
"timeCreated": {
|
||||
"type": "number"
|
||||
"time": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["created"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -17122,7 +17143,7 @@
|
||||
"$ref": "#/components/schemas/Session.Inbox.Delivery"
|
||||
}
|
||||
},
|
||||
"required": ["id", "sessionID", "timeCreated", "type", "payload", "delivery"],
|
||||
"required": ["id", "sessionID", "time", "type", "payload", "delivery"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Session.Inbox.SyntheticPayload": {
|
||||
@@ -17152,8 +17173,15 @@
|
||||
"type": "string",
|
||||
"pattern": "^ses"
|
||||
},
|
||||
"timeCreated": {
|
||||
"type": "number"
|
||||
"time": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["created"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
@@ -17166,7 +17194,7 @@
|
||||
"$ref": "#/components/schemas/Session.Inbox.Delivery"
|
||||
}
|
||||
},
|
||||
"required": ["id", "sessionID", "timeCreated", "type", "payload", "delivery"],
|
||||
"required": ["id", "sessionID", "time", "type", "payload", "delivery"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Session.Inbox.UserPayload": {
|
||||
|
||||
Reference in New Issue
Block a user