@case-framework/survey-assistant 0.1.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.
- package/README.md +212 -0
- package/dist/authoring-references-Cy8J-DWt.d.mts +48 -0
- package/dist/authoring-references-Cy8J-DWt.d.mts.map +1 -0
- package/dist/authoring-references-X6uRaWuf.mjs +68 -0
- package/dist/authoring-references-X6uRaWuf.mjs.map +1 -0
- package/dist/capabilities-B6tvE7fK.mjs +66 -0
- package/dist/capabilities-B6tvE7fK.mjs.map +1 -0
- package/dist/capabilities-DvSKtjAw.d.mts +182 -0
- package/dist/capabilities-DvSKtjAw.d.mts.map +1 -0
- package/dist/capabilities-default.d.mts +15 -0
- package/dist/capabilities-default.d.mts.map +1 -0
- package/dist/capabilities-default.mjs +347 -0
- package/dist/capabilities-default.mjs.map +1 -0
- package/dist/constants-CFUWrRtl.mjs +7 -0
- package/dist/constants-CFUWrRtl.mjs.map +1 -0
- package/dist/constants-Jw0k8ojS.d.mts +67 -0
- package/dist/constants-Jw0k8ojS.d.mts.map +1 -0
- package/dist/controller-proxy-BRDusFiO.d.mts +57 -0
- package/dist/controller-proxy-BRDusFiO.d.mts.map +1 -0
- package/dist/controller-proxy-Duxo2IFE.mjs +92 -0
- package/dist/controller-proxy-Duxo2IFE.mjs.map +1 -0
- package/dist/digest-BsoVq49o.d.mts +9 -0
- package/dist/digest-BsoVq49o.d.mts.map +1 -0
- package/dist/digest.d.mts +2 -0
- package/dist/digest.mjs +20 -0
- package/dist/digest.mjs.map +1 -0
- package/dist/engine-sPvuixWg.mjs +4857 -0
- package/dist/engine-sPvuixWg.mjs.map +1 -0
- package/dist/engine.d.mts +3 -0
- package/dist/engine.mjs +4 -0
- package/dist/index-BWNHkpkh.d.mts +187 -0
- package/dist/index-BWNHkpkh.d.mts.map +1 -0
- package/dist/index-CUqbBjkc.d.mts +641 -0
- package/dist/index-CUqbBjkc.d.mts.map +1 -0
- package/dist/index-MpEMQzTm.d.mts +123 -0
- package/dist/index-MpEMQzTm.d.mts.map +1 -0
- package/dist/index-TFtvBiSQ.d.mts +1149 -0
- package/dist/index-TFtvBiSQ.d.mts.map +1 -0
- package/dist/memory-thread-repository-CJkkVE2-.mjs +718 -0
- package/dist/memory-thread-repository-CJkkVE2-.mjs.map +1 -0
- package/dist/protocol-DV0ka9WT.mjs +1032 -0
- package/dist/protocol-DV0ka9WT.mjs.map +1 -0
- package/dist/protocol.d.mts +3 -0
- package/dist/protocol.mjs +2 -0
- package/dist/react-VuYe-cPh.mjs +521 -0
- package/dist/react-VuYe-cPh.mjs.map +1 -0
- package/dist/react-integration.d.mts +2 -0
- package/dist/react-integration.mjs +3 -0
- package/dist/react.d.mts +3 -0
- package/dist/react.mjs +4 -0
- package/dist/references/assistant-operations.md +287 -0
- package/dist/references/core-rules.md +11 -0
- package/dist/references/embedded-forms.md +80 -0
- package/dist/references/expressions.md +301 -0
- package/dist/references/item-types.md +364 -0
- package/dist/references/localization.md +25 -0
- package/dist/references/rich-text-content.md +193 -0
- package/dist/references/source-material-surveys.md +60 -0
- package/dist/references/survey-data-model.md +109 -0
- package/dist/references/survey-quality.md +23 -0
- package/dist/request-context-jcmXT_Q2.mjs +44 -0
- package/dist/request-context-jcmXT_Q2.mjs.map +1 -0
- package/dist/request-guardrails-C59IWnH8.mjs +73 -0
- package/dist/request-guardrails-C59IWnH8.mjs.map +1 -0
- package/dist/server-agent.d.mts +131 -0
- package/dist/server-agent.d.mts.map +1 -0
- package/dist/server-agent.mjs +229 -0
- package/dist/server-agent.mjs.map +1 -0
- package/dist/server-runtime.d.mts +123 -0
- package/dist/server-runtime.d.mts.map +1 -0
- package/dist/server-runtime.mjs +296 -0
- package/dist/server-runtime.mjs.map +1 -0
- package/dist/server-tasks.d.mts +78 -0
- package/dist/server-tasks.d.mts.map +1 -0
- package/dist/server-tasks.mjs +253 -0
- package/dist/server-tasks.mjs.map +1 -0
- package/dist/server-tools.d.mts +2 -0
- package/dist/server-tools.mjs +2 -0
- package/dist/server.d.mts +52 -0
- package/dist/server.d.mts.map +1 -0
- package/dist/server.mjs +6 -0
- package/dist/storage-postgres.d.mts +37 -0
- package/dist/storage-postgres.d.mts.map +1 -0
- package/dist/storage-postgres.mjs +167 -0
- package/dist/storage-postgres.mjs.map +1 -0
- package/dist/thread-documents-DamIq9Od.d.mts +91 -0
- package/dist/thread-documents-DamIq9Od.d.mts.map +1 -0
- package/dist/thread-handlers-DpynUc64.d.mts +112 -0
- package/dist/thread-handlers-DpynUc64.d.mts.map +1 -0
- package/dist/tools-Hz2p7vyv.mjs +1879 -0
- package/dist/tools-Hz2p7vyv.mjs.map +1 -0
- package/dist/ui.css +2 -0
- package/dist/ui.d.mts +63 -0
- package/dist/ui.d.mts.map +1 -0
- package/dist/ui.mjs +2238 -0
- package/dist/ui.mjs.map +1 -0
- package/package.json +166 -0
- package/ui.css.d.ts +3 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { C as surveyAssistantTaskRequestSchema } from "./protocol-DV0ka9WT.mjs";
|
|
2
|
+
import { n as SURVEY_ASSISTANT_TASK_AGENT_ID } from "./constants-CFUWrRtl.mjs";
|
|
3
|
+
import { n as surveyAuthoringReferences } from "./authoring-references-X6uRaWuf.mjs";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { RequestContext } from "@mastra/core/request-context";
|
|
6
|
+
import { Agent } from "@mastra/core/agent";
|
|
7
|
+
//#region src/server/tasks.ts
|
|
8
|
+
const createSurveyAssistantTaskAgent = ({ model }) => new Agent({
|
|
9
|
+
id: SURVEY_ASSISTANT_TASK_AGENT_ID,
|
|
10
|
+
name: "Survey Assistant Tasks",
|
|
11
|
+
instructions: "Perform the supplied bounded survey-authoring task and return only its requested structured output.",
|
|
12
|
+
model
|
|
13
|
+
});
|
|
14
|
+
const BASE_TASK_INSTRUCTIONS = [
|
|
15
|
+
"You perform one bounded CASE Survey Editor AI task and return only the requested structured result.",
|
|
16
|
+
"The supplied task context was derived from the current canonical survey document snapshot. Use it as current survey context, but do not mutate it and do not claim that any editor change was applied.",
|
|
17
|
+
"Follow the supplied CASE authoring references where relevant. Do not invent item types, locales, ids, or capabilities that are absent from the task input and context.",
|
|
18
|
+
"Keep generated respondent-facing wording neutral, concise, and consistent with the requested locale and surrounding survey content."
|
|
19
|
+
];
|
|
20
|
+
const runSurveyAssistantTask = async ({ agent, taskId, input, context, schema, instructions, referenceTopics = [], requestContext, providerOptions, abortSignal }) => {
|
|
21
|
+
const references = referenceTopics.map((topic) => ({
|
|
22
|
+
topic,
|
|
23
|
+
title: surveyAuthoringReferences[topic].title,
|
|
24
|
+
content: surveyAuthoringReferences[topic].content
|
|
25
|
+
}));
|
|
26
|
+
const response = await agent.generate(JSON.stringify({
|
|
27
|
+
taskId,
|
|
28
|
+
input,
|
|
29
|
+
currentSurveyContext: context
|
|
30
|
+
}), {
|
|
31
|
+
instructions: [
|
|
32
|
+
...BASE_TASK_INSTRUCTIONS,
|
|
33
|
+
...instructions,
|
|
34
|
+
...references.map((entry) => `Reference: ${entry.title}\n${entry.content}`)
|
|
35
|
+
],
|
|
36
|
+
activeTools: [],
|
|
37
|
+
inputProcessors: [],
|
|
38
|
+
maxSteps: 1,
|
|
39
|
+
structuredOutput: {
|
|
40
|
+
schema,
|
|
41
|
+
errorStrategy: "strict"
|
|
42
|
+
},
|
|
43
|
+
...requestContext ? { requestContext } : {},
|
|
44
|
+
...providerOptions ? { providerOptions } : {},
|
|
45
|
+
...abortSignal ? { abortSignal } : {}
|
|
46
|
+
});
|
|
47
|
+
return schema.parse(response.object);
|
|
48
|
+
};
|
|
49
|
+
const keySuggestionValueSchema = z.object({
|
|
50
|
+
text: z.string().min(1),
|
|
51
|
+
rationale: z.string().optional()
|
|
52
|
+
});
|
|
53
|
+
const keySuggestionCategorySchema = z.enum([
|
|
54
|
+
"survey-pattern",
|
|
55
|
+
"compact",
|
|
56
|
+
"preferred",
|
|
57
|
+
"fair"
|
|
58
|
+
]);
|
|
59
|
+
const keySuggestionSchema = z.object({
|
|
60
|
+
surveyPattern: keySuggestionValueSchema.describe("A key that follows the strongest naming and numbering pattern in the current survey."),
|
|
61
|
+
compact: keySuggestionValueSchema.extend({ text: z.string().min(2).max(5).regex(/^[A-Z][A-Z0-9]{1,4}$/).describe("A recognizable 2-5 character uppercase abbreviation.") }),
|
|
62
|
+
preferred: keySuggestionValueSchema.describe("The key the model considers clearest without a category-specific naming constraint."),
|
|
63
|
+
fair: keySuggestionValueSchema.extend({ text: z.string().min(1).max(32).regex(/^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/).describe("A FAIR-by-design lowercase snake_case variable name.") }),
|
|
64
|
+
alternatives: z.array(keySuggestionValueSchema.extend({ category: keySuggestionCategorySchema })).max(2)
|
|
65
|
+
});
|
|
66
|
+
const labelSuggestionSchema = z.object({ suggestions: z.array(z.object({ text: z.string().min(1) })) });
|
|
67
|
+
const translationsSchema = z.object({ translations: z.record(z.string(), z.record(z.string(), z.string())) });
|
|
68
|
+
const clampLimit = (value, fallback, maximum) => Math.min(Math.max(1, value ?? fallback), maximum);
|
|
69
|
+
const sanitizeCodingKey = (value) => value.trim().replace(/[.\s-]+/g, "_").replace(/[^A-Za-z0-9_]+/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
|
|
70
|
+
const getCodingKeyIdentity = (value) => sanitizeCodingKey(value).toLocaleLowerCase();
|
|
71
|
+
const invocationInstruction = (mode) => mode === "background" ? "This is a background invocation. Be efficient, but do not relax task conventions, completeness, or output quality." : "This is an explicit user invocation. Prioritize quality and useful variation.";
|
|
72
|
+
const runSurveyAssistantSuggestItemKeyTask = async (input, options) => {
|
|
73
|
+
const maxSuggestions = Math.min(Math.max(4, input.maxSuggestions ?? 6), 6);
|
|
74
|
+
const result = await runSurveyAssistantTask({
|
|
75
|
+
...options,
|
|
76
|
+
taskId: "suggest-item-key",
|
|
77
|
+
input,
|
|
78
|
+
schema: keySuggestionSchema,
|
|
79
|
+
instructions: [
|
|
80
|
+
"Generate coding keys for the focused survey item, not editor labels or respondent-facing text.",
|
|
81
|
+
"Infer the dominant topic from the focused item's visible text, descendants, hierarchy, and draft key.",
|
|
82
|
+
"The input currentKey and draftKey, plus the focused item's key and fullKey in currentSurveyContext, identify the value being replaced. They may provide topic hints, but they are not evidence of an established naming or numbering pattern.",
|
|
83
|
+
"Use only currentSurveyContext.naming.keyExamples and sibling keys from other items to infer the survey's established naming pattern. Pay particular attention to prefixes, casing, separators, numeric sequences, and zero padding.",
|
|
84
|
+
"Treat a numeric pattern as established only when at least one other survey item supports it. For example, another item Q1_APPLES can support a topic-appropriate Q2_... key, while Q1_APPLES and Q2_ORANGES support Q3_.... The focused item's current key choice_1 by itself does not support choice_2 or a numeric suffix in other suggestions.",
|
|
85
|
+
"Return one surveyPattern key that follows the strongest detected local pattern. Preserve that pattern's casing and increment a clear sequence rather than copying an existing number. If no meaningful pattern exists, use a consistent descriptive key.",
|
|
86
|
+
"Return one compact key: a recognizable 2-5 character uppercase abbreviation using only A-Z and digits.",
|
|
87
|
+
"Return one preferred key: the key you consider clearest and most useful without category-specific naming constraints, while still using only letters, digits, and underscores.",
|
|
88
|
+
"Return one fair key following these FAIR-by-design rules: start with a letter; use lowercase ASCII letters, digits, and underscores only; use lowercase snake_case; stay at or below 32 characters; avoid programming/database reserved words; prefer a stable, language-neutral English concept name; use established instrument prefixes and sortable item numbers when applicable; distinguish raw from derived variables. Meaning belongs in metadata, so do not turn it into a sentence.",
|
|
89
|
+
`You may return up to ${Math.max(0, maxSuggestions - 4)} genuinely useful alternatives when another category has more than one strong candidate. Tag each alternative with its category.`,
|
|
90
|
+
"Never repeat the same suggestion, including case-only or punctuation-only variations.",
|
|
91
|
+
"Do not return the current key, a sibling key, or a semantically unrelated abbreviation.",
|
|
92
|
+
`Return between 4 and ${maxSuggestions} distinct suggestions in total.`,
|
|
93
|
+
invocationInstruction(options.mode)
|
|
94
|
+
]
|
|
95
|
+
});
|
|
96
|
+
const excluded = new Set([input.currentKey, ...input.siblingKeys].map(getCodingKeyIdentity).filter(Boolean));
|
|
97
|
+
const seen = /* @__PURE__ */ new Set();
|
|
98
|
+
return { suggestions: [
|
|
99
|
+
{
|
|
100
|
+
...result.surveyPattern,
|
|
101
|
+
category: "survey-pattern"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
...result.compact,
|
|
105
|
+
category: "compact"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
...result.preferred,
|
|
109
|
+
category: "preferred"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
...result.fair,
|
|
113
|
+
category: "fair"
|
|
114
|
+
},
|
|
115
|
+
...result.alternatives
|
|
116
|
+
].flatMap((suggestion) => {
|
|
117
|
+
const text = sanitizeCodingKey(suggestion.text);
|
|
118
|
+
const identity = getCodingKeyIdentity(text);
|
|
119
|
+
if (!text || excluded.has(identity) || seen.has(identity)) return [];
|
|
120
|
+
seen.add(identity);
|
|
121
|
+
return [{
|
|
122
|
+
...suggestion,
|
|
123
|
+
text
|
|
124
|
+
}];
|
|
125
|
+
}).slice(0, maxSuggestions) };
|
|
126
|
+
};
|
|
127
|
+
const runSurveyAssistantSuggestItemLabelTask = async (input, options) => {
|
|
128
|
+
const maxSuggestions = clampLimit(input.maxSuggestions, 3, 10);
|
|
129
|
+
const locale = input.locale ?? options.context.survey.selectedLocale;
|
|
130
|
+
const result = await runSurveyAssistantTask({
|
|
131
|
+
...options,
|
|
132
|
+
taskId: "suggest-item-label",
|
|
133
|
+
input,
|
|
134
|
+
schema: labelSuggestionSchema,
|
|
135
|
+
instructions: [
|
|
136
|
+
"Suggest concise editor-only item labels, not coding keys and not respondent-facing question text.",
|
|
137
|
+
"Infer the item's purpose from its type, draft label, visible content, hierarchy, siblings, and descendants.",
|
|
138
|
+
"Use currentSurveyContext.naming.labelExamples to infer established capitalization, prefixes, abbreviations, delimiters, and typical length.",
|
|
139
|
+
"If existing label examples are available, the first suggestion must follow their dominant pattern while still describing the focused item accurately. Other suggestions may offer useful concise alternatives.",
|
|
140
|
+
"Do not copy the subject matter of an unrelated example merely to imitate its style, and do not return an existing unrelated label verbatim.",
|
|
141
|
+
`Write labels in locale ${locale}.`,
|
|
142
|
+
`Return at most ${maxSuggestions} distinct, specific, human-readable suggestions.`,
|
|
143
|
+
invocationInstruction(options.mode)
|
|
144
|
+
],
|
|
145
|
+
referenceTopics: ["core-rules"]
|
|
146
|
+
});
|
|
147
|
+
const normalizeLabel = (value) => value.trim().toLocaleLowerCase();
|
|
148
|
+
const excludedLabels = new Set([normalizeLabel(input.draftLabel), ...(options.context.naming?.labelExamples ?? []).map((example) => normalizeLabel(example.label))]);
|
|
149
|
+
const seen = /* @__PURE__ */ new Set();
|
|
150
|
+
return { suggestions: result.suggestions.flatMap((suggestion) => {
|
|
151
|
+
const text = suggestion.text.trim();
|
|
152
|
+
const normalizedText = normalizeLabel(text);
|
|
153
|
+
if (!text || excludedLabels.has(normalizedText) || seen.has(normalizedText)) return [];
|
|
154
|
+
seen.add(normalizedText);
|
|
155
|
+
return [{
|
|
156
|
+
...suggestion,
|
|
157
|
+
text
|
|
158
|
+
}];
|
|
159
|
+
}).slice(0, maxSuggestions) };
|
|
160
|
+
};
|
|
161
|
+
const getProtectedTokens = (value) => value.match(/\{\{[^{}]+\}\}|\{[^{}]+\}|\$\{[^{}]+\}|%\d*\$?[a-z]/gi) ?? [];
|
|
162
|
+
const runSurveyAssistantTranslateContentTask = async (input, options) => {
|
|
163
|
+
const result = await runSurveyAssistantTask({
|
|
164
|
+
...options,
|
|
165
|
+
taskId: "translate-content",
|
|
166
|
+
input,
|
|
167
|
+
schema: translationsSchema,
|
|
168
|
+
instructions: [
|
|
169
|
+
"Translate every supplied survey-content entry faithfully without adding explanations or omitting content.",
|
|
170
|
+
`Translate from ${input.sourceLocale} into exactly these target locales: ${input.targetLocales.join(", ")}.`,
|
|
171
|
+
"Use currentSurveyContext.translation.examples as a terminology and style reference when relevant. The supplied source entries remain authoritative.",
|
|
172
|
+
"Preserve meaning, register, survey terminology, punctuation, line breaks, response semantics, placeholders, interpolation tokens, URLs, and identifiers that should not be translated.",
|
|
173
|
+
"Keep repeated terminology consistent across all entries and target locales. Do not use a neighboring translation when its meaning differs.",
|
|
174
|
+
"Return plain strings keyed first by target locale and then by the original entry id. Return every requested locale and entry exactly once.",
|
|
175
|
+
invocationInstruction(options.mode)
|
|
176
|
+
],
|
|
177
|
+
referenceTopics: ["localization"]
|
|
178
|
+
});
|
|
179
|
+
const translations = {};
|
|
180
|
+
for (const locale of input.targetLocales) {
|
|
181
|
+
const entries = result.translations[locale];
|
|
182
|
+
if (!entries) throw new Error(`Translation result is missing locale ${locale}.`);
|
|
183
|
+
const translatedEntries = {};
|
|
184
|
+
for (const entry of input.entries) {
|
|
185
|
+
const translation = entries[entry.id];
|
|
186
|
+
if (typeof translation !== "string" || translation.trim().length === 0) throw new Error(`Translation result is missing entry ${entry.id} for locale ${locale}.`);
|
|
187
|
+
const sourceTokens = getProtectedTokens(entry.text).sort();
|
|
188
|
+
const translatedTokens = getProtectedTokens(translation).sort();
|
|
189
|
+
if (sourceTokens.join("\0") !== translatedTokens.join("\0")) throw new Error(`Translation result changed protected tokens in entry ${entry.id} for locale ${locale}.`);
|
|
190
|
+
translatedEntries[entry.id] = translation;
|
|
191
|
+
}
|
|
192
|
+
translations[locale] = translatedEntries;
|
|
193
|
+
}
|
|
194
|
+
return { translations };
|
|
195
|
+
};
|
|
196
|
+
const MAX_TASK_REQUEST_BYTES = 512 * 1024;
|
|
197
|
+
const taskErrorResponse = (error) => {
|
|
198
|
+
const status = typeof error === "object" && error !== null && "status" in error && typeof error.status === "number" ? error.status : 400;
|
|
199
|
+
const message = error instanceof Error ? error.message : "The survey assistant task could not be completed.";
|
|
200
|
+
return Response.json({
|
|
201
|
+
code: status === 401 || status === 403 ? "authorization_failed" : "request_failed",
|
|
202
|
+
error: message
|
|
203
|
+
}, { status });
|
|
204
|
+
};
|
|
205
|
+
const createSurveyAssistantTaskHandler = ({ agent, authorize, getReadinessError, isEnabled, providerOptions, resolveModel }) => async (request) => {
|
|
206
|
+
try {
|
|
207
|
+
if (isEnabled && !await isEnabled(request)) return Response.json({
|
|
208
|
+
code: "request_failed",
|
|
209
|
+
error: "Survey assistant is disabled."
|
|
210
|
+
}, { status: 404 });
|
|
211
|
+
const identity = await authorize(request);
|
|
212
|
+
if (!identity?.resourceId?.trim()) throw Object.assign(/* @__PURE__ */ new Error("The host returned an invalid task identity."), { status: 500 });
|
|
213
|
+
const readinessError = await getReadinessError?.(request);
|
|
214
|
+
if (readinessError) return Response.json({
|
|
215
|
+
code: "request_failed",
|
|
216
|
+
error: readinessError
|
|
217
|
+
}, { status: 503 });
|
|
218
|
+
const text = await request.text();
|
|
219
|
+
if (new TextEncoder().encode(text).byteLength > MAX_TASK_REQUEST_BYTES) return Response.json({
|
|
220
|
+
code: "request_failed",
|
|
221
|
+
error: "The survey assistant task request is too large."
|
|
222
|
+
}, { status: 413 });
|
|
223
|
+
const task = surveyAssistantTaskRequestSchema.parse(JSON.parse(text));
|
|
224
|
+
const requestContext = new RequestContext();
|
|
225
|
+
if (resolveModel) {
|
|
226
|
+
const modelSelection = await resolveModel({
|
|
227
|
+
identity,
|
|
228
|
+
request,
|
|
229
|
+
requestedModelId: task.modelId
|
|
230
|
+
});
|
|
231
|
+
if (!modelSelection) return Response.json({
|
|
232
|
+
code: "request_failed",
|
|
233
|
+
error: "The selected survey assistant model is unavailable."
|
|
234
|
+
}, { status: 400 });
|
|
235
|
+
requestContext.set("modelSelection", modelSelection);
|
|
236
|
+
}
|
|
237
|
+
const runtime = {
|
|
238
|
+
agent: typeof agent === "function" ? await agent() : agent,
|
|
239
|
+
context: task.context,
|
|
240
|
+
mode: task.mode,
|
|
241
|
+
requestContext,
|
|
242
|
+
providerOptions
|
|
243
|
+
};
|
|
244
|
+
const result = task.taskId === "suggest-item-key" ? await runSurveyAssistantSuggestItemKeyTask(task.input, runtime) : task.taskId === "suggest-item-label" ? await runSurveyAssistantSuggestItemLabelTask(task.input, runtime) : await runSurveyAssistantTranslateContentTask(task.input, runtime);
|
|
245
|
+
return Response.json(result);
|
|
246
|
+
} catch (error) {
|
|
247
|
+
return taskErrorResponse(error);
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
//#endregion
|
|
251
|
+
export { createSurveyAssistantTaskAgent, createSurveyAssistantTaskHandler, runSurveyAssistantSuggestItemKeyTask, runSurveyAssistantSuggestItemLabelTask, runSurveyAssistantTask, runSurveyAssistantTranslateContentTask };
|
|
252
|
+
|
|
253
|
+
//# sourceMappingURL=server-tasks.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-tasks.mjs","names":[],"sources":["../src/server/tasks.ts"],"sourcesContent":["import { Agent, type AgentConfig, type AgentExecutionOptions } from \"@mastra/core/agent\";\nimport { RequestContext } from \"@mastra/core/request-context\";\nimport { z } from \"zod\";\nimport { surveyAssistantTaskRequestSchema } from \"../protocol\";\nimport type {\n SurveyAssistantSuggestItemKeyInput,\n SurveyAssistantSuggestItemKeyResult,\n SurveyAssistantKeySuggestionCategory,\n SurveyAssistantSuggestItemLabelInput,\n SurveyAssistantSuggestItemLabelResult,\n SurveyAssistantTaskInvocationMode,\n SurveyAssistantTaskContext,\n SurveyAssistantTranslateContentInput,\n SurveyAssistantTranslateContentResult,\n} from \"../protocol\";\nimport {\n surveyAuthoringReferences,\n type SurveyAuthoringReferenceTopic,\n} from \"./authoring-references\";\nimport type {\n SurveyAssistantModelSelection,\n SurveyAssistantRequestContext,\n} from \"./request-context\";\nimport { SURVEY_ASSISTANT_TASK_AGENT_ID } from \"./constants\";\n\ntype SurveyAssistantTaskAgentConfig = AgentConfig<\n typeof SURVEY_ASSISTANT_TASK_AGENT_ID,\n Record<string, never>,\n undefined,\n SurveyAssistantRequestContext\n>;\n\nexport interface CreateSurveyAssistantTaskAgentOptions {\n model: SurveyAssistantTaskAgentConfig[\"model\"];\n}\n\nexport const createSurveyAssistantTaskAgent = ({ model }: CreateSurveyAssistantTaskAgentOptions) =>\n new Agent<\n typeof SURVEY_ASSISTANT_TASK_AGENT_ID,\n Record<string, never>,\n undefined,\n SurveyAssistantRequestContext\n >({\n id: SURVEY_ASSISTANT_TASK_AGENT_ID,\n name: \"Survey Assistant Tasks\",\n instructions:\n \"Perform the supplied bounded survey-authoring task and return only its requested structured output.\",\n model,\n });\n\nexport interface RunSurveyAssistantTaskOptions<TSchema extends z.ZodType> {\n agent: Pick<Agent, \"generate\">;\n taskId: string;\n input: unknown;\n context: SurveyAssistantTaskContext;\n schema: TSchema;\n instructions: readonly string[];\n referenceTopics?: readonly SurveyAuthoringReferenceTopic[];\n requestContext?: RequestContext<SurveyAssistantRequestContext>;\n providerOptions?: AgentExecutionOptions[\"providerOptions\"];\n abortSignal?: AbortSignal;\n}\n\nconst BASE_TASK_INSTRUCTIONS = [\n \"You perform one bounded CASE Survey Editor AI task and return only the requested structured result.\",\n \"The supplied task context was derived from the current canonical survey document snapshot. Use it as current survey context, but do not mutate it and do not claim that any editor change was applied.\",\n \"Follow the supplied CASE authoring references where relevant. Do not invent item types, locales, ids, or capabilities that are absent from the task input and context.\",\n \"Keep generated respondent-facing wording neutral, concise, and consistent with the requested locale and surrounding survey content.\",\n] as const;\n\nexport const runSurveyAssistantTask = async <TSchema extends z.ZodType>({\n agent,\n taskId,\n input,\n context,\n schema,\n instructions,\n referenceTopics = [],\n requestContext,\n providerOptions,\n abortSignal,\n}: RunSurveyAssistantTaskOptions<TSchema>): Promise<z.output<TSchema>> => {\n const references = referenceTopics.map((topic) => ({\n topic,\n title: surveyAuthoringReferences[topic].title,\n content: surveyAuthoringReferences[topic].content,\n }));\n const response = await agent.generate(\n JSON.stringify({ taskId, input, currentSurveyContext: context }),\n {\n instructions: [\n ...BASE_TASK_INSTRUCTIONS,\n ...instructions,\n ...references.map((entry) => `Reference: ${entry.title}\\n${entry.content}`),\n ],\n activeTools: [],\n inputProcessors: [],\n maxSteps: 1,\n structuredOutput: {\n schema,\n errorStrategy: \"strict\",\n },\n ...(requestContext ? { requestContext } : {}),\n ...(providerOptions ? { providerOptions } : {}),\n ...(abortSignal ? { abortSignal } : {}),\n },\n );\n\n return schema.parse(response.object);\n};\n\nconst keySuggestionValueSchema = z.object({\n text: z.string().min(1),\n rationale: z.string().optional(),\n});\n\nconst keySuggestionCategorySchema = z.enum([\"survey-pattern\", \"compact\", \"preferred\", \"fair\"]);\n\nconst keySuggestionSchema = z.object({\n surveyPattern: keySuggestionValueSchema.describe(\n \"A key that follows the strongest naming and numbering pattern in the current survey.\",\n ),\n compact: keySuggestionValueSchema.extend({\n text: z\n .string()\n .min(2)\n .max(5)\n .regex(/^[A-Z][A-Z0-9]{1,4}$/)\n .describe(\"A recognizable 2-5 character uppercase abbreviation.\"),\n }),\n preferred: keySuggestionValueSchema.describe(\n \"The key the model considers clearest without a category-specific naming constraint.\",\n ),\n fair: keySuggestionValueSchema.extend({\n text: z\n .string()\n .min(1)\n .max(32)\n .regex(/^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/)\n .describe(\"A FAIR-by-design lowercase snake_case variable name.\"),\n }),\n alternatives: z\n .array(\n keySuggestionValueSchema.extend({\n category: keySuggestionCategorySchema,\n }),\n )\n .max(2),\n});\n\nconst labelSuggestionSchema = z.object({\n suggestions: z.array(\n z.object({\n text: z.string().min(1),\n }),\n ),\n});\n\nconst translationsSchema = z.object({\n translations: z.record(z.string(), z.record(z.string(), z.string())),\n});\n\nexport interface RunSurveyAssistantBuiltInTaskOptions {\n agent: Pick<Agent, \"generate\">;\n context: SurveyAssistantTaskContext;\n mode?: SurveyAssistantTaskInvocationMode;\n requestContext?: RequestContext<SurveyAssistantRequestContext>;\n providerOptions?: AgentExecutionOptions[\"providerOptions\"];\n abortSignal?: AbortSignal;\n}\n\nconst clampLimit = (value: number | undefined, fallback: number, maximum: number) =>\n Math.min(Math.max(1, value ?? fallback), maximum);\n\nconst sanitizeCodingKey = (value: string) =>\n value\n .trim()\n .replace(/[.\\s-]+/g, \"_\")\n .replace(/[^A-Za-z0-9_]+/g, \"_\")\n .replace(/_+/g, \"_\")\n .replace(/^_+|_+$/g, \"\");\n\nconst getCodingKeyIdentity = (value: string) => sanitizeCodingKey(value).toLocaleLowerCase();\n\nconst invocationInstruction = (mode: SurveyAssistantTaskInvocationMode | undefined) =>\n mode === \"background\"\n ? \"This is a background invocation. Be efficient, but do not relax task conventions, completeness, or output quality.\"\n : \"This is an explicit user invocation. Prioritize quality and useful variation.\";\n\nexport const runSurveyAssistantSuggestItemKeyTask = async (\n input: SurveyAssistantSuggestItemKeyInput,\n options: RunSurveyAssistantBuiltInTaskOptions,\n): Promise<SurveyAssistantSuggestItemKeyResult> => {\n const maxSuggestions = Math.min(Math.max(4, input.maxSuggestions ?? 6), 6);\n const result = await runSurveyAssistantTask({\n ...options,\n taskId: \"suggest-item-key\",\n input,\n schema: keySuggestionSchema,\n instructions: [\n \"Generate coding keys for the focused survey item, not editor labels or respondent-facing text.\",\n \"Infer the dominant topic from the focused item's visible text, descendants, hierarchy, and draft key.\",\n \"The input currentKey and draftKey, plus the focused item's key and fullKey in currentSurveyContext, identify the value being replaced. They may provide topic hints, but they are not evidence of an established naming or numbering pattern.\",\n \"Use only currentSurveyContext.naming.keyExamples and sibling keys from other items to infer the survey's established naming pattern. Pay particular attention to prefixes, casing, separators, numeric sequences, and zero padding.\",\n \"Treat a numeric pattern as established only when at least one other survey item supports it. For example, another item Q1_APPLES can support a topic-appropriate Q2_... key, while Q1_APPLES and Q2_ORANGES support Q3_.... The focused item's current key choice_1 by itself does not support choice_2 or a numeric suffix in other suggestions.\",\n \"Return one surveyPattern key that follows the strongest detected local pattern. Preserve that pattern's casing and increment a clear sequence rather than copying an existing number. If no meaningful pattern exists, use a consistent descriptive key.\",\n \"Return one compact key: a recognizable 2-5 character uppercase abbreviation using only A-Z and digits.\",\n \"Return one preferred key: the key you consider clearest and most useful without category-specific naming constraints, while still using only letters, digits, and underscores.\",\n \"Return one fair key following these FAIR-by-design rules: start with a letter; use lowercase ASCII letters, digits, and underscores only; use lowercase snake_case; stay at or below 32 characters; avoid programming/database reserved words; prefer a stable, language-neutral English concept name; use established instrument prefixes and sortable item numbers when applicable; distinguish raw from derived variables. Meaning belongs in metadata, so do not turn it into a sentence.\",\n `You may return up to ${Math.max(0, maxSuggestions - 4)} genuinely useful alternatives when another category has more than one strong candidate. Tag each alternative with its category.`,\n \"Never repeat the same suggestion, including case-only or punctuation-only variations.\",\n \"Do not return the current key, a sibling key, or a semantically unrelated abbreviation.\",\n `Return between 4 and ${maxSuggestions} distinct suggestions in total.`,\n invocationInstruction(options.mode),\n ],\n });\n\n const excluded = new Set(\n [input.currentKey, ...input.siblingKeys].map(getCodingKeyIdentity).filter(Boolean),\n );\n const seen = new Set<string>();\n const categorizedSuggestions: Array<{\n text: string;\n rationale?: string;\n category: SurveyAssistantKeySuggestionCategory;\n }> = [\n { ...result.surveyPattern, category: \"survey-pattern\" },\n { ...result.compact, category: \"compact\" },\n { ...result.preferred, category: \"preferred\" },\n { ...result.fair, category: \"fair\" },\n ...result.alternatives,\n ];\n const suggestions = categorizedSuggestions\n .flatMap((suggestion) => {\n const text = sanitizeCodingKey(suggestion.text);\n const identity = getCodingKeyIdentity(text);\n if (!text || excluded.has(identity) || seen.has(identity)) return [];\n seen.add(identity);\n return [{ ...suggestion, text }];\n })\n .slice(0, maxSuggestions);\n return { suggestions };\n};\n\nexport const runSurveyAssistantSuggestItemLabelTask = async (\n input: SurveyAssistantSuggestItemLabelInput,\n options: RunSurveyAssistantBuiltInTaskOptions,\n): Promise<SurveyAssistantSuggestItemLabelResult> => {\n const maxSuggestions = clampLimit(input.maxSuggestions, 3, 10);\n const locale = input.locale ?? options.context.survey.selectedLocale;\n const result = await runSurveyAssistantTask({\n ...options,\n taskId: \"suggest-item-label\",\n input,\n schema: labelSuggestionSchema,\n instructions: [\n \"Suggest concise editor-only item labels, not coding keys and not respondent-facing question text.\",\n \"Infer the item's purpose from its type, draft label, visible content, hierarchy, siblings, and descendants.\",\n \"Use currentSurveyContext.naming.labelExamples to infer established capitalization, prefixes, abbreviations, delimiters, and typical length.\",\n \"If existing label examples are available, the first suggestion must follow their dominant pattern while still describing the focused item accurately. Other suggestions may offer useful concise alternatives.\",\n \"Do not copy the subject matter of an unrelated example merely to imitate its style, and do not return an existing unrelated label verbatim.\",\n `Write labels in locale ${locale}.`,\n `Return at most ${maxSuggestions} distinct, specific, human-readable suggestions.`,\n invocationInstruction(options.mode),\n ],\n referenceTopics: [\"core-rules\"],\n });\n\n const normalizeLabel = (value: string) => value.trim().toLocaleLowerCase();\n const excludedLabels = new Set([\n normalizeLabel(input.draftLabel),\n ...(options.context.naming?.labelExamples ?? []).map((example) =>\n normalizeLabel(example.label),\n ),\n ]);\n const seen = new Set<string>();\n return {\n suggestions: result.suggestions\n .flatMap((suggestion) => {\n const text = suggestion.text.trim();\n const normalizedText = normalizeLabel(text);\n if (!text || excludedLabels.has(normalizedText) || seen.has(normalizedText)) return [];\n seen.add(normalizedText);\n return [{ ...suggestion, text }];\n })\n .slice(0, maxSuggestions),\n };\n};\n\nconst getProtectedTokens = (value: string) =>\n value.match(/\\{\\{[^{}]+\\}\\}|\\{[^{}]+\\}|\\$\\{[^{}]+\\}|%\\d*\\$?[a-z]/gi) ?? [];\n\nexport const runSurveyAssistantTranslateContentTask = async (\n input: SurveyAssistantTranslateContentInput,\n options: RunSurveyAssistantBuiltInTaskOptions,\n): Promise<SurveyAssistantTranslateContentResult> => {\n const result = await runSurveyAssistantTask({\n ...options,\n taskId: \"translate-content\",\n input,\n schema: translationsSchema,\n instructions: [\n \"Translate every supplied survey-content entry faithfully without adding explanations or omitting content.\",\n `Translate from ${input.sourceLocale} into exactly these target locales: ${input.targetLocales.join(\", \")}.`,\n \"Use currentSurveyContext.translation.examples as a terminology and style reference when relevant. The supplied source entries remain authoritative.\",\n \"Preserve meaning, register, survey terminology, punctuation, line breaks, response semantics, placeholders, interpolation tokens, URLs, and identifiers that should not be translated.\",\n \"Keep repeated terminology consistent across all entries and target locales. Do not use a neighboring translation when its meaning differs.\",\n \"Return plain strings keyed first by target locale and then by the original entry id. Return every requested locale and entry exactly once.\",\n invocationInstruction(options.mode),\n ],\n referenceTopics: [\"localization\"],\n });\n\n const translations: SurveyAssistantTranslateContentResult[\"translations\"] = {};\n for (const locale of input.targetLocales) {\n const entries = result.translations[locale];\n if (!entries) throw new Error(`Translation result is missing locale ${locale}.`);\n const translatedEntries: Record<string, string> = {};\n for (const entry of input.entries) {\n const translation = entries[entry.id];\n if (typeof translation !== \"string\" || translation.trim().length === 0) {\n throw new Error(`Translation result is missing entry ${entry.id} for locale ${locale}.`);\n }\n const sourceTokens = getProtectedTokens(entry.text).sort();\n const translatedTokens = getProtectedTokens(translation).sort();\n if (sourceTokens.join(\"\\u0000\") !== translatedTokens.join(\"\\u0000\")) {\n throw new Error(\n `Translation result changed protected tokens in entry ${entry.id} for locale ${locale}.`,\n );\n }\n translatedEntries[entry.id] = translation;\n }\n translations[locale] = translatedEntries;\n }\n return { translations };\n};\n\nconst MAX_TASK_REQUEST_BYTES = 512 * 1024;\n\nexport interface SurveyAssistantTaskAuthorizedIdentity {\n resourceId: string;\n}\n\nexport interface SurveyAssistantTaskModelResolutionInput {\n identity: SurveyAssistantTaskAuthorizedIdentity;\n request: Request;\n requestedModelId?: string;\n}\n\nexport interface CreateSurveyAssistantTaskHandlerOptions {\n agent:\n | Pick<Agent, \"generate\">\n | (() => Pick<Agent, \"generate\"> | Promise<Pick<Agent, \"generate\">>);\n authorize(\n request: Request,\n ): SurveyAssistantTaskAuthorizedIdentity | Promise<SurveyAssistantTaskAuthorizedIdentity>;\n getReadinessError?(request: Request): string | null | Promise<string | null>;\n isEnabled?(request: Request): boolean | Promise<boolean>;\n providerOptions?: AgentExecutionOptions[\"providerOptions\"];\n resolveModel?(\n input: SurveyAssistantTaskModelResolutionInput,\n ):\n | SurveyAssistantModelSelection\n | null\n | undefined\n | Promise<SurveyAssistantModelSelection | null | undefined>;\n}\n\nconst taskErrorResponse = (error: unknown) => {\n const status =\n typeof error === \"object\" &&\n error !== null &&\n \"status\" in error &&\n typeof error.status === \"number\"\n ? error.status\n : 400;\n const message =\n error instanceof Error ? error.message : \"The survey assistant task could not be completed.\";\n return Response.json(\n {\n code: status === 401 || status === 403 ? \"authorization_failed\" : \"request_failed\",\n error: message,\n },\n { status },\n );\n};\n\nexport const createSurveyAssistantTaskHandler =\n ({\n agent,\n authorize,\n getReadinessError,\n isEnabled,\n providerOptions,\n resolveModel,\n }: CreateSurveyAssistantTaskHandlerOptions) =>\n async (request: Request): Promise<Response> => {\n try {\n if (isEnabled && !(await isEnabled(request))) {\n return Response.json(\n { code: \"request_failed\", error: \"Survey assistant is disabled.\" },\n { status: 404 },\n );\n }\n const identity = await authorize(request);\n if (!identity?.resourceId?.trim()) {\n throw Object.assign(new Error(\"The host returned an invalid task identity.\"), {\n status: 500,\n });\n }\n\n const readinessError = await getReadinessError?.(request);\n if (readinessError) {\n return Response.json({ code: \"request_failed\", error: readinessError }, { status: 503 });\n }\n\n const text = await request.text();\n if (new TextEncoder().encode(text).byteLength > MAX_TASK_REQUEST_BYTES) {\n return Response.json(\n { code: \"request_failed\", error: \"The survey assistant task request is too large.\" },\n { status: 413 },\n );\n }\n const task = surveyAssistantTaskRequestSchema.parse(JSON.parse(text));\n\n const requestContext = new RequestContext<SurveyAssistantRequestContext>();\n if (resolveModel) {\n const modelSelection = await resolveModel({\n identity,\n request,\n requestedModelId: task.modelId,\n });\n if (!modelSelection) {\n return Response.json(\n {\n code: \"request_failed\",\n error: \"The selected survey assistant model is unavailable.\",\n },\n { status: 400 },\n );\n }\n requestContext.set(\"modelSelection\", modelSelection);\n }\n\n const resolvedAgent = typeof agent === \"function\" ? await agent() : agent;\n const runtime: RunSurveyAssistantBuiltInTaskOptions = {\n agent: resolvedAgent,\n context: task.context,\n mode: task.mode,\n requestContext,\n providerOptions,\n };\n const result =\n task.taskId === \"suggest-item-key\"\n ? await runSurveyAssistantSuggestItemKeyTask(task.input, runtime)\n : task.taskId === \"suggest-item-label\"\n ? await runSurveyAssistantSuggestItemLabelTask(task.input, runtime)\n : await runSurveyAssistantTranslateContentTask(task.input, runtime);\n return Response.json(result);\n } catch (error) {\n return taskErrorResponse(error);\n }\n };\n"],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { g as TurnChangeCollector } from "./index-CUqbBjkc.mjs";
|
|
2
|
+
import { a as SurveyAssistantThreadDocumentRepository, c as loadSurveyAssistantThreadAttachments, i as SurveyAssistantThreadDocumentContent, l as registerSurveyAssistantThreadAttachments, n as SurveyAssistantModelAttachment, o as getSurveyAssistantReplayableDocuments, r as SurveyAssistantThreadDocument, s as loadSurveyAssistantDocuments, t as SurveyAssistantAttachmentAccess, u as removeHistoricalSurveyAssistantAttachments } from "./thread-documents-DamIq9Od.mjs";
|
|
3
|
+
import { a as SurveyAssistantRequestContext, c as parseSurveyAssistantSnapshot, i as SurveyAssistantModelSelection, l as requireSurveyAssistantTurnState, n as SURVEY_ASSISTANT_TASK_AGENT_ID, o as SurveyAssistantSnapshotSource, r as SurveyAssistantIdentityContext, s as buildSurveyAssistantRequestContext, t as SURVEY_ASSISTANT_AGENT_ID } from "./constants-Jw0k8ojS.mjs";
|
|
4
|
+
import { _ as formatSurveyAssistantStreamError, a as createSurveyAssistantThreadHandlers, c as SurveyAssistantAuthorize, d as SurveyAssistantModelResolutionInput, f as SurveyAssistantResolveModel, g as describeSurveyAssistantStreamError, h as createSurveyAssistantChatHandler, i as SurveyAssistantThreadRepository, l as SurveyAssistantAuthorizedIdentity, m as SurveyAssistantTurnMetrics, n as SurveyAssistantStoredThread, o as SurveyAssistantAuthorizationError, p as SurveyAssistantStreamErrorContext, r as SurveyAssistantThreadIdentity, s as SurveyAssistantAuthorizationInput, t as CreateSurveyAssistantThreadHandlersOptions, u as SurveyAssistantChatHandlerOptions } from "./thread-handlers-DpynUc64.mjs";
|
|
5
|
+
import { n as surveyAuthoringReferenceTopics, r as surveyAuthoringReferences, t as SurveyAuthoringReferenceTopic } from "./authoring-references-Cy8J-DWt.mjs";
|
|
6
|
+
import { UIMessage, UIMessageChunk } from "ai";
|
|
7
|
+
import { MastraMemory } from "@mastra/core/memory";
|
|
8
|
+
|
|
9
|
+
//#region src/server/memory-thread-repository.d.ts
|
|
10
|
+
type ThreadMemory = Pick<MastraMemory, "createThread" | "deleteThread" | "getThreadById" | "listThreads" | "recall" | "updateThread">;
|
|
11
|
+
interface CreateMastraMemoryThreadRepositoryOptions {
|
|
12
|
+
getMemory(): ThreadMemory | Promise<ThreadMemory>;
|
|
13
|
+
threadDocuments?: SurveyAssistantThreadDocumentRepository;
|
|
14
|
+
}
|
|
15
|
+
declare const createMastraMemoryThreadRepository: ({
|
|
16
|
+
getMemory,
|
|
17
|
+
threadDocuments
|
|
18
|
+
}: CreateMastraMemoryThreadRepositoryOptions) => SurveyAssistantThreadRepository;
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/server/request-guardrails.d.ts
|
|
21
|
+
declare const SURVEY_ASSISTANT_MAX_REQUEST_BYTES: number;
|
|
22
|
+
declare const SURVEY_ASSISTANT_MAX_MESSAGES = 32;
|
|
23
|
+
declare const SURVEY_ASSISTANT_MAX_ATTACHMENTS = 4;
|
|
24
|
+
declare const SURVEY_ASSISTANT_MAX_ATTACHMENT_BYTES: number;
|
|
25
|
+
declare const SURVEY_ASSISTANT_MAX_TOTAL_ATTACHMENT_BYTES: number;
|
|
26
|
+
declare const SURVEY_ASSISTANT_MAX_TEXT_PART_CHARS = 64000;
|
|
27
|
+
declare const SURVEY_ASSISTANT_ACCEPTED_ATTACHMENT_TYPES: Set<string>;
|
|
28
|
+
declare class SurveyAssistantRequestError extends Error {
|
|
29
|
+
readonly status: number;
|
|
30
|
+
constructor(message: string, status?: number);
|
|
31
|
+
}
|
|
32
|
+
declare const validateSurveyAssistantMessages: (value: unknown) => UIMessage[];
|
|
33
|
+
declare const readSurveyAssistantRequestJson: (request: Request) => Promise<unknown>;
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/server/turn-stream.d.ts
|
|
36
|
+
interface SurveyAssistantTurnStreamOptions {
|
|
37
|
+
stream: ReadableStream<UIMessageChunk>;
|
|
38
|
+
changeCollector: TurnChangeCollector;
|
|
39
|
+
signal?: AbortSignal;
|
|
40
|
+
onUnexpectedError?: (error: unknown) => string;
|
|
41
|
+
onSettled?: () => void;
|
|
42
|
+
}
|
|
43
|
+
declare const createSurveyAssistantTurnStream: ({
|
|
44
|
+
changeCollector,
|
|
45
|
+
onSettled,
|
|
46
|
+
onUnexpectedError,
|
|
47
|
+
signal,
|
|
48
|
+
stream
|
|
49
|
+
}: SurveyAssistantTurnStreamOptions) => ReadableStream<UIMessageChunk>;
|
|
50
|
+
//#endregion
|
|
51
|
+
export { type CreateMastraMemoryThreadRepositoryOptions, type CreateSurveyAssistantThreadHandlersOptions, SURVEY_ASSISTANT_ACCEPTED_ATTACHMENT_TYPES, SURVEY_ASSISTANT_AGENT_ID, SURVEY_ASSISTANT_MAX_ATTACHMENTS, SURVEY_ASSISTANT_MAX_ATTACHMENT_BYTES, SURVEY_ASSISTANT_MAX_MESSAGES, SURVEY_ASSISTANT_MAX_REQUEST_BYTES, SURVEY_ASSISTANT_MAX_TEXT_PART_CHARS, SURVEY_ASSISTANT_MAX_TOTAL_ATTACHMENT_BYTES, SURVEY_ASSISTANT_TASK_AGENT_ID, type SurveyAssistantAttachmentAccess, SurveyAssistantAuthorizationError, type SurveyAssistantAuthorizationInput, type SurveyAssistantAuthorize, type SurveyAssistantAuthorizedIdentity, type SurveyAssistantChatHandlerOptions, type SurveyAssistantIdentityContext, type SurveyAssistantModelAttachment, type SurveyAssistantModelResolutionInput, type SurveyAssistantModelSelection, type SurveyAssistantRequestContext, SurveyAssistantRequestError, type SurveyAssistantResolveModel, type SurveyAssistantSnapshotSource, type SurveyAssistantStoredThread, type SurveyAssistantStreamErrorContext, type SurveyAssistantThreadDocument, type SurveyAssistantThreadDocumentContent, type SurveyAssistantThreadDocumentRepository, type SurveyAssistantThreadIdentity, type SurveyAssistantThreadRepository, type SurveyAssistantTurnMetrics, type SurveyAssistantTurnStreamOptions, type SurveyAuthoringReferenceTopic, buildSurveyAssistantRequestContext, createMastraMemoryThreadRepository, createSurveyAssistantChatHandler, createSurveyAssistantThreadHandlers, createSurveyAssistantTurnStream, describeSurveyAssistantStreamError, formatSurveyAssistantStreamError, getSurveyAssistantReplayableDocuments, loadSurveyAssistantDocuments, loadSurveyAssistantThreadAttachments, parseSurveyAssistantSnapshot, readSurveyAssistantRequestJson, registerSurveyAssistantThreadAttachments, removeHistoricalSurveyAssistantAttachments, requireSurveyAssistantTurnState, surveyAuthoringReferenceTopics, surveyAuthoringReferences, validateSurveyAssistantMessages };
|
|
52
|
+
//# sourceMappingURL=server.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.mts","names":[],"sources":["../src/server/memory-thread-repository.ts","../src/server/request-guardrails.ts","../src/server/turn-stream.ts"],"mappings":";;;;;;;;;KAKK,YAAA,GAAe,IAAA,CAClB,YAAA;AAAA,UAIe,yCAAA;EACf,SAAA,IAAa,YAAA,GAAe,OAAA,CAAQ,YAAA;EACpC,eAAA,GAAkB,uCAAA;AAAA;AAAA,cAGP,kCAAA;EAAsC,SAAA;EAAA;AAAA,GAGhD,yCAAA,KAA4C,+BAAA;;;cChBlC,kCAAA;AAAA,cACA,6BAAA;AAAA,cACA,gCAAA;AAAA,cACA,qCAAA;AAAA,cACA,2CAAA;AAAA,cACA,oCAAA;AAAA,cAEA,0CAAA,EAA0C,GAAA;AAAA,cAQ1C,2BAAA,SAAoC,KAAA;EAAA,SACtC,MAAA;cAEG,OAAA,UAAiB,MAAA;AAAA;AAAA,cAqBlB,+BAAA,GAAmC,KAAA,cAAiB,SAAA;AAAA,cA2EpD,8BAAA,GAAwC,OAAA,EAAS,OAAA,KAAU,OAAA;;;UCvGvD,gCAAA;EACf,MAAA,EAAQ,cAAA,CAAe,cAAA;EACvB,eAAA,EAAiB,mBAAA;EACjB,MAAA,GAAS,WAAA;EACT,iBAAA,IAAqB,KAAA;EACrB,SAAA;AAAA;AAAA,cAGW,+BAAA;EAAmC,eAAA;EAAA,SAAA;EAAA,iBAAA;EAAA,MAAA;EAAA;AAAA,GAM7C,gCAAA,KAAmC,cAAA,CAAe,cAAA"}
|
package/dist/server.mjs
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { n as SURVEY_ASSISTANT_TASK_AGENT_ID, t as SURVEY_ASSISTANT_AGENT_ID } from "./constants-CFUWrRtl.mjs";
|
|
2
|
+
import { n as parseSurveyAssistantSnapshot, r as requireSurveyAssistantTurnState, t as buildSurveyAssistantRequestContext } from "./request-context-jcmXT_Q2.mjs";
|
|
3
|
+
import { a as SURVEY_ASSISTANT_MAX_REQUEST_BYTES, c as SurveyAssistantRequestError, i as SURVEY_ASSISTANT_MAX_MESSAGES, l as readSurveyAssistantRequestJson, n as SURVEY_ASSISTANT_MAX_ATTACHMENTS, o as SURVEY_ASSISTANT_MAX_TEXT_PART_CHARS, r as SURVEY_ASSISTANT_MAX_ATTACHMENT_BYTES, s as SURVEY_ASSISTANT_MAX_TOTAL_ATTACHMENT_BYTES, t as SURVEY_ASSISTANT_ACCEPTED_ATTACHMENT_TYPES, u as validateSurveyAssistantMessages } from "./request-guardrails-C59IWnH8.mjs";
|
|
4
|
+
import { a as describeSurveyAssistantStreamError, c as loadSurveyAssistantDocuments, d as removeHistoricalSurveyAssistantAttachments, f as createSurveyAssistantTurnStream, i as createSurveyAssistantChatHandler, l as loadSurveyAssistantThreadAttachments, n as createSurveyAssistantThreadHandlers, o as formatSurveyAssistantStreamError, r as SurveyAssistantAuthorizationError, s as getSurveyAssistantReplayableDocuments, t as createMastraMemoryThreadRepository, u as registerSurveyAssistantThreadAttachments } from "./memory-thread-repository-CJkkVE2-.mjs";
|
|
5
|
+
import { n as surveyAuthoringReferences, t as surveyAuthoringReferenceTopics } from "./authoring-references-X6uRaWuf.mjs";
|
|
6
|
+
export { SURVEY_ASSISTANT_ACCEPTED_ATTACHMENT_TYPES, SURVEY_ASSISTANT_AGENT_ID, SURVEY_ASSISTANT_MAX_ATTACHMENTS, SURVEY_ASSISTANT_MAX_ATTACHMENT_BYTES, SURVEY_ASSISTANT_MAX_MESSAGES, SURVEY_ASSISTANT_MAX_REQUEST_BYTES, SURVEY_ASSISTANT_MAX_TEXT_PART_CHARS, SURVEY_ASSISTANT_MAX_TOTAL_ATTACHMENT_BYTES, SURVEY_ASSISTANT_TASK_AGENT_ID, SurveyAssistantAuthorizationError, SurveyAssistantRequestError, buildSurveyAssistantRequestContext, createMastraMemoryThreadRepository, createSurveyAssistantChatHandler, createSurveyAssistantThreadHandlers, createSurveyAssistantTurnStream, describeSurveyAssistantStreamError, formatSurveyAssistantStreamError, getSurveyAssistantReplayableDocuments, loadSurveyAssistantDocuments, loadSurveyAssistantThreadAttachments, parseSurveyAssistantSnapshot, readSurveyAssistantRequestJson, registerSurveyAssistantThreadAttachments, removeHistoricalSurveyAssistantAttachments, requireSurveyAssistantTurnState, surveyAuthoringReferenceTopics, surveyAuthoringReferences, validateSurveyAssistantMessages };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { a as SurveyAssistantThreadDocumentRepository } from "./thread-documents-DamIq9Od.mjs";
|
|
2
|
+
import { PostgresStore, PostgresStoreConfig } from "@mastra/pg";
|
|
3
|
+
|
|
4
|
+
//#region src/storage/postgres.d.ts
|
|
5
|
+
interface InitializeSurveyAssistantPostgresStorageOptions {
|
|
6
|
+
ensureObservationalMemory?: boolean;
|
|
7
|
+
schemaName?: string;
|
|
8
|
+
}
|
|
9
|
+
declare const initializeSurveyAssistantPostgresStorage: (storage: PostgresStore, {
|
|
10
|
+
ensureObservationalMemory,
|
|
11
|
+
schemaName
|
|
12
|
+
}?: InitializeSurveyAssistantPostgresStorageOptions) => Promise<PostgresStore>;
|
|
13
|
+
interface CreateSurveyAssistantPostgresThreadDocumentRepositoryOptions {
|
|
14
|
+
getStorage(): PostgresStore | Promise<PostgresStore>;
|
|
15
|
+
schemaName?: string;
|
|
16
|
+
}
|
|
17
|
+
declare const createSurveyAssistantPostgresThreadDocumentRepository: ({
|
|
18
|
+
getStorage,
|
|
19
|
+
schemaName
|
|
20
|
+
}: CreateSurveyAssistantPostgresThreadDocumentRepositoryOptions) => SurveyAssistantThreadDocumentRepository;
|
|
21
|
+
interface CreateSurveyAssistantPostgresRuntimeOptions {
|
|
22
|
+
ensureObservationalMemory?: boolean;
|
|
23
|
+
schemaName?: string;
|
|
24
|
+
store: PostgresStore | PostgresStoreConfig;
|
|
25
|
+
}
|
|
26
|
+
declare const createSurveyAssistantPostgresRuntime: ({
|
|
27
|
+
ensureObservationalMemory,
|
|
28
|
+
schemaName,
|
|
29
|
+
store: storeOrConfig
|
|
30
|
+
}: CreateSurveyAssistantPostgresRuntimeOptions) => {
|
|
31
|
+
storage: PostgresStore;
|
|
32
|
+
getStorage: () => Promise<PostgresStore>;
|
|
33
|
+
threadDocuments: SurveyAssistantThreadDocumentRepository;
|
|
34
|
+
};
|
|
35
|
+
//#endregion
|
|
36
|
+
export { CreateSurveyAssistantPostgresRuntimeOptions, CreateSurveyAssistantPostgresThreadDocumentRepositoryOptions, InitializeSurveyAssistantPostgresStorageOptions, createSurveyAssistantPostgresRuntime, createSurveyAssistantPostgresThreadDocumentRepository, initializeSurveyAssistantPostgresStorage };
|
|
37
|
+
//# sourceMappingURL=storage-postgres.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-postgres.d.mts","names":[],"sources":["../src/storage/postgres.ts"],"mappings":";;;;UAwHiB,+CAAA;EACf,yBAAA;EACA,UAAA;AAAA;AAAA,cAGW,wCAAA,GACX,OAAA,EAAS,aAAA;EACT,yBAAA;EAAA;AAAA,IAGG,+CAAA,KAAoD,OAAA,CAAA,aAAA;AAAA,UAwBxC,4DAAA;EACf,UAAA,IAAc,aAAA,GAAgB,OAAA,CAAQ,aAAA;EACtC,UAAA;AAAA;AAAA,cAGW,qDAAA;EAAyD,UAAA;EAAA;AAAA,GAGnE,4DAAA,KAA+D,uCAAA;AAAA,UAmFjD,2CAAA;EACf,yBAAA;EACA,UAAA;EACA,KAAA,EAAO,aAAA,GAAgB,mBAAA;AAAA;AAAA,cAGZ,oCAAA;EAAwC,yBAAA;EAAA,UAAA;EAAA,KAAA,EAAA;AAAA,GAIlD,2CAAA"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { c as SurveyAssistantRequestError } from "./request-guardrails-C59IWnH8.mjs";
|
|
2
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
3
|
+
import { OBSERVATIONAL_MEMORY_TABLE_SCHEMA } from "@mastra/core/storage";
|
|
4
|
+
import { PostgresStore } from "@mastra/pg";
|
|
5
|
+
//#region src/storage/postgres.ts
|
|
6
|
+
const OBSERVATIONAL_MEMORY_TABLE = "mastra_observational_memory";
|
|
7
|
+
const THREAD_DOCUMENTS_TABLE = "survey_assistant_thread_documents";
|
|
8
|
+
const quoteIdentifier = (value) => `"${value.replaceAll("\"", "\"\"")}"`;
|
|
9
|
+
const postgresType = (column) => {
|
|
10
|
+
switch (column.type) {
|
|
11
|
+
case "text": return "TEXT";
|
|
12
|
+
case "timestamp": return "TIMESTAMP";
|
|
13
|
+
case "jsonb": return "JSONB";
|
|
14
|
+
case "integer": return "INTEGER";
|
|
15
|
+
case "float": return "DOUBLE PRECISION";
|
|
16
|
+
case "bigint": return "BIGINT";
|
|
17
|
+
case "boolean": return "BOOLEAN";
|
|
18
|
+
case "uuid": return "UUID";
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const migrationDefault = (column) => {
|
|
22
|
+
switch (column.type) {
|
|
23
|
+
case "boolean": return "FALSE";
|
|
24
|
+
case "integer":
|
|
25
|
+
case "bigint":
|
|
26
|
+
case "float": return "0";
|
|
27
|
+
case "jsonb": return "'{}'::jsonb";
|
|
28
|
+
case "timestamp": return "NOW()";
|
|
29
|
+
case "text": return "''";
|
|
30
|
+
case "uuid": return "gen_random_uuid()";
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const columnSql = (name, column, includeMigrationDefault = false) => {
|
|
34
|
+
const constraints = [
|
|
35
|
+
column.primaryKey ? "PRIMARY KEY" : void 0,
|
|
36
|
+
column.nullable === false ? "NOT NULL" : void 0,
|
|
37
|
+
includeMigrationDefault && column.nullable === false ? `DEFAULT ${migrationDefault(column)}` : void 0
|
|
38
|
+
].filter(Boolean).join(" ");
|
|
39
|
+
return `${quoteIdentifier(name)} ${postgresType(column)}${constraints ? ` ${constraints}` : ""}`;
|
|
40
|
+
};
|
|
41
|
+
const ensureObservationalMemorySchema = async (storage, schemaName) => {
|
|
42
|
+
const tableSchema = OBSERVATIONAL_MEMORY_TABLE_SCHEMA[OBSERVATIONAL_MEMORY_TABLE];
|
|
43
|
+
if (!tableSchema) throw new Error("Mastra observational memory schema is unavailable.");
|
|
44
|
+
const tableName = `${quoteIdentifier(schemaName)}.${quoteIdentifier(OBSERVATIONAL_MEMORY_TABLE)}`;
|
|
45
|
+
const columns = Object.entries(tableSchema).flatMap(([name, column]) => [columnSql(name, column), ...column.type === "timestamp" ? [`${quoteIdentifier(`${name}Z`)} TIMESTAMPTZ DEFAULT NOW()`] : []]);
|
|
46
|
+
await storage.db.none(`CREATE TABLE IF NOT EXISTS ${tableName} (${columns.join(", ")})`);
|
|
47
|
+
for (const [name, column] of Object.entries(tableSchema)) {
|
|
48
|
+
await storage.db.none(`ALTER TABLE ${tableName} ADD COLUMN IF NOT EXISTS ${columnSql(name, column, true)}`);
|
|
49
|
+
if (column.type === "timestamp") await storage.db.none(`ALTER TABLE ${tableName} ADD COLUMN IF NOT EXISTS ${quoteIdentifier(`${name}Z`)} TIMESTAMPTZ DEFAULT NOW()`);
|
|
50
|
+
}
|
|
51
|
+
await storage.db.none(`CREATE INDEX IF NOT EXISTS idx_om_lookup_key ON ${tableName} (${quoteIdentifier("lookupKey")})`);
|
|
52
|
+
};
|
|
53
|
+
const ensureThreadDocumentsSchema = async (storage, schemaName) => {
|
|
54
|
+
const tableName = `${quoteIdentifier(schemaName)}.${quoteIdentifier(THREAD_DOCUMENTS_TABLE)}`;
|
|
55
|
+
await storage.db.none(`
|
|
56
|
+
CREATE TABLE IF NOT EXISTS ${tableName} (
|
|
57
|
+
id TEXT PRIMARY KEY,
|
|
58
|
+
resource_id TEXT NOT NULL,
|
|
59
|
+
thread_id TEXT NOT NULL,
|
|
60
|
+
name TEXT NOT NULL,
|
|
61
|
+
media_type TEXT NOT NULL,
|
|
62
|
+
byte_size INTEGER NOT NULL,
|
|
63
|
+
content_hash TEXT NOT NULL,
|
|
64
|
+
data BYTEA NOT NULL,
|
|
65
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
66
|
+
UNIQUE (resource_id, thread_id, content_hash)
|
|
67
|
+
)
|
|
68
|
+
`);
|
|
69
|
+
await storage.db.none(`CREATE INDEX IF NOT EXISTS idx_survey_assistant_thread_documents_thread ON ${tableName} (resource_id, thread_id, created_at)`);
|
|
70
|
+
};
|
|
71
|
+
const initializeSurveyAssistantPostgresStorage = async (storage, { ensureObservationalMemory = true, schemaName = "public" } = {}) => {
|
|
72
|
+
await storage.init();
|
|
73
|
+
if (ensureObservationalMemory) await ensureObservationalMemorySchema(storage, schemaName);
|
|
74
|
+
await ensureThreadDocumentsSchema(storage, schemaName);
|
|
75
|
+
return storage;
|
|
76
|
+
};
|
|
77
|
+
const toThreadDocument = (row) => ({
|
|
78
|
+
id: row.id,
|
|
79
|
+
name: row.name,
|
|
80
|
+
mediaType: row.media_type,
|
|
81
|
+
bytes: row.byte_size,
|
|
82
|
+
contentHash: row.content_hash,
|
|
83
|
+
createdAt: new Date(row.created_at).toISOString()
|
|
84
|
+
});
|
|
85
|
+
const createSurveyAssistantPostgresThreadDocumentRepository = ({ getStorage, schemaName = "public" }) => {
|
|
86
|
+
const tableName = `${quoteIdentifier(schemaName)}.${quoteIdentifier(THREAD_DOCUMENTS_TABLE)}`;
|
|
87
|
+
return {
|
|
88
|
+
async put({ bytes, data, mediaType, name, resourceId, threadId }) {
|
|
89
|
+
const storage = await getStorage();
|
|
90
|
+
const contentHash = createHash("sha256").update(data).digest("hex");
|
|
91
|
+
return toThreadDocument(await storage.db.tx(async (transaction) => {
|
|
92
|
+
await transaction.none("SELECT pg_advisory_xact_lock(hashtext($1), hashtext($2))", [resourceId, threadId]);
|
|
93
|
+
const existing = await transaction.oneOrNone(`SELECT id, name, media_type, byte_size, content_hash, created_at FROM ${tableName}
|
|
94
|
+
WHERE resource_id = $1 AND thread_id = $2 AND content_hash = $3`, [
|
|
95
|
+
resourceId,
|
|
96
|
+
threadId,
|
|
97
|
+
contentHash
|
|
98
|
+
]);
|
|
99
|
+
if (existing) return existing;
|
|
100
|
+
const usage = await transaction.one(`SELECT COUNT(*) AS count, COALESCE(SUM(byte_size), 0) AS bytes FROM ${tableName}
|
|
101
|
+
WHERE resource_id = $1 AND thread_id = $2`, [resourceId, threadId]);
|
|
102
|
+
if (Number(usage.count) >= 4) throw new SurveyAssistantRequestError(`A chat can contain up to 4 attachments.`);
|
|
103
|
+
if (Number(usage.bytes) + bytes > 12582912) throw new SurveyAssistantRequestError("The attachments stored for this chat are too large in total.");
|
|
104
|
+
return transaction.one(`INSERT INTO ${tableName}
|
|
105
|
+
(id, resource_id, thread_id, name, media_type, byte_size, content_hash, data)
|
|
106
|
+
VALUES
|
|
107
|
+
($1, $2, $3, $4, $5, $6, $7, decode($8, 'base64'))
|
|
108
|
+
RETURNING id, name, media_type, byte_size, content_hash, created_at`, [
|
|
109
|
+
randomUUID(),
|
|
110
|
+
resourceId,
|
|
111
|
+
threadId,
|
|
112
|
+
name,
|
|
113
|
+
mediaType,
|
|
114
|
+
bytes,
|
|
115
|
+
contentHash,
|
|
116
|
+
data
|
|
117
|
+
]);
|
|
118
|
+
}));
|
|
119
|
+
},
|
|
120
|
+
async list({ resourceId, threadId }) {
|
|
121
|
+
return (await (await getStorage()).db.manyOrNone(`SELECT id, name, media_type, byte_size, content_hash, created_at
|
|
122
|
+
FROM ${tableName}
|
|
123
|
+
WHERE resource_id = $1 AND thread_id = $2
|
|
124
|
+
ORDER BY created_at ASC`, [resourceId, threadId])).map(toThreadDocument);
|
|
125
|
+
},
|
|
126
|
+
async read({ documentId, resourceId, threadId }) {
|
|
127
|
+
const row = await (await getStorage()).db.oneOrNone(`SELECT id, name, media_type, byte_size, content_hash, created_at,
|
|
128
|
+
encode(data, 'base64') AS data
|
|
129
|
+
FROM ${tableName}
|
|
130
|
+
WHERE id = $1 AND resource_id = $2 AND thread_id = $3`, [
|
|
131
|
+
documentId,
|
|
132
|
+
resourceId,
|
|
133
|
+
threadId
|
|
134
|
+
]);
|
|
135
|
+
return row ? {
|
|
136
|
+
...toThreadDocument(row),
|
|
137
|
+
data: String(row.data).replace(/\s+/g, "")
|
|
138
|
+
} : null;
|
|
139
|
+
},
|
|
140
|
+
async deleteThread({ resourceId, threadId }) {
|
|
141
|
+
await (await getStorage()).db.none(`DELETE FROM ${tableName} WHERE resource_id = $1 AND thread_id = $2`, [resourceId, threadId]);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
const createSurveyAssistantPostgresRuntime = ({ ensureObservationalMemory, schemaName = "public", store: storeOrConfig }) => {
|
|
146
|
+
const storage = storeOrConfig instanceof PostgresStore ? storeOrConfig : new PostgresStore(storeOrConfig);
|
|
147
|
+
let initialization;
|
|
148
|
+
const getStorage = () => {
|
|
149
|
+
initialization ??= initializeSurveyAssistantPostgresStorage(storage, {
|
|
150
|
+
ensureObservationalMemory,
|
|
151
|
+
schemaName
|
|
152
|
+
});
|
|
153
|
+
return initialization;
|
|
154
|
+
};
|
|
155
|
+
return {
|
|
156
|
+
storage,
|
|
157
|
+
getStorage,
|
|
158
|
+
threadDocuments: createSurveyAssistantPostgresThreadDocumentRepository({
|
|
159
|
+
getStorage,
|
|
160
|
+
schemaName
|
|
161
|
+
})
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
//#endregion
|
|
165
|
+
export { createSurveyAssistantPostgresRuntime, createSurveyAssistantPostgresThreadDocumentRepository, initializeSurveyAssistantPostgresStorage };
|
|
166
|
+
|
|
167
|
+
//# sourceMappingURL=storage-postgres.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-postgres.mjs","names":[],"sources":["../src/storage/postgres.ts"],"sourcesContent":["import { OBSERVATIONAL_MEMORY_TABLE_SCHEMA, type StorageColumn } from \"@mastra/core/storage\";\nimport { PostgresStore, type PostgresStoreConfig } from \"@mastra/pg\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport {\n SURVEY_ASSISTANT_MAX_ATTACHMENTS,\n SURVEY_ASSISTANT_MAX_TOTAL_ATTACHMENT_BYTES,\n SurveyAssistantRequestError,\n} from \"../server/request-guardrails\";\nimport type {\n SurveyAssistantThreadDocument,\n SurveyAssistantThreadDocumentRepository,\n} from \"../server/thread-documents\";\n\nconst OBSERVATIONAL_MEMORY_TABLE = \"mastra_observational_memory\";\nconst THREAD_DOCUMENTS_TABLE = \"survey_assistant_thread_documents\";\n\nconst quoteIdentifier = (value: string) => `\"${value.replaceAll('\"', '\"\"')}\"`;\n\nconst postgresType = (column: StorageColumn) => {\n switch (column.type) {\n case \"text\":\n return \"TEXT\";\n case \"timestamp\":\n return \"TIMESTAMP\";\n case \"jsonb\":\n return \"JSONB\";\n case \"integer\":\n return \"INTEGER\";\n case \"float\":\n return \"DOUBLE PRECISION\";\n case \"bigint\":\n return \"BIGINT\";\n case \"boolean\":\n return \"BOOLEAN\";\n case \"uuid\":\n return \"UUID\";\n }\n};\n\nconst migrationDefault = (column: StorageColumn) => {\n switch (column.type) {\n case \"boolean\":\n return \"FALSE\";\n case \"integer\":\n case \"bigint\":\n case \"float\":\n return \"0\";\n case \"jsonb\":\n return \"'{}'::jsonb\";\n case \"timestamp\":\n return \"NOW()\";\n case \"text\":\n return \"''\";\n case \"uuid\":\n return \"gen_random_uuid()\";\n }\n};\n\nconst columnSql = (name: string, column: StorageColumn, includeMigrationDefault = false) => {\n const constraints = [\n column.primaryKey ? \"PRIMARY KEY\" : undefined,\n column.nullable === false ? \"NOT NULL\" : undefined,\n includeMigrationDefault && column.nullable === false\n ? `DEFAULT ${migrationDefault(column)}`\n : undefined,\n ]\n .filter(Boolean)\n .join(\" \");\n return `${quoteIdentifier(name)} ${postgresType(column)}${constraints ? ` ${constraints}` : \"\"}`;\n};\n\nconst ensureObservationalMemorySchema = async (storage: PostgresStore, schemaName: string) => {\n const tableSchema = OBSERVATIONAL_MEMORY_TABLE_SCHEMA[OBSERVATIONAL_MEMORY_TABLE];\n if (!tableSchema) throw new Error(\"Mastra observational memory schema is unavailable.\");\n\n const tableName = `${quoteIdentifier(schemaName)}.${quoteIdentifier(OBSERVATIONAL_MEMORY_TABLE)}`;\n const columns = Object.entries(tableSchema).flatMap(([name, column]) => [\n columnSql(name, column),\n ...(column.type === \"timestamp\"\n ? [`${quoteIdentifier(`${name}Z`)} TIMESTAMPTZ DEFAULT NOW()`]\n : []),\n ]);\n\n await storage.db.none(`CREATE TABLE IF NOT EXISTS ${tableName} (${columns.join(\", \")})`);\n for (const [name, column] of Object.entries(tableSchema)) {\n await storage.db.none(\n `ALTER TABLE ${tableName} ADD COLUMN IF NOT EXISTS ${columnSql(name, column, true)}`,\n );\n if (column.type === \"timestamp\") {\n await storage.db.none(\n `ALTER TABLE ${tableName} ADD COLUMN IF NOT EXISTS ${quoteIdentifier(`${name}Z`)} TIMESTAMPTZ DEFAULT NOW()`,\n );\n }\n }\n await storage.db.none(\n `CREATE INDEX IF NOT EXISTS idx_om_lookup_key ON ${tableName} (${quoteIdentifier(\"lookupKey\")})`,\n );\n};\n\nconst ensureThreadDocumentsSchema = async (storage: PostgresStore, schemaName: string) => {\n const tableName = `${quoteIdentifier(schemaName)}.${quoteIdentifier(THREAD_DOCUMENTS_TABLE)}`;\n await storage.db.none(`\n CREATE TABLE IF NOT EXISTS ${tableName} (\n id TEXT PRIMARY KEY,\n resource_id TEXT NOT NULL,\n thread_id TEXT NOT NULL,\n name TEXT NOT NULL,\n media_type TEXT NOT NULL,\n byte_size INTEGER NOT NULL,\n content_hash TEXT NOT NULL,\n data BYTEA NOT NULL,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n UNIQUE (resource_id, thread_id, content_hash)\n )\n `);\n await storage.db.none(\n `CREATE INDEX IF NOT EXISTS idx_survey_assistant_thread_documents_thread ON ${tableName} (resource_id, thread_id, created_at)`,\n );\n};\n\nexport interface InitializeSurveyAssistantPostgresStorageOptions {\n ensureObservationalMemory?: boolean;\n schemaName?: string;\n}\n\nexport const initializeSurveyAssistantPostgresStorage = async (\n storage: PostgresStore,\n {\n ensureObservationalMemory = true,\n schemaName = \"public\",\n }: InitializeSurveyAssistantPostgresStorageOptions = {},\n) => {\n await storage.init();\n if (ensureObservationalMemory) await ensureObservationalMemorySchema(storage, schemaName);\n await ensureThreadDocumentsSchema(storage, schemaName);\n return storage;\n};\n\nconst toThreadDocument = (row: {\n id: string;\n name: string;\n media_type: string;\n byte_size: number;\n content_hash: string;\n created_at: Date | string;\n}): SurveyAssistantThreadDocument => ({\n id: row.id,\n name: row.name,\n mediaType: row.media_type,\n bytes: row.byte_size,\n contentHash: row.content_hash,\n createdAt: new Date(row.created_at).toISOString(),\n});\n\nexport interface CreateSurveyAssistantPostgresThreadDocumentRepositoryOptions {\n getStorage(): PostgresStore | Promise<PostgresStore>;\n schemaName?: string;\n}\n\nexport const createSurveyAssistantPostgresThreadDocumentRepository = ({\n getStorage,\n schemaName = \"public\",\n}: CreateSurveyAssistantPostgresThreadDocumentRepositoryOptions): SurveyAssistantThreadDocumentRepository => {\n const tableName = `${quoteIdentifier(schemaName)}.${quoteIdentifier(THREAD_DOCUMENTS_TABLE)}`;\n return {\n async put({ bytes, data, mediaType, name, resourceId, threadId }) {\n const storage = await getStorage();\n const contentHash = createHash(\"sha256\").update(data).digest(\"hex\");\n const row = await storage.db.tx(async (transaction) => {\n await transaction.none(\"SELECT pg_advisory_xact_lock(hashtext($1), hashtext($2))\", [\n resourceId,\n threadId,\n ]);\n const existing = await transaction.oneOrNone(\n `SELECT id, name, media_type, byte_size, content_hash, created_at FROM ${tableName}\n WHERE resource_id = $1 AND thread_id = $2 AND content_hash = $3`,\n [resourceId, threadId, contentHash],\n );\n if (existing) return existing;\n\n const usage = await transaction.one<{ count: string; bytes: string }>(\n `SELECT COUNT(*) AS count, COALESCE(SUM(byte_size), 0) AS bytes FROM ${tableName}\n WHERE resource_id = $1 AND thread_id = $2`,\n [resourceId, threadId],\n );\n if (Number(usage.count) >= SURVEY_ASSISTANT_MAX_ATTACHMENTS) {\n throw new SurveyAssistantRequestError(\n `A chat can contain up to ${SURVEY_ASSISTANT_MAX_ATTACHMENTS} attachments.`,\n );\n }\n if (Number(usage.bytes) + bytes > SURVEY_ASSISTANT_MAX_TOTAL_ATTACHMENT_BYTES) {\n throw new SurveyAssistantRequestError(\n \"The attachments stored for this chat are too large in total.\",\n );\n }\n\n return transaction.one(\n `INSERT INTO ${tableName}\n (id, resource_id, thread_id, name, media_type, byte_size, content_hash, data)\n VALUES\n ($1, $2, $3, $4, $5, $6, $7, decode($8, 'base64'))\n RETURNING id, name, media_type, byte_size, content_hash, created_at`,\n [randomUUID(), resourceId, threadId, name, mediaType, bytes, contentHash, data],\n );\n });\n return toThreadDocument(row);\n },\n async list({ resourceId, threadId }) {\n const storage = await getStorage();\n const rows = await storage.db.manyOrNone(\n `SELECT id, name, media_type, byte_size, content_hash, created_at\n FROM ${tableName}\n WHERE resource_id = $1 AND thread_id = $2\n ORDER BY created_at ASC`,\n [resourceId, threadId],\n );\n return rows.map(toThreadDocument);\n },\n async read({ documentId, resourceId, threadId }) {\n const storage = await getStorage();\n const row = await storage.db.oneOrNone(\n `SELECT id, name, media_type, byte_size, content_hash, created_at,\n encode(data, 'base64') AS data\n FROM ${tableName}\n WHERE id = $1 AND resource_id = $2 AND thread_id = $3`,\n [documentId, resourceId, threadId],\n );\n return row\n ? {\n ...toThreadDocument(row),\n // PostgreSQL wraps encoded BYTEA output at 76 characters.\n data: String(row.data).replace(/\\s+/g, \"\"),\n }\n : null;\n },\n async deleteThread({ resourceId, threadId }) {\n const storage = await getStorage();\n await storage.db.none(`DELETE FROM ${tableName} WHERE resource_id = $1 AND thread_id = $2`, [\n resourceId,\n threadId,\n ]);\n },\n };\n};\n\nexport interface CreateSurveyAssistantPostgresRuntimeOptions {\n ensureObservationalMemory?: boolean;\n schemaName?: string;\n store: PostgresStore | PostgresStoreConfig;\n}\n\nexport const createSurveyAssistantPostgresRuntime = ({\n ensureObservationalMemory,\n schemaName = \"public\",\n store: storeOrConfig,\n}: CreateSurveyAssistantPostgresRuntimeOptions) => {\n const storage =\n storeOrConfig instanceof PostgresStore ? storeOrConfig : new PostgresStore(storeOrConfig);\n let initialization: Promise<PostgresStore> | undefined;\n const getStorage = () => {\n initialization ??= initializeSurveyAssistantPostgresStorage(storage, {\n ensureObservationalMemory,\n schemaName,\n });\n return initialization;\n };\n\n return {\n storage,\n getStorage,\n threadDocuments: createSurveyAssistantPostgresThreadDocumentRepository({\n getStorage,\n schemaName,\n }),\n };\n};\n"],"mappings":"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"}
|