@mastra/core
Version:
1,864 lines • 88.1 kB
JavaScript
const require_utils = require("./utils-CNiGU0Uf.cjs");
const require_tracing = require("./tracing-BUrUJwCM.cjs");
const require_zod_utils = require("./zod-utils-BAGXGqPm.cjs");
let zod_v4 = require("zod/v4");
//#region src/evals/types.ts
const scoringSourceSchema = zod_v4.z.enum(["LIVE", "TEST"]);
const scoringEntityTypeSchema = zod_v4.z.enum([
"AGENT",
"WORKFLOW",
"TRAJECTORY",
"STEP",
...Object.values(require_tracing.SpanType)
]);
const scoringPromptsSchema = zod_v4.z.object({
description: zod_v4.z.string(),
prompt: zod_v4.z.string()
});
/** Reusable schema for required record fields (e.g., scorer, entity) */
const recordSchema = zod_v4.z.record(zod_v4.z.string(), zod_v4.z.unknown());
/** Reusable schema for optional record fields (e.g., metadata, additionalContext) */
const optionalRecordSchema = recordSchema.optional();
const scoringInputSchema = zod_v4.z.object({
runId: zod_v4.z.string().optional(),
input: zod_v4.z.unknown().optional(),
output: zod_v4.z.unknown(),
additionalContext: optionalRecordSchema,
requestContext: optionalRecordSchema
});
const scoringHookInputSchema = zod_v4.z.object({
runId: zod_v4.z.string().optional(),
scorer: recordSchema,
input: zod_v4.z.unknown(),
output: zod_v4.z.unknown(),
metadata: optionalRecordSchema,
additionalContext: optionalRecordSchema,
source: scoringSourceSchema,
entity: recordSchema,
entityType: scoringEntityTypeSchema,
requestContext: optionalRecordSchema,
structuredOutput: zod_v4.z.boolean().optional(),
traceId: zod_v4.z.string().optional(),
spanId: zod_v4.z.string().optional(),
resourceId: zod_v4.z.string().optional(),
threadId: zod_v4.z.string().optional(),
projectId: zod_v4.z.string().optional()
});
const scoringExtractStepResultSchema = optionalRecordSchema;
const scoringValueSchema = zod_v4.z.number();
const scoreResultSchema = zod_v4.z.object({
result: optionalRecordSchema,
score: scoringValueSchema,
prompt: zod_v4.z.string().optional()
});
const scoringInputWithExtractStepResultSchema = scoringInputSchema.extend({
runId: zod_v4.z.string(),
extractStepResult: optionalRecordSchema,
extractPrompt: zod_v4.z.string().optional()
});
const scoringInputWithExtractStepResultAndAnalyzeStepResultSchema = scoringInputWithExtractStepResultSchema.extend({
score: zod_v4.z.number(),
analyzeStepResult: optionalRecordSchema,
analyzePrompt: zod_v4.z.string().optional()
});
const scoringInputWithExtractStepResultAndScoreAndReasonSchema = scoringInputWithExtractStepResultAndAnalyzeStepResultSchema.extend({
reason: zod_v4.z.string().optional(),
reasonPrompt: zod_v4.z.string().optional()
});
const scoreRowDataSchema = zod_v4.z.object({
id: zod_v4.z.string(),
scorerId: zod_v4.z.string(),
entityId: zod_v4.z.string(),
runId: zod_v4.z.string(),
input: zod_v4.z.unknown().optional(),
output: zod_v4.z.unknown(),
additionalContext: optionalRecordSchema,
requestContext: optionalRecordSchema,
extractStepResult: optionalRecordSchema,
extractPrompt: zod_v4.z.string().optional(),
score: zod_v4.z.number(),
analyzeStepResult: optionalRecordSchema,
analyzePrompt: zod_v4.z.string().optional(),
reason: zod_v4.z.string().optional(),
reasonPrompt: zod_v4.z.string().optional(),
scorer: recordSchema,
metadata: optionalRecordSchema,
source: scoringSourceSchema,
entity: recordSchema,
entityType: scoringEntityTypeSchema.optional(),
structuredOutput: zod_v4.z.boolean().optional(),
traceId: zod_v4.z.string().optional(),
spanId: zod_v4.z.string().optional(),
resourceId: zod_v4.z.string().optional(),
threadId: zod_v4.z.string().optional(),
organizationId: zod_v4.z.string().nullish(),
projectId: zod_v4.z.string().nullish(),
batchId: zod_v4.z.string().nullish(),
datasetId: zod_v4.z.string().nullish(),
datasetItemId: zod_v4.z.string().nullish(),
preprocessStepResult: optionalRecordSchema,
preprocessPrompt: zod_v4.z.string().optional(),
generateScorePrompt: zod_v4.z.string().optional(),
generateReasonPrompt: zod_v4.z.string().optional(),
...require_utils.dbTimestamps
});
const saveScorePayloadSchema = scoreRowDataSchema.omit({
id: true,
createdAt: true,
updatedAt: true
});
const listScoresResponseSchema = zod_v4.z.object({
pagination: require_utils.paginationInfoSchema,
scores: zod_v4.z.array(scoreRowDataSchema)
});
/**
* Extracts a Trajectory from agent output messages by walking through
* tool invocations.
*
* This is called automatically by `runEvals` when using `AgentScorerConfig.trajectory`
* scorers — trajectory scorers receive a pre-extracted `Trajectory` as their `output`
* instead of raw `MastraDBMessage[]`.
*
* @param output - The raw agent output messages
* @returns A Trajectory with ToolCallStep entries extracted from tool invocations
*/
function extractTrajectory(output) {
const steps = [];
for (const message of output) {
const legacy = message?.content?.toolInvocations;
const fromParts = legacy ? void 0 : message?.content?.parts?.filter((p) => p.type === "tool-invocation").map((p) => p.toolInvocation);
const toolInvocations = legacy ?? fromParts;
if (!toolInvocations?.length) continue;
for (const invocation of toolInvocations) if (invocation && invocation.toolName && (invocation.state === "result" || invocation.state === "call")) {
const toolArgs = invocation.args != null && typeof invocation.args === "object" && !Array.isArray(invocation.args) ? invocation.args : invocation.args != null ? { value: invocation.args } : void 0;
const rawResult = invocation.state === "result" ? invocation.result : void 0;
const toolResult = rawResult != null && typeof rawResult === "object" && !Array.isArray(rawResult) ? rawResult : rawResult != null ? { value: rawResult } : void 0;
steps.push({
stepType: "tool_call",
name: invocation.toolName,
toolArgs,
toolResult,
success: invocation.state === "result"
});
}
}
return {
steps,
rawOutput: output
};
}
/**
* Extracts a Trajectory from workflow step results.
*
* Converts the `stepResults` record (and optional `stepExecutionPath` ordering)
* into a flat list of `WorkflowStepStep` entries. Each step captures its status,
* output, and timing.
*
* This is called automatically by `runEvals` when using `WorkflowScorerConfig.trajectory`
* scorers.
*
* @param stepResults - The workflow step results record
* @param stepExecutionPath - Optional ordered list of step IDs for execution ordering
* @returns A Trajectory with WorkflowStepStep entries
*/
function extractWorkflowTrajectory(stepResults, stepExecutionPath) {
const steps = [];
const stepIds = stepExecutionPath ?? Object.keys(stepResults);
let totalStartedAt;
let totalEndedAt;
for (const stepId of stepIds) {
const result = stepResults[stepId];
if (!result) continue;
if (result.startedAt != null) {
if (totalStartedAt == null || result.startedAt < totalStartedAt) totalStartedAt = result.startedAt;
}
const endedAt = "endedAt" in result ? result.endedAt : void 0;
if (endedAt != null) {
if (totalEndedAt == null || endedAt > totalEndedAt) totalEndedAt = endedAt;
}
const durationMs = result.startedAt != null && endedAt != null ? endedAt - result.startedAt : void 0;
const output = "output" in result && result.output != null && typeof result.output === "object" && !Array.isArray(result.output) ? result.output : "output" in result && result.output != null ? { value: result.output } : void 0;
steps.push({
stepType: "workflow_step",
name: stepId,
stepId,
status: result.status,
output,
durationMs,
metadata: result.metadata
});
}
return {
steps,
totalDurationMs: totalStartedAt != null && totalEndedAt != null ? totalEndedAt - totalStartedAt : void 0,
rawWorkflowResult: {
stepResults,
stepExecutionPath
}
};
}
/**
* Span types that are considered noise and should be skipped during
* trace-to-trajectory conversion (internal implementation details, not
* meaningful trajectory steps).
*/
const SKIPPED_SPAN_TYPES = /* @__PURE__ */ new Set([
"scorer_run",
"scorer_step",
"generic",
"model_step",
"model_inference",
"model_chunk",
"workflow_conditional_eval"
]);
/**
* Converts a `SpanTreeNode` to `TrajectoryStep` entries.
*
* Returns an array because a skipped span promotes its children into the
* parent's list rather than dropping them entirely.
*/
function spanToTrajectorySteps(node) {
const { span, children: childNodes } = node;
if (SKIPPED_SPAN_TYPES.has(span.spanType)) return childNodes.flatMap(spanToTrajectorySteps);
const durationMs = span.endedAt != null && span.startedAt != null ? span.endedAt.getTime() - span.startedAt.getTime() : void 0;
const childSteps = childNodes.flatMap(spanToTrajectorySteps);
const base = {
name: span.name,
durationMs,
metadata: span.metadata,
...childSteps.length > 0 ? { children: childSteps } : {}
};
const attrs = span.attributes ?? {};
switch (span.spanType) {
case "tool_call": {
const toolArgs = toRecordOrUndefined(span.input);
const toolResult = toRecordOrUndefined(span.output);
return [{
...base,
stepType: "tool_call",
toolArgs,
toolResult,
success: typeof attrs.success === "boolean" ? attrs.success : void 0
}];
}
case "mcp_tool_call": {
const toolArgs = toRecordOrUndefined(span.input);
const toolResult = toRecordOrUndefined(span.output);
return [{
...base,
stepType: "mcp_tool_call",
toolArgs,
toolResult,
mcpServer: typeof attrs.mcpServer === "string" ? attrs.mcpServer : void 0,
success: typeof attrs.success === "boolean" ? attrs.success : void 0
}];
}
case "provider_tool_call": {
const toolArgs = toRecordOrUndefined(span.input);
const toolResult = toRecordOrUndefined(span.output);
return [{
...base,
stepType: "provider_tool_call",
toolArgs,
toolResult,
success: typeof attrs.success === "boolean" ? attrs.success : void 0
}];
}
case "model_generation": {
const usage = attrs.usage;
return [{
...base,
stepType: "model_generation",
modelId: typeof attrs.model === "string" ? attrs.model : void 0,
promptTokens: usage?.inputTokens,
completionTokens: usage?.outputTokens,
finishReason: typeof attrs.finishReason === "string" ? attrs.finishReason : void 0
}];
}
case "agent_run": return [{
...base,
stepType: "agent_run",
agentId: span.entityId ?? void 0
}];
case "workflow_run": return [{
...base,
stepType: "workflow_run",
workflowId: span.entityId ?? void 0
}];
case "workflow_step": {
const output = toRecordOrUndefined(span.output);
return [{
...base,
stepType: "workflow_step",
stepId: span.name,
output
}];
}
case "workflow_conditional": return [{
...base,
stepType: "workflow_conditional"
}];
case "workflow_parallel": return [{
...base,
stepType: "workflow_parallel"
}];
case "workflow_loop": return [{
...base,
stepType: "workflow_loop"
}];
case "workflow_sleep": return [{
...base,
stepType: "workflow_sleep"
}];
case "workflow_wait_event": return [{
...base,
stepType: "workflow_wait_event"
}];
case "processor_run": return [{
...base,
stepType: "processor_run"
}];
default: return childSteps;
}
}
/**
* Safely converts a value to `Record<string, unknown>` or returns undefined.
*/
function toRecordOrUndefined(value) {
if (value == null) return void 0;
if (typeof value === "object" && !Array.isArray(value)) return value;
return { value };
}
/**
* Extracts a hierarchical Trajectory from trace spans (as returned by the
* observability store's `getTrace()`).
*
* Builds a parent-child tree from `parentSpanId` references, then recursively
* converts each span to the appropriate `TrajectoryStep` discriminated union
* type with nested `children`.
*
* Noise spans (`generic`, `model_step`, `model_chunk`, `workflow_conditional_eval`)
* are automatically skipped.
*
* This is used by `runEvals` when storage is available to produce richer,
* hierarchical trajectories that include nested agent runs, tool calls, and
* model generations inside workflow or agent steps.
*
* @param spans - Flat array of span records from `getTrace().spans`
* @param rootSpanId - Optional span ID to use as root. If omitted, spans with
* no parent are used as roots.
* @returns A Trajectory with hierarchical TrajectoryStep entries
*
* @example
* ```ts
* const trace = await observabilityStore.getTrace({ traceId });
* const trajectory = extractTrajectoryFromTrace(trace.spans, workflowSpanId);
* ```
*/
function extractTrajectoryFromTrace(spans, rootSpanId) {
if (spans.length === 0) return { steps: [] };
const nodeMap = /* @__PURE__ */ new Map();
for (const span of spans) nodeMap.set(span.spanId, {
span,
children: []
});
const roots = [];
for (const span of spans) {
const node = nodeMap.get(span.spanId);
if (span.parentSpanId && nodeMap.has(span.parentSpanId)) nodeMap.get(span.parentSpanId).children.push(node);
else roots.push(node);
}
for (const node of nodeMap.values()) node.children.sort((a, b) => a.span.startedAt.getTime() - b.span.startedAt.getTime());
let targetRoots;
if (rootSpanId) {
const rootNode = nodeMap.get(rootSpanId);
targetRoots = rootNode ? [rootNode] : roots;
} else targetRoots = roots;
let stepsToConvert;
if (targetRoots.length === 1) {
const root = targetRoots[0];
if ((/* @__PURE__ */ new Set(["workflow_run", "agent_run"])).has(root.span.spanType)) stepsToConvert = root.children;
else stepsToConvert = targetRoots;
} else stepsToConvert = targetRoots;
const steps = stepsToConvert.flatMap(spanToTrajectorySteps);
let totalDurationMs;
if (targetRoots.length === 1) {
const root = targetRoots[0].span;
if (root.endedAt && root.startedAt) totalDurationMs = root.endedAt.getTime() - root.startedAt.getTime();
}
return {
steps,
totalDurationMs
};
}
//#endregion
//#region src/storage/types.ts
const STORAGE_VISIBILITY_VALUES = ["private", "public"];
function unwrapSchema(schema) {
let current = schema;
let nullable = false;
while (true) {
const typeName = require_zod_utils.getZodTypeName(current);
if (!typeName) break;
if (typeName === "ZodNullable" || typeName === "ZodOptional") nullable = true;
const inner = require_zod_utils.getZodInnerType(current, typeName);
if (!inner) break;
current = inner;
}
return {
base: current,
nullable
};
}
/**
* Extract checks array from Zod schema, compatible with both Zod 3 and Zod 4.
* Zod 3 uses _def.checks with {kind: "..."} objects
* Zod 4 uses _zod.def.checks with {def: {check: "...", format: "..."}} objects
*/
function getZodChecks(schema) {
if ("_zod" in schema) {
const checks = schema._zod?.def?.checks;
if (checks && Array.isArray(checks)) return checks.map((check) => {
if (typeof check === "object" && check !== null && "def" in check && typeof check.def === "object" && check.def !== null) {
const def = check.def;
if (def.check === "number_format" && def.format === "safeint") return { kind: "int" };
if (def.check === "string_format" && typeof def.format === "string") return { kind: def.format };
return { kind: typeof def.check === "string" ? def.check : "unknown" };
}
return { kind: "unknown" };
});
}
if ("_def" in schema) {
const checks = schema._def?.checks;
if (checks && Array.isArray(checks)) return checks;
}
return [];
}
function zodToStorageType(schema) {
const typeName = require_zod_utils.getZodTypeName(schema);
if (typeName === "ZodString") {
if (getZodChecks(schema).some((c) => c.kind === "uuid")) return "uuid";
return "text";
}
if (typeName === "ZodNativeEnum" || typeName === "ZodEnum") return "text";
if (typeName === "ZodNumber") return getZodChecks(schema).some((c) => c.kind === "int") ? "integer" : "float";
if (typeName === "ZodBigInt" || typeName === "ZodBigint") return "bigint";
if (typeName === "ZodDate") return "timestamp";
if (typeName === "ZodBoolean") return "boolean";
return "jsonb";
}
/**
* Converts a zod schema into a database schema
* @param zObject A zod schema object
* @returns database schema record with StorageColumns
*/
function buildStorageSchema(zObject) {
const shape = zObject.shape;
const result = {};
for (const [key, field] of Object.entries(shape)) {
const { base, nullable } = unwrapSchema(field);
result[key] = {
type: zodToStorageType(base),
nullable
};
}
return result;
}
const STORAGE_FAVORITE_ENTITY_TYPES = ["agent", "skill"];
//#endregion
//#region src/storage/domains/observability/tracing.ts
/**
* Creates an omit key object from a Zod schema shape.
* This allows dynamically deriving omit keys from existing schema definitions.
*/
const createOmitKeys = (shape) => Object.fromEntries(Object.keys(shape).map((k) => [k, true]));
const spanNameField = zod_v4.z.string().describe("Human-readable span name");
const parentSpanIdField = zod_v4.z.string().describe("Parent span reference (null = root span)");
const spanTypeField = zod_v4.z.nativeEnum(require_tracing.SpanType).describe("Span type (e.g., WORKFLOW_RUN, AGENT_RUN, TOOL_CALL, etc.)");
const attributesField = zod_v4.z.record(zod_v4.z.string(), zod_v4.z.unknown()).describe("Span-type specific attributes (e.g., model, tokens, tools)");
const linksField = zod_v4.z.array(zod_v4.z.unknown()).describe("References to related spans in other traces");
const inputField = zod_v4.z.unknown().describe("Input data passed to the span");
const outputField = zod_v4.z.unknown().describe("Output data returned from the span");
const errorField = zod_v4.z.unknown().describe("Error info - presence indicates failure (status derived from this)");
const isEventField = zod_v4.z.boolean().describe("Whether this is an event (point-in-time) vs a span (duration)");
const startedAtField = zod_v4.z.date().describe("When the span started");
const endedAtField = zod_v4.z.date().describe("When the span ended (null = running, status derived from this)");
/** Derived status of a trace, computed from the root span's error and endedAt fields. */
let TraceStatus = /* @__PURE__ */ function(TraceStatus) {
TraceStatus["SUCCESS"] = "success";
TraceStatus["ERROR"] = "error";
TraceStatus["RUNNING"] = "running";
return TraceStatus;
}({});
const traceStatusField = zod_v4.z.nativeEnum(TraceStatus).describe("Current status of the trace");
const hasChildErrorField = zod_v4.z.preprocess((v) => {
if (v === "true") return true;
if (v === "false") return false;
return v;
}, zod_v4.z.boolean()).describe("True if any span in the trace encountered an error");
/**
* All optional fields shared between span records and trace filters.
* Built from spanContextFields plus span-specific metadata/tags.
* Note: When filtering traces, these fields are matched against the root span.
*/
const sharedFields = {
...require_utils.spanContextFields,
metadata: require_utils.metadataField.nullish(),
tags: require_utils.tagsField.nullish()
};
/** Shape containing trace and span identifier fields */
const spanIds = {
traceId: require_utils.traceIdField,
spanId: require_utils.spanIdField
};
/** Schema for span identifiers (traceId and spanId) */
const spanIdsSchema = zod_v4.z.object({ ...spanIds });
const omitDbTimestamps = createOmitKeys(require_utils.dbTimestamps);
const omitSpanIds = createOmitKeys(spanIds);
/** Schema for a complete span record as stored in the database */
const spanRecordSchema = zod_v4.z.object({
...spanIds,
name: spanNameField,
spanType: spanTypeField,
isEvent: isEventField,
startedAt: startedAtField,
parentSpanId: parentSpanIdField.nullish(),
...sharedFields,
experimentId: zod_v4.z.string().nullish().describe("Experiment or eval run identifier"),
attributes: attributesField.nullish(),
links: linksField.nullish(),
input: inputField.nullish(),
output: outputField.nullish(),
error: errorField.nullish(),
endedAt: endedAtField.nullish(),
requestContext: zod_v4.z.record(zod_v4.z.string(), zod_v4.z.unknown()).nullish().describe("Request context data"),
...require_utils.dbTimestamps
}).describe("Span record data");
/**
* Computes the trace status from a root span's error and endedAt fields.
* - ERROR: if error is present (regardless of endedAt)
* - RUNNING: if endedAt is null/undefined and no error
* - SUCCESS: if endedAt is present and no error
*/
function computeTraceStatus(span) {
if (span.error != null) return "error";
if (span.endedAt == null) return "running";
return "success";
}
/** Schema for a trace span (root span with computed status) */
const traceSpanSchema = spanRecordSchema.extend({ status: traceStatusField }).describe("Trace span with computed status (root spans only)");
/**
* Converts a SpanRecord to a TraceSpan by adding computed status.
* Used when returning root spans from listTraces.
*/
function toTraceSpan(span) {
return {
...span,
status: computeTraceStatus(span)
};
}
/**
* Converts an array of SpanRecords to TraceSpans by adding computed status.
* Used when returning root spans from listTraces.
*/
function toTraceSpans(spans) {
return spans.map(toTraceSpan);
}
/**
* Schema for creating a span (without db timestamps)
*/
const createSpanRecordSchema = spanRecordSchema.omit(omitDbTimestamps);
/**
* Schema for createSpan operation arguments
*/
const createSpanArgsSchema = zod_v4.z.object({ span: createSpanRecordSchema }).describe("Arguments for creating a single span");
/**
* Schema for batchCreateSpans operation arguments
*/
const batchCreateSpansArgsSchema = zod_v4.z.object({ records: zod_v4.z.array(createSpanRecordSchema) }).describe("Arguments for batch creating spans");
/**
* Schema for getSpan operation arguments
*/
const getSpanArgsSchema = zod_v4.z.object({
traceId: require_utils.traceIdField.min(1),
spanId: require_utils.spanIdField.min(1)
}).describe("Arguments for getting a single span");
/**
* Response schema for getSpan operation
*/
const getSpanResponseSchema = zod_v4.z.object({ span: spanRecordSchema });
/**
* Schema for getSpans (batch) operation arguments.
*
* Fetches multiple spans in a trace by spanId in one call. Used to power the
* progressive-disclosure path in {@link getBranchArgsSchema}: walk the
* lightweight {@link getStructureResponseSchema} to find which spanIds belong
* to a branch, then fetch only those with full data instead of pulling the
* entire trace.
*/
const getSpansArgsSchema = zod_v4.z.object({
traceId: require_utils.traceIdField.min(1),
spanIds: zod_v4.z.array(require_utils.spanIdField.min(1)).min(1).describe("Span IDs to fetch within the trace")
}).describe("Arguments for batch-fetching spans by spanId within a trace");
/** Response schema for getSpans operation */
const getSpansResponseSchema = zod_v4.z.object({
traceId: require_utils.traceIdField,
spans: zod_v4.z.array(spanRecordSchema)
});
/**
* Schema for getRootSpan operation arguments
*/
const getRootSpanArgsSchema = zod_v4.z.object({ traceId: require_utils.traceIdField.min(1) }).describe("Arguments for getting a root span");
/**
* Response schema for getRootSpan operation
*/
const getRootSpanResponseSchema = zod_v4.z.object({ span: spanRecordSchema });
/**
* Schema for getTrace operation arguments
*/
const getTraceArgsSchema = zod_v4.z.object({ traceId: require_utils.traceIdField.min(1) }).describe("Arguments for getting a single trace");
/**
* Response schema for getTrace operation
*/
const getTraceResponseSchema = zod_v4.z.object({
traceId: require_utils.traceIdField,
spans: zod_v4.z.array(spanRecordSchema)
});
/**
* Schema for getBranch operation arguments.
*
* Returns the subtree rooted at `spanId`. When `depth` is omitted the full
* descendant subtree is returned; with a finite `depth` only that many levels
* below the anchor are returned (depth: 0 → only the anchor span; depth: 1 →
* anchor plus immediate children; etc).
*/
const getBranchArgsSchema = zod_v4.z.object({
traceId: require_utils.traceIdField.min(1),
spanId: require_utils.spanIdField.min(1),
depth: zod_v4.z.coerce.number().int().min(0).optional().describe("Maximum descendant levels below the anchor span (omit for full subtree)")
}).describe("Arguments for getting a span branch (subtree rooted at a span)");
/**
* Response schema for getBranch operation. Mirrors getTrace -- a flat list of
* spans, traversal-agnostic. The anchor span is included as the first matching
* span; callers reconstruct the tree via parentSpanId.
*/
const getBranchResponseSchema = zod_v4.z.object({
traceId: require_utils.traceIdField,
spans: zod_v4.z.array(spanRecordSchema)
});
/**
* Extracts the subtree rooted at `anchorSpanId` from a flat list of trace
* spans. The anchor itself is included as the first element; descendants are
* walked via `parentSpanId` and returned sorted by `startedAt` ascending after
* the anchor. When `maxDepth` is provided, only that many levels of
* descendants are returned (anchor counts as depth 0).
*
* Cycles in `parentSpanId` (which shouldn't happen in well-formed traces but
* could surface from corrupted data) are handled by tracking visited spanIds
* and skipping any span seen during this walk.
*
* Returns an empty array if the anchor isn't in the input.
*
* Generic over the span shape so it works on both full {@link SpanRecord}
* lists (e.g. result of `getTrace`) and lightweight skeletons (result of
* `getStructure`).
*/
function extractBranchSpans(spans, anchorSpanId, maxDepth) {
const anchor = spans.find((s) => s.spanId === anchorSpanId);
if (!anchor) return [];
const childrenByParent = /* @__PURE__ */ new Map();
for (const span of spans) {
if (span.parentSpanId == null) continue;
const bucket = childrenByParent.get(span.parentSpanId);
if (bucket) bucket.push(span);
else childrenByParent.set(span.parentSpanId, [span]);
}
const visited = /* @__PURE__ */ new Set([anchor.spanId]);
const descendants = [];
let frontier = [anchor];
let depth = 0;
while (frontier.length > 0) {
if (maxDepth != null && depth >= maxDepth) break;
const next = [];
for (const span of frontier) {
const children = childrenByParent.get(span.spanId);
if (!children) continue;
for (const child of children) {
if (visited.has(child.spanId)) continue;
visited.add(child.spanId);
descendants.push(child);
next.push(child);
}
}
frontier = next;
depth++;
}
descendants.sort((a, b) => a.startedAt.getTime() - b.startedAt.getTime());
return [anchor, ...descendants];
}
/**
* Lightweight span record containing only the fields needed for timeline rendering.
* Excludes heavy fields: input, output, attributes, metadata, tags, links.
* This reduces per-span payload from ~17KB to ~370 bytes (~97% reduction).
*/
const lightSpanRecordSchema = zod_v4.z.object({
...spanIds,
name: spanNameField,
spanType: spanTypeField,
isEvent: isEventField,
startedAt: startedAtField,
parentSpanId: parentSpanIdField.nullish(),
endedAt: endedAtField.nullish(),
error: errorField.nullish(),
entityType: require_utils.spanContextFields.entityType,
entityId: require_utils.spanContextFields.entityId,
entityName: require_utils.spanContextFields.entityName,
...require_utils.dbTimestamps
}).describe("Lightweight span record for timeline rendering (excludes input, output, attributes, metadata, tags, links)");
/**
* Response schema for getStructure operation.
* Returns a trace with lightweight spans (only fields needed for timeline).
*/
const getStructureResponseSchema = zod_v4.z.object({
traceId: require_utils.traceIdField,
spans: zod_v4.z.array(lightSpanRecordSchema)
});
/** @deprecated Use {@link getStructureResponseSchema} instead. */
const getTraceLightResponseSchema = getStructureResponseSchema;
/** Schema for filtering traces in list queries */
const tracesFilterSchema = zod_v4.z.object({
startedAt: require_utils.dateRangeSchema.optional().describe("Filter by span start time range"),
endedAt: require_utils.dateRangeSchema.optional().describe("Filter by span end time range"),
spanType: spanTypeField.optional(),
traceId: require_utils.traceIdField.optional().describe("Filter by trace ID (matches root span)"),
...sharedFields,
status: traceStatusField.optional(),
hasChildError: hasChildErrorField.optional()
}).describe("Filters for querying traces");
/**
* Fields available for ordering trace results
*/
const tracesOrderByFieldSchema = zod_v4.z.enum(["startedAt", "endedAt"]).describe("Field to order by: 'startedAt' | 'endedAt'");
/**
* Order by configuration for trace queries
* Follows the existing StorageOrderBy pattern
* Defaults to startedAt desc (newest first)
*/
const tracesOrderBySchema = zod_v4.z.object({
field: tracesOrderByFieldSchema.default("startedAt").describe("Field to order by"),
direction: require_utils.sortDirectionSchema.default("DESC").describe("Sort direction")
}).describe("Order by configuration");
/**
* Arguments for listing traces
*/
const listTracesArgsSchema = zod_v4.z.object({
mode: require_utils.listModeSchema.optional(),
filters: tracesFilterSchema.optional().describe("Optional filters to apply"),
pagination: require_utils.paginationArgsSchema.optional(),
orderBy: tracesOrderBySchema.optional(),
after: require_utils.deltaCursorSchema.optional(),
limit: require_utils.deltaLimitSchema
}).strict().superRefine(require_utils.refineObservabilityListMode).transform((value) => require_utils.normalizeObservabilityListArgs(value, { orderBy: {
field: "startedAt",
direction: "DESC"
} })).describe("Arguments for listing traces.");
/** Schema for listTraces operation response */
const listTracesResponseSchema = zod_v4.z.object({
pagination: require_utils.paginationInfoSchema.optional(),
delta: require_utils.deltaInfoSchema.optional(),
deltaCursor: require_utils.deltaCursorSchema.optional(),
spans: zod_v4.z.array(traceSpanSchema)
});
/** Schema for listTracesLight operation response */
const listTracesLightResponseSchema = zod_v4.z.object({
pagination: require_utils.paginationInfoSchema,
spans: zod_v4.z.array(lightSpanRecordSchema)
});
/**
* Span types that anchor a listable trace branch -- the spans a user thinks
* about when looking for a specific run (agent/workflow/tool/etc.),
* regardless of whether the entity ran as the root of its trace or nested
* under a parent. Each row in {@link listBranchesArgsSchema} corresponds to
* one such anchor span; the subtree below it is fetched via
* {@link getBranchArgsSchema}.
*
* Excludes sub-operation spans (model_step, workflow_step, scorer_step,
* memory_operation, rag_*, etc.) which are internal to a containing branch
* rather than separately listable.
*/
const BRANCH_SPAN_TYPES = [
"agent_run",
"workflow_run",
"processor_run",
"scorer_run",
"rag_ingestion",
"tool_call",
"mcp_tool_call",
"provider_tool_call"
];
/** Set form of {@link BRANCH_SPAN_TYPES} for fast membership checks. */
const BRANCH_SPAN_TYPE_SET = new Set(BRANCH_SPAN_TYPES);
/** Schema for filtering branch anchor spans in list queries. */
const branchesFilterSchema = zod_v4.z.object({
startedAt: require_utils.dateRangeSchema.optional().describe("Filter by span start time range"),
endedAt: require_utils.dateRangeSchema.optional().describe("Filter by span end time range"),
spanType: spanTypeField.optional(),
traceId: require_utils.traceIdField.optional().describe("Filter by parent trace ID"),
...sharedFields,
status: traceStatusField.optional()
}).describe("Filters for querying trace branches");
const branchesOrderByFieldSchema = zod_v4.z.enum(["startedAt", "endedAt"]).describe("Field to order by: 'startedAt' | 'endedAt'");
const branchesOrderBySchema = zod_v4.z.object({
field: branchesOrderByFieldSchema.default("startedAt").describe("Field to order by"),
direction: require_utils.sortDirectionSchema.default("DESC").describe("Sort direction")
}).describe("Order by configuration");
/**
* Arguments for listing trace branches.
*
* Each row is a single branch anchor span ({@link BRANCH_SPAN_TYPES}),
* including ones nested under a different root entity. Use this when you
* want every run of a given agent/processor/tool regardless of how it was
* triggered. Use {@link listTracesArgsSchema} when you want one row per
* trace, and {@link getBranchArgsSchema} to expand a single branch into its
* subtree.
*/
const listBranchesArgsSchema = zod_v4.z.object({
mode: require_utils.listModeSchema.optional(),
filters: branchesFilterSchema.optional().describe("Optional filters to apply"),
pagination: require_utils.paginationArgsSchema.optional(),
orderBy: branchesOrderBySchema.optional(),
after: require_utils.deltaCursorSchema.optional(),
limit: require_utils.deltaLimitSchema
}).strict().superRefine(require_utils.refineObservabilityListMode).transform((value) => require_utils.normalizeObservabilityListArgs(value, { orderBy: {
field: "startedAt",
direction: "DESC"
} })).describe("Arguments for listing trace branches.");
/**
* Schema for listBranches operation response. Each row is a single branch
* anchor span -- repeated runs of the same entity within one parent trace
* surface as separate rows.
*/
const listBranchesResponseSchema = zod_v4.z.object({
pagination: require_utils.paginationInfoSchema.optional(),
delta: require_utils.deltaInfoSchema.optional(),
deltaCursor: require_utils.deltaCursorSchema.optional(),
branches: zod_v4.z.array(traceSpanSchema)
});
/**
* Schema for updating a span (without db timestamps and span IDs)
*/
const updateSpanRecordSchema = createSpanRecordSchema.omit(omitSpanIds);
/**
* Schema for updateSpan operation arguments
*/
const updateSpanArgsSchema = zod_v4.z.object({
spanId: require_utils.spanIdField,
traceId: require_utils.traceIdField,
updates: updateSpanRecordSchema.partial()
}).describe("Arguments for updating a single span");
/**
* Schema for batchUpdateSpans operation arguments
*/
const batchUpdateSpansArgsSchema = zod_v4.z.object({ records: zod_v4.z.array(zod_v4.z.object({
traceId: require_utils.traceIdField,
spanId: require_utils.spanIdField,
updates: updateSpanRecordSchema.partial()
})) }).describe("Arguments for batch updating spans");
/**
* Schema for batchDeleteTraces operation arguments
*/
const batchDeleteTracesArgsSchema = zod_v4.z.object({ traceIds: zod_v4.z.array(require_utils.traceIdField) }).describe("Arguments for batch deleting traces");
/** Schema for listScoresBySpan operation response */
const listScoresBySpanResponseSchema = zod_v4.z.object({
pagination: require_utils.paginationInfoSchema,
scores: zod_v4.z.array(scoreRowDataSchema)
});
/** Schema for scoreTraces operation request */
const scoreTracesRequestSchema = zod_v4.z.object({
scorerName: zod_v4.z.string().min(1),
targets: zod_v4.z.array(zod_v4.z.object({
traceId: require_utils.traceIdField,
spanId: require_utils.spanIdField.optional()
})).min(1)
});
/** Schema for scoreTraces operation response */
const scoreTracesResponseSchema = zod_v4.z.object({
status: zod_v4.z.string(),
message: zod_v4.z.string(),
traceCount: zod_v4.z.number()
});
//#endregion
//#region src/storage/constants.ts
const TABLE_WORKFLOW_SNAPSHOT = "mastra_workflow_snapshot";
const TABLE_MESSAGES = "mastra_messages";
const TABLE_THREADS = "mastra_threads";
const TABLE_TRACES = "mastra_traces";
const TABLE_RESOURCES = "mastra_resources";
const TABLE_SCORERS = "mastra_scorers";
const TABLE_SPANS = "mastra_ai_spans";
const TABLE_AGENTS = "mastra_agents";
const TABLE_AGENT_VERSIONS = "mastra_agent_versions";
const TABLE_OBSERVATIONAL_MEMORY = "mastra_observational_memory";
const TABLE_PROMPT_BLOCKS = "mastra_prompt_blocks";
const TABLE_PROMPT_BLOCK_VERSIONS = "mastra_prompt_block_versions";
const TABLE_SCORER_DEFINITIONS = "mastra_scorer_definitions";
const TABLE_SCORER_DEFINITION_VERSIONS = "mastra_scorer_definition_versions";
const TABLE_MCP_CLIENTS = "mastra_mcp_clients";
const TABLE_MCP_CLIENT_VERSIONS = "mastra_mcp_client_versions";
const TABLE_MCP_SERVERS = "mastra_mcp_servers";
const TABLE_MCP_SERVER_VERSIONS = "mastra_mcp_server_versions";
const TABLE_WORKSPACES = "mastra_workspaces";
const TABLE_WORKSPACE_VERSIONS = "mastra_workspace_versions";
const TABLE_SKILLS = "mastra_skills";
const TABLE_SKILL_VERSIONS = "mastra_skill_versions";
const TABLE_SKILL_BLOBS = "mastra_skill_blobs";
const TABLE_FAVORITES = "mastra_favorites";
const TABLE_DATASETS = "mastra_datasets";
const TABLE_DATASET_ITEMS = "mastra_dataset_items";
const TABLE_DATASET_VERSIONS = "mastra_dataset_versions";
const TABLE_EXPERIMENTS = "mastra_experiments";
const TABLE_EXPERIMENT_RESULTS = "mastra_experiment_results";
const TABLE_BACKGROUND_TASKS = "mastra_background_tasks";
const TABLE_SCHEDULES = "mastra_schedules";
const TABLE_SCHEDULE_TRIGGERS = "mastra_schedule_triggers";
const TABLE_WORKFLOW_DEFINITIONS = "mastra_workflow_definitions";
const TABLE_CHANNEL_INSTALLATIONS = "mastra_channel_installations";
const TABLE_CHANNEL_CONFIG = "mastra_channel_config";
const TABLE_TOOL_PROVIDER_CONNECTIONS = "mastra_tool_provider_connections";
const TABLE_NOTIFICATIONS = "mastra_notifications";
const TABLE_HARNESS_SESSIONS = "mastra_harness_sessions";
const TABLE_THREAD_STATE = "mastra_thread_state";
const SCORERS_SCHEMA = {
id: {
type: "text",
nullable: false,
primaryKey: true
},
scorerId: { type: "text" },
traceId: {
type: "text",
nullable: true
},
spanId: {
type: "text",
nullable: true
},
runId: { type: "text" },
scorer: { type: "jsonb" },
preprocessStepResult: {
type: "jsonb",
nullable: true
},
extractStepResult: {
type: "jsonb",
nullable: true
},
analyzeStepResult: {
type: "jsonb",
nullable: true
},
score: { type: "float" },
reason: {
type: "text",
nullable: true
},
metadata: {
type: "jsonb",
nullable: true
},
preprocessPrompt: {
type: "text",
nullable: true
},
extractPrompt: {
type: "text",
nullable: true
},
generateScorePrompt: {
type: "text",
nullable: true
},
generateReasonPrompt: {
type: "text",
nullable: true
},
analyzePrompt: {
type: "text",
nullable: true
},
reasonPrompt: {
type: "text",
nullable: true
},
input: { type: "jsonb" },
output: { type: "jsonb" },
additionalContext: {
type: "jsonb",
nullable: true
},
requestContext: {
type: "jsonb",
nullable: true
},
/**
* Things you can evaluate
*/
entityType: {
type: "text",
nullable: true
},
entity: {
type: "jsonb",
nullable: true
},
entityId: {
type: "text",
nullable: true
},
source: { type: "text" },
resourceId: {
type: "text",
nullable: true
},
threadId: {
type: "text",
nullable: true
},
organizationId: {
type: "text",
nullable: true
},
projectId: {
type: "text",
nullable: true
},
batchId: {
type: "text",
nullable: true
},
datasetId: {
type: "text",
nullable: true
},
datasetItemId: {
type: "text",
nullable: true
},
createdAt: { type: "timestamp" },
updatedAt: { type: "timestamp" }
};
const SPAN_SCHEMA = buildStorageSchema(spanRecordSchema);
/**
* @deprecated Use SPAN_SCHEMA instead. This legacy schema is retained only for migration purposes.
* @internal
*/
const OLD_SPAN_SCHEMA = {
traceId: {
type: "text",
nullable: false
},
spanId: {
type: "text",
nullable: false
},
parentSpanId: {
type: "text",
nullable: true
},
name: {
type: "text",
nullable: false
},
scope: {
type: "jsonb",
nullable: true
},
spanType: {
type: "text",
nullable: false
},
attributes: {
type: "jsonb",
nullable: true
},
metadata: {
type: "jsonb",
nullable: true
},
links: {
type: "jsonb",
nullable: true
},
input: {
type: "jsonb",
nullable: true
},
output: {
type: "jsonb",
nullable: true
},
error: {
type: "jsonb",
nullable: true
},
startedAt: {
type: "timestamp",
nullable: false
},
endedAt: {
type: "timestamp",
nullable: true
},
createdAt: {
type: "timestamp",
nullable: false
},
updatedAt: {
type: "timestamp",
nullable: true
},
isEvent: {
type: "boolean",
nullable: false
}
};
const AGENTS_SCHEMA = {
id: {
type: "text",
nullable: false,
primaryKey: true
},
status: {
type: "text",
nullable: false
},
activeVersionId: {
type: "text",
nullable: true
},
authorId: {
type: "text",
nullable: true
},
visibility: {
type: "text",
nullable: true
},
metadata: {
type: "jsonb",
nullable: true
},
favoriteCount: {
type: "integer",
nullable: true
},
createdAt: {
type: "timestamp",
nullable: false
},
updatedAt: {
type: "timestamp",
nullable: false
}
};
const AGENT_VERSIONS_SCHEMA = {
id: {
type: "text",
nullable: false,
primaryKey: true
},
agentId: {
type: "text",
nullable: false
},
versionNumber: {
type: "integer",
nullable: false
},
name: {
type: "text",
nullable: false
},
description: {
type: "text",
nullable: true
},
instructions: {
type: "text",
nullable: false
},
model: {
type: "jsonb",
nullable: false
},
tools: {
type: "jsonb",
nullable: true
},
defaultOptions: {
type: "jsonb",
nullable: true
},
workflows: {
type: "jsonb",
nullable: true
},
agents: {
type: "jsonb",
nullable: true
},
integrationTools: {
type: "jsonb",
nullable: true
},
toolProviders: {
type: "jsonb",
nullable: true
},
inputProcessors: {
type: "jsonb",
nullable: true
},
outputProcessors: {
type: "jsonb",
nullable: true
},
memory: {
type: "jsonb",
nullable: true
},
scorers: {
type: "jsonb",
nullable: true
},
mcpClients: {
type: "jsonb",
nullable: true
},
requestContextSchema: {
type: "jsonb",
nullable: true
},
workspace: {
type: "jsonb",
nullable: true
},
skills: {
type: "jsonb",
nullable: true
},
skillsFormat: {
type: "text",
nullable: true
},
browser: {
type: "jsonb",
nullable: true
},
changedFields: {
type: "jsonb",
nullable: true
},
changeMessage: {
type: "text",
nullable: true
},
createdAt: {
type: "timestamp",
nullable: false
}
};
const PROMPT_BLOCKS_SCHEMA = {
id: {
type: "text",
nullable: false,
primaryKey: true
},
status: {
type: "text",
nullable: false
},
activeVersionId: {
type: "text",
nullable: true
},
authorId: {
type: "text",
nullable: true
},
metadata: {
type: "jsonb",
nullable: true
},
createdAt: {
type: "timestamp",
nullable: false
},
updatedAt: {
type: "timestamp",
nullable: false
}
};
const PROMPT_BLOCK_VERSIONS_SCHEMA = {
id: {
type: "text",
nullable: false,
primaryKey: true
},
blockId: {
type: "text",
nullable: false
},
versionNumber: {
type: "integer",
nullable: false
},
name: {
type: "text",
nullable: false
},
description: {
type: "text",
nullable: true
},
content: {
type: "text",
nullable: false
},
rules: {
type: "jsonb",
nullable: true
},
requestContextSchema: {
type: "jsonb",
nullable: true
},
changedFields: {
type: "jsonb",
nullable: true
},
changeMessage: {
type: "text",
nullable: true
},
createdAt: {
type: "timestamp",
nullable: false
}
};
const SCORER_DEFINITIONS_SCHEMA = {
id: {
type: "text",
nullable: false,
primaryKey: true
},
status: {
type: "text",
nullable: false
},
activeVersionId: {
type: "text",
nullable: true
},
authorId: {
type: "text",
nullable: true
},
organizationId: {
type: "text",
nullable: true
},
projectId: {
type: "text",
nullable: true
},
metadata: {
type: "jsonb",
nullable: true
},
createdAt: {
type: "timestamp",
nullable: false
},
updatedAt: {
type: "timestamp",
nullable: false
}
};
const SCORER_DEFINITION_VERSIONS_SCHEMA = {
id: {
type: "text",
nullable: false,
primaryKey: true
},
scorerDefinitionId: {
type: "text",
nullable: false
},
versionNumber: {
type: "integer",
nullable: false
},
name: {
type: "text",
nullable: false
},
description: {
type: "text",
nullable: true
},
type: {
type: "text",
nullable: false
},
model: {
type: "jsonb",
nullable: true
},
instructions: {
type: "text",
nullable: true
},
scoreRange: {
type: "jsonb",
nullable: true
},
presetConfig: {
type: "jsonb",
nullable: true
},
defaultSampling: {
type: "jsonb",
nullable: true
},
changedFields: {
type: "jsonb",
nullable: true
},
changeMessage: {
type: "text",
nullable: true
},
createdAt: {
type: "timestamp",
nullable: false
}
};
const MCP_CLIENTS_SCHEMA = {
id: {
type: "text",
nullable: false,
primaryKey: true
},
status: {
type: "text",
nullable: false
},
activeVersionId: {
type: "text",
nullable: true
},
authorId: {
type: "text",
nullable: true
},
metadata: {
type: "jsonb",
nullable: true
},
createdAt: {
type: "timestamp",
nullable: false
},
updatedAt: {
type: "timestamp",
nullable: false
}
};
const MCP_CLIENT_VERSIONS_SCHEMA = {
id: {
type: "text",
nullable: false,
primaryKey: true
},
mcpClientId: {
type: "text",
nullable: false
},
versionNumber: {
type: "integer",
nullable: false
},
name: {
type: "text",
nullable: false
},
description: {
type: "text",
nullable: true
},
servers: {
type: "jsonb",
nullable: false
},
changedFields: {
type: "jsonb",
nullable: true
},
changeMessage: {
type: "text",
nullable: true
},
createdAt: {
type: "timestamp",
nullable: false
}
};
const MCP_SERVERS_SCHEMA = {
id: {
type: "text",
nullable: false,
primaryKey: true
},
status: {
type: "text",
nullable: false
},
activeVersionId: {
type: "text",
nullable: true
},
authorId: {
type: "text",
nullable: true
},
metadata: {
type: "jsonb",
nullable: true
},
createdAt: {
type: "timestamp",
nullable: false
},
updatedAt: {
type: "timestamp",
nullable: false
}
};
const MCP_SERVER_VERSIONS_SCHEMA = {
id: {
type: "text",
nullable: false,
primaryKey: true
},
mcpServerId: {
type: "text",
nullable: false
},
versionNumber: {
type: "integer",
nullable: false
},
name: {
type: "text",
nullable: false
},
version: {
type: "text",
nullable: false
},
description: {
type: "text",
nullable: true
},
instructions: {
type: "text",
nullable: true
},
repository: {
type: "jsonb",
nullable: true
},
releaseDate: {
type: "text",
nullable: true
},
isLatest: {
type: "boolean",
nullable: true
},
packageCanonical: {
type: "text",
nullable: true
},
tools: {
type: "jsonb",
nullable: true
},
agents: {
type: "jsonb",
nullable: true
},
workflows: {
type: "jsonb",
nullable: true
},
changedFields: {
type: "jsonb",
nullable: true
},
changeMessage: {
type: "text",
nullable: true
},
createdAt: {
type: "timestamp",
nullable: false
}
};
const WORKFLOW_DEFINITIONS_SCHEMA = {
id: {
type: "text",
nullable: false,
primaryKey: true
},
description: {
type: "text",
nullable: true
},
metadata: {
type: "jsonb",
nullable: true
},
inputSchema: {
type: "jsonb",
nullable: false
},
outputSchema: {
type: "jsonb",
nullable: false
},
stateSchema: {
type: "jsonb",
nullable: true
},
requestContextSchema: {
type: "jsonb",
nullable: true
},
graph: {
type: "jsonb",
nullable: false
},
status: {
type: "text",
nullable: false
},
source: {
type: "text",
nullable: false
},
authorId: {
type: "text",
nullable: true
},
createdAt: {
type: "timestamp",
nullable: false
},
updatedAt: {
type: "timestamp",
nullable: false
}
};
const WORKSPACES_SCHEMA = {
id: {
type: "text",
nullable: false,
primaryKey: true
},
status: {
type: "text",
nullable: false
},
activeVersionId: {
type: "text",
nullable: true
},
authorId: {
type: "text",
nullable: true
},
metadata: {
type: "jsonb",
nullable: true
},
createdAt: {
type: "timestamp",
nullable: false
},
updatedAt: {
type: "timestamp",
nullable: false
}
};
const WORKSPACE_VERSIONS_SCHEMA = {
id: {
type: "text",
nullable: false,
primaryKey: true
},
workspaceId: {
type: "text",
nullable: false
},
versionNumber: {
type: "integer",
nullable: false
},
name: {
type: "text",
nullable: false
},
description: {
type: "text",
nullable: true
},
filesystem: {
type: "jsonb",
nullable: true
},
sandbox: {
type: "jsonb",
nullable: true
},
mounts: {
type: "jsonb",
nullable: true
},
search: {
type: "jsonb",
nullable: true
},
skills: {
type: "jsonb",
nullable: true
},
tools: {
type: "jsonb",
nullable: true
},
autoSync: {
type: "boolean",
nullable: true
},
operationTimeout: {
type: "integer",
nullable: true
},
changedFields: {
type: "jsonb",
nullable: true
},
changeMessage: {
type: "text",
nullable: true
},
createdAt: {
type: "timestamp",
nullable: false
}
};
const SKILLS_SCHEMA = {
id: {
type: "text",
nullable: false,
primaryKey: true
},
status: {
type: "text",
nullable: false
},
activeVersionId: {
type: "text",
nullable: true
},
authorId: {
type: "text",
nullable: true
},
visibility: {
type: "text",
nullable: true
},
favoriteCount: {
type: "integer",
nullable: true
},
createdAt: {
type: "timestamp",
nullable: false
},
updatedAt: {
type: "timestamp",
nullable: false
}
};
const FAVORITES_SCHEMA = {
userId: {
type: "text",
nullable: false
},
entityType: {
type: "text",
nullable: false
},
entityId: {
type: "text",
nullable: false
},
createdAt: {
type: "timestamp",
nullable: false
}
};
/**
* Per-author registry of authorized tool provider connections. Stores a stable
* user-supplied label across agents. Composite primary key on
* (authorId, providerId, connectionId). `scope` buckets identity:
* 'per-author' (default), 'shared' (visible to all callers), or
* 'caller-supplied' (authorId is a host-app end-user id forwarded via request
* context).
*/
const TOOL_PROVIDER_CONNECTIONS_SCHEMA = {
authorId: {
type: "text",
nullable: false
},
providerId: {
type: "text",
nullable: false
},
connectionId: {
type: "text",
nullable: false
},
toolkit: {
type: "text",
nullable: false
},
label: {
type: "text",
nullable: true
},
scope: {
type: "text",
nullable: false
},
createdAt: {
type: "timestamp",
nullable: false
},
updatedAt: {
type: "timestamp",
nullabl