@mastra/code-sdk 1.9.0-alpha.9 → 1.10.0-alpha.0
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 +23 -0
- package/dist/agent-connections/tools.d.ts.map +1 -1
- package/dist/agent-connections/tools.js +5 -5
- package/dist/agent-connections/tools.js.map +1 -1
- package/dist/agents/tools.d.ts +1 -1
- package/dist/agents/tools.d.ts.map +1 -1
- package/dist/agents/tools.js +2 -1
- package/dist/agents/tools.js.map +1 -1
- package/dist/analytics.d.ts.map +1 -1
- package/dist/analytics.js +2 -3
- package/dist/analytics.js.map +1 -1
- package/dist/auth/account-rotation-processor.d.ts.map +1 -1
- package/dist/auth/account-rotation-processor.js +17 -10
- package/dist/auth/account-rotation-processor.js.map +1 -1
- package/dist/auth/providers/kimi-coding.d.ts.map +1 -1
- package/dist/auth/providers/kimi-coding.js +1 -2
- package/dist/auth/providers/kimi-coding.js.map +1 -1
- package/dist/auth/providers/openai-codex.d.ts +1 -1
- package/dist/auth/providers/openai-codex.d.ts.map +1 -1
- package/dist/auth/providers/openai-codex.js +7 -19
- package/dist/auth/providers/openai-codex.js.map +1 -1
- package/dist/auth/storage.js +3 -3
- package/dist/auth/storage.js.map +1 -1
- package/dist/experimental-agent.d.ts +11 -0
- package/dist/experimental-agent.d.ts.map +1 -0
- package/dist/experimental-agent.js +36 -0
- package/dist/experimental-agent.js.map +1 -0
- package/dist/goal-manager.d.ts +39 -3
- package/dist/goal-manager.d.ts.map +1 -1
- package/dist/goal-manager.js +113 -31
- package/dist/goal-manager.js.map +1 -1
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +95 -12
- package/dist/index.js.map +1 -1
- package/dist/knowledge-inspector.d.ts.map +1 -1
- package/dist/knowledge-inspector.js +1 -2
- package/dist/knowledge-inspector.js.map +1 -1
- package/dist/onboarding/settings.d.ts +11 -0
- package/dist/onboarding/settings.d.ts.map +1 -1
- package/dist/onboarding/settings.js +39 -5
- package/dist/onboarding/settings.js.map +1 -1
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +6 -1
- package/dist/permissions.js.map +1 -1
- package/dist/plugins/loader.d.ts.map +1 -1
- package/dist/plugins/loader.js +1 -2
- package/dist/plugins/loader.js.map +1 -1
- package/dist/process-memory-diagnostics.d.ts.map +1 -1
- package/dist/process-memory-diagnostics.js +2 -3
- package/dist/process-memory-diagnostics.js.map +1 -1
- package/dist/schedules/index.d.ts +10 -0
- package/dist/schedules/index.d.ts.map +1 -0
- package/dist/schedules/index.js +6 -0
- package/dist/schedules/interval.d.ts +49 -0
- package/dist/schedules/interval.d.ts.map +1 -0
- package/dist/schedules/interval.js +215 -0
- package/dist/schedules/interval.js.map +1 -0
- package/dist/schedules/prompt.d.ts +36 -0
- package/dist/schedules/prompt.d.ts.map +1 -0
- package/dist/schedules/prompt.js +39 -0
- package/dist/schedules/prompt.js.map +1 -0
- package/dist/schedules/run-script.d.ts +8 -0
- package/dist/schedules/run-script.d.ts.map +1 -0
- package/dist/schedules/run-script.js +83 -0
- package/dist/schedules/run-script.js.map +1 -0
- package/dist/schedules/scheduler.d.ts +101 -0
- package/dist/schedules/scheduler.d.ts.map +1 -0
- package/dist/schedules/scheduler.js +169 -0
- package/dist/schedules/scheduler.js.map +1 -0
- package/dist/schedules/tools.d.ts +57 -0
- package/dist/schedules/tools.d.ts.map +1 -0
- package/dist/schedules/tools.js +220 -0
- package/dist/schedules/tools.js.map +1 -0
- package/dist/tools/workflows/ephemeral-memory.d.ts +21 -0
- package/dist/tools/workflows/ephemeral-memory.d.ts.map +1 -1
- package/dist/tools/workflows/ephemeral-memory.js +1 -2
- package/dist/tools/workflows/ephemeral-memory.js.map +1 -1
- package/dist/utils/discarding-scores-storage.d.ts +33 -0
- package/dist/utils/discarding-scores-storage.d.ts.map +1 -0
- package/dist/utils/discarding-scores-storage.js +54 -0
- package/dist/utils/discarding-scores-storage.js.map +1 -0
- package/dist/utils/maintenance-lock.d.ts +42 -0
- package/dist/utils/maintenance-lock.d.ts.map +1 -0
- package/dist/utils/maintenance-lock.js +199 -0
- package/dist/utils/maintenance-lock.js.map +1 -0
- package/dist/utils/prune-cli.d.ts +24 -0
- package/dist/utils/prune-cli.d.ts.map +1 -0
- package/dist/utils/prune-cli.js +125 -0
- package/dist/utils/prune-cli.js.map +1 -0
- package/dist/utils/signals-pubsub.d.ts.map +1 -1
- package/dist/utils/signals-pubsub.js +1 -2
- package/dist/utils/signals-pubsub.js.map +1 -1
- package/dist/utils/storage-maintenance.d.ts.map +1 -1
- package/dist/utils/storage-maintenance.js +33 -3
- package/dist/utils/storage-maintenance.js.map +1 -1
- package/package.json +21 -15
package/dist/goal-manager.d.ts
CHANGED
|
@@ -19,6 +19,8 @@ export interface GoalState {
|
|
|
19
19
|
startedAt: string;
|
|
20
20
|
activeStartedAt?: string;
|
|
21
21
|
activeDurationMs?: number;
|
|
22
|
+
/** Why the goal paused (judge failure, budget exhaustion, ...). Only set while paused. */
|
|
23
|
+
pausedReason?: string;
|
|
22
24
|
}
|
|
23
25
|
export declare const DEFAULT_MAX_TURNS = 50;
|
|
24
26
|
export declare class GoalManager {
|
|
@@ -27,6 +29,13 @@ export declare class GoalManager {
|
|
|
27
29
|
private threadId;
|
|
28
30
|
private agentId;
|
|
29
31
|
private persistGoalOnNextThreadCreate;
|
|
32
|
+
/**
|
|
33
|
+
* Set by {@link clear} to the thread the goal was cleared on: the next save
|
|
34
|
+
* with an empty mirror on that same thread deletes the goal. A goal hydrated
|
|
35
|
+
* from legacy metadata has no known thread, so its clear applies to whichever
|
|
36
|
+
* thread the next save runs on (the pre-existing behaviour).
|
|
37
|
+
*/
|
|
38
|
+
private pendingDelete;
|
|
30
39
|
getGoal(): GoalState | null;
|
|
31
40
|
isActive(): boolean;
|
|
32
41
|
persistOnNextThreadCreate(): void;
|
|
@@ -53,18 +62,45 @@ export declare class GoalManager {
|
|
|
53
62
|
applyEvaluation(update: {
|
|
54
63
|
runsUsed: number;
|
|
55
64
|
status: GoalStatus;
|
|
65
|
+
pausedReason?: string;
|
|
56
66
|
}): GoalState | null;
|
|
57
67
|
/**
|
|
58
68
|
* Persist the active objective to ThreadState via the agent. The objective
|
|
59
|
-
* record is the source of truth; the legacy thread-metadata key is cleared
|
|
60
|
-
* stale state from older sessions
|
|
69
|
+
* record is the source of truth; the legacy thread-metadata key is cleared on
|
|
70
|
+
* a save that actually wrote, so stale state from older sessions cannot
|
|
71
|
+
* shadow the record — and a save that wrote nothing leaves it alone.
|
|
72
|
+
*
|
|
73
|
+
* An empty in-memory mirror means "I have nothing *loaded*", which is not the
|
|
74
|
+
* same statement as "there is nothing": the mirror is also emptied by storage
|
|
75
|
+
* failures and thread switches. So a save with an empty mirror deletes the
|
|
76
|
+
* goal (durable record and legacy key) only right after an explicit
|
|
77
|
+
* {@link clear} on the same thread (or any thread, for a legacy-hydrated goal
|
|
78
|
+
* whose thread is unknown), and is a complete no-op otherwise.
|
|
61
79
|
*/
|
|
62
80
|
saveToThread(state: GoalManagerState): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Remove the objective from the thread, whatever the in-memory mirror holds.
|
|
83
|
+
*
|
|
84
|
+
* The durable record needs an agent and a thread; the legacy thread-metadata
|
|
85
|
+
* key does not, so it is wiped either way — unlike {@link saveToThread}, which
|
|
86
|
+
* writes nothing with an empty mirror unless {@link clear} ran. That asymmetry is deliberate: a
|
|
87
|
+
* pre-migration goal must not resurface from the legacy key after a clear.
|
|
88
|
+
* Like the save, this is best-effort: a failed durable delete also skips the
|
|
89
|
+
* legacy wipe. A pending {@link clear} stays pending until both writes
|
|
90
|
+
* succeed, so a later save retries it; loading the thread retries it once
|
|
91
|
+
* and then drops it. Resolves to whether the delete landed.
|
|
92
|
+
*/
|
|
93
|
+
deleteFromThread(state: GoalManagerState): Promise<boolean>;
|
|
63
94
|
/**
|
|
64
95
|
* Load the objective from ThreadState (called on thread switch). Falls back to
|
|
65
96
|
* the legacy thread-metadata goal for threads created before this migration.
|
|
97
|
+
*
|
|
98
|
+
* A clear whose delete failed is retried here when it targeted this thread and
|
|
99
|
+
* the stored goal is the one that was cleared; otherwise the stored goal loads,
|
|
100
|
+
* so the mirror never hides a goal core is still judging. Resolves to whether
|
|
101
|
+
* that retried delete landed.
|
|
66
102
|
*/
|
|
67
|
-
loadFromThread(state: GoalManagerState, isCurrent?: () => boolean): Promise<
|
|
103
|
+
loadFromThread(state: GoalManagerState, isCurrent?: () => boolean): Promise<boolean>;
|
|
68
104
|
/**
|
|
69
105
|
* Legacy entry point retained for thread-switch call sites that only have the
|
|
70
106
|
* thread metadata available. Hydrates from a previously-persisted GoalState.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goal-manager.d.ts","sourceRoot":"","sources":["../src/goal-manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"goal-manager.d.ts","sourceRoot":"","sources":["../src/goal-manager.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAI9E,MAAM,WAAW,gBAAgB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAChG,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACpC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1B;AAMD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEtD;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0FAA0F;IAC1F,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAWpC,qBAAa,WAAW;IACtB,kGAAkG;IAClG,OAAO,CAAC,MAAM,CAAuD;IACrE,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,6BAA6B,CAAS;IAC9C;;;;;OAKG;IACH,OAAO,CAAC,aAAa,CAAkE;IAMvF,OAAO,IAAI,SAAS,GAAG,IAAI;IAwB3B,QAAQ,IAAI,OAAO;IAInB,yBAAyB,IAAI,IAAI;IAIjC,gCAAgC,IAAI,OAAO;IAU3C;;;;OAIG;IACG,OAAO,CACX,KAAK,EAAE,gBAAgB,EACvB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,QAAQ,GAAE,MAA0B,GACnC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IA2B5B;;;OAGG;IACG,mBAAmB,CACvB,KAAK,EAAE,gBAAgB,EACvB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAsB5B,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAOxC,MAAM,IAAI,SAAS,GAAG,IAAI;IAO1B,QAAQ,IAAI,IAAI;IAMhB,KAAK,IAAI,IAAI;IAQb;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,GAAG,IAAI;IAqB1G;;;;;;;;;;;;OAYG;IACG,YAAY,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA2D1D;;;;;;;;;;;OAWG;IACG,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBjE;;;;;;;;OAQG;IACG,cAAc,CAAC,KAAK,EAAE,gBAAgB,EAAE,SAAS,GAAE,MAAM,OAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;IAsCtG;;;OAGG;IACH,sBAAsB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI;IA4B3E,OAAO,CAAC,QAAQ;IAQhB,kFAAkF;IAClF,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,WAAW;CAmBpB"}
|
package/dist/goal-manager.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { loadSettings } from "./onboarding/settings.js";
|
|
2
|
-
import { randomUUID } from "crypto";
|
|
3
2
|
import { getGoalActivityDurationMs } from "@mastra/core/agent";
|
|
4
3
|
//#region src/goal-manager.ts
|
|
5
4
|
/**
|
|
@@ -26,6 +25,13 @@ var GoalManager = class {
|
|
|
26
25
|
threadId;
|
|
27
26
|
agentId;
|
|
28
27
|
persistGoalOnNextThreadCreate = false;
|
|
28
|
+
/**
|
|
29
|
+
* Set by {@link clear} to the thread the goal was cleared on: the next save
|
|
30
|
+
* with an empty mirror on that same thread deletes the goal. A goal hydrated
|
|
31
|
+
* from legacy metadata has no known thread, so its clear applies to whichever
|
|
32
|
+
* thread the next save runs on (the pre-existing behaviour).
|
|
33
|
+
*/
|
|
34
|
+
pendingDelete = null;
|
|
29
35
|
getGoal() {
|
|
30
36
|
if (!this.record) return null;
|
|
31
37
|
const { judgeModelId, maxTurns } = this.effectiveSettings(this.record);
|
|
@@ -37,6 +43,7 @@ var GoalManager = class {
|
|
|
37
43
|
maxTurns,
|
|
38
44
|
judgeModelId,
|
|
39
45
|
startedAt: new Date(this.record.startedAt).toISOString(),
|
|
46
|
+
...this.record.pausedReason ? { pausedReason: this.record.pausedReason } : {},
|
|
40
47
|
activeDurationMs: this.agentId && this.threadId ? getGoalActivityDurationMs({
|
|
41
48
|
agentId: this.agentId,
|
|
42
49
|
threadId: this.threadId,
|
|
@@ -65,7 +72,8 @@ var GoalManager = class {
|
|
|
65
72
|
const threadId = state.session.thread.getId();
|
|
66
73
|
const agent = this.getAgent(state);
|
|
67
74
|
const now = Date.now();
|
|
68
|
-
const id = randomUUID();
|
|
75
|
+
const id = globalThis.crypto.randomUUID();
|
|
76
|
+
this.pendingDelete = null;
|
|
69
77
|
this.threadId = threadId ?? void 0;
|
|
70
78
|
this.agentId = agent?.id;
|
|
71
79
|
if (agent && threadId) {
|
|
@@ -131,10 +139,15 @@ var GoalManager = class {
|
|
|
131
139
|
if (this.record) this.record = {
|
|
132
140
|
...this.record,
|
|
133
141
|
status: "done",
|
|
142
|
+
pausedReason: void 0,
|
|
134
143
|
updatedAt: Date.now()
|
|
135
144
|
};
|
|
136
145
|
}
|
|
137
146
|
clear() {
|
|
147
|
+
this.pendingDelete = {
|
|
148
|
+
threadId: this.threadId,
|
|
149
|
+
goalId: this.record?.id
|
|
150
|
+
};
|
|
138
151
|
this.record = null;
|
|
139
152
|
this.threadId = void 0;
|
|
140
153
|
this.agentId = void 0;
|
|
@@ -146,74 +159,141 @@ var GoalManager = class {
|
|
|
146
159
|
*/
|
|
147
160
|
applyEvaluation(update) {
|
|
148
161
|
if (!this.record) return null;
|
|
162
|
+
const pausedReason = update.status === "paused" ? update.pausedReason ?? (this.record.status === "paused" ? this.record.pausedReason : void 0) : void 0;
|
|
149
163
|
this.record = {
|
|
150
164
|
...this.record,
|
|
151
165
|
runsUsed: update.runsUsed,
|
|
152
166
|
status: update.status,
|
|
167
|
+
pausedReason,
|
|
153
168
|
updatedAt: Date.now()
|
|
154
169
|
};
|
|
155
170
|
return this.getGoal();
|
|
156
171
|
}
|
|
157
172
|
/**
|
|
158
173
|
* Persist the active objective to ThreadState via the agent. The objective
|
|
159
|
-
* record is the source of truth; the legacy thread-metadata key is cleared
|
|
160
|
-
* stale state from older sessions
|
|
174
|
+
* record is the source of truth; the legacy thread-metadata key is cleared on
|
|
175
|
+
* a save that actually wrote, so stale state from older sessions cannot
|
|
176
|
+
* shadow the record — and a save that wrote nothing leaves it alone.
|
|
177
|
+
*
|
|
178
|
+
* An empty in-memory mirror means "I have nothing *loaded*", which is not the
|
|
179
|
+
* same statement as "there is nothing": the mirror is also emptied by storage
|
|
180
|
+
* failures and thread switches. So a save with an empty mirror deletes the
|
|
181
|
+
* goal (durable record and legacy key) only right after an explicit
|
|
182
|
+
* {@link clear} on the same thread (or any thread, for a legacy-hydrated goal
|
|
183
|
+
* whose thread is unknown), and is a complete no-op otherwise.
|
|
161
184
|
*/
|
|
162
185
|
async saveToThread(state) {
|
|
163
186
|
const threadId = state.session.thread.getId();
|
|
164
187
|
const agent = this.getAgent(state);
|
|
188
|
+
if (!this.record && this.pendingDelete) {
|
|
189
|
+
const clearedThreadId = this.pendingDelete.threadId;
|
|
190
|
+
if (clearedThreadId === void 0 || clearedThreadId === threadId) await this.deleteFromThread(state);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
165
193
|
try {
|
|
166
|
-
if (agent && threadId)
|
|
167
|
-
if (
|
|
168
|
-
|
|
169
|
-
status: this.record.status,
|
|
170
|
-
...this.record.pausedReason ? { pausedReason: this.record.pausedReason } : {},
|
|
171
|
-
...this.record.judgeModelId ? { judgeModelId: this.record.judgeModelId } : {},
|
|
172
|
-
...this.record.maxRuns !== void 0 ? { maxRuns: this.record.maxRuns } : {}
|
|
173
|
-
})) {
|
|
174
|
-
const desiredStatus = this.record.status;
|
|
175
|
-
await agent.setObjective(this.record.objective, {
|
|
176
|
-
id: this.record.id,
|
|
194
|
+
if (agent && threadId) {
|
|
195
|
+
if (this.record) {
|
|
196
|
+
if (!await agent.updateObjectiveOptions({
|
|
177
197
|
threadId,
|
|
178
|
-
|
|
179
|
-
|
|
198
|
+
status: this.record.status,
|
|
199
|
+
...this.record.pausedReason ? { pausedReason: this.record.pausedReason } : {},
|
|
180
200
|
...this.record.judgeModelId ? { judgeModelId: this.record.judgeModelId } : {},
|
|
181
201
|
...this.record.maxRuns !== void 0 ? { maxRuns: this.record.maxRuns } : {}
|
|
182
|
-
})
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
202
|
+
})) {
|
|
203
|
+
const desiredStatus = this.record.status;
|
|
204
|
+
if (!await agent.setObjective(this.record.objective, {
|
|
205
|
+
id: this.record.id,
|
|
206
|
+
threadId,
|
|
207
|
+
resourceId: state.session.identity.getResourceId(),
|
|
208
|
+
activeDurationMs: normalizeActiveDurationMs(this.record.activeDurationMs),
|
|
209
|
+
...this.record.judgeModelId ? { judgeModelId: this.record.judgeModelId } : {},
|
|
210
|
+
...this.record.maxRuns !== void 0 ? { maxRuns: this.record.maxRuns } : {}
|
|
211
|
+
})) return;
|
|
212
|
+
if (desiredStatus !== "active") await agent.updateObjectiveOptions({
|
|
213
|
+
threadId,
|
|
214
|
+
status: desiredStatus,
|
|
215
|
+
...this.record.pausedReason ? { pausedReason: this.record.pausedReason } : {}
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
await state.session.thread.setSetting({
|
|
219
|
+
key: THREAD_GOAL_KEY,
|
|
220
|
+
value: void 0
|
|
187
221
|
});
|
|
188
222
|
}
|
|
189
|
-
}
|
|
223
|
+
}
|
|
224
|
+
} catch {}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Remove the objective from the thread, whatever the in-memory mirror holds.
|
|
228
|
+
*
|
|
229
|
+
* The durable record needs an agent and a thread; the legacy thread-metadata
|
|
230
|
+
* key does not, so it is wiped either way — unlike {@link saveToThread}, which
|
|
231
|
+
* writes nothing with an empty mirror unless {@link clear} ran. That asymmetry is deliberate: a
|
|
232
|
+
* pre-migration goal must not resurface from the legacy key after a clear.
|
|
233
|
+
* Like the save, this is best-effort: a failed durable delete also skips the
|
|
234
|
+
* legacy wipe. A pending {@link clear} stays pending until both writes
|
|
235
|
+
* succeed, so a later save retries it; loading the thread retries it once
|
|
236
|
+
* and then drops it. Resolves to whether the delete landed.
|
|
237
|
+
*/
|
|
238
|
+
async deleteFromThread(state) {
|
|
239
|
+
const threadId = state.session.thread.getId();
|
|
240
|
+
const agent = this.getAgent(state);
|
|
241
|
+
try {
|
|
242
|
+
if (agent && threadId) await agent.clearObjective({ threadId });
|
|
190
243
|
await state.session.thread.setSetting({
|
|
191
244
|
key: THREAD_GOAL_KEY,
|
|
192
245
|
value: void 0
|
|
193
246
|
});
|
|
194
|
-
|
|
247
|
+
this.pendingDelete = null;
|
|
248
|
+
return true;
|
|
249
|
+
} catch {
|
|
250
|
+
if (threadId) this.pendingDelete = {
|
|
251
|
+
threadId,
|
|
252
|
+
goalId: this.pendingDelete?.goalId
|
|
253
|
+
};
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
195
256
|
}
|
|
196
257
|
/**
|
|
197
258
|
* Load the objective from ThreadState (called on thread switch). Falls back to
|
|
198
259
|
* the legacy thread-metadata goal for threads created before this migration.
|
|
260
|
+
*
|
|
261
|
+
* A clear whose delete failed is retried here when it targeted this thread and
|
|
262
|
+
* the stored goal is the one that was cleared; otherwise the stored goal loads,
|
|
263
|
+
* so the mirror never hides a goal core is still judging. Resolves to whether
|
|
264
|
+
* that retried delete landed.
|
|
199
265
|
*/
|
|
200
266
|
async loadFromThread(state, isCurrent = () => true) {
|
|
267
|
+
const pending = this.pendingDelete;
|
|
201
268
|
const threadId = state.session.thread.getId();
|
|
202
269
|
const agent = this.getAgent(state);
|
|
203
270
|
let nextRecord = null;
|
|
271
|
+
let storedId;
|
|
204
272
|
if (agent && threadId) try {
|
|
205
273
|
const record = await agent.getObjective({ threadId });
|
|
206
|
-
if (record)
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
274
|
+
if (record) {
|
|
275
|
+
storedId = record.id;
|
|
276
|
+
nextRecord = {
|
|
277
|
+
...record,
|
|
278
|
+
id: record.id ?? globalThis.crypto.randomUUID(),
|
|
279
|
+
activeDurationMs: normalizeActiveDurationMs(record.activeDurationMs)
|
|
280
|
+
};
|
|
281
|
+
}
|
|
211
282
|
} catch {}
|
|
212
|
-
if (!isCurrent()) return;
|
|
283
|
+
if (!isCurrent()) return false;
|
|
284
|
+
if (pending && this.pendingDelete !== pending) return false;
|
|
285
|
+
let retriedDelete = false;
|
|
286
|
+
if (pending?.goalId && pending.threadId === threadId && storedId === pending.goalId) {
|
|
287
|
+
retriedDelete = await this.deleteFromThread(state);
|
|
288
|
+
if (retriedDelete) nextRecord = null;
|
|
289
|
+
if (!isCurrent()) return false;
|
|
290
|
+
}
|
|
213
291
|
this.persistGoalOnNextThreadCreate = false;
|
|
292
|
+
this.pendingDelete = null;
|
|
214
293
|
this.threadId = threadId ?? void 0;
|
|
215
294
|
this.agentId = agent?.id;
|
|
216
295
|
this.record = nextRecord;
|
|
296
|
+
return retriedDelete;
|
|
217
297
|
}
|
|
218
298
|
/**
|
|
219
299
|
* Legacy entry point retained for thread-switch call sites that only have the
|
|
@@ -222,6 +302,7 @@ var GoalManager = class {
|
|
|
222
302
|
loadFromThreadMetadata(metadata) {
|
|
223
303
|
const saved = metadata?.[THREAD_GOAL_KEY];
|
|
224
304
|
this.persistGoalOnNextThreadCreate = false;
|
|
305
|
+
this.pendingDelete = null;
|
|
225
306
|
this.threadId = void 0;
|
|
226
307
|
this.agentId = void 0;
|
|
227
308
|
if (saved && saved.objective && saved.status) this.record = {
|
|
@@ -231,9 +312,10 @@ var GoalManager = class {
|
|
|
231
312
|
activeDurationMs: normalizeActiveDurationMs(saved.activeDurationMs),
|
|
232
313
|
maxRuns: saved.maxTurns ?? 50,
|
|
233
314
|
judgeModelId: saved.judgeModelId ?? "",
|
|
315
|
+
...saved.pausedReason ? { pausedReason: saved.pausedReason } : {},
|
|
234
316
|
startedAt: saved.startedAt ? Date.parse(saved.startedAt) || Date.now() : Date.now(),
|
|
235
317
|
updatedAt: Date.now(),
|
|
236
|
-
id: saved.id ?? randomUUID()
|
|
318
|
+
id: saved.id ?? globalThis.crypto.randomUUID()
|
|
237
319
|
};
|
|
238
320
|
else this.record = null;
|
|
239
321
|
}
|
package/dist/goal-manager.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goal-manager.js","names":[],"sources":["../src/goal-manager.ts"],"sourcesContent":["/**\n * GoalManager — persistent cross-turn goals, backed by the Agent's native goal\n * mechanism.\n *\n * The objective lives in the durable `threadState` `'goal'` slot (via\n * `agent.setObjective`/`getObjective`/`clearObjective`/`updateObjectiveOptions`)\n * and is judged in-loop by the core goal step. This manager is a thin adapter:\n * it keeps a synchronous in-memory view of the current objective for the TUI\n * (status line, modal, keyboard shortcuts) and delegates persistence to the\n * agent. There is no standalone judge agent and no between-turn re-invocation —\n * the core goal step drives continuation and surfaces progress via `goal` stream\n * chunks.\n */\nimport { randomUUID } from 'node:crypto';\nimport { getGoalActivityDurationMs } from '@mastra/core/agent';\nimport type { Agent } from '@mastra/core/agent';\nimport type { AgentController, Session } from '@mastra/core/agent-controller';\nimport type { GoalObjectiveRecord } from '@mastra/core/storage';\nimport { loadSettings } from './onboarding/settings.js';\n\nexport interface GoalManagerState<TState extends Record<string, unknown> = Record<string, unknown>> {\n controller: AgentController<TState>;\n session: Session<TState>;\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type GoalStatus = 'active' | 'paused' | 'done';\n\n/**\n * TUI-facing view of a goal. Derived from the durable {@link GoalObjectiveRecord}\n * plus the effective judge/max-runs settings, with display-only timer fields and\n * a stable `id` used to match plan-started goals.\n */\nexport interface GoalState {\n id: string;\n objective: string;\n status: GoalStatus;\n turnsUsed: number;\n maxTurns: number;\n judgeModelId: string;\n startedAt: string;\n activeStartedAt?: string;\n activeDurationMs?: number;\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\nexport const DEFAULT_MAX_TURNS = 50;\nconst THREAD_GOAL_KEY = 'goal';\n\nfunction normalizeActiveDurationMs(value: number | undefined): number {\n return value !== undefined && Number.isFinite(value) && value >= 0 ? value : 0;\n}\n\n// =============================================================================\n// GoalManager\n// =============================================================================\n\nexport class GoalManager {\n /** Synchronous in-memory view of the active objective record (source of truth is ThreadState). */\n private record: (GoalObjectiveRecord & { id: string }) | null = null;\n private threadId: string | undefined;\n private agentId: string | undefined;\n private persistGoalOnNextThreadCreate = false;\n\n // ---------------------------------------------------------------------------\n // Synchronous TUI surface\n // ---------------------------------------------------------------------------\n\n getGoal(): GoalState | null {\n if (!this.record) return null;\n const { judgeModelId, maxTurns } = this.effectiveSettings(this.record);\n return {\n id: this.record.id,\n objective: this.record.objective,\n status: this.record.status,\n turnsUsed: this.record.runsUsed,\n maxTurns,\n judgeModelId,\n startedAt: new Date(this.record.startedAt).toISOString(),\n activeDurationMs:\n this.agentId && this.threadId\n ? getGoalActivityDurationMs({\n agentId: this.agentId,\n threadId: this.threadId,\n objectiveId: this.record.id,\n activeDurationMs: this.record.activeDurationMs,\n })\n : normalizeActiveDurationMs(this.record.activeDurationMs),\n };\n }\n\n isActive(): boolean {\n return this.record?.status === 'active';\n }\n\n persistOnNextThreadCreate(): void {\n this.persistGoalOnNextThreadCreate = true;\n }\n\n consumePersistOnNextThreadCreate(): boolean {\n if (!this.persistGoalOnNextThreadCreate) return false;\n this.persistGoalOnNextThreadCreate = false;\n return true;\n }\n\n // ---------------------------------------------------------------------------\n // Objective lifecycle (ThreadState-backed via the agent)\n // ---------------------------------------------------------------------------\n\n /**\n * Set a new objective. Persists to ThreadState via `agent.setObjective` and\n * updates the in-memory view. Only the provided settings are persisted into\n * the record; unset ones fall back to the agent's `goal` config at read time.\n */\n async setGoal(\n state: GoalManagerState,\n objective: string,\n judgeModelId: string,\n maxTurns: number = DEFAULT_MAX_TURNS,\n ): Promise<GoalState | null> {\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n const now = Date.now();\n const id = randomUUID();\n this.threadId = threadId ?? undefined;\n this.agentId = agent?.id;\n\n if (agent && threadId) {\n const persisted = await agent.setObjective(objective, {\n id,\n threadId,\n resourceId: state.session.identity.getResourceId(),\n ...(judgeModelId ? { judgeModelId } : {}),\n maxRuns: maxTurns,\n });\n this.record = persisted\n ? { ...persisted, id: persisted.id ?? id }\n : this.localRecord(objective, judgeModelId, maxTurns, now, id);\n } else {\n this.record = this.localRecord(objective, judgeModelId, maxTurns, now, id);\n }\n\n return this.getGoal();\n }\n\n /**\n * Update the judge model / max-runs defaults. Persists into the active record\n * (so the override is remembered in thread state) when a goal is set.\n */\n async updateJudgeDefaults(\n state: GoalManagerState,\n judgeModelId: string,\n maxTurns: number,\n ): Promise<GoalState | null> {\n if (!this.record) return null;\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n if (agent && threadId) {\n const updated = await agent.updateObjectiveOptions({\n threadId,\n ...(judgeModelId ? { judgeModelId } : {}),\n maxRuns: maxTurns,\n });\n if (updated) this.record = { ...updated, id: this.record.id };\n } else {\n this.record = {\n ...this.record,\n ...(judgeModelId ? { judgeModelId } : {}),\n maxRuns: maxTurns,\n updatedAt: Date.now(),\n };\n }\n return this.getGoal();\n }\n\n pause(reason?: string): GoalState | null {\n if (this.record && this.record.status === 'active') {\n this.record = { ...this.record, status: 'paused', pausedReason: reason, updatedAt: Date.now() };\n }\n return this.getGoal();\n }\n\n resume(): GoalState | null {\n if (this.record && this.record.status === 'paused') {\n this.record = { ...this.record, status: 'active', pausedReason: undefined, updatedAt: Date.now() };\n }\n return this.getGoal();\n }\n\n markDone(): void {\n if (this.record) {\n this.record = { ...this.record, status: 'done', updatedAt: Date.now() };\n }\n }\n\n clear(): void {\n this.record = null;\n this.threadId = undefined;\n this.agentId = undefined;\n this.persistGoalOnNextThreadCreate = false;\n }\n\n /**\n * Sync the latest objective record from ThreadState into the in-memory view.\n * Called from the `goal` stream-chunk handler after each evaluation.\n */\n applyEvaluation(update: { runsUsed: number; status: GoalStatus }): GoalState | null {\n if (!this.record) return null;\n this.record = { ...this.record, runsUsed: update.runsUsed, status: update.status, updatedAt: Date.now() };\n return this.getGoal();\n }\n\n // ---------------------------------------------------------------------------\n // Persistence\n // ---------------------------------------------------------------------------\n\n /**\n * Persist the active objective to ThreadState via the agent. The objective\n * record is the source of truth; the legacy thread-metadata key is cleared so\n * stale state from older sessions does not resurface.\n */\n async saveToThread(state: GoalManagerState): Promise<void> {\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n try {\n if (agent && threadId) {\n if (this.record) {\n // Push the current status/options into the existing record. If no\n // record is persisted yet (e.g. first save), create one.\n const updated = await agent.updateObjectiveOptions({\n threadId,\n status: this.record.status,\n ...(this.record.pausedReason ? { pausedReason: this.record.pausedReason } : {}),\n ...(this.record.judgeModelId ? { judgeModelId: this.record.judgeModelId } : {}),\n ...(this.record.maxRuns !== undefined ? { maxRuns: this.record.maxRuns } : {}),\n });\n if (!updated) {\n // No persisted record yet: create one. `setObjective` always writes\n // `status: 'active'`, so re-apply the in-memory status afterwards if\n // the local goal was already paused/done — otherwise the resumed\n // thread state would no longer match the in-memory state.\n const desiredStatus = this.record.status;\n await agent.setObjective(this.record.objective, {\n id: this.record.id,\n threadId,\n resourceId: state.session.identity.getResourceId(),\n activeDurationMs: normalizeActiveDurationMs(this.record.activeDurationMs),\n ...(this.record.judgeModelId ? { judgeModelId: this.record.judgeModelId } : {}),\n ...(this.record.maxRuns !== undefined ? { maxRuns: this.record.maxRuns } : {}),\n });\n if (desiredStatus !== 'active') {\n await agent.updateObjectiveOptions({\n threadId,\n status: desiredStatus,\n ...(this.record.pausedReason ? { pausedReason: this.record.pausedReason } : {}),\n });\n }\n }\n } else {\n await agent.clearObjective({ threadId });\n }\n }\n // Clear any legacy thread-metadata goal so it can't shadow the record.\n await state.session.thread.setSetting({ key: THREAD_GOAL_KEY, value: undefined });\n } catch {\n // Persistence is not critical.\n }\n }\n\n /**\n * Load the objective from ThreadState (called on thread switch). Falls back to\n * the legacy thread-metadata goal for threads created before this migration.\n */\n async loadFromThread(state: GoalManagerState, isCurrent: () => boolean = () => true): Promise<void> {\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n let nextRecord: typeof this.record = null;\n if (agent && threadId) {\n try {\n const record = await agent.getObjective({ threadId });\n if (record) {\n nextRecord = {\n ...record,\n id: record.id ?? randomUUID(),\n activeDurationMs: normalizeActiveDurationMs(record.activeDurationMs),\n };\n }\n } catch {\n // fall through to legacy metadata\n }\n }\n if (!isCurrent()) return;\n this.persistGoalOnNextThreadCreate = false;\n this.threadId = threadId ?? undefined;\n this.agentId = agent?.id;\n this.record = nextRecord;\n }\n\n /**\n * Legacy entry point retained for thread-switch call sites that only have the\n * thread metadata available. Hydrates from a previously-persisted GoalState.\n */\n loadFromThreadMetadata(metadata: Record<string, unknown> | undefined): void {\n const saved = metadata?.[THREAD_GOAL_KEY] as Partial<GoalState> | undefined;\n this.persistGoalOnNextThreadCreate = false;\n this.threadId = undefined;\n this.agentId = undefined;\n if (saved && saved.objective && saved.status) {\n this.record = {\n objective: saved.objective,\n status: saved.status,\n runsUsed: saved.turnsUsed ?? 0,\n activeDurationMs: normalizeActiveDurationMs(saved.activeDurationMs),\n maxRuns: saved.maxTurns ?? DEFAULT_MAX_TURNS,\n judgeModelId: saved.judgeModelId ?? '',\n startedAt: saved.startedAt ? Date.parse(saved.startedAt) || Date.now() : Date.now(),\n updatedAt: Date.now(),\n id: saved.id ?? randomUUID(),\n };\n } else {\n this.record = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private\n // ---------------------------------------------------------------------------\n\n private getAgent(state: GoalManagerState): Agent | undefined {\n try {\n return state.controller.getCurrentAgent(state.session);\n } catch {\n return undefined;\n }\n }\n\n /** Resolve effective judge model + max runs (record value → settings default). */\n private effectiveSettings(record: GoalObjectiveRecord): { judgeModelId: string; maxTurns: number } {\n const settings = loadSettings();\n return {\n judgeModelId: record.judgeModelId ?? settings.models.goalJudgeModel ?? '',\n maxTurns: record.maxRuns ?? settings.models.goalMaxTurns ?? DEFAULT_MAX_TURNS,\n };\n }\n\n private localRecord(\n objective: string,\n judgeModelId: string,\n maxTurns: number,\n now: number,\n id: string,\n ): GoalObjectiveRecord & { id: string } {\n return {\n objective,\n status: 'active',\n runsUsed: 0,\n activeDurationMs: 0,\n maxRuns: maxTurns,\n ...(judgeModelId ? { judgeModelId } : {}),\n startedAt: now,\n updatedAt: now,\n id,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"goal-manager.js","names":[],"sources":["../src/goal-manager.ts"],"sourcesContent":["/**\n * GoalManager — persistent cross-turn goals, backed by the Agent's native goal\n * mechanism.\n *\n * The objective lives in the durable `threadState` `'goal'` slot (via\n * `agent.setObjective`/`getObjective`/`clearObjective`/`updateObjectiveOptions`)\n * and is judged in-loop by the core goal step. This manager is a thin adapter:\n * it keeps a synchronous in-memory view of the current objective for the TUI\n * (status line, modal, keyboard shortcuts) and delegates persistence to the\n * agent. There is no standalone judge agent and no between-turn re-invocation —\n * the core goal step drives continuation and surfaces progress via `goal` stream\n * chunks.\n */\nimport { getGoalActivityDurationMs } from '@mastra/core/agent';\nimport type { Agent } from '@mastra/core/agent';\nimport type { AgentController, Session } from '@mastra/core/agent-controller';\nimport type { GoalObjectiveRecord } from '@mastra/core/storage';\nimport { loadSettings } from './onboarding/settings.js';\n\nexport interface GoalManagerState<TState extends Record<string, unknown> = Record<string, unknown>> {\n controller: AgentController<TState>;\n session: Session<TState>;\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type GoalStatus = 'active' | 'paused' | 'done';\n\n/**\n * TUI-facing view of a goal. Derived from the durable {@link GoalObjectiveRecord}\n * plus the effective judge/max-runs settings, with display-only timer fields and\n * a stable `id` used to match plan-started goals.\n */\nexport interface GoalState {\n id: string;\n objective: string;\n status: GoalStatus;\n turnsUsed: number;\n maxTurns: number;\n judgeModelId: string;\n startedAt: string;\n activeStartedAt?: string;\n activeDurationMs?: number;\n /** Why the goal paused (judge failure, budget exhaustion, ...). Only set while paused. */\n pausedReason?: string;\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\nexport const DEFAULT_MAX_TURNS = 50;\nconst THREAD_GOAL_KEY = 'goal';\n\nfunction normalizeActiveDurationMs(value: number | undefined): number {\n return value !== undefined && Number.isFinite(value) && value >= 0 ? value : 0;\n}\n\n// =============================================================================\n// GoalManager\n// =============================================================================\n\nexport class GoalManager {\n /** Synchronous in-memory view of the active objective record (source of truth is ThreadState). */\n private record: (GoalObjectiveRecord & { id: string }) | null = null;\n private threadId: string | undefined;\n private agentId: string | undefined;\n private persistGoalOnNextThreadCreate = false;\n /**\n * Set by {@link clear} to the thread the goal was cleared on: the next save\n * with an empty mirror on that same thread deletes the goal. A goal hydrated\n * from legacy metadata has no known thread, so its clear applies to whichever\n * thread the next save runs on (the pre-existing behaviour).\n */\n private pendingDelete: { threadId: string | undefined; goalId?: string } | null = null;\n\n // ---------------------------------------------------------------------------\n // Synchronous TUI surface\n // ---------------------------------------------------------------------------\n\n getGoal(): GoalState | null {\n if (!this.record) return null;\n const { judgeModelId, maxTurns } = this.effectiveSettings(this.record);\n return {\n id: this.record.id,\n objective: this.record.objective,\n status: this.record.status,\n turnsUsed: this.record.runsUsed,\n maxTurns,\n judgeModelId,\n startedAt: new Date(this.record.startedAt).toISOString(),\n ...(this.record.pausedReason ? { pausedReason: this.record.pausedReason } : {}),\n activeDurationMs:\n this.agentId && this.threadId\n ? getGoalActivityDurationMs({\n agentId: this.agentId,\n threadId: this.threadId,\n objectiveId: this.record.id,\n activeDurationMs: this.record.activeDurationMs,\n })\n : normalizeActiveDurationMs(this.record.activeDurationMs),\n };\n }\n\n isActive(): boolean {\n return this.record?.status === 'active';\n }\n\n persistOnNextThreadCreate(): void {\n this.persistGoalOnNextThreadCreate = true;\n }\n\n consumePersistOnNextThreadCreate(): boolean {\n if (!this.persistGoalOnNextThreadCreate) return false;\n this.persistGoalOnNextThreadCreate = false;\n return true;\n }\n\n // ---------------------------------------------------------------------------\n // Objective lifecycle (ThreadState-backed via the agent)\n // ---------------------------------------------------------------------------\n\n /**\n * Set a new objective. Persists to ThreadState via `agent.setObjective` and\n * updates the in-memory view. Only the provided settings are persisted into\n * the record; unset ones fall back to the agent's `goal` config at read time.\n */\n async setGoal(\n state: GoalManagerState,\n objective: string,\n judgeModelId: string,\n maxTurns: number = DEFAULT_MAX_TURNS,\n ): Promise<GoalState | null> {\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n const now = Date.now();\n const id = globalThis.crypto.randomUUID();\n this.pendingDelete = null;\n this.threadId = threadId ?? undefined;\n this.agentId = agent?.id;\n\n if (agent && threadId) {\n const persisted = await agent.setObjective(objective, {\n id,\n threadId,\n resourceId: state.session.identity.getResourceId(),\n ...(judgeModelId ? { judgeModelId } : {}),\n maxRuns: maxTurns,\n });\n this.record = persisted\n ? { ...persisted, id: persisted.id ?? id }\n : this.localRecord(objective, judgeModelId, maxTurns, now, id);\n } else {\n this.record = this.localRecord(objective, judgeModelId, maxTurns, now, id);\n }\n\n return this.getGoal();\n }\n\n /**\n * Update the judge model / max-runs defaults. Persists into the active record\n * (so the override is remembered in thread state) when a goal is set.\n */\n async updateJudgeDefaults(\n state: GoalManagerState,\n judgeModelId: string,\n maxTurns: number,\n ): Promise<GoalState | null> {\n if (!this.record) return null;\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n if (agent && threadId) {\n const updated = await agent.updateObjectiveOptions({\n threadId,\n ...(judgeModelId ? { judgeModelId } : {}),\n maxRuns: maxTurns,\n });\n if (updated) this.record = { ...updated, id: this.record.id };\n } else {\n this.record = {\n ...this.record,\n ...(judgeModelId ? { judgeModelId } : {}),\n maxRuns: maxTurns,\n updatedAt: Date.now(),\n };\n }\n return this.getGoal();\n }\n\n pause(reason?: string): GoalState | null {\n if (this.record && this.record.status === 'active') {\n this.record = { ...this.record, status: 'paused', pausedReason: reason, updatedAt: Date.now() };\n }\n return this.getGoal();\n }\n\n resume(): GoalState | null {\n if (this.record && this.record.status === 'paused') {\n this.record = { ...this.record, status: 'active', pausedReason: undefined, updatedAt: Date.now() };\n }\n return this.getGoal();\n }\n\n markDone(): void {\n if (this.record) {\n this.record = { ...this.record, status: 'done', pausedReason: undefined, updatedAt: Date.now() };\n }\n }\n\n clear(): void {\n this.pendingDelete = { threadId: this.threadId, goalId: this.record?.id };\n this.record = null;\n this.threadId = undefined;\n this.agentId = undefined;\n this.persistGoalOnNextThreadCreate = false;\n }\n\n /**\n * Sync the latest objective record from ThreadState into the in-memory view.\n * Called from the `goal` stream-chunk handler after each evaluation.\n */\n applyEvaluation(update: { runsUsed: number; status: GoalStatus; pausedReason?: string }): GoalState | null {\n if (!this.record) return null;\n const pausedReason =\n update.status === 'paused'\n ? (update.pausedReason ?? (this.record.status === 'paused' ? this.record.pausedReason : undefined))\n : undefined;\n this.record = {\n ...this.record,\n runsUsed: update.runsUsed,\n status: update.status,\n // The cause lasts for one pause; leaving paused retires it.\n pausedReason,\n updatedAt: Date.now(),\n };\n return this.getGoal();\n }\n\n // ---------------------------------------------------------------------------\n // Persistence\n // ---------------------------------------------------------------------------\n\n /**\n * Persist the active objective to ThreadState via the agent. The objective\n * record is the source of truth; the legacy thread-metadata key is cleared on\n * a save that actually wrote, so stale state from older sessions cannot\n * shadow the record — and a save that wrote nothing leaves it alone.\n *\n * An empty in-memory mirror means \"I have nothing *loaded*\", which is not the\n * same statement as \"there is nothing\": the mirror is also emptied by storage\n * failures and thread switches. So a save with an empty mirror deletes the\n * goal (durable record and legacy key) only right after an explicit\n * {@link clear} on the same thread (or any thread, for a legacy-hydrated goal\n * whose thread is unknown), and is a complete no-op otherwise.\n */\n async saveToThread(state: GoalManagerState): Promise<void> {\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n if (!this.record && this.pendingDelete) {\n const clearedThreadId = this.pendingDelete.threadId;\n if (clearedThreadId === undefined || clearedThreadId === threadId) {\n await this.deleteFromThread(state);\n }\n return;\n }\n try {\n if (agent && threadId) {\n if (this.record) {\n // Push the current status/options into the existing record. If no\n // record is persisted yet (e.g. first save), create one.\n const updated = await agent.updateObjectiveOptions({\n threadId,\n status: this.record.status,\n ...(this.record.pausedReason ? { pausedReason: this.record.pausedReason } : {}),\n ...(this.record.judgeModelId ? { judgeModelId: this.record.judgeModelId } : {}),\n ...(this.record.maxRuns !== undefined ? { maxRuns: this.record.maxRuns } : {}),\n });\n if (!updated) {\n // No persisted record yet: create one. `setObjective` always writes\n // `status: 'active'`, so re-apply the in-memory status afterwards if\n // the local goal was already paused/done — otherwise the resumed\n // thread state would no longer match the in-memory state.\n const desiredStatus = this.record.status;\n const created = await agent.setObjective(this.record.objective, {\n id: this.record.id,\n threadId,\n resourceId: state.session.identity.getResourceId(),\n activeDurationMs: normalizeActiveDurationMs(this.record.activeDurationMs),\n ...(this.record.judgeModelId ? { judgeModelId: this.record.judgeModelId } : {}),\n ...(this.record.maxRuns !== undefined ? { maxRuns: this.record.maxRuns } : {}),\n });\n // Nothing durable was written (no goal store, or no thread), so\n // there is no record for a legacy key to shadow — and wiping it\n // would take a pre-migration thread's only copy with it.\n if (!created) return;\n if (desiredStatus !== 'active') {\n await agent.updateObjectiveOptions({\n threadId,\n status: desiredStatus,\n ...(this.record.pausedReason ? { pausedReason: this.record.pausedReason } : {}),\n });\n }\n }\n // Clear any legacy thread-metadata goal so it can't shadow the\n // record we just wrote. Only on the path that actually wrote: on the\n // no-op path a pre-migration thread's only goal may live in that key.\n await state.session.thread.setSetting({ key: THREAD_GOAL_KEY, value: undefined });\n }\n }\n } catch {\n // Persistence is not critical.\n }\n }\n\n /**\n * Remove the objective from the thread, whatever the in-memory mirror holds.\n *\n * The durable record needs an agent and a thread; the legacy thread-metadata\n * key does not, so it is wiped either way — unlike {@link saveToThread}, which\n * writes nothing with an empty mirror unless {@link clear} ran. That asymmetry is deliberate: a\n * pre-migration goal must not resurface from the legacy key after a clear.\n * Like the save, this is best-effort: a failed durable delete also skips the\n * legacy wipe. A pending {@link clear} stays pending until both writes\n * succeed, so a later save retries it; loading the thread retries it once\n * and then drops it. Resolves to whether the delete landed.\n */\n async deleteFromThread(state: GoalManagerState): Promise<boolean> {\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n try {\n if (agent && threadId) {\n await agent.clearObjective({ threadId });\n }\n await state.session.thread.setSetting({ key: THREAD_GOAL_KEY, value: undefined });\n this.pendingDelete = null;\n return true;\n } catch {\n // Persistence is not critical, but keep the retry scoped to the thread\n // this delete targeted so an empty save elsewhere cannot delete a goal.\n // An unknown thread would widen the retry to every thread, so keep the old scope then.\n if (threadId) this.pendingDelete = { threadId, goalId: this.pendingDelete?.goalId };\n return false;\n }\n }\n\n /**\n * Load the objective from ThreadState (called on thread switch). Falls back to\n * the legacy thread-metadata goal for threads created before this migration.\n *\n * A clear whose delete failed is retried here when it targeted this thread and\n * the stored goal is the one that was cleared; otherwise the stored goal loads,\n * so the mirror never hides a goal core is still judging. Resolves to whether\n * that retried delete landed.\n */\n async loadFromThread(state: GoalManagerState, isCurrent: () => boolean = () => true): Promise<boolean> {\n const pending = this.pendingDelete;\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n let nextRecord: typeof this.record = null;\n let storedId: string | undefined;\n if (agent && threadId) {\n try {\n const record = await agent.getObjective({ threadId });\n if (record) {\n storedId = record.id;\n nextRecord = {\n ...record,\n id: record.id ?? globalThis.crypto.randomUUID(),\n activeDurationMs: normalizeActiveDurationMs(record.activeDurationMs),\n };\n }\n } catch {\n // fall through to legacy metadata\n }\n }\n if (!isCurrent()) return false;\n // A goal set or cleared during the read replaced this intent; keep the newer state.\n if (pending && this.pendingDelete !== pending) return false;\n let retriedDelete = false;\n if (pending?.goalId && pending.threadId === threadId && storedId === pending.goalId) {\n retriedDelete = await this.deleteFromThread(state);\n if (retriedDelete) nextRecord = null;\n if (!isCurrent()) return false;\n }\n this.persistGoalOnNextThreadCreate = false;\n this.pendingDelete = null;\n this.threadId = threadId ?? undefined;\n this.agentId = agent?.id;\n this.record = nextRecord;\n return retriedDelete;\n }\n\n /**\n * Legacy entry point retained for thread-switch call sites that only have the\n * thread metadata available. Hydrates from a previously-persisted GoalState.\n */\n loadFromThreadMetadata(metadata: Record<string, unknown> | undefined): void {\n const saved = metadata?.[THREAD_GOAL_KEY] as Partial<GoalState> | undefined;\n this.persistGoalOnNextThreadCreate = false;\n this.pendingDelete = null;\n this.threadId = undefined;\n this.agentId = undefined;\n if (saved && saved.objective && saved.status) {\n this.record = {\n objective: saved.objective,\n status: saved.status,\n runsUsed: saved.turnsUsed ?? 0,\n activeDurationMs: normalizeActiveDurationMs(saved.activeDurationMs),\n maxRuns: saved.maxTurns ?? DEFAULT_MAX_TURNS,\n judgeModelId: saved.judgeModelId ?? '',\n ...(saved.pausedReason ? { pausedReason: saved.pausedReason } : {}),\n startedAt: saved.startedAt ? Date.parse(saved.startedAt) || Date.now() : Date.now(),\n updatedAt: Date.now(),\n id: saved.id ?? globalThis.crypto.randomUUID(),\n };\n } else {\n this.record = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private\n // ---------------------------------------------------------------------------\n\n private getAgent(state: GoalManagerState): Agent | undefined {\n try {\n return state.controller.getCurrentAgent(state.session);\n } catch {\n return undefined;\n }\n }\n\n /** Resolve effective judge model + max runs (record value → settings default). */\n private effectiveSettings(record: GoalObjectiveRecord): { judgeModelId: string; maxTurns: number } {\n const settings = loadSettings();\n return {\n judgeModelId: record.judgeModelId ?? settings.models.goalJudgeModel ?? '',\n maxTurns: record.maxRuns ?? settings.models.goalMaxTurns ?? DEFAULT_MAX_TURNS,\n };\n }\n\n private localRecord(\n objective: string,\n judgeModelId: string,\n maxTurns: number,\n now: number,\n id: string,\n ): GoalObjectiveRecord & { id: string } {\n return {\n objective,\n status: 'active',\n runsUsed: 0,\n activeDurationMs: 0,\n maxRuns: maxTurns,\n ...(judgeModelId ? { judgeModelId } : {}),\n startedAt: now,\n updatedAt: now,\n id,\n };\n }\n}\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ import { HookManager } from './hooks/index.js';
|
|
|
18
18
|
import type { McpServerConfig } from './mcp/index.js';
|
|
19
19
|
import { loadSettings } from './onboarding/settings.js';
|
|
20
20
|
import { PluginManager } from './plugins/manager.js';
|
|
21
|
+
import { ThreadScheduler } from './schedules/index.js';
|
|
21
22
|
import type { MastraCodeState } from './schema.js';
|
|
22
23
|
import type { StorageConfig } from './utils/project.js';
|
|
23
24
|
import type { StorageMaintenance } from './utils/storage-maintenance.js';
|
|
@@ -125,6 +126,13 @@ export interface MastraCodeConfig {
|
|
|
125
126
|
* uses the configured PubSub when enabled.
|
|
126
127
|
*/
|
|
127
128
|
crossAgentSignals?: boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Enable the experimental agent schedule tools (`schedule_create`,
|
|
131
|
+
* `schedule_list`, `schedule_update`, `schedule_run`), which manage the same
|
|
132
|
+
* process-local schedules as `/schedules`. Defaults to the
|
|
133
|
+
* `signals.experimentalScheduleTools` global setting (off).
|
|
134
|
+
*/
|
|
135
|
+
scheduleTools?: boolean;
|
|
128
136
|
/**
|
|
129
137
|
* Prepare the request context of a wake: a run on a thread with no inbound
|
|
130
138
|
* request, such as a notification or cross-agent signal delivered to an idle
|
|
@@ -201,6 +209,8 @@ export declare function createMastraCodeAgentController(config?: MastraCodeConfi
|
|
|
201
209
|
* keeps firing for a controller that is gone.
|
|
202
210
|
*/
|
|
203
211
|
stopPluginSignalProviders: () => void;
|
|
212
|
+
/** Process-local `/schedules` scheduler. Call `stop()` on shutdown. */
|
|
213
|
+
threadScheduler: ThreadScheduler;
|
|
204
214
|
/**
|
|
205
215
|
* Hands Mastra to the statically configured input processors.
|
|
206
216
|
*
|
|
@@ -289,6 +299,8 @@ export declare function bootLocalAgentController(config?: MastraCodeConfig): Pro
|
|
|
289
299
|
* keeps firing for a controller that is gone.
|
|
290
300
|
*/
|
|
291
301
|
stopPluginSignalProviders: () => void;
|
|
302
|
+
/** Process-local `/schedules` scheduler. Call `stop()` on shutdown. */
|
|
303
|
+
threadScheduler: ThreadScheduler;
|
|
292
304
|
/**
|
|
293
305
|
* Hands Mastra to the statically configured input processors.
|
|
294
306
|
*
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|