@dbx-tools/appkit-mastra 0.9.119 → 0.9.120
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 +39 -32
- package/index.ts +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -2
- package/lib/src/agents.js +3 -4
- package/lib/src/chart.js +4 -4
- package/lib/src/chat.js +2 -2
- package/lib/src/config.d.ts +6 -4
- package/lib/src/config.js +3 -3
- package/lib/src/genie.d.ts +3 -1
- package/lib/src/genie.js +11 -7
- package/lib/src/memory.d.ts +2 -22
- package/lib/src/memory.js +2 -32
- package/lib/src/mlflow.d.ts +3 -10
- package/lib/src/mlflow.js +6 -6
- package/lib/src/monty-sandbox.js +2 -2
- package/lib/src/plugin.d.ts +2 -19
- package/lib/src/plugin.js +13 -71
- package/lib/src/remote-skills.js +12 -6
- package/lib/src/server.js +2 -2
- package/lib/src/workspaces.js +6 -6
- package/lib/src/writer.js +2 -2
- package/package.json +16 -16
- package/src/agents.ts +2 -3
- package/src/chart.ts +3 -3
- package/src/chat.ts +1 -1
- package/src/config.ts +8 -6
- package/src/genie.ts +9 -6
- package/src/memory.ts +2 -32
- package/src/mlflow.ts +7 -15
- package/src/monty-sandbox.ts +1 -1
- package/src/plugin.ts +14 -69
- package/src/remote-skills.ts +11 -5
- package/src/server.ts +1 -1
- package/src/workspaces.ts +5 -5
- package/src/writer.ts +1 -1
package/src/genie.ts
CHANGED
|
@@ -248,7 +248,7 @@ async function readCachedConversationId(cacheKey: string | undefined): Promise<s
|
|
|
248
248
|
return v ?? undefined;
|
|
249
249
|
} catch (err) {
|
|
250
250
|
logger.warn("conversation-cache:read-error", {
|
|
251
|
-
error: errorUtils.
|
|
251
|
+
error: errorUtils.toError(err),
|
|
252
252
|
});
|
|
253
253
|
return undefined;
|
|
254
254
|
}
|
|
@@ -272,7 +272,7 @@ async function saveCachedConversationId(
|
|
|
272
272
|
});
|
|
273
273
|
} catch (err) {
|
|
274
274
|
logger.warn("conversation-cache:write-error", {
|
|
275
|
-
error: errorUtils.
|
|
275
|
+
error: errorUtils.toError(err),
|
|
276
276
|
});
|
|
277
277
|
}
|
|
278
278
|
}
|
|
@@ -284,7 +284,7 @@ async function evictCachedConversationId(cacheKey: string | undefined): Promise<
|
|
|
284
284
|
await CacheManager.getInstanceSync().delete(cacheKey);
|
|
285
285
|
} catch (err) {
|
|
286
286
|
logger.warn("conversation-cache:delete-error", {
|
|
287
|
-
error: errorUtils.
|
|
287
|
+
error: errorUtils.toError(err),
|
|
288
288
|
});
|
|
289
289
|
}
|
|
290
290
|
}
|
|
@@ -515,7 +515,7 @@ function buildAskGenieTool(opts: {
|
|
|
515
515
|
logger.warn("conversation-cache:stale, resetting", {
|
|
516
516
|
spaceId,
|
|
517
517
|
conversationId: rejectedConversationId,
|
|
518
|
-
error: errorUtils.
|
|
518
|
+
error: errorUtils.toError(err),
|
|
519
519
|
});
|
|
520
520
|
if (ownsReusableConversation) {
|
|
521
521
|
await evictCachedConversationId(cacheKey);
|
|
@@ -1115,7 +1115,9 @@ async function writeSuggestionCache(spaceId: string, questions: string[]): Promi
|
|
|
1115
1115
|
* questions and a multi-space app round-trips breadth-first up to the
|
|
1116
1116
|
* cap. A per-space fetch failure degrades to "no questions for that
|
|
1117
1117
|
* space" (logged, not thrown) so one unreachable space never blanks
|
|
1118
|
-
* the whole list.
|
|
1118
|
+
* the whole list. When `signal` aborts (the HTTP caller disconnected),
|
|
1119
|
+
* collection stops silently and returns what was merged so far.
|
|
1120
|
+
* Returns `[]` when no spaces are configured.
|
|
1119
1121
|
*/
|
|
1120
1122
|
export async function collectSpaceSuggestions(opts: {
|
|
1121
1123
|
spaces: Record<string, GenieSpaceConfig>;
|
|
@@ -1138,9 +1140,10 @@ export async function collectSpaceSuggestions(opts: {
|
|
|
1138
1140
|
questions = genieSpace.genieSampleQuestions(space);
|
|
1139
1141
|
await writeSuggestionCache(spaceId, questions);
|
|
1140
1142
|
} catch (err) {
|
|
1143
|
+
if (opts.signal?.aborted) return merged;
|
|
1141
1144
|
logger.warn("suggestions:fetch-error", {
|
|
1142
1145
|
spaceId,
|
|
1143
|
-
error: errorUtils.
|
|
1146
|
+
error: errorUtils.toError(err),
|
|
1144
1147
|
});
|
|
1145
1148
|
questions = [];
|
|
1146
1149
|
}
|
package/src/memory.ts
CHANGED
|
@@ -32,9 +32,7 @@
|
|
|
32
32
|
* @module
|
|
33
33
|
*/
|
|
34
34
|
|
|
35
|
-
import { getUsernameWithApiLookup } from "@databricks/appkit";
|
|
36
35
|
import { migration as appkitMigration } from "@dbx-tools/appkit";
|
|
37
|
-
import { postgresConnectionOptions } from "@dbx-tools/postgres";
|
|
38
36
|
import { hash, log } from "@dbx-tools/shared-core";
|
|
39
37
|
import type { AgentMemoryOption } from "@mastra/core/agent";
|
|
40
38
|
import {
|
|
@@ -45,7 +43,7 @@ import {
|
|
|
45
43
|
import { fastembed } from "@mastra/fastembed";
|
|
46
44
|
import { Memory } from "@mastra/memory";
|
|
47
45
|
import { PgVector, PostgresStore } from "@mastra/pg";
|
|
48
|
-
import { Pool
|
|
46
|
+
import type { Pool } from "pg";
|
|
49
47
|
|
|
50
48
|
import type { AnyMastraAgentDefinition, MastraMemoryConfigOverride } from "./agents.ts";
|
|
51
49
|
import type { MastraPluginConfig } from "./config.ts";
|
|
@@ -132,34 +130,6 @@ export function withSoftStorageInit(store: PostgresStore): PostgresStore {
|
|
|
132
130
|
return store;
|
|
133
131
|
}
|
|
134
132
|
|
|
135
|
-
/**
|
|
136
|
-
* Build a dedicated **service-principal** Lakebase pool for Mastra
|
|
137
|
-
* memory from the lakebase plugin's resolved SP pg config.
|
|
138
|
-
*
|
|
139
|
-
* The plugin's `exports().pool` is a `RoutingPool` that switches to
|
|
140
|
-
* the per-user (OBO) pool whenever a query runs inside an `asUser`
|
|
141
|
-
* scope - exactly the context the mastra plugin establishes around
|
|
142
|
-
* every chat turn. Memory (threads / messages + semantic recall) must
|
|
143
|
-
* instead always act as the app service principal: it owns the
|
|
144
|
-
* auto-created `mastra_*` schemas (a per-user role usually can't
|
|
145
|
-
* `CREATE SCHEMA`) and is shared across users, so it cannot inherit a
|
|
146
|
-
* request's OBO identity.
|
|
147
|
-
*
|
|
148
|
-
* `pgConfig` must be the plugin's `exports().getPgConfig()` evaluated
|
|
149
|
-
* **outside** any `asUser` scope (i.e. during setup), so it carries
|
|
150
|
-
* the SP connection target, OAuth token-refresh `password` callback,
|
|
151
|
-
* and any `lakebase({ pool })` tuning overrides - all of which this
|
|
152
|
-
* pool inherits. See the call site in `plugin.ts`.
|
|
153
|
-
*/
|
|
154
|
-
export async function createServicePrincipalPool(pgConfig: PoolConfig): Promise<Pool> {
|
|
155
|
-
// `getPgConfig()` resolves the SP username synchronously from
|
|
156
|
-
// `PGUSER` / `DATABRICKS_CLIENT_ID`; fall back to the async API
|
|
157
|
-
// lookup (e.g. local dev authenticating via PAT) so the pool always
|
|
158
|
-
// has an identity to connect with.
|
|
159
|
-
const user = pgConfig.user ?? (await getUsernameWithApiLookup());
|
|
160
|
-
return new Pool(postgresConnectionOptions({ ...pgConfig, user }));
|
|
161
|
-
}
|
|
162
|
-
|
|
163
133
|
/** Effective per-knob setting after the plugin/agent cascade. */
|
|
164
134
|
type StorageSetting = AnyMastraAgentDefinition["storage"];
|
|
165
135
|
type MemorySetting = AnyMastraAgentDefinition["memory"];
|
|
@@ -179,7 +149,7 @@ export function needsLakebase(config: MastraPluginConfig): boolean {
|
|
|
179
149
|
|
|
180
150
|
/**
|
|
181
151
|
* Construct a per-agent {@link Memory} factory bound to the supplied
|
|
182
|
-
* service-principal pool
|
|
152
|
+
* service-principal pool.
|
|
183
153
|
* Caches the shared `PgVector` singleton (built on first need) so each
|
|
184
154
|
* agent build is O(1) after the first.
|
|
185
155
|
*/
|
package/src/mlflow.ts
CHANGED
|
@@ -366,7 +366,7 @@ export async function initializeAppMlflowTraceInfo(client?: WorkspaceClient): Pr
|
|
|
366
366
|
return true;
|
|
367
367
|
} catch (err) {
|
|
368
368
|
logger.warn("Databricks Apps MLflow trace-info promotion disabled", {
|
|
369
|
-
error: errorUtils.
|
|
369
|
+
error: errorUtils.toError(err),
|
|
370
370
|
});
|
|
371
371
|
return false;
|
|
372
372
|
}
|
|
@@ -424,7 +424,7 @@ export function persistAppMlflowTraceInfo(params: AppMlflowTraceInfo): void {
|
|
|
424
424
|
.catch((err) => {
|
|
425
425
|
logger.warn("Databricks Apps MLflow trace-info promotion failed", {
|
|
426
426
|
traceId: params.traceId,
|
|
427
|
-
error: errorUtils.
|
|
427
|
+
error: errorUtils.toError(err),
|
|
428
428
|
});
|
|
429
429
|
})
|
|
430
430
|
.finally(() => pendingAppMlflowTraceInfo.delete(pending));
|
|
@@ -466,7 +466,7 @@ async function detectedDirectMlflowTraceLocation(
|
|
|
466
466
|
} catch (err) {
|
|
467
467
|
logger.warn("direct MLflow UC trace-location detection failed", {
|
|
468
468
|
experimentId,
|
|
469
|
-
error: errorUtils.
|
|
469
|
+
error: errorUtils.toError(err),
|
|
470
470
|
});
|
|
471
471
|
return undefined;
|
|
472
472
|
}
|
|
@@ -530,7 +530,7 @@ export async function initializeDirectMlflowTracing(): Promise<boolean> {
|
|
|
530
530
|
return true;
|
|
531
531
|
} catch (err) {
|
|
532
532
|
logger.warn("direct MLflow tracing disabled", {
|
|
533
|
-
error: errorUtils.
|
|
533
|
+
error: errorUtils.toError(err),
|
|
534
534
|
});
|
|
535
535
|
return false;
|
|
536
536
|
}
|
|
@@ -693,18 +693,10 @@ async function resolveExperimentId(client: WorkspaceClient): Promise<string | un
|
|
|
693
693
|
}
|
|
694
694
|
|
|
695
695
|
/** Parameters for {@link logFeedback}. */
|
|
696
|
-
export
|
|
697
|
-
/** MLflow trace id the assessment attaches to (`tr-<hex>`). */
|
|
698
|
-
traceId: string;
|
|
699
|
-
/** Assessment name; defaults per whether a value or a comment is sent. */
|
|
700
|
-
name?: string;
|
|
701
|
-
/** Thumbs / rating / label value. Omit for a comment-only submission. */
|
|
702
|
-
value?: boolean | number | string;
|
|
703
|
-
/** Freeform comment: the rationale alongside a value, or the value itself when none. */
|
|
704
|
-
comment?: string;
|
|
696
|
+
export type LogFeedbackParams = feedback.MastraFeedbackRequest & {
|
|
705
697
|
/** Identity the feedback is attributed to (user email / id). */
|
|
706
698
|
sourceId?: string;
|
|
707
|
-
}
|
|
699
|
+
};
|
|
708
700
|
|
|
709
701
|
/**
|
|
710
702
|
* Log a HUMAN feedback assessment to a trace. Returns the created
|
|
@@ -751,7 +743,7 @@ export async function logFeedback(
|
|
|
751
743
|
logger.warn("feedback request failed", {
|
|
752
744
|
traceId: params.traceId,
|
|
753
745
|
assessmentTraceId,
|
|
754
|
-
error: errorUtils.
|
|
746
|
+
error: errorUtils.toError(err),
|
|
755
747
|
});
|
|
756
748
|
return undefined;
|
|
757
749
|
}
|
package/src/monty-sandbox.ts
CHANGED
|
@@ -68,7 +68,7 @@ const montyContext = functionUtils.memoize(async (): Promise<MontyContext> => {
|
|
|
68
68
|
} catch (error) {
|
|
69
69
|
errors.push(errorUtils.toError(error));
|
|
70
70
|
logger.debug(`${target.name} unavailable`, {
|
|
71
|
-
error: errorUtils.
|
|
71
|
+
error: errorUtils.toError(error),
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
74
|
}
|
package/src/plugin.ts
CHANGED
|
@@ -56,7 +56,7 @@ import {
|
|
|
56
56
|
type PluginManifest,
|
|
57
57
|
type ResourceRequirement,
|
|
58
58
|
} from "@databricks/appkit";
|
|
59
|
-
import { pluginRegistry } from "@dbx-tools/appkit";
|
|
59
|
+
import { lakebaseResolver, pluginRegistry } from "@dbx-tools/appkit";
|
|
60
60
|
import { modelCatalog } from "@dbx-tools/model";
|
|
61
61
|
import { asyncUtils, errorUtils, log, object, stringUtils } from "@dbx-tools/shared-core";
|
|
62
62
|
import {
|
|
@@ -98,7 +98,7 @@ import {
|
|
|
98
98
|
type MastraIdentityMode,
|
|
99
99
|
} from "./identity.ts";
|
|
100
100
|
import { buildMcpServer, type ResolvedMcp } from "./mcp.ts";
|
|
101
|
-
import { createMemoryBuilder,
|
|
101
|
+
import { createMemoryBuilder, needsLakebase } from "./memory.ts";
|
|
102
102
|
import {
|
|
103
103
|
flushDirectMlflowTracing,
|
|
104
104
|
logFeedback,
|
|
@@ -124,13 +124,6 @@ import { invalidFields } from "./validation.ts";
|
|
|
124
124
|
const GENIE_MANIFEST = pluginRegistry.data(genie).plugin.manifest;
|
|
125
125
|
const LAKEBASE_MANIFEST = pluginRegistry.data(lakebase).plugin.manifest;
|
|
126
126
|
|
|
127
|
-
/**
|
|
128
|
-
* Budget for draining the memory service-principal pool on shutdown. Well
|
|
129
|
-
* inside AppKit's 15s graceful-shutdown window, so a stuck connection can
|
|
130
|
-
* never be what holds the process open.
|
|
131
|
-
*/
|
|
132
|
-
const POOL_DRAIN_TIMEOUT_MS = 5_000;
|
|
133
|
-
|
|
134
127
|
/** Ceiling on the `?timeoutMs=` long-poll budget a client may request. */
|
|
135
128
|
const MAX_EMBED_POLL_TIMEOUT_MS = 5 * 60_000;
|
|
136
129
|
|
|
@@ -243,15 +236,6 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
243
236
|
* boot rather than the first request, and so every request agrees.
|
|
244
237
|
*/
|
|
245
238
|
private identityMode: MastraIdentityMode = "user";
|
|
246
|
-
/**
|
|
247
|
-
* Dedicated service-principal Lakebase pool backing Mastra memory /
|
|
248
|
-
* storage. Built once in {@link buildAgentAndServer} (outside any
|
|
249
|
-
* `asUser` scope, so it never inherits a request's OBO identity) and
|
|
250
|
-
* drained in {@link shutdown}. `null` until setup runs or when
|
|
251
|
-
* Lakebase isn't needed.
|
|
252
|
-
*/
|
|
253
|
-
private servicePrincipalPool: Pool | null = null;
|
|
254
|
-
|
|
255
239
|
override async setup(): Promise<void> {
|
|
256
240
|
// Resolve the identity mode up front so an invalid `genieIdentity` fails the
|
|
257
241
|
// app boot with a clear message rather than 500-ing the first chat request.
|
|
@@ -298,44 +282,19 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
298
282
|
if (this.config.memory === undefined) this.config.memory = true;
|
|
299
283
|
}
|
|
300
284
|
|
|
301
|
-
/**
|
|
302
|
-
* Drain the memory service-principal pool. Idempotent: the handle is
|
|
303
|
-
* cleared before the drain starts, so a second call is a no-op and a
|
|
304
|
-
* later `setup()` rebuilds the pool. Bounded by
|
|
305
|
-
* {@link POOL_DRAIN_TIMEOUT_MS} to stay well inside the 15s graceful
|
|
306
|
-
* shutdown budget.
|
|
307
|
-
*/
|
|
285
|
+
/** Flush pending direct MLflow traces during graceful shutdown. */
|
|
308
286
|
async shutdown(): Promise<void> {
|
|
309
287
|
try {
|
|
310
288
|
await flushDirectMlflowTracing();
|
|
311
289
|
} catch (err) {
|
|
312
290
|
this.logger.warn("error flushing direct MLflow traces", {
|
|
313
|
-
error: errorUtils.
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
const pool = this.servicePrincipalPool;
|
|
317
|
-
if (!pool) return;
|
|
318
|
-
this.servicePrincipalPool = null;
|
|
319
|
-
this.logger.info("closing memory SP pool");
|
|
320
|
-
// The budget timer is cancelled on the way out so a drain that finished
|
|
321
|
-
// early cannot hold the event loop open for the rest of the window.
|
|
322
|
-
const budget = new AbortController();
|
|
323
|
-
try {
|
|
324
|
-
await Promise.race([pool.end(), asyncUtils.sleep(POOL_DRAIN_TIMEOUT_MS, budget.signal)]);
|
|
325
|
-
} catch (err) {
|
|
326
|
-
this.logger.error("error closing memory SP pool", {
|
|
327
|
-
error: errorUtils.errorMessage(err),
|
|
291
|
+
error: errorUtils.toError(err),
|
|
328
292
|
});
|
|
329
|
-
} finally {
|
|
330
|
-
budget.abort();
|
|
331
293
|
}
|
|
332
294
|
}
|
|
333
295
|
|
|
334
296
|
/**
|
|
335
|
-
* Abort in-flight work
|
|
336
|
-
* synchronously and never awaits {@link shutdown}, so the pool drain is
|
|
337
|
-
* started here too; it cannot be awaited from a `void` hook, and
|
|
338
|
-
* {@link shutdown} is idempotent so the duplicate call is free.
|
|
297
|
+
* Abort in-flight work and start the asynchronous trace flush.
|
|
339
298
|
*/
|
|
340
299
|
override abortActiveOperations(): void {
|
|
341
300
|
super.abortActiveOperations();
|
|
@@ -719,7 +678,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
719
678
|
// the upstream status. Log and degrade.
|
|
720
679
|
this.logger.warn("suggestions:error", {
|
|
721
680
|
status: result.status,
|
|
722
|
-
error: result.message,
|
|
681
|
+
error: errorUtils.toError(result.message),
|
|
723
682
|
});
|
|
724
683
|
res.json({ questions: [] });
|
|
725
684
|
return;
|
|
@@ -765,7 +724,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
765
724
|
if (!parsed.success) {
|
|
766
725
|
// A Zod issue string quotes the received body back, so only the
|
|
767
726
|
// offending field names travel; the full issue list is logged.
|
|
768
|
-
this.logger.warn("feedback:invalid", { error: parsed.error
|
|
727
|
+
this.logger.warn("feedback:invalid", { error: parsed.error });
|
|
769
728
|
res.status(400).json({
|
|
770
729
|
ok: false,
|
|
771
730
|
error: INVALID_FEEDBACK_MESSAGE,
|
|
@@ -856,7 +815,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
856
815
|
): void {
|
|
857
816
|
this.logger.warn(`${operation}:error`, {
|
|
858
817
|
status: result.status,
|
|
859
|
-
error: result.message,
|
|
818
|
+
error: errorUtils.toError(result.message),
|
|
860
819
|
});
|
|
861
820
|
if (res.headersSent) return;
|
|
862
821
|
res.status(result.status).json({ error: clientMessage });
|
|
@@ -1074,32 +1033,18 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
1074
1033
|
if (result.ok) return result.data;
|
|
1075
1034
|
this.logger.warn("listModels:error", {
|
|
1076
1035
|
status: result.status,
|
|
1077
|
-
error: result.message,
|
|
1036
|
+
error: errorUtils.toError(result.message),
|
|
1078
1037
|
});
|
|
1079
1038
|
throw new ExecutionError(MODEL_CATALOGUE_FAILED_MESSAGE);
|
|
1080
1039
|
}
|
|
1081
1040
|
|
|
1082
1041
|
private async buildAgentAndServer(): Promise<void> {
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
// `getPgConfig()` is read here, outside any `asUser` scope, so it
|
|
1088
|
-
// returns the SP connection target + token refresh plus any
|
|
1089
|
-
// `lakebase({ pool })` overrides; `require` turns a missing
|
|
1090
|
-
// sibling into a clear wiring error. The builder caches the shared
|
|
1091
|
-
// `PgVector` singleton so registering N agents stays cheap. See
|
|
1092
|
-
// `./memory.js`.
|
|
1093
|
-
if (needsLakebase(this.config)) {
|
|
1094
|
-
const spPgConfig = pluginRegistry
|
|
1095
|
-
.require(this.context, lakebase, this.config)
|
|
1096
|
-
.exports()
|
|
1097
|
-
.getPgConfig();
|
|
1098
|
-
this.servicePrincipalPool = await createServicePrincipalPool(spPgConfig);
|
|
1099
|
-
}
|
|
1100
|
-
const memoryBuilder = this.servicePrincipalPool
|
|
1101
|
-
? createMemoryBuilder(this.config, this.servicePrincipalPool)
|
|
1042
|
+
const memoryPool = needsLakebase(this.config)
|
|
1043
|
+
? (lakebaseResolver.captureServicePrincipalPool(
|
|
1044
|
+
pluginRegistry.require(this.context, lakebase, this.config).exports().pool,
|
|
1045
|
+
) as Pool)
|
|
1102
1046
|
: undefined;
|
|
1047
|
+
const memoryBuilder = memoryPool ? createMemoryBuilder(this.config, memoryPool) : undefined;
|
|
1103
1048
|
|
|
1104
1049
|
// Build every agent declared in `config.agents` (or the built-in
|
|
1105
1050
|
// fallback when none are declared). Each agent's `model` resolves
|
package/src/remote-skills.ts
CHANGED
|
@@ -436,7 +436,7 @@ async function readMetadata(fs: FileSystem): Promise<RemoteSkillsMetadata | unde
|
|
|
436
436
|
if (!object.isRecord(parsed) || parsed.version !== METADATA_VERSION) return undefined;
|
|
437
437
|
return object.isRecord(parsed.sources) ? parsed : undefined;
|
|
438
438
|
} catch (err) {
|
|
439
|
-
logger.debug("cache:unreadable", { error: errorUtils.
|
|
439
|
+
logger.debug("cache:unreadable", { error: errorUtils.toError(err) });
|
|
440
440
|
return undefined;
|
|
441
441
|
}
|
|
442
442
|
}
|
|
@@ -599,7 +599,7 @@ export async function provisionRemoteSkills(
|
|
|
599
599
|
}
|
|
600
600
|
logger.warn("source:skipped", {
|
|
601
601
|
source: sourceOptions.source,
|
|
602
|
-
error: errorUtils.
|
|
602
|
+
error: errorUtils.toError(err),
|
|
603
603
|
});
|
|
604
604
|
}
|
|
605
605
|
}
|
|
@@ -658,7 +658,10 @@ async function cachedAiToolsTree(
|
|
|
658
658
|
async function serializeSkillDirs(dirs: readonly StagedSkillDir[]): Promise<CachedSkillFile[]> {
|
|
659
659
|
const files: CachedSkillFile[] = [];
|
|
660
660
|
for (const dir of dirs) {
|
|
661
|
-
for (const relative of find.findFiles("**/*", {
|
|
661
|
+
for await (const relative of find.findFiles("**/*", {
|
|
662
|
+
cwd: dir.absolutePath,
|
|
663
|
+
nodir: true,
|
|
664
|
+
})) {
|
|
662
665
|
files.push({
|
|
663
666
|
path: posix.join(dir.name, relative.split(/[\\/]/).join("/")),
|
|
664
667
|
content: (await readFile(join(dir.absolutePath, relative))).toString("base64"),
|
|
@@ -752,7 +755,7 @@ async function openWritableWorkspace(
|
|
|
752
755
|
} catch (err) {
|
|
753
756
|
logger.warn("destination:unwritable", {
|
|
754
757
|
destination: basePath,
|
|
755
|
-
error: errorUtils.
|
|
758
|
+
error: errorUtils.toError(err),
|
|
756
759
|
});
|
|
757
760
|
return undefined;
|
|
758
761
|
}
|
|
@@ -996,7 +999,10 @@ async function collectSkillDirs(root: string): Promise<StagedSkillDir[]> {
|
|
|
996
999
|
async function copySkillDirs(destination: FileSystem, dirs: StagedSkillDir[]): Promise<void> {
|
|
997
1000
|
await destination.init();
|
|
998
1001
|
for (const dir of dirs) {
|
|
999
|
-
for (const relative of find.findFiles("**/*", {
|
|
1002
|
+
for await (const relative of find.findFiles("**/*", {
|
|
1003
|
+
cwd: dir.absolutePath,
|
|
1004
|
+
nodir: true,
|
|
1005
|
+
})) {
|
|
1000
1006
|
const buffer = await readFile(join(dir.absolutePath, relative));
|
|
1001
1007
|
const skillPath = posix.join(dir.name, relative.split(/[\\/]/).join("/"));
|
|
1002
1008
|
await destination.writeFile(skillPath, buffer, { overwrite: true });
|
package/src/server.ts
CHANGED
|
@@ -484,7 +484,7 @@ export function attachStaleResumeRecovery(app: express.Express): void {
|
|
|
484
484
|
}
|
|
485
485
|
logger.warn("ignored stale mastra resume", {
|
|
486
486
|
path: req.path,
|
|
487
|
-
error: errorUtils.
|
|
487
|
+
error: errorUtils.toError(error),
|
|
488
488
|
});
|
|
489
489
|
if (res.headersSent) {
|
|
490
490
|
res.end();
|
package/src/workspaces.ts
CHANGED
|
@@ -840,7 +840,7 @@ async function loadInMemorySkillFilesystem(mount: LocalSkillMount): Promise<File
|
|
|
840
840
|
root: "/",
|
|
841
841
|
});
|
|
842
842
|
await memory.init();
|
|
843
|
-
for (const relative of find.findFiles("**/*", { cwd: mount.root, nodir: true })) {
|
|
843
|
+
for await (const relative of find.findFiles("**/*", { cwd: mount.root, nodir: true })) {
|
|
844
844
|
await memory.writeFile(relative, await source.readFile(relative), { overwrite: true });
|
|
845
845
|
}
|
|
846
846
|
await source.close();
|
|
@@ -896,7 +896,7 @@ async function databricksFilesystem(
|
|
|
896
896
|
logger.debug("databricks-mount:skipped", {
|
|
897
897
|
root,
|
|
898
898
|
readOnly,
|
|
899
|
-
error: errorUtils.
|
|
899
|
+
error: errorUtils.toError(err),
|
|
900
900
|
});
|
|
901
901
|
}
|
|
902
902
|
return undefined;
|
|
@@ -945,7 +945,7 @@ function verifyFirstFileSystemAccess<TFileSystem extends FileSystem>(
|
|
|
945
945
|
readCheck = undefined;
|
|
946
946
|
logger.debug("databricks-mount:read-check-failed", {
|
|
947
947
|
root,
|
|
948
|
-
error: errorUtils.
|
|
948
|
+
error: errorUtils.toError(error),
|
|
949
949
|
});
|
|
950
950
|
throw error;
|
|
951
951
|
}
|
|
@@ -976,7 +976,7 @@ function verifyFirstFileSystemAccess<TFileSystem extends FileSystem>(
|
|
|
976
976
|
if (!writeVerified) {
|
|
977
977
|
logger.debug("databricks-mount:write-check-failed", {
|
|
978
978
|
root,
|
|
979
|
-
error: errorUtils.
|
|
979
|
+
error: errorUtils.toError(error),
|
|
980
980
|
});
|
|
981
981
|
}
|
|
982
982
|
throw error;
|
|
@@ -1079,7 +1079,7 @@ async function resolveDistinctSkillPaths(
|
|
|
1079
1079
|
} catch (error) {
|
|
1080
1080
|
logger.debug("skill-path:skipped", {
|
|
1081
1081
|
path,
|
|
1082
|
-
error: errorUtils.
|
|
1082
|
+
error: errorUtils.toError(error),
|
|
1083
1083
|
});
|
|
1084
1084
|
}
|
|
1085
1085
|
}
|