@dexto/server 1.6.7 → 1.6.9

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.
@@ -37,6 +37,7 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
37
37
  lastUsedAt: number;
38
38
  }[] | undefined;
39
39
  workspaceId?: string | null | undefined;
40
+ parentSessionId?: string | null | undefined;
40
41
  }[];
41
42
  };
42
43
  outputFormat: "json";
@@ -84,12 +85,79 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
84
85
  lastUsedAt: number;
85
86
  }[] | undefined;
86
87
  workspaceId?: string | null | undefined;
88
+ parentSessionId?: string | null | undefined;
87
89
  };
88
90
  };
89
91
  outputFormat: "json";
90
92
  status: 201;
91
93
  };
92
94
  };
95
+ } & {
96
+ "/sessions/:sessionId/fork": {
97
+ $post: {
98
+ input: {
99
+ param: {
100
+ sessionId: string;
101
+ };
102
+ };
103
+ output: {
104
+ session: {
105
+ id: string;
106
+ messageCount: number;
107
+ createdAt: number | null;
108
+ lastActivity: number | null;
109
+ title?: string | null | undefined;
110
+ tokenUsage?: {
111
+ inputTokens: number;
112
+ outputTokens: number;
113
+ reasoningTokens: number;
114
+ totalTokens: number;
115
+ cacheReadTokens: number;
116
+ cacheWriteTokens: number;
117
+ } | undefined;
118
+ estimatedCost?: number | undefined;
119
+ modelStats?: {
120
+ tokenUsage: {
121
+ inputTokens: number;
122
+ outputTokens: number;
123
+ reasoningTokens: number;
124
+ totalTokens: number;
125
+ cacheReadTokens: number;
126
+ cacheWriteTokens: number;
127
+ };
128
+ model: string;
129
+ provider: string;
130
+ messageCount: number;
131
+ estimatedCost: number;
132
+ firstUsedAt: number;
133
+ lastUsedAt: number;
134
+ }[] | undefined;
135
+ workspaceId?: string | null | undefined;
136
+ parentSessionId?: string | null | undefined;
137
+ };
138
+ };
139
+ outputFormat: "json";
140
+ status: 201;
141
+ } | {
142
+ input: {
143
+ param: {
144
+ sessionId: string;
145
+ };
146
+ };
147
+ output: never;
148
+ outputFormat: "json";
149
+ status: 400;
150
+ } | {
151
+ input: {
152
+ param: {
153
+ sessionId: string;
154
+ };
155
+ };
156
+ output: never;
157
+ outputFormat: "json";
158
+ status: 404;
159
+ };
160
+ };
93
161
  } & {
94
162
  "/sessions/:sessionId": {
95
163
  $get: {
@@ -132,6 +200,7 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
132
200
  lastUsedAt: number;
133
201
  }[] | undefined;
134
202
  workspaceId?: string | null | undefined;
203
+ parentSessionId?: string | null | undefined;
135
204
  };
136
205
  };
137
206
  outputFormat: "json";
@@ -284,6 +353,7 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
284
353
  lastUsedAt: number;
285
354
  }[] | undefined;
286
355
  workspaceId?: string | null | undefined;
356
+ parentSessionId?: string | null | undefined;
287
357
  };
288
358
  };
289
359
  outputFormat: "json";
@@ -346,6 +416,7 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
346
416
  lastUsedAt: number;
347
417
  }[] | undefined;
348
418
  workspaceId?: string | null | undefined;
419
+ parentSessionId?: string | null | undefined;
349
420
  };
350
421
  };
351
422
  outputFormat: "json";
@@ -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;AAEhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAQ9C,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAuexD"}
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,8 +1,23 @@
1
1
  import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
2
- import { SessionMetadataSchema, InternalMessageSchema } from "../schemas/responses.js";
2
+ import {
3
+ SessionMetadataSchema,
4
+ InternalMessageSchema,
5
+ StandardErrorEnvelopeSchema
6
+ } from "../schemas/responses.js";
3
7
  const CreateSessionSchema = z.object({
4
8
  sessionId: z.string().optional().describe("A custom ID for the new session")
5
9
  }).describe("Request body for creating a new session");
10
+ function mapSessionMetadata(sessionId, metadata, defaults) {
11
+ return {
12
+ id: sessionId,
13
+ createdAt: metadata?.createdAt ?? defaults?.createdAt ?? null,
14
+ lastActivity: metadata?.lastActivity ?? defaults?.lastActivity ?? null,
15
+ messageCount: metadata?.messageCount ?? defaults?.messageCount ?? 0,
16
+ title: metadata?.title ?? defaults?.title ?? null,
17
+ workspaceId: metadata?.workspaceId ?? defaults?.workspaceId ?? null,
18
+ parentSessionId: metadata?.parentSessionId ?? defaults?.parentSessionId ?? null
19
+ };
20
+ }
6
21
  function createSessionsRouter(getAgent) {
7
22
  const app = new OpenAPIHono();
8
23
  const listRoute = createRoute({
@@ -68,6 +83,48 @@ function createSessionsRouter(getAgent) {
68
83
  }
69
84
  }
70
85
  });
86
+ const forkRoute = createRoute({
87
+ method: "post",
88
+ path: "/sessions/{sessionId}/fork",
89
+ summary: "Fork Session",
90
+ description: "Creates a new child session by cloning the specified parent session history and metadata lineage.",
91
+ tags: ["sessions"],
92
+ request: {
93
+ params: z.object({
94
+ sessionId: z.string().describe("Parent session identifier")
95
+ })
96
+ },
97
+ responses: {
98
+ 201: {
99
+ description: "Forked session created successfully",
100
+ content: {
101
+ "application/json": {
102
+ schema: z.object({
103
+ session: SessionMetadataSchema.describe(
104
+ "Newly created child session metadata"
105
+ )
106
+ }).strict()
107
+ }
108
+ }
109
+ },
110
+ 400: {
111
+ description: "Invalid fork request (for example, max session limit reached)",
112
+ content: {
113
+ "application/json": {
114
+ schema: StandardErrorEnvelopeSchema
115
+ }
116
+ }
117
+ },
118
+ 404: {
119
+ description: "Parent session not found",
120
+ content: {
121
+ "application/json": {
122
+ schema: StandardErrorEnvelopeSchema
123
+ }
124
+ }
125
+ }
126
+ }
127
+ });
71
128
  const historyRoute = createRoute({
72
129
  method: "get",
73
130
  path: "/sessions/{sessionId}/history",
@@ -251,23 +308,9 @@ function createSessionsRouter(getAgent) {
251
308
  sessionIds.map(async (id) => {
252
309
  try {
253
310
  const metadata = await agent.getSessionMetadata(id);
254
- return {
255
- id,
256
- createdAt: metadata?.createdAt || null,
257
- lastActivity: metadata?.lastActivity || null,
258
- messageCount: metadata?.messageCount || 0,
259
- title: metadata?.title || null,
260
- workspaceId: metadata?.workspaceId || null
261
- };
311
+ return mapSessionMetadata(id, metadata);
262
312
  } catch {
263
- return {
264
- id,
265
- createdAt: null,
266
- lastActivity: null,
267
- messageCount: 0,
268
- title: null,
269
- workspaceId: null
270
- };
313
+ return mapSessionMetadata(id, void 0);
271
314
  }
272
315
  })
273
316
  );
@@ -279,14 +322,21 @@ function createSessionsRouter(getAgent) {
279
322
  const metadata = await agent.getSessionMetadata(session.id);
280
323
  return ctx.json(
281
324
  {
282
- session: {
283
- id: session.id,
284
- createdAt: metadata?.createdAt || Date.now(),
285
- lastActivity: metadata?.lastActivity || Date.now(),
286
- messageCount: metadata?.messageCount || 0,
287
- title: metadata?.title || null,
288
- workspaceId: metadata?.workspaceId || null
289
- }
325
+ session: mapSessionMetadata(session.id, metadata, {
326
+ createdAt: Date.now(),
327
+ lastActivity: Date.now()
328
+ })
329
+ },
330
+ 201
331
+ );
332
+ }).openapi(forkRoute, async (ctx) => {
333
+ const agent = await getAgent(ctx);
334
+ const { sessionId: parentSessionId } = ctx.req.valid("param");
335
+ const session = await agent.forkSession(parentSessionId);
336
+ const metadata = await agent.getSessionMetadata(session.id);
337
+ return ctx.json(
338
+ {
339
+ session: mapSessionMetadata(session.id, metadata)
290
340
  },
291
341
  201
292
342
  );
@@ -297,12 +347,7 @@ function createSessionsRouter(getAgent) {
297
347
  const history = await agent.getSessionHistory(sessionId);
298
348
  return ctx.json({
299
349
  session: {
300
- id: sessionId,
301
- createdAt: metadata?.createdAt || null,
302
- lastActivity: metadata?.lastActivity || null,
303
- messageCount: metadata?.messageCount || 0,
304
- title: metadata?.title || null,
305
- workspaceId: metadata?.workspaceId || null,
350
+ ...mapSessionMetadata(sessionId, metadata),
306
351
  history: history.length
307
352
  }
308
353
  });
@@ -363,12 +408,7 @@ function createSessionsRouter(getAgent) {
363
408
  return ctx.json(
364
409
  {
365
410
  session: {
366
- id: sessionId,
367
- createdAt: metadata?.createdAt || null,
368
- lastActivity: metadata?.lastActivity || null,
369
- messageCount: metadata?.messageCount || 0,
370
- title: metadata?.title || null,
371
- workspaceId: metadata?.workspaceId || null,
411
+ ...mapSessionMetadata(sessionId, metadata),
372
412
  isBusy
373
413
  }
374
414
  },
@@ -381,14 +421,7 @@ function createSessionsRouter(getAgent) {
381
421
  await agent.setSessionTitle(sessionId, title);
382
422
  const metadata = await agent.getSessionMetadata(sessionId);
383
423
  return ctx.json({
384
- session: {
385
- id: sessionId,
386
- createdAt: metadata?.createdAt || null,
387
- lastActivity: metadata?.lastActivity || null,
388
- messageCount: metadata?.messageCount || 0,
389
- title: metadata?.title || title,
390
- workspaceId: metadata?.workspaceId || null
391
- }
424
+ session: mapSessionMetadata(sessionId, metadata, { title })
392
425
  });
393
426
  }).openapi(generateTitleRoute, async (ctx) => {
394
427
  const agent = await getAgent(ctx);
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var system_prompt_exports = {};
20
+ __export(system_prompt_exports, {
21
+ createSystemPromptRouter: () => createSystemPromptRouter
22
+ });
23
+ module.exports = __toCommonJS(system_prompt_exports);
24
+ var import_zod_openapi = require("@hono/zod-openapi");
25
+ var import_core = require("@dexto/core");
26
+ var import_responses = require("../schemas/responses.js");
27
+ const MAX_SYSTEM_PROMPT_CONTRIBUTOR_CONTENT_CHARS = 12e4;
28
+ const DEFAULT_SYSTEM_PROMPT_CONTRIBUTOR_PRIORITY = 45;
29
+ const ContributorInfoSchema = import_zod_openapi.z.object({
30
+ id: import_zod_openapi.z.string().describe("Contributor identifier"),
31
+ priority: import_zod_openapi.z.number().describe("Contributor priority")
32
+ }).strict().describe("System prompt contributor metadata.");
33
+ const UpsertSystemPromptContributorSchema = import_zod_openapi.z.object({
34
+ id: import_zod_openapi.z.string().min(1).describe("Contributor identifier"),
35
+ priority: import_zod_openapi.z.number().optional().describe("Optional priority override"),
36
+ enabled: import_zod_openapi.z.boolean().optional().describe("Set false to remove the contributor instead of adding/updating it"),
37
+ content: import_zod_openapi.z.string().optional().describe("Static contributor content (required when enabled).")
38
+ }).strict().describe("System prompt contributor update payload.");
39
+ const SystemPromptContributorErrorSchema = import_responses.StandardErrorEnvelopeSchema.describe(
40
+ "System prompt contributor error response."
41
+ );
42
+ function sanitizeContributorId(value) {
43
+ return value.trim().replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
44
+ }
45
+ function resolveContributorPriority(value) {
46
+ if (typeof value === "number" && Number.isFinite(value)) {
47
+ return Math.trunc(value);
48
+ }
49
+ return DEFAULT_SYSTEM_PROMPT_CONTRIBUTOR_PRIORITY;
50
+ }
51
+ function createSystemPromptRouter(getAgent) {
52
+ const app = new import_zod_openapi.OpenAPIHono();
53
+ const listContributorsRoute = (0, import_zod_openapi.createRoute)({
54
+ method: "get",
55
+ path: "/system-prompt/contributors",
56
+ summary: "List System Prompt Contributors",
57
+ description: "Lists currently registered system prompt contributors.",
58
+ tags: ["config"],
59
+ responses: {
60
+ 200: {
61
+ description: "Current contributor list",
62
+ content: {
63
+ "application/json": {
64
+ schema: import_zod_openapi.z.object({
65
+ contributors: import_zod_openapi.z.array(ContributorInfoSchema).describe("Registered system prompt contributors.")
66
+ }).strict().describe("System prompt contributors list response.")
67
+ }
68
+ }
69
+ }
70
+ }
71
+ });
72
+ const upsertContributorRoute = (0, import_zod_openapi.createRoute)({
73
+ method: "post",
74
+ path: "/system-prompt/contributors",
75
+ summary: "Upsert System Prompt Contributor",
76
+ description: "Adds or updates a static system prompt contributor. Set enabled=false (or empty content) to remove.",
77
+ tags: ["config"],
78
+ request: {
79
+ body: {
80
+ content: {
81
+ "application/json": {
82
+ schema: UpsertSystemPromptContributorSchema
83
+ }
84
+ }
85
+ }
86
+ },
87
+ responses: {
88
+ 200: {
89
+ description: "Contributor upsert result",
90
+ content: {
91
+ "application/json": {
92
+ schema: import_zod_openapi.z.object({
93
+ id: import_zod_openapi.z.string().describe("Contributor identifier"),
94
+ enabled: import_zod_openapi.z.boolean().describe("Whether the contributor remains enabled"),
95
+ priority: import_zod_openapi.z.number().optional().describe("Contributor priority"),
96
+ replaced: import_zod_openapi.z.boolean().optional().describe("Whether an existing contributor was replaced"),
97
+ removed: import_zod_openapi.z.boolean().optional().describe("Whether the contributor was removed"),
98
+ contentLength: import_zod_openapi.z.number().optional().describe("Stored content length in characters"),
99
+ truncated: import_zod_openapi.z.boolean().optional().describe("Whether the submitted content was truncated")
100
+ }).strict().describe("System prompt contributor upsert response.")
101
+ }
102
+ }
103
+ },
104
+ 400: {
105
+ description: "Invalid contributor update request",
106
+ content: {
107
+ "application/json": {
108
+ schema: SystemPromptContributorErrorSchema
109
+ }
110
+ }
111
+ }
112
+ }
113
+ });
114
+ return app.openapi(listContributorsRoute, async (ctx) => {
115
+ const agent = await getAgent(ctx);
116
+ const contributors = agent.systemPromptManager.getContributors().map((contributor) => ({
117
+ id: contributor.id,
118
+ priority: contributor.priority
119
+ }));
120
+ return ctx.json({ contributors });
121
+ }).openapi(upsertContributorRoute, async (ctx) => {
122
+ const agent = await getAgent(ctx);
123
+ const payload = ctx.req.valid("json");
124
+ const contributorId = sanitizeContributorId(payload.id);
125
+ if (contributorId.length === 0) {
126
+ throw new import_core.DextoRuntimeError(
127
+ "systemprompt_contributor_config_invalid",
128
+ import_core.ErrorScope.SYSTEM_PROMPT,
129
+ import_core.ErrorType.USER,
130
+ "A valid contributor id is required",
131
+ {
132
+ id: payload.id
133
+ }
134
+ );
135
+ }
136
+ const enabled = payload.enabled !== false;
137
+ const hasContent = payload.content !== void 0;
138
+ const rawContent = payload.content ?? "";
139
+ const content = rawContent.slice(0, MAX_SYSTEM_PROMPT_CONTRIBUTOR_CONTENT_CHARS);
140
+ const priority = resolveContributorPriority(payload.priority);
141
+ if (!enabled || hasContent && content.trim().length === 0) {
142
+ const removed = agent.systemPromptManager.removeContributor(contributorId);
143
+ return ctx.json(
144
+ {
145
+ id: contributorId,
146
+ enabled: false,
147
+ removed
148
+ },
149
+ 200
150
+ );
151
+ }
152
+ if (!hasContent || content.trim().length === 0) {
153
+ throw new import_core.DextoRuntimeError(
154
+ "systemprompt_contributor_config_invalid",
155
+ import_core.ErrorScope.SYSTEM_PROMPT,
156
+ import_core.ErrorType.USER,
157
+ "Contributor content is required when enabled",
158
+ {
159
+ id: payload.id
160
+ }
161
+ );
162
+ }
163
+ const replaced = agent.systemPromptManager.removeContributor(contributorId);
164
+ agent.systemPromptManager.addContributor({
165
+ id: contributorId,
166
+ priority,
167
+ getContent: async () => content
168
+ });
169
+ return ctx.json(
170
+ {
171
+ id: contributorId,
172
+ enabled: true,
173
+ priority,
174
+ replaced,
175
+ contentLength: hasContent ? content.length : void 0,
176
+ truncated: hasContent ? rawContent.length > content.length : void 0
177
+ },
178
+ 200
179
+ );
180
+ });
181
+ }
182
+ // Annotate the CommonJS export names for ESM import in node:
183
+ 0 && (module.exports = {
184
+ createSystemPromptRouter
185
+ });
@@ -0,0 +1,57 @@
1
+ import { OpenAPIHono } from '@hono/zod-openapi';
2
+ import type { DextoAgent } from '@dexto/core';
3
+ import type { Context } from 'hono';
4
+ type GetAgentFn = (ctx: Context) => DextoAgent | Promise<DextoAgent>;
5
+ export declare function createSystemPromptRouter(getAgent: GetAgentFn): OpenAPIHono<import("hono").Env, {
6
+ "/system-prompt/contributors": {
7
+ $get: {
8
+ input: {};
9
+ output: {
10
+ contributors: {
11
+ id: string;
12
+ priority: number;
13
+ }[];
14
+ };
15
+ outputFormat: "json";
16
+ status: 200;
17
+ };
18
+ };
19
+ } & {
20
+ "/system-prompt/contributors": {
21
+ $post: {
22
+ input: {
23
+ json: {
24
+ id: string;
25
+ content?: string | undefined;
26
+ enabled?: boolean | undefined;
27
+ priority?: number | undefined;
28
+ };
29
+ };
30
+ output: never;
31
+ outputFormat: "json";
32
+ status: 400;
33
+ } | {
34
+ input: {
35
+ json: {
36
+ id: string;
37
+ content?: string | undefined;
38
+ enabled?: boolean | undefined;
39
+ priority?: number | undefined;
40
+ };
41
+ };
42
+ output: {
43
+ id: string;
44
+ enabled: boolean;
45
+ removed?: boolean | undefined;
46
+ priority?: number | undefined;
47
+ replaced?: boolean | undefined;
48
+ contentLength?: number | undefined;
49
+ truncated?: boolean | undefined;
50
+ };
51
+ outputFormat: "json";
52
+ status: 200;
53
+ };
54
+ };
55
+ }, "/">;
56
+ export {};
57
+ //# sourceMappingURL=system-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/system-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAgDrE,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAoK5D"}