@dbx-tools/appkit-mastra 0.3.44 → 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.
- package/lib/index.d.ts +71 -0
- package/lib/index.js +56 -0
- package/lib/src/agents.d.ts +347 -0
- package/lib/src/agents.js +554 -0
- package/lib/src/chart.d.ts +192 -0
- package/lib/src/chart.js +638 -0
- package/lib/src/config.d.ts +479 -0
- package/lib/src/config.js +190 -0
- package/lib/src/defaults.d.ts +68 -0
- package/lib/src/defaults.js +107 -0
- package/lib/src/filesystems.d.ts +208 -0
- package/lib/src/filesystems.js +958 -0
- package/lib/src/genie.d.ts +166 -0
- package/lib/src/genie.js +969 -0
- package/lib/src/history.d.ts +97 -0
- package/lib/src/history.js +264 -0
- package/lib/src/mcp.d.ts +66 -0
- package/lib/src/mcp.js +65 -0
- package/lib/src/memory.d.ts +111 -0
- package/lib/src/memory.js +275 -0
- package/lib/src/mlflow.d.ts +63 -0
- package/lib/src/mlflow.js +117 -0
- package/lib/src/model.d.ts +62 -0
- package/lib/src/model.js +168 -0
- package/lib/src/observability.d.ts +81 -0
- package/lib/src/observability.js +98 -0
- package/lib/src/pagination.d.ts +23 -0
- package/lib/src/pagination.js +31 -0
- package/lib/src/plugin.d.ts +352 -0
- package/lib/src/plugin.js +1015 -0
- package/lib/src/processors.d.ts +62 -0
- package/lib/src/processors.js +162 -0
- package/lib/src/rest.d.ts +36 -0
- package/lib/src/rest.js +46 -0
- package/lib/src/server.d.ts +155 -0
- package/lib/src/server.js +336 -0
- package/lib/src/serving-sanitize.d.ts +104 -0
- package/lib/src/serving-sanitize.js +228 -0
- package/lib/src/serving.d.ts +61 -0
- package/lib/src/serving.js +78 -0
- package/lib/src/statement.d.ts +51 -0
- package/lib/src/statement.js +83 -0
- package/lib/src/storage-schema.d.ts +14 -0
- package/lib/src/storage-schema.js +34 -0
- package/lib/src/summarize.d.ts +70 -0
- package/lib/src/summarize.js +142 -0
- package/lib/src/threads.d.ts +109 -0
- package/lib/src/threads.js +301 -0
- package/lib/src/validation.d.ts +19 -0
- package/lib/src/validation.js +17 -0
- package/lib/src/workspaces.d.ts +68 -0
- package/lib/src/workspaces.js +246 -0
- package/lib/src/writer.d.ts +25 -0
- package/lib/src/writer.js +40 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/package.json +17 -13
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mastra workspace factory for Databricks Apps.
|
|
3
|
+
*
|
|
4
|
+
* Builds a per-request {@link Workspace} whose filesystem is a
|
|
5
|
+
* {@link CompositeFilesystem} over Databricks paths resolved from the
|
|
6
|
+
* OBO client on {@link MASTRA_USER_KEY}. Optional mount resolver
|
|
7
|
+
* contributions merge extra filesystems and skill scan roots; built-in
|
|
8
|
+
* Assistant skill trees are toggled with `assistantSkills` (on by default).
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import { log, string, token } from "@dbx-tools/shared-core";
|
|
13
|
+
import { CompositeFilesystem, Workspace, } from "@mastra/core/workspace";
|
|
14
|
+
import { MASTRA_SCOPES_KEY, MASTRA_USER_EMAIL_KEY, MASTRA_USER_KEY } from "./config.js";
|
|
15
|
+
import { DatabricksWorkspaceFilesystem, emptyFilesystem } from "./filesystems.js";
|
|
16
|
+
/* ------------------------------ constants ------------------------------ */
|
|
17
|
+
/** Shared Assistant skills tree in the workspace namespace. */
|
|
18
|
+
const ASSISTANT_SHARED_SKILLS_PATH = "/Workspace/.assistant/skills";
|
|
19
|
+
/** Composite mount for {@link ASSISTANT_SHARED_SKILLS_PATH}. */
|
|
20
|
+
const ASSISTANT_WORKSPACE_SKILLS_MOUNT = "/workspace_skills";
|
|
21
|
+
/** Composite mount for the caller's `/.assistant/skills` tree. */
|
|
22
|
+
const ASSISTANT_USER_SKILLS_MOUNT = "/workspace_user_skills";
|
|
23
|
+
/** OAuth scopes that gate Databricks workspace file mounts. */
|
|
24
|
+
const WORKSPACE_FILE_SCOPES = ["workspace", "workspace.workspace", "all-apis"];
|
|
25
|
+
const logger = log.logger("mastra/workspaces");
|
|
26
|
+
/**
|
|
27
|
+
* Create a Mastra {@link Workspace} with per-request Databricks mounts.
|
|
28
|
+
*
|
|
29
|
+
* @example Assistant skills only (default for agents in this plugin)
|
|
30
|
+
* ```ts
|
|
31
|
+
* createWorkspace()
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @example Assistant skills plus a custom mount resolver
|
|
35
|
+
* ```ts
|
|
36
|
+
* createWorkspace({
|
|
37
|
+
* assistantSkills: true,
|
|
38
|
+
* mounts: [
|
|
39
|
+
* async ({ requestContext }) => ({
|
|
40
|
+
* mounts: { "/data": myFilesystem },
|
|
41
|
+
* skillPaths: [],
|
|
42
|
+
* }),
|
|
43
|
+
* ],
|
|
44
|
+
* })
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export function createWorkspace(options = {}) {
|
|
48
|
+
const { id, name } = resolveWorkspaceIdentity(options);
|
|
49
|
+
const resolvers = buildMountResolvers(options);
|
|
50
|
+
const skills = options.skills ?? (resolvers.length > 0 ? buildWorkspaceSkillsResolver(resolvers) : undefined);
|
|
51
|
+
const checkSkillFileMtime = options.checkSkillFileMtime ?? options.assistantSkills !== false;
|
|
52
|
+
const bm25 = options.bm25 !== false;
|
|
53
|
+
logger.debug("workspace:create", {
|
|
54
|
+
id,
|
|
55
|
+
name,
|
|
56
|
+
resolverCount: resolvers.length,
|
|
57
|
+
assistantSkills: options.assistantSkills !== false,
|
|
58
|
+
customMountResolvers: options.mounts?.length ?? 0,
|
|
59
|
+
customSkillsResolver: Boolean(options.skills),
|
|
60
|
+
checkSkillFileMtime,
|
|
61
|
+
bm25,
|
|
62
|
+
});
|
|
63
|
+
return new Workspace({
|
|
64
|
+
id,
|
|
65
|
+
name,
|
|
66
|
+
filesystem: (context) => resolveWorkspaceFilesystem(resolvers, context),
|
|
67
|
+
...(skills
|
|
68
|
+
? {
|
|
69
|
+
skills,
|
|
70
|
+
checkSkillFileMtime,
|
|
71
|
+
}
|
|
72
|
+
: {}),
|
|
73
|
+
bm25,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/* ---------------------------- private helpers ---------------------------- */
|
|
77
|
+
/**
|
|
78
|
+
* Map an OBO user email to their Assistant skills directory in the
|
|
79
|
+
* workspace namespace.
|
|
80
|
+
*/
|
|
81
|
+
function userAssistantSkillsPath(userEmail) {
|
|
82
|
+
return `/Users/${userEmail.trim()}/.assistant/skills`;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Return whether the request token carries a scope that allows workspace
|
|
86
|
+
* file API access (`workspace` or `all-apis` on {@link MASTRA_SCOPES_KEY}).
|
|
87
|
+
*/
|
|
88
|
+
function hasWorkspaceFileScope(requestContext) {
|
|
89
|
+
return token.includesAccessTokenScope(requestContext?.get(MASTRA_SCOPES_KEY), WORKSPACE_FILE_SCOPES);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Built-in mount resolver for Assistant `SKILL.md` trees.
|
|
93
|
+
*
|
|
94
|
+
* Mounts {@link ASSISTANT_SHARED_SKILLS_PATH} when scope checks pass and
|
|
95
|
+
* `/Users/<email>/.assistant/skills` when {@link MASTRA_USER_EMAIL_KEY} is
|
|
96
|
+
* set. Returns empty mounts when the OBO user or client is missing.
|
|
97
|
+
* Mastra owns filesystem initialization.
|
|
98
|
+
*/
|
|
99
|
+
function resolveAssistantSkillsMounts(context) {
|
|
100
|
+
const mounts = {};
|
|
101
|
+
const requestContext = context.requestContext;
|
|
102
|
+
if (!shouldMountAssistantSkills(requestContext)) {
|
|
103
|
+
logger.debug("assistant-skills:skipped", {
|
|
104
|
+
reason: !requestContext ? "no-request-context" : "missing-workspace-scope",
|
|
105
|
+
nodeEnv: process.env.NODE_ENV,
|
|
106
|
+
scopes: context.requestContext?.get(MASTRA_SCOPES_KEY),
|
|
107
|
+
});
|
|
108
|
+
return { mounts, skillPaths: [] };
|
|
109
|
+
}
|
|
110
|
+
const user = requestContext.get(MASTRA_USER_KEY);
|
|
111
|
+
const client = user?.executionContext.client;
|
|
112
|
+
if (!client) {
|
|
113
|
+
logger.debug("assistant-skills:skipped", {
|
|
114
|
+
reason: "missing-obo-client",
|
|
115
|
+
userId: user?.id,
|
|
116
|
+
});
|
|
117
|
+
return { mounts, skillPaths: [] };
|
|
118
|
+
}
|
|
119
|
+
mounts[ASSISTANT_WORKSPACE_SKILLS_MOUNT] = databricksFilesystem(client, ASSISTANT_SHARED_SKILLS_PATH);
|
|
120
|
+
const email = resolveScopedEmail(requestContext);
|
|
121
|
+
if (email) {
|
|
122
|
+
mounts[ASSISTANT_USER_SKILLS_MOUNT] = databricksFilesystem(client, userAssistantSkillsPath(email), false);
|
|
123
|
+
}
|
|
124
|
+
logger.debug("assistant-skills:mounted", {
|
|
125
|
+
sharedPath: ASSISTANT_SHARED_SKILLS_PATH,
|
|
126
|
+
sharedMount: ASSISTANT_WORKSPACE_SKILLS_MOUNT,
|
|
127
|
+
userMount: email ? ASSISTANT_USER_SKILLS_MOUNT : undefined,
|
|
128
|
+
userPath: email ? userAssistantSkillsPath(email) : undefined,
|
|
129
|
+
mountKeys: Object.keys(mounts),
|
|
130
|
+
});
|
|
131
|
+
return { mounts, skillPaths: Object.keys(mounts) };
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Fill in `id` and `name` when either is omitted on {@link CreateWorkspaceOptions}.
|
|
135
|
+
* Slugifies `name` into `id`; tokenizes `id` into a display `name`.
|
|
136
|
+
*/
|
|
137
|
+
function resolveWorkspaceIdentity(options) {
|
|
138
|
+
let id = options.id;
|
|
139
|
+
let name = options.name;
|
|
140
|
+
if (!id) {
|
|
141
|
+
id = name ? string.toSlug(name) : "workspace";
|
|
142
|
+
}
|
|
143
|
+
if (!name) {
|
|
144
|
+
name = Array.from(string.tokenize(id)).join(" ");
|
|
145
|
+
}
|
|
146
|
+
return { id, name };
|
|
147
|
+
}
|
|
148
|
+
/** Collect built-in and caller-supplied mount resolvers for one workspace. */
|
|
149
|
+
function buildMountResolvers(options) {
|
|
150
|
+
const resolvers = [];
|
|
151
|
+
const { assistantSkills = true, mounts } = options;
|
|
152
|
+
if (assistantSkills) {
|
|
153
|
+
resolvers.push(resolveAssistantSkillsMounts);
|
|
154
|
+
}
|
|
155
|
+
if (mounts?.length) {
|
|
156
|
+
resolvers.push(...mounts);
|
|
157
|
+
}
|
|
158
|
+
logger.debug("mounts:resolvers", {
|
|
159
|
+
assistantSkills,
|
|
160
|
+
builtInResolver: assistantSkills,
|
|
161
|
+
customResolverCount: mounts?.length ?? 0,
|
|
162
|
+
totalResolverCount: resolvers.length,
|
|
163
|
+
});
|
|
164
|
+
return resolvers;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Gate Assistant skill mounts on request context.
|
|
168
|
+
*
|
|
169
|
+
* Always allows mounts in development; in other environments requires
|
|
170
|
+
* {@link hasWorkspaceFileScope}.
|
|
171
|
+
*/
|
|
172
|
+
function shouldMountAssistantSkills(requestContext) {
|
|
173
|
+
if (!requestContext)
|
|
174
|
+
return false;
|
|
175
|
+
if (process.env.NODE_ENV === "development")
|
|
176
|
+
return true;
|
|
177
|
+
return hasWorkspaceFileScope(requestContext);
|
|
178
|
+
}
|
|
179
|
+
/** Read the trimmed OBO user email stamped on {@link MASTRA_USER_EMAIL_KEY}. */
|
|
180
|
+
function resolveScopedEmail(requestContext) {
|
|
181
|
+
const email = requestContext?.get(MASTRA_USER_EMAIL_KEY);
|
|
182
|
+
return email?.trim() || undefined;
|
|
183
|
+
}
|
|
184
|
+
/** Construct a read-only {@link DatabricksWorkspaceFilesystem} for `basePath`. */
|
|
185
|
+
function databricksFilesystem(client, basePath, readOnly = true) {
|
|
186
|
+
return new DatabricksWorkspaceFilesystem({
|
|
187
|
+
client,
|
|
188
|
+
basePath,
|
|
189
|
+
readOnly,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Run every mount resolver for one request and merge mounts plus skill paths.
|
|
194
|
+
* Later resolvers overwrite mount keys from earlier ones.
|
|
195
|
+
*/
|
|
196
|
+
async function resolveWorkspaceContribution(resolvers, context) {
|
|
197
|
+
const mounts = {};
|
|
198
|
+
const skillPaths = [];
|
|
199
|
+
for (const [index, resolver] of resolvers.entries()) {
|
|
200
|
+
const contribution = await resolver(context);
|
|
201
|
+
logger.debug("mounts:resolver", {
|
|
202
|
+
index,
|
|
203
|
+
mountKeys: Object.keys(contribution.mounts),
|
|
204
|
+
skillPaths: contribution.skillPaths ?? [],
|
|
205
|
+
});
|
|
206
|
+
Object.assign(mounts, contribution.mounts);
|
|
207
|
+
if (contribution.skillPaths?.length) {
|
|
208
|
+
skillPaths.push(...contribution.skillPaths);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
logger.debug("mounts:merged", {
|
|
212
|
+
mountKeys: Object.keys(mounts),
|
|
213
|
+
skillPaths,
|
|
214
|
+
});
|
|
215
|
+
return { mounts, skillPaths };
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Dynamic filesystem resolver passed to Mastra {@link Workspace}.
|
|
219
|
+
*
|
|
220
|
+
* Returns a {@link CompositeFilesystem} when any mount resolved; otherwise
|
|
221
|
+
* {@link emptyFilesystem}.
|
|
222
|
+
*/
|
|
223
|
+
async function resolveWorkspaceFilesystem(resolvers, context) {
|
|
224
|
+
const { mounts } = await resolveWorkspaceContribution(resolvers, context);
|
|
225
|
+
const mountKeys = Object.keys(mounts);
|
|
226
|
+
if (mountKeys.length === 0) {
|
|
227
|
+
logger.debug("filesystem:empty", {
|
|
228
|
+
hasRequestContext: Boolean(context.requestContext),
|
|
229
|
+
});
|
|
230
|
+
return emptyFilesystem();
|
|
231
|
+
}
|
|
232
|
+
logger.debug("filesystem:composite", { mountKeys });
|
|
233
|
+
return new CompositeFilesystem({ mounts });
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Build the dynamic {@link SkillsResolver} that collects `skillPaths` from
|
|
237
|
+
* every mount resolver on each request.
|
|
238
|
+
*/
|
|
239
|
+
function buildWorkspaceSkillsResolver(resolvers) {
|
|
240
|
+
return async (context) => {
|
|
241
|
+
const { skillPaths } = await resolveWorkspaceContribution(resolvers, context);
|
|
242
|
+
logger.debug("skills:resolved", { skillPaths });
|
|
243
|
+
return skillPaths ?? [];
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya3NwYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93b3Jrc3BhY2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7O0dBVUc7QUFHSCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUU1RCxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLFNBQVMsR0FJVixNQUFNLHdCQUF3QixDQUFDO0FBRWhDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxxQkFBcUIsRUFBRSxlQUFlLEVBQWEsTUFBTSxVQUFVLENBQUM7QUFDaEcsT0FBTyxFQUFFLDZCQUE2QixFQUFFLGVBQWUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUvRSw2RUFBNkU7QUFFN0UsK0RBQStEO0FBQy9ELE1BQU0sNEJBQTRCLEdBQUcsOEJBQThCLENBQUM7QUFFcEUsZ0VBQWdFO0FBQ2hFLE1BQU0sZ0NBQWdDLEdBQUcsbUJBQW1CLENBQUM7QUFFN0Qsa0VBQWtFO0FBQ2xFLE1BQU0sMkJBQTJCLEdBQUcsd0JBQXdCLENBQUM7QUFFN0QsK0RBQStEO0FBQy9ELE1BQU0scUJBQXFCLEdBQUcsQ0FBQyxXQUFXLEVBQUUscUJBQXFCLEVBQUUsVUFBVSxDQUFVLENBQUM7QUFFeEYsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0FBMEMvQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7QUFDSCxNQUFNLFVBQVUsZUFBZSxDQUFDLFVBQWtDLEVBQUU7SUFDbEUsTUFBTSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsR0FBRyx3QkFBd0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN2RCxNQUFNLFNBQVMsR0FBRyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMvQyxNQUFNLE1BQU0sR0FDVixPQUFPLENBQUMsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFD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cHBzLlxuICpcbiAqIEJ1aWxkcyBhIHBlci1yZXF1ZXN0IHtAbGluayBXb3Jrc3BhY2V9IHdob3NlIGZpbGVzeXN0ZW0gaXMgYVxuICoge0BsaW5rIENvbXBvc2l0ZUZpbGVzeXN0ZW19IG92ZXIgRGF0YWJyaWNrcyBwYXRocyByZXNvbHZlZCBmcm9tIHRoZVxuICogT0JPIGNsaWVudCBvbiB7QGxpbmsgTUFTVFJBX1VTRVJfS0VZfS4gT3B0aW9uYWwgbW91bnQgcmVzb2x2ZXJcbiAqIGNvbnRyaWJ1dGlvbnMgbWVyZ2UgZXh0cmEgZmlsZXN5c3RlbXMgYW5kIHNraWxsIHNjYW4gcm9vdHM7IGJ1aWx0LWluXG4gKiBBc3Npc3RhbnQgc2tpbGwgdHJlZXMgYXJlIHRvZ2dsZWQgd2l0aCBgYXNzaXN0YW50U2tpbGxzYCAob24gYnkgZGVmYXVsdCkuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB0eXBlIHsgV29ya3NwYWNlQ2xpZW50IH0gZnJvbSBcIkBkYXRhYnJpY2tzL3Nkay1leHBlcmltZW50YWxcIjtcbmltcG9ydCB7IGxvZywgc3RyaW5nLCB0b2tlbiB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgdHlwZSB7IFJlcXVlc3RDb250ZXh0IH0gZnJvbSBcIkBtYXN0cmEvY29yZS9yZXF1ZXN0LWNvbnRleHRcIjtcbmltcG9ydCB7XG4gIENvbXBvc2l0ZUZpbGVzeXN0ZW0sXG4gIFdvcmtzcGFjZSxcbiAgdHlwZSBTa2lsbHNDb250ZXh0LFxuICB0eXBlIFNraWxsc1Jlc29sdmVyLFxuICB0eXBlIFdvcmtzcGFjZUZpbGVzeXN0ZW0sXG59IGZyb20gXCJAbWFzdHJhL2NvcmUvd29ya3NwYWNlXCI7XG5cbmltcG9ydCB7IE1BU1RSQV9TQ09QRVNfS0VZLCBNQVNUUkFfVVNFUl9FTUFJTF9LRVksIE1BU1RSQV9VU0VSX0tFWSwgdHlwZSBVc2VyIH0gZnJvbSBcIi4vY29uZmlnXCI7XG5pbXBvcnQgeyBEYXRhYnJpY2tzV29ya3NwYWNlRmlsZXN5c3RlbSwgZW1wdHlGaWxlc3lzdGVtIH0gZnJvbSBcIi4vZmlsZXN5c3RlbXNcIjtcblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGNvbnN0YW50cyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuLyoqIFNoYXJlZCBBc3Npc3RhbnQgc2tpbGxzIHRyZWUgaW4gdGhlIHdvcmtzcGFjZSBuYW1lc3BhY2UuICovXG5jb25zdCBBU1NJU1RBTlRfU0hBUkVEX1NLSUxMU19QQVRIID0gXCIvV29ya3NwYWNlLy5hc3Npc3RhbnQvc2tpbGxzXCI7XG5cbi8qKiBDb21wb3NpdGUgbW91bnQgZm9yIHtAbGluayBBU1NJU1RBTlRfU0hBUkVEX1NLSUxMU19QQVRIfS4gKi9cbmNvbnN0IEFTU0lTVEFOVF9XT1JLU1BBQ0VfU0tJTExTX01PVU5UID0gXCIvd29ya3NwYWNlX3NraWxsc1wiO1xuXG4vKiogQ29tcG9zaXRlIG1vdW50IGZvciB0aGUgY2FsbGVyJ3MgYC8uYXNzaXN0YW50L3NraWxsc2AgdHJlZS4gKi9cbmNvbnN0IEFTU0lTVEFOVF9VU0VSX1NLSUxMU19NT1VOVCA9IFwiL3dvcmtzcGFjZV91c2VyX3NraWxsc1wiO1xuXG4vKiogT0F1dGggc2NvcGVzIHRoYXQgZ2F0ZSBEYXRhYnJpY2tzIHdvcmtzcGFjZSBmaWxlIG1vdW50cy4gKi9cbmNvbnN0IFdPUktTUEFDRV9GSUxFX1NDT1BFUyA9IFtcIndvcmtzcGFjZVwiLCBcIndvcmtzcGFjZS53b3Jrc3BhY2VcIiwgXCJhbGwtYXBpc1wiXSBhcyBjb25zdDtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcIm1hc3RyYS93b3Jrc3BhY2VzXCIpO1xuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKiogUGVyLXJlcXVlc3QgY29udGV4dCBmb3IgbW91bnQgcmVzb2x2ZXJzLiAqL1xuaW50ZXJmYWNlIFdvcmtzcGFjZU1vdW50Q29udGV4dCB7XG4gIHJlcXVlc3RDb250ZXh0PzogUmVxdWVzdENvbnRleHQ7XG59XG5cbi8qKiBNb3VudCBtYXAgcGx1cyBvcHRpb25hbCBNYXN0cmEgc2tpbGwgc2NhbiByb290cyBmb3Igb25lIHJlc29sdmVyLiAqL1xuaW50ZXJmYWNlIFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uIHtcbiAgbW91bnRzOiBSZWNvcmQ8c3RyaW5nLCBXb3Jrc3BhY2VGaWxlc3lzdGVtPjtcbiAgLyoqIFBhdGhzIHdpdGhpbiB0aGUgY29tcG9zaXRlIG5hbWVzcGFjZSB3aGVyZSBgU0tJTEwubWRgIGZpbGVzIGFyZSBzY2FubmVkLiAqL1xuICBza2lsbFBhdGhzPzogc3RyaW5nW107XG59XG5cbi8qKiBDb250cmlidXRlcyBmaWxlc3lzdGVtIG1vdW50cyAoYW5kIG9wdGlvbmFsIHNraWxsIHBhdGhzKSBmb3Igb25lIHJlcXVlc3QuICovXG50eXBlIFdvcmtzcGFjZU1vdW50UmVzb2x2ZXIgPSAoXG4gIGNvbnRleHQ6IFdvcmtzcGFjZU1vdW50Q29udGV4dCxcbikgPT4gV29ya3NwYWNlTW91bnRDb250cmlidXRpb24gfCBQcm9taXNlPFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uPjtcblxuLyoqIE9wdGlvbnMgZm9yIHtAbGluayBjcmVhdGVXb3Jrc3BhY2V9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVXb3Jrc3BhY2VPcHRpb25zIHtcbiAgLyoqIFdvcmtzcGFjZSBpZDsgZGVyaXZlZCBmcm9tIGBuYW1lYCBvciBgXCJ3b3Jrc3BhY2VcImAgd2hlbiBvbWl0dGVkLiAqL1xuICBpZD86IHN0cmluZztcbiAgLyoqIERpc3BsYXkgbmFtZTsgZGVyaXZlZCBmcm9tIGBpZGAgd2hlbiBvbWl0dGVkLiAqL1xuICBuYW1lPzogc3RyaW5nO1xuICAvKipcbiAgICogTW91bnQgcmVhZC1vbmx5IEFzc2lzdGFudCBza2lsbCB0cmVlcyBmcm9tIGAvV29ya3NwYWNlLy5hc3Npc3RhbnQvc2tpbGxzYFxuICAgKiBhbmQgYC9Vc2Vycy88ZW1haWw+Ly5hc3Npc3RhbnQvc2tpbGxzYC4gRGVmYXVsdHMgdG8gYHRydWVgLlxuICAgKi9cbiAgYXNzaXN0YW50U2tpbGxzPzogYm9vbGVhbjtcbiAgLyoqIEV4dHJhIHBlci1yZXF1ZXN0IG1vdW50IHJlc29sdmVycyAocnVuIGFmdGVyIGJ1aWx0LWluIG9wdGlvbnMpLiAqL1xuICBtb3VudHM/OiBXb3Jrc3BhY2VNb3VudFJlc29sdmVyW107XG4gIC8qKiBSZXBsYWNlIHRoZSBhdXRvLWJ1aWx0IGR5bmFtaWMgc2tpbGxzIHJlc29sdmVyLiAqL1xuICBza2lsbHM/OiBTa2lsbHNSZXNvbHZlcjtcbiAgLyoqIEZvcndhcmRlZCB0byBNYXN0cmEgd2hlbiBza2lsbCBkaXNjb3ZlcnkgaXMgZW5hYmxlZC4gKi9cbiAgY2hlY2tTa2lsbEZpbGVNdGltZT86IGJvb2xlYW47XG4gIC8qKiBFbmFibGUgQk0yNSBrZXl3b3JkIHNlYXJjaCBvdmVyIGluZGV4ZWQgd29ya3NwYWNlIGNvbnRlbnQuICovXG4gIGJtMjU/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIE1hc3RyYSB7QGxpbmsgV29ya3NwYWNlfSB3aXRoIHBlci1yZXF1ZXN0IERhdGFicmlja3MgbW91bnRzLlxuICpcbiAqIEBleGFtcGxlIEFzc2lzdGFudCBza2lsbHMgb25seSAoZGVmYXVsdCBmb3IgYWdlbnRzIGluIHRoaXMgcGx1Z2luKVxuICogYGBgdHNcbiAqIGNyZWF0ZVdvcmtzcGFjZSgpXG4gKiBgYGBcbiAqXG4gKiBAZXhhbXBsZSBBc3Npc3RhbnQgc2tpbGxzIHBsdXMgYSBjdXN0b20gbW91bnQgcmVzb2x2ZXJcbiAqIGBgYHRzXG4gKiBjcmVhdGVXb3Jrc3BhY2Uoe1xuICogICBhc3Npc3RhbnRTa2lsbHM6IHRydWUsXG4gKiAgIG1vdW50czogW1xuICogICAgIGFzeW5jICh7IHJlcXVlc3RDb250ZXh0IH0pID0+ICh7XG4gKiAgICAgICBtb3VudHM6IHsgXCIvZGF0YVwiOiBteUZpbGVzeXN0ZW0gfSxcbiAqICAgICAgIHNraWxsUGF0aHM6IFtdLFxuICogICAgIH0pLFxuICogICBdLFxuICogfSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlV29ya3NwYWNlKG9wdGlvbnM6IENyZWF0ZVdvcmtzcGFjZU9wdGlvbnMgPSB7fSk6IFdvcmtzcGFjZSB7XG4gIGNvbnN0IHsgaWQsIG5hbWUgfSA9IHJlc29sdmVXb3Jrc3BhY2VJZGVudGl0eShvcHRpb25zKTtcbiAgY29uc3QgcmVzb2x2ZXJzID0gYnVpbGRNb3VudFJlc29sdmVycyhvcHRpb25zKTtcbiAgY29uc3Qgc2tpbGxzID1cbiAgICBvcHRpb25zLnNraWxscyA/PyAocmVzb2x2ZXJzLmxlbmd0aCA+IDAgPyBidWlsZFdvcmtzcGFjZVNraWxsc1Jlc29sdmVyKHJlc29sdmVycykgOiB1bmRlZmluZWQpO1xuICBjb25zdCBjaGVja1NraWxsRmlsZU10aW1lID0gb3B0aW9ucy5jaGVja1NraWxsRmlsZU10aW1lID8/IG9wdGlvbnMuYXNzaXN0YW50U2tpbGxzICE9PSBmYWxzZTtcbiAgY29uc3QgYm0yNSA9IG9wdGlvbnMuYm0yNSAhPT0gZmFsc2U7XG4gIGxvZ2dlci5kZWJ1ZyhcIndvcmtzcGFjZTpjcmVhdGVcIiwge1xuICAgIGlkLFxuICAgIG5hbWUsXG4gICAgcmVzb2x2ZXJDb3VudDogcmVzb2x2ZXJzLmxlbmd0aCxcbiAgICBhc3Npc3RhbnRTa2lsbHM6IG9wdGlvbnMuYXNzaXN0YW50U2tpbGxzICE9PSBmYWxzZSxcbiAgICBjdXN0b21Nb3VudFJlc29sdmVyczogb3B0aW9ucy5tb3VudHM/Lmxlbmd0aCA/PyAwLFxuICAgIGN1c3RvbVNraWxsc1Jlc29sdmVyOiBCb29sZWFuKG9wdGlvbnMuc2tpbGxzKSxcbiAgICBjaGVja1NraWxsRmlsZU10aW1lLFxuICAgIGJtMjUsXG4gIH0pO1xuXG4gIHJldHVybiBuZXcgV29ya3NwYWNlKHtcbiAgICBpZCxcbiAgICBuYW1lLFxuICAgIGZpbGVzeXN0ZW06IChjb250ZXh0KSA9PiByZXNvbHZlV29ya3NwYWNlRmlsZXN5c3RlbShyZXNvbHZlcnMsIGNvbnRleHQpLFxuICAgIC4uLihza2lsbHNcbiAgICAgID8ge1xuICAgICAgICAgIHNraWxscyxcbiAgICAgICAgICBjaGVja1NraWxsRmlsZU10aW1lLFxuICAgICAgICB9XG4gICAgICA6IHt9KSxcbiAgICBibTI1LFxuICB9KTtcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBwcml2YXRlIGhlbHBlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKipcbiAqIE1hcCBhbiBPQk8gdXNlciBlbWFpbCB0byB0aGVpciBBc3Npc3RhbnQgc2tpbGxzIGRpcmVjdG9yeSBpbiB0aGVcbiAqIHdvcmtzcGFjZSBuYW1lc3BhY2UuXG4gKi9cbmZ1bmN0aW9uIHVzZXJBc3Npc3RhbnRTa2lsbHNQYXRoKHVzZXJFbWFpbDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAvVXNlcnMvJHt1c2VyRW1haWwudHJpbSgpfS8uYXNzaXN0YW50L3NraWxsc2A7XG59XG5cbi8qKlxuICogUmV0dXJuIHdoZXRoZXIgdGhlIHJlcXVlc3QgdG9rZW4gY2FycmllcyBhIHNjb3BlIHRoYXQgYWxsb3dzIHdvcmtzcGFjZVxuICogZmlsZSBBUEkgYWNjZXNzIChgd29ya3NwYWNlYCBvciBgYWxsLWFwaXNgIG9uIHtAbGluayBNQVNUUkFfU0NPUEVTX0tFWX0pLlxuICovXG5mdW5jdGlvbiBoYXNXb3Jrc3BhY2VGaWxlU2NvcGUocmVxdWVzdENvbnRleHQ6IFJlcXVlc3RDb250ZXh0IHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gIHJldHVybiB0b2tlbi5pbmNsdWRlc0FjY2Vzc1Rva2VuU2NvcGUoXG4gICAgcmVxdWVzdENvbnRleHQ/LmdldChNQVNUUkFfU0NPUEVTX0tFWSksXG4gICAgV09SS1NQQUNFX0ZJTEVfU0NPUEVTLFxuICApO1xufVxuXG4vKipcbiAqIEJ1aWx0LWluIG1vdW50IHJlc29sdmVyIGZvciBBc3Npc3RhbnQgYFNLSUxMLm1kYCB0cmVlcy5cbiAqXG4gKiBNb3VudHMge0BsaW5rIEFTU0lTVEFOVF9TSEFSRURfU0tJTExTX1BBVEh9IHdoZW4gc2NvcGUgY2hlY2tzIHBhc3MgYW5kXG4gKiBgL1VzZXJzLzxlbWFpbD4vLmFzc2lzdGFudC9za2lsbHNgIHdoZW4ge0BsaW5rIE1BU1RSQV9VU0VSX0VNQUlMX0tFWX0gaXNcbiAqIHNldC4gUmV0dXJucyBlbXB0eSBtb3VudHMgd2hlbiB0aGUgT0JPIHVzZXIgb3IgY2xpZW50IGlzIG1pc3NpbmcuXG4gKiBNYXN0cmEgb3ducyBmaWxlc3lzdGVtIGluaXRpYWxpemF0aW9uLlxuICovXG5mdW5jdGlvbiByZXNvbHZlQXNzaXN0YW50U2tpbGxzTW91bnRzKGNvbnRleHQ6IFdvcmtzcGFjZU1vdW50Q29udGV4dCk6IFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uIHtcbiAgY29uc3QgbW91bnRzOiBSZWNvcmQ8c3RyaW5nLCBEYXRhYnJpY2tzV29ya3NwYWNlRmlsZXN5c3RlbT4gPSB7fTtcbiAgY29uc3QgcmVxdWVzdENvbnRleHQgPSBjb250ZXh0LnJlcXVlc3RDb250ZXh0O1xuXG4gIGlmICghc2hvdWxkTW91bnRBc3Npc3RhbnRTa2lsbHMocmVxdWVzdENvbnRleHQpKSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwiYXNzaXN0YW50LXNraWxsczpza2lwcGVkXCIsIHtcbiAgICAgIHJlYXNvbjogIXJlcXVlc3RDb250ZXh0ID8gXCJuby1yZXF1ZXN0LWNvbnRleHRcIiA6IFwibWlzc2luZy13b3Jrc3BhY2Utc2NvcGVcIixcbiAgICAgIG5vZGVFbnY6IHByb2Nlc3MuZW52Lk5PREVfRU5WLFxuICAgICAgc2NvcGVzOiBjb250ZXh0LnJlcXVlc3RDb250ZXh0Py5nZXQoTUFTVFJBX1NDT1BFU19LRVkpLFxuICAgIH0pO1xuICAgIHJldHVybiB7IG1vdW50cywgc2tpbGxQYXRoczogW10gfTtcbiAgfVxuXG4gIGNvbnN0IHVzZXIgPSByZXF1ZXN0Q29udGV4dCEuZ2V0KE1BU1RSQV9VU0VSX0tFWSkgYXMgVXNlciB8IHVuZGVmaW5lZDtcbiAgY29uc3QgY2xpZW50ID0gdXNlcj8uZXhlY3V0aW9uQ29udGV4dC5jbGllbnQ7XG4gIGlmICghY2xpZW50KSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwiYXNzaXN0YW50LXNraWxsczpza2lwcGVkXCIsIHtcbiAgICAgIHJlYXNvbjogXCJtaXNzaW5nLW9iby1jbGllbnRcIixcbiAgICAgIHVzZXJJZDogdXNlcj8uaWQsXG4gICAgfSk7XG4gICAgcmV0dXJuIHsgbW91bnRzLCBza2lsbFBhdGhzOiBbXSB9O1xuICB9XG5cbiAgbW91bnRzW0FTU0lTVEFOVF9XT1JLU1BBQ0VfU0tJTExTX01PVU5UXSA9IGRhdGFicmlja3NGaWxlc3lzdGVtKFxuICAgIGNsaWVudCxcbiAgICBBU1NJU1RBTlRfU0hBUkVEX1NLSUxMU19QQVRILFxuICApO1xuXG4gIGNvbnN0IGVtYWlsID0gcmVzb2x2ZVNjb3BlZEVtYWlsKHJlcXVlc3RDb250ZXh0KTtcbiAgaWYgKGVtYWlsKSB7XG4gICAgbW91bnRzW0FTU0lTVEFOVF9VU0VSX1NLSUxMU19NT1VOVF0gPSBkYXRhYnJpY2tzRmlsZXN5c3RlbShcbiAgICAgIGNsaWVudCxcbiAgICAgIHVzZXJBc3Npc3RhbnRTa2lsbHNQYXRoKGVtYWlsKSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gIH1cblxuICBsb2dnZXIuZGVidWcoXCJhc3Npc3RhbnQtc2tpbGxzOm1vdW50ZWRcIiwge1xuICAgIHNoYXJlZFBhdGg6IEFTU0lTVEFOVF9TSEFSRURfU0tJTExTX1BBVEgsXG4gICAgc2hhcmVkTW91bnQ6IEFTU0lTVEFOVF9XT1JLU1BBQ0VfU0tJTExTX01PVU5ULFxuICAgIHVzZXJNb3VudDogZW1haWwgPyBBU1NJU1RBTlRfVVNFUl9TS0lMTFNfTU9VTlQgOiB1bmRlZmluZWQsXG4gICAgdXNlclBhdGg6IGVtYWlsID8gdXNlckFzc2lzdGFudFNraWxsc1BhdGgoZW1haWwpIDogdW5kZWZpbmVkLFxuICAgIG1vdW50S2V5czogT2JqZWN0LmtleXMobW91bnRzKSxcbiAgfSk7XG5cbiAgcmV0dXJuIHsgbW91bnRzLCBza2lsbFBhdGhzOiBPYmplY3Qua2V5cyhtb3VudHMpIH07XG59XG5cbi8qKlxuICogRmlsbCBpbiBgaWRgIGFuZCBgbmFtZWAgd2hlbiBlaXRoZXIgaXMgb21pdHRlZCBvbiB7QGxpbmsgQ3JlYXRlV29ya3NwYWNlT3B0aW9uc30uXG4gKiBTbHVnaWZpZXMgYG5hbWVgIGludG8gYGlkYDsgdG9rZW5pemVzIGBpZGAgaW50byBhIGRpc3BsYXkgYG5hbWVgLlxuICovXG5mdW5jdGlvbiByZXNvbHZlV29ya3NwYWNlSWRlbnRpdHkob3B0aW9uczogQ3JlYXRlV29ya3NwYWNlT3B0aW9ucyk6IHtcbiAgaWQ6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xufSB7XG4gIGxldCBpZCA9IG9wdGlvbnMuaWQ7XG4gIGxldCBuYW1lID0gb3B0aW9ucy5uYW1lO1xuICBpZiAoIWlkKSB7XG4gICAgaWQgPSBuYW1lID8gc3RyaW5nLnRvU2x1ZyhuYW1lKSA6IFwid29ya3NwYWNlXCI7XG4gIH1cbiAgaWYgKCFuYW1lKSB7XG4gICAgbmFtZSA9IEFycmF5LmZyb20oc3RyaW5nLnRva2VuaXplKGlkKSkuam9pbihcIiBcIik7XG4gIH1cbiAgcmV0dXJuIHsgaWQsIG5hbWUgfTtcbn1cblxuLyoqIENvbGxlY3QgYnVpbHQtaW4gYW5kIGNhbGxlci1zdXBwbGllZCBtb3VudCByZXNvbHZlcnMgZm9yIG9uZSB3b3Jrc3BhY2UuICovXG5mdW5jdGlvbiBidWlsZE1vdW50UmVzb2x2ZXJzKG9wdGlvbnM6IENyZWF0ZVdvcmtzcGFjZU9wdGlvbnMpOiBXb3Jrc3BhY2VNb3VudFJlc29sdmVyW10ge1xuICBjb25zdCByZXNvbHZlcnM6IFdvcmtzcGFjZU1vdW50UmVzb2x2ZXJbXSA9IFtdO1xuICBjb25zdCB7IGFzc2lzdGFudFNraWxscyA9IHRydWUsIG1vdW50cyB9ID0gb3B0aW9ucztcbiAgaWYgKGFzc2lzdGFudFNraWxscykge1xuICAgIHJlc29sdmVycy5wdXNoKHJlc29sdmVBc3Npc3RhbnRTa2lsbHNNb3VudHMpO1xuICB9XG4gIGlmIChtb3VudHM/Lmxlbmd0aCkge1xuICAgIHJlc29sdmVycy5wdXNoKC4uLm1vdW50cyk7XG4gIH1cbiAgbG9nZ2VyLmRlYnVnKFwibW91bnRzOnJlc29sdmVyc1wiLCB7XG4gICAgYXNzaXN0YW50U2tpbGxzLFxuICAgIGJ1aWx0SW5SZXNvbHZlcjogYXNzaXN0YW50U2tpbGxzLFxuICAgIGN1c3RvbVJlc29sdmVyQ291bnQ6IG1vdW50cz8ubGVuZ3RoID8/IDAsXG4gICAgdG90YWxSZXNvbHZlckNvdW50OiByZXNvbHZlcnMubGVuZ3RoLFxuICB9KTtcbiAgcmV0dXJuIHJlc29sdmVycztcbn1cblxuLyoqXG4gKiBHYXRlIEFzc2lzdGFudCBza2lsbCBtb3VudHMgb24gcmVxdWVzdCBjb250ZXh0LlxuICpcbiAqIEFsd2F5cyBhbGxvd3MgbW91bnRzIGluIGRldmVsb3BtZW50OyBpbiBvdGhlciBlbnZpcm9ubWVudHMgcmVxdWlyZXNcbiAqIHtAbGluayBoYXNXb3Jrc3BhY2VGaWxlU2NvcGV9LlxuICovXG5mdW5jdGlvbiBzaG91bGRNb3VudEFzc2lzdGFudFNraWxscyhcbiAgcmVxdWVzdENvbnRleHQ6IFJlcXVlc3RDb250ZXh0IHwgdW5kZWZpbmVkLFxuKTogcmVxdWVzdENvbnRleHQgaXMgUmVxdWVzdENvbnRleHQge1xuICBpZiAoIXJlcXVlc3RDb250ZXh0KSByZXR1cm4gZmFsc2U7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJkZXZlbG9wbWVudFwiKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuIGhhc1dvcmtzcGFjZUZpbGVTY29wZShyZXF1ZXN0Q29udGV4dCk7XG59XG5cbi8qKiBSZWFkIHRoZSB0cmltbWVkIE9CTyB1c2VyIGVtYWlsIHN0YW1wZWQgb24ge0BsaW5rIE1BU1RSQV9VU0VSX0VNQUlMX0tFWX0uICovXG5mdW5jdGlvbiByZXNvbHZlU2NvcGVkRW1haWwocmVxdWVzdENvbnRleHQ6IFJlcXVlc3RDb250ZXh0IHwgdW5kZWZpbmVkKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgZW1haWwgPSByZXF1ZXN0Q29udGV4dD8uZ2V0KE1BU1RSQV9VU0VSX0VNQUlMX0tFWSkgYXMgc3RyaW5nIHwgdW5kZWZpbmVkO1xuICByZXR1cm4gZW1haWw/LnRyaW0oKSB8fCB1bmRlZmluZWQ7XG59XG5cbi8qKiBDb25zdHJ1Y3QgYSByZWFkLW9ubHkge0BsaW5rIERhdGFicmlja3NXb3Jrc3BhY2VGaWxlc3lzdGVtfSBmb3IgYGJhc2VQYXRoYC4gKi9cbmZ1bmN0aW9uIGRhdGFicmlja3NGaWxlc3lzdGVtKFxuICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudCxcbiAgYmFzZVBhdGg6IHN0cmluZyxcbiAgcmVhZE9ubHk6IGJvb2xlYW4gPSB0cnVlLFxuKTogRGF0YWJyaWNrc1dvcmtzcGFjZUZpbGVzeXN0ZW0ge1xuICByZXR1cm4gbmV3IERhdGFicmlja3NXb3Jrc3BhY2VGaWxlc3lzdGVtKHtcbiAgICBjbGllbnQsXG4gICAgYmFzZVBhdGgsXG4gICAgcmVhZE9ubHksXG4gIH0pO1xufVxuXG4vKipcbiAqIFJ1biBldmVyeSBtb3VudCByZXNvbHZlciBmb3Igb25lIHJlcXVlc3QgYW5kIG1lcmdlIG1vdW50cyBwbHVzIHNraWxsIHBhdGhzLlxuICogTGF0ZXIgcmVzb2x2ZXJzIG92ZXJ3cml0ZSBtb3VudCBrZXlzIGZyb20gZWFybGllciBvbmVzLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlV29ya3NwYWNlQ29udHJpYnV0aW9uKFxuICByZXNvbHZlcnM6IFdvcmtzcGFjZU1vdW50UmVzb2x2ZXJbXSxcbiAgY29udGV4dDogV29ya3NwYWNlTW91bnRDb250ZXh0LFxuKTogUHJvbWlzZTxXb3Jrc3BhY2VNb3VudENvbnRyaWJ1dGlvbj4ge1xuICBjb25zdCBtb3VudHM6IFJlY29yZDxzdHJpbmcsIFdvcmtzcGFjZUZpbGVzeXN0ZW0+ID0ge307XG4gIGNvbnN0IHNraWxsUGF0aHM6IHN0cmluZ1tdID0gW107XG5cbiAgZm9yIChjb25zdCBbaW5kZXgsIHJlc29sdmVyXSBvZiByZXNvbHZlcnMuZW50cmllcygpKSB7XG4gICAgY29uc3QgY29udHJpYnV0aW9uID0gYXdhaXQgcmVzb2x2ZXIoY29udGV4dCk7XG4gICAgbG9nZ2VyLmRlYnVnKFwibW91bnRzOnJlc29sdmVyXCIsIHtcbiAgICAgIGluZGV4LFxuICAgICAgbW91bnRLZXlzOiBPYmplY3Qua2V5cyhjb250cmlidXRpb24ubW91bnRzKSxcbiAgICAgIHNraWxsUGF0aHM6IGNvbnRyaWJ1dGlvbi5za2lsbFBhdGhzID8/IFtdLFxuICAgIH0pO1xuICAgIE9iamVjdC5hc3NpZ24obW91bnRzLCBjb250cmlidXRpb24ubW91bnRzKTtcbiAgICBpZiAoY29udHJpYnV0aW9uLnNraWxsUGF0aHM/Lmxlbmd0aCkge1xuICAgICAgc2tpbGxQYXRocy5wdXNoKC4uLmNvbnRyaWJ1dGlvbi5za2lsbFBhdGhzKTtcbiAgICB9XG4gIH1cblxuICBsb2dnZXIuZGVidWcoXCJtb3VudHM6bWVyZ2VkXCIsIHtcbiAgICBtb3VudEtleXM6IE9iamVjdC5rZXlzKG1vdW50cyksXG4gICAgc2tpbGxQYXRocyxcbiAgfSk7XG5cbiAgcmV0dXJuIHsgbW91bnRzLCBza2lsbFBhdGhzIH07XG59XG5cbi8qKlxuICogRHluYW1pYyBmaWxlc3lzdGVtIHJlc29sdmVyIHBhc3NlZCB0byBNYXN0cmEge0BsaW5rIFdvcmtzcGFjZX0uXG4gKlxuICogUmV0dXJucyBhIHtAbGluayBDb21wb3NpdGVGaWxlc3lzdGVtfSB3aGVuIGFueSBtb3VudCByZXNvbHZlZDsgb3RoZXJ3aXNlXG4gKiB7QGxpbmsgZW1wdHlGaWxlc3lzdGVtfS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZVdvcmtzcGFjZUZpbGVzeXN0ZW0oXG4gIHJlc29sdmVyczogV29ya3NwYWNlTW91bnRSZXNvbHZlcltdLFxuICBjb250ZXh0OiBXb3Jrc3BhY2VNb3VudENvbnRleHQsXG4pOiBQcm9taXNlPFdvcmtzcGFjZUZpbGVzeXN0ZW0+IHtcbiAgY29uc3QgeyBtb3VudHMgfSA9IGF3YWl0IHJlc29sdmVXb3Jrc3BhY2VDb250cmlidXRpb24ocmVzb2x2ZXJzLCBjb250ZXh0KTtcbiAgY29uc3QgbW91bnRLZXlzID0gT2JqZWN0LmtleXMobW91bnRzKTtcbiAgaWYgKG1vdW50S2V5cy5sZW5ndGggPT09IDApIHtcbiAgICBsb2dnZXIuZGVidWcoXCJmaWxlc3lzdGVtOmVtcHR5XCIsIHtcbiAgICAgIGhhc1JlcXVlc3RDb250ZXh0OiBCb29sZWFuKGNvbnRleHQucmVxdWVzdENvbnRleHQpLFxuICAgIH0pO1xuICAgIHJldHVybiBlbXB0eUZpbGVzeXN0ZW0oKTtcbiAgfVxuICBsb2dnZXIuZGVidWcoXCJmaWxlc3lzdGVtOmNvbXBvc2l0ZVwiLCB7IG1vdW50S2V5cyB9KTtcbiAgcmV0dXJuIG5ldyBDb21wb3NpdGVGaWxlc3lzdGVtKHsgbW91bnRzIH0pO1xufVxuXG4vKipcbiAqIEJ1aWxkIHRoZSBkeW5hbWljIHtAbGluayBTa2lsbHNSZXNvbHZlcn0gdGhhdCBjb2xsZWN0cyBgc2tpbGxQYXRoc2AgZnJvbVxuICogZXZlcnkgbW91bnQgcmVzb2x2ZXIgb24gZWFjaCByZXF1ZXN0LlxuICovXG5mdW5jdGlvbiBidWlsZFdvcmtzcGFjZVNraWxsc1Jlc29sdmVyKHJlc29sdmVyczogV29ya3NwYWNlTW91bnRSZXNvbHZlcltdKTogU2tpbGxzUmVzb2x2ZXIge1xuICByZXR1cm4gYXN5bmMgKGNvbnRleHQ6IFNraWxsc0NvbnRleHQpID0+IHtcbiAgICBjb25zdCB7IHNraWxsUGF0aHMgfSA9IGF3YWl0IHJlc29sdmVXb3Jrc3BhY2VDb250cmlidXRpb24ocmVzb2x2ZXJzLCBjb250ZXh0KTtcbiAgICBsb2dnZXIuZGVidWcoXCJza2lsbHM6cmVzb2x2ZWRcIiwgeyBza2lsbFBhdGhzIH0pO1xuICAgIHJldHVybiBza2lsbFBhdGhzID8/IFtdO1xuICB9O1xufVxuIl19
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helper for publishing events through Mastra's
|
|
3
|
+
* `ctx.writer`. Centralizes the "the downstream stream may already
|
|
4
|
+
* be closed, don't take the whole tool down" pattern that the
|
|
5
|
+
* Genie agent and chart tool both need.
|
|
6
|
+
*
|
|
7
|
+
* Failures are logged at `warn` (a persistently-closed writer is
|
|
8
|
+
* the most likely culprit when events go missing client-side) but
|
|
9
|
+
* swallowed so a cancelled request or a client that navigated
|
|
10
|
+
* away can't crash a tool mid-flight.
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
import { log } from "@dbx-tools/shared-core";
|
|
15
|
+
import type { MastraWriter } from "@dbx-tools/shared-mastra";
|
|
16
|
+
/**
|
|
17
|
+
* Best-effort `writer.write`. No-op when `writer` is undefined;
|
|
18
|
+
* caught errors are logged via `log.warn("writer:error", ...)`
|
|
19
|
+
* along with any caller-supplied `context` fields (e.g. a
|
|
20
|
+
* `chartId` or `messageId`) so the warning is greppable per
|
|
21
|
+
* resource.
|
|
22
|
+
*
|
|
23
|
+
* Returns when the write resolves or rejects; never throws.
|
|
24
|
+
*/
|
|
25
|
+
export declare function safeWrite(log: log.Logger, writer: MastraWriter | undefined, chunk: unknown, context?: Record<string, unknown>): Promise<void>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helper for publishing events through Mastra's
|
|
3
|
+
* `ctx.writer`. Centralizes the "the downstream stream may already
|
|
4
|
+
* be closed, don't take the whole tool down" pattern that the
|
|
5
|
+
* Genie agent and chart tool both need.
|
|
6
|
+
*
|
|
7
|
+
* Failures are logged at `warn` (a persistently-closed writer is
|
|
8
|
+
* the most likely culprit when events go missing client-side) but
|
|
9
|
+
* swallowed so a cancelled request or a client that navigated
|
|
10
|
+
* away can't crash a tool mid-flight.
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
import { error } from "@dbx-tools/shared-core";
|
|
15
|
+
/**
|
|
16
|
+
* Best-effort `writer.write`. No-op when `writer` is undefined;
|
|
17
|
+
* caught errors are logged via `log.warn("writer:error", ...)`
|
|
18
|
+
* along with any caller-supplied `context` fields (e.g. a
|
|
19
|
+
* `chartId` or `messageId`) so the warning is greppable per
|
|
20
|
+
* resource.
|
|
21
|
+
*
|
|
22
|
+
* Returns when the write resolves or rejects; never throws.
|
|
23
|
+
*/
|
|
24
|
+
export async function safeWrite(log, writer, chunk, context = {}) {
|
|
25
|
+
if (!writer) {
|
|
26
|
+
log.debug("writer:no-writer", context);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
await writer.write(chunk);
|
|
31
|
+
log.debug("writer:ok", context);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
log.warn("writer:error", {
|
|
35
|
+
...context,
|
|
36
|
+
error: error.errorMessage(err),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3JpdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3dyaXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7O0dBWUc7QUFFSCxPQUFPLEVBQUUsS0FBSyxFQUFPLE1BQU0sd0JBQXdCLENBQUM7QUFHcEQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLFNBQVMsQ0FDN0IsR0FBZSxFQUNmLE1BQWdDLEVBQ2hDLEtBQWMsRUFDZCxVQUFtQyxFQUFFO0lBRXJDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNaLEdBQUcsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDdkMsT0FBTztJQUNULENBQUM7SUFDRCxJQUFJLENBQUM7UUFDSCxNQUFNLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsR0FBRyxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDYixHQUFHLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUN2QixHQUFHLE9BQU87WUFDVixLQUFLLEVBQUUsS0FBSyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUM7U0FDL0IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNoYXJlZCBoZWxwZXIgZm9yIHB1Ymxpc2hpbmcgZXZlbnRzIHRocm91Z2ggTWFzdHJhJ3NcbiAqIGBjdHgud3JpdGVyYC4gQ2VudHJhbGl6ZXMgdGhlIFwidGhlIGRvd25zdHJlYW0gc3RyZWFtIG1heSBhbHJlYWR5XG4gKiBiZSBjbG9zZWQsIGRvbid0IHRha2UgdGhlIHdob2xlIHRvb2wgZG93blwiIHBhdHRlcm4gdGhhdCB0aGVcbiAqIEdlbmllIGFnZW50IGFuZCBjaGFydCB0b29sIGJvdGggbmVlZC5cbiAqXG4gKiBGYWlsdXJlcyBhcmUgbG9nZ2VkIGF0IGB3YXJuYCAoYSBwZXJzaXN0ZW50bHktY2xvc2VkIHdyaXRlciBpc1xuICogdGhlIG1vc3QgbGlrZWx5IGN1bHByaXQgd2hlbiBldmVudHMgZ28gbWlzc2luZyBjbGllbnQtc2lkZSkgYnV0XG4gKiBzd2FsbG93ZWQgc28gYSBjYW5jZWxsZWQgcmVxdWVzdCBvciBhIGNsaWVudCB0aGF0IG5hdmlnYXRlZFxuICogYXdheSBjYW4ndCBjcmFzaCBhIHRvb2wgbWlkLWZsaWdodC5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgZXJyb3IsIGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgdHlwZSB7IE1hc3RyYVdyaXRlciB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1tYXN0cmFcIjtcblxuLyoqXG4gKiBCZXN0LWVmZm9ydCBgd3JpdGVyLndyaXRlYC4gTm8tb3Agd2hlbiBgd3JpdGVyYCBpcyB1bmRlZmluZWQ7XG4gKiBjYXVnaHQgZXJyb3JzIGFyZSBsb2dnZWQgdmlhIGBsb2cud2FybihcIndyaXRlcjplcnJvclwiLCAuLi4pYFxuICogYWxvbmcgd2l0aCBhbnkgY2FsbGVyLXN1cHBsaWVkIGBjb250ZXh0YCBmaWVsZHMgKGUuZy4gYVxuICogYGNoYXJ0SWRgIG9yIGBtZXNzYWdlSWRgKSBzbyB0aGUgd2FybmluZyBpcyBncmVwcGFibGUgcGVyXG4gKiByZXNvdXJjZS5cbiAqXG4gKiBSZXR1cm5zIHdoZW4gdGhlIHdyaXRlIHJlc29sdmVzIG9yIHJlamVjdHM7IG5ldmVyIHRocm93cy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNhZmVXcml0ZShcbiAgbG9nOiBsb2cuTG9nZ2VyLFxuICB3cml0ZXI6IE1hc3RyYVdyaXRlciB8IHVuZGVmaW5lZCxcbiAgY2h1bms6IHVua25vd24sXG4gIGNvbnRleHQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge30sXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKCF3cml0ZXIpIHtcbiAgICBsb2cuZGVidWcoXCJ3cml0ZXI6bm8td3JpdGVyXCIsIGNvbnRleHQpO1xuICAgIHJldHVybjtcbiAgfVxuICB0cnkge1xuICAgIGF3YWl0IHdyaXRlci53cml0ZShjaHVuayk7XG4gICAgbG9nLmRlYnVnKFwid3JpdGVyOm9rXCIsIGNvbnRleHQpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2cud2FybihcIndyaXRlcjplcnJvclwiLCB7XG4gICAgICAuLi5jb250ZXh0LFxuICAgICAgZXJyb3I6IGVycm9yLmVycm9yTWVzc2FnZShlcnIpLFxuICAgIH0pO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["../src/agents.ts","../src/chart.ts","../src/config.ts","../src/defaults.ts","../src/filesystems.ts","../src/genie.ts","../src/history.ts","../src/mcp.ts","../src/memory.ts","../src/mlflow.ts","../src/model.ts","../src/observability.ts","../src/pagination.ts","../src/plugin.ts","../src/processors.ts","../src/rest.ts","../src/server.ts","../src/serving-sanitize.ts","../src/serving.ts","../src/statement.ts","../src/storage-schema.ts","../src/summarize.ts","../src/threads.ts","../src/validation.ts","../src/workspaces.ts","../src/writer.ts","../index.ts"],"version":"5.9.3"}
|
package/package.json
CHANGED
|
@@ -28,30 +28,34 @@
|
|
|
28
28
|
"express": "^5.1.0",
|
|
29
29
|
"pg": "^8.22.0",
|
|
30
30
|
"zod": "4.3.6",
|
|
31
|
-
"@dbx-tools/appkit": "0.
|
|
32
|
-
"@dbx-tools/
|
|
33
|
-
"@dbx-tools/
|
|
34
|
-
"@dbx-tools/model": "0.
|
|
35
|
-
"@dbx-tools/shared-core": "0.
|
|
36
|
-
"@dbx-tools/shared-
|
|
37
|
-
"@dbx-tools/shared-
|
|
38
|
-
"@dbx-tools/shared-
|
|
31
|
+
"@dbx-tools/appkit": "0.4.0",
|
|
32
|
+
"@dbx-tools/core": "0.4.0",
|
|
33
|
+
"@dbx-tools/genie": "0.4.0",
|
|
34
|
+
"@dbx-tools/model": "0.4.0",
|
|
35
|
+
"@dbx-tools/shared-core": "0.4.0",
|
|
36
|
+
"@dbx-tools/shared-mastra": "0.4.0",
|
|
37
|
+
"@dbx-tools/shared-model": "0.4.0",
|
|
38
|
+
"@dbx-tools/shared-genie": "0.4.0"
|
|
39
39
|
},
|
|
40
|
-
"main": "index.
|
|
40
|
+
"main": "./lib/index.js",
|
|
41
41
|
"license": "UNLICENSED",
|
|
42
42
|
"publishConfig": {
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
|
-
"version": "0.
|
|
46
|
-
"types": "index.ts",
|
|
45
|
+
"version": "0.4.0",
|
|
46
|
+
"types": "./lib/index.d.ts",
|
|
47
47
|
"type": "module",
|
|
48
48
|
"exports": {
|
|
49
|
-
".":
|
|
49
|
+
".": {
|
|
50
|
+
"types": "./lib/index.d.ts",
|
|
51
|
+
"default": "./lib/index.js"
|
|
52
|
+
},
|
|
50
53
|
"./package.json": "./package.json"
|
|
51
54
|
},
|
|
52
55
|
"files": [
|
|
53
56
|
"index.ts",
|
|
54
|
-
"src"
|
|
57
|
+
"src",
|
|
58
|
+
"lib"
|
|
55
59
|
],
|
|
56
60
|
"dbxToolsConfig": {
|
|
57
61
|
"tags": [
|