mastracode 0.23.1-alpha.1 → 0.24.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/CHANGELOG.md +216 -0
- package/dist/agents/memory.d.ts.map +1 -1
- package/dist/agents/modes/plan.d.ts.map +1 -1
- package/dist/{chunk-7QUEBL6Z.js → chunk-3JEAYMT5.js} +49 -50
- package/dist/chunk-3JEAYMT5.js.map +1 -0
- package/dist/{chunk-EWXZ5A65.js → chunk-KYA2RSC5.js} +216 -204
- package/dist/chunk-KYA2RSC5.js.map +1 -0
- package/dist/{chunk-RDG7DHFG.cjs → chunk-T7R2KIKY.cjs} +216 -204
- package/dist/chunk-T7R2KIKY.cjs.map +1 -0
- package/dist/{chunk-3PNUO4FX.cjs → chunk-XRYRSXRP.cjs} +50 -51
- package/dist/chunk-XRYRSXRP.cjs.map +1 -0
- package/dist/cli.cjs +16 -16
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +10 -10
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/tools/utils.d.ts.map +1 -1
- package/dist/tui/chat-boundary-reconciliation.d.ts.map +1 -1
- package/dist/tui/commands/github.d.ts.map +1 -1
- package/dist/tui/commands/om.d.ts.map +1 -1
- package/dist/tui/commands/sandbox.d.ts.map +1 -1
- package/dist/tui/commands/types.d.ts +2 -1
- package/dist/tui/commands/types.d.ts.map +1 -1
- package/dist/tui/handlers/message.d.ts.map +1 -1
- package/dist/tui/mastra-tui.d.ts.map +1 -1
- package/dist/tui/render-messages.d.ts.map +1 -1
- package/dist/tui/state.d.ts +2 -1
- package/dist/tui/state.d.ts.map +1 -1
- package/dist/tui.cjs +11 -11
- package/dist/tui.js +1 -1
- package/package.json +18 -19
- package/dist/HarnessCompat.d.ts +0 -60
- package/dist/HarnessCompat.d.ts.map +0 -1
- package/dist/chunk-3PNUO4FX.cjs.map +0 -1
- package/dist/chunk-7QUEBL6Z.js.map +0 -1
- package/dist/chunk-EWXZ5A65.js.map +0 -1
- package/dist/chunk-RDG7DHFG.cjs.map +0 -1
- package/dist/harness-tui-v1.d.ts +0 -2
- package/dist/harness-tui-v1.d.ts.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,221 @@
|
|
|
1
1
|
# mastracode
|
|
2
2
|
|
|
3
|
+
## 0.24.0-alpha.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Random bump ([#18178](https://github.com/mastra-ai/mastra/pull/18178))
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Improved Mastra Code responsiveness in large threads by speeding up chat rendering and keeping the initial thread render window bounded. ([#18181](https://github.com/mastra-ai/mastra/pull/18181))
|
|
12
|
+
|
|
13
|
+
- Fixed plan mode not calling submit_plan tool by removing conflicting subagent-style output instructions from mode definition ([#18157](https://github.com/mastra-ai/mastra/pull/18157))
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [[`7c0d868`](https://github.com/mastra-ai/mastra/commit/7c0d868d97d0fdbc04c14d0166dbf44d4c5a4a62), [`d9d2273`](https://github.com/mastra-ai/mastra/commit/d9d2273c702690c9a26eab2aebea879701d4355a), [`b04369d`](https://github.com/mastra-ai/mastra/commit/b04369d6b167c698ef103981171a8bf92808e756), [`8f3c262`](https://github.com/mastra-ai/mastra/commit/8f3c262587b335588a02d96b17fd6aca34c885b3)]:
|
|
16
|
+
- @mastra/core@1.45.0-alpha.0
|
|
17
|
+
- @mastra/agent-browser@0.4.0-alpha.0
|
|
18
|
+
- @mastra/stagehand@0.3.0-alpha.0
|
|
19
|
+
- @mastra/tavily@1.1.0-alpha.0
|
|
20
|
+
- @mastra/observability@1.15.0-alpha.0
|
|
21
|
+
- @mastra/fastembed@1.2.0-alpha.0
|
|
22
|
+
- @mastra/mcp@1.11.0-alpha.0
|
|
23
|
+
- @mastra/memory@1.21.0-alpha.0
|
|
24
|
+
- @mastra/schema-compat@1.3.0-alpha.0
|
|
25
|
+
- @mastra/github-signals@0.2.0-alpha.0
|
|
26
|
+
- @mastra/duckdb@1.5.0-alpha.0
|
|
27
|
+
- @mastra/libsql@1.14.0-alpha.0
|
|
28
|
+
- @mastra/pg@1.14.0-alpha.0
|
|
29
|
+
|
|
30
|
+
## 0.23.1
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- Removed the unused harness v1 TUI development script. ([#18131](https://github.com/mastra-ai/mastra/pull/18131))
|
|
35
|
+
|
|
36
|
+
- Security remediation for the 2026-06-17 "easy-day-js" supply-chain incident. Patch bump to publish clean versions and move the `latest` dist-tag forward, superseding the compromised versions that declared the malicious `easy-day-js` dependency. ([#18056](https://github.com/mastra-ai/mastra/pull/18056))
|
|
37
|
+
|
|
38
|
+
- Made the native Agent goal mechanism robust, restoring behavior that regressed when goal handling moved into core. ([#18016](https://github.com/mastra-ai/mastra/pull/18016))
|
|
39
|
+
- **Tool-capable judges.** Scorer judge configs accept optional `tools`, and the default goal scorer can use them to verify the agent's work against reality instead of grading prose alone. MastraCode wires its read-only workspace tools (`view`, `search_content`, `find_files`, `file_stat`, `lsp_inspect`) into `goal.tools`.
|
|
40
|
+
- **Judge memory restored.** Scorer judge configs accept optional `memory`; goal scoring uses the original MastraCode per-goal judge thread shape and prompt format so repeated evaluations retain prior facts, feedback, and user checkpoints through judge memory.
|
|
41
|
+
- **Tri-state waiting.** The default goal scorer emits `done`/`continue`/`waiting`; a `waiting` decision (only when the goal text explicitly asks to stop for the user) stops the auto-loop but keeps the objective `active` so the next agent turn is still judged — no `/goal resume` needed.
|
|
42
|
+
- **Budget-exhaustion pause.** Reaching `maxRuns` without completing now parks the objective as `paused` with a clear reason, resumable by raising `maxRuns` and reactivating, instead of silently leaving it `active`.
|
|
43
|
+
- **Judge-failure pause (no infinite loop).** Any failure while evaluating the goal — including judge-model/tools resolution, not just the scorer run — pauses the objective and stops the loop, surfacing the cause, rather than re-running the model against a broken judge every turn.
|
|
44
|
+
- **Structured-output retry.** `tryGenerateWithJsonFallback` now retries with `jsonPromptInjection` when the judge resolves without a parseable object (not only on a thrown error), matching the streaming path.
|
|
45
|
+
- **Signal-based feedback.** Goal judge feedback is now injected as a `goal-judge` system-reminder signal instead of an assistant-authored "Completion Check Results" transcript message, so reloads and subsequent model context match the original MastraCode goal loop. Continuation, waiting, paused, and done decisions all persist structured evaluation metadata for replay.
|
|
46
|
+
- **TUI activity/replay fixes.** Goal evaluation chunks close the current assistant message before rendering the judge UI, stream judge activity with useful tool targets, stream partial judge reason text while scoring, replay persisted judge results as judge display components instead of raw Goal reminder text, and correctly persist Esc/Ctrl+C pauses while the judge is running.
|
|
47
|
+
|
|
48
|
+
The goal evaluation chunk now carries `pausedReason`, `judgeFailed`, `waitingForUser`, `pending` (emitted before scoring starts so consumers can show a loading indicator), and judge `activity` entries including streamed `reason` updates.
|
|
49
|
+
|
|
50
|
+
- Move the Harness display state onto `session.displayState` ([#18136](https://github.com/mastra-ai/mastra/pull/18136))
|
|
51
|
+
|
|
52
|
+
The canonical display state a UI renders — `isRunning`, active tools, tool-input
|
|
53
|
+
buffers, pending approval/suspensions, active subagents, current message,
|
|
54
|
+
queued follow-ups, modified files, tasks, OM progress, and token usage — now
|
|
55
|
+
lives on the Session as `session.displayState`, alongside the reducer that keeps
|
|
56
|
+
it in sync with every Harness event.
|
|
57
|
+
|
|
58
|
+
`SessionDisplayState` owns:
|
|
59
|
+
- `get()` — a read-only snapshot to render from (replaces `harness.getDisplayState()`)
|
|
60
|
+
- `apply(event)` — the centralized state machine that folds each event into the snapshot
|
|
61
|
+
- `resetThread()` — reset thread-scoped fields on thread switch/create
|
|
62
|
+
- `restoreTasks(tasks)` — restore replayed task history without emitting an event
|
|
63
|
+
- `clearPendingSuspensions()` / `deletePendingSuspension(toolCallId)` — display mirror upkeep on abort/resume
|
|
64
|
+
|
|
65
|
+
Display state is inherently per-conversation, so in a shared (multi-user) host
|
|
66
|
+
it can't hang off the Harness — `harness.getDisplayState()` has no single answer
|
|
67
|
+
when one host serves many sessions. It reads from `harness.session.displayState`
|
|
68
|
+
instead.
|
|
69
|
+
|
|
70
|
+
The Harness stays the **event-bus owner**: `emit()` folds the event into
|
|
71
|
+
`session.displayState` and then dispatches to listeners (including the
|
|
72
|
+
`display_state_changed` fan-out). The reducer needs a few read-only host facts it
|
|
73
|
+
doesn't own — the live token-usage tally, the subagent display-name lookup
|
|
74
|
+
(Harness config), and the active thread id — which are injected into the Session
|
|
75
|
+
at construction.
|
|
76
|
+
|
|
77
|
+
Removed from the Harness public API (read through `harness.session.displayState.*`):
|
|
78
|
+
- `getDisplayState()` → `session.displayState.get()`
|
|
79
|
+
- `restoreDisplayTasks(tasks)` → `session.displayState.restoreTasks(tasks)`
|
|
80
|
+
|
|
81
|
+
`restoreTasks` is now a pure session-state mutation (it no longer emits
|
|
82
|
+
`display_state_changed`); the UI re-renders explicitly after a replay.
|
|
83
|
+
|
|
84
|
+
- Introduce the Harness `Session`: the Harness now exposes `harness.session`, a class that owns the per-conversation runtime state that previously lived flattened on the Harness instance. The Harness remains the shared host (storage, the thread lock, the agent registry, the event bus); the Session owns the state scoped to a single user's conversation. ([#18107](https://github.com/mastra-ai/mastra/pull/18107))
|
|
85
|
+
|
|
86
|
+
`harness.session` owns:
|
|
87
|
+
- **`session.identity`** — the session's `resourceId` / `defaultResourceId` (the stable "who").
|
|
88
|
+
- **`session.thread`** — the active thread binding (`getId` / `set` / `clear` / `isSet` / `requireId`) plus the thread data domain scoped to the session: `list`, `getById`, `listMessages`, `listActiveMessages`, `firstUserMessage(s)`, and thread settings (`getSetting` / `setSetting` / `deleteSetting`). It reaches shared-host storage through an injected gateway rather than calling back into Harness orchestration.
|
|
89
|
+
- **`session.mode`** / **`session.model`** — the currently-selected mode and model (source of truth), the mode-switch sequence, and per-mode model memory. The Harness still owns the mode _definitions_ (`config.modes`).
|
|
90
|
+
- **`session.run`** — transient per-run identity (run id, trace id, operation counter) and abort control (controller, `isRunning`, `requestAbort`, …). Never persisted.
|
|
91
|
+
- **`session.stream`** — the live agent-thread subscription handle and its dedup key. Adds `session.getCurrentRunId()` and `session.abortRun()`, which compose the subscription.
|
|
92
|
+
- **`session.suspensions`** — the parked-tool resume map (`toolCallId → { runId, toolName }`) for tools paused via the native suspension primitive (`ask_user` / `request_access` / `submit_plan`).
|
|
93
|
+
- **`session.followUps`** — the queue of messages to send after the active run finishes.
|
|
94
|
+
- **`session.approval`** — the interactive tool-approval gate; `session.respondToToolApproval({ decision, requestContext })` applies the user's approve / decline / always-allow choice and releases the run.
|
|
95
|
+
- session-scoped permission grants and the live token-usage counter (the Harness still persists usage to thread metadata, since usage is thread-scoped).
|
|
96
|
+
|
|
97
|
+
**Removed from the Harness public API** — read these through `harness.session.*` instead:
|
|
98
|
+
- `getSessionGrants()`, `getTokenUsage()` → `session.getGrants()` / `session.getTokenUsage()`
|
|
99
|
+
- `getCurrentModelId()`, `hasModelSelected()` → `session.model.get()` / `session.model.hasSelection()`
|
|
100
|
+
- `getCurrentRunId()`, `getCurrentTraceId()`, `isRunning()` → `session.getCurrentRunId()` / `session.run.getTraceId()` / `session.run.isRunning()`
|
|
101
|
+
- `getCurrentThreadId()`, `getThreads()`, `listThreads()`, `listMessages()`, `listMessagesForThread()`, `getFirstUserMessage(s)ForThread(s)()`, `getThreadSetting()`, `setThreadSetting()` → `session.thread.*`
|
|
102
|
+
- `getResourceId()`, `getDefaultResourceId()` → `session.identity.*`
|
|
103
|
+
- `getFollowUpCount()` → `session.followUps.count()`
|
|
104
|
+
- `respondToToolApproval()` → `session.respondToToolApproval()`
|
|
105
|
+
- `getCurrentModeId()` → `session.mode.get()`
|
|
106
|
+
- `getCurrentMode()` → `session.mode.resolve()` (resolves the selected mode id against the host's `config.modes` catalog, injected into the Session)
|
|
107
|
+
- `hasPendingSuspensions()` → `session.suspensions.hasPending()`
|
|
108
|
+
- `isCurrentThreadStreamActive()` → `session.stream.isActive()`
|
|
109
|
+
|
|
110
|
+
`Harness.abort()` and `setResourceId()` remain on the Harness with unchanged behavior — they orchestrate Harness-host state (the display-state mirror, the agent-stream subscription, thread teardown) before delegating the relevant reads/writes to the session.
|
|
111
|
+
|
|
112
|
+
`session.mode` exposes two complementary accessors: `get()` returns the selected mode **id** (a `string`, mirroring `session.model.get()`), while `resolve()` returns the full `HarnessMode` definition by looking the id up in the injected mode catalog.
|
|
113
|
+
|
|
114
|
+
The legacy `HarnessCompat` shim (v1-session/legacy-thread merge) has been removed; its thread-list merge now lives in the Session's thread-data store, so `session.thread.list()` returns the merged result directly.
|
|
115
|
+
|
|
116
|
+
`session.abortRun()` now also releases a parked tool-approval gate: a run awaiting `session.approval.arm()` is not actively streaming, so aborting resolves the gate as a decline (rejecting the gated tool) instead of leaving the await hung. Mirrors how abort already drops parked tool suspensions.
|
|
117
|
+
|
|
118
|
+
- Improved MastraCode Harness state access. ([#18133](https://github.com/mastra-ai/mastra/pull/18133))
|
|
119
|
+
|
|
120
|
+
MastraCode now reads and writes Harness state through `harness.session.state` while keeping fallback support for older request-context mocks during the transition.
|
|
121
|
+
|
|
122
|
+
- Updated dependencies [[`339c57c`](https://github.com/mastra-ai/mastra/commit/339c57c5b2c6dbe75a125e138228e0556528976f), [`1dd4117`](https://github.com/mastra-ai/mastra/commit/1dd4117dcbd8e031ede9f0489436bfbc6f0315b8), [`2b11d1f`](https://github.com/mastra-ai/mastra/commit/2b11d1f6ac7024c5dd2b2dd12a48a956ac9d63bd), [`7d6ff70`](https://github.com/mastra-ai/mastra/commit/7d6ff708727297a0526ca0e26e93eeb5bbaaa187), [`77a2351`](https://github.com/mastra-ai/mastra/commit/77a2351ee79296e360bce822cb3391f7cfd6489d), [`b7dff0a`](https://github.com/mastra-ai/mastra/commit/b7dff0a3d1022eb6868f48dc40a2b1febd5c277f), [`b91d921`](https://github.com/mastra-ai/mastra/commit/b91d9213a4998eb343dccd0ff780c42ba22bdfa1), [`02087e1`](https://github.com/mastra-ai/mastra/commit/02087e1fbc54aa07f3071f7a200df1bf5be601a8), [`49af8df`](https://github.com/mastra-ai/mastra/commit/49af8df589c4ff71a5015a4553b377b32704b691), [`30ce559`](https://github.com/mastra-ai/mastra/commit/30ce55902ecf819b8ab8697398dd68b108228063), [`c241b92`](https://github.com/mastra-ai/mastra/commit/c241b929dc8c8d6a7b7219c99ed13ac1f3124a77), [`7d6ff70`](https://github.com/mastra-ai/mastra/commit/7d6ff708727297a0526ca0e26e93eeb5bbaaa187), [`ab975d4`](https://github.com/mastra-ai/mastra/commit/ab975d4dd9488752f05bda7afa03166d207e3e2a), [`9d6aa1b`](https://github.com/mastra-ai/mastra/commit/9d6aa1bae407e2afa6a089abc2a6accbbcb287b8)]:
|
|
123
|
+
- @mastra/core@1.44.0
|
|
124
|
+
- @mastra/observability@1.14.4
|
|
125
|
+
- @mastra/agent-browser@0.3.4
|
|
126
|
+
- @mastra/duckdb@1.4.3
|
|
127
|
+
- @mastra/fastembed@1.1.3
|
|
128
|
+
- @mastra/github-signals@0.1.4
|
|
129
|
+
- @mastra/libsql@1.13.3
|
|
130
|
+
- @mastra/mcp@1.10.1
|
|
131
|
+
- @mastra/memory@1.20.6
|
|
132
|
+
- @mastra/pg@1.13.3
|
|
133
|
+
- @mastra/schema-compat@1.2.14
|
|
134
|
+
- @mastra/stagehand@0.2.7
|
|
135
|
+
- @mastra/tavily@1.0.5
|
|
136
|
+
|
|
137
|
+
## 0.23.1-alpha.2
|
|
138
|
+
|
|
139
|
+
### Patch Changes
|
|
140
|
+
|
|
141
|
+
- Removed the unused harness v1 TUI development script. ([#18131](https://github.com/mastra-ai/mastra/pull/18131))
|
|
142
|
+
|
|
143
|
+
- Move the Harness display state onto `session.displayState` ([#18136](https://github.com/mastra-ai/mastra/pull/18136))
|
|
144
|
+
|
|
145
|
+
The canonical display state a UI renders — `isRunning`, active tools, tool-input
|
|
146
|
+
buffers, pending approval/suspensions, active subagents, current message,
|
|
147
|
+
queued follow-ups, modified files, tasks, OM progress, and token usage — now
|
|
148
|
+
lives on the Session as `session.displayState`, alongside the reducer that keeps
|
|
149
|
+
it in sync with every Harness event.
|
|
150
|
+
|
|
151
|
+
`SessionDisplayState` owns:
|
|
152
|
+
- `get()` — a read-only snapshot to render from (replaces `harness.getDisplayState()`)
|
|
153
|
+
- `apply(event)` — the centralized state machine that folds each event into the snapshot
|
|
154
|
+
- `resetThread()` — reset thread-scoped fields on thread switch/create
|
|
155
|
+
- `restoreTasks(tasks)` — restore replayed task history without emitting an event
|
|
156
|
+
- `clearPendingSuspensions()` / `deletePendingSuspension(toolCallId)` — display mirror upkeep on abort/resume
|
|
157
|
+
|
|
158
|
+
Display state is inherently per-conversation, so in a shared (multi-user) host
|
|
159
|
+
it can't hang off the Harness — `harness.getDisplayState()` has no single answer
|
|
160
|
+
when one host serves many sessions. It reads from `harness.session.displayState`
|
|
161
|
+
instead.
|
|
162
|
+
|
|
163
|
+
The Harness stays the **event-bus owner**: `emit()` folds the event into
|
|
164
|
+
`session.displayState` and then dispatches to listeners (including the
|
|
165
|
+
`display_state_changed` fan-out). The reducer needs a few read-only host facts it
|
|
166
|
+
doesn't own — the live token-usage tally, the subagent display-name lookup
|
|
167
|
+
(Harness config), and the active thread id — which are injected into the Session
|
|
168
|
+
at construction.
|
|
169
|
+
|
|
170
|
+
Removed from the Harness public API (read through `harness.session.displayState.*`):
|
|
171
|
+
- `getDisplayState()` → `session.displayState.get()`
|
|
172
|
+
- `restoreDisplayTasks(tasks)` → `session.displayState.restoreTasks(tasks)`
|
|
173
|
+
|
|
174
|
+
`restoreTasks` is now a pure session-state mutation (it no longer emits
|
|
175
|
+
`display_state_changed`); the UI re-renders explicitly after a replay.
|
|
176
|
+
|
|
177
|
+
- Introduce the Harness `Session`: the Harness now exposes `harness.session`, a class that owns the per-conversation runtime state that previously lived flattened on the Harness instance. The Harness remains the shared host (storage, the thread lock, the agent registry, the event bus); the Session owns the state scoped to a single user's conversation. ([#18107](https://github.com/mastra-ai/mastra/pull/18107))
|
|
178
|
+
|
|
179
|
+
`harness.session` owns:
|
|
180
|
+
- **`session.identity`** — the session's `resourceId` / `defaultResourceId` (the stable "who").
|
|
181
|
+
- **`session.thread`** — the active thread binding (`getId` / `set` / `clear` / `isSet` / `requireId`) plus the thread data domain scoped to the session: `list`, `getById`, `listMessages`, `listActiveMessages`, `firstUserMessage(s)`, and thread settings (`getSetting` / `setSetting` / `deleteSetting`). It reaches shared-host storage through an injected gateway rather than calling back into Harness orchestration.
|
|
182
|
+
- **`session.mode`** / **`session.model`** — the currently-selected mode and model (source of truth), the mode-switch sequence, and per-mode model memory. The Harness still owns the mode _definitions_ (`config.modes`).
|
|
183
|
+
- **`session.run`** — transient per-run identity (run id, trace id, operation counter) and abort control (controller, `isRunning`, `requestAbort`, …). Never persisted.
|
|
184
|
+
- **`session.stream`** — the live agent-thread subscription handle and its dedup key. Adds `session.getCurrentRunId()` and `session.abortRun()`, which compose the subscription.
|
|
185
|
+
- **`session.suspensions`** — the parked-tool resume map (`toolCallId → { runId, toolName }`) for tools paused via the native suspension primitive (`ask_user` / `request_access` / `submit_plan`).
|
|
186
|
+
- **`session.followUps`** — the queue of messages to send after the active run finishes.
|
|
187
|
+
- **`session.approval`** — the interactive tool-approval gate; `session.respondToToolApproval({ decision, requestContext })` applies the user's approve / decline / always-allow choice and releases the run.
|
|
188
|
+
- session-scoped permission grants and the live token-usage counter (the Harness still persists usage to thread metadata, since usage is thread-scoped).
|
|
189
|
+
|
|
190
|
+
**Removed from the Harness public API** — read these through `harness.session.*` instead:
|
|
191
|
+
- `getSessionGrants()`, `getTokenUsage()` → `session.getGrants()` / `session.getTokenUsage()`
|
|
192
|
+
- `getCurrentModelId()`, `hasModelSelected()` → `session.model.get()` / `session.model.hasSelection()`
|
|
193
|
+
- `getCurrentRunId()`, `getCurrentTraceId()`, `isRunning()` → `session.getCurrentRunId()` / `session.run.getTraceId()` / `session.run.isRunning()`
|
|
194
|
+
- `getCurrentThreadId()`, `getThreads()`, `listThreads()`, `listMessages()`, `listMessagesForThread()`, `getFirstUserMessage(s)ForThread(s)()`, `getThreadSetting()`, `setThreadSetting()` → `session.thread.*`
|
|
195
|
+
- `getResourceId()`, `getDefaultResourceId()` → `session.identity.*`
|
|
196
|
+
- `getFollowUpCount()` → `session.followUps.count()`
|
|
197
|
+
- `respondToToolApproval()` → `session.respondToToolApproval()`
|
|
198
|
+
- `getCurrentModeId()` → `session.mode.get()`
|
|
199
|
+
- `getCurrentMode()` → `session.mode.resolve()` (resolves the selected mode id against the host's `config.modes` catalog, injected into the Session)
|
|
200
|
+
- `hasPendingSuspensions()` → `session.suspensions.hasPending()`
|
|
201
|
+
- `isCurrentThreadStreamActive()` → `session.stream.isActive()`
|
|
202
|
+
|
|
203
|
+
`Harness.abort()` and `setResourceId()` remain on the Harness with unchanged behavior — they orchestrate Harness-host state (the display-state mirror, the agent-stream subscription, thread teardown) before delegating the relevant reads/writes to the session.
|
|
204
|
+
|
|
205
|
+
`session.mode` exposes two complementary accessors: `get()` returns the selected mode **id** (a `string`, mirroring `session.model.get()`), while `resolve()` returns the full `HarnessMode` definition by looking the id up in the injected mode catalog.
|
|
206
|
+
|
|
207
|
+
The legacy `HarnessCompat` shim (v1-session/legacy-thread merge) has been removed; its thread-list merge now lives in the Session's thread-data store, so `session.thread.list()` returns the merged result directly.
|
|
208
|
+
|
|
209
|
+
`session.abortRun()` now also releases a parked tool-approval gate: a run awaiting `session.approval.arm()` is not actively streaming, so aborting resolves the gate as a decline (rejecting the gated tool) instead of leaving the await hung. Mirrors how abort already drops parked tool suspensions.
|
|
210
|
+
|
|
211
|
+
- Improved MastraCode Harness state access. ([#18133](https://github.com/mastra-ai/mastra/pull/18133))
|
|
212
|
+
|
|
213
|
+
MastraCode now reads and writes Harness state through `harness.session.state` while keeping fallback support for older request-context mocks during the transition.
|
|
214
|
+
|
|
215
|
+
- Updated dependencies [[`339c57c`](https://github.com/mastra-ai/mastra/commit/339c57c5b2c6dbe75a125e138228e0556528976f), [`1dd4117`](https://github.com/mastra-ai/mastra/commit/1dd4117dcbd8e031ede9f0489436bfbc6f0315b8), [`2b11d1f`](https://github.com/mastra-ai/mastra/commit/2b11d1f6ac7024c5dd2b2dd12a48a956ac9d63bd), [`7d6ff70`](https://github.com/mastra-ai/mastra/commit/7d6ff708727297a0526ca0e26e93eeb5bbaaa187), [`49af8df`](https://github.com/mastra-ai/mastra/commit/49af8df589c4ff71a5015a4553b377b32704b691), [`30ce559`](https://github.com/mastra-ai/mastra/commit/30ce55902ecf819b8ab8697398dd68b108228063), [`c241b92`](https://github.com/mastra-ai/mastra/commit/c241b929dc8c8d6a7b7219c99ed13ac1f3124a77), [`7d6ff70`](https://github.com/mastra-ai/mastra/commit/7d6ff708727297a0526ca0e26e93eeb5bbaaa187)]:
|
|
216
|
+
- @mastra/core@1.44.0-alpha.2
|
|
217
|
+
- @mastra/observability@1.14.4-alpha.1
|
|
218
|
+
|
|
3
219
|
## 0.23.1-alpha.1
|
|
4
220
|
|
|
5
221
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/agents/memory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/agents/memory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAqExC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,oBAAoB,EAAE,MAAM,CAAC,EAAE,YAAY,IAC3E,oBAAoB;IAAE,cAAc,EAAE,cAAc,CAAA;CAAE,YA4D/D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/agents/modes/plan.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,eAAO,MAAM,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/agents/modes/plan.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,eAAO,MAAM,QAAQ,EAAE,WA6BtB,CAAC"}
|
|
@@ -556,8 +556,8 @@ function detectPackageRunner(projectPath) {
|
|
|
556
556
|
}
|
|
557
557
|
function getDynamicWorkspace({ requestContext, mastra: mastra2 }) {
|
|
558
558
|
const ctx = requestContext.get("harness");
|
|
559
|
-
const state = ctx?.
|
|
560
|
-
const modeId = ctx?.modeId ?? "build";
|
|
559
|
+
const state = ctx?.session.state.get();
|
|
560
|
+
const modeId = ctx?.session?.modeId ?? "build";
|
|
561
561
|
const rawProjectPath = state?.projectPath;
|
|
562
562
|
if (!rawProjectPath) {
|
|
563
563
|
throw new Error("Project path is required");
|
|
@@ -644,7 +644,7 @@ function isPathAllowed(targetPath, projectRoot, allowedPaths = []) {
|
|
|
644
644
|
}
|
|
645
645
|
function getAllowedPathsFromContext(toolContext) {
|
|
646
646
|
const harnessCtx = toolContext?.requestContext?.get("harness");
|
|
647
|
-
const state = harnessCtx?.
|
|
647
|
+
const state = harnessCtx?.session.state.get();
|
|
648
648
|
const projectPath = state?.projectPath ? path.resolve(state.projectPath) : process.cwd();
|
|
649
649
|
const configDir = state?.configDir ?? DEFAULT_CONFIG_DIR;
|
|
650
650
|
const skillPaths = buildSkillPaths(projectPath, configDir);
|
|
@@ -700,9 +700,9 @@ var requestSandboxAccessTool = createTool({
|
|
|
700
700
|
const answerText = Array.isArray(resumeData) ? resumeData.join(", ") : String(resumeData);
|
|
701
701
|
const approved = answerText.toLowerCase().startsWith("y") || answerText.toLowerCase() === "approve";
|
|
702
702
|
if (approved) {
|
|
703
|
-
const currentAllowed = harnessCtx?.
|
|
703
|
+
const currentAllowed = harnessCtx?.session.state.get()?.sandboxAllowedPaths ?? [];
|
|
704
704
|
if (!currentAllowed.includes(absolutePath)) {
|
|
705
|
-
await harnessCtx?.
|
|
705
|
+
await harnessCtx?.session.state.set({
|
|
706
706
|
sandboxAllowedPaths: [...currentAllowed, absolutePath]
|
|
707
707
|
});
|
|
708
708
|
}
|
|
@@ -999,7 +999,7 @@ var modePrompts = {
|
|
|
999
999
|
fast: fastModePrompt
|
|
1000
1000
|
};
|
|
1001
1001
|
function buildFullPrompt(ctx) {
|
|
1002
|
-
const modelId = ctx.
|
|
1002
|
+
const modelId = ctx.modelId;
|
|
1003
1003
|
const hasWebSearch = hasTavilyKey() || !!modelId && modelId.startsWith("anthropic/");
|
|
1004
1004
|
const deniedTools = /* @__PURE__ */ new Set();
|
|
1005
1005
|
const permRules = ctx.state?.permissionRules;
|
|
@@ -1034,8 +1034,8 @@ function buildFullPrompt(ctx) {
|
|
|
1034
1034
|
// src/agents/instructions.ts
|
|
1035
1035
|
async function getDynamicInstructions({ requestContext }) {
|
|
1036
1036
|
const harnessContext = requestContext.get("harness");
|
|
1037
|
-
const state = harnessContext?.
|
|
1038
|
-
const modeId = harnessContext?.modeId ?? "build";
|
|
1037
|
+
const state = harnessContext?.session.state.get();
|
|
1038
|
+
const modeId = harnessContext?.session?.modeId ?? "build";
|
|
1039
1039
|
const projectPath = state?.projectPath ?? process.cwd();
|
|
1040
1040
|
const promptCtx = {
|
|
1041
1041
|
projectPath,
|
|
@@ -1045,7 +1045,7 @@ async function getDynamicInstructions({ requestContext }) {
|
|
|
1045
1045
|
commonBinaries: await detectCommonBinariesAsync(),
|
|
1046
1046
|
date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
1047
1047
|
mode: modeId,
|
|
1048
|
-
modelId:
|
|
1048
|
+
modelId: harnessContext?.session?.modelId || void 0,
|
|
1049
1049
|
activePlan: state?.activePlan ?? null,
|
|
1050
1050
|
modeId,
|
|
1051
1051
|
currentDate: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
@@ -2016,7 +2016,7 @@ function resolveModel(modelId, options) {
|
|
|
2016
2016
|
}
|
|
2017
2017
|
function getDynamicModel({ requestContext }) {
|
|
2018
2018
|
const harnessContext = requestContext.get("harness");
|
|
2019
|
-
const modelId = harnessContext?.
|
|
2019
|
+
const modelId = harnessContext?.session?.modelId;
|
|
2020
2020
|
if (!modelId) {
|
|
2021
2021
|
throw new Error("No model selected. Use /models to select a model first.");
|
|
2022
2022
|
}
|
|
@@ -2033,7 +2033,8 @@ function getGoalJudgeModel({ requestContext }, settingsPath) {
|
|
|
2033
2033
|
var cachedMemory = null;
|
|
2034
2034
|
var cachedMemoryKey = null;
|
|
2035
2035
|
function getHarnessState(requestContext) {
|
|
2036
|
-
|
|
2036
|
+
const ctx = requestContext.get("harness");
|
|
2037
|
+
return ctx?.session.state.get();
|
|
2037
2038
|
}
|
|
2038
2039
|
function getObserverModel({ requestContext }) {
|
|
2039
2040
|
const state = getHarnessState(requestContext);
|
|
@@ -2223,21 +2224,11 @@ var planMode = {
|
|
|
2223
2224
|
- **Understand deeply**: Use view with view_range to read specific sections of key files
|
|
2224
2225
|
- **Parallelize**: Make multiple independent tool calls when exploring different areas
|
|
2225
2226
|
|
|
2226
|
-
##
|
|
2227
|
-
|
|
2228
|
-
-
|
|
2229
|
-
-
|
|
2230
|
-
-
|
|
2231
|
-
|
|
2232
|
-
## Output Format
|
|
2233
|
-
Structure your plan as:
|
|
2234
|
-
|
|
2235
|
-
. **Summary**: One-paragraph overview (2-3 sentences)
|
|
2236
|
-
. **Files to Change**: List each file with specific changes needed
|
|
2237
|
-
. **Implementation Order**: Numbered steps in dependency order
|
|
2238
|
-
. **Risks**: Potential issues or edge cases (if any)
|
|
2239
|
-
|
|
2240
|
-
Be specific about code locations (file paths, function names, line numbers). Keep the plan actionable and under 500 words.`,
|
|
2227
|
+
## Plan Delivery
|
|
2228
|
+
- When your exploration is complete, call the \`submit_plan\` tool with your plan.
|
|
2229
|
+
- Do NOT output the plan as text \u2014 it MUST go through the submit_plan tool call.
|
|
2230
|
+
- Be concise: reference files by path and line number, don't include raw contents.
|
|
2231
|
+
- Focus on actionable details, not general observations.`,
|
|
2241
2232
|
metadata: {
|
|
2242
2233
|
default: false
|
|
2243
2234
|
}
|
|
@@ -2255,16 +2246,16 @@ var THREAD_STATE_SETTINGS = [
|
|
|
2255
2246
|
}
|
|
2256
2247
|
];
|
|
2257
2248
|
function getStateValue(harness, setting) {
|
|
2258
|
-
const value = harness.
|
|
2249
|
+
const value = harness.session.state.get()[setting.key];
|
|
2259
2250
|
return setting.isValid(value) ? value : void 0;
|
|
2260
2251
|
}
|
|
2261
2252
|
async function findThread(harness, threadId) {
|
|
2262
|
-
const threads = await harness.
|
|
2253
|
+
const threads = await harness.session.thread.list({ allResources: true });
|
|
2263
2254
|
return threads.find((t) => t.id === threadId);
|
|
2264
2255
|
}
|
|
2265
2256
|
async function restoreSettingsForThread(harness, threadId) {
|
|
2266
2257
|
const thread = await findThread(harness, threadId);
|
|
2267
|
-
if (harness.
|
|
2258
|
+
if (harness.session.thread.getId() !== threadId) return;
|
|
2268
2259
|
const updates = {};
|
|
2269
2260
|
const settingsToSeed = [];
|
|
2270
2261
|
for (const setting of THREAD_STATE_SETTINGS) {
|
|
@@ -2281,10 +2272,10 @@ async function restoreSettingsForThread(harness, threadId) {
|
|
|
2281
2272
|
}
|
|
2282
2273
|
}
|
|
2283
2274
|
if (Object.keys(updates).length > 0) {
|
|
2284
|
-
await harness.
|
|
2275
|
+
await harness.session.state.set(updates);
|
|
2285
2276
|
}
|
|
2286
2277
|
for (const setting of settingsToSeed) {
|
|
2287
|
-
await harness.
|
|
2278
|
+
await harness.session.thread.setSetting(setting);
|
|
2288
2279
|
}
|
|
2289
2280
|
}
|
|
2290
2281
|
function attachOMThreadStatePersistence(harness) {
|
|
@@ -2297,7 +2288,7 @@ function attachOMThreadStatePersistence(harness) {
|
|
|
2297
2288
|
});
|
|
2298
2289
|
}
|
|
2299
2290
|
async function restoreOMThreadStateForCurrentThread(harness) {
|
|
2300
|
-
const threadId = harness.
|
|
2291
|
+
const threadId = harness.session.thread.getId();
|
|
2301
2292
|
if (!threadId) return;
|
|
2302
2293
|
await restoreSettingsForThread(harness, threadId);
|
|
2303
2294
|
}
|
|
@@ -2360,8 +2351,8 @@ function createToolHooks(hookManager) {
|
|
|
2360
2351
|
function createDynamicTools(mcpManager, extraTools, disabledTools, storage) {
|
|
2361
2352
|
return function getDynamicTools({ requestContext }) {
|
|
2362
2353
|
const ctx = requestContext.get("harness");
|
|
2363
|
-
const state = ctx?.
|
|
2364
|
-
const modelId =
|
|
2354
|
+
const state = ctx?.session.state.get();
|
|
2355
|
+
const modelId = ctx?.session?.modelId;
|
|
2365
2356
|
const isAnthropicModel = modelId?.startsWith("anthropic/");
|
|
2366
2357
|
const isOpenAIModel = modelId?.startsWith("openai/");
|
|
2367
2358
|
const tools = {
|
|
@@ -4179,11 +4170,11 @@ async function createMastraCode(config) {
|
|
|
4179
4170
|
// Use dot-notation because these are nested inside the 'harness' key.
|
|
4180
4171
|
//
|
|
4181
4172
|
// Session identifiers:
|
|
4182
|
-
// threadId, resourceId, modeId, harnessId
|
|
4173
|
+
// threadId, resourceId, session.modeId, harnessId
|
|
4183
4174
|
// Environment & project:
|
|
4184
4175
|
// state.projectName, state.gitBranch
|
|
4185
4176
|
// Model configuration:
|
|
4186
|
-
//
|
|
4177
|
+
// session.modelId, state.subagentModelId
|
|
4187
4178
|
// Agent settings:
|
|
4188
4179
|
// state.yolo, state.thinkingLevel, state.smartEditing
|
|
4189
4180
|
// Observational memory settings:
|
|
@@ -4193,13 +4184,13 @@ async function createMastraCode(config) {
|
|
|
4193
4184
|
// Session identifiers
|
|
4194
4185
|
"harness.threadId",
|
|
4195
4186
|
"harness.resourceId",
|
|
4196
|
-
"harness.modeId",
|
|
4187
|
+
"harness.session.modeId",
|
|
4197
4188
|
"harness.harnessId",
|
|
4198
4189
|
// Environment & project
|
|
4199
4190
|
"harness.state.projectName",
|
|
4200
4191
|
"harness.state.gitBranch",
|
|
4201
4192
|
// Model configuration
|
|
4202
|
-
"harness.
|
|
4193
|
+
"harness.session.modelId",
|
|
4203
4194
|
"harness.state.subagentModelId",
|
|
4204
4195
|
// Agent settings
|
|
4205
4196
|
"harness.state.yolo",
|
|
@@ -4237,12 +4228,20 @@ async function createMastraCode(config) {
|
|
|
4237
4228
|
const requestContext = new RequestContext();
|
|
4238
4229
|
const harnessContext = {
|
|
4239
4230
|
harnessId: harness.id,
|
|
4240
|
-
state: harness.
|
|
4241
|
-
getState: () => harness.
|
|
4242
|
-
setState: (updates) => harness.
|
|
4231
|
+
state: harness.session.state.get(),
|
|
4232
|
+
getState: () => harness.session.state.get(),
|
|
4233
|
+
setState: (updates) => harness.session.state.set(updates),
|
|
4243
4234
|
threadId,
|
|
4244
4235
|
resourceId,
|
|
4245
|
-
|
|
4236
|
+
session: {
|
|
4237
|
+
modeId: harness.session.mode.get(),
|
|
4238
|
+
modelId: harness.session.model.get(),
|
|
4239
|
+
state: {
|
|
4240
|
+
get: () => harness.session.state.get(),
|
|
4241
|
+
set: (updates) => harness.session.state.set(updates),
|
|
4242
|
+
update: (updater) => harness.session.state.update(updater)
|
|
4243
|
+
}
|
|
4244
|
+
},
|
|
4246
4245
|
workspace: harness.getWorkspace(),
|
|
4247
4246
|
getSubagentModelId: (params) => harness.getSubagentModelId(params)
|
|
4248
4247
|
};
|
|
@@ -4252,7 +4251,7 @@ async function createMastraCode(config) {
|
|
|
4252
4251
|
requestContext,
|
|
4253
4252
|
maxSteps: 1e3,
|
|
4254
4253
|
savePerStep: false,
|
|
4255
|
-
requireToolApproval: harness.
|
|
4254
|
+
requireToolApproval: harness.session.state.get().yolo !== true,
|
|
4256
4255
|
modelSettings: { temperature: 1 }
|
|
4257
4256
|
};
|
|
4258
4257
|
}
|
|
@@ -4304,8 +4303,8 @@ async function createMastraCode(config) {
|
|
|
4304
4303
|
new AgentsMDInjector({
|
|
4305
4304
|
getIgnoredInstructionPaths: ({ requestContext }) => {
|
|
4306
4305
|
const harnessContext = requestContext?.get("harness");
|
|
4307
|
-
const
|
|
4308
|
-
return getStaticallyLoadedInstructionPaths(projectPath);
|
|
4306
|
+
const state = harnessContext?.session.state.get();
|
|
4307
|
+
return getStaticallyLoadedInstructionPaths(state?.projectPath ?? project.rootPath);
|
|
4309
4308
|
}
|
|
4310
4309
|
}),
|
|
4311
4310
|
new ProviderHistoryCompat()
|
|
@@ -4479,12 +4478,12 @@ async function createMastraCode(config) {
|
|
|
4479
4478
|
if (!threadId) return;
|
|
4480
4479
|
githubSignals.stopAllPolling();
|
|
4481
4480
|
try {
|
|
4482
|
-
const threads = await harness.
|
|
4481
|
+
const threads = await harness.session.thread.list({ allResources: true });
|
|
4483
4482
|
const thread = threads.find((item) => item.id === threadId);
|
|
4484
4483
|
await githubSignals.startPollingForThread(
|
|
4485
4484
|
{
|
|
4486
4485
|
threadId,
|
|
4487
|
-
resourceId: thread?.resourceId ?? harness.getResourceId()
|
|
4486
|
+
resourceId: thread?.resourceId ?? harness.session.identity.getResourceId()
|
|
4488
4487
|
},
|
|
4489
4488
|
{ pollImmediately: true }
|
|
4490
4489
|
);
|
|
@@ -4496,7 +4495,7 @@ async function createMastraCode(config) {
|
|
|
4496
4495
|
if (event.type === "thread_changed") void startGithubPollingForCurrentThread(event.threadId);
|
|
4497
4496
|
else if (event.type === "thread_created") void startGithubPollingForCurrentThread(event.thread.id);
|
|
4498
4497
|
});
|
|
4499
|
-
void startGithubPollingForCurrentThread(harness.
|
|
4498
|
+
void startGithubPollingForCurrentThread(harness.session.thread.getId());
|
|
4500
4499
|
}
|
|
4501
4500
|
const omThreadStateHarness = harness;
|
|
4502
4501
|
attachOMThreadStatePersistence(omThreadStateHarness);
|
|
@@ -4519,5 +4518,5 @@ async function createMastraCode(config) {
|
|
|
4519
4518
|
}
|
|
4520
4519
|
|
|
4521
4520
|
export { createAuthStorage, createMastraCode };
|
|
4522
|
-
//# sourceMappingURL=chunk-
|
|
4523
|
-
//# sourceMappingURL=chunk-
|
|
4521
|
+
//# sourceMappingURL=chunk-3JEAYMT5.js.map
|
|
4522
|
+
//# sourceMappingURL=chunk-3JEAYMT5.js.map
|