Skip to content

Commit 79b5ce5

Browse files
authored
feat(core): add message delete endpoint (#14417)
1 parent 088a81c commit 79b5ce5

4 files changed

Lines changed: 120 additions & 2 deletions

File tree

packages/opencode/src/server/routes/session.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,42 @@ export const SessionRoutes = lazy(() =>
618618
return c.json(message)
619619
},
620620
)
621+
.delete(
622+
"/:sessionID/message/:messageID",
623+
describeRoute({
624+
summary: "Delete message",
625+
description:
626+
"Permanently delete a specific message (and all of its parts) from a session. This does not revert any file changes that may have been made while processing the message.",
627+
operationId: "session.deleteMessage",
628+
responses: {
629+
200: {
630+
description: "Successfully deleted message",
631+
content: {
632+
"application/json": {
633+
schema: resolver(z.boolean()),
634+
},
635+
},
636+
},
637+
...errors(400, 404),
638+
},
639+
}),
640+
validator(
641+
"param",
642+
z.object({
643+
sessionID: z.string().meta({ description: "Session ID" }),
644+
messageID: z.string().meta({ description: "Message ID" }),
645+
}),
646+
),
647+
async (c) => {
648+
const params = c.req.valid("param")
649+
SessionPrompt.assertNotBusy(params.sessionID)
650+
await Session.removeMessage({
651+
sessionID: params.sessionID,
652+
messageID: params.messageID,
653+
})
654+
return c.json(true)
655+
},
656+
)
621657
.delete(
622658
"/:sessionID/message/:messageID/part/:partID",
623659
describeRoute({

packages/opencode/src/session/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,9 @@ export namespace Session {
697697
async (input) => {
698698
// CASCADE delete handles parts automatically
699699
Database.use((db) => {
700-
db.delete(MessageTable).where(eq(MessageTable.id, input.messageID)).run()
700+
db.delete(MessageTable)
701+
.where(and(eq(MessageTable.id, input.messageID), eq(MessageTable.session_id, input.sessionID)))
702+
.run()
701703
Database.effect(() =>
702704
Bus.publish(MessageV2.Event.Removed, {
703705
sessionID: input.sessionID,
@@ -717,7 +719,9 @@ export namespace Session {
717719
}),
718720
async (input) => {
719721
Database.use((db) => {
720-
db.delete(PartTable).where(eq(PartTable.id, input.partID)).run()
722+
db.delete(PartTable)
723+
.where(and(eq(PartTable.id, input.partID), eq(PartTable.session_id, input.sessionID)))
724+
.run()
721725
Database.effect(() =>
722726
Bus.publish(MessageV2.Event.PartRemoved, {
723727
sessionID: input.sessionID,

packages/sdk/js/src/v2/gen/sdk.gen.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ import type {
107107
SessionCreateErrors,
108108
SessionCreateResponses,
109109
SessionDeleteErrors,
110+
SessionDeleteMessageErrors,
111+
SessionDeleteMessageResponses,
110112
SessionDeleteResponses,
111113
SessionDiffResponses,
112114
SessionForkResponses,
@@ -1561,6 +1563,42 @@ export class Session2 extends HeyApiClient {
15611563
})
15621564
}
15631565

1566+
/**
1567+
* Delete message
1568+
*
1569+
* Permanently delete a specific message (and all of its parts) from a session. This does not revert any file changes that may have been made while processing the message.
1570+
*/
1571+
public deleteMessage<ThrowOnError extends boolean = false>(
1572+
parameters: {
1573+
sessionID: string
1574+
messageID: string
1575+
directory?: string
1576+
},
1577+
options?: Options<never, ThrowOnError>,
1578+
) {
1579+
const params = buildClientParams(
1580+
[parameters],
1581+
[
1582+
{
1583+
args: [
1584+
{ in: "path", key: "sessionID" },
1585+
{ in: "path", key: "messageID" },
1586+
{ in: "query", key: "directory" },
1587+
],
1588+
},
1589+
],
1590+
)
1591+
return (options?.client ?? this.client).delete<
1592+
SessionDeleteMessageResponses,
1593+
SessionDeleteMessageErrors,
1594+
ThrowOnError
1595+
>({
1596+
url: "/session/{sessionID}/message/{messageID}",
1597+
...options,
1598+
...params,
1599+
})
1600+
}
1601+
15641602
/**
15651603
* Get message
15661604
*

packages/sdk/js/src/v2/gen/types.gen.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3564,6 +3564,46 @@ export type SessionPromptResponses = {
35643564

35653565
export type SessionPromptResponse = SessionPromptResponses[keyof SessionPromptResponses]
35663566

3567+
export type SessionDeleteMessageData = {
3568+
body?: never
3569+
path: {
3570+
/**
3571+
* Session ID
3572+
*/
3573+
sessionID: string
3574+
/**
3575+
* Message ID
3576+
*/
3577+
messageID: string
3578+
}
3579+
query?: {
3580+
directory?: string
3581+
}
3582+
url: "/session/{sessionID}/message/{messageID}"
3583+
}
3584+
3585+
export type SessionDeleteMessageErrors = {
3586+
/**
3587+
* Bad request
3588+
*/
3589+
400: BadRequestError
3590+
/**
3591+
* Not found
3592+
*/
3593+
404: NotFoundError
3594+
}
3595+
3596+
export type SessionDeleteMessageError = SessionDeleteMessageErrors[keyof SessionDeleteMessageErrors]
3597+
3598+
export type SessionDeleteMessageResponses = {
3599+
/**
3600+
* Successfully deleted message
3601+
*/
3602+
200: boolean
3603+
}
3604+
3605+
export type SessionDeleteMessageResponse = SessionDeleteMessageResponses[keyof SessionDeleteMessageResponses]
3606+
35673607
export type SessionMessageData = {
35683608
body?: never
35693609
path: {

0 commit comments

Comments
 (0)