Skip to content

Commit 7d518e3

Browse files
committed
feat(sessions): label lookup tightening (#570) (thanks @azade-c)
1 parent 09b602b commit 7d518e3

8 files changed

Lines changed: 343 additions & 598 deletions

File tree

apps/macos/Sources/ClawdbotProtocol/GatewayModels.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,7 @@ public struct SessionsListParams: Codable, Sendable {
671671
public let activeminutes: Int?
672672
public let includeglobal: Bool?
673673
public let includeunknown: Bool?
674+
public let label: String?
674675
public let spawnedby: String?
675676
public let agentid: String?
676677

@@ -679,13 +680,15 @@ public struct SessionsListParams: Codable, Sendable {
679680
activeminutes: Int?,
680681
includeglobal: Bool?,
681682
includeunknown: Bool?,
683+
label: String?,
682684
spawnedby: String?,
683685
agentid: String?
684686
) {
685687
self.limit = limit
686688
self.activeminutes = activeminutes
687689
self.includeglobal = includeglobal
688690
self.includeunknown = includeunknown
691+
self.label = label
689692
self.spawnedby = spawnedby
690693
self.agentid = agentid
691694
}
@@ -694,6 +697,7 @@ public struct SessionsListParams: Codable, Sendable {
694697
case activeminutes = "activeMinutes"
695698
case includeglobal = "includeGlobal"
696699
case includeunknown = "includeUnknown"
700+
case label
697701
case spawnedby = "spawnedBy"
698702
case agentid = "agentId"
699703
}

src/agents/tools/sessions-send-tool.ts

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const SessionsSendToolSchema = Type.Union([
4040
),
4141
Type.Object(
4242
{
43-
label: Type.String(),
43+
label: Type.String({ minLength: 1, maxLength: 64 }),
4444
message: Type.String(),
4545
timeoutSeconds: Type.Optional(Type.Integer({ minimum: 0 })),
4646
},
@@ -81,7 +81,7 @@ export function createSessionsSendTool(opts?: {
8181
!isSubagentSessionKey(requesterInternalKey);
8282

8383
const sessionKeyParam = readStringParam(params, "sessionKey");
84-
const labelParam = readStringParam(params, "label");
84+
const labelParam = readStringParam(params, "label")?.trim() || undefined;
8585
if (sessionKeyParam && labelParam) {
8686
return jsonResult({
8787
runId: crypto.randomUUID(),
@@ -99,32 +99,21 @@ export function createSessionsSendTool(opts?: {
9999
return Array.isArray(result?.sessions) ? result.sessions : [];
100100
};
101101

102-
const activeMinutes = 24 * 60;
103-
const visibleSessions = restrictToSpawned
104-
? await listSessions({
105-
activeMinutes,
106-
includeGlobal: false,
107-
includeUnknown: false,
108-
limit: 500,
109-
spawnedBy: requesterInternalKey,
110-
})
111-
: undefined;
112-
113102
let sessionKey = sessionKeyParam;
114103
if (!sessionKey && labelParam) {
115-
const sessions =
116-
visibleSessions ??
117-
(await listSessions({
118-
activeMinutes,
119-
includeGlobal: false,
120-
includeUnknown: false,
121-
limit: 500,
122-
}));
123-
const matches = sessions.filter((entry) => {
124-
const label =
125-
typeof entry?.label === "string" ? entry.label : undefined;
126-
return label === labelParam;
127-
});
104+
const agentIdForLookup = requesterInternalKey
105+
? normalizeAgentId(
106+
parseAgentSessionKey(requesterInternalKey)?.agentId,
107+
)
108+
: undefined;
109+
const listParams: Record<string, unknown> = {
110+
includeGlobal: false,
111+
includeUnknown: false,
112+
label: labelParam,
113+
};
114+
if (restrictToSpawned) listParams.spawnedBy = requesterInternalKey;
115+
if (agentIdForLookup) listParams.agentId = agentIdForLookup;
116+
const matches = await listSessions(listParams);
128117
if (matches.length === 0) {
129118
if (restrictToSpawned) {
130119
return jsonResult({
@@ -176,7 +165,18 @@ export function createSessionsSendTool(opts?: {
176165
});
177166

178167
if (restrictToSpawned) {
179-
const sessions = visibleSessions ?? [];
168+
const agentIdForLookup = requesterInternalKey
169+
? normalizeAgentId(
170+
parseAgentSessionKey(requesterInternalKey)?.agentId,
171+
)
172+
: undefined;
173+
const sessions = await listSessions({
174+
includeGlobal: false,
175+
includeUnknown: false,
176+
limit: 500,
177+
spawnedBy: requesterInternalKey,
178+
...(agentIdForLookup ? { agentId: agentIdForLookup } : {}),
179+
});
180180
const ok = sessions.some((entry) => entry?.key === resolvedKey);
181181
if (!ok) {
182182
return jsonResult({

src/gateway/protocol/schema.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { type Static, type TSchema, Type } from "@sinclair/typebox";
22

33
const NonEmptyString = Type.String({ minLength: 1 });
4+
const SessionLabelString = Type.String({ minLength: 1, maxLength: 64 });
45

56
export const PresenceEntrySchema = Type.Object(
67
{
@@ -225,7 +226,7 @@ export const AgentParamsSchema = Type.Object(
225226
lane: Type.Optional(Type.String()),
226227
extraSystemPrompt: Type.Optional(Type.String()),
227228
idempotencyKey: NonEmptyString,
228-
label: Type.Optional(Type.String()),
229+
label: Type.Optional(SessionLabelString),
229230
spawnedBy: Type.Optional(Type.String()),
230231
},
231232
{ additionalProperties: false },
@@ -315,6 +316,7 @@ export const SessionsListParamsSchema = Type.Object(
315316
activeMinutes: Type.Optional(Type.Integer({ minimum: 1 })),
316317
includeGlobal: Type.Optional(Type.Boolean()),
317318
includeUnknown: Type.Optional(Type.Boolean()),
319+
label: Type.Optional(SessionLabelString),
318320
spawnedBy: Type.Optional(NonEmptyString),
319321
agentId: Type.Optional(NonEmptyString),
320322
},
@@ -324,7 +326,7 @@ export const SessionsListParamsSchema = Type.Object(
324326
export const SessionsPatchParamsSchema = Type.Object(
325327
{
326328
key: NonEmptyString,
327-
label: Type.Optional(Type.Union([NonEmptyString, Type.Null()])),
329+
label: Type.Optional(Type.Union([SessionLabelString, Type.Null()])),
328330
thinkingLevel: Type.Optional(Type.Union([NonEmptyString, Type.Null()])),
329331
verboseLevel: Type.Optional(Type.Union([NonEmptyString, Type.Null()])),
330332
reasoningLevel: Type.Optional(Type.Union([NonEmptyString, Type.Null()])),

0 commit comments

Comments
 (0)