Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions packages/opencode/src/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1177,6 +1177,79 @@ export namespace Server {
return c.json(message)
},
)
.delete(
"/session/:sessionID/message/:messageID/part/:partID",
describeRoute({
description: "Delete a part from a message",
operationId: "part.delete",
responses: {
200: {
description: "Successfully deleted part",
content: {
"application/json": {
schema: resolver(z.boolean()),
},
},
},
...errors(400, 404),
},
}),
validator(
"param",
z.object({
sessionID: z.string().meta({ description: "Session ID" }),
messageID: z.string().meta({ description: "Message ID" }),
partID: z.string().meta({ description: "Part ID" }),
}),
),
async (c) => {
const params = c.req.valid("param")
await Session.removePart({
sessionID: params.sessionID,
messageID: params.messageID,
partID: params.partID,
})
return c.json(true)
},
)
.patch(
"/session/:sessionID/message/:messageID/part/:partID",
describeRoute({
description: "Update a part in a message",
operationId: "part.update",
responses: {
200: {
description: "Successfully updated part",
content: {
"application/json": {
schema: resolver(MessageV2.Part),
},
},
},
...errors(400, 404),
},
}),
validator(
"param",
z.object({
sessionID: z.string().meta({ description: "Session ID" }),
messageID: z.string().meta({ description: "Message ID" }),
partID: z.string().meta({ description: "Part ID" }),
}),
),
validator("json", MessageV2.Part),
async (c) => {
const params = c.req.valid("param")
const body = c.req.valid("json")
if (body.id !== params.partID || body.messageID !== params.messageID || body.sessionID !== params.sessionID) {
throw new Error(
`Part mismatch: body.id='${body.id}' vs partID='${params.partID}', body.messageID='${body.messageID}' vs messageID='${params.messageID}', body.sessionID='${body.sessionID}' vs sessionID='${params.sessionID}'`,
)
}
const part = await Session.updatePart(body)
return c.json(part)
},
)
.post(
"/session/:sessionID/message",
describeRoute({
Expand Down
17 changes: 17 additions & 0 deletions packages/opencode/src/session/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,23 @@ export namespace Session {
},
)

export const removePart = fn(
z.object({
sessionID: Identifier.schema("session"),
messageID: Identifier.schema("message"),
partID: Identifier.schema("part"),
}),
async (input) => {
await Storage.remove(["part", input.messageID, input.partID])
Bus.publish(MessageV2.Event.PartRemoved, {
sessionID: input.sessionID,
messageID: input.messageID,
partID: input.partID,
})
return input.partID
},
)

const UpdatePartInput = z.union([
MessageV2.Part,
z.object({
Expand Down
80 changes: 80 additions & 0 deletions packages/sdk/js/src/v2/gen/sdk.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ import type {
McpLocalConfig,
McpRemoteConfig,
McpStatusResponses,
Part as Part2,
PartDeleteErrors,
PartDeleteResponses,
PartUpdateErrors,
PartUpdateResponses,
PathGetResponses,
PermissionRespondErrors,
PermissionRespondResponses,
Expand Down Expand Up @@ -1486,6 +1491,79 @@ export class Session extends HeyApiClient {
}
}

export class Part extends HeyApiClient {
/**
* Delete a part from a message
*/
public delete<ThrowOnError extends boolean = false>(
parameters: {
sessionID: string
messageID: string
partID: string
directory?: string
},
options?: Options<never, ThrowOnError>,
) {
const params = buildClientParams(
[parameters],
[
{
args: [
{ in: "path", key: "sessionID" },
{ in: "path", key: "messageID" },
{ in: "path", key: "partID" },
{ in: "query", key: "directory" },
],
},
],
)
return (options?.client ?? this.client).delete<PartDeleteResponses, PartDeleteErrors, ThrowOnError>({
url: "/session/{sessionID}/message/{messageID}/part/{partID}",
...options,
...params,
})
}

/**
* Update a part in a message
*/
public update<ThrowOnError extends boolean = false>(
parameters: {
sessionID: string
messageID: string
partID: string
directory?: string
part?: Part2
},
options?: Options<never, ThrowOnError>,
) {
const params = buildClientParams(
[parameters],
[
{
args: [
{ in: "path", key: "sessionID" },
{ in: "path", key: "messageID" },
{ in: "path", key: "partID" },
{ in: "query", key: "directory" },
{ key: "part", map: "body" },
],
},
],
)
return (options?.client ?? this.client).patch<PartUpdateResponses, PartUpdateErrors, ThrowOnError>({
url: "/session/{sessionID}/message/{messageID}/part/{partID}",
...options,
...params,
headers: {
"Content-Type": "application/json",
...options?.headers,
...params.headers,
},
})
}
}

export class Permission extends HeyApiClient {
/**
* Respond to permission
Expand Down Expand Up @@ -2588,6 +2666,8 @@ export class OpencodeClient extends HeyApiClient {

session = new Session({ client: this.client })

part = new Part({ client: this.client })

permission = new Permission({ client: this.client })

command = new Command({ client: this.client })
Expand Down
88 changes: 88 additions & 0 deletions packages/sdk/js/src/v2/gen/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2901,6 +2901,94 @@ export type SessionMessageResponses = {

export type SessionMessageResponse = SessionMessageResponses[keyof SessionMessageResponses]

export type PartDeleteData = {
body?: never
path: {
/**
* Session ID
*/
sessionID: string
/**
* Message ID
*/
messageID: string
/**
* Part ID
*/
partID: string
}
query?: {
directory?: string
}
url: "/session/{sessionID}/message/{messageID}/part/{partID}"
}

export type PartDeleteErrors = {
/**
* Bad request
*/
400: BadRequestError
/**
* Not found
*/
404: NotFoundError
}

export type PartDeleteError = PartDeleteErrors[keyof PartDeleteErrors]

export type PartDeleteResponses = {
/**
* Successfully deleted part
*/
200: boolean
}

export type PartDeleteResponse = PartDeleteResponses[keyof PartDeleteResponses]

export type PartUpdateData = {
body?: Part
path: {
/**
* Session ID
*/
sessionID: string
/**
* Message ID
*/
messageID: string
/**
* Part ID
*/
partID: string
}
query?: {
directory?: string
}
url: "/session/{sessionID}/message/{messageID}/part/{partID}"
}

export type PartUpdateErrors = {
/**
* Bad request
*/
400: BadRequestError
/**
* Not found
*/
404: NotFoundError
}

export type PartUpdateError = PartUpdateErrors[keyof PartUpdateErrors]

export type PartUpdateResponses = {
/**
* Successfully updated part
*/
200: Part
}

export type PartUpdateResponse = PartUpdateResponses[keyof PartUpdateResponses]

export type SessionPromptAsyncData = {
body?: {
messageID?: string
Expand Down
Loading