@case-framework/survey-assistant 0.2.3 → 0.4.0

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 (87) hide show
  1. package/README.md +12 -4
  2. package/dist/{authoring-references-ChDTVnms.mjs → authoring-references-yyYC4Ydi.mjs} +2 -2
  3. package/dist/{authoring-references-ChDTVnms.mjs.map → authoring-references-yyYC4Ydi.mjs.map} +1 -1
  4. package/dist/capabilities-default.d.mts +1 -1
  5. package/dist/capabilities-default.mjs +1 -1
  6. package/dist/{constants-BK1-g6pR.d.mts → constants-k1b_evIb.d.mts} +7 -4
  7. package/dist/constants-k1b_evIb.d.mts.map +1 -0
  8. package/dist/{controller-proxy-DY36XFV3.mjs → controller-proxy-jWIPOZAv.mjs} +18 -8
  9. package/dist/controller-proxy-jWIPOZAv.mjs.map +1 -0
  10. package/dist/{controller-proxy-CIDRd8Wu.d.mts → controller-proxy-quQjtA7j.d.mts} +5 -2
  11. package/dist/controller-proxy-quQjtA7j.d.mts.map +1 -0
  12. package/dist/{engine-CWTuN3o2.mjs → engine-BvfUx_Jx.mjs} +85 -12
  13. package/dist/engine-BvfUx_Jx.mjs.map +1 -0
  14. package/dist/engine.d.mts +2 -2
  15. package/dist/engine.mjs +3 -3
  16. package/dist/{form-authoring-DCd9XfXf.mjs → form-authoring-BQh40yDb.mjs} +2 -2
  17. package/dist/{form-authoring-DCd9XfXf.mjs.map → form-authoring-BQh40yDb.mjs.map} +1 -1
  18. package/dist/index-8x1Eqlnz.d.mts +741 -0
  19. package/dist/index-8x1Eqlnz.d.mts.map +1 -0
  20. package/dist/{index-SPHf3OoJ.d.mts → index-BDp6S7r9.d.mts} +14 -5
  21. package/dist/index-BDp6S7r9.d.mts.map +1 -0
  22. package/dist/{index-Bp5W_oPa.d.mts → index-biZnRl-h.d.mts} +26 -24
  23. package/dist/index-biZnRl-h.d.mts.map +1 -0
  24. package/dist/{index-CPOQgkTN.d.mts → index-r8HVcn5b.d.mts} +9 -4
  25. package/dist/index-r8HVcn5b.d.mts.map +1 -0
  26. package/dist/lifecycle-DWv5CiSu.d.mts +523 -0
  27. package/dist/lifecycle-DWv5CiSu.d.mts.map +1 -0
  28. package/dist/{memory-thread-repository-acbz6HZJ.mjs → memory-thread-repository-xBZOog_q.mjs} +49 -21
  29. package/dist/memory-thread-repository-xBZOog_q.mjs.map +1 -0
  30. package/dist/{protocol-DATvkr1S.mjs → protocol-DJUP4gc0.mjs} +10 -4
  31. package/dist/protocol-DJUP4gc0.mjs.map +1 -0
  32. package/dist/protocol.d.mts +2 -1
  33. package/dist/protocol.mjs +1 -1
  34. package/dist/{react-3kSE6WtS.mjs → react-CY6N7lVi.mjs} +30 -8
  35. package/dist/react-CY6N7lVi.mjs.map +1 -0
  36. package/dist/react-integration.d.mts +1 -1
  37. package/dist/react-integration.mjs +1 -1
  38. package/dist/react.d.mts +2 -2
  39. package/dist/react.mjs +2 -2
  40. package/dist/{request-context-BEjnaaFr.mjs → request-context-DixY5DYu.mjs} +3 -3
  41. package/dist/request-context-DixY5DYu.mjs.map +1 -0
  42. package/dist/server-agent.d.mts +26 -24
  43. package/dist/server-agent.d.mts.map +1 -1
  44. package/dist/server-agent.mjs +7 -6
  45. package/dist/server-agent.mjs.map +1 -1
  46. package/dist/server-runtime.d.mts +341 -8
  47. package/dist/server-runtime.d.mts.map +1 -1
  48. package/dist/server-runtime.mjs +321 -23
  49. package/dist/server-runtime.mjs.map +1 -1
  50. package/dist/server-tasks.d.mts +1 -1
  51. package/dist/server-tasks.mjs +8 -6
  52. package/dist/server-tasks.mjs.map +1 -1
  53. package/dist/server-tools.d.mts +1 -1
  54. package/dist/server-tools.mjs +1 -1
  55. package/dist/server.d.mts +8 -8
  56. package/dist/server.d.mts.map +1 -1
  57. package/dist/server.mjs +3 -3
  58. package/dist/storage-postgres.d.mts +1 -1
  59. package/dist/{tasks-DIZgr4nD.d.mts → tasks-BWmTMXoK.d.mts} +3 -3
  60. package/dist/{tasks-DIZgr4nD.d.mts.map → tasks-BWmTMXoK.d.mts.map} +1 -1
  61. package/dist/{thread-documents-C3kf0Vds.d.mts → thread-documents-Dvo6XS7o.d.mts} +1 -1
  62. package/dist/{thread-documents-C3kf0Vds.d.mts.map → thread-documents-Dvo6XS7o.d.mts.map} +1 -1
  63. package/dist/{thread-handlers-DZ1WsorO.d.mts → thread-handlers-D8gkLfU6.d.mts} +15 -7
  64. package/dist/{thread-handlers-DZ1WsorO.d.mts.map → thread-handlers-D8gkLfU6.d.mts.map} +1 -1
  65. package/dist/{tools-GDd5_GUh.mjs → tools-TXI8bfzZ.mjs} +28 -9
  66. package/dist/tools-TXI8bfzZ.mjs.map +1 -0
  67. package/dist/ui.css +2 -2
  68. package/dist/ui.d.mts +94 -10
  69. package/dist/ui.d.mts.map +1 -1
  70. package/dist/ui.mjs +561 -203
  71. package/dist/ui.mjs.map +1 -1
  72. package/docs/integration.md +84 -63
  73. package/package.json +25 -19
  74. package/dist/constants-BK1-g6pR.d.mts.map +0 -1
  75. package/dist/controller-proxy-CIDRd8Wu.d.mts.map +0 -1
  76. package/dist/controller-proxy-DY36XFV3.mjs.map +0 -1
  77. package/dist/engine-CWTuN3o2.mjs.map +0 -1
  78. package/dist/index-Bp5W_oPa.d.mts.map +0 -1
  79. package/dist/index-CPOQgkTN.d.mts.map +0 -1
  80. package/dist/index-EDL1V168.d.mts +0 -1257
  81. package/dist/index-EDL1V168.d.mts.map +0 -1
  82. package/dist/index-SPHf3OoJ.d.mts.map +0 -1
  83. package/dist/memory-thread-repository-acbz6HZJ.mjs.map +0 -1
  84. package/dist/protocol-DATvkr1S.mjs.map +0 -1
  85. package/dist/react-3kSE6WtS.mjs.map +0 -1
  86. package/dist/request-context-BEjnaaFr.mjs.map +0 -1
  87. package/dist/tools-GDd5_GUh.mjs.map +0 -1
@@ -1,11 +1,122 @@
1
1
  import { n as SURVEY_ASSISTANT_TASK_AGENT_ID, t as SURVEY_ASSISTANT_AGENT_ID } from "./constants-CFUWrRtl.mjs";
2
2
  import { n as SURVEY_ASSISTANT_DEFAULT_REQUEST_LIMITS } from "./request-guardrails-h4t6u8mP.mjs";
3
- import { i as createSurveyAssistantChatHandler, n as createSurveyAssistantThreadHandlers, r as SurveyAssistantAuthorizationError, t as createMastraMemoryThreadRepository } from "./memory-thread-repository-acbz6HZJ.mjs";
4
- import { t as SURVEY_ASSISTANT_TOOL_IDS } from "./tools-GDd5_GUh.mjs";
3
+ import { i as createSurveyAssistantChatHandler, n as createSurveyAssistantThreadHandlers, r as SurveyAssistantAuthorizationError, t as createMastraMemoryThreadRepository } from "./memory-thread-repository-xBZOog_q.mjs";
4
+ import { t as SURVEY_ASSISTANT_TOOL_IDS } from "./tools-TXI8bfzZ.mjs";
5
5
  import { SURVEY_ASSISTANT_OBSERVATIONAL_MEMORY_DEFAULTS, createSurveyAssistantAgent, createSurveyAssistantObservationalMemoryOptions } from "./server-agent.mjs";
6
6
  import { createSurveyAssistantTaskAgent, createSurveyAssistantTaskHandler } from "./server-tasks.mjs";
7
+ import { z } from "zod";
7
8
  import { AzureOpenAIGateway } from "@mastra/core/llm";
8
9
  //#region src/server/runtime-config.ts
10
+ const ENVIRONMENT_VARIABLE_NAME = /^[A-Z_][A-Z0-9_]*$/;
11
+ const modelRoleSchema = z.enum([
12
+ "chat-default",
13
+ "chat-picker",
14
+ "memory",
15
+ "task-default"
16
+ ]);
17
+ const providerModelOptionsSchema = z.object({
18
+ parallelToolCalls: z.boolean().optional(),
19
+ promptCacheKey: z.string().trim().min(1).optional(),
20
+ promptCacheRetention: z.enum(["in_memory", "24h"]).optional(),
21
+ reasoningEffort: z.string().trim().min(1).optional(),
22
+ reasoningSummary: z.enum([
23
+ "auto",
24
+ "concise",
25
+ "detailed",
26
+ "off",
27
+ "none"
28
+ ]).optional(),
29
+ serviceTier: z.enum([
30
+ "auto",
31
+ "flex",
32
+ "priority",
33
+ "default"
34
+ ]).optional(),
35
+ textVerbosity: z.enum([
36
+ "low",
37
+ "medium",
38
+ "high"
39
+ ]).optional()
40
+ }).strict();
41
+ const configuredModelSchema = z.object({
42
+ id: z.string().trim().min(1).max(240),
43
+ label: z.string().trim().min(1).max(240).optional(),
44
+ upstreamModel: z.string().trim().min(1).max(240).optional(),
45
+ roles: z.array(modelRoleSchema).min(1),
46
+ options: providerModelOptionsSchema.optional()
47
+ }).strict().superRefine(({ roles }, context) => {
48
+ if (new Set(roles).size !== roles.length) context.addIssue({
49
+ code: "custom",
50
+ message: "Model roles must be unique."
51
+ });
52
+ });
53
+ const providerBaseShape = {
54
+ apiKeyEnv: z.string().regex(ENVIRONMENT_VARIABLE_NAME).optional(),
55
+ models: z.array(configuredModelSchema).min(1),
56
+ options: providerModelOptionsSchema.optional()
57
+ };
58
+ const providerSchema = z.discriminatedUnion("type", [
59
+ z.object({
60
+ ...providerBaseShape,
61
+ type: z.literal("openai"),
62
+ apiKeyEnv: z.string().regex(ENVIRONMENT_VARIABLE_NAME)
63
+ }).strict(),
64
+ z.object({
65
+ ...providerBaseShape,
66
+ type: z.literal("mistral"),
67
+ apiKeyEnv: z.string().regex(ENVIRONMENT_VARIABLE_NAME)
68
+ }).strict(),
69
+ z.object({
70
+ ...providerBaseShape,
71
+ type: z.literal("lmstudio"),
72
+ baseUrl: z.string().url().default("http://127.0.0.1:1234/v1"),
73
+ apiKeyOptional: z.boolean().default(true)
74
+ }).strict(),
75
+ z.object({
76
+ ...providerBaseShape,
77
+ type: z.literal("azure-openai"),
78
+ apiKeyEnv: z.string().regex(ENVIRONMENT_VARIABLE_NAME),
79
+ apiVersion: z.enum(["v1", "preview"]).default("v1"),
80
+ discoverModels: z.boolean().default(false),
81
+ resourceName: z.string().trim().min(1),
82
+ management: z.object({
83
+ tenantId: z.string().trim().min(1),
84
+ clientId: z.string().trim().min(1),
85
+ clientSecretEnv: z.string().regex(ENVIRONMENT_VARIABLE_NAME),
86
+ subscriptionId: z.string().trim().min(1),
87
+ resourceGroup: z.string().trim().min(1)
88
+ }).strict().optional()
89
+ }).strict()
90
+ ]);
91
+ const surveyAssistantConfigurationDocumentSchema = z.object({
92
+ version: z.literal(1),
93
+ activeProvider: z.string().trim().min(1),
94
+ enabled: z.boolean().optional(),
95
+ providers: z.record(z.string().trim().min(1), providerSchema),
96
+ execution: z.object({
97
+ firstResponseTimeoutMs: z.number().int().positive().optional(),
98
+ idleTimeoutMs: z.number().int().positive().optional(),
99
+ maxConcurrentRequests: z.number().int().positive().optional(),
100
+ maxDurationMs: z.number().int().positive().optional(),
101
+ maxSteps: z.number().int().positive().optional(),
102
+ sendReasoning: z.boolean().optional()
103
+ }).strict().optional(),
104
+ memory: z.object({
105
+ enabled: z.boolean().optional(),
106
+ bufferOnIdle: z.boolean().optional(),
107
+ messageTokens: z.number().int().positive().optional(),
108
+ observationTokens: z.number().int().positive().optional(),
109
+ temporalMarkers: z.boolean().optional()
110
+ }).strict().optional(),
111
+ modelCatalogTtlMs: z.number().int().positive().optional(),
112
+ requestLimits: z.object({
113
+ maxAttachmentBytes: z.number().int().positive().optional(),
114
+ maxAttachments: z.number().int().positive().optional(),
115
+ maxRequestBytes: z.number().int().positive().optional(),
116
+ maxTextPartChars: z.number().int().positive().optional(),
117
+ maxTotalAttachmentBytes: z.number().int().positive().optional()
118
+ }).strict().optional()
119
+ }).strict();
9
120
  const DEFAULT_MAX_STEPS = 48;
10
121
  const HARD_MAX_STEPS = 64;
11
122
  const DEFAULT_FIRST_RESPONSE_TIMEOUT_MS = 900 * 1e3;
@@ -45,6 +156,26 @@ const getOptionalSameProviderModelId = (env, name, options) => {
45
156
  return value ? getSameProviderModelId(value, name, options) : void 0;
46
157
  };
47
158
  const resolveSurveyAssistantProviderOptionsKey = (provider) => provider === "azure-openai" ? "azure" : provider;
159
+ const createProviderOptions = (provider, options, sendReasoning) => {
160
+ const providerOptionsKey = resolveSurveyAssistantProviderOptionsKey(provider);
161
+ const reasoningSummary = options?.reasoningSummary === "off" || options?.reasoningSummary === "none" ? void 0 : options?.reasoningSummary;
162
+ const reasoningEffort = options?.reasoningEffort === "default" || options?.reasoningEffort === "provider-default" ? void 0 : options?.reasoningEffort;
163
+ const resolved = {
164
+ parallelToolCalls: options?.parallelToolCalls ?? false,
165
+ ...reasoningEffort ? { reasoningEffort } : {},
166
+ ...options?.promptCacheKey ? { promptCacheKey: options.promptCacheKey } : {},
167
+ ...options?.promptCacheRetention ? { promptCacheRetention: options.promptCacheRetention } : {},
168
+ ...sendReasoning && reasoningSummary ? { reasoningSummary } : {},
169
+ ...options?.serviceTier ? { serviceTier: options.serviceTier } : {},
170
+ ...options?.textVerbosity ? { textVerbosity: options.textVerbosity } : {}
171
+ };
172
+ return { [providerOptionsKey]: resolved };
173
+ };
174
+ const resolveConfiguredEnabled = (env, configured, requireExperimentalIdentityOptIn) => {
175
+ const environmentOverride = getValue(env, "SURVEY_ASSISTANT_ENABLED");
176
+ if (environmentOverride !== void 0 && environmentOverride !== "true" && environmentOverride !== "false") throw new Error("SURVEY_ASSISTANT_ENABLED must be \"true\" or \"false\".");
177
+ return (environmentOverride === "true" ? true : environmentOverride === "false" ? false : configured ?? env.NODE_ENV === "development") && (!requireExperimentalIdentityOptIn || env.NODE_ENV === "development" || getBoolean(env, "SURVEY_ASSISTANT_ALLOW_EXPERIMENTAL_IDENTITY", false));
178
+ };
48
179
  const parseProvider = (env, fallback) => {
49
180
  const value = getValue(env, "SURVEY_ASSISTANT_PROVIDER")?.toLowerCase();
50
181
  if (value === "azure" || value === "azure-openai") return "azure-openai";
@@ -75,6 +206,139 @@ const getReadinessError = ({ azure, env, modelWasConfigured, provider, requireSt
75
206
  }
76
207
  return null;
77
208
  };
209
+ const parseSurveyAssistantConfigurationDocument = (input, env, { requireExperimentalIdentityOptIn = false, requireStorage = true } = {}) => {
210
+ const document = surveyAssistantConfigurationDocumentSchema.parse(input);
211
+ const activeProvider = document.providers[document.activeProvider];
212
+ if (!activeProvider) throw new Error(`activeProvider references unknown provider "${document.activeProvider}".`);
213
+ const memoryEnabled = document.memory?.enabled ?? true;
214
+ for (const [providerName, configuredProvider] of Object.entries(document.providers)) {
215
+ const duplicateModelId = configuredProvider.models.find((model, index, models) => models.findIndex((candidate) => candidate.id === model.id) !== index)?.id;
216
+ if (duplicateModelId) throw new Error(`Provider "${providerName}" contains duplicate model id "${duplicateModelId}".`);
217
+ const modelsForProviderRole = (role) => configuredProvider.models.filter((model) => model.roles.includes(role));
218
+ const providerChatDefaults = modelsForProviderRole("chat-default");
219
+ const providerChatModels = modelsForProviderRole("chat-picker");
220
+ const providerTaskDefaults = modelsForProviderRole("task-default");
221
+ const providerMemoryModels = modelsForProviderRole("memory");
222
+ if (providerChatDefaults.length !== 1) throw new Error(`Provider "${providerName}" must configure exactly one chat-default model.`);
223
+ if (!providerChatDefaults[0].roles.includes("chat-picker")) throw new Error(`The chat-default model for provider "${providerName}" must also have the chat-picker role.`);
224
+ if (providerChatModels.length === 0) throw new Error(`Provider "${providerName}" must configure a chat-picker model.`);
225
+ if (providerTaskDefaults.length > 1) throw new Error(`Provider "${providerName}" may configure at most one task-default model.`);
226
+ if (providerMemoryModels.length > 1 || memoryEnabled && providerMemoryModels.length !== 1) throw new Error(memoryEnabled ? `Provider "${providerName}" must configure exactly one memory model when memory is enabled.` : `Provider "${providerName}" may configure at most one memory model.`);
227
+ if (configuredProvider.type === "lmstudio" && !configuredProvider.apiKeyOptional && !configuredProvider.apiKeyEnv) throw new Error(`Provider "${providerName}" must configure apiKeyEnv when apiKeyOptional is false.`);
228
+ const validateOptions = (options, location) => {
229
+ if (!options) return;
230
+ if (configuredProvider.type !== "openai" && configuredProvider.type !== "azure-openai" && (options.promptCacheKey || options.promptCacheRetention || options.reasoningSummary || options.textVerbosity)) throw new Error(`${location} contains options unsupported by ${configuredProvider.type}.`);
231
+ if (configuredProvider.type !== "openai" && options.serviceTier) throw new Error(`${location} contains serviceTier, which is only supported by openai.`);
232
+ };
233
+ validateOptions(configuredProvider.options, `Provider "${providerName}"`);
234
+ for (const model of configuredProvider.models) {
235
+ const upstreamModelId = model.upstreamModel ?? model.id;
236
+ if (configuredProvider.type !== "lmstudio" && upstreamModelId.includes("/")) throw new Error(`Model "${model.id}" must use an upstreamModel without a provider prefix for ${configuredProvider.type}.`);
237
+ validateOptions(model.options, `Model "${model.id}" in provider "${providerName}"`);
238
+ }
239
+ }
240
+ const modelsForRole = (role) => activeProvider.models.filter((model) => model.roles.includes(role));
241
+ const chatDefaults = modelsForRole("chat-default");
242
+ const chatModels = modelsForRole("chat-picker");
243
+ const taskDefaults = modelsForRole("task-default");
244
+ const memoryModels = modelsForRole("memory");
245
+ const provider = activeProvider.type;
246
+ const sendReasoning = document.execution?.sendReasoning ?? true;
247
+ const providerDefaults = {
248
+ parallelToolCalls: false,
249
+ ...provider === "openai" || provider === "azure-openai" ? {
250
+ reasoningEffort: "low",
251
+ reasoningSummary: "detailed",
252
+ promptCacheKey: "survey-assistant-chat-v21"
253
+ } : provider === "mistral" ? { reasoningEffort: "none" } : {},
254
+ ...activeProvider.options
255
+ };
256
+ const models = activeProvider.models.map((model) => ({
257
+ id: model.id,
258
+ label: model.label ?? model.id,
259
+ upstreamModelId: model.upstreamModel ?? model.id,
260
+ providerOptions: createProviderOptions(provider, {
261
+ ...providerDefaults,
262
+ ...model.options
263
+ }, sendReasoning)
264
+ }));
265
+ const configuredModel = (id) => models.find((model) => model.id === id);
266
+ const defaultModelId = chatDefaults[0].id;
267
+ const memoryModelId = (memoryModels[0] ?? chatDefaults[0]).id;
268
+ const taskModelId = taskDefaults[0]?.id;
269
+ const providerApiKey = activeProvider.apiKeyEnv ? getValue(env, activeProvider.apiKeyEnv) : void 0;
270
+ const memoryModel = configuredModel(memoryModelId);
271
+ const memoryModelConfig = provider === "lmstudio" ? {
272
+ providerId: "lmstudio",
273
+ modelId: memoryModel.upstreamModelId,
274
+ url: activeProvider.baseUrl,
275
+ ...providerApiKey ? { apiKey: providerApiKey } : {}
276
+ } : provider === "azure-openai" ? `${provider}/${memoryModel.upstreamModelId}` : {
277
+ id: `${provider}/${memoryModel.upstreamModelId}`,
278
+ ...providerApiKey ? { apiKey: providerApiKey } : {}
279
+ };
280
+ const azure = provider === "azure-openai" ? {
281
+ resourceName: activeProvider.resourceName,
282
+ apiKey: providerApiKey,
283
+ apiVersion: activeProvider.apiVersion,
284
+ discoverModels: activeProvider.discoverModels,
285
+ management: activeProvider.management ? {
286
+ tenantId: activeProvider.management.tenantId,
287
+ clientId: activeProvider.management.clientId,
288
+ clientSecret: getValue(env, activeProvider.management.clientSecretEnv) ?? "",
289
+ subscriptionId: activeProvider.management.subscriptionId,
290
+ resourceGroup: activeProvider.management.resourceGroup
291
+ } : void 0
292
+ } : void 0;
293
+ const lmstudio = provider === "lmstudio" ? {
294
+ baseUrl: activeProvider.baseUrl,
295
+ ...providerApiKey ? { apiKey: providerApiKey } : {}
296
+ } : void 0;
297
+ const missingProviderSecret = activeProvider.apiKeyEnv && !providerApiKey && !(provider === "lmstudio" && activeProvider.apiKeyOptional);
298
+ const missingManagementSecret = provider === "azure-openai" && activeProvider.discoverModels && (!activeProvider.management || !azure?.management?.clientSecret);
299
+ const readinessError = requireStorage && !getValue(env, "SURVEY_ASSISTANT_DATABASE_URL") && !getValue(env, "DATABASE_URL") ? "Survey assistant storage is not configured." : missingProviderSecret ? `The provider credential ${activeProvider.apiKeyEnv} is not configured for the survey assistant.` : missingManagementSecret ? "Azure deployment discovery requires complete management configuration and credentials." : null;
300
+ const configuredMaxSteps = document.execution?.maxSteps ?? DEFAULT_MAX_STEPS;
301
+ return {
302
+ provider,
303
+ providerApiKey,
304
+ defaultModelId,
305
+ memoryModelId,
306
+ taskModelId,
307
+ modelIds: chatModels.map((model) => model.id),
308
+ models,
309
+ modelCatalogTtlMs: document.modelCatalogTtlMs ?? DEFAULT_CATALOG_TTL_MS,
310
+ azure,
311
+ lmstudio,
312
+ enabled: resolveConfiguredEnabled(env, document.enabled, requireExperimentalIdentityOptIn),
313
+ readinessError,
314
+ requestLimits: {
315
+ maxAttachmentBytes: document.requestLimits?.maxAttachmentBytes ?? SURVEY_ASSISTANT_DEFAULT_REQUEST_LIMITS.maxAttachmentBytes,
316
+ maxAttachments: document.requestLimits?.maxAttachments ?? SURVEY_ASSISTANT_DEFAULT_REQUEST_LIMITS.maxAttachments,
317
+ maxRequestBytes: document.requestLimits?.maxRequestBytes ?? SURVEY_ASSISTANT_DEFAULT_REQUEST_LIMITS.maxRequestBytes,
318
+ maxTextPartChars: document.requestLimits?.maxTextPartChars ?? SURVEY_ASSISTANT_DEFAULT_REQUEST_LIMITS.maxTextPartChars,
319
+ maxTotalAttachmentBytes: document.requestLimits?.maxTotalAttachmentBytes ?? SURVEY_ASSISTANT_DEFAULT_REQUEST_LIMITS.maxTotalAttachmentBytes
320
+ },
321
+ execution: {
322
+ firstResponseTimeoutMs: document.execution?.firstResponseTimeoutMs ?? DEFAULT_FIRST_RESPONSE_TIMEOUT_MS,
323
+ idleTimeoutMs: document.execution?.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS,
324
+ maxConcurrentRequests: document.execution?.maxConcurrentRequests ?? 4,
325
+ maxDurationMs: document.execution?.maxDurationMs ?? DEFAULT_MAX_DURATION_MS,
326
+ maxSteps: Math.min(configuredMaxSteps, HARD_MAX_STEPS),
327
+ providerOptions: configuredModel(defaultModelId).providerOptions,
328
+ sendReasoning
329
+ },
330
+ observationalMemory: memoryEnabled ? createSurveyAssistantObservationalMemoryOptions({
331
+ model: memoryModelConfig,
332
+ temporalMarkers: document.memory?.temporalMarkers ?? false,
333
+ observation: {
334
+ messageTokens: document.memory?.messageTokens ?? SURVEY_ASSISTANT_OBSERVATIONAL_MEMORY_DEFAULTS.messageTokens,
335
+ bufferOnIdle: document.memory?.bufferOnIdle ?? false,
336
+ observeAttachments: false
337
+ },
338
+ reflection: { observationTokens: document.memory?.observationTokens ?? SURVEY_ASSISTANT_OBSERVATIONAL_MEMORY_DEFAULTS.observationTokens }
339
+ }) : false
340
+ };
341
+ };
78
342
  const parseSurveyAssistantEnvironment = (env, { defaultLmStudioModel, defaultMistralModel = "mistral-medium-latest", defaultOpenAIModel = "gpt-5.4-nano", defaultProvider = "openai", requireExperimentalIdentityOptIn = false, requireStorage = true } = {}) => {
79
343
  const provider = parseProvider(env, defaultProvider);
80
344
  const modelIdOptions = { allowNestedId: provider === "lmstudio" };
@@ -122,7 +386,7 @@ const parseSurveyAssistantEnvironment = (env, { defaultLmStudioModel, defaultMis
122
386
  const azure = provider === "azure-openai" ? {
123
387
  resourceName: getValue(env, "AZURE_RESOURCE_NAME"),
124
388
  apiKey: getValue(env, "AZURE_API_KEY"),
125
- apiVersion: getValue(env, "SURVEY_ASSISTANT_AZURE_API_VERSION") ?? "v1",
389
+ apiVersion: getEnum(env, "SURVEY_ASSISTANT_AZURE_API_VERSION", ["v1", "preview"]) ?? "v1",
126
390
  discoverModels: getBoolean(env, "SURVEY_ASSISTANT_AZURE_DISCOVER_MODELS", false),
127
391
  management: parseAzureManagement(env)
128
392
  } : void 0;
@@ -130,8 +394,14 @@ const parseSurveyAssistantEnvironment = (env, { defaultLmStudioModel, defaultMis
130
394
  baseUrl: getValue(env, "SURVEY_ASSISTANT_LMSTUDIO_BASE_URL") ?? "http://127.0.0.1:1234/v1",
131
395
  apiKey: getValue(env, "SURVEY_ASSISTANT_LMSTUDIO_API_KEY")
132
396
  } : void 0;
397
+ const providerApiKey = provider === "openai" ? getValue(env, "OPENAI_API_KEY") : provider === "mistral" ? getValue(env, "MISTRAL_API_KEY") : provider === "lmstudio" ? getValue(env, "SURVEY_ASSISTANT_LMSTUDIO_API_KEY") : getValue(env, "AZURE_API_KEY");
133
398
  const memoryModelId = getOptionalSameProviderModelId(env, "SURVEY_ASSISTANT_MEMORY_MODEL", modelIdOptions) ?? defaultModelId;
134
- const memoryModel = `${provider}/${memoryModelId}`;
399
+ const memoryModel = provider === "lmstudio" ? {
400
+ providerId: "lmstudio",
401
+ modelId: memoryModelId,
402
+ url: lmstudio.baseUrl,
403
+ ...providerApiKey ? { apiKey: providerApiKey } : {}
404
+ } : provider === "azure-openai" ? `${provider}/${memoryModelId}` : `${provider}/${memoryModelId}`;
135
405
  const observationalMemory = getBoolean(env, "SURVEY_ASSISTANT_MEMORY_ENABLED", true) ? createSurveyAssistantObservationalMemoryOptions({
136
406
  model: memoryModel,
137
407
  temporalMarkers: getBoolean(env, "SURVEY_ASSISTANT_MEMORY_TEMPORAL_MARKERS", false),
@@ -143,14 +413,22 @@ const parseSurveyAssistantEnvironment = (env, { defaultLmStudioModel, defaultMis
143
413
  reflection: { observationTokens: getPositiveNumber(env, "SURVEY_ASSISTANT_MEMORY_OBSERVATION_TOKENS", SURVEY_ASSISTANT_OBSERVATIONAL_MEMORY_DEFAULTS.observationTokens) }
144
414
  }) : false;
145
415
  const configuredMaxSteps = getPositiveNumber(env, "SURVEY_ASSISTANT_MAX_STEPS", DEFAULT_MAX_STEPS);
146
- const enabledSetting = getValue(env, "SURVEY_ASSISTANT_ENABLED")?.toLowerCase();
147
- if (enabledSetting !== void 0 && enabledSetting !== "true" && enabledSetting !== "false") throw new Error("SURVEY_ASSISTANT_ENABLED must be \"true\" or \"false\".");
148
- const enabled = enabledSetting === "false" ? false : enabledSetting === "true" ? !requireExperimentalIdentityOptIn || env.NODE_ENV === "development" || getBoolean(env, "SURVEY_ASSISTANT_ALLOW_EXPERIMENTAL_IDENTITY", false) : env.NODE_ENV === "development";
416
+ const enabled = resolveConfiguredEnabled(env, void 0, requireExperimentalIdentityOptIn);
149
417
  return {
150
418
  provider,
151
419
  defaultModelId,
152
420
  memoryModelId,
153
421
  modelIds,
422
+ models: [...new Set([
423
+ ...modelIds,
424
+ ...taskModelId ? [taskModelId] : [],
425
+ memoryModelId
426
+ ])].map((id) => ({
427
+ id,
428
+ label: id,
429
+ upstreamModelId: id,
430
+ providerOptions
431
+ })),
154
432
  modelCatalogTtlMs: getPositiveNumber(env, "SURVEY_ASSISTANT_MODEL_CATALOG_TTL_MS", DEFAULT_CATALOG_TTL_MS),
155
433
  azure,
156
434
  lmstudio,
@@ -185,18 +463,30 @@ const parseSurveyAssistantEnvironment = (env, { defaultLmStudioModel, defaultMis
185
463
  //#endregion
186
464
  //#region src/server/runtime.ts
187
465
  const createSurveyAssistantModelRouter = (config) => {
466
+ const configuredModels = new Map(config.models?.map((model) => [model.id, model]));
467
+ const getConfiguredModel = (modelId) => configuredModels.get(modelId) ?? {
468
+ id: modelId,
469
+ label: modelId,
470
+ upstreamModelId: modelId,
471
+ providerOptions: config.execution.providerOptions
472
+ };
188
473
  const toProviderModel = (modelId, configName) => {
474
+ const upstreamModelId = getConfiguredModel(modelId).upstreamModelId;
189
475
  if (config.provider === "lmstudio") {
190
476
  if (!config.lmstudio) throw new Error("LM Studio configuration is missing for the lmstudio provider.");
191
477
  return {
192
478
  providerId: "lmstudio",
193
- modelId,
479
+ modelId: upstreamModelId,
194
480
  url: config.lmstudio.baseUrl,
195
481
  ...config.lmstudio.apiKey ? { apiKey: config.lmstudio.apiKey } : {}
196
482
  };
197
483
  }
198
- if (modelId.includes("/")) throw new Error(`${configName} must be a model or deployment id without a provider prefix. All survey assistant models use the configured provider.`);
199
- return `${config.provider}/${modelId}`;
484
+ if (upstreamModelId.includes("/")) throw new Error(`${configName} must be a model or deployment id without a provider prefix. All survey assistant models use the configured provider.`);
485
+ const id = `${config.provider}/${upstreamModelId}`;
486
+ return config.providerApiKey && config.provider !== "azure-openai" ? {
487
+ id,
488
+ apiKey: config.providerApiKey
489
+ } : id;
200
490
  };
201
491
  const defaultModel = toProviderModel(config.defaultModelId, "defaultModelId");
202
492
  const chatModelIds = config.modelIds.map((modelId) => {
@@ -207,13 +497,13 @@ const createSurveyAssistantModelRouter = (config) => {
207
497
  const taskModel = config.taskModelId ? toProviderModel(config.taskModelId, "taskModelId") : void 0;
208
498
  const memoryModel = toProviderModel(config.memoryModelId, "memoryModelId");
209
499
  if (config.observationalMemory !== false) {
210
- const configuredMemoryModel = `${config.provider}/${config.memoryModelId}`;
211
- if (typeof config.observationalMemory.model !== "string" || config.observationalMemory.model !== configuredMemoryModel || config.observationalMemory.observation?.model !== void 0 || config.observationalMemory.reflection?.model !== void 0) throw new Error("The standard runtime requires observationalMemory to use memoryModelId for both observation and reflection. Use the low-level Agent factory for custom memory model routing.");
500
+ const configuredMemoryModel = toProviderModel(config.memoryModelId, "memoryModelId");
501
+ if (JSON.stringify(config.observationalMemory.model) !== JSON.stringify(configuredMemoryModel) || config.observationalMemory.observation?.model !== void 0 || config.observationalMemory.reflection?.model !== void 0) throw new Error("The standard runtime requires observationalMemory to use memoryModelId for both observation and reflection. Use the low-level Agent factory for custom memory model routing.");
212
502
  }
213
503
  const deploymentIds = [...new Set([
214
- ...chatModelIds,
215
- ...config.taskModelId ? [config.taskModelId] : [],
216
- config.memoryModelId
504
+ ...chatModelIds.map((id) => getConfiguredModel(id).upstreamModelId),
505
+ ...config.taskModelId ? [getConfiguredModel(config.taskModelId).upstreamModelId] : [],
506
+ getConfiguredModel(config.memoryModelId).upstreamModelId
217
507
  ])];
218
508
  const azureGateway = config.azure ? new AzureOpenAIGateway({
219
509
  resourceName: config.azure.resourceName ?? "",
@@ -228,14 +518,18 @@ const createSurveyAssistantModelRouter = (config) => {
228
518
  let ids = chatModelIds;
229
519
  if (azureGateway && config.azure?.discoverModels) try {
230
520
  const providers = await azureGateway.fetchProviders();
231
- ids = [...new Set([...chatModelIds, ...providers["azure-openai"]?.models ?? []])];
521
+ const configuredUpstreamIds = new Set(chatModelIds.map((id) => getConfiguredModel(id).upstreamModelId));
522
+ const discoveredIds = (providers["azure-openai"]?.models ?? []).filter((id) => !configuredUpstreamIds.has(id));
523
+ ids = [...new Set([...chatModelIds, ...discoveredIds])];
232
524
  } catch {}
233
525
  const value = {
234
526
  defaultModelId: config.defaultModelId,
235
- models: ids.map((id) => ({
236
- id,
237
- label: id
238
- }))
527
+ models: ids.map((id) => {
528
+ return {
529
+ id,
530
+ label: getConfiguredModel(id).label
531
+ };
532
+ })
239
533
  };
240
534
  cachedCatalog = {
241
535
  expiresAt: Date.now() + config.modelCatalogTtlMs,
@@ -248,7 +542,9 @@ const createSurveyAssistantModelRouter = (config) => {
248
542
  const id = requestedModelId ?? catalog.defaultModelId;
249
543
  return catalog.models.some((model) => model.id === id) ? {
250
544
  id,
251
- model: toProviderModel(id, "requestedModelId")
545
+ model: toProviderModel(id, "requestedModelId"),
546
+ providerName: config.provider,
547
+ ...getConfiguredModel(id).providerOptions ? { providerOptions: getConfiguredModel(id).providerOptions } : {}
252
548
  } : null;
253
549
  };
254
550
  return {
@@ -261,7 +557,9 @@ const createSurveyAssistantModelRouter = (config) => {
261
557
  resolveModel: async ({ requestedModelId }) => resolveRequestedModel(requestedModelId),
262
558
  resolveTaskModel: async ({ requestedModelId }) => config.taskModelId ? {
263
559
  id: config.taskModelId,
264
- model: taskModel
560
+ model: taskModel,
561
+ providerName: config.provider,
562
+ ...getConfiguredModel(config.taskModelId).providerOptions ? { providerOptions: getConfiguredModel(config.taskModelId).providerOptions } : {}
265
563
  } : resolveRequestedModel(requestedModelId),
266
564
  taskModel
267
565
  };
@@ -385,6 +683,6 @@ const createSurveyAssistantRuntime = (config, runtimeOptions = {}) => {
385
683
  };
386
684
  };
387
685
  //#endregion
388
- export { createSurveyAssistantModelRouter, createSurveyAssistantRuntime, createSurveyAssistantRuntimeComponents, createSurveyAssistantRuntimeHandlers, parseSurveyAssistantEnvironment, resolveSurveyAssistantProviderOptionsKey };
686
+ export { createSurveyAssistantModelRouter, createSurveyAssistantRuntime, createSurveyAssistantRuntimeComponents, createSurveyAssistantRuntimeHandlers, parseSurveyAssistantConfigurationDocument, parseSurveyAssistantEnvironment, resolveSurveyAssistantProviderOptionsKey, surveyAssistantConfigurationDocumentSchema };
389
687
 
390
688
  //# sourceMappingURL=server-runtime.mjs.map