Skip to content

Commit 0ea28dd

Browse files
committed
fix: speed up exact session lookups
1 parent 81e1dea commit 0ea28dd

15 files changed

Lines changed: 154 additions & 30 deletions

docs/cli/mcp.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ The current bridge exposes these MCP tools:
147147

148148
</Accordion>
149149
<Accordion title="conversation_get">
150-
Returns one conversation by `session_key`.
150+
Returns one conversation by `session_key` using a direct Gateway session lookup.
151151
</Accordion>
152152
<Accordion title="messages_read">
153153
Reads recent transcript messages for one session-backed conversation.

docs/gateway/protocol.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ enumeration of `src/gateway/server-methods/*.ts`.
399399
- `sessions.subscribe` and `sessions.unsubscribe` toggle session change event subscriptions for the current WS client.
400400
- `sessions.messages.subscribe` and `sessions.messages.unsubscribe` toggle transcript/message event subscriptions for one session.
401401
- `sessions.preview` returns bounded transcript previews for specific session keys.
402+
- `sessions.describe` returns one Gateway session row for an exact session key.
402403
- `sessions.resolve` resolves or canonicalizes a session target.
403404
- `sessions.create` creates a new session entry.
404405
- `sessions.send` sends a message into an existing session.

src/gateway/method-scopes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ const METHOD_SCOPE_GROUPS: Record<OperatorScope, readonly string[]> = {
9797
"sessions.list",
9898
"sessions.get",
9999
"sessions.preview",
100+
"sessions.describe",
100101
"sessions.resolve",
101102
"sessions.compaction.list",
102103
"sessions.compaction.get",

src/gateway/protocol/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,8 @@ import {
270270
SessionsCreateParamsSchema,
271271
type SessionsDeleteParams,
272272
SessionsDeleteParamsSchema,
273+
type SessionsDescribeParams,
274+
SessionsDescribeParamsSchema,
273275
type SessionsListParams,
274276
SessionsListParamsSchema,
275277
type SessionsMessagesSubscribeParams,
@@ -452,6 +454,9 @@ export const validateSessionsCleanupParams = ajv.compile<SessionsCleanupParams>(
452454
export const validateSessionsPreviewParams = ajv.compile<SessionsPreviewParams>(
453455
SessionsPreviewParamsSchema,
454456
);
457+
export const validateSessionsDescribeParams = ajv.compile<SessionsDescribeParams>(
458+
SessionsDescribeParamsSchema,
459+
);
455460
export const validateSessionsResolveParams = ajv.compile<SessionsResolveParams>(
456461
SessionsResolveParamsSchema,
457462
);
@@ -700,6 +705,7 @@ export {
700705
SessionsListParamsSchema,
701706
SessionsCleanupParamsSchema,
702707
SessionsPreviewParamsSchema,
708+
SessionsDescribeParamsSchema,
703709
SessionsResolveParamsSchema,
704710
SessionsCompactionListParamsSchema,
705711
SessionsCompactionGetParamsSchema,
@@ -926,6 +932,7 @@ export type {
926932
SessionsListParams,
927933
SessionsCleanupParams,
928934
SessionsPreviewParams,
935+
SessionsDescribeParams,
929936
SessionsResolveParams,
930937
SessionsPatchParams,
931938
SessionsPatchResult,

src/gateway/protocol/schema/protocol-schemas.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ import {
204204
SessionsCleanupParamsSchema,
205205
SessionsCreateParamsSchema,
206206
SessionsDeleteParamsSchema,
207+
SessionsDescribeParamsSchema,
207208
SessionsListParamsSchema,
208209
SessionsMessagesSubscribeParamsSchema,
209210
SessionsMessagesUnsubscribeParamsSchema,
@@ -278,6 +279,7 @@ export const ProtocolSchemas = {
278279
SessionsListParams: SessionsListParamsSchema,
279280
SessionsCleanupParams: SessionsCleanupParamsSchema,
280281
SessionsPreviewParams: SessionsPreviewParamsSchema,
282+
SessionsDescribeParams: SessionsDescribeParamsSchema,
281283
SessionsResolveParams: SessionsResolveParamsSchema,
282284
SessionCompactionCheckpoint: SessionCompactionCheckpointSchema,
283285
SessionsCompactionListParams: SessionsCompactionListParamsSchema,

src/gateway/protocol/schema/sessions.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,15 @@ export const SessionsPreviewParamsSchema = Type.Object(
8080
{ additionalProperties: false },
8181
);
8282

83+
export const SessionsDescribeParamsSchema = Type.Object(
84+
{
85+
key: NonEmptyString,
86+
includeDerivedTitles: Type.Optional(Type.Boolean()),
87+
includeLastMessage: Type.Optional(Type.Boolean()),
88+
},
89+
{ additionalProperties: false },
90+
);
91+
8392
export const SessionsResolveParamsSchema = Type.Object(
8493
{
8594
key: Type.Optional(NonEmptyString),

src/gateway/protocol/schema/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export type PushTestResult = SchemaType<"PushTestResult">;
4646
export type SessionsListParams = SchemaType<"SessionsListParams">;
4747
export type SessionsCleanupParams = SchemaType<"SessionsCleanupParams">;
4848
export type SessionsPreviewParams = SchemaType<"SessionsPreviewParams">;
49+
export type SessionsDescribeParams = SchemaType<"SessionsDescribeParams">;
4950
export type SessionsResolveParams = SchemaType<"SessionsResolveParams">;
5051
export type SessionCompactionCheckpoint = SchemaType<"SessionCompactionCheckpoint">;
5152
export type SessionsCompactionListParams = SchemaType<"SessionsCompactionListParams">;

src/gateway/server-methods-list.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ const BASE_METHODS = [
9696
"sessions.messages.subscribe",
9797
"sessions.messages.unsubscribe",
9898
"sessions.preview",
99+
"sessions.describe",
99100
"sessions.compaction.list",
100101
"sessions.compaction.get",
101102
"sessions.compaction.branch",

src/gateway/server-methods/sessions.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import {
5757
validateSessionsCompactionRestoreParams,
5858
validateSessionsCreateParams,
5959
validateSessionsDeleteParams,
60+
validateSessionsDescribeParams,
6061
validateSessionsListParams,
6162
validateSessionsMessagesSubscribeParams,
6263
validateSessionsMessagesUnsubscribeParams,
@@ -76,6 +77,7 @@ import {
7677
import { reactivateCompletedSubagentSession } from "../session-subagent-reactivation.js";
7778
import {
7879
archiveFileOnDisk,
80+
buildGatewaySessionRow,
7981
listSessionsFromStoreAsync,
8082
loadCombinedSessionStoreForGateway,
8183
loadGatewaySessionRow,
@@ -824,6 +826,34 @@ export const sessionsHandlers: GatewayRequestHandlers = {
824826

825827
respond(true, { ts: Date.now(), previews } satisfies SessionsPreviewResult, undefined);
826828
},
829+
"sessions.describe": ({ params, respond, context }) => {
830+
if (!assertValidParams(params, validateSessionsDescribeParams, "sessions.describe", respond)) {
831+
return;
832+
}
833+
const key = requireSessionKey(params.key, respond);
834+
if (!key) {
835+
return;
836+
}
837+
const cfg = context.getRuntimeConfig();
838+
const { target, storePath } = resolveGatewaySessionTargetFromKey(key, cfg);
839+
const store = loadSessionStore(storePath);
840+
const entry = resolveFreshestSessionEntryFromStoreKeys(store, target.storeKeys);
841+
if (!entry) {
842+
respond(true, { session: null }, undefined);
843+
return;
844+
}
845+
const row = buildGatewaySessionRow({
846+
cfg,
847+
storePath,
848+
store,
849+
key: target.canonicalKey,
850+
entry,
851+
includeDerivedTitles: params.includeDerivedTitles,
852+
includeLastMessage: params.includeLastMessage,
853+
transcriptUsageMaxBytes: 64 * 1024,
854+
});
855+
respond(true, { session: row }, undefined);
856+
},
827857
"sessions.resolve": async ({ params, respond, context }) => {
828858
if (!assertValidParams(params, validateSessionsResolveParams, "sessions.resolve", respond)) {
829859
return;

src/gateway/session-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1688,7 +1688,7 @@ export function loadGatewaySessionRow(
16881688
*/
16891689
const SESSIONS_LIST_YIELD_BATCH_SIZE = 10;
16901690

1691-
function filterAndSortSessionEntries(params: {
1691+
export function filterAndSortSessionEntries(params: {
16921692
store: Record<string, SessionEntry>;
16931693
opts: import("./protocol/index.js").SessionsListParams;
16941694
now: number;

0 commit comments

Comments
 (0)