feat(core): add message delete endpoint (#14417)

This commit is contained in:
Shantur Rathore
2026-02-25 14:25:26 +00:00
committed by GitHub
parent 088a81c116
commit 79b5ce58e9
4 changed files with 120 additions and 2 deletions

View File

@@ -618,6 +618,42 @@ export const SessionRoutes = lazy(() =>
return c.json(message)
},
)
.delete(
"/:sessionID/message/:messageID",
describeRoute({
summary: "Delete message",
description:
"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.",
operationId: "session.deleteMessage",
responses: {
200: {
description: "Successfully deleted message",
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" }),
}),
),
async (c) => {
const params = c.req.valid("param")
SessionPrompt.assertNotBusy(params.sessionID)
await Session.removeMessage({
sessionID: params.sessionID,
messageID: params.messageID,
})
return c.json(true)
},
)
.delete(
"/:sessionID/message/:messageID/part/:partID",
describeRoute({

View File

@@ -697,7 +697,9 @@ export namespace Session {
async (input) => {
// CASCADE delete handles parts automatically
Database.use((db) => {
db.delete(MessageTable).where(eq(MessageTable.id, input.messageID)).run()
db.delete(MessageTable)
.where(and(eq(MessageTable.id, input.messageID), eq(MessageTable.session_id, input.sessionID)))
.run()
Database.effect(() =>
Bus.publish(MessageV2.Event.Removed, {
sessionID: input.sessionID,
@@ -717,7 +719,9 @@ export namespace Session {
}),
async (input) => {
Database.use((db) => {
db.delete(PartTable).where(eq(PartTable.id, input.partID)).run()
db.delete(PartTable)
.where(and(eq(PartTable.id, input.partID), eq(PartTable.session_id, input.sessionID)))
.run()
Database.effect(() =>
Bus.publish(MessageV2.Event.PartRemoved, {
sessionID: input.sessionID,

View File

@@ -107,6 +107,8 @@ import type {
SessionCreateErrors,
SessionCreateResponses,
SessionDeleteErrors,
SessionDeleteMessageErrors,
SessionDeleteMessageResponses,
SessionDeleteResponses,
SessionDiffResponses,
SessionForkResponses,
@@ -1561,6 +1563,42 @@ export class Session2 extends HeyApiClient {
})
}
/**
* Delete message
*
* 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.
*/
public deleteMessage<ThrowOnError extends boolean = false>(
parameters: {
sessionID: string
messageID: string
directory?: string
},
options?: Options<never, ThrowOnError>,
) {
const params = buildClientParams(
[parameters],
[
{
args: [
{ in: "path", key: "sessionID" },
{ in: "path", key: "messageID" },
{ in: "query", key: "directory" },
],
},
],
)
return (options?.client ?? this.client).delete<
SessionDeleteMessageResponses,
SessionDeleteMessageErrors,
ThrowOnError
>({
url: "/session/{sessionID}/message/{messageID}",
...options,
...params,
})
}
/**
* Get message
*

View File

@@ -3564,6 +3564,46 @@ export type SessionPromptResponses = {
export type SessionPromptResponse = SessionPromptResponses[keyof SessionPromptResponses]
export type SessionDeleteMessageData = {
body?: never
path: {
/**
* Session ID
*/
sessionID: string
/**
* Message ID
*/
messageID: string
}
query?: {
directory?: string
}
url: "/session/{sessionID}/message/{messageID}"
}
export type SessionDeleteMessageErrors = {
/**
* Bad request
*/
400: BadRequestError
/**
* Not found
*/
404: NotFoundError
}
export type SessionDeleteMessageError = SessionDeleteMessageErrors[keyof SessionDeleteMessageErrors]
export type SessionDeleteMessageResponses = {
/**
* Successfully deleted message
*/
200: boolean
}
export type SessionDeleteMessageResponse = SessionDeleteMessageResponses[keyof SessionDeleteMessageResponses]
export type SessionMessageData = {
body?: never
path: {