Skip to content

Commit 3207b65

Browse files
committed
feat(session): add messageCount endpoint for efficient message counting
1 parent d848c9b commit 3207b65

4 files changed

Lines changed: 117 additions & 1 deletion

File tree

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,36 @@ export const SessionRoutes = lazy(() =>
579579
return c.json(messages)
580580
},
581581
)
582+
.get(
583+
"/:sessionID/message/count",
584+
describeRoute({
585+
summary: "Get message count",
586+
description: "Get the total number of messages in a session.",
587+
operationId: "session.messageCount",
588+
responses: {
589+
200: {
590+
description: "Message count",
591+
content: {
592+
"application/json": {
593+
schema: resolver(z.object({ count: z.number() })),
594+
},
595+
},
596+
},
597+
...errors(400, 404),
598+
},
599+
}),
600+
validator(
601+
"param",
602+
z.object({
603+
sessionID: z.string().meta({ description: "Session ID" }),
604+
}),
605+
),
606+
async (c) => {
607+
const sessionID = c.req.valid("param").sessionID
608+
const count = await Session.messageCount({ sessionID })
609+
return c.json({ count })
610+
},
611+
)
582612
.get(
583613
"/:sessionID/message/:messageID",
584614
describeRoute({

packages/opencode/src/session/index.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { Flag } from "../flag/flag"
1010
import { Identifier } from "../id/id"
1111
import { Installation } from "../installation"
1212

13-
import { Database, NotFoundError, eq, and, or, gte, isNull, desc, like, inArray, lt } from "../storage/db"
13+
import { Database, NotFoundError, eq, and, or, gte, isNull, desc, like, inArray, lt, sql } from "../storage/db"
1414
import type { SQL } from "../storage/db"
1515
import { SessionTable, MessageTable, PartTable } from "./session.sql"
1616
import { ProjectTable } from "../project/project.sql"
@@ -525,6 +525,22 @@ export namespace Session {
525525
},
526526
)
527527

528+
export const messageCount = fn(
529+
z.object({
530+
sessionID: Identifier.schema("session"),
531+
}),
532+
async (input) => {
533+
const result = Database.use((db) =>
534+
db
535+
.select({ count: sql<number>`COUNT(*)` })
536+
.from(MessageTable)
537+
.where(eq(MessageTable.session_id, input.sessionID))
538+
.get(),
539+
)
540+
return result?.count ?? 0
541+
},
542+
)
543+
528544
export function* list(input?: {
529545
directory?: string
530546
roots?: boolean

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ import type {
115115
SessionInitErrors,
116116
SessionInitResponses,
117117
SessionListResponses,
118+
SessionMessageCountErrors,
119+
SessionMessageCountResponses,
118120
SessionMessageErrors,
119121
SessionMessageResponses,
120122
SessionMessagesErrors,
@@ -1561,6 +1563,36 @@ export class Session2 extends HeyApiClient {
15611563
})
15621564
}
15631565

1566+
/**
1567+
* Get message count
1568+
*
1569+
* Get the total number of messages in a session.
1570+
*/
1571+
public messageCount<ThrowOnError extends boolean = false>(
1572+
parameters: {
1573+
sessionID: string
1574+
directory?: string
1575+
},
1576+
options?: Options<never, ThrowOnError>,
1577+
) {
1578+
const params = buildClientParams(
1579+
[parameters],
1580+
[
1581+
{
1582+
args: [
1583+
{ in: "path", key: "sessionID" },
1584+
{ in: "query", key: "directory" },
1585+
],
1586+
},
1587+
],
1588+
)
1589+
return (options?.client ?? this.client).get<SessionMessageCountResponses, SessionMessageCountErrors, ThrowOnError>({
1590+
url: "/session/{sessionID}/message/count",
1591+
...options,
1592+
...params,
1593+
})
1594+
}
1595+
15641596
/**
15651597
* Get message
15661598
*

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

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

35653565
export type SessionPromptResponse = SessionPromptResponses[keyof SessionPromptResponses]
35663566

3567+
export type SessionMessageCountData = {
3568+
body?: never
3569+
path: {
3570+
/**
3571+
* Session ID
3572+
*/
3573+
sessionID: string
3574+
}
3575+
query?: {
3576+
directory?: string
3577+
}
3578+
url: "/session/{sessionID}/message/count"
3579+
}
3580+
3581+
export type SessionMessageCountErrors = {
3582+
/**
3583+
* Bad request
3584+
*/
3585+
400: BadRequestError
3586+
/**
3587+
* Not found
3588+
*/
3589+
404: NotFoundError
3590+
}
3591+
3592+
export type SessionMessageCountError = SessionMessageCountErrors[keyof SessionMessageCountErrors]
3593+
3594+
export type SessionMessageCountResponses = {
3595+
/**
3596+
* Message count
3597+
*/
3598+
200: {
3599+
count: number
3600+
}
3601+
}
3602+
3603+
export type SessionMessageCountResponse = SessionMessageCountResponses[keyof SessionMessageCountResponses]
3604+
35673605
export type SessionMessageData = {
35683606
body?: never
35693607
path: {

0 commit comments

Comments
 (0)