@dexto/server 1.6.17 → 1.6.19
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.
- package/dist/hono/__tests__/test-fixtures.cjs +3 -2
- package/dist/hono/__tests__/test-fixtures.d.ts +6 -2
- package/dist/hono/__tests__/test-fixtures.d.ts.map +1 -1
- package/dist/hono/__tests__/test-fixtures.js +3 -2
- package/dist/hono/index.d.ts +101 -14
- package/dist/hono/index.d.ts.map +1 -1
- package/dist/hono/routes/approvals.d.ts +10 -10
- package/dist/hono/routes/approvals.d.ts.map +1 -1
- package/dist/hono/routes/messages.d.ts +1 -1
- package/dist/hono/routes/search.d.ts +2 -2
- package/dist/hono/routes/sessions.cjs +198 -2
- package/dist/hono/routes/sessions.d.ts +88 -1
- package/dist/hono/routes/sessions.d.ts.map +1 -1
- package/dist/hono/routes/sessions.js +202 -3
- package/dist/hono/routes/system-prompt.d.ts +1 -1
- package/dist/hono/schemas/responses.d.ts +26 -26
- package/package.json +11 -11
|
@@ -24,9 +24,33 @@ module.exports = __toCommonJS(sessions_exports);
|
|
|
24
24
|
var import_zod_openapi = require("@hono/zod-openapi");
|
|
25
25
|
var import_core = require("@dexto/core");
|
|
26
26
|
var import_responses = require("../schemas/responses.js");
|
|
27
|
+
var import_error = require("../middleware/error.js");
|
|
27
28
|
const CreateSessionSchema = import_zod_openapi.z.object({
|
|
28
29
|
sessionId: import_zod_openapi.z.string().optional().describe("A custom ID for the new session")
|
|
29
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
|
+
}
|
|
30
54
|
function mapSessionMetadata(sessionId, metadata, defaults) {
|
|
31
55
|
return {
|
|
32
56
|
id: sessionId,
|
|
@@ -45,7 +69,24 @@ function mapSessionMetadata(sessionId, metadata, defaults) {
|
|
|
45
69
|
};
|
|
46
70
|
}
|
|
47
71
|
function createSessionsRouter(getAgent) {
|
|
48
|
-
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));
|
|
49
90
|
const listRoute = (0, import_zod_openapi.createRoute)({
|
|
50
91
|
method: "get",
|
|
51
92
|
path: "/sessions",
|
|
@@ -174,6 +215,86 @@ function createSessionsRouter(getAgent) {
|
|
|
174
215
|
}
|
|
175
216
|
}
|
|
176
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
|
+
});
|
|
177
298
|
const deleteRoute = (0, import_zod_openapi.createRoute)({
|
|
178
299
|
method: "delete",
|
|
179
300
|
path: "/sessions/{sessionId}",
|
|
@@ -420,6 +541,81 @@ function createSessionsRouter(getAgent) {
|
|
|
420
541
|
history,
|
|
421
542
|
isBusy
|
|
422
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
|
+
);
|
|
423
619
|
}).openapi(deleteRoute, async (ctx) => {
|
|
424
620
|
const agent = await getAgent(ctx);
|
|
425
621
|
const { sessionId } = ctx.req.param();
|
|
@@ -464,7 +660,7 @@ function createSessionsRouter(getAgent) {
|
|
|
464
660
|
const metadata = await agent.getSessionMetadata(sessionId);
|
|
465
661
|
const isBusy = await agent.isSessionBusy(sessionId);
|
|
466
662
|
const usageSummary = await agent.getSessionUsageSummary(sessionId);
|
|
467
|
-
const activeUsageScopeId =
|
|
663
|
+
const activeUsageScopeId = agent.getEffectiveConfig().usageScopeId ?? null;
|
|
468
664
|
const activeUsageScope = activeUsageScopeId ? {
|
|
469
665
|
scopeId: activeUsageScopeId,
|
|
470
666
|
...await agent.getSessionUsageSummary(sessionId, activeUsageScopeId)
|
|
@@ -256,6 +256,7 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
|
|
|
256
256
|
} | undefined;
|
|
257
257
|
})[] | null;
|
|
258
258
|
role: "system" | "user" | "assistant" | "tool";
|
|
259
|
+
usageScopeId?: string | undefined;
|
|
259
260
|
id?: string | undefined;
|
|
260
261
|
name?: string | undefined;
|
|
261
262
|
timestamp?: number | undefined;
|
|
@@ -270,7 +271,6 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
|
|
|
270
271
|
} | undefined;
|
|
271
272
|
estimatedCost?: number | undefined;
|
|
272
273
|
pricingStatus?: "estimated" | "unpriced" | undefined;
|
|
273
|
-
usageScopeId?: string | undefined;
|
|
274
274
|
model?: string | undefined;
|
|
275
275
|
provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "minimax" | "glm" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova" | undefined;
|
|
276
276
|
toolCalls?: {
|
|
@@ -290,6 +290,93 @@ export declare function createSessionsRouter(getAgent: GetAgentFn): OpenAPIHono<
|
|
|
290
290
|
status: 200;
|
|
291
291
|
};
|
|
292
292
|
};
|
|
293
|
+
} & {
|
|
294
|
+
"/sessions/:sessionId/system-prompt/contributors": {
|
|
295
|
+
$get: {
|
|
296
|
+
input: {
|
|
297
|
+
param: {
|
|
298
|
+
sessionId: string;
|
|
299
|
+
};
|
|
300
|
+
};
|
|
301
|
+
output: never;
|
|
302
|
+
outputFormat: "json";
|
|
303
|
+
status: 404;
|
|
304
|
+
} | {
|
|
305
|
+
input: {
|
|
306
|
+
param: {
|
|
307
|
+
sessionId: string;
|
|
308
|
+
};
|
|
309
|
+
};
|
|
310
|
+
output: {
|
|
311
|
+
contributors: {
|
|
312
|
+
id: string;
|
|
313
|
+
priority: number;
|
|
314
|
+
}[];
|
|
315
|
+
};
|
|
316
|
+
outputFormat: "json";
|
|
317
|
+
status: 200;
|
|
318
|
+
};
|
|
319
|
+
};
|
|
320
|
+
} & {
|
|
321
|
+
"/sessions/:sessionId/system-prompt/contributors": {
|
|
322
|
+
$post: {
|
|
323
|
+
input: {
|
|
324
|
+
param: {
|
|
325
|
+
sessionId: string;
|
|
326
|
+
};
|
|
327
|
+
} & {
|
|
328
|
+
json: {
|
|
329
|
+
id: string;
|
|
330
|
+
content?: string | undefined;
|
|
331
|
+
enabled?: boolean | undefined;
|
|
332
|
+
priority?: number | undefined;
|
|
333
|
+
};
|
|
334
|
+
};
|
|
335
|
+
output: never;
|
|
336
|
+
outputFormat: "json";
|
|
337
|
+
status: 400;
|
|
338
|
+
} | {
|
|
339
|
+
input: {
|
|
340
|
+
param: {
|
|
341
|
+
sessionId: string;
|
|
342
|
+
};
|
|
343
|
+
} & {
|
|
344
|
+
json: {
|
|
345
|
+
id: string;
|
|
346
|
+
content?: string | undefined;
|
|
347
|
+
enabled?: boolean | undefined;
|
|
348
|
+
priority?: number | undefined;
|
|
349
|
+
};
|
|
350
|
+
};
|
|
351
|
+
output: never;
|
|
352
|
+
outputFormat: "json";
|
|
353
|
+
status: 404;
|
|
354
|
+
} | {
|
|
355
|
+
input: {
|
|
356
|
+
param: {
|
|
357
|
+
sessionId: string;
|
|
358
|
+
};
|
|
359
|
+
} & {
|
|
360
|
+
json: {
|
|
361
|
+
id: string;
|
|
362
|
+
content?: string | undefined;
|
|
363
|
+
enabled?: boolean | undefined;
|
|
364
|
+
priority?: number | undefined;
|
|
365
|
+
};
|
|
366
|
+
};
|
|
367
|
+
output: {
|
|
368
|
+
id: string;
|
|
369
|
+
enabled: boolean;
|
|
370
|
+
priority?: number | undefined;
|
|
371
|
+
replaced?: boolean | undefined;
|
|
372
|
+
removed?: boolean | undefined;
|
|
373
|
+
contentLength?: number | undefined;
|
|
374
|
+
truncated?: boolean | undefined;
|
|
375
|
+
};
|
|
376
|
+
outputFormat: "json";
|
|
377
|
+
status: 200;
|
|
378
|
+
};
|
|
379
|
+
};
|
|
293
380
|
} & {
|
|
294
381
|
"/sessions/:sessionId": {
|
|
295
382
|
$delete: {
|
|
@@ -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;
|
|
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;AAwF9C,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAowBxD"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
DextoRuntimeError,
|
|
4
|
+
ErrorScope,
|
|
5
|
+
ErrorType,
|
|
6
|
+
zodToIssues
|
|
4
7
|
} from "@dexto/core";
|
|
5
8
|
import {
|
|
6
9
|
SessionMetadataSchema,
|
|
@@ -9,9 +12,33 @@ import {
|
|
|
9
12
|
StandardErrorEnvelopeSchema,
|
|
10
13
|
UsageSummarySchema
|
|
11
14
|
} from "../schemas/responses.js";
|
|
15
|
+
import { handleHonoError } from "../middleware/error.js";
|
|
12
16
|
const CreateSessionSchema = z.object({
|
|
13
17
|
sessionId: z.string().optional().describe("A custom ID for the new session")
|
|
14
18
|
}).describe("Request body for creating a new session");
|
|
19
|
+
const MAX_SYSTEM_PROMPT_CONTRIBUTOR_CONTENT_CHARS = 12e4;
|
|
20
|
+
const DEFAULT_SYSTEM_PROMPT_CONTRIBUTOR_PRIORITY = 45;
|
|
21
|
+
const SessionPromptContributorInfoSchema = z.object({
|
|
22
|
+
id: z.string().describe("Contributor identifier"),
|
|
23
|
+
priority: z.number().describe("Contributor priority")
|
|
24
|
+
}).strict().describe("Session-scoped system prompt contributor metadata.");
|
|
25
|
+
const UpsertSessionPromptContributorSchema = z.object({
|
|
26
|
+
id: z.string().min(1).describe("Contributor identifier"),
|
|
27
|
+
priority: z.number().int().nonnegative().optional().default(DEFAULT_SYSTEM_PROMPT_CONTRIBUTOR_PRIORITY).describe("Optional priority override"),
|
|
28
|
+
enabled: z.boolean().default(true).describe("Set false to remove the contributor instead of adding or updating it"),
|
|
29
|
+
content: z.string().optional().describe("Static contributor content for this session (required when enabled)")
|
|
30
|
+
}).strict().superRefine((value, ctx) => {
|
|
31
|
+
if (value.enabled !== false && (!value.content || value.content.trim().length === 0)) {
|
|
32
|
+
ctx.addIssue({
|
|
33
|
+
code: z.ZodIssueCode.custom,
|
|
34
|
+
path: ["content"],
|
|
35
|
+
message: "Contributor content is required when enabled"
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}).describe("Session-scoped system prompt contributor update payload.");
|
|
39
|
+
function sanitizeContributorId(value) {
|
|
40
|
+
return value.trim().replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
41
|
+
}
|
|
15
42
|
function mapSessionMetadata(sessionId, metadata, defaults) {
|
|
16
43
|
return {
|
|
17
44
|
id: sessionId,
|
|
@@ -30,7 +57,24 @@ function mapSessionMetadata(sessionId, metadata, defaults) {
|
|
|
30
57
|
};
|
|
31
58
|
}
|
|
32
59
|
function createSessionsRouter(getAgent) {
|
|
33
|
-
const app = new OpenAPIHono(
|
|
60
|
+
const app = new OpenAPIHono({
|
|
61
|
+
defaultHook: (result, ctx) => {
|
|
62
|
+
if (!result.success) {
|
|
63
|
+
const issues = zodToIssues(result.error);
|
|
64
|
+
return handleHonoError(
|
|
65
|
+
ctx,
|
|
66
|
+
new DextoRuntimeError(
|
|
67
|
+
"validation_failed",
|
|
68
|
+
"validation",
|
|
69
|
+
ErrorType.USER,
|
|
70
|
+
issues[0]?.message ?? "Validation failed",
|
|
71
|
+
{ issues }
|
|
72
|
+
)
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
app.onError((err, ctx) => handleHonoError(ctx, err));
|
|
34
78
|
const listRoute = createRoute({
|
|
35
79
|
method: "get",
|
|
36
80
|
path: "/sessions",
|
|
@@ -159,6 +203,86 @@ function createSessionsRouter(getAgent) {
|
|
|
159
203
|
}
|
|
160
204
|
}
|
|
161
205
|
});
|
|
206
|
+
const listSessionPromptContributorsRoute = createRoute({
|
|
207
|
+
method: "get",
|
|
208
|
+
path: "/sessions/{sessionId}/system-prompt/contributors",
|
|
209
|
+
summary: "List Session System Prompt Contributors",
|
|
210
|
+
description: "Lists static system prompt contributors that apply only to the specified session.",
|
|
211
|
+
tags: ["sessions", "config"],
|
|
212
|
+
request: { params: z.object({ sessionId: z.string().describe("Session identifier") }) },
|
|
213
|
+
responses: {
|
|
214
|
+
200: {
|
|
215
|
+
description: "Current session contributor list",
|
|
216
|
+
content: {
|
|
217
|
+
"application/json": {
|
|
218
|
+
schema: z.object({
|
|
219
|
+
contributors: z.array(SessionPromptContributorInfoSchema).describe("Registered session prompt contributors.")
|
|
220
|
+
}).strict()
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
404: {
|
|
225
|
+
description: "Session not found",
|
|
226
|
+
content: {
|
|
227
|
+
"application/json": {
|
|
228
|
+
schema: StandardErrorEnvelopeSchema
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
const upsertSessionPromptContributorRoute = createRoute({
|
|
235
|
+
method: "post",
|
|
236
|
+
path: "/sessions/{sessionId}/system-prompt/contributors",
|
|
237
|
+
summary: "Upsert Session System Prompt Contributor",
|
|
238
|
+
description: "Adds or updates a static system prompt contributor that applies only to the specified session. Set enabled=false to remove it.",
|
|
239
|
+
tags: ["sessions", "config"],
|
|
240
|
+
request: {
|
|
241
|
+
params: z.object({ sessionId: z.string().describe("Session identifier") }),
|
|
242
|
+
body: {
|
|
243
|
+
required: true,
|
|
244
|
+
content: {
|
|
245
|
+
"application/json": {
|
|
246
|
+
schema: UpsertSessionPromptContributorSchema
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
responses: {
|
|
252
|
+
200: {
|
|
253
|
+
description: "Session contributor upsert result",
|
|
254
|
+
content: {
|
|
255
|
+
"application/json": {
|
|
256
|
+
schema: z.object({
|
|
257
|
+
id: z.string().describe("Contributor identifier"),
|
|
258
|
+
enabled: z.boolean().describe("Whether the contributor remains enabled"),
|
|
259
|
+
priority: z.number().optional().describe("Contributor priority"),
|
|
260
|
+
replaced: z.boolean().optional().describe("Whether an existing contributor was replaced"),
|
|
261
|
+
removed: z.boolean().optional().describe("Whether the contributor was removed"),
|
|
262
|
+
contentLength: z.number().optional().describe("Stored content length in characters"),
|
|
263
|
+
truncated: z.boolean().optional().describe("Whether the submitted content was truncated")
|
|
264
|
+
}).strict()
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
400: {
|
|
269
|
+
description: "Invalid session contributor request",
|
|
270
|
+
content: {
|
|
271
|
+
"application/json": {
|
|
272
|
+
schema: StandardErrorEnvelopeSchema
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
404: {
|
|
277
|
+
description: "Session not found",
|
|
278
|
+
content: {
|
|
279
|
+
"application/json": {
|
|
280
|
+
schema: StandardErrorEnvelopeSchema
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
});
|
|
162
286
|
const deleteRoute = createRoute({
|
|
163
287
|
method: "delete",
|
|
164
288
|
path: "/sessions/{sessionId}",
|
|
@@ -405,6 +529,81 @@ function createSessionsRouter(getAgent) {
|
|
|
405
529
|
history,
|
|
406
530
|
isBusy
|
|
407
531
|
});
|
|
532
|
+
}).openapi(listSessionPromptContributorsRoute, async (ctx) => {
|
|
533
|
+
const agent = await getAgent(ctx);
|
|
534
|
+
const { sessionId } = ctx.req.valid("param");
|
|
535
|
+
const contributors = await agent.getSessionSystemPromptContributors(sessionId);
|
|
536
|
+
return ctx.json(
|
|
537
|
+
{
|
|
538
|
+
contributors: contributors.map((contributor) => ({
|
|
539
|
+
id: contributor.id,
|
|
540
|
+
priority: contributor.priority
|
|
541
|
+
}))
|
|
542
|
+
},
|
|
543
|
+
200
|
|
544
|
+
);
|
|
545
|
+
}).openapi(upsertSessionPromptContributorRoute, async (ctx) => {
|
|
546
|
+
const agent = await getAgent(ctx);
|
|
547
|
+
const { sessionId } = ctx.req.valid("param");
|
|
548
|
+
const payload = ctx.req.valid("json");
|
|
549
|
+
const contributorId = sanitizeContributorId(payload.id);
|
|
550
|
+
if (contributorId.length === 0) {
|
|
551
|
+
throw new DextoRuntimeError(
|
|
552
|
+
"session_systemprompt_contributor_config_invalid",
|
|
553
|
+
ErrorScope.SYSTEM_PROMPT,
|
|
554
|
+
ErrorType.USER,
|
|
555
|
+
"A valid contributor id is required",
|
|
556
|
+
{
|
|
557
|
+
id: payload.id,
|
|
558
|
+
sessionId
|
|
559
|
+
}
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
const rawContent = payload.content ?? "";
|
|
563
|
+
const content = rawContent.slice(0, MAX_SYSTEM_PROMPT_CONTRIBUTOR_CONTENT_CHARS);
|
|
564
|
+
if (!payload.enabled) {
|
|
565
|
+
const removed = await agent.removeSessionSystemPromptContributor(
|
|
566
|
+
sessionId,
|
|
567
|
+
contributorId
|
|
568
|
+
);
|
|
569
|
+
return ctx.json(
|
|
570
|
+
{
|
|
571
|
+
id: contributorId,
|
|
572
|
+
enabled: false,
|
|
573
|
+
removed
|
|
574
|
+
},
|
|
575
|
+
200
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
if (content.trim().length === 0) {
|
|
579
|
+
throw new DextoRuntimeError(
|
|
580
|
+
"session_systemprompt_contributor_config_invalid",
|
|
581
|
+
ErrorScope.SYSTEM_PROMPT,
|
|
582
|
+
ErrorType.USER,
|
|
583
|
+
"Contributor content is required when enabled",
|
|
584
|
+
{
|
|
585
|
+
id: payload.id,
|
|
586
|
+
sessionId
|
|
587
|
+
}
|
|
588
|
+
);
|
|
589
|
+
}
|
|
590
|
+
const priority = payload.priority;
|
|
591
|
+
const result = await agent.upsertSessionSystemPromptContributor(sessionId, {
|
|
592
|
+
id: contributorId,
|
|
593
|
+
priority,
|
|
594
|
+
content
|
|
595
|
+
});
|
|
596
|
+
return ctx.json(
|
|
597
|
+
{
|
|
598
|
+
id: contributorId,
|
|
599
|
+
enabled: true,
|
|
600
|
+
priority,
|
|
601
|
+
replaced: result.replaced,
|
|
602
|
+
contentLength: content.length,
|
|
603
|
+
truncated: rawContent.length > content.length
|
|
604
|
+
},
|
|
605
|
+
200
|
|
606
|
+
);
|
|
408
607
|
}).openapi(deleteRoute, async (ctx) => {
|
|
409
608
|
const agent = await getAgent(ctx);
|
|
410
609
|
const { sessionId } = ctx.req.param();
|
|
@@ -449,7 +648,7 @@ function createSessionsRouter(getAgent) {
|
|
|
449
648
|
const metadata = await agent.getSessionMetadata(sessionId);
|
|
450
649
|
const isBusy = await agent.isSessionBusy(sessionId);
|
|
451
650
|
const usageSummary = await agent.getSessionUsageSummary(sessionId);
|
|
452
|
-
const activeUsageScopeId =
|
|
651
|
+
const activeUsageScopeId = agent.getEffectiveConfig().usageScopeId ?? null;
|
|
453
652
|
const activeUsageScope = activeUsageScopeId ? {
|
|
454
653
|
scopeId: activeUsageScopeId,
|
|
455
654
|
...await agent.getSessionUsageSummary(sessionId, activeUsageScopeId)
|
|
@@ -42,9 +42,9 @@ export declare function createSystemPromptRouter(getAgent: GetAgentFn): OpenAPIH
|
|
|
42
42
|
output: {
|
|
43
43
|
id: string;
|
|
44
44
|
enabled: boolean;
|
|
45
|
-
removed?: boolean | undefined;
|
|
46
45
|
priority?: number | undefined;
|
|
47
46
|
replaced?: boolean | undefined;
|
|
47
|
+
removed?: boolean | undefined;
|
|
48
48
|
contentLength?: number | undefined;
|
|
49
49
|
truncated?: boolean | undefined;
|
|
50
50
|
};
|