@mastra/libsql 1.23.1-alpha.1 → 1.23.1-alpha.3

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.
@@ -3,7 +3,7 @@ name: mastra-libsql
3
3
  description: Documentation for @mastra/libsql. Use when working with @mastra/libsql APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/libsql"
6
- version: "1.23.1-alpha.1"
6
+ version: "1.23.1-alpha.3"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.23.1-alpha.1",
2
+ "version": "1.23.1-alpha.3",
3
3
  "package": "@mastra/libsql",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -170,6 +170,43 @@ export const supportAgent = new Agent({
170
170
 
171
171
  Title generation runs asynchronously after the agent responds and doesn't affect response time.
172
172
 
173
+ ### Streaming the generated title
174
+
175
+ By default title generation runs in the background and the run's stream doesn't wait for it, so HTTP clients only see the title on their next thread fetch. Set `emitEvent: true` to deliver the title on the run's stream instead: the stream waits for the title and emits a transient `data-thread-title` chunk before `finish`.
176
+
177
+ ```typescript
178
+ import { Agent } from '@mastra/core/agent'
179
+ import { Memory } from '@mastra/memory'
180
+
181
+ export const supportAgent = new Agent({
182
+ id: 'support-agent',
183
+ name: 'Support agent',
184
+ instructions: 'Answer customer support questions.',
185
+ model: 'openai/gpt-5.6-sol',
186
+ memory: new Memory({
187
+ options: {
188
+ generateTitle: {
189
+ emitEvent: true,
190
+ },
191
+ },
192
+ }),
193
+ })
194
+ ```
195
+
196
+ Stream consumers receive the chunk with the persisted title, so a chat UI can rename its thread list entry without polling:
197
+
198
+ ```typescript
199
+ for await (const chunk of stream.fullStream) {
200
+ if (chunk.type === 'data-thread-title') {
201
+ renameThreadInSidebar(chunk.data.threadId, chunk.data.title)
202
+ }
203
+ }
204
+ ```
205
+
206
+ The chunk is transient: it's delivered to stream consumers but never persisted as part of the conversation's messages. Because the stream waits for the title, `emitEvent` delays the stream's `finish` on the turn that generates the title: the first turn of a thread, or a later turn when `minMessages` sets a higher threshold. Leave it off to keep title generation fully non-blocking.
207
+
208
+ > **Note:** `emitEvent` applies to `stream()` runs. `generate()` returns JSON and can't carry the chunk, so it keeps non-blocking title generation. [Durable and evented agents](https://mastra.ai/docs/harness/durable-agents) don't emit this chunk yet. In all of these cases the title is still generated and persisted.
209
+
173
210
  To optimize cost or behavior, provide a smaller [`model`](https://mastra.ai/models) and custom `instructions`:
174
211
 
175
212
  ```typescript
@@ -41,9 +41,13 @@ GitHub Signals requires:
41
41
  - A Mastra storage adapter with memory and notification support. The provider stores each subscription in the thread's metadata, so the thread must already exist.
42
42
  - The `gitcrawl` command on `PATH`, configured to access the repositories you want to monitor. The provider runs `gitcrawl sync` and reads its SQLite database.
43
43
  - The `sqlite3` command on `PATH`.
44
- - The [GitHub CLI](https://cli.github.com/) installed and authenticated. The provider uses `gh api` to check whether comment authors have access to the repository before notifying the agent.
44
+ - The [GitHub CLI](https://cli.github.com/) installed and authenticated. The provider uses real `gh api` responses to check repository permissions and GitHub App ownership before notifying the agent.
45
45
 
46
- By default, comments from users with `admin`, `maintain`, or `write` access can trigger notifications. CodeRabbit and Devin bot comments are also allowed. Configure `authorizedPermissions`, `authorizedBots`, or `ignoredBots` when you need different rules.
46
+ By default, comments from users with `admin`, `maintain`, or `write` access can trigger notifications. CodeRabbit and Devin bot comments are explicitly allowed.
47
+
48
+ Bot authorization checks `ignoredBots` first, using an exact case-insensitive login match. Other bots can trigger notifications when they appear in `authorizedBots`, when the GitHub App is owned by a user whose repository permission appears in `authorizedPermissions`, or when the app is owned by the organization that owns the repository. The default authorized permissions are `admin`, `maintain`, and `write`.
49
+
50
+ Failed, inaccessible, malformed, and unsupported app-owner lookups deny the bot comment. Successful app-owner lookups are cached for 24 hours; failed lookups aren't cached.
47
51
 
48
52
  ## Agent and subscription
49
53
 
@@ -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: DynamicArgument<MastraLanguageModel>; instructions?: DynamicArgument<string> }`): Controls automatic thread title generation from the conversation transcript. Can be a boolean or an object with custom model and instructions.
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
@@ -3892,6 +3892,14 @@ var DatasetsLibSQL = class extends _mastra_core_storage.DatasetsStorage {
3892
3892
  }
3893
3893
  async listDatasets(args) {
3894
3894
  try {
3895
+ const orderBy = (0, _mastra_core_storage.resolveListOrderBy)(args.orderBy, [
3896
+ "createdAt",
3897
+ "updatedAt",
3898
+ "name"
3899
+ ], {
3900
+ field: "createdAt",
3901
+ direction: "DESC"
3902
+ });
3895
3903
  const { page, perPage: perPageInput } = args.pagination;
3896
3904
  const filterConditions = [];
3897
3905
  const filterParams = [];
@@ -3945,7 +3953,7 @@ var DatasetsLibSQL = class extends _mastra_core_storage.DatasetsStorage {
3945
3953
  const end = perPageInput === false ? total : start + perPage;
3946
3954
  return {
3947
3955
  datasets: (await this.#client.execute({
3948
- sql: `SELECT ${buildSelectColumns(_mastra_core_storage.TABLE_DATASETS)} FROM ${_mastra_core_storage.TABLE_DATASETS} ${whereClause} ORDER BY createdAt DESC, id ASC LIMIT ? OFFSET ?`,
3956
+ sql: `SELECT ${buildSelectColumns(_mastra_core_storage.TABLE_DATASETS)} FROM ${_mastra_core_storage.TABLE_DATASETS} ${whereClause} ORDER BY ${orderBy.field} ${orderBy.direction}, id ASC LIMIT ? OFFSET ?`,
3949
3957
  args: [
3950
3958
  ...filterParams,
3951
3959
  limitValue,
@@ -4360,6 +4368,10 @@ var DatasetsLibSQL = class extends _mastra_core_storage.DatasetsStorage {
4360
4368
  async listItems(args) {
4361
4369
  try {
4362
4370
  const { page, perPage: perPageInput } = args.pagination;
4371
+ const itemsOrderBy = (0, _mastra_core_storage.resolveListOrderBy)(args.orderBy, ["createdAt", "updatedAt"], {
4372
+ field: "createdAt",
4373
+ direction: "DESC"
4374
+ });
4363
4375
  if (args.version !== void 0) {
4364
4376
  const conditions = [
4365
4377
  "datasetId = ?",
@@ -4406,7 +4418,7 @@ var DatasetsLibSQL = class extends _mastra_core_storage.DatasetsStorage {
4406
4418
  const end = perPageInput === false ? total : start + perPage;
4407
4419
  return {
4408
4420
  items: (await this.#client.execute({
4409
- sql: `SELECT ${buildSelectColumns(_mastra_core_storage.TABLE_DATASET_ITEMS)} FROM ${_mastra_core_storage.TABLE_DATASET_ITEMS} ${whereClause} ORDER BY createdAt DESC, id ASC LIMIT ? OFFSET ?`,
4421
+ sql: `SELECT ${buildSelectColumns(_mastra_core_storage.TABLE_DATASET_ITEMS)} FROM ${_mastra_core_storage.TABLE_DATASET_ITEMS} ${whereClause} ORDER BY ${itemsOrderBy.field} ${itemsOrderBy.direction}, id ASC LIMIT ? OFFSET ?`,
4410
4422
  args: [
4411
4423
  ...queryParams,
4412
4424
  limitValue,
@@ -4461,7 +4473,7 @@ var DatasetsLibSQL = class extends _mastra_core_storage.DatasetsStorage {
4461
4473
  const end = perPageInput === false ? total : start + perPage;
4462
4474
  return {
4463
4475
  items: (await this.#client.execute({
4464
- sql: `SELECT ${buildSelectColumns(_mastra_core_storage.TABLE_DATASET_ITEMS)} FROM ${_mastra_core_storage.TABLE_DATASET_ITEMS} ${whereClause} ORDER BY createdAt DESC, id ASC LIMIT ? OFFSET ?`,
4476
+ sql: `SELECT ${buildSelectColumns(_mastra_core_storage.TABLE_DATASET_ITEMS)} FROM ${_mastra_core_storage.TABLE_DATASET_ITEMS} ${whereClause} ORDER BY ${itemsOrderBy.field} ${itemsOrderBy.direction}, id ASC LIMIT ? OFFSET ?`,
4465
4477
  args: [
4466
4478
  ...queryParams,
4467
4479
  limitValue,
@@ -5156,6 +5168,10 @@ var ExperimentsLibSQL = class extends _mastra_core_storage.ExperimentsStorage {
5156
5168
  }
5157
5169
  async listExperiments(args) {
5158
5170
  try {
5171
+ const orderBy = (0, _mastra_core_storage.resolveListOrderBy)(args.orderBy, ["createdAt", "status"], {
5172
+ field: "createdAt",
5173
+ direction: "DESC"
5174
+ });
5159
5175
  const { page, perPage: perPageInput } = args.pagination;
5160
5176
  const conditions = [];
5161
5177
  const queryParams = [];
@@ -5227,7 +5243,7 @@ var ExperimentsLibSQL = class extends _mastra_core_storage.ExperimentsStorage {
5227
5243
  const end = perPageInput === false ? total : start + perPage;
5228
5244
  return {
5229
5245
  experiments: (await this.#client.execute({
5230
- sql: `SELECT ${buildSelectColumns(_mastra_core_storage.TABLE_EXPERIMENTS)} FROM ${_mastra_core_storage.TABLE_EXPERIMENTS} ${whereClause} ORDER BY createdAt DESC LIMIT ? OFFSET ?`,
5246
+ sql: `SELECT ${buildSelectColumns(_mastra_core_storage.TABLE_EXPERIMENTS)} FROM ${_mastra_core_storage.TABLE_EXPERIMENTS} ${whereClause} ORDER BY ${orderBy.field} ${orderBy.direction}, id ASC LIMIT ? OFFSET ?`,
5231
5247
  args: [
5232
5248
  ...queryParams,
5233
5249
  limitValue,
@@ -5474,6 +5490,10 @@ var ExperimentsLibSQL = class extends _mastra_core_storage.ExperimentsStorage {
5474
5490
  }
5475
5491
  async listExperimentResults(args) {
5476
5492
  try {
5493
+ const orderBy = (0, _mastra_core_storage.resolveListOrderBy)(args.orderBy, ["startedAt", "createdAt"], {
5494
+ field: "startedAt",
5495
+ direction: "ASC"
5496
+ });
5477
5497
  const { page, perPage: perPageInput } = args.pagination;
5478
5498
  const conditions = ["experimentId = ?"];
5479
5499
  const queryParams = [args.experimentId];
@@ -5521,7 +5541,7 @@ var ExperimentsLibSQL = class extends _mastra_core_storage.ExperimentsStorage {
5521
5541
  const end = perPageInput === false ? total : start + perPage;
5522
5542
  return {
5523
5543
  results: (await this.#client.execute({
5524
- sql: `SELECT ${buildSelectColumns(_mastra_core_storage.TABLE_EXPERIMENT_RESULTS)} FROM ${_mastra_core_storage.TABLE_EXPERIMENT_RESULTS} ${whereClause} ORDER BY startedAt ASC LIMIT ? OFFSET ?`,
5544
+ sql: `SELECT ${buildSelectColumns(_mastra_core_storage.TABLE_EXPERIMENT_RESULTS)} FROM ${_mastra_core_storage.TABLE_EXPERIMENT_RESULTS} ${whereClause} ORDER BY ${orderBy.field} ${orderBy.direction}, id ASC LIMIT ? OFFSET ?`,
5525
5545
  args: [
5526
5546
  ...queryParams,
5527
5547
  limitValue,
@@ -13503,7 +13523,7 @@ var WorkflowsLibSQL = class WorkflowsLibSQL extends _mastra_core_storage.Workflo
13503
13523
  }
13504
13524
  }, "deleteWorkflowRunById");
13505
13525
  }
13506
- async listWorkflowRuns({ workflowName, fromDate, toDate, page, perPage, resourceId, status } = {}) {
13526
+ async listWorkflowRuns({ workflowName, fromDate, toDate, page, perPage, resourceId, threadId, status } = {}) {
13507
13527
  try {
13508
13528
  const conditions = [];
13509
13529
  const args = [];
@@ -13527,6 +13547,10 @@ var WorkflowsLibSQL = class WorkflowsLibSQL extends _mastra_core_storage.Workflo
13527
13547
  conditions.push("resourceId = ?");
13528
13548
  args.push(resourceId);
13529
13549
  } else this.logger.warn(`[${_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT}] resourceId column not found. Skipping resourceId filter.`);
13550
+ if (threadId) {
13551
+ conditions.push(`(EXISTS (SELECT 1 FROM json_each(snapshot, '$.context') AS je WHERE json_extract(je.value, '$.status') = 'suspended' AND json_extract(je.value, '$.suspendPayload.__streamState.messageList.memoryInfo.threadId') = ?) OR json_extract(snapshot, '$.context.input.messageListState.memoryInfo.threadId') = ?)`);
13552
+ args.push(threadId, threadId);
13553
+ }
13530
13554
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
13531
13555
  let total = 0;
13532
13556
  const usePagination = typeof perPage === "number" && typeof page === "number";