@deepseek-ai/dsh-api-session-controller 0.2.0-rc.1 → 0.2.1-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -131,6 +131,52 @@ const _deepseek_ai_dsh_api_session_controller_session_control_result$schema = ()
131
131
  'label': z.string(),
132
132
  'seq': z.intersection(z.number(), z.unknown()),
133
133
  })]).optional(),
134
+ 'tokenUsage': z.object({
135
+ 'uncachedInputTokens': z.number(),
136
+ 'outputTokens': z.number(),
137
+ 'cacheReadTokens': z.number(),
138
+ 'cacheWriteTokens': z.number(),
139
+ }).optional(),
140
+ 'contextPressure': z.object({
141
+ 'pressureTokens': z.number().optional(),
142
+ 'projectedTokens': z.number().optional(),
143
+ 'contextWindow': z.number().optional(),
144
+ }).optional(),
145
+ 'contextBreakdown': z.object({
146
+ 'systemTokens': z.number(),
147
+ 'toolsTokens': z.number(),
148
+ 'messageTokens': z.number(),
149
+ }).optional(),
150
+ 'userQuestions': z.object({
151
+ 'active': z.array(z.object({
152
+ 'callId': z.intersection(z.string(), z.unknown()).readonly(),
153
+ 'questions': z.array(z.object({
154
+ 'id': z.string(),
155
+ 'question': z.string(),
156
+ 'detail': z.string().optional(),
157
+ 'header': z.string().optional(),
158
+ 'options': z.array(z.object({
159
+ 'label': z.string(),
160
+ 'description': z.string().optional(),
161
+ })).optional(),
162
+ 'multiSelect': z.boolean().optional(),
163
+ 'intent': z.object({
164
+ 'kind': z.literal("plan-review"),
165
+ 'approve': z.string(),
166
+ 'callId': z.intersection(z.string(), z.unknown()).optional(),
167
+ }).optional(),
168
+ })).readonly(),
169
+ 'state': z.union([z.literal("open"), z.literal("continued")]).readonly(),
170
+ })).readonly(),
171
+ 'settled': z.array(z.object({
172
+ 'callId': z.intersection(z.string(), z.unknown()).readonly(),
173
+ 'answers': z.array(z.object({
174
+ 'id': z.string(),
175
+ 'selected': z.array(z.string()),
176
+ 'custom': z.string().optional(),
177
+ })).readonly(),
178
+ })).readonly(),
179
+ }).optional(),
134
180
  'goal': z.union([z.literal(null), z.object({
135
181
  'goal': z.object({
136
182
  'objective': z.string().readonly(),
@@ -303,6 +349,52 @@ const _deepseek_ai_dsh_api_session_controller_session_follow_result$schema = ()
303
349
  'label': z.string(),
304
350
  'seq': z.intersection(z.number(), z.unknown()),
305
351
  })]).optional(),
352
+ 'tokenUsage': z.object({
353
+ 'uncachedInputTokens': z.number(),
354
+ 'outputTokens': z.number(),
355
+ 'cacheReadTokens': z.number(),
356
+ 'cacheWriteTokens': z.number(),
357
+ }).optional(),
358
+ 'contextPressure': z.object({
359
+ 'pressureTokens': z.number().optional(),
360
+ 'projectedTokens': z.number().optional(),
361
+ 'contextWindow': z.number().optional(),
362
+ }).optional(),
363
+ 'contextBreakdown': z.object({
364
+ 'systemTokens': z.number(),
365
+ 'toolsTokens': z.number(),
366
+ 'messageTokens': z.number(),
367
+ }).optional(),
368
+ 'userQuestions': z.object({
369
+ 'active': z.array(z.object({
370
+ 'callId': z.intersection(z.string(), z.unknown()).readonly(),
371
+ 'questions': z.array(z.object({
372
+ 'id': z.string(),
373
+ 'question': z.string(),
374
+ 'detail': z.string().optional(),
375
+ 'header': z.string().optional(),
376
+ 'options': z.array(z.object({
377
+ 'label': z.string(),
378
+ 'description': z.string().optional(),
379
+ })).optional(),
380
+ 'multiSelect': z.boolean().optional(),
381
+ 'intent': z.object({
382
+ 'kind': z.literal("plan-review"),
383
+ 'approve': z.string(),
384
+ 'callId': z.intersection(z.string(), z.unknown()).optional(),
385
+ }).optional(),
386
+ })).readonly(),
387
+ 'state': z.union([z.literal("open"), z.literal("continued")]).readonly(),
388
+ })).readonly(),
389
+ 'settled': z.array(z.object({
390
+ 'callId': z.intersection(z.string(), z.unknown()).readonly(),
391
+ 'answers': z.array(z.object({
392
+ 'id': z.string(),
393
+ 'selected': z.array(z.string()),
394
+ 'custom': z.string().optional(),
395
+ })).readonly(),
396
+ })).readonly(),
397
+ }).optional(),
306
398
  'goal': z.union([z.literal(null), z.object({
307
399
  'goal': z.object({
308
400
  'objective': z.string().readonly(),
@@ -465,6 +557,52 @@ const _deepseek_ai_dsh_api_session_controller_session_list_result$schema = () =>
465
557
  'label': z.string(),
466
558
  'seq': z.intersection(z.number(), z.unknown()),
467
559
  })]).optional(),
560
+ 'tokenUsage': z.object({
561
+ 'uncachedInputTokens': z.number(),
562
+ 'outputTokens': z.number(),
563
+ 'cacheReadTokens': z.number(),
564
+ 'cacheWriteTokens': z.number(),
565
+ }).optional(),
566
+ 'contextPressure': z.object({
567
+ 'pressureTokens': z.number().optional(),
568
+ 'projectedTokens': z.number().optional(),
569
+ 'contextWindow': z.number().optional(),
570
+ }).optional(),
571
+ 'contextBreakdown': z.object({
572
+ 'systemTokens': z.number(),
573
+ 'toolsTokens': z.number(),
574
+ 'messageTokens': z.number(),
575
+ }).optional(),
576
+ 'userQuestions': z.object({
577
+ 'active': z.array(z.object({
578
+ 'callId': z.intersection(z.string(), z.unknown()).readonly(),
579
+ 'questions': z.array(z.object({
580
+ 'id': z.string(),
581
+ 'question': z.string(),
582
+ 'detail': z.string().optional(),
583
+ 'header': z.string().optional(),
584
+ 'options': z.array(z.object({
585
+ 'label': z.string(),
586
+ 'description': z.string().optional(),
587
+ })).optional(),
588
+ 'multiSelect': z.boolean().optional(),
589
+ 'intent': z.object({
590
+ 'kind': z.literal("plan-review"),
591
+ 'approve': z.string(),
592
+ 'callId': z.intersection(z.string(), z.unknown()).optional(),
593
+ }).optional(),
594
+ })).readonly(),
595
+ 'state': z.union([z.literal("open"), z.literal("continued")]).readonly(),
596
+ })).readonly(),
597
+ 'settled': z.array(z.object({
598
+ 'callId': z.intersection(z.string(), z.unknown()).readonly(),
599
+ 'answers': z.array(z.object({
600
+ 'id': z.string(),
601
+ 'selected': z.array(z.string()),
602
+ 'custom': z.string().optional(),
603
+ })).readonly(),
604
+ })).readonly(),
605
+ }).optional(),
468
606
  'goal': z.union([z.literal(null), z.object({
469
607
  'goal': z.object({
470
608
  'objective': z.string().readonly(),
@@ -642,6 +780,52 @@ const _deepseek_ai_dsh_api_session_controller_session_projections_result$schema
642
780
  'label': z.string(),
643
781
  'seq': z.intersection(z.number(), z.unknown()),
644
782
  })]).optional(),
783
+ 'tokenUsage': z.object({
784
+ 'uncachedInputTokens': z.number(),
785
+ 'outputTokens': z.number(),
786
+ 'cacheReadTokens': z.number(),
787
+ 'cacheWriteTokens': z.number(),
788
+ }).optional(),
789
+ 'contextPressure': z.object({
790
+ 'pressureTokens': z.number().optional(),
791
+ 'projectedTokens': z.number().optional(),
792
+ 'contextWindow': z.number().optional(),
793
+ }).optional(),
794
+ 'contextBreakdown': z.object({
795
+ 'systemTokens': z.number(),
796
+ 'toolsTokens': z.number(),
797
+ 'messageTokens': z.number(),
798
+ }).optional(),
799
+ 'userQuestions': z.object({
800
+ 'active': z.array(z.object({
801
+ 'callId': z.intersection(z.string(), z.unknown()).readonly(),
802
+ 'questions': z.array(z.object({
803
+ 'id': z.string(),
804
+ 'question': z.string(),
805
+ 'detail': z.string().optional(),
806
+ 'header': z.string().optional(),
807
+ 'options': z.array(z.object({
808
+ 'label': z.string(),
809
+ 'description': z.string().optional(),
810
+ })).optional(),
811
+ 'multiSelect': z.boolean().optional(),
812
+ 'intent': z.object({
813
+ 'kind': z.literal("plan-review"),
814
+ 'approve': z.string(),
815
+ 'callId': z.intersection(z.string(), z.unknown()).optional(),
816
+ }).optional(),
817
+ })).readonly(),
818
+ 'state': z.union([z.literal("open"), z.literal("continued")]).readonly(),
819
+ })).readonly(),
820
+ 'settled': z.array(z.object({
821
+ 'callId': z.intersection(z.string(), z.unknown()).readonly(),
822
+ 'answers': z.array(z.object({
823
+ 'id': z.string(),
824
+ 'selected': z.array(z.string()),
825
+ 'custom': z.string().optional(),
826
+ })).readonly(),
827
+ })).readonly(),
828
+ }).optional(),
645
829
  'goal': z.union([z.literal(null), z.object({
646
830
  'goal': z.object({
647
831
  'objective': z.string().readonly(),
@@ -833,7 +1017,7 @@ export const TYPERT_REMOTE = {
833
1017
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionAttachmentValue',
834
1018
  create: _deepseek_ai_dsh_api_session_controller_session_attachment_result$schema,
835
1019
  },
836
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":437,"column":3},
1020
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":444,"column":3},
837
1021
  },
838
1022
  {
839
1023
  id: '@deepseek-ai/dsh-api-session-controller#session/cancel',
@@ -858,7 +1042,7 @@ export const TYPERT_REMOTE = {
858
1042
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionCancelValue',
859
1043
  create: _deepseek_ai_dsh_api_session_controller_session_cancel_result$schema,
860
1044
  },
861
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":457,"column":3},
1045
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":464,"column":3},
862
1046
  },
863
1047
  {
864
1048
  id: '@deepseek-ai/dsh-api-session-controller#session/canOpenWorkspacePath',
@@ -873,7 +1057,7 @@ export const TYPERT_REMOTE = {
873
1057
  typeSymbol: '@deepseek-ai/dsh-api-session-controller#session/canOpenWorkspacePath:result',
874
1058
  create: _deepseek_ai_dsh_api_session_controller_session_canOpenWorkspacePath_result$schema,
875
1059
  },
876
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":319,"column":3},
1060
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":326,"column":3},
877
1061
  },
878
1062
  {
879
1063
  id: '@deepseek-ai/dsh-api-session-controller#session/control',
@@ -890,7 +1074,7 @@ export const TYPERT_REMOTE = {
890
1074
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionControlFrame',
891
1075
  create: _deepseek_ai_dsh_api_session_controller_session_control_result$schema,
892
1076
  },
893
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":520,"column":3},
1077
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":527,"column":3},
894
1078
  },
895
1079
  {
896
1080
  id: '@deepseek-ai/dsh-api-session-controller#session/create',
@@ -915,7 +1099,7 @@ export const TYPERT_REMOTE = {
915
1099
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionCreateValue',
916
1100
  create: _deepseek_ai_dsh_api_session_controller_session_create_result$schema,
917
1101
  },
918
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":273,"column":3},
1102
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":280,"column":3},
919
1103
  },
920
1104
  {
921
1105
  id: '@deepseek-ai/dsh-api-session-controller#session/follow',
@@ -942,7 +1126,7 @@ export const TYPERT_REMOTE = {
942
1126
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionFollowFrame',
943
1127
  create: _deepseek_ai_dsh_api_session_controller_session_follow_result$schema,
944
1128
  },
945
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":480,"column":3},
1129
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":487,"column":3},
946
1130
  },
947
1131
  {
948
1132
  id: '@deepseek-ai/dsh-api-session-controller#session/fork',
@@ -967,7 +1151,7 @@ export const TYPERT_REMOTE = {
967
1151
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionForkValue',
968
1152
  create: _deepseek_ai_dsh_api_session_controller_session_fork_result$schema,
969
1153
  },
970
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":415,"column":3},
1154
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":422,"column":3},
971
1155
  },
972
1156
  {
973
1157
  id: '@deepseek-ai/dsh-api-session-controller#session/initializeDefaultModel',
@@ -982,7 +1166,7 @@ export const TYPERT_REMOTE = {
982
1166
  typeSymbol: '@deepseek-ai/dsh-api-session-controller#session/initializeDefaultModel:result',
983
1167
  create: _deepseek_ai_dsh_api_session_controller_session_initializeDefaultModel_result$schema,
984
1168
  },
985
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":292,"column":9},
1169
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":299,"column":9},
986
1170
  },
987
1171
  {
988
1172
  id: '@deepseek-ai/dsh-api-session-controller#session/list',
@@ -1008,7 +1192,7 @@ export const TYPERT_REMOTE = {
1008
1192
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionListValue',
1009
1193
  create: _deepseek_ai_dsh_api_session_controller_session_list_result$schema,
1010
1194
  },
1011
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":252,"column":9},
1195
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":259,"column":9},
1012
1196
  },
1013
1197
  {
1014
1198
  id: '@deepseek-ai/dsh-api-session-controller#session/modelCatalog',
@@ -1023,7 +1207,7 @@ export const TYPERT_REMOTE = {
1023
1207
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#ModelCatalog',
1024
1208
  create: _deepseek_ai_dsh_api_session_controller_session_modelCatalog_result$schema,
1025
1209
  },
1026
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":310,"column":3},
1210
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":317,"column":3},
1027
1211
  },
1028
1212
  {
1029
1213
  id: '@deepseek-ai/dsh-api-session-controller#session/openWorkspacePath',
@@ -1049,7 +1233,7 @@ export const TYPERT_REMOTE = {
1049
1233
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionOpenWorkspacePathValue',
1050
1234
  create: _deepseek_ai_dsh_api_session_controller_session_openWorkspacePath_result$schema,
1051
1235
  },
1052
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":340,"column":9},
1236
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":347,"column":9},
1053
1237
  },
1054
1238
  {
1055
1239
  id: '@deepseek-ai/dsh-api-session-controller#session/page',
@@ -1075,7 +1259,7 @@ export const TYPERT_REMOTE = {
1075
1259
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionPage',
1076
1260
  create: _deepseek_ai_dsh_api_session_controller_session_page_result$schema,
1077
1261
  },
1078
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":468,"column":3},
1262
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":475,"column":3},
1079
1263
  },
1080
1264
  {
1081
1265
  id: '@deepseek-ai/dsh-api-session-controller#session/projections',
@@ -1101,7 +1285,7 @@ export const TYPERT_REMOTE = {
1101
1285
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionProjectionsValue',
1102
1286
  create: _deepseek_ai_dsh_api_session_controller_session_projections_result$schema,
1103
1287
  },
1104
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":491,"column":9},
1288
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":498,"column":9},
1105
1289
  },
1106
1290
  {
1107
1291
  id: '@deepseek-ai/dsh-api-session-controller#session/prompt',
@@ -1127,7 +1311,7 @@ export const TYPERT_REMOTE = {
1127
1311
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionPromptValue',
1128
1312
  create: _deepseek_ai_dsh_api_session_controller_session_prompt_result$schema,
1129
1313
  },
1130
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":426,"column":3},
1314
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":433,"column":3},
1131
1315
  },
1132
1316
  {
1133
1317
  id: '@deepseek-ai/dsh-api-session-controller#session/rename',
@@ -1152,7 +1336,7 @@ export const TYPERT_REMOTE = {
1152
1336
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionRenameValue',
1153
1337
  create: _deepseek_ai_dsh_api_session_controller_session_rename_result$schema,
1154
1338
  },
1155
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":403,"column":3},
1339
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":410,"column":3},
1156
1340
  },
1157
1341
  {
1158
1342
  id: '@deepseek-ai/dsh-api-session-controller#session/search',
@@ -1178,7 +1362,7 @@ export const TYPERT_REMOTE = {
1178
1362
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionSearchValue',
1179
1363
  create: _deepseek_ai_dsh_api_session_controller_session_search_result$schema,
1180
1364
  },
1181
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":263,"column":3},
1365
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":270,"column":3},
1182
1366
  },
1183
1367
  {
1184
1368
  id: '@deepseek-ai/dsh-api-session-controller#session/selectModel',
@@ -1203,7 +1387,7 @@ export const TYPERT_REMOTE = {
1203
1387
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionSelectModelValue',
1204
1388
  create: _deepseek_ai_dsh_api_session_controller_session_selectModel_result$schema,
1205
1389
  },
1206
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":283,"column":3},
1390
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":290,"column":3},
1207
1391
  },
1208
1392
  {
1209
1393
  id: '@deepseek-ai/dsh-api-session-controller#session/updateQueue',
@@ -1228,7 +1412,7 @@ export const TYPERT_REMOTE = {
1228
1412
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionUpdateQueueValue',
1229
1413
  create: _deepseek_ai_dsh_api_session_controller_session_updateQueue_result$schema,
1230
1414
  },
1231
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":447,"column":3},
1415
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":454,"column":3},
1232
1416
  },
1233
1417
  {
1234
1418
  id: '@deepseek-ai/dsh-api-session-controller#session/workspacePathApplications',
@@ -1254,7 +1438,7 @@ export const TYPERT_REMOTE = {
1254
1438
  typeSymbol: '@deepseek-ai/dsh-api-session-controller#session/workspacePathApplications:result',
1255
1439
  create: _deepseek_ai_dsh_api_session_controller_session_workspacePathApplications_result$schema,
1256
1440
  },
1257
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":370,"column":9},
1441
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":377,"column":9},
1258
1442
  },
1259
1443
  {
1260
1444
  id: '@deepseek-ai/dsh-api-session-controller#skills/list',
@@ -22,7 +22,13 @@ declare module '@deepseek-ai/cordis' {
22
22
  export interface Config {
23
23
  /** Override platform desktop-opener detection. */
24
24
  readonly nativeOpen?: boolean;
25
+ /** Positive integral milliseconds of list work before yielding between complete rows. */
26
+ readonly listWorkSliceMs?: number;
25
27
  }
28
+ /** Deployment policy after schema defaults have been applied. */
29
+ type ResolvedConfig = Config & {
30
+ readonly listWorkSliceMs: number;
31
+ };
26
32
  /** Host integrations replaceable by direct unit tests. */
27
33
  export interface SessionControllerInternals {
28
34
  /** Native default-application handoff. */
@@ -39,7 +45,7 @@ export interface SessionControllerInternals {
39
45
  /** Host service backing the generated `ctx.remote.session` namespace. */
40
46
  export declare class SessionController extends TypertRemoteService {
41
47
  static inject: string[];
42
- static Config: z<Config>;
48
+ static Config: z<Config, ResolvedConfig>;
43
49
  private readonly agents;
44
50
  private readonly commands;
45
51
  private readonly controlState;
@@ -53,7 +59,7 @@ export declare class SessionController extends TypertRemoteService {
53
59
  private readonly promotions;
54
60
  /**
55
61
  * @param ctx - Host context containing the Session capability assembly.
56
- * @param config - native-opener deployment policy.
62
+ * @param config - native-opener and list-scheduling deployment policy.
57
63
  * @param internals - host integrations replaceable by direct unit tests.
58
64
  */
59
65
  constructor(ctx: Context, config: Config, internals?: SessionControllerInternals);
@@ -74,7 +80,7 @@ export declare class SessionController extends TypertRemoteService {
74
80
  /**
75
81
  * Read all visible Session rows without resuming an Agent.
76
82
  * @param _request - reserved empty list request.
77
- * @param signal - cancellation for persistence reads.
83
+ * @param signal - cancellation for persistence reads and summary generation.
78
84
  * @returns visible Session summaries ordered by activity.
79
85
  */
80
86
  list(_request: SessionListRequest, signal: AbortSignal): Promise<SessionListValue>;
@@ -187,6 +187,7 @@ let SessionController = (() => {
187
187
  ];
188
188
  static Config = z.object({
189
189
  nativeOpen: z.boolean(),
190
+ listWorkSliceMs: z.natural().min(1).default(16),
190
191
  });
191
192
  agents = __runInitializers(this, _instanceExtraInitializers);
192
193
  commands;
@@ -201,11 +202,12 @@ let SessionController = (() => {
201
202
  promotions = new Set();
202
203
  /**
203
204
  * @param ctx - Host context containing the Session capability assembly.
204
- * @param config - native-opener deployment policy.
205
+ * @param config - native-opener and list-scheduling deployment policy.
205
206
  * @param internals - host integrations replaceable by direct unit tests.
206
207
  */
207
208
  constructor(ctx, config, internals = {}) {
208
209
  super(ctx, 'sessionController', { namespace: 'session' });
210
+ const resolved = SessionController.Config(config);
209
211
  installModelSelectionProjection(ctx);
210
212
  this.agents = new ApiSessionAgentController(ctx);
211
213
  this.commands = new SessionCommandController(ctx, this.agents, process.cwd());
@@ -222,7 +224,7 @@ let SessionController = (() => {
222
224
  await Promise.allSettled([...this.promotions]);
223
225
  }, 'session-controller.promotions');
224
226
  this.history = new SessionHistoryController(ctx, (observation) => { this.promote(observation); });
225
- this.listState = new ApiSessionList(ctx);
227
+ this.listState = new ApiSessionList(ctx, resolved.listWorkSliceMs);
226
228
  this.fileApplications = internals.fileApplications ?? nativeFileApplications;
227
229
  this.openFileApplication = internals.openFileApplication ?? openNativeFileApplication;
228
230
  this.openPath = internals.openPath ?? openNativeAssociatedPath;
@@ -318,7 +320,7 @@ let SessionController = (() => {
318
320
  /**
319
321
  * Read all visible Session rows without resuming an Agent.
320
322
  * @param _request - reserved empty list request.
321
- * @param signal - cancellation for persistence reads.
323
+ * @param signal - cancellation for persistence reads and summary generation.
322
324
  * @returns visible Session summaries ordered by activity.
323
325
  */
324
326
  async list(_request, signal) {
@@ -19,8 +19,12 @@ export declare function truncateUnicodeCodePoints(value: string, maximum: number
19
19
  /** Owns list projection registration, bounded cold summaries, and authorized search. */
20
20
  export declare class ApiSessionList {
21
21
  private readonly ctx;
22
- /** @param ctx - Host context carrying Session, query, persistence, and projection services. */
23
- constructor(ctx: Context);
22
+ private readonly workSliceMs;
23
+ /**
24
+ * @param ctx - Host context carrying Session, query, persistence, and projection services.
25
+ * @param workSliceMs - Resolved positive integral list-work budget in milliseconds.
26
+ */
27
+ constructor(ctx: Context, workSliceMs: number);
24
28
  /**
25
29
  * Build one current attached-Session summary.
26
30
  * @param session - attached Session to summarize.
@@ -29,7 +33,7 @@ export declare class ApiSessionList {
29
33
  summaryFor(session: Session): SessionSummary;
30
34
  /**
31
35
  * Read every visible attached and persisted Session without activating an Agent.
32
- * @param signal - optional cancellation for persistence reads.
36
+ * @param signal - optional cancellation for persistence reads and summary generation.
33
37
  * @returns visible Session summaries ordered by activity.
34
38
  */
35
39
  list(signal?: AbortSignal): Promise<SessionSummary[]>;
package/lib/types/list.js CHANGED
@@ -1,4 +1,6 @@
1
1
  /** Cold-safe Session list and search projection. */
2
+ import { performance } from 'node:perf_hooks';
3
+ import { scheduler } from 'node:timers/promises';
2
4
  import { SessionQueryError } from '@deepseek-ai/dsh-session-query';
3
5
  import { RemoteError } from '@deepseek-ai/dsh-typert-protocol';
4
6
  import { z } from 'zod';
@@ -53,9 +55,14 @@ export function truncateUnicodeCodePoints(value, maximum) {
53
55
  /** Owns list projection registration, bounded cold summaries, and authorized search. */
54
56
  export class ApiSessionList {
55
57
  ctx;
56
- /** @param ctx - Host context carrying Session, query, persistence, and projection services. */
57
- constructor(ctx) {
58
+ workSliceMs;
59
+ /**
60
+ * @param ctx - Host context carrying Session, query, persistence, and projection services.
61
+ * @param workSliceMs - Resolved positive integral list-work budget in milliseconds.
62
+ */
63
+ constructor(ctx, workSliceMs) {
58
64
  this.ctx = ctx;
65
+ this.workSliceMs = workSliceMs;
59
66
  ctx.sessionProjections.register({
60
67
  key: 'sessionListMetadata',
61
68
  stateSchema: sessionListMetadataSchema,
@@ -98,7 +105,7 @@ export class ApiSessionList {
98
105
  }
99
106
  /**
100
107
  * Read every visible attached and persisted Session without activating an Agent.
101
- * @param signal - optional cancellation for persistence reads.
108
+ * @param signal - optional cancellation for persistence reads and summary generation.
102
109
  * @returns visible Session summaries ordered by activity.
103
110
  */
104
111
  async list(signal) {
@@ -107,18 +114,32 @@ export class ApiSessionList {
107
114
  signal?.throwIfAborted();
108
115
  const items = [];
109
116
  const cold = [];
117
+ let yieldDeadline = performance.now() + this.workSliceMs;
110
118
  for (const record of records) {
119
+ signal?.throwIfAborted();
111
120
  const live = this.ctx.sessions.get(record.header.id);
112
121
  if (live !== undefined) {
113
122
  items.push(this.summaryFor(live));
114
- continue;
115
123
  }
116
- if (record.header.cwd === undefined)
117
- continue;
118
- cold.push(record.header);
124
+ else if (record.header.cwd !== undefined) {
125
+ cold.push(record.header);
126
+ }
127
+ if (performance.now() >= yieldDeadline) {
128
+ await scheduler.yield();
129
+ signal?.throwIfAborted();
130
+ yieldDeadline = performance.now() + this.workSliceMs;
131
+ }
119
132
  }
120
- for (const header of cold)
133
+ for (const header of cold) {
134
+ signal?.throwIfAborted();
121
135
  items.push(this.summarizeCold(header));
136
+ if (performance.now() >= yieldDeadline) {
137
+ await scheduler.yield();
138
+ signal?.throwIfAborted();
139
+ yieldDeadline = performance.now() + this.workSliceMs;
140
+ }
141
+ }
142
+ signal?.throwIfAborted();
122
143
  items.sort((left, right) => right.updatedAt - left.updatedAt);
123
144
  return items;
124
145
  }