@dexto/server 1.6.16 → 1.6.18

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 (42) 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/__tests__/test-fixtures.cjs +3 -2
  13. package/dist/hono/__tests__/test-fixtures.d.ts +6 -2
  14. package/dist/hono/__tests__/test-fixtures.d.ts.map +1 -1
  15. package/dist/hono/__tests__/test-fixtures.js +3 -2
  16. package/dist/hono/index.d.ts +245 -33
  17. package/dist/hono/index.d.ts.map +1 -1
  18. package/dist/hono/routes/a2a-tasks.d.ts +9 -9
  19. package/dist/hono/routes/approvals.cjs +94 -6
  20. package/dist/hono/routes/approvals.d.ts +22 -6
  21. package/dist/hono/routes/approvals.d.ts.map +1 -1
  22. package/dist/hono/routes/approvals.js +94 -6
  23. package/dist/hono/routes/messages.cjs +16 -5
  24. package/dist/hono/routes/messages.d.ts +6 -0
  25. package/dist/hono/routes/messages.d.ts.map +1 -1
  26. package/dist/hono/routes/messages.js +17 -6
  27. package/dist/hono/routes/search.d.ts +10 -0
  28. package/dist/hono/routes/search.d.ts.map +1 -1
  29. package/dist/hono/routes/sessions.cjs +251 -2
  30. package/dist/hono/routes/sessions.d.ts +198 -18
  31. package/dist/hono/routes/sessions.d.ts.map +1 -1
  32. package/dist/hono/routes/sessions.js +259 -3
  33. package/dist/hono/routes/system-prompt.d.ts +1 -1
  34. package/dist/hono/schemas/responses.cjs +48 -8
  35. package/dist/hono/schemas/responses.d.ts +489 -22
  36. package/dist/hono/schemas/responses.d.ts.map +1 -1
  37. package/dist/hono/schemas/responses.js +49 -9
  38. package/dist/index.cjs +4 -0
  39. package/dist/index.d.ts +2 -0
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +2 -0
  42. package/package.json +9 -9
@@ -45,6 +45,7 @@ export declare function createSearchRouter(getAgent: GetAgentFn): OpenAPIHono<im
45
45
  } | undefined;
46
46
  })[] | null;
47
47
  role: "system" | "user" | "assistant" | "tool";
48
+ usageScopeId?: string | undefined;
48
49
  id?: string | undefined;
49
50
  name?: string | undefined;
50
51
  timestamp?: number | undefined;
@@ -53,8 +54,12 @@ export declare function createSearchRouter(getAgent: GetAgentFn): OpenAPIHono<im
53
54
  inputTokens?: number | undefined;
54
55
  outputTokens?: number | undefined;
55
56
  reasoningTokens?: number | undefined;
57
+ cacheReadTokens?: number | undefined;
58
+ cacheWriteTokens?: number | undefined;
56
59
  totalTokens?: number | undefined;
57
60
  } | undefined;
61
+ estimatedCost?: number | undefined;
62
+ pricingStatus?: "estimated" | "unpriced" | undefined;
58
63
  model?: string | undefined;
59
64
  provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "minimax" | "glm" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova" | undefined;
60
65
  toolCalls?: {
@@ -127,6 +132,7 @@ export declare function createSearchRouter(getAgent: GetAgentFn): OpenAPIHono<im
127
132
  } | undefined;
128
133
  })[] | null;
129
134
  role: "system" | "user" | "assistant" | "tool";
135
+ usageScopeId?: string | undefined;
130
136
  id?: string | undefined;
131
137
  name?: string | undefined;
132
138
  timestamp?: number | undefined;
@@ -135,8 +141,12 @@ export declare function createSearchRouter(getAgent: GetAgentFn): OpenAPIHono<im
135
141
  inputTokens?: number | undefined;
136
142
  outputTokens?: number | undefined;
137
143
  reasoningTokens?: number | undefined;
144
+ cacheReadTokens?: number | undefined;
145
+ cacheWriteTokens?: number | undefined;
138
146
  totalTokens?: number | undefined;
139
147
  } | undefined;
148
+ estimatedCost?: number | undefined;
149
+ pricingStatus?: "estimated" | "unpriced" | undefined;
140
150
  model?: string | undefined;
141
151
  provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "minimax" | "glm" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova" | undefined;
142
152
  toolCalls?: {
@@ -1 +1 @@
1
- {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AA0BrE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAwDtD"}
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AA0BrE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAwDtD"}
@@ -22,10 +22,35 @@ __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");
27
+ var import_error = require("../middleware/error.js");
26
28
  const CreateSessionSchema = import_zod_openapi.z.object({
27
29
  sessionId: import_zod_openapi.z.string().optional().describe("A custom ID for the new session")
28
30
  }).describe("Request body for creating a new session");
31
+ const MAX_SYSTEM_PROMPT_CONTRIBUTOR_CONTENT_CHARS = 12e4;
32
+ const DEFAULT_SYSTEM_PROMPT_CONTRIBUTOR_PRIORITY = 45;
33
+ const SessionPromptContributorInfoSchema = import_zod_openapi.z.object({
34
+ id: import_zod_openapi.z.string().describe("Contributor identifier"),
35
+ priority: import_zod_openapi.z.number().describe("Contributor priority")
36
+ }).strict().describe("Session-scoped system prompt contributor metadata.");
37
+ const UpsertSessionPromptContributorSchema = import_zod_openapi.z.object({
38
+ id: import_zod_openapi.z.string().min(1).describe("Contributor identifier"),
39
+ priority: import_zod_openapi.z.number().int().nonnegative().optional().default(DEFAULT_SYSTEM_PROMPT_CONTRIBUTOR_PRIORITY).describe("Optional priority override"),
40
+ enabled: import_zod_openapi.z.boolean().default(true).describe("Set false to remove the contributor instead of adding or updating it"),
41
+ content: import_zod_openapi.z.string().optional().describe("Static contributor content for this session (required when enabled)")
42
+ }).strict().superRefine((value, ctx) => {
43
+ if (value.enabled !== false && (!value.content || value.content.trim().length === 0)) {
44
+ ctx.addIssue({
45
+ code: import_zod_openapi.z.ZodIssueCode.custom,
46
+ path: ["content"],
47
+ message: "Contributor content is required when enabled"
48
+ });
49
+ }
50
+ }).describe("Session-scoped system prompt contributor update payload.");
51
+ function sanitizeContributorId(value) {
52
+ return value.trim().replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
53
+ }
29
54
  function mapSessionMetadata(sessionId, metadata, defaults) {
30
55
  return {
31
56
  id: sessionId,
@@ -33,12 +58,35 @@ function mapSessionMetadata(sessionId, metadata, defaults) {
33
58
  lastActivity: metadata?.lastActivity ?? defaults?.lastActivity ?? null,
34
59
  messageCount: metadata?.messageCount ?? defaults?.messageCount ?? 0,
35
60
  title: metadata?.title ?? defaults?.title ?? null,
61
+ ...metadata?.tokenUsage && { tokenUsage: metadata.tokenUsage },
62
+ ...metadata?.estimatedCost !== void 0 && {
63
+ estimatedCost: metadata.estimatedCost
64
+ },
65
+ ...metadata?.modelStats && { modelStats: metadata.modelStats },
66
+ ...metadata?.usageTracking && { usageTracking: metadata.usageTracking },
36
67
  workspaceId: metadata?.workspaceId ?? defaults?.workspaceId ?? null,
37
68
  parentSessionId: metadata?.parentSessionId ?? defaults?.parentSessionId ?? null
38
69
  };
39
70
  }
40
71
  function createSessionsRouter(getAgent) {
41
- const app = new import_zod_openapi.OpenAPIHono();
72
+ const app = new import_zod_openapi.OpenAPIHono({
73
+ defaultHook: (result, ctx) => {
74
+ if (!result.success) {
75
+ const issues = (0, import_core.zodToIssues)(result.error);
76
+ return (0, import_error.handleHonoError)(
77
+ ctx,
78
+ new import_core.DextoRuntimeError(
79
+ "validation_failed",
80
+ "validation",
81
+ import_core.ErrorType.USER,
82
+ issues[0]?.message ?? "Validation failed",
83
+ { issues }
84
+ )
85
+ );
86
+ }
87
+ }
88
+ });
89
+ app.onError((err, ctx) => (0, import_error.handleHonoError)(ctx, err));
42
90
  const listRoute = (0, import_zod_openapi.createRoute)({
43
91
  method: "get",
44
92
  path: "/sessions",
@@ -167,6 +215,86 @@ function createSessionsRouter(getAgent) {
167
215
  }
168
216
  }
169
217
  });
218
+ const listSessionPromptContributorsRoute = (0, import_zod_openapi.createRoute)({
219
+ method: "get",
220
+ path: "/sessions/{sessionId}/system-prompt/contributors",
221
+ summary: "List Session System Prompt Contributors",
222
+ description: "Lists static system prompt contributors that apply only to the specified session.",
223
+ tags: ["sessions", "config"],
224
+ request: { params: import_zod_openapi.z.object({ sessionId: import_zod_openapi.z.string().describe("Session identifier") }) },
225
+ responses: {
226
+ 200: {
227
+ description: "Current session contributor list",
228
+ content: {
229
+ "application/json": {
230
+ schema: import_zod_openapi.z.object({
231
+ contributors: import_zod_openapi.z.array(SessionPromptContributorInfoSchema).describe("Registered session prompt contributors.")
232
+ }).strict()
233
+ }
234
+ }
235
+ },
236
+ 404: {
237
+ description: "Session not found",
238
+ content: {
239
+ "application/json": {
240
+ schema: import_responses.StandardErrorEnvelopeSchema
241
+ }
242
+ }
243
+ }
244
+ }
245
+ });
246
+ const upsertSessionPromptContributorRoute = (0, import_zod_openapi.createRoute)({
247
+ method: "post",
248
+ path: "/sessions/{sessionId}/system-prompt/contributors",
249
+ summary: "Upsert Session System Prompt Contributor",
250
+ description: "Adds or updates a static system prompt contributor that applies only to the specified session. Set enabled=false to remove it.",
251
+ tags: ["sessions", "config"],
252
+ request: {
253
+ params: import_zod_openapi.z.object({ sessionId: import_zod_openapi.z.string().describe("Session identifier") }),
254
+ body: {
255
+ required: true,
256
+ content: {
257
+ "application/json": {
258
+ schema: UpsertSessionPromptContributorSchema
259
+ }
260
+ }
261
+ }
262
+ },
263
+ responses: {
264
+ 200: {
265
+ description: "Session contributor upsert result",
266
+ content: {
267
+ "application/json": {
268
+ schema: import_zod_openapi.z.object({
269
+ id: import_zod_openapi.z.string().describe("Contributor identifier"),
270
+ enabled: import_zod_openapi.z.boolean().describe("Whether the contributor remains enabled"),
271
+ priority: import_zod_openapi.z.number().optional().describe("Contributor priority"),
272
+ replaced: import_zod_openapi.z.boolean().optional().describe("Whether an existing contributor was replaced"),
273
+ removed: import_zod_openapi.z.boolean().optional().describe("Whether the contributor was removed"),
274
+ contentLength: import_zod_openapi.z.number().optional().describe("Stored content length in characters"),
275
+ truncated: import_zod_openapi.z.boolean().optional().describe("Whether the submitted content was truncated")
276
+ }).strict()
277
+ }
278
+ }
279
+ },
280
+ 400: {
281
+ description: "Invalid session contributor request",
282
+ content: {
283
+ "application/json": {
284
+ schema: import_responses.StandardErrorEnvelopeSchema
285
+ }
286
+ }
287
+ },
288
+ 404: {
289
+ description: "Session not found",
290
+ content: {
291
+ "application/json": {
292
+ schema: import_responses.StandardErrorEnvelopeSchema
293
+ }
294
+ }
295
+ }
296
+ }
297
+ });
170
298
  const deleteRoute = (0, import_zod_openapi.createRoute)({
171
299
  method: "delete",
172
300
  path: "/sessions/{sessionId}",
@@ -245,6 +373,15 @@ function createSessionsRouter(getAgent) {
245
373
  session: import_responses.SessionMetadataSchema.extend({
246
374
  isBusy: import_zod_openapi.z.boolean().describe(
247
375
  "Whether the session is currently processing a message"
376
+ ),
377
+ usageSummary: import_responses.UsageSummarySchema.describe(
378
+ "Exact usage summary derived from assistant message history"
379
+ ),
380
+ activeUsageScopeId: import_zod_openapi.z.string().nullable().describe(
381
+ "Current runtime usage scope identifier, if configured"
382
+ ),
383
+ activeUsageScope: import_responses.ScopedUsageSummarySchema.nullable().describe(
384
+ "Usage summary for the current runtime scope, if configured"
248
385
  )
249
386
  }).describe("Session metadata with processing status")
250
387
  }).strict()
@@ -263,6 +400,29 @@ function createSessionsRouter(getAgent) {
263
400
  }
264
401
  }
265
402
  });
403
+ const clearContextRoute = (0, import_zod_openapi.createRoute)({
404
+ method: "post",
405
+ path: "/sessions/{sessionId}/clear-context",
406
+ summary: "Clear Session Context",
407
+ description: "Clears the model context window for a session while preserving conversation history for review.",
408
+ tags: ["sessions"],
409
+ request: {
410
+ params: import_zod_openapi.z.object({ sessionId: import_zod_openapi.z.string().describe("Session identifier") })
411
+ },
412
+ responses: {
413
+ 200: {
414
+ description: "Session context cleared successfully",
415
+ content: {
416
+ "application/json": {
417
+ schema: import_zod_openapi.z.object({
418
+ status: import_zod_openapi.z.literal("context cleared").describe("Context clear status"),
419
+ sessionId: import_zod_openapi.z.string().describe("Session ID")
420
+ }).strict()
421
+ }
422
+ }
423
+ }
424
+ }
425
+ });
266
426
  const patchRoute = (0, import_zod_openapi.createRoute)({
267
427
  method: "patch",
268
428
  path: "/sessions/{sessionId}",
@@ -381,6 +541,81 @@ function createSessionsRouter(getAgent) {
381
541
  history,
382
542
  isBusy
383
543
  });
544
+ }).openapi(listSessionPromptContributorsRoute, async (ctx) => {
545
+ const agent = await getAgent(ctx);
546
+ const { sessionId } = ctx.req.valid("param");
547
+ const contributors = await agent.getSessionSystemPromptContributors(sessionId);
548
+ return ctx.json(
549
+ {
550
+ contributors: contributors.map((contributor) => ({
551
+ id: contributor.id,
552
+ priority: contributor.priority
553
+ }))
554
+ },
555
+ 200
556
+ );
557
+ }).openapi(upsertSessionPromptContributorRoute, async (ctx) => {
558
+ const agent = await getAgent(ctx);
559
+ const { sessionId } = ctx.req.valid("param");
560
+ const payload = ctx.req.valid("json");
561
+ const contributorId = sanitizeContributorId(payload.id);
562
+ if (contributorId.length === 0) {
563
+ throw new import_core.DextoRuntimeError(
564
+ "session_systemprompt_contributor_config_invalid",
565
+ import_core.ErrorScope.SYSTEM_PROMPT,
566
+ import_core.ErrorType.USER,
567
+ "A valid contributor id is required",
568
+ {
569
+ id: payload.id,
570
+ sessionId
571
+ }
572
+ );
573
+ }
574
+ const rawContent = payload.content ?? "";
575
+ const content = rawContent.slice(0, MAX_SYSTEM_PROMPT_CONTRIBUTOR_CONTENT_CHARS);
576
+ if (!payload.enabled) {
577
+ const removed = await agent.removeSessionSystemPromptContributor(
578
+ sessionId,
579
+ contributorId
580
+ );
581
+ return ctx.json(
582
+ {
583
+ id: contributorId,
584
+ enabled: false,
585
+ removed
586
+ },
587
+ 200
588
+ );
589
+ }
590
+ if (content.trim().length === 0) {
591
+ throw new import_core.DextoRuntimeError(
592
+ "session_systemprompt_contributor_config_invalid",
593
+ import_core.ErrorScope.SYSTEM_PROMPT,
594
+ import_core.ErrorType.USER,
595
+ "Contributor content is required when enabled",
596
+ {
597
+ id: payload.id,
598
+ sessionId
599
+ }
600
+ );
601
+ }
602
+ const priority = payload.priority;
603
+ const result = await agent.upsertSessionSystemPromptContributor(sessionId, {
604
+ id: contributorId,
605
+ priority,
606
+ content
607
+ });
608
+ return ctx.json(
609
+ {
610
+ id: contributorId,
611
+ enabled: true,
612
+ priority,
613
+ replaced: result.replaced,
614
+ contentLength: content.length,
615
+ truncated: rawContent.length > content.length
616
+ },
617
+ 200
618
+ );
384
619
  }).openapi(deleteRoute, async (ctx) => {
385
620
  const agent = await getAgent(ctx);
386
621
  const { sessionId } = ctx.req.param();
@@ -424,15 +659,29 @@ function createSessionsRouter(getAgent) {
424
659
  }
425
660
  const metadata = await agent.getSessionMetadata(sessionId);
426
661
  const isBusy = await agent.isSessionBusy(sessionId);
662
+ const usageSummary = await agent.getSessionUsageSummary(sessionId);
663
+ const activeUsageScopeId = agent.getEffectiveConfig().usageScopeId ?? null;
664
+ const activeUsageScope = activeUsageScopeId ? {
665
+ scopeId: activeUsageScopeId,
666
+ ...await agent.getSessionUsageSummary(sessionId, activeUsageScopeId)
667
+ } : null;
427
668
  return ctx.json(
428
669
  {
429
670
  session: {
430
671
  ...mapSessionMetadata(sessionId, metadata),
431
- isBusy
672
+ isBusy,
673
+ usageSummary,
674
+ activeUsageScopeId,
675
+ activeUsageScope
432
676
  }
433
677
  },
434
678
  200
435
679
  );
680
+ }).openapi(clearContextRoute, async (ctx) => {
681
+ const agent = await getAgent(ctx);
682
+ const { sessionId } = ctx.req.valid("param");
683
+ await agent.clearContext(sessionId);
684
+ return ctx.json({ status: "context cleared", sessionId });
436
685
  }).openapi(patchRoute, async (ctx) => {
437
686
  const agent = await getAgent(ctx);
438
687
  const { sessionId } = ctx.req.valid("param");