@dbx-tools/appkit-mastra 0.6.217 → 0.6.219
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 +63 -18
- package/index.ts +4 -7
- package/lib/index.d.ts +4 -7
- package/lib/index.js +4 -5
- package/lib/src/agents.d.ts +15 -6
- package/lib/src/agents.js +30 -12
- package/lib/src/chat.d.ts +7 -0
- package/lib/src/chat.js +19 -0
- package/lib/src/config.d.ts +2 -2
- package/lib/src/config.js +1 -1
- package/lib/src/genie.js +5 -4
- package/lib/src/memory.d.ts +2 -2
- package/lib/src/memory.js +2 -2
- package/lib/src/plugin.d.ts +1 -1
- package/lib/src/plugin.js +3 -31
- package/lib/src/processors.d.ts +4 -28
- package/lib/src/processors.js +4 -61
- package/lib/src/server.d.ts +10 -21
- package/lib/src/server.js +52 -28
- package/lib/src/trace-io.js +7 -3
- package/lib/src/writer.d.ts +7 -7
- package/lib/src/writer.js +12 -9
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +22 -22
- package/src/agents.ts +92 -27
- package/src/chat.ts +20 -0
- package/src/config.ts +5 -2
- package/src/genie.ts +7 -11
- package/src/memory.ts +8 -8
- package/src/plugin.ts +2 -30
- package/src/processors.ts +4 -66
- package/src/server.ts +49 -27
- package/src/trace-io.ts +7 -2
- package/src/writer.ts +15 -11
- package/lib/src/history.d.ts +0 -93
- package/lib/src/history.js +0 -231
- package/lib/src/threads.d.ts +0 -104
- package/lib/src/threads.js +0 -264
- package/src/history.ts +0 -270
- package/src/threads.ts +0 -309
package/lib/src/history.js
DELETED
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Thread history loader exposed as a Mastra custom API route.
|
|
3
|
-
*
|
|
4
|
-
* Backed entirely by native Mastra: looks up the active agent by id,
|
|
5
|
-
* asks its `Memory` instance to `recall` a page of `MastraDBMessage`s,
|
|
6
|
-
* and converts the result to AI SDK V5 `UIMessage`s with the official
|
|
7
|
-
* {@link toAISdkV5Messages} helper from `@mastra/ai-sdk/ui`. No direct
|
|
8
|
-
* database reads.
|
|
9
|
-
*
|
|
10
|
-
* The route is registered through {@link historyRoute} as a Mastra
|
|
11
|
-
* `registerApiRoute` so it sits in the same dispatcher pipeline as
|
|
12
|
-
* the standard agent routes. That means the `MastraServer` auth
|
|
13
|
-
* middleware (in `./server.ts`) has already populated `RequestContext` with
|
|
14
|
-
* `MASTRA_THREAD_ID_KEY` and `MASTRA_RESOURCE_ID_KEY` by the time
|
|
15
|
-
* the handler runs - no cookie or user lookups happen here, and the
|
|
16
|
-
* session-cookie logic stays the single source of truth in `server.ts`.
|
|
17
|
-
*
|
|
18
|
-
* @module
|
|
19
|
-
*/
|
|
20
|
-
import { error, log } from "@dbx-tools/shared-core";
|
|
21
|
-
import { toAISdkV5Messages } from "@mastra/ai-sdk/ui";
|
|
22
|
-
import { registerApiRoute } from "@mastra/core/server";
|
|
23
|
-
import { resolveAgentRequestContext, resolveAgentRouteOptions, } from "./_agent-route-context.js";
|
|
24
|
-
import { clampPerPage, parseIntParam } from "./pagination.js";
|
|
25
|
-
const logger = log.logger("mastra/history");
|
|
26
|
-
/** Default history page size; matches the Mastra storage default. */
|
|
27
|
-
const DEFAULT_PER_PAGE = 20;
|
|
28
|
-
/** Hard cap so a misbehaving client can't fetch the whole thread at once. */
|
|
29
|
-
const MAX_PER_PAGE = 200;
|
|
30
|
-
/**
|
|
31
|
-
* Fetch a page of UI-formatted messages for a thread.
|
|
32
|
-
*
|
|
33
|
-
* Uses the agent's resolved `Memory` (`getMemory()`) so per-agent
|
|
34
|
-
* storage namespaces (`mastra_<agentId>` schemas) and any future
|
|
35
|
-
* memory-side filters apply automatically. When the agent has no
|
|
36
|
-
* memory configured the response is a successful empty page so
|
|
37
|
-
* callers don't have to special-case stateless agents.
|
|
38
|
-
*
|
|
39
|
-
* Pagination is descending-by-default: page 0 is the most recent
|
|
40
|
-
* page, page 1 the page before that, etc. The returned `uiMessages`
|
|
41
|
-
* are always re-sorted into chronological order (oldest -> newest)
|
|
42
|
-
* so the client can prepend them above the existing transcript
|
|
43
|
-
* without sorting locally.
|
|
44
|
-
*/
|
|
45
|
-
export async function loadHistory(opts) {
|
|
46
|
-
const perPage = clampPerPage(opts.perPage, {
|
|
47
|
-
fallback: DEFAULT_PER_PAGE,
|
|
48
|
-
max: MAX_PER_PAGE,
|
|
49
|
-
});
|
|
50
|
-
const page = Math.max(0, Math.trunc(opts.page ?? 0));
|
|
51
|
-
const memory = await opts.agent.getMemory();
|
|
52
|
-
if (!memory) {
|
|
53
|
-
logger.debug("recall:no-memory", { agentId: opts.agent.id, threadId: opts.threadId });
|
|
54
|
-
return { uiMessages: [], page, perPage, total: 0, hasMore: false };
|
|
55
|
-
}
|
|
56
|
-
const startedAt = Date.now();
|
|
57
|
-
const result = await memory.recall({
|
|
58
|
-
threadId: opts.threadId,
|
|
59
|
-
resourceId: opts.resourceId,
|
|
60
|
-
page,
|
|
61
|
-
perPage,
|
|
62
|
-
orderBy: {
|
|
63
|
-
field: "createdAt",
|
|
64
|
-
direction: opts.ascending ? "ASC" : "DESC",
|
|
65
|
-
},
|
|
66
|
-
});
|
|
67
|
-
const chronological = sortChronological(result.messages);
|
|
68
|
-
const uiMessages = toAISdkV5Messages(chronological);
|
|
69
|
-
logger.debug("recall:done", {
|
|
70
|
-
agentId: opts.agent.id,
|
|
71
|
-
threadId: opts.threadId,
|
|
72
|
-
page,
|
|
73
|
-
perPage,
|
|
74
|
-
returned: uiMessages.length,
|
|
75
|
-
total: result.total,
|
|
76
|
-
hasMore: result.hasMore,
|
|
77
|
-
elapsedMs: Date.now() - startedAt,
|
|
78
|
-
});
|
|
79
|
-
return {
|
|
80
|
-
uiMessages,
|
|
81
|
-
page,
|
|
82
|
-
perPage,
|
|
83
|
-
total: result.total,
|
|
84
|
-
hasMore: result.hasMore,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Wipe every persisted message tied to a thread. Returns the count
|
|
89
|
-
* of messages that were on the thread at delete time so the caller
|
|
90
|
-
* can render a "cleared N messages" affordance without an
|
|
91
|
-
* additional round-trip.
|
|
92
|
-
*
|
|
93
|
-
* Agents without a configured `Memory` resolve to a no-op (count
|
|
94
|
-
* 0), matching {@link loadHistory}'s "stateless agents return an
|
|
95
|
-
* empty page" stance so callers don't have to special-case them.
|
|
96
|
-
* Threads that don't exist yet are also a successful no-op - the
|
|
97
|
-
* operation is idempotent so the UI can fire-and-forget without
|
|
98
|
-
* tracking thread existence.
|
|
99
|
-
*/
|
|
100
|
-
export async function clearHistory(opts) {
|
|
101
|
-
const memory = await opts.agent.getMemory();
|
|
102
|
-
if (!memory) {
|
|
103
|
-
logger.debug("clear:no-memory", { agentId: opts.agent.id, threadId: opts.threadId });
|
|
104
|
-
return { cleared: 0 };
|
|
105
|
-
}
|
|
106
|
-
const existing = await memory.getThreadById({ threadId: opts.threadId });
|
|
107
|
-
if (!existing || existing.resourceId !== opts.resourceId) {
|
|
108
|
-
logger.debug("clear:not-owned", {
|
|
109
|
-
agentId: opts.agent.id,
|
|
110
|
-
threadId: opts.threadId,
|
|
111
|
-
found: existing !== null,
|
|
112
|
-
});
|
|
113
|
-
return { cleared: 0 };
|
|
114
|
-
}
|
|
115
|
-
// Mastra's `deleteThread` cascades to the message table, so we
|
|
116
|
-
// can't ask for a count after the fact. Read it pre-delete with a
|
|
117
|
-
// one-page recall sized to fit common threads in a single round
|
|
118
|
-
// trip; the value is for telemetry / UI, not correctness.
|
|
119
|
-
let cleared = 0;
|
|
120
|
-
try {
|
|
121
|
-
const probe = await memory.recall({
|
|
122
|
-
threadId: opts.threadId,
|
|
123
|
-
resourceId: opts.resourceId,
|
|
124
|
-
page: 0,
|
|
125
|
-
perPage: 1,
|
|
126
|
-
});
|
|
127
|
-
cleared = probe.total;
|
|
128
|
-
}
|
|
129
|
-
catch (err) {
|
|
130
|
-
// A missing-thread error is the happy-path "nothing to count";
|
|
131
|
-
// every other error is logged but doesn't block the delete.
|
|
132
|
-
logger.debug("clear:probe-failed", {
|
|
133
|
-
agentId: opts.agent.id,
|
|
134
|
-
threadId: opts.threadId,
|
|
135
|
-
error: error.errorMessage(err),
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
const startedAt = Date.now();
|
|
139
|
-
await memory.deleteThread(opts.threadId);
|
|
140
|
-
logger.info("clear:done", {
|
|
141
|
-
agentId: opts.agent.id,
|
|
142
|
-
threadId: opts.threadId,
|
|
143
|
-
cleared,
|
|
144
|
-
elapsedMs: Date.now() - startedAt,
|
|
145
|
-
});
|
|
146
|
-
return { cleared };
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Register the `<path>` Mastra custom API route. Handles two
|
|
150
|
-
* methods on the same mount:
|
|
151
|
-
*
|
|
152
|
-
* - `GET`: return a page of AI SDK V5 `UIMessage`s for the
|
|
153
|
-
* caller's current thread ({@link loadHistory}).
|
|
154
|
-
* - `DELETE`: wipe every persisted message on the caller's
|
|
155
|
-
* thread ({@link clearHistory}). The session cookie that
|
|
156
|
-
* anchors the thread id is left alone so the user keeps the
|
|
157
|
-
* same thread - only the contents go away.
|
|
158
|
-
*
|
|
159
|
-
* Follows the `@mastra/ai-sdk` `chatRoute` convention for agent
|
|
160
|
-
* binding: pass `agent` for a fixed-agent mount, or include
|
|
161
|
-
* `:agentId` in the path for dynamic routing. The plugin registers
|
|
162
|
-
* both `/route/history` (default agent) and `/route/history/:agentId`.
|
|
163
|
-
*
|
|
164
|
-
* The handler reads `threadId` and `resourceId` from `RequestContext`
|
|
165
|
-
* (populated upstream by `MastraServer.registerAuthMiddleware`), so
|
|
166
|
-
* no cookie or user lookups happen here.
|
|
167
|
-
*/
|
|
168
|
-
export function historyRoute(options) {
|
|
169
|
-
const { path, fixedAgent } = resolveAgentRouteOptions(options, "historyRoute.path");
|
|
170
|
-
return [
|
|
171
|
-
registerApiRoute(path, {
|
|
172
|
-
method: "GET",
|
|
173
|
-
handler: async (c) => {
|
|
174
|
-
const ctx = resolveAgentRequestContext(c, { fixedAgent, threadId: "required" });
|
|
175
|
-
if ("error" in ctx)
|
|
176
|
-
return ctx.error;
|
|
177
|
-
const payload = await loadHistory({
|
|
178
|
-
agent: ctx.agent,
|
|
179
|
-
threadId: ctx.threadId,
|
|
180
|
-
resourceId: ctx.resourceId,
|
|
181
|
-
page: parseIntParam(c.req.query("page")),
|
|
182
|
-
perPage: parseIntParam(c.req.query("perPage")),
|
|
183
|
-
});
|
|
184
|
-
return c.json(payload);
|
|
185
|
-
},
|
|
186
|
-
}),
|
|
187
|
-
registerApiRoute(path, {
|
|
188
|
-
method: "DELETE",
|
|
189
|
-
handler: async (c) => {
|
|
190
|
-
const ctx = resolveAgentRequestContext(c, { fixedAgent, threadId: "required" });
|
|
191
|
-
if ("error" in ctx)
|
|
192
|
-
return ctx.error;
|
|
193
|
-
const { cleared } = await clearHistory({
|
|
194
|
-
agent: ctx.agent,
|
|
195
|
-
threadId: ctx.threadId,
|
|
196
|
-
resourceId: ctx.resourceId,
|
|
197
|
-
});
|
|
198
|
-
const payload = {
|
|
199
|
-
ok: true,
|
|
200
|
-
agentId: ctx.agentId,
|
|
201
|
-
threadId: ctx.threadId,
|
|
202
|
-
cleared,
|
|
203
|
-
};
|
|
204
|
-
return c.json(payload);
|
|
205
|
-
},
|
|
206
|
-
}),
|
|
207
|
-
];
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Sort messages oldest-first by `createdAt`, falling back to whatever
|
|
211
|
-
* order the storage returned them in. The native `recall` call honors
|
|
212
|
-
* `orderBy` but doesn't guarantee a stable secondary sort, so we
|
|
213
|
-
* normalize here before handing the page to the AI SDK converter.
|
|
214
|
-
*/
|
|
215
|
-
function sortChronological(messages) {
|
|
216
|
-
return [...messages].sort((a, b) => {
|
|
217
|
-
const ta = toEpoch(a.createdAt);
|
|
218
|
-
const tb = toEpoch(b.createdAt);
|
|
219
|
-
return ta - tb;
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
function toEpoch(value) {
|
|
223
|
-
if (value instanceof Date)
|
|
224
|
-
return value.getTime();
|
|
225
|
-
if (typeof value === "string" || typeof value === "number") {
|
|
226
|
-
const parsed = new Date(value).getTime();
|
|
227
|
-
return Number.isNaN(parsed) ? 0 : parsed;
|
|
228
|
-
}
|
|
229
|
-
return 0;
|
|
230
|
-
}
|
|
231
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGlzdG9yeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9oaXN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFFSCxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBTXBELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBSXRELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXZELE9BQU8sRUFDTCwwQkFBMEIsRUFDMUIsd0JBQXdCLEdBRXpCLE1BQU0sMkJBQTJCLENBQUM7QUFDbkMsT0FBTyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUU5RCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFFNUMscUVBQXFFO0FBQ3JFLE1BQU0sZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO0FBQzVCLDZFQUE2RTtBQUM3RSxNQUFNLFlBQVksR0FBRyxHQUFHLENBQUM7QUFhekI7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLFdBQVcsQ0FBQyxJQUF3QjtJQUN4RCxNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtRQUN6QyxRQUFRLEVBQUUsZ0JBQWdCO1FBQzFCLEdBQUcsRUFBRSxZQUFZO0tBQ2xCLENBQUMsQ0FBQztJQUNILE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3JELE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUM1QyxJQUFJLENBQUMs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TyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUMzQyxDQUFDO0lBQ0QsT0FBTyxDQUFDLENBQUM7QUFDWCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaHJlYWQgaGlzdG9yeSBsb2FkZXIgZXhwb3NlZCBhcyBhIE1hc3RyYSBjdXN0b20gQVBJIHJvdXRlLlxuICpcbiAqIEJhY2tlZCBlbnRpcmVseSBieSBuYXRpdmUgTWFzdHJhOiBsb29rcyB1cCB0aGUgYWN0aXZlIGFnZW50IGJ5IGlkLFxuICogYXNrcyBpdHMgYE1lbW9yeWAgaW5zdGFuY2UgdG8gYHJlY2FsbGAgYSBwYWdlIG9mIGBNYXN0cmFEQk1lc3NhZ2VgcyxcbiAqIGFuZCBjb252ZXJ0cyB0aGUgcmVzdWx0IHRvIEFJIFNESyBWNSBgVUlNZXNzYWdlYHMgd2l0aCB0aGUgb2ZmaWNpYWxcbiAqIHtAbGluayB0b0FJU2RrVjVNZXNzYWdlc30gaGVscGVyIGZyb20gYEBtYXN0cmEvYWktc2RrL3VpYC4gTm8gZGlyZWN0XG4gKiBkYXRhYmFzZSByZWFkcy5cbiAqXG4gKiBUaGUgcm91dGUgaXMgcmVnaXN0ZXJlZCB0aHJvdWdoIHtAbGluayBoaXN0b3J5Um91dGV9IGFzIGEgTWFzdHJhXG4gKiBgcmVnaXN0ZXJBcGlSb3V0ZWAgc28gaXQgc2l0cyBpbiB0aGUgc2FtZSBkaXNwYXRjaGVyIHBpcGVsaW5lIGFzXG4gKiB0aGUgc3RhbmRhcmQgYWdlbnQgcm91dGVzLiBUaGF0IG1lYW5zIHRoZSBgTWFzdHJhU2VydmVyYCBhdXRoXG4gKiBtaWRkbGV3YXJlIChpbiBgLi9zZXJ2ZXIudHNgKSBoYXMgYWxyZWFkeSBwb3B1bGF0ZWQgYFJlcXVlc3RDb250ZXh0YCB3aXRoXG4gKiBgTUFTVFJBX1RIUkVBRF9JRF9LRVlgIGFuZCBgTUFTVFJBX1JFU09VUkNFX0lEX0tFWWAgYnkgdGhlIHRpbWVcbiAqIHRoZSBoYW5kbGVyIHJ1bnMgLSBubyBjb29raWUgb3IgdXNlciBsb29rdXBzIGhhcHBlbiBoZXJlLCBhbmQgdGhlXG4gKiBzZXNzaW9uLWNvb2tpZSBsb2dpYyBzdGF5cyB0aGUgc2luZ2xlIHNvdXJjZSBvZiB0cnV0aCBpbiBgc2VydmVyLnRzYC5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgZXJyb3IsIGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgdHlwZSB7XG4gIE1hc3RyYUNsZWFySGlzdG9yeVJlc3BvbnNlLFxuICBNYXN0cmFIaXN0b3J5UmVzcG9uc2UsXG4gIE1hc3RyYUhpc3RvcnlVSU1lc3NhZ2UsXG59IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1tYXN0cmFcIjtcbmltcG9ydCB7IHRvQUlTZGtWNU1lc3NhZ2VzIH0gZnJvbSBcIkBtYXN0cmEvYWktc2RrL3VpXCI7XG5pbXBvcnQgdHlwZSB7IEFnZW50IH0gZnJvbSBcIkBtYXN0cmEvY29yZS9hZ2VudFwiO1xuaW1wb3J0IHR5cGUgeyBNYXN0cmFEQk1lc3NhZ2UgfSBmcm9tIFwiQG1hc3RyYS9jb3JlL2FnZW50L21lc3NhZ2UtbGlzdFwiO1xuaW1wb3J0IHR5cGUgeyBDb250ZXh0V2l0aE1hc3RyYSB9IGZyb20gXCJAbWFzdHJhL2NvcmUvc2VydmVyXCI7XG5pbXBvcnQgeyByZWdpc3RlckFwaVJvdXRlIH0gZnJvbSBcIkBtYXN0cmEvY29yZS9zZXJ2ZXJcIjtcblxuaW1wb3J0IHtcbiAgcmVzb2x2ZUFnZW50UmVxdWVzdENvbnRleHQsXG4gIHJlc29sdmVBZ2VudFJvdXRlT3B0aW9ucyxcbiAgdHlwZSBBZ2VudFJvdXRlT3B0aW9ucyxcbn0gZnJvbSBcIi4vX2FnZW50LXJvdXRlLWNvbnRleHQudHNcIjtcbmltcG9ydCB7IGNsYW1wUGVyUGFnZSwgcGFyc2VJbnRQYXJhbSB9IGZyb20gXCIuL3BhZ2luYXRpb24udHNcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcIm1hc3RyYS9oaXN0b3J5XCIpO1xuXG4vKiogRGVmYXVsdCBoaXN0b3J5IHBhZ2Ugc2l6ZTsgbWF0Y2hlcyB0aGUgTWFzdHJhIHN0b3JhZ2UgZGVmYXVsdC4gKi9cbmNvbnN0IERFRkFVTFRfUEVSX1BBR0UgPSAyMDtcbi8qKiBIYXJkIGNhcCBzbyBhIG1pc2JlaGF2aW5nIGNsaWVudCBjYW4ndCBmZXRjaCB0aGUgd2hvbGUgdGhyZWFkIGF0IG9uY2UuICovXG5jb25zdCBNQVhfUEVSX1BBR0UgPSAyMDA7XG5cbi8qKiBJbnB1dHMgYWNjZXB0ZWQgYnkge0BsaW5rIGxvYWRIaXN0b3J5fS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTG9hZEhpc3RvcnlPcHRpb25zIHtcbiAgYWdlbnQ6IEFnZW50O1xuICB0aHJlYWRJZDogc3RyaW5nO1xuICByZXNvdXJjZUlkOiBzdHJpbmc7XG4gIHBhZ2U/OiBudW1iZXI7XG4gIHBlclBhZ2U/OiBudW1iZXI7XG4gIC8qKiBXaGVuIHRydWUsIHJldHVybnMgdGhlICpvbGRlc3QqIHBhZ2UgZmlyc3QgKGNocm9ub2xvZ2ljYWwpLiAqL1xuICBhc2NlbmRpbmc/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIEZldGNoIGEgcGFnZSBvZiBVSS1mb3JtYXR0ZWQgbWVzc2FnZXMgZm9yIGEgdGhyZWFkLlxuICpcbiAqIFVzZXMgdGhlIGFnZW50J3MgcmVzb2x2ZWQgYE1lbW9yeWAgKGBnZXRNZW1vcnkoKWApIHNvIHBlci1hZ2VudFxuICogc3RvcmFnZSBuYW1lc3BhY2VzIChgbWFzdHJhXzxhZ2VudElkPmAgc2NoZW1hcykgYW5kIGFueSBmdXR1cmVcbiAqIG1lbW9yeS1zaWRlIGZpbHRlcnMgYXBwbHkgYXV0b21hdGljYWxseS4gV2hlbiB0aGUgYWdlbnQgaGFzIG5vXG4gKiBtZW1vcnkgY29uZmlndXJlZCB0aGUgcmVzcG9uc2UgaXMgYSBzdWNjZXNzZnVsIGVtcHR5IHBhZ2Ugc29cbiAqIGNhbGxlcnMgZG9uJ3QgaGF2ZSB0byBzcGVjaWFsLWNhc2Ugc3RhdGVsZXNzIGFnZW50cy5cbiAqXG4gKiBQYWdpbmF0aW9uIGlzIGRlc2NlbmRpbmctYnktZGVmYXVsdDogcGFnZSAwIGlzIHRoZSBtb3N0IHJlY2VudFxuICogcGFnZSwgcGFnZSAxIHRoZSBwYWdlIGJlZm9yZSB0aGF0LCBldGMuIFRoZSByZXR1cm5lZCBgdWlNZXNzYWdlc2BcbiAqIGFyZSBhbHdheXMgcmUtc29ydGVkIGludG8gY2hyb25vbG9naWNhbCBvcmRlciAob2xkZXN0IC0+IG5ld2VzdClcbiAqIHNvIHRoZSBjbGllbnQgY2FuIHByZXBlbmQgdGhlbSBhYm92ZSB0aGUgZXhpc3RpbmcgdHJhbnNjcmlwdFxuICogd2l0aG91dCBzb3J0aW5nIGxvY2FsbHkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2FkSGlzdG9yeShvcHRzOiBMb2FkSGlzdG9yeU9wdGlvbnMpOiBQcm9taXNlPE1hc3RyYUhpc3RvcnlSZXNwb25zZT4ge1xuICBjb25zdCBwZXJQYWdlID0gY2xhbXBQZXJQYWdlKG9wdHMucGVyUGFnZSwge1xuICAgIGZhbGxiYWNrOiBERUZBVUxUX1BFUl9QQUdFLFxuICAgIG1heDogTUFYX1BFUl9QQUdFLFxuICB9KTtcbiAgY29uc3QgcGFnZSA9IE1hdGgubWF4KDAsIE1hdGgudHJ1bmMob3B0cy5wYWdlID8/IDApKTtcbiAgY29uc3QgbWVtb3J5ID0gYXdhaXQgb3B0cy5hZ2VudC5nZXRNZW1vcnkoKTtcbiAgaWYgKCFtZW1vcnkpIHtcbiAgICBsb2dnZXIuZGVidWcoXCJyZWNhbGw6bm8tbWVtb3J5XCIsIHsgYWdlbnRJZDogb3B0cy5hZ2VudC5pZCwgdGhyZWFkSWQ6IG9wdHMudGhyZWFkSWQgfSk7XG4gICAgcmV0dXJuIHsgdWlNZXNzYWdlczogW10sIHBhZ2UsIHBlclBhZ2UsIHRvdGFsOiAwLCBoYXNNb3JlOiBmYWxzZSB9O1xuICB9XG4gIGNvbnN0IHN0YXJ0ZWRBdCA9IERhdGUubm93KCk7XG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG1lbW9yeS5yZWNhbGwoe1xuICAgIHRocmVhZElkOiBvcHRzLnRocmVhZElkLFxuICAgIHJlc291cmNlSWQ6IG9wdHMucmVzb3VyY2VJZCxcbiAgICBwYWdlLFxuICAgIHBlclBhZ2UsXG4gICAgb3JkZXJCeToge1xuICAgICAgZmllbGQ6IFwiY3JlYXRlZEF0XCIsXG4gICAgICBkaXJlY3Rpb246IG9wdHMuYXNjZW5kaW5nID8gXCJBU0NcIiA6IFwiREVTQ1wiLFxuICAgIH0sXG4gIH0pO1xuICBjb25zdCBjaHJvbm9sb2dpY2FsID0gc29ydENocm9ub2xvZ2ljYWwocmVzdWx0Lm1lc3NhZ2VzKTtcbiAgY29uc3QgdWlNZXNzYWdlcyA9IHRvQUlTZGtWNU1lc3NhZ2VzKGNocm9ub2xvZ2ljYWwpIGFzIHVua25vd24gYXMgTWFzdHJhSGlzdG9yeVVJTWVzc2FnZVtdO1xuICBsb2dnZXIuZGVidWcoXCJyZWNhbGw6ZG9uZVwiLCB7XG4gICAgYWdlbnRJZDogb3B0cy5hZ2VudC5pZCxcbiAgICB0aHJlYWRJZDogb3B0cy50aHJlYWRJZCxcbiAgICBwYWdlLFxuICAgIHBlclBhZ2UsXG4gICAgcmV0dXJuZWQ6IHVpTWVzc2FnZXMubGVuZ3RoLFxuICAgIHRvdGFsOiByZXN1bHQudG90YWwsXG4gICAgaGFzTW9yZTogcmVzdWx0Lmhhc01vcmUsXG4gICAgZWxhcHNlZE1zOiBEYXRlLm5vdygpIC0gc3RhcnRlZEF0LFxuICB9KTtcbiAgcmV0dXJuIHtcbiAgICB1aU1lc3NhZ2VzLFxuICAgIHBhZ2UsXG4gICAgcGVyUGFnZSxcbiAgICB0b3RhbDogcmVzdWx0LnRvdGFsLFxuICAgIGhhc01vcmU6IHJlc3VsdC5oYXNNb3JlLFxuICB9O1xufVxuXG4vKiogSW5wdXRzIGFjY2VwdGVkIGJ5IHtAbGluayBjbGVhckhpc3Rvcnl9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBDbGVhckhpc3RvcnlPcHRpb25zIHtcbiAgYWdlbnQ6IEFnZW50O1xuICB0aHJlYWRJZDogc3RyaW5nO1xuICByZXNvdXJjZUlkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogV2lwZSBldmVyeSBwZXJzaXN0ZWQgbWVzc2FnZSB0aWVkIHRvIGEgdGhyZWFkLiBSZXR1cm5zIHRoZSBjb3VudFxuICogb2YgbWVzc2FnZXMgdGhhdCB3ZXJlIG9uIHRoZSB0aHJlYWQgYXQgZGVsZXRlIHRpbWUgc28gdGhlIGNhbGxlclxuICogY2FuIHJlbmRlciBhIFwiY2xlYXJlZCBOIG1lc3NhZ2VzXCIgYWZmb3JkYW5jZSB3aXRob3V0IGFuXG4gKiBhZGRpdGlvbmFsIHJvdW5kLXRyaXAuXG4gKlxuICogQWdlbnRzIHdpdGhvdXQgYSBjb25maWd1cmVkIGBNZW1vcnlgIHJlc29sdmUgdG8gYSBuby1vcCAoY291bnRcbiAqIDApLCBtYXRjaGluZyB7QGxpbmsgbG9hZEhpc3Rvcnl9J3MgXCJzdGF0ZWxlc3MgYWdlbnRzIHJldHVybiBhblxuICogZW1wdHkgcGFnZVwiIHN0YW5jZSBzbyBjYWxsZXJzIGRvbid0IGhhdmUgdG8gc3BlY2lhbC1jYXNlIHRoZW0uXG4gKiBUaHJlYWRzIHRoYXQgZG9uJ3QgZXhpc3QgeWV0IGFyZSBhbHNvIGEgc3VjY2Vzc2Z1bCBuby1vcCAtIHRoZVxuICogb3BlcmF0aW9uIGlzIGlkZW1wb3RlbnQgc28gdGhlIFVJIGNhbiBmaXJlLWFuZC1mb3JnZXQgd2l0aG91dFxuICogdHJhY2tpbmcgdGhyZWFkIGV4aXN0ZW5jZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNsZWFySGlzdG9yeShvcHRzOiBDbGVhckhpc3RvcnlPcHRpb25zKTogUHJvbWlzZTx7IGNsZWFyZWQ6IG51bWJlciB9PiB7XG4gIGNvbnN0IG1lbW9yeSA9IGF3YWl0IG9wdHMuYWdlbnQuZ2V0TWVtb3J5KCk7XG4gIGlmICghbWVtb3J5KSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwiY2xlYXI6bm8tbWVtb3J5XCIsIHsgYWdlbnRJZDogb3B0cy5hZ2VudC5pZCwgdGhyZWFkSWQ6IG9wdHMudGhyZWFkSWQgfSk7XG4gICAgcmV0dXJuIHsgY2xlYXJlZDogMCB9O1xuICB9XG4gIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgbWVtb3J5LmdldFRocmVhZEJ5SWQoeyB0aHJlYWRJZDogb3B0cy50aHJlYWRJZCB9KTtcbiAgaWYgKCFleGlzdGluZyB8fCBleGlzdGluZy5yZXNvdXJjZUlkICE9PSBvcHRzLnJlc291cmNlSWQpIHtcbiAgICBsb2dnZXIuZGVidWcoXCJjbGVhcjpub3Qtb3duZWRcIiwge1xuICAgICAgYWdlbnRJZDogb3B0cy5hZ2VudC5pZCxcbiAgICAgIHRocmVhZElkOiBvcHRzLnRocmVhZElkLFxuICAgICAgZm91bmQ6IGV4aXN0aW5nICE9PSBudWxsLFxuICAgIH0pO1xuICAgIHJldHVybiB7IGNsZWFyZWQ6IDAgfTtcbiAgfVxuICAvLyBNYXN0cmEncyBgZGVsZXRlVGhyZWFkYCBjYXNjYWRlcyB0byB0aGUgbWVzc2FnZSB0YWJsZSwgc28gd2VcbiAgLy8gY2FuJ3QgYXNrIGZvciBhIGNvdW50IGFmdGVyIHRoZSBmYWN0LiBSZWFkIGl0IHByZS1kZWxldGUgd2l0aCBhXG4gIC8vIG9uZS1wYWdlIHJlY2FsbCBzaXplZCB0byBmaXQgY29tbW9uIHRocmVhZHMgaW4gYSBzaW5nbGUgcm91bmRcbiAgLy8gdHJpcDsgdGhlIHZhbHVlIGlzIGZvciB0ZWxlbWV0cnkgLyBVSSwgbm90IGNvcnJlY3RuZXNzLlxuICBsZXQgY2xlYXJlZCA9IDA7XG4gIHRyeSB7XG4gICAgY29uc3QgcHJvYmUgPSBhd2FpdCBtZW1vcnkucmVjYWxsKHtcbiAgICAgIHRocmVhZElkOiBvcHRzLnRocmVhZElkLFxuICAgICAgcmVzb3VyY2VJZDogb3B0cy5yZXNvdXJjZUlkLFxuICAgICAgcGFnZTogMCxcbiAgICAgIHBlclBhZ2U6IDEsXG4gICAgfSk7XG4gICAgY2xlYXJlZCA9IHByb2JlLnRvdGFsO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICAvLyBBIG1pc3NpbmctdGhyZWFkIGVycm9yIGlzIHRoZSBoYXBweS1wYXRoIFwibm90aGluZyB0byBjb3VudFwiO1xuICAgIC8vIGV2ZXJ5IG90aGVyIGVycm9yIGlzIGxvZ2dlZCBidXQgZG9lc24ndCBibG9jayB0aGUgZGVsZXRlLlxuICAgIGxvZ2dlci5kZWJ1ZyhcImNsZWFyOnByb2JlLWZhaWxlZFwiLCB7XG4gICAgICBhZ2VudElkOiBvcHRzLmFnZW50LmlkLFxuICAgICAgdGhyZWFkSWQ6IG9wdHMudGhyZWFkSWQsXG4gICAgICBlcnJvcjogZXJyb3IuZXJyb3JNZXNzYWdlKGVyciksXG4gICAgfSk7XG4gIH1cblxuICBjb25zdCBzdGFydGVkQXQgPSBEYXRlLm5vdygpO1xuICBhd2FpdCBtZW1vcnkuZGVsZXRlVGhyZWFkKG9wdHMudGhyZWFkSWQpO1xuICBsb2dnZXIuaW5mbyhcImNsZWFyOmRvbmVcIiwge1xuICAgIGFnZW50SWQ6IG9wdHMuYWdlbnQuaWQsXG4gICAgdGhyZWFkSWQ6IG9wdHMudGhyZWFkSWQsXG4gICAgY2xlYXJlZCxcbiAgICBlbGFwc2VkTXM6IERhdGUubm93KCkgLSBzdGFydGVkQXQsXG4gIH0pO1xuICByZXR1cm4geyBjbGVhcmVkIH07XG59XG5cbi8qKiBPcHRpb25zIGFjY2VwdGVkIGJ5IHtAbGluayBoaXN0b3J5Um91dGV9LiAqL1xuZXhwb3J0IHR5cGUgSGlzdG9yeVJvdXRlT3B0aW9ucyA9IEFnZW50Um91dGVPcHRpb25zO1xuXG4vKipcbiAqIFJlZ2lzdGVyIHRoZSBgPHBhdGg+YCBNYXN0cmEgY3VzdG9tIEFQSSByb3V0ZS4gSGFuZGxlcyB0d29cbiAqIG1ldGhvZHMgb24gdGhlIHNhbWUgbW91bnQ6XG4gKlxuICogICAtIGBHRVRgOiByZXR1cm4gYSBwYWdlIG9mIEFJIFNESyBWNSBgVUlNZXNzYWdlYHMgZm9yIHRoZVxuICogICAgIGNhbGxlcidzIGN1cnJlbnQgdGhyZWFkICh7QGxpbmsgbG9hZEhpc3Rvcnl9KS5cbiAqICAgLSBgREVMRVRFYDogd2lwZSBldmVyeSBwZXJzaXN0ZWQgbWVzc2FnZSBvbiB0aGUgY2FsbGVyJ3NcbiAqICAgICB0aHJlYWQgKHtAbGluayBjbGVhckhpc3Rvcnl9KS4gVGhlIHNlc3Npb24gY29va2llIHRoYXRcbiAqICAgICBhbmNob3JzIHRoZSB0aHJlYWQgaWQgaXMgbGVmdCBhbG9uZSBzbyB0aGUgdXNlciBrZWVwcyB0aGVcbiAqICAgICBzYW1lIHRocmVhZCAtIG9ubHkgdGhlIGNvbnRlbnRzIGdvIGF3YXkuXG4gKlxuICogRm9sbG93cyB0aGUgYEBtYXN0cmEvYWktc2RrYCBgY2hhdFJvdXRlYCBjb252ZW50aW9uIGZvciBhZ2VudFxuICogYmluZGluZzogcGFzcyBgYWdlbnRgIGZvciBhIGZpeGVkLWFnZW50IG1vdW50LCBvciBpbmNsdWRlXG4gKiBgOmFnZW50SWRgIGluIHRoZSBwYXRoIGZvciBkeW5hbWljIHJvdXRpbmcuIFRoZSBwbHVnaW4gcmVnaXN0ZXJzXG4gKiBib3RoIGAvcm91dGUvaGlzdG9yeWAgKGRlZmF1bHQgYWdlbnQpIGFuZCBgL3JvdXRlL2hpc3RvcnkvOmFnZW50SWRgLlxuICpcbiAqIFRoZSBoYW5kbGVyIHJlYWRzIGB0aHJlYWRJZGAgYW5kIGByZXNvdXJjZUlkYCBmcm9tIGBSZXF1ZXN0Q29udGV4dGBcbiAqIChwb3B1bGF0ZWQgdXBzdHJlYW0gYnkgYE1hc3RyYVNlcnZlci5yZWdpc3RlckF1dGhNaWRkbGV3YXJlYCksIHNvXG4gKiBubyBjb29raWUgb3IgdXNlciBsb29rdXBzIGhhcHBlbiBoZXJlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGlzdG9yeVJvdXRlKG9wdGlvbnM6IEhpc3RvcnlSb3V0ZU9wdGlvbnMpIHtcbiAgY29uc3QgeyBwYXRoLCBmaXhlZEFnZW50IH0gPSByZXNvbHZlQWdlbnRSb3V0ZU9wdGlvbnMob3B0aW9ucywgXCJoaXN0b3J5Um91dGUucGF0aFwiKTtcblxuICByZXR1cm4gW1xuICAgIHJlZ2lzdGVyQXBpUm91dGUocGF0aCwge1xuICAgICAgbWV0aG9kOiBcIkdFVFwiLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKGM6IENvbnRleHRXaXRoTWFzdHJhKSA9PiB7XG4gICAgICAgIGNvbnN0IGN0eCA9IHJlc29sdmVBZ2VudFJlcXVlc3RDb250ZXh0KGMsIHsgZml4ZWRBZ2VudCwgdGhyZWFkSWQ6IFwicmVxdWlyZWRcIiB9KTtcbiAgICAgICAgaWYgKFwiZXJyb3JcIiBpbiBjdHgpIHJldHVybiBjdHguZXJyb3I7XG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSBhd2FpdCBsb2FkSGlzdG9yeSh7XG4gICAgICAgICAgYWdlbnQ6IGN0eC5hZ2VudCxcbiAgICAgICAgICB0aHJlYWRJZDogY3R4LnRocmVhZElkLFxuICAgICAgICAgIHJlc291cmNlSWQ6IGN0eC5yZXNvdXJjZUlkLFxuICAgICAgICAgIHBhZ2U6IHBhcnNlSW50UGFyYW0oYy5yZXEucXVlcnkoXCJwYWdlXCIpKSxcbiAgICAgICAgICBwZXJQYWdlOiBwYXJzZUludFBhcmFtKGMucmVxLnF1ZXJ5KFwicGVyUGFnZVwiKSksXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gYy5qc29uKHBheWxvYWQpO1xuICAgICAgfSxcbiAgICB9KSxcbiAgICByZWdpc3RlckFwaVJvdXRlKHBhdGgsIHtcbiAgICAgIG1ldGhvZDogXCJERUxFVEVcIixcbiAgICAgIGhhbmRsZXI6IGFzeW5jIChjOiBDb250ZXh0V2l0aE1hc3RyYSkgPT4ge1xuICAgICAgICBjb25zdCBjdHggPSByZXNvbHZlQWdlbnRSZXF1ZXN0Q29udGV4dChjLCB7IGZpeGVkQWdlbnQsIHRocmVhZElkOiBcInJlcXVpcmVkXCIgfSk7XG4gICAgICAgIGlmIChcImVycm9yXCIgaW4gY3R4KSByZXR1cm4gY3R4LmVycm9yO1xuICAgICAgICBjb25zdCB7IGNsZWFyZWQgfSA9IGF3YWl0IGNsZWFySGlzdG9yeSh7XG4gICAgICAgICAgYWdlbnQ6IGN0eC5hZ2VudCxcbiAgICAgICAgICB0aHJlYWRJZDogY3R4LnRocmVhZElkLFxuICAgICAgICAgIHJlc291cmNlSWQ6IGN0eC5yZXNvdXJjZUlkLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcGF5bG9hZDogTWFzdHJhQ2xlYXJIaXN0b3J5UmVzcG9uc2UgPSB7XG4gICAgICAgICAgb2s6IHRydWUsXG4gICAgICAgICAgYWdlbnRJZDogY3R4LmFnZW50SWQsXG4gICAgICAgICAgdGhyZWFkSWQ6IGN0eC50aHJlYWRJZCxcbiAgICAgICAgICBjbGVhcmVkLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gYy5qc29uKHBheWxvYWQpO1xuICAgICAgfSxcbiAgICB9KSxcbiAgXTtcbn1cblxuLyoqXG4gKiBTb3J0IG1lc3NhZ2VzIG9sZGVzdC1maXJzdCBieSBgY3JlYXRlZEF0YCwgZmFsbGluZyBiYWNrIHRvIHdoYXRldmVyXG4gKiBvcmRlciB0aGUgc3RvcmFnZSByZXR1cm5lZCB0aGVtIGluLiBUaGUgbmF0aXZlIGByZWNhbGxgIGNhbGwgaG9ub3JzXG4gKiBgb3JkZXJCeWAgYnV0IGRvZXNuJ3QgZ3VhcmFudGVlIGEgc3RhYmxlIHNlY29uZGFyeSBzb3J0LCBzbyB3ZVxuICogbm9ybWFsaXplIGhlcmUgYmVmb3JlIGhhbmRpbmcgdGhlIHBhZ2UgdG8gdGhlIEFJIFNESyBjb252ZXJ0ZXIuXG4gKi9cbmZ1bmN0aW9uIHNvcnRDaHJvbm9sb2dpY2FsKG1lc3NhZ2VzOiBNYXN0cmFEQk1lc3NhZ2VbXSk6IE1hc3RyYURCTWVzc2FnZVtdIHtcbiAgcmV0dXJuIFsuLi5tZXNzYWdlc10uc29ydCgoYSwgYikgPT4ge1xuICAgIGNvbnN0IHRhID0gdG9FcG9jaChhLmNyZWF0ZWRBdCk7XG4gICAgY29uc3QgdGIgPSB0b0Vwb2NoKGIuY3JlYXRlZEF0KTtcbiAgICByZXR1cm4gdGEgLSB0YjtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHRvRXBvY2godmFsdWU6IHVua25vd24pOiBudW1iZXIge1xuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSByZXR1cm4gdmFsdWUuZ2V0VGltZSgpO1xuICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiIHx8IHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIikge1xuICAgIGNvbnN0IHBhcnNlZCA9IG5ldyBEYXRlKHZhbHVlKS5nZXRUaW1lKCk7XG4gICAgcmV0dXJuIE51bWJlci5pc05hTihwYXJzZWQpID8gMCA6IHBhcnNlZDtcbiAgfVxuICByZXR1cm4gMDtcbn1cbiJdfQ==
|
package/lib/src/threads.d.ts
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Conversation-thread listing exposed as a Mastra custom API route.
|
|
3
|
-
*
|
|
4
|
-
* Backed entirely by native Mastra: looks up the active agent by id,
|
|
5
|
-
* asks its `Memory` instance to `listThreads` filtered to the caller's
|
|
6
|
-
* resource, and shapes each into the JSON-safe {@link MastraThread}
|
|
7
|
-
* wire type. A sibling `DELETE` removes a single named thread.
|
|
8
|
-
*
|
|
9
|
-
* A sibling `DELETE` removes a single named thread; a `PATCH` renames
|
|
10
|
-
* one ({@link renameThread}).
|
|
11
|
-
*
|
|
12
|
-
* Like {@link historyRoute} this registers through Mastra's
|
|
13
|
-
* `registerApiRoute` so it shares the `MastraServer` auth-middleware
|
|
14
|
-
* pipeline (in `./server.ts`), which has already stamped the resource
|
|
15
|
-
* id (`MASTRA_RESOURCE_ID_KEY`) and the targeted thread id
|
|
16
|
-
* (`MASTRA_THREAD_ID_KEY`, resolved from the thread-selection header /
|
|
17
|
-
* cookie) on `RequestContext` by the time a handler runs. Resource
|
|
18
|
-
* scoping lives here so a caller can only ever see, rename, or delete
|
|
19
|
-
* its own threads; no cookie or user lookups happen in this module.
|
|
20
|
-
*
|
|
21
|
-
* @module
|
|
22
|
-
*/
|
|
23
|
-
import { type MastraThread, type MastraThreadsResponse } from "@dbx-tools/shared-mastra";
|
|
24
|
-
import type { Agent } from "@mastra/core/agent";
|
|
25
|
-
import { type AgentRouteOptions } from "./_agent-route-context.ts";
|
|
26
|
-
/** Inputs accepted by {@link listThreads}. */
|
|
27
|
-
export interface ListThreadsOptions {
|
|
28
|
-
agent: Agent;
|
|
29
|
-
resourceId: string;
|
|
30
|
-
page?: number;
|
|
31
|
-
perPage?: number;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Fetch a page of the resource's conversation threads, newest
|
|
35
|
-
* (`updatedAt` DESC) first.
|
|
36
|
-
*
|
|
37
|
-
* Uses the agent's resolved `Memory` (`getMemory()`) so the per-agent
|
|
38
|
-
* storage namespace (`mastra_<agentId>` schema) applies automatically.
|
|
39
|
-
* When the agent has no memory configured the response is a successful
|
|
40
|
-
* empty page so callers don't have to special-case stateless agents.
|
|
41
|
-
*/
|
|
42
|
-
export declare function listThreads(opts: ListThreadsOptions): Promise<MastraThreadsResponse>;
|
|
43
|
-
/** Inputs accepted by {@link deleteThread}. */
|
|
44
|
-
export interface DeleteThreadOptions {
|
|
45
|
-
agent: Agent;
|
|
46
|
-
threadId: string;
|
|
47
|
-
resourceId: string;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Delete a single named thread (and every message on it).
|
|
51
|
-
*
|
|
52
|
-
* Ownership is enforced: the thread is only removed when it belongs to
|
|
53
|
-
* the calling resource, so a client can't delete another user's
|
|
54
|
-
* conversation by guessing its id. A thread that doesn't exist (or
|
|
55
|
-
* isn't owned by the caller) is a successful no-op (`deleted: false`)
|
|
56
|
-
* so the UI can fire-and-forget.
|
|
57
|
-
*/
|
|
58
|
-
export declare function deleteThread(opts: DeleteThreadOptions): Promise<{
|
|
59
|
-
deleted: boolean;
|
|
60
|
-
}>;
|
|
61
|
-
/** Inputs accepted by {@link renameThread}. */
|
|
62
|
-
export interface RenameThreadOptions {
|
|
63
|
-
agent: Agent;
|
|
64
|
-
threadId: string;
|
|
65
|
-
resourceId: string;
|
|
66
|
-
title: string;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Rename a single thread, returning the updated wire thread.
|
|
70
|
-
*
|
|
71
|
-
* Ownership is enforced the same way {@link deleteThread} enforces it:
|
|
72
|
-
* the title is only changed when the thread belongs to the calling
|
|
73
|
-
* resource, so a client can't rename another user's conversation by
|
|
74
|
-
* guessing its id. Existing thread `metadata` is preserved untouched
|
|
75
|
-
* (Mastra's `updateThread` replaces the row, so it must be passed back
|
|
76
|
-
* in). Returns `null` when the thread doesn't exist, isn't owned by the
|
|
77
|
-
* caller, or the agent has no memory configured, letting the route map
|
|
78
|
-
* that to a 404.
|
|
79
|
-
*/
|
|
80
|
-
export declare function renameThread(opts: RenameThreadOptions): Promise<MastraThread | null>;
|
|
81
|
-
/** Options accepted by {@link threadsRoute}. */
|
|
82
|
-
export type ThreadsRouteOptions = AgentRouteOptions;
|
|
83
|
-
/**
|
|
84
|
-
* Register the `<path>` Mastra custom API route. Handles three methods
|
|
85
|
-
* on the same mount:
|
|
86
|
-
*
|
|
87
|
-
* - `GET`: a page of the resource's conversation threads
|
|
88
|
-
* ({@link listThreads}).
|
|
89
|
-
* - `DELETE`: remove the thread named by the thread-selection header
|
|
90
|
-
* / `?threadId=` query ({@link deleteThread}). The id is read from
|
|
91
|
-
* `RequestContext` (the auth middleware resolves it the same way it
|
|
92
|
-
* does for streaming and history), so the client deletes any of its
|
|
93
|
-
* threads by stamping the target id - no separate path param.
|
|
94
|
-
* - `PATCH`: rename the thread named by the thread-selection header /
|
|
95
|
-
* `?threadId=` query to the `{ title }` in the JSON body
|
|
96
|
-
* ({@link renameThread}). Targets a thread the same way `DELETE`
|
|
97
|
-
* does; 404s when the thread isn't owned by the caller.
|
|
98
|
-
*
|
|
99
|
-
* Follows the `@mastra/ai-sdk` agent-binding convention: pass `agent`
|
|
100
|
-
* for a fixed-agent mount, or include `:agentId` in the path for
|
|
101
|
-
* dynamic routing. The plugin registers both `/route/threads` (default
|
|
102
|
-
* agent) and `/route/threads/:agentId`.
|
|
103
|
-
*/
|
|
104
|
-
export declare function threadsRoute(options: ThreadsRouteOptions): import("@mastra/core/server").ApiRoute[];
|