@mastra/pg 1.26.0-alpha.3 → 1.26.0-alpha.4
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/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/reference-memory-memory-class.md +1 -1
- package/dist/index.cjs +76 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +76 -3
- package/dist/index.js.map +1 -1
- package/dist/storage/db/constraint-utils.d.ts +11 -1
- package/dist/storage/db/constraint-utils.d.ts.map +1 -1
- package/dist/storage/domains/workflows/index.d.ts +32 -1
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/docs/SKILL.md
CHANGED
|
@@ -51,7 +51,7 @@ export const agent = new Agent({
|
|
|
51
51
|
|
|
52
52
|
**options.observationalMemory** (`boolean | ObservationalMemoryOptions`): Enable Observational Memory for long-context agentic memory. Set to true for defaults, or pass a config object to customize token budgets, models, and scope. See Observational Memory reference for configuration details.
|
|
53
53
|
|
|
54
|
-
**options.generateTitle** (`boolean | { model
|
|
54
|
+
**options.generateTitle** (`boolean | { model?: DynamicArgument<MastraModelConfig>; instructions?: DynamicArgument<string>; minMessages?: number; emitEvent?: boolean }`): Controls automatic thread title generation from the conversation transcript. Accepts a boolean or an object with a custom model (any MastraModelConfig: a model instance, a "provider/model" ID, or an OpenAI-compatible config; defaults to the agent's own model), custom instructions, a minimum message count, and emitEvent. With emitEvent: true the run's stream waits for the title and emits it as a transient data-thread-title chunk before finish (durable and evented agents persist the title but don't emit the chunk yet).
|
|
55
55
|
|
|
56
56
|
## Returns
|
|
57
57
|
|
package/dist/index.cjs
CHANGED
|
@@ -2360,6 +2360,8 @@ var RoutingDbClient = class {
|
|
|
2360
2360
|
return this.active.tx(callback);
|
|
2361
2361
|
}
|
|
2362
2362
|
};
|
|
2363
|
+
/** Bytes reserved for the `_xxxxxxxx` collision suffix when hashWhenTruncated applies. */
|
|
2364
|
+
const TRUNCATION_HASH_SUFFIX_LENGTH = 9;
|
|
2363
2365
|
function truncateIdentifier(value, maxLength = 63) {
|
|
2364
2366
|
if (maxLength <= 0) return "";
|
|
2365
2367
|
if (Buffer.byteLength(value, "utf-8") <= maxLength) return value;
|
|
@@ -2380,9 +2382,25 @@ function truncateIdentifier(value, maxLength = 63) {
|
|
|
2380
2382
|
* in system catalogs (pg_constraint.conname, pg_indexes.indexname, etc.).
|
|
2381
2383
|
* Without this normalisation, runtime lookups that compare a mixed-case name
|
|
2382
2384
|
* against the catalog would silently fail.
|
|
2385
|
+
*
|
|
2386
|
+
* With `hashWhenTruncated`, a name that exceeds the limit is truncated further
|
|
2387
|
+
* to make room for `_` + 8 hex chars of the full name's sha256. Plain
|
|
2388
|
+
* truncation cuts the tail, so two names sharing a long `<schema>_<prefix>`
|
|
2389
|
+
* collapse to the same identifier and `CREATE INDEX IF NOT EXISTS` (which
|
|
2390
|
+
* matches by name only) silently skips the second one. The suffix is
|
|
2391
|
+
* deterministic, so creation, warm-init snapshot checks, and DDL export all
|
|
2392
|
+
* agree on the same name. Opt-in because renaming already-released constraint
|
|
2393
|
+
* names would orphan the existing objects in deployed catalogs.
|
|
2383
2394
|
*/
|
|
2384
|
-
function buildConstraintName({ baseName, schemaName, maxLength = 63 }) {
|
|
2385
|
-
|
|
2395
|
+
function buildConstraintName({ baseName, schemaName, maxLength = 63, hashWhenTruncated = false }) {
|
|
2396
|
+
const fullName = `${schemaName ? `${schemaName}_` : ""}${baseName}`.toLowerCase();
|
|
2397
|
+
if (hashWhenTruncated && Buffer.byteLength(fullName, "utf-8") > maxLength) {
|
|
2398
|
+
const suffixLength = Math.min(TRUNCATION_HASH_SUFFIX_LENGTH, maxLength);
|
|
2399
|
+
if (suffixLength < 2) return truncateIdentifier(fullName, maxLength);
|
|
2400
|
+
const hash = (0, crypto$1.createHash)("sha256").update(fullName).digest("hex").slice(0, suffixLength - 1);
|
|
2401
|
+
return `${truncateIdentifier(fullName, maxLength - suffixLength)}_${hash}`;
|
|
2402
|
+
}
|
|
2403
|
+
return truncateIdentifier(fullName, maxLength);
|
|
2386
2404
|
}
|
|
2387
2405
|
//#endregion
|
|
2388
2406
|
//#region src/storage/db/pg-errors.ts
|
|
@@ -22317,6 +22335,7 @@ const WORKFLOW_SNAPSHOT_STATUS_INDEX = "mastra_workflow_snapshot_name_status_cre
|
|
|
22317
22335
|
* Schema-prefixed name of the status index, lowercased and truncated the same way Postgres
|
|
22318
22336
|
* stores it, so the init snapshot's index set answers "does it exist?" without a probe or a
|
|
22319
22337
|
* no-op `CREATE INDEX` (schema-prefixed names routinely exceed the 63-byte limit).
|
|
22338
|
+
* Exported for tests.
|
|
22320
22339
|
*/
|
|
22321
22340
|
function workflowSnapshotStatusIndexName(schemaName) {
|
|
22322
22341
|
return buildConstraintName({
|
|
@@ -22334,6 +22353,48 @@ function workflowSnapshotStatusIndexSQL(indexName, schemaName) {
|
|
|
22334
22353
|
schemaName: getSchemaName(schemaName)
|
|
22335
22354
|
})} (workflow_name, (snapshot ->> 'status'), "createdAt" DESC)`;
|
|
22336
22355
|
}
|
|
22356
|
+
/** Base name (before any schema prefix) of the expression index backing the threadId filter. */
|
|
22357
|
+
const WORKFLOW_SNAPSHOT_THREAD_ID_INDEX = "mastra_workflow_snapshot_threadid_idx";
|
|
22358
|
+
/**
|
|
22359
|
+
* Schema-prefixed name of the threadId index (see workflowSnapshotStatusIndexName).
|
|
22360
|
+
*
|
|
22361
|
+
* Unlike the status index, truncation appends a collision hash: both index names share the
|
|
22362
|
+
* long `<schema>_mastra_workflow_snapshot_` prefix, so with a schema name of 37+ bytes plain
|
|
22363
|
+
* truncation collapses them to the same 63-byte identifier and `CREATE INDEX IF NOT EXISTS`
|
|
22364
|
+
* silently skips this index. The status index keeps plain truncation because its truncated
|
|
22365
|
+
* name already exists in deployed catalogs; this index is new and free to adopt the rule.
|
|
22366
|
+
* Exported for tests.
|
|
22367
|
+
*/
|
|
22368
|
+
function workflowSnapshotThreadIdIndexName(schemaName) {
|
|
22369
|
+
return buildConstraintName({
|
|
22370
|
+
baseName: WORKFLOW_SNAPSHOT_THREAD_ID_INDEX,
|
|
22371
|
+
schemaName: schemaName && schemaName !== "public" ? schemaName : void 0,
|
|
22372
|
+
hashWhenTruncated: true
|
|
22373
|
+
});
|
|
22374
|
+
}
|
|
22375
|
+
/**
|
|
22376
|
+
* Expression extracting the thread id embedded in a snapshot (jsonb columns only). Mirrors
|
|
22377
|
+
* the canonical extraction in `@mastra/core` (`getSnapshotMemoryInfo`), which reads one of
|
|
22378
|
+
* two layouts:
|
|
22379
|
+
* 1. agentic-loop: `context.<suspended step>.suspendPayload.__streamState.messageList.memoryInfo.threadId`
|
|
22380
|
+
* 2. durable loop: `context.input.messageListState.memoryInfo.threadId`
|
|
22381
|
+
*
|
|
22382
|
+
* `jsonb_path_query_first(jsonb, jsonpath)` is IMMUTABLE, so the expression is valid in an
|
|
22383
|
+
* expression index. The WHERE clause in listWorkflowRuns() must use this exact expression
|
|
22384
|
+
* text so the planner can match it against the index. If the snapshot layout changes in
|
|
22385
|
+
* core, this expression must be updated in lockstep or it will wrongly exclude rows.
|
|
22386
|
+
*/
|
|
22387
|
+
const WORKFLOW_SNAPSHOT_THREAD_ID_EXPR = `COALESCE(jsonb_path_query_first(snapshot, '$.context.* ? (@.status == "suspended").suspendPayload.__streamState.messageList.memoryInfo.threadId') #>> '{}', snapshot #>> '{context,input,messageListState,memoryInfo,threadId}')`;
|
|
22388
|
+
/**
|
|
22389
|
+
* Expression index on the snapshot-embedded thread id so listWorkflowRuns() threadId filters
|
|
22390
|
+
* (Agent.listSuspendedRuns) can use an index instead of detoasting every snapshot.
|
|
22391
|
+
*/
|
|
22392
|
+
function workflowSnapshotThreadIdIndexSQL(indexName, schemaName) {
|
|
22393
|
+
return `CREATE INDEX IF NOT EXISTS "${indexName}" ON ${getTableName({
|
|
22394
|
+
indexName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
22395
|
+
schemaName: getSchemaName(schemaName)
|
|
22396
|
+
})} ((${WORKFLOW_SNAPSHOT_THREAD_ID_EXPR}))`;
|
|
22397
|
+
}
|
|
22337
22398
|
var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorage {
|
|
22338
22399
|
#db;
|
|
22339
22400
|
#schema;
|
|
@@ -22406,6 +22467,7 @@ var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorag
|
|
|
22406
22467
|
}));
|
|
22407
22468
|
for (const idx of WorkflowsPG.getDefaultIndexDefs(schemaPrefix)) statements.push(generateIndexSQL(idx, schemaName));
|
|
22408
22469
|
statements.push(`${workflowSnapshotStatusIndexSQL(workflowSnapshotStatusIndexName(parsedSchema), schemaName)};`);
|
|
22470
|
+
statements.push(`${workflowSnapshotThreadIdIndexSQL(workflowSnapshotThreadIdIndexName(parsedSchema), schemaName)};`);
|
|
22409
22471
|
return statements;
|
|
22410
22472
|
}
|
|
22411
22473
|
/**
|
|
@@ -22432,6 +22494,12 @@ var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorag
|
|
|
22432
22494
|
} catch (error) {
|
|
22433
22495
|
this.logger?.warn?.(`Failed to create index ${indexName}:`, error);
|
|
22434
22496
|
}
|
|
22497
|
+
const threadIdIndexName = workflowSnapshotThreadIdIndexName(this.#schema);
|
|
22498
|
+
try {
|
|
22499
|
+
await this.#db.createIndexFromStatement(threadIdIndexName, workflowSnapshotThreadIdIndexSQL(threadIdIndexName, this.#schema));
|
|
22500
|
+
} catch (error) {
|
|
22501
|
+
this.logger?.warn?.(`Failed to create index ${threadIdIndexName}:`, error);
|
|
22502
|
+
}
|
|
22435
22503
|
}
|
|
22436
22504
|
async init() {
|
|
22437
22505
|
await this.#db.createTable({
|
|
@@ -22712,7 +22780,7 @@ var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorag
|
|
|
22712
22780
|
}, error);
|
|
22713
22781
|
}
|
|
22714
22782
|
}
|
|
22715
|
-
async listWorkflowRuns({ workflowName, fromDate, toDate, perPage, page, resourceId, status } = {}) {
|
|
22783
|
+
async listWorkflowRuns({ workflowName, fromDate, toDate, perPage, page, resourceId, threadId, status } = {}) {
|
|
22716
22784
|
try {
|
|
22717
22785
|
const conditions = [];
|
|
22718
22786
|
const values = [];
|
|
@@ -22733,6 +22801,11 @@ var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorag
|
|
|
22733
22801
|
values.push(resourceId);
|
|
22734
22802
|
paramIndex++;
|
|
22735
22803
|
} else this.logger?.warn?.(`[${_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT}] resourceId column not found. Skipping resourceId filter.`);
|
|
22804
|
+
if (threadId) if (await this.#db.getColumnType(_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT, "snapshot") === "jsonb") {
|
|
22805
|
+
conditions.push(`${WORKFLOW_SNAPSHOT_THREAD_ID_EXPR} = $${paramIndex}`);
|
|
22806
|
+
values.push(threadId);
|
|
22807
|
+
paramIndex++;
|
|
22808
|
+
} else this.logger?.warn?.(`[${_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT}] snapshot column is not jsonb. Skipping threadId filter.`);
|
|
22736
22809
|
if (fromDate) {
|
|
22737
22810
|
conditions.push(`"createdAt" >= $${paramIndex}`);
|
|
22738
22811
|
values.push(fromDate);
|