@dexto/server 1.6.16 → 1.6.17

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.
Files changed (37) hide show
  1. package/dist/events/a2a-sse-subscriber.cjs +9 -2
  2. package/dist/events/a2a-sse-subscriber.d.ts.map +1 -1
  3. package/dist/events/a2a-sse-subscriber.js +9 -2
  4. package/dist/events/usage-event-subscriber.cjs +263 -0
  5. package/dist/events/usage-event-subscriber.d.ts +35 -0
  6. package/dist/events/usage-event-subscriber.d.ts.map +1 -0
  7. package/dist/events/usage-event-subscriber.js +244 -0
  8. package/dist/events/usage-event-types.cjs +16 -0
  9. package/dist/events/usage-event-types.d.ts +33 -0
  10. package/dist/events/usage-event-types.d.ts.map +1 -0
  11. package/dist/events/usage-event-types.js +0 -0
  12. package/dist/hono/index.d.ts +157 -32
  13. package/dist/hono/index.d.ts.map +1 -1
  14. package/dist/hono/routes/a2a-tasks.d.ts +9 -9
  15. package/dist/hono/routes/approvals.cjs +94 -6
  16. package/dist/hono/routes/approvals.d.ts +22 -6
  17. package/dist/hono/routes/approvals.d.ts.map +1 -1
  18. package/dist/hono/routes/approvals.js +94 -6
  19. package/dist/hono/routes/messages.cjs +16 -5
  20. package/dist/hono/routes/messages.d.ts +6 -0
  21. package/dist/hono/routes/messages.d.ts.map +1 -1
  22. package/dist/hono/routes/messages.js +17 -6
  23. package/dist/hono/routes/search.d.ts +10 -0
  24. package/dist/hono/routes/search.d.ts.map +1 -1
  25. package/dist/hono/routes/sessions.cjs +54 -1
  26. package/dist/hono/routes/sessions.d.ts +111 -18
  27. package/dist/hono/routes/sessions.d.ts.map +1 -1
  28. package/dist/hono/routes/sessions.js +59 -2
  29. package/dist/hono/schemas/responses.cjs +48 -8
  30. package/dist/hono/schemas/responses.d.ts +489 -22
  31. package/dist/hono/schemas/responses.d.ts.map +1 -1
  32. package/dist/hono/schemas/responses.js +49 -9
  33. package/dist/index.cjs +4 -0
  34. package/dist/index.d.ts +2 -0
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +2 -0
  37. package/package.json +9 -9
@@ -22,6 +22,7 @@ __export(sessions_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(sessions_exports);
24
24
  var import_zod_openapi = require("@hono/zod-openapi");
25
+ var import_core = require("@dexto/core");
25
26
  var import_responses = require("../schemas/responses.js");
26
27
  const CreateSessionSchema = import_zod_openapi.z.object({
27
28
  sessionId: import_zod_openapi.z.string().optional().describe("A custom ID for the new session")
@@ -33,6 +34,12 @@ function mapSessionMetadata(sessionId, metadata, defaults) {
33
34
  lastActivity: metadata?.lastActivity ?? defaults?.lastActivity ?? null,
34
35
  messageCount: metadata?.messageCount ?? defaults?.messageCount ?? 0,
35
36
  title: metadata?.title ?? defaults?.title ?? null,
37
+ ...metadata?.tokenUsage && { tokenUsage: metadata.tokenUsage },
38
+ ...metadata?.estimatedCost !== void 0 && {
39
+ estimatedCost: metadata.estimatedCost
40
+ },
41
+ ...metadata?.modelStats && { modelStats: metadata.modelStats },
42
+ ...metadata?.usageTracking && { usageTracking: metadata.usageTracking },
36
43
  workspaceId: metadata?.workspaceId ?? defaults?.workspaceId ?? null,
37
44
  parentSessionId: metadata?.parentSessionId ?? defaults?.parentSessionId ?? null
38
45
  };
@@ -245,6 +252,15 @@ function createSessionsRouter(getAgent) {
245
252
  session: import_responses.SessionMetadataSchema.extend({
246
253
  isBusy: import_zod_openapi.z.boolean().describe(
247
254
  "Whether the session is currently processing a message"
255
+ ),
256
+ usageSummary: import_responses.UsageSummarySchema.describe(
257
+ "Exact usage summary derived from assistant message history"
258
+ ),
259
+ activeUsageScopeId: import_zod_openapi.z.string().nullable().describe(
260
+ "Current runtime usage scope identifier, if configured"
261
+ ),
262
+ activeUsageScope: import_responses.ScopedUsageSummarySchema.nullable().describe(
263
+ "Usage summary for the current runtime scope, if configured"
248
264
  )
249
265
  }).describe("Session metadata with processing status")
250
266
  }).strict()
@@ -263,6 +279,29 @@ function createSessionsRouter(getAgent) {
263
279
  }
264
280
  }
265
281
  });
282
+ const clearContextRoute = (0, import_zod_openapi.createRoute)({
283
+ method: "post",
284
+ path: "/sessions/{sessionId}/clear-context",
285
+ summary: "Clear Session Context",
286
+ description: "Clears the model context window for a session while preserving conversation history for review.",
287
+ tags: ["sessions"],
288
+ request: {
289
+ params: import_zod_openapi.z.object({ sessionId: import_zod_openapi.z.string().describe("Session identifier") })
290
+ },
291
+ responses: {
292
+ 200: {
293
+ description: "Session context cleared successfully",
294
+ content: {
295
+ "application/json": {
296
+ schema: import_zod_openapi.z.object({
297
+ status: import_zod_openapi.z.literal("context cleared").describe("Context clear status"),
298
+ sessionId: import_zod_openapi.z.string().describe("Session ID")
299
+ }).strict()
300
+ }
301
+ }
302
+ }
303
+ }
304
+ });
266
305
  const patchRoute = (0, import_zod_openapi.createRoute)({
267
306
  method: "patch",
268
307
  path: "/sessions/{sessionId}",
@@ -424,15 +463,29 @@ function createSessionsRouter(getAgent) {
424
463
  }
425
464
  const metadata = await agent.getSessionMetadata(sessionId);
426
465
  const isBusy = await agent.isSessionBusy(sessionId);
466
+ const usageSummary = await agent.getSessionUsageSummary(sessionId);
467
+ const activeUsageScopeId = (0, import_core.getConfiguredUsageScopeId)() ?? null;
468
+ const activeUsageScope = activeUsageScopeId ? {
469
+ scopeId: activeUsageScopeId,
470
+ ...await agent.getSessionUsageSummary(sessionId, activeUsageScopeId)
471
+ } : null;
427
472
  return ctx.json(
428
473
  {
429
474
  session: {
430
475
  ...mapSessionMetadata(sessionId, metadata),
431
- isBusy
476
+ isBusy,
477
+ usageSummary,
478
+ activeUsageScopeId,
479
+ activeUsageScope
432
480
  }
433
481
  },
434
482
  200
435
483
  );
484
+ }).openapi(clearContextRoute, async (ctx) => {
485
+ const agent = await getAgent(ctx);
486
+ const { sessionId } = ctx.req.valid("param");
487
+ await agent.clearContext(sessionId);
488
+ return ctx.json({ status: "context cleared", sessionId });
436
489
  }).openapi(patchRoute, async (ctx) => {
437
490
  const agent = await getAgent(ctx);
438
491
  const { sessionId } = ctx.req.valid("param");
@@ -15,9 +15,9 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
15
15
  inputTokens: number;
16
16
  outputTokens: number;
17
17
  reasoningTokens: number;
18
- totalTokens: number;
19
18
  cacheReadTokens: number;
20
19
  cacheWriteTokens: number;
20
+ totalTokens: number;
21
21
  } | undefined;
22
22
  estimatedCost?: number | undefined;
23
23
  modelStats?: {
@@ -25,17 +25,20 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
25
25
  inputTokens: number;
26
26
  outputTokens: number;
27
27
  reasoningTokens: number;
28
- totalTokens: number;
29
28
  cacheReadTokens: number;
30
29
  cacheWriteTokens: number;
30
+ totalTokens: number;
31
31
  };
32
+ estimatedCost: number;
32
33
  model: string;
33
34
  provider: string;
34
35
  messageCount: number;
35
- estimatedCost: number;
36
36
  firstUsedAt: number;
37
37
  lastUsedAt: number;
38
38
  }[] | undefined;
39
+ usageTracking?: {
40
+ hasUntrackedChatGPTLoginUsage?: boolean | undefined;
41
+ } | undefined;
39
42
  workspaceId?: string | null | undefined;
40
43
  parentSessionId?: string | null | undefined;
41
44
  }[];
@@ -63,9 +66,9 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
63
66
  inputTokens: number;
64
67
  outputTokens: number;
65
68
  reasoningTokens: number;
66
- totalTokens: number;
67
69
  cacheReadTokens: number;
68
70
  cacheWriteTokens: number;
71
+ totalTokens: number;
69
72
  } | undefined;
70
73
  estimatedCost?: number | undefined;
71
74
  modelStats?: {
@@ -73,17 +76,20 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
73
76
  inputTokens: number;
74
77
  outputTokens: number;
75
78
  reasoningTokens: number;
76
- totalTokens: number;
77
79
  cacheReadTokens: number;
78
80
  cacheWriteTokens: number;
81
+ totalTokens: number;
79
82
  };
83
+ estimatedCost: number;
80
84
  model: string;
81
85
  provider: string;
82
86
  messageCount: number;
83
- estimatedCost: number;
84
87
  firstUsedAt: number;
85
88
  lastUsedAt: number;
86
89
  }[] | undefined;
90
+ usageTracking?: {
91
+ hasUntrackedChatGPTLoginUsage?: boolean | undefined;
92
+ } | undefined;
87
93
  workspaceId?: string | null | undefined;
88
94
  parentSessionId?: string | null | undefined;
89
95
  };
@@ -111,9 +117,9 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
111
117
  inputTokens: number;
112
118
  outputTokens: number;
113
119
  reasoningTokens: number;
114
- totalTokens: number;
115
120
  cacheReadTokens: number;
116
121
  cacheWriteTokens: number;
122
+ totalTokens: number;
117
123
  } | undefined;
118
124
  estimatedCost?: number | undefined;
119
125
  modelStats?: {
@@ -121,17 +127,20 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
121
127
  inputTokens: number;
122
128
  outputTokens: number;
123
129
  reasoningTokens: number;
124
- totalTokens: number;
125
130
  cacheReadTokens: number;
126
131
  cacheWriteTokens: number;
132
+ totalTokens: number;
127
133
  };
134
+ estimatedCost: number;
128
135
  model: string;
129
136
  provider: string;
130
137
  messageCount: number;
131
- estimatedCost: number;
132
138
  firstUsedAt: number;
133
139
  lastUsedAt: number;
134
140
  }[] | undefined;
141
+ usageTracking?: {
142
+ hasUntrackedChatGPTLoginUsage?: boolean | undefined;
143
+ } | undefined;
135
144
  workspaceId?: string | null | undefined;
136
145
  parentSessionId?: string | null | undefined;
137
146
  };
@@ -178,9 +187,9 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
178
187
  inputTokens: number;
179
188
  outputTokens: number;
180
189
  reasoningTokens: number;
181
- totalTokens: number;
182
190
  cacheReadTokens: number;
183
191
  cacheWriteTokens: number;
192
+ totalTokens: number;
184
193
  } | undefined;
185
194
  estimatedCost?: number | undefined;
186
195
  modelStats?: {
@@ -188,17 +197,20 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
188
197
  inputTokens: number;
189
198
  outputTokens: number;
190
199
  reasoningTokens: number;
191
- totalTokens: number;
192
200
  cacheReadTokens: number;
193
201
  cacheWriteTokens: number;
202
+ totalTokens: number;
194
203
  };
204
+ estimatedCost: number;
195
205
  model: string;
196
206
  provider: string;
197
207
  messageCount: number;
198
- estimatedCost: number;
199
208
  firstUsedAt: number;
200
209
  lastUsedAt: number;
201
210
  }[] | undefined;
211
+ usageTracking?: {
212
+ hasUntrackedChatGPTLoginUsage?: boolean | undefined;
213
+ } | undefined;
202
214
  workspaceId?: string | null | undefined;
203
215
  parentSessionId?: string | null | undefined;
204
216
  };
@@ -252,8 +264,13 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
252
264
  inputTokens?: number | undefined;
253
265
  outputTokens?: number | undefined;
254
266
  reasoningTokens?: number | undefined;
267
+ cacheReadTokens?: number | undefined;
268
+ cacheWriteTokens?: number | undefined;
255
269
  totalTokens?: number | undefined;
256
270
  } | undefined;
271
+ estimatedCost?: number | undefined;
272
+ pricingStatus?: "estimated" | "unpriced" | undefined;
273
+ usageScopeId?: string | undefined;
257
274
  model?: string | undefined;
258
275
  provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "minimax" | "glm" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova" | undefined;
259
276
  toolCalls?: {
@@ -326,14 +343,68 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
326
343
  createdAt: number | null;
327
344
  lastActivity: number | null;
328
345
  isBusy: boolean;
346
+ usageSummary: {
347
+ tokenUsage: {
348
+ inputTokens: number;
349
+ outputTokens: number;
350
+ reasoningTokens: number;
351
+ cacheReadTokens: number;
352
+ cacheWriteTokens: number;
353
+ totalTokens: number;
354
+ };
355
+ estimatedCost: number;
356
+ hasUnpricedResponses: boolean;
357
+ modelStats?: {
358
+ tokenUsage: {
359
+ inputTokens: number;
360
+ outputTokens: number;
361
+ reasoningTokens: number;
362
+ cacheReadTokens: number;
363
+ cacheWriteTokens: number;
364
+ totalTokens: number;
365
+ };
366
+ estimatedCost: number;
367
+ model: string;
368
+ provider: string;
369
+ messageCount: number;
370
+ }[] | undefined;
371
+ };
372
+ activeUsageScopeId: string | null;
373
+ activeUsageScope: {
374
+ tokenUsage: {
375
+ inputTokens: number;
376
+ outputTokens: number;
377
+ reasoningTokens: number;
378
+ cacheReadTokens: number;
379
+ cacheWriteTokens: number;
380
+ totalTokens: number;
381
+ };
382
+ estimatedCost: number;
383
+ hasUnpricedResponses: boolean;
384
+ scopeId: string;
385
+ modelStats?: {
386
+ tokenUsage: {
387
+ inputTokens: number;
388
+ outputTokens: number;
389
+ reasoningTokens: number;
390
+ cacheReadTokens: number;
391
+ cacheWriteTokens: number;
392
+ totalTokens: number;
393
+ };
394
+ estimatedCost: number;
395
+ model: string;
396
+ provider: string;
397
+ messageCount: number;
398
+ }[] | undefined;
399
+ } | null;
329
400
  title?: string | null | undefined;
330
401
  tokenUsage?: {
331
402
  inputTokens: number;
332
403
  outputTokens: number;
333
404
  reasoningTokens: number;
334
- totalTokens: number;
335
405
  cacheReadTokens: number;
336
406
  cacheWriteTokens: number;
407
+ totalTokens: number;
337
408
  } | undefined;
338
409
  estimatedCost?: number | undefined;
339
410
  modelStats?: {
@@ -341,17 +412,20 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
341
412
  inputTokens: number;
342
413
  outputTokens: number;
343
414
  reasoningTokens: number;
344
- totalTokens: number;
345
415
  cacheReadTokens: number;
346
416
  cacheWriteTokens: number;
417
+ totalTokens: number;
347
418
  };
419
+ estimatedCost: number;
348
420
  model: string;
349
421
  provider: string;
350
422
  messageCount: number;
351
- estimatedCost: number;
352
423
  firstUsedAt: number;
353
424
  lastUsedAt: number;
354
425
  }[] | undefined;
426
+ usageTracking?: {
427
+ hasUntrackedChatGPTLoginUsage?: boolean | undefined;
428
+ } | undefined;
355
429
  workspaceId?: string | null | undefined;
356
430
  parentSessionId?: string | null | undefined;
357
431
  };
@@ -371,6 +445,22 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
371
445
  status: 404;
372
446
  };
373
447
  };
448
+ } & {
449
+ "/sessions/:sessionId/clear-context": {
450
+ $post: {
451
+ input: {
452
+ param: {
453
+ sessionId: string;
454
+ };
455
+ };
456
+ output: {
457
+ status: "context cleared";
458
+ sessionId: string;
459
+ };
460
+ outputFormat: "json";
461
+ status: 200;
462
+ };
463
+ };
374
464
  } & {
375
465
  "/sessions/:sessionId": {
376
466
  $patch: {
@@ -394,9 +484,9 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
394
484
  inputTokens: number;
395
485
  outputTokens: number;
396
486
  reasoningTokens: number;
397
- totalTokens: number;
398
487
  cacheReadTokens: number;
399
488
  cacheWriteTokens: number;
489
+ totalTokens: number;
400
490
  } | undefined;
401
491
  estimatedCost?: number | undefined;
402
492
  modelStats?: {
@@ -404,17 +494,20 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
404
494
  inputTokens: number;
405
495
  outputTokens: number;
406
496
  reasoningTokens: number;
407
- totalTokens: number;
408
497
  cacheReadTokens: number;
409
498
  cacheWriteTokens: number;
499
+ totalTokens: number;
410
500
  };
501
+ estimatedCost: number;
411
502
  model: string;
412
503
  provider: string;
413
504
  messageCount: number;
414
- estimatedCost: number;
415
505
  firstUsedAt: number;
416
506
  lastUsedAt: number;
417
507
  }[] | undefined;
508
+ usageTracking?: {
509
+ hasUntrackedChatGPTLoginUsage?: boolean | undefined;
510
+ } | undefined;
418
511
  workspaceId?: string | null | undefined;
419
512
  parentSessionId?: string | null | undefined;
420
513
  };
@@ -1 +1 @@
1
- {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAOhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA+B9C,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA8fxD"}
1
+ {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAYhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAqC9C,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAwjBxD"}
@@ -1,8 +1,13 @@
1
1
  import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
2
+ import {
3
+ getConfiguredUsageScopeId
4
+ } from "@dexto/core";
2
5
  import {
3
6
  SessionMetadataSchema,
4
7
  InternalMessageSchema,
5
- StandardErrorEnvelopeSchema
8
+ ScopedUsageSummarySchema,
9
+ StandardErrorEnvelopeSchema,
10
+ UsageSummarySchema
6
11
  } from "../schemas/responses.js";
7
12
  const CreateSessionSchema = z.object({
8
13
  sessionId: z.string().optional().describe("A custom ID for the new session")
@@ -14,6 +19,12 @@ function mapSessionMetadata(sessionId, metadata, defaults) {
14
19
  lastActivity: metadata?.lastActivity ?? defaults?.lastActivity ?? null,
15
20
  messageCount: metadata?.messageCount ?? defaults?.messageCount ?? 0,
16
21
  title: metadata?.title ?? defaults?.title ?? null,
22
+ ...metadata?.tokenUsage && { tokenUsage: metadata.tokenUsage },
23
+ ...metadata?.estimatedCost !== void 0 && {
24
+ estimatedCost: metadata.estimatedCost
25
+ },
26
+ ...metadata?.modelStats && { modelStats: metadata.modelStats },
27
+ ...metadata?.usageTracking && { usageTracking: metadata.usageTracking },
17
28
  workspaceId: metadata?.workspaceId ?? defaults?.workspaceId ?? null,
18
29
  parentSessionId: metadata?.parentSessionId ?? defaults?.parentSessionId ?? null
19
30
  };
@@ -226,6 +237,15 @@ function createSessionsRouter(getAgent) {
226
237
  session: SessionMetadataSchema.extend({
227
238
  isBusy: z.boolean().describe(
228
239
  "Whether the session is currently processing a message"
240
+ ),
241
+ usageSummary: UsageSummarySchema.describe(
242
+ "Exact usage summary derived from assistant message history"
243
+ ),
244
+ activeUsageScopeId: z.string().nullable().describe(
245
+ "Current runtime usage scope identifier, if configured"
246
+ ),
247
+ activeUsageScope: ScopedUsageSummarySchema.nullable().describe(
248
+ "Usage summary for the current runtime scope, if configured"
229
249
  )
230
250
  }).describe("Session metadata with processing status")
231
251
  }).strict()
@@ -244,6 +264,29 @@ function createSessionsRouter(getAgent) {
244
264
  }
245
265
  }
246
266
  });
267
+ const clearContextRoute = createRoute({
268
+ method: "post",
269
+ path: "/sessions/{sessionId}/clear-context",
270
+ summary: "Clear Session Context",
271
+ description: "Clears the model context window for a session while preserving conversation history for review.",
272
+ tags: ["sessions"],
273
+ request: {
274
+ params: z.object({ sessionId: z.string().describe("Session identifier") })
275
+ },
276
+ responses: {
277
+ 200: {
278
+ description: "Session context cleared successfully",
279
+ content: {
280
+ "application/json": {
281
+ schema: z.object({
282
+ status: z.literal("context cleared").describe("Context clear status"),
283
+ sessionId: z.string().describe("Session ID")
284
+ }).strict()
285
+ }
286
+ }
287
+ }
288
+ }
289
+ });
247
290
  const patchRoute = createRoute({
248
291
  method: "patch",
249
292
  path: "/sessions/{sessionId}",
@@ -405,15 +448,29 @@ function createSessionsRouter(getAgent) {
405
448
  }
406
449
  const metadata = await agent.getSessionMetadata(sessionId);
407
450
  const isBusy = await agent.isSessionBusy(sessionId);
451
+ const usageSummary = await agent.getSessionUsageSummary(sessionId);
452
+ const activeUsageScopeId = getConfiguredUsageScopeId() ?? null;
453
+ const activeUsageScope = activeUsageScopeId ? {
454
+ scopeId: activeUsageScopeId,
455
+ ...await agent.getSessionUsageSummary(sessionId, activeUsageScopeId)
456
+ } : null;
408
457
  return ctx.json(
409
458
  {
410
459
  session: {
411
460
  ...mapSessionMetadata(sessionId, metadata),
412
- isBusy
461
+ isBusy,
462
+ usageSummary,
463
+ activeUsageScopeId,
464
+ activeUsageScope
413
465
  }
414
466
  },
415
467
  200
416
468
  );
469
+ }).openapi(clearContextRoute, async (ctx) => {
470
+ const agent = await getAgent(ctx);
471
+ const { sessionId } = ctx.req.valid("param");
472
+ await agent.clearContext(sessionId);
473
+ return ctx.json({ status: "context cleared", sessionId });
417
474
  }).openapi(patchRoute, async (ctx) => {
418
475
  const agent = await getAgent(ctx);
419
476
  const { sessionId } = ctx.req.valid("param");
@@ -39,6 +39,7 @@ __export(responses_exports, {
39
39
  ModelStatisticsSchema: () => ModelStatisticsSchema,
40
40
  OkResponseSchema: () => OkResponseSchema,
41
41
  PermissionsConfigSchema: () => import_core6.PermissionsConfigSchema,
42
+ PricingStatusSchema: () => PricingStatusSchema,
42
43
  PromptArgumentSchema: () => PromptArgumentSchema,
43
44
  PromptDefinitionSchema: () => PromptDefinitionSchema,
44
45
  PromptInfoSchema: () => PromptInfoSchema,
@@ -48,11 +49,13 @@ __export(responses_exports, {
48
49
  ResourceSchema: () => ResourceSchema,
49
50
  ScheduleSchema: () => ScheduleSchema,
50
51
  ScheduleTaskSchema: () => ScheduleTaskSchema,
52
+ ScopedUsageSummarySchema: () => ScopedUsageSummarySchema,
51
53
  SearchResultSchema: () => SearchResultSchema,
52
54
  SessionMetadataSchema: () => SessionMetadataSchema,
53
55
  SessionSearchResponseSchema: () => SessionSearchResponseSchema,
54
56
  SessionSearchResultSchema: () => SessionSearchResultSchema,
55
57
  SessionTokenUsageSchema: () => SessionTokenUsageSchema,
58
+ SessionUsageTrackingSchema: () => SessionUsageTrackingSchema,
56
59
  SseServerConfigSchema: () => import_core5.SseServerConfigSchema,
57
60
  StandardErrorEnvelopeSchema: () => StandardErrorEnvelopeSchema,
58
61
  StatusResponseSchema: () => StatusResponseSchema,
@@ -62,6 +65,7 @@ __export(responses_exports, {
62
65
  ToolCallSchema: () => ToolCallSchema,
63
66
  ToolSchema: () => ToolSchema,
64
67
  UIResourcePartSchema: () => UIResourcePartSchema,
68
+ UsageSummarySchema: () => UsageSummarySchema,
65
69
  WebhookSchema: () => WebhookSchema,
66
70
  WorkspaceSchema: () => WorkspaceSchema
67
71
  });
@@ -121,8 +125,11 @@ const TokenUsageSchema = import_zod.z.object({
121
125
  inputTokens: import_zod.z.number().int().nonnegative().optional().describe("Number of input tokens"),
122
126
  outputTokens: import_zod.z.number().int().nonnegative().optional().describe("Number of output tokens"),
123
127
  reasoningTokens: import_zod.z.number().int().nonnegative().optional().describe("Number of reasoning tokens"),
128
+ cacheReadTokens: import_zod.z.number().int().nonnegative().optional().describe("Number of cache read tokens"),
129
+ cacheWriteTokens: import_zod.z.number().int().nonnegative().optional().describe("Number of cache write tokens"),
124
130
  totalTokens: import_zod.z.number().int().nonnegative().optional().describe("Total tokens used")
125
131
  }).strict().describe("Token usage accounting");
132
+ const PricingStatusSchema = import_zod.z.enum(import_core.LLM_PRICING_STATUSES).describe("Whether pricing was resolved for this response");
126
133
  const InternalMessageSchema = import_zod.z.object({
127
134
  id: import_zod.z.string().uuid().optional().describe("Unique message identifier (UUID)"),
128
135
  role: import_zod.z.enum(["system", "user", "assistant", "tool"]).describe("Role of the message sender"),
@@ -130,6 +137,11 @@ const InternalMessageSchema = import_zod.z.object({
130
137
  content: import_zod.z.union([import_zod.z.string(), import_zod.z.null(), import_zod.z.array(ContentPartSchema)]).describe("Message content (string, null, or array of parts)"),
131
138
  reasoning: import_zod.z.string().optional().describe("Optional model reasoning text"),
132
139
  tokenUsage: TokenUsageSchema.optional().describe("Optional token usage accounting"),
140
+ estimatedCost: import_zod.z.number().nonnegative().optional().describe("Estimated cost in USD for this response"),
141
+ pricingStatus: PricingStatusSchema.optional().describe(
142
+ "Whether pricing was resolved for this response"
143
+ ),
144
+ usageScopeId: import_zod.z.string().optional().describe("Optional usage scope identifier for runtime-scoped metering"),
133
145
  model: import_zod.z.string().optional().describe("Model identifier for assistant messages"),
134
146
  provider: import_zod.z.enum(import_core.LLM_PROVIDERS).optional().describe("Provider identifier for assistant messages"),
135
147
  toolCalls: import_zod.z.array(ToolCallSchema).optional().describe("Tool calls made by the assistant"),
@@ -141,14 +153,12 @@ const LLMConfigResponseSchema = import_core.LLMConfigBaseSchema.omit({ apiKey: t
141
153
  hasApiKey: import_zod.z.boolean().optional().describe("Whether an API key is configured")
142
154
  }).describe("LLM configuration (apiKey omitted for security)");
143
155
  const LLMConfigSchema = import_core.LLMConfigBaseSchema.describe("LLM configuration with API key");
144
- const SessionTokenUsageSchema = import_zod.z.object({
145
- inputTokens: import_zod.z.number().int().nonnegative().describe("Number of input tokens"),
146
- outputTokens: import_zod.z.number().int().nonnegative().describe("Number of output tokens"),
147
- reasoningTokens: import_zod.z.number().int().nonnegative().describe("Number of reasoning tokens"),
148
- cacheReadTokens: import_zod.z.number().int().nonnegative().describe("Number of cache read tokens"),
149
- cacheWriteTokens: import_zod.z.number().int().nonnegative().describe("Number of cache write tokens"),
150
- totalTokens: import_zod.z.number().int().nonnegative().describe("Total tokens used")
151
- }).strict().describe("Session-level token usage (all fields required for cumulative totals)");
156
+ const SessionTokenUsageSchema = TokenUsageSchema.required().describe(
157
+ "Session-level token usage (all fields required for cumulative totals)"
158
+ );
159
+ const SessionUsageTrackingSchema = import_zod.z.object({
160
+ hasUntrackedChatGPTLoginUsage: import_zod.z.boolean().optional().describe("Whether this session includes known untracked ChatGPT Login usage")
161
+ }).strict().describe("Usage tracking caveats for a session");
152
162
  const ModelStatisticsSchema = import_zod.z.object({
153
163
  provider: import_zod.z.string().describe("LLM provider identifier"),
154
164
  model: import_zod.z.string().describe("Model identifier"),
@@ -158,6 +168,29 @@ const ModelStatisticsSchema = import_zod.z.object({
158
168
  firstUsedAt: import_zod.z.number().int().positive().describe("First use timestamp (Unix ms)"),
159
169
  lastUsedAt: import_zod.z.number().int().positive().describe("Last use timestamp (Unix ms)")
160
170
  }).strict().describe("Per-model statistics within a session");
171
+ const UsageSummarySchema = import_zod.z.object({
172
+ tokenUsage: SessionTokenUsageSchema.describe(
173
+ "Aggregate token usage for the selected scope"
174
+ ),
175
+ estimatedCost: import_zod.z.number().nonnegative().describe("Total estimated cost in USD for the selected scope"),
176
+ hasUnpricedResponses: import_zod.z.boolean().describe(
177
+ "Whether any response in the selected scope has usage but no resolved pricing"
178
+ ),
179
+ modelStats: import_zod.z.array(
180
+ import_zod.z.object({
181
+ provider: import_zod.z.string().describe("LLM provider identifier"),
182
+ model: import_zod.z.string().describe("Model identifier"),
183
+ messageCount: import_zod.z.number().int().nonnegative().describe("Number of responses using this model in the selected scope"),
184
+ tokenUsage: SessionTokenUsageSchema.describe(
185
+ "Token usage for this model in the selected scope"
186
+ ),
187
+ estimatedCost: import_zod.z.number().nonnegative().describe("Estimated cost in USD for this model in the selected scope")
188
+ }).strict()
189
+ ).optional().describe("Per-model usage statistics within the selected scope")
190
+ }).strict().describe("Usage summary for a session or session scope");
191
+ const ScopedUsageSummarySchema = UsageSummarySchema.extend({
192
+ scopeId: import_zod.z.string().describe("Usage scope identifier")
193
+ }).strict().describe("Usage summary for a specific scope within a session");
161
194
  const SessionMetadataSchema = import_zod.z.object({
162
195
  id: import_zod.z.string().describe("Unique session identifier"),
163
196
  createdAt: import_zod.z.number().int().positive().nullable().describe("Creation timestamp (Unix ms, null if unavailable)"),
@@ -169,6 +202,9 @@ const SessionMetadataSchema = import_zod.z.object({
169
202
  ),
170
203
  estimatedCost: import_zod.z.number().nonnegative().optional().describe("Total estimated cost in USD across all models"),
171
204
  modelStats: import_zod.z.array(ModelStatisticsSchema).optional().describe("Per-model usage statistics (for multi-model sessions)"),
205
+ usageTracking: SessionUsageTrackingSchema.optional().describe(
206
+ "Known caveats or gaps in usage tracking for this session"
207
+ ),
172
208
  workspaceId: import_zod.z.string().optional().nullable().describe("Associated workspace ID, if any"),
173
209
  parentSessionId: import_zod.z.string().optional().nullable().describe("Parent session ID if this session was forked, otherwise null")
174
210
  }).strict().describe("Session metadata");
@@ -379,6 +415,7 @@ const DeleteResponseSchema = import_zod.z.object({
379
415
  ModelStatisticsSchema,
380
416
  OkResponseSchema,
381
417
  PermissionsConfigSchema,
418
+ PricingStatusSchema,
382
419
  PromptArgumentSchema,
383
420
  PromptDefinitionSchema,
384
421
  PromptInfoSchema,
@@ -388,11 +425,13 @@ const DeleteResponseSchema = import_zod.z.object({
388
425
  ResourceSchema,
389
426
  ScheduleSchema,
390
427
  ScheduleTaskSchema,
428
+ ScopedUsageSummarySchema,
391
429
  SearchResultSchema,
392
430
  SessionMetadataSchema,
393
431
  SessionSearchResponseSchema,
394
432
  SessionSearchResultSchema,
395
433
  SessionTokenUsageSchema,
434
+ SessionUsageTrackingSchema,
396
435
  SseServerConfigSchema,
397
436
  StandardErrorEnvelopeSchema,
398
437
  StatusResponseSchema,
@@ -402,6 +441,7 @@ const DeleteResponseSchema = import_zod.z.object({
402
441
  ToolCallSchema,
403
442
  ToolSchema,
404
443
  UIResourcePartSchema,
444
+ UsageSummarySchema,
405
445
  WebhookSchema,
406
446
  WorkspaceSchema
407
447
  });