refactor(core): simplify session pagination
This commit is contained in:
@@ -25,7 +25,6 @@ import {
|
||||
} from "../../src/server/routes/instance/httpapi/groups/session"
|
||||
import { PtyPaths } from "../../src/server/routes/instance/httpapi/groups/pty"
|
||||
import { MessagesQuery as V2MessagesQuery } from "../../src/server/routes/instance/httpapi/groups/v2/message"
|
||||
import { SessionsQuery as V2SessionsQuery } from "../../src/server/routes/instance/httpapi/groups/v2/session"
|
||||
import { QueryBoolean, QueryBooleanOpenApi } from "../../src/server/routes/instance/httpapi/groups/query"
|
||||
import { resetDatabase } from "../fixture/db"
|
||||
import { disposeAllInstances, tmpdir } from "../fixture/fixture"
|
||||
@@ -55,7 +54,6 @@ const openApiDriftRoutes = [
|
||||
{ method: "get", path: ExperimentalPaths.session, query: ExperimentalSessionListQuery },
|
||||
{ method: "get", path: ExperimentalPaths.tool, query: ToolListQuery },
|
||||
{ method: "get", path: InstancePaths.vcsDiff, query: VcsDiffQuery },
|
||||
{ method: "get", path: "/api/session", query: V2SessionsQuery },
|
||||
{ method: "get", path: "/api/session/:sessionID/message", query: V2MessagesQuery },
|
||||
] satisfies Array<{ method: Method; path: string; query: QuerySchema }>
|
||||
|
||||
@@ -72,8 +70,6 @@ const numericSdkQueryParams = [
|
||||
name: "limit",
|
||||
schema: { type: "integer", minimum: 0, maximum: Number.MAX_SAFE_INTEGER },
|
||||
},
|
||||
{ method: "get", path: "/api/session", name: "limit", schema: { type: "number" } },
|
||||
{ method: "get", path: "/api/session", name: "start", schema: { type: "number" } },
|
||||
{ method: "get", path: "/api/session/:sessionID/message", name: "limit", schema: { type: "number" } },
|
||||
] satisfies Array<{ method: Method; path: string; name: string; schema: OpenApiSchema }>
|
||||
|
||||
@@ -81,7 +77,6 @@ const booleanSdkQueryParams = [
|
||||
{ method: "get", path: ExperimentalPaths.session, name: "roots" },
|
||||
{ method: "get", path: ExperimentalPaths.session, name: "archived" },
|
||||
{ method: "get", path: SessionPaths.list, name: "roots" },
|
||||
{ method: "get", path: "/api/session", name: "roots" },
|
||||
] satisfies Array<{ method: Method; path: string; name: string }>
|
||||
|
||||
const queryParamPatterns = [
|
||||
@@ -239,7 +234,7 @@ describe("httpapi query schema drift", () => {
|
||||
],
|
||||
},
|
||||
path: "/fixture",
|
||||
query: { fields: {} },
|
||||
query: Schema.Struct({}),
|
||||
}),
|
||||
).toThrow("advertises query params not accepted by runtime schema")
|
||||
}),
|
||||
|
||||
@@ -444,17 +444,27 @@ describe("session HttpApi", () => {
|
||||
yield* insertLegacyAssistantMessage(session.id, 1)
|
||||
yield* insertLegacyAssistantMessage(session.id, 2)
|
||||
|
||||
const sessionPage = yield* request(`/api/session?limit=1`, { headers })
|
||||
const sessionPage = yield* request(
|
||||
`/api/session?${new URLSearchParams({
|
||||
limit: "1",
|
||||
order: "asc",
|
||||
directory: test.directory,
|
||||
search: "v2",
|
||||
})}`,
|
||||
{ headers },
|
||||
)
|
||||
const sessionCursor = (yield* json<{ cursor: { next?: string } }>(sessionPage)).cursor.next
|
||||
expect(sessionCursor).toBeTruthy()
|
||||
|
||||
const cursorWithFilter = yield* request(`/api/session?cursor=${sessionCursor}&search=v2`, { headers })
|
||||
expect(cursorWithFilter.status).toBe(400)
|
||||
expect(yield* responseJson(cursorWithFilter)).toMatchObject({
|
||||
_tag: "InvalidCursorError",
|
||||
message: "Cursor cannot be combined with order or filters",
|
||||
expect(JSON.parse(Buffer.from(sessionCursor!, "base64url").toString("utf8"))).toMatchObject({
|
||||
order: "asc",
|
||||
directory: test.directory,
|
||||
search: "v2",
|
||||
anchor: { id: session.id, direction: "next" },
|
||||
})
|
||||
|
||||
const sessionNextPage = yield* request(`/api/session?cursor=${sessionCursor}`, { headers })
|
||||
expect(sessionNextPage.status).toBe(200)
|
||||
|
||||
const invalidSessionCursor = yield* request(`/api/session?cursor=invalid`, { headers })
|
||||
expect(invalidSessionCursor.status).toBe(400)
|
||||
expect(yield* responseJson(invalidSessionCursor)).toMatchObject({
|
||||
@@ -462,21 +472,11 @@ describe("session HttpApi", () => {
|
||||
message: "Invalid cursor",
|
||||
})
|
||||
|
||||
const mismatchedRouting = yield* request(`/api/session?cursor=${sessionCursor}&directory=/elsewhere`, {
|
||||
headers,
|
||||
})
|
||||
expect(mismatchedRouting.status).toBe(400)
|
||||
expect(yield* responseJson(mismatchedRouting)).toMatchObject({
|
||||
_tag: "InvalidCursorError",
|
||||
message: "Cursor does not match requested directory or workspace",
|
||||
})
|
||||
|
||||
const invalidWorkspace = yield* request(`/api/session?workspace=bad`, { headers })
|
||||
expect(invalidWorkspace.status).toBe(400)
|
||||
expect(yield* responseJson(invalidWorkspace)).toMatchObject({
|
||||
_tag: "InvalidRequestError",
|
||||
message: "Invalid workspace query parameter",
|
||||
field: "workspace",
|
||||
kind: "Query",
|
||||
})
|
||||
|
||||
const messagePage = yield* request(`/api/session/${session.id}/message?limit=1`, { headers })
|
||||
|
||||
Reference in New Issue
Block a user